Plane.Sdk3/PlaneGcsSdk_Shared/CopterManagement/SingleCopterManager.cs

285 lines
9.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Plane.Communication;
using Plane.Copters;
using Plane.Messaging;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
namespace Plane.CopterManagement
{
public class SingleCopterManager : PLObservableObject, ICopterManager
{
private ICopter _Copter = EmptyCopter.Instance;
private bool _IsSearching;
private IPLMessenger _messenger;
private UdpServerConnectionManager _udpServerConnectionManager = UdpServerConnectionManager.Instance;
public SingleCopterManager(IPLMessenger messenger, SynchronizationContext uiSyncContext) : base(uiSyncContext)
{
_messenger = messenger;
}
public ObservableCollection<ICopter> AllCopters { get { throw new NotSupportedException(); } }
/// <summary>
/// 获取或设置单个 <see cref="ICopter"/> 实例。用 <see cref="EmptyCopter.Instance"/> 代替了 null使用时不必判断是否为 null。
/// </summary>
public ICopter Copter
{
get { return _Copter; }
set { Set(nameof(Copter), ref _Copter, value ?? EmptyCopter.Instance); }
}
public bool IsSearching
{
get { return _IsSearching; }
private set { Set(nameof(IsSearching), ref _IsSearching, value); }
}
public ObservableCollection<ICopter> SelectedCopters { get { throw new NotSupportedException(); } }
public async Task AddOrUpdateCopterAsync(string id, string name, IConnection connection)
{
var copter = CreateCopter(id, name, connection);
await ConnectAsync(copter);
}
public async Task<bool> CheckStatusAndFlyToAsync(double lat, double lng)
{
var copter = this.Copter;
if (copter == null) return false;
switch (copter.State)
{
case CopterState.TakingOff:
case CopterState.HoverMode:
case CopterState.CommandMode:
case CopterState.Returning:
case CopterState.Landing:
await copter.FlyToAsync(lat, lng).ConfigureAwait(false);
return true;
case CopterState.Locked:
case CopterState.Initialized:
case CopterState.FloatMode:
default:
return false;
}
}
public async Task ConnectAsync(ICopter copter)
{
await DisconnectAsync(this.Copter);
RegisterCopterEventHandlers(copter);
await copter.ConnectAsync();
copter.StartMobileControl();
this.Copter = copter;
_uiSyncContext.Post(() =>
_messenger.Send(new CopterConnectedMessage(copter)));
}
public async Task DisconnectAsync(ICopter copter)
{
copter.StopMobileControl();
await copter.DisconnectAsync().ConfigureAwait(false);
UnregisterCopterEventHandlers(copter);
}
public async Task DisconnectAsync()
{
await DisconnectAsync(this.Copter);
_udpServerConnectionManager.StopReceiving();
_udpServerConnectionManager.ClearConnections();
}
public Task FloatAsync()
{
return Copter.FloatAsync();
}
public Task FlyToAsync(double lat, double lng)
{
return Copter.FlyToAsync(lat, lng);
}
public Task FlyToAsync(double lat, double lng, float alt, float flytime = 0, int flytype = 0)
{
return Copter.FlyToAsync(lat, lng, alt);
}
public Task HoverAsync()
{
return Copter.HoverAsync();
}
public Task GuidAsync()
{
return Copter.GuidAsync();
}
public Task LandAsync()
{
return Copter.LandAsync();
}
public Task LockAsync()
{
return Copter.LockAsync();
}
public Task ReturnToLaunchAsync()
{
return Copter.ReturnToLaunchAsync();
}
public Task SetChannelsAsync(ushort? ch1 = default(ushort?), ushort? ch2 = default(ushort?), ushort? ch3 = default(ushort?), ushort? ch4 = default(ushort?), ushort? ch5 = default(ushort?), ushort? ch6 = default(ushort?), ushort? ch7 = default(ushort?), ushort? ch8 = default(ushort?))
{
return Copter.SetChannelsAsync(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8);
}
public Task SetMobileControlAsync(ushort? ch1 = default(ushort?), ushort? ch2 = default(ushort?), ushort? ch3 = default(ushort?), ushort? ch4 = default(ushort?), ushort? ch5 = default(ushort?), ushort? ch6 = default(ushort?), ushort? ch7 = default(ushort?), ushort? ch8 = default(ushort?), float? yaw = default(float?))
{
return Copter.SetMobileControlAsync(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, yaw);
}
public Task StartEmergencyHoverAsync()
{
return Copter.StartEmergencyHoverAsync();
}
public Task MissionStartAsync(int hour_utc, int minute_utc, int second_utc, double Missionlng, double Missionlat)
{
return Copter.MissionStartAsync(hour_utc, minute_utc, second_utc, Missionlng, Missionlat);
}
public void StartMobileControl(int? millisecondsInterval = default(int?))
{
Copter.StartMobileControl(millisecondsInterval);
}
public virtual void StartSearching()
{
if (!IsSearching)
{
_udpServerConnectionManager.ConnectionEstablished += OnConnectionEstablished;
_udpServerConnectionManager.StartReceiving();
IsSearching = true;
}
}
public void StopEmergencyHover()
{
Copter.StopEmergencyHover();
}
public void StopMobileControl()
{
Copter.StopMobileControl();
}
public void StopSearching()
{
if (IsSearching)
{
_udpServerConnectionManager.ConnectionEstablished -= OnConnectionEstablished;
IsSearching = false;
}
}
public Task TakeOffAsync()
{
return Copter.TakeOffAsync();
}
public Task InjectGpsDataAsync(byte[] data, ushort length)
{
return Copter.InjectGpsDataAsync(data, length);
}
public Task MotorTestAsync(int motor)
{
return Copter.TakeOffAsync(motor);
}
public Task TakeOffAsync(float alt)
{
return Copter.TakeOffAsync(alt);
}
public Task UnlockAsync()
{
return Copter.UnlockAsync();
}
public Task LEDAsync()
{
return Copter.LEDAsync();
}
protected virtual ICopter CreateCopter(string id, string name, IConnection connection)
{
return new PLCopter(connection, _uiSyncContext)
{
Id = id,
Name = name
};
}
protected virtual void RegisterCopterEventHandlers(ICopter copter)
{
copter.HeartbeatReceived += Copter_HeartbeatReceived;
copter.LocationChanged += Copter_LocationChanged;
copter.PropertyChanged += Copter_PropertyChanged;
copter.AltitudeChanged += Copter_AltitudeChanged;
copter.AttitudeChanged += Copter_AttitudeChanged;
copter.PairingCompleted += Copter_PairingCompleted;
}
protected virtual void UnregisterCopterEventHandlers(ICopter copter)
{
copter.HeartbeatReceived -= Copter_HeartbeatReceived;
copter.LocationChanged -= Copter_LocationChanged;
copter.PropertyChanged -= Copter_PropertyChanged;
copter.AltitudeChanged -= Copter_AltitudeChanged;
copter.AttitudeChanged -= Copter_AttitudeChanged;
copter.PairingCompleted -= Copter_PairingCompleted;
}
private void Copter_AltitudeChanged(object sender, EventArgs e)
{
_messenger.Send(new CopterAltitudeChangedMessage(sender as ICopter));
}
private void Copter_AttitudeChanged(object sender, EventArgs e)
{
_messenger.Send(new CopterAttitudeChangedMessage(sender as ICopter));
}
private void Copter_HeartbeatReceived(object sender, HeartbeatReceivedEventArgs e)
{
_messenger.Send(new CopterHeartbeatReceivedMessage(sender as ICopter));
}
private void Copter_LocationChanged(object sender, EventArgs e)
{
_messenger.Send(new CopterLocationChangedMessage(sender as ICopter));
}
private void Copter_PairingCompleted(object sender, PairingCompletedEventArgs e)
{
_messenger.Send(new CopterPairingCompletedMessage(sender as ICopter, e.IsSuccessful));
}
private void Copter_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
_messenger.Send(new CopterPropertyChangedMessage(sender as ICopter, e.PropertyName));
}
private async void OnConnectionEstablished(object sender, ConnectionEstablishedEventArgs e)
{
var ip = e.RemoteAddress;
await AddOrUpdateCopterAsync(ip, ip.Substring(ip.LastIndexOfAny(new[] { '.', ':' }) + 1), e.Connection);
}
}
}