Plane.FormationCreator/Plane.FormationCreator/ViewModels/ControlPanelViewModel.cs
2017-02-27 02:06:48 +08:00

465 lines
19 KiB
C#

using Plane.Copters;
using Plane.FormationCreator.Formation;
using Plane.Geography;
using Plane.Logging;
using Plane.Windows.Messages;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using Microsoft.Practices.ServiceLocation;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace Plane.FormationCreator.ViewModels
{
public class ControlPanelViewModel : ViewModelBase
{
public ControlPanelViewModel(FormationController formationController, CopterManager copterManager)
{
_formationController = formationController;
_copterManager = copterManager;
}
private FormationController _formationController;
private CopterManager _copterManager;
private ILogger _logger = ServiceLocator.Current.GetInstance<ILogger>();
private float _AltP = 0.5f;
public float AltP
{
get { return _AltP; }
set { Set(nameof(AltP), ref _AltP, value); }
}
private ICommand _UnlockCommand;
public ICommand UnlockCommand
{
get
{
return _UnlockCommand ?? (_UnlockCommand = new RelayCommand(async () =>
{
// await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.UnlockAsync()));
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select( async c => {
await c.UnlockAsync();
for (int i = 0; !c.IsUnlocked; i++)
{
if (i % (1000 / 25) == 1000 / 25 - 1)
{
await c.UnlockAsync(); // 每 1000 毫秒重试一次。
}
await Task.Delay(25).ConfigureAwait(false);
}
}));
}));
}
}
private ICommand _LockCommand;
public ICommand LockCommand
{
get
{
return _LockCommand ?? (_LockCommand = new RelayCommand(async () =>
{
if (Alert.Show("您确定要上锁吗?飞行器将立即停止运转!", "警告", MessageBoxButton.OKCancel, MessageBoxImage.Warning)
== MessageBoxResult.OK)
{
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.LockAsync()));
}
}));
}
}
private ICommand _TakeOffCommand;
public ICommand TakeOffCommand
{
get
{
return _TakeOffCommand ?? (_TakeOffCommand = new RelayCommand(async () =>
{
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.TakeOffAsync()));
}));
}
}
private ICommand _HoverCommand;
public ICommand HoverCommand
{
get
{
return _HoverCommand ?? (_HoverCommand = new RelayCommand(async () =>
{
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.HoverAsync()));
}));
}
}
private ICommand _FloatCommand;
public ICommand FloatCommand
{
get
{
return _FloatCommand ?? (_FloatCommand = new RelayCommand(async () =>
{
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.FloatAsync()));
}));
}
}
private ICommand _ReturnToLaunchCommand;
public ICommand ReturnToLaunchCommand
{
get
{
return _ReturnToLaunchCommand ?? (_ReturnToLaunchCommand = new RelayCommand(async () =>
{
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.ReturnToLaunchAsync()));
}));
}
}
private ICommand _LandCommand;
public ICommand LandCommand
{
get
{
return _LandCommand ?? (_LandCommand = new RelayCommand(async () =>
{
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.LandAsync()));
}));
}
}
private ICommand _ConnectCommand;
public ICommand ConnectCommand
{
get
{
return _ConnectCommand ?? (_ConnectCommand = new RelayCommand(async () =>
{
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(async copter =>
{
await copter.ConnectAsync();
await copter.GetCopterDataAsync();
}));
}));
}
}
private ICommand _DisconnectCommand;
public ICommand DisconnectCommand
{
get
{
return _DisconnectCommand ?? (_DisconnectCommand = new RelayCommand(async () =>
{
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.DisconnectAsync()));
}));
}
}
private ICommand _FlyToAltitudeCommand;
public ICommand FlyToAltitudeCommand
{
get
{
return _FlyToAltitudeCommand ?? (_FlyToAltitudeCommand = new RelayCommand<float>(async alt =>
{
await _formationController.FlyToAltitudeAsync(_copterManager.AcceptingControlCopters, targetAlt: alt).ConfigureAwait(false);
}));
}
}
private ICommand _FlyInCircleCommand;
public ICommand FlyInCircleCommand
{
get
{
return _FlyInCircleCommand ?? (_FlyInCircleCommand = new RelayCommand(async () =>
{
await _formationController.FlyInCircleAsync(_copterManager.AcceptingControlCopters, centerDirection: 180, radius: 10, loop: true).ConfigureAwait(false);
}));
}
}
private ICommand _FlyAroundCenterOfCoptersCommand;
public ICommand FlyAroundCenterOfCoptersCommand
{
get
{
return _FlyAroundCenterOfCoptersCommand ?? (_FlyAroundCenterOfCoptersCommand = new RelayCommand(async () =>
{
await _formationController.FlyAroundCenterOfCoptersAsync(_copterManager.AcceptingControlCopters).ConfigureAwait(false);
}));
}
}
private ICommand _FlyInRectangleCommand;
public ICommand FlyInRectangleCommand
{
get
{
return _FlyInRectangleCommand ?? (_FlyInRectangleCommand = new RelayCommand(async () =>
{
await _formationController.FlyInRectangleAsync(_copterManager.AcceptingControlCopters, startDirection: 180, sideLength1: 15, sideLength2: 5, loop: true).ConfigureAwait(false);
}));
}
}
private ICommand _FlyToVerticalLineAndMakeCircleCommand;
public ICommand FlyToVerticalLineAndMakeCircleCommand
{
get
{
return _FlyToVerticalLineAndMakeCircleCommand ?? (_FlyToVerticalLineAndMakeCircleCommand = new RelayCommand(async () =>
{
await _formationController.FlyToVerticalLineAndMakeCircle(
_copterManager.AcceptingControlCopters,
centerDirection: 180,
radius: 10
).ConfigureAwait(false);
}));
}
}
private ICommand _FlagCommand;
public ICommand FlagCommand
{
get
{
return _FlagCommand ?? (_FlagCommand = new RelayCommand(async () =>
{
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter =>
{
var copters = _copterManager.Copters;
int index = copters.IndexOf(copter);
_copterManager.CopterStatus[index] = true;
return Task.Run(()=> { });
}));
}));
}
}
private ICommand _TestCommand;
public ICommand TestCommand
{
get
{
return _TestCommand ?? (_TestCommand = new RelayCommand(async () =>
{
var firstCopter = _copterManager.Copters.First();
// Test TurnAsync.
//var latLng = GeographyUtils.CalcLatLngSomeMetersAway(firstCopter.Latitude, firstCopter.Longitude, 135, 10);
//await _formationController.TurnAsync(_copterManager.AcceptingControlCopters, latLng.Item1, latLng.Item2);
// Test FlyToLatLngAsync.
//var copters = _copterManager.AcceptingControlCopters;
//var centerLat = copters.Average(c => c.Latitude);
//var centerLng = copters.Average(c => c.Longitude);
//var latDelta = 10 * GeographyUtils.MetersToLocalLat;
//var lngDelta = 10 * GeographyUtils.GetMetersToLocalLon(copters.First().Latitude);
//var targetLat = centerLat + latDelta;
//var targetLng = centerLng + lngDelta;
//await _formationController.FlyToLatLngAsync(copters, targetLat, targetLng);
// Test FlyInCircleAsync.
//await _formationController.FlyInCircleAsync(_copterManager.AcceptingControlCopters, centerDirection: 180, radius: 10, loop: false);
// Test FlyAroundCenterOfCoptersAsync.
//await _formationController.FlyAroundCenterOfCoptersAsync(_copterManager.AcceptingControlCopters);
// Test FlyToLatLngAsync.
//var targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway(firstCopter.Latitude, firstCopter.Longitude, 135, 20);
//await _formationController.FlyToLatLngAsync(firstCopter, targetLatLng.Item1, targetLatLng.Item2);
//firstCopter.LoiterTurns(1, 10);
//var radius = await firstCopter.GetParamAsync("CIRCLE_RADIUS");
////await firstCopter.SetParamAsync("CIRCLE_RADIUS", 1500);
////var param = await firstCopter.GetParamAsync("CIRCLE_RADIUS");
//// Alert.Show($"半径设置成功啦: {param}");
////await firstCopter.SetParamAsync("CIRCLE_RATE", 30);
//var rate = await firstCopter.GetParamAsync("CIRCLE_RATE");
//Alert.Show($"半径: {radius} 角速度: {rate}");
//await firstCopter.SetMobileControlAsync(yaw: 90);
//if (!_listeningMissionItemReceived)
//{
// firstCopter.MissionItemReceived += (sender, e) => Alert.Show($"{e.Index} {e.Total} {(Protocols.MAVLink.MAV_CMD)e.Details.id}");
// _listeningMissionItemReceived = true;
//}
//await firstCopter.RequestMissionListAsync();
var copter = firstCopter;
///* 写航线 */
//// 任务总数。
//await copter.SetMissionCountAsync(6).ConfigureAwait(false);
//// 起飞前准备。
//await copter.WritePreTakeOffMissionAsync().ConfigureAwait(false);
//// 起飞。
//await copter.WriteTakeOffMissionAsync().ConfigureAwait(false);
//// 不断自增的编号。
//ushort index = 2;
//// 航点。
//await copter.WriteWaypointMissionAsync(new EHLocation(copter).AddLatLngAlt(0.001, 0.002, 2), index++).ConfigureAwait(false);
//// 航点。
//await copter.WriteWaypointMissionAsync(new EHLocation(copter).AddLatLngAlt(0.003, 0.002, 2), index++).ConfigureAwait(false);
//// 返航。
//await copter.WriteReturnToLaunchMissionAsync(index++).ConfigureAwait(false);
//// 降落。
//await copter.WriteLandMissionAsync(index++).ConfigureAwait(false);
///* 读航线 */
// 监听“任务项已接收”事件。
//(copter as EHCopter).MissionItemReceived += (sender, e) => Alert.Show($"{e.Mission.Sequence} {e.Mission.Latitude} {e.Mission.Command}");
// 请求任务列表。
var missions = await copter.RequestMissionListAsync();
// Alert.Show(string.Join(Environment.NewLine, missions.Select(m => $"{m.Sequence}\t{m.Command}\t\t{m.Latitude}")));
//ICopter previousCopter = firstCopter;
//foreach (var item in _copterManager.Copters.Where(c => c != firstCopter))
//{
// item.Follow(previousCopter, keepYawDifference: false, keepFacingTarget: false);
// previousCopter = item;
//}
//var missions = new Mission[]
//{
// Mission.CreateWaypointMission(new EHLocation(firstCopter).AddLatLngAlt(0.0001, 0, 10)),
// Mission.CreateReturnToLaunchMission(),
// Mission.CreateLandMission()
//};
//var result = await firstCopter.WriteMissionsAsync(missions);
//var result2 = await firstCopter.WriteMissionsAsync(missions);
//Debug.WriteLine($"{result1} {result2}");
//var missions = new Mission[]
//{
// Mission.CreateWaypointMission(23.123, 113.123, 10),
// Mission.CreateWaypointMission(23.123, 113.123, 10),
// Mission.CreateWaypointMission(23.123, 113.123, 10),
// Mission.CreateWaypointMission(23.123, 113.123, 10),
// Mission.CreateWaypointMission(23.123, 113.123, 10),
// Mission.CreateWaypointMission(23.123, 113.123, 10),
// Mission.CreateWaypointMission(23.123, 113.123, 10),
// Mission.CreateWaypointMission(23.123, 113.123, 10),
// Mission.CreateWaypointMission(23.123, 113.123, 10),
// Mission.CreateWaypointMission(23.123, 113.123, 10),
// Mission.CreateReturnToLaunchMission(),
// Mission.CreateLandMission()
//};
//var result = await firstCopter.WriteMissionListAsync(missions);
//MessageBox.Show($"The result of WriteMissions: {result}");
// 跟随测试
/*
ICopter previousCopter = firstCopter;
foreach (var item in _copterManager.Copters.Where(c => c != firstCopter))
{
item.Follow(previousCopter, keepYawDifference: false, keepFacingTarget: false);
previousCopter = item;
}
*/
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(async c =>
{
float gpsLed = await c.GetParamAsync("NOTI_GPSLED");
if (gpsLed == 0.0f)
{
await LEDFlashAsync(c, true);
}
else
{
await LEDFlashAsync(c, false);
}
// for (int jj = 0; jj < 5; jj++)
{
// await LEDFlashAsync(c, true);
// await c.SetParamAsync("THR_ALT_P", AltP);
// await c.SetParamAsync("WPNAV_ACCEL_Z", AltP);
// await c.SetParamAsync("WPNAV_ACCEL", AltP);
// await c.SetParamAsync("WPNAV_SPEED", AltP);
// await c.SetParamAsync("WPNAV_SPEED_DN", AltP);
// await c.SetParamAsync("WPNAV_SPEED_UP", AltP);
// await LEDFlashAsync(c, false);
// await LEDFlashAsync(c, true);
// await Task.Delay(500).ConfigureAwait(false);
// await Task.Delay(1000).ConfigureAwait(false);
// await LEDFlashAsync(c, true);
// await Task.Delay(1000).ConfigureAwait(false);
}
}));
}));
}
}
private async Task LEDFlashAsync(ICopter copter, bool isOn)
{
// float gpsLed = await c.GetParamAsync("NOTI_GPSLED");
float ledControl = 0.0f;
if (isOn)
{
ledControl = 1.0f;
}
var tasks = new Task[2];
//tasks[0] = copter.SetParamAsync("NOTI_GPSLED", ledControl);
//tasks[1] = copter.SetParamAsync("NOTI_ARMLED", ledControl);
tasks[0] = Task.Run(async () =>
{
try
{
await copter.SetParamAsync("NOTI_GPSLED", ledControl, 5000);
}
catch (TimeoutException e)
{
_logger.Log($"NOTI_GPSLED 超时, CopterId: {copter.Id}。");
}
});
tasks[1] = Task.Run(async () =>
{
try
{
await copter.SetParamAsync("NOTI_ARMLED", ledControl, 5000);
}
catch (TimeoutException e)
{
_logger.Log($"NOTI_ARMLED 超时, CopterId: {copter.Id}。");
}
});
await Task.WhenAll(tasks).ConfigureAwait(false);
}
private bool _listeningMissionItemReceived;
private ICommand _StopTaskCommand;
public ICommand StopTaskCommand
{
get
{
return _StopTaskCommand ?? (_StopTaskCommand = new RelayCommand(async () =>
{
await _formationController.AllStop().ConfigureAwait(false);
}));
}
}
}
}