using Plane.CopterManagement;
using Plane.Copters;
using Plane.Messaging;
using System.Collections.Generic;
namespace Plane.CopterControllers
{
///
/// 通过倾斜、旋转设备对飞行器进行控制的控制器。
///
public class AvatarController : CopterControllerBase
{
///
/// 允许最大的偏角范围的绝对值(例如飞行器左倾斜多少度为有效值,超出此值则取此值)
///
private const int MAX_ANGLE_OFFSET = 45;
private static readonly HashSet _acceptingMobileControlStates = new HashSet { CopterState.Locked, CopterState.HoverMode, CopterState.FloatMode, CopterState.CommandMode, CopterState.Returning, CopterState.Following };
public AvatarController(IPLMessenger messenger, ICopterManager copterManager) : base(messenger, copterManager)
{
messenger.Register(this, m =>
{
if (m.LandingStateAcceptsAvatar) _acceptingMobileControlStates.Add(CopterState.Landing);
else _acceptingMobileControlStates.Remove(CopterState.Landing);
});
}
public override bool IsEnabled
{
get
{
return base.IsEnabled;
}
set
{
if (base.IsEnabled != value)
{
base.IsEnabled = value;
if (value)
{
_messenger.Register(this, OnRequestUpdateAttitude);
}
else
{
_messenger.Unregister(this);
}
}
}
}
public SpeedType Speed { get; set; }
public override CopterControllerTypes Type
{
get
{
return CopterControllerTypes.AvatarController;
}
}
private void OnRequestUpdateAttitude(RequestUpdateAttitudeMessage m)
{
if (_copterManager.Copter != null && _acceptingMobileControlStates.Contains(_copterManager.Copter.State))
{
// TODO: 王海, 20151109, 整理并使用 Plane.Copters.Constants 类中的常量。
ushort maxChannelOffset = (ushort)(Speed == SpeedType.SpeedFast ? 400 : 200);
if (m.RollDegrees.IsInRange(-5, 5))
{
_copterManager.Copter.DesiredChannel1 = RollMedianValue;
}
else
{
_copterManager.Copter.DesiredChannel1 = (ushort)(m.RollDegrees.Limit(-MAX_ANGLE_OFFSET, MAX_ANGLE_OFFSET) * maxChannelOffset / MAX_ANGLE_OFFSET + RollMedianValue);
}
if (m.PitchDegrees.IsInRange(-5, 5))
{
_copterManager.Copter.DesiredChannel2 = PitchMedianValue;
}
else
{
_copterManager.Copter.DesiredChannel2 = (ushort)(m.PitchDegrees.Limit(-MAX_ANGLE_OFFSET, MAX_ANGLE_OFFSET) * maxChannelOffset / MAX_ANGLE_OFFSET + PitchMedianValue);
}
_copterManager.Copter.DesiredYaw = m.YawDegrees;
}
}
}
}