紧急返航功能,策略不对,临时保存
This commit is contained in:
parent
2614dc2f59
commit
36875bcdc2
@ -163,7 +163,11 @@ namespace Plane.FormationCreator.Formation
|
|||||||
get { return _ModifyingSingleCopterInfo; }
|
get { return _ModifyingSingleCopterInfo; }
|
||||||
set { Set(nameof(ModifyingSingleCopterInfo), ref _ModifyingSingleCopterInfo, value); }
|
set { Set(nameof(ModifyingSingleCopterInfo), ref _ModifyingSingleCopterInfo, value); }
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 实际执行某一个任务--包含等待
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="InvalidOperationException"></exception>
|
||||||
public async Task RunAsync()
|
public async Task RunAsync()
|
||||||
{
|
{
|
||||||
switch (TaskType)
|
switch (TaskType)
|
||||||
@ -172,8 +176,6 @@ namespace Plane.FormationCreator.Formation
|
|||||||
await RunFlyToTaskAsync().ConfigureAwait(false);
|
await RunFlyToTaskAsync().ConfigureAwait(false);
|
||||||
break;
|
break;
|
||||||
case FlightTaskType.TakeOff:
|
case FlightTaskType.TakeOff:
|
||||||
//多架同时起飞
|
|
||||||
//await MutilRunTakeOffTaskAsync().ConfigureAwait(false);
|
|
||||||
await NewMutilRunTakeOffTaskAsync().ConfigureAwait(false);
|
await NewMutilRunTakeOffTaskAsync().ConfigureAwait(false);
|
||||||
break;
|
break;
|
||||||
case FlightTaskType.Land:
|
case FlightTaskType.Land:
|
||||||
|
@ -22,6 +22,10 @@ using Plane.CommunicationManagement;
|
|||||||
using Microsoft.Practices.ServiceLocation;
|
using Microsoft.Practices.ServiceLocation;
|
||||||
using Plane.FormationCreator.ViewModels;
|
using Plane.FormationCreator.ViewModels;
|
||||||
using MahApps.Metro.Controls;
|
using MahApps.Metro.Controls;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using GMap.NET.MapProviders;
|
||||||
|
using GMap.NET;
|
||||||
|
using static Plane.FormationCreator.CalculationLogLatDistance;
|
||||||
|
|
||||||
namespace Plane.FormationCreator.Formation
|
namespace Plane.FormationCreator.Formation
|
||||||
{
|
{
|
||||||
@ -648,7 +652,21 @@ namespace Plane.FormationCreator.Formation
|
|||||||
// SelectedTaskIndex = 0;
|
// SelectedTaskIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//模拟紧急返航
|
||||||
|
public async Task sim_DoMissionEmergencyRetAsync(PLLocation takeoffcentloc, PLLocation taskcentloc, float mindistance,int rettime, bool descending)
|
||||||
|
{
|
||||||
|
var copters = _copterManager.Copters;
|
||||||
|
if (TaskState == TasksStatus.Stop)
|
||||||
|
return;
|
||||||
|
IsEmergencyRet = true;
|
||||||
|
//设置所有模拟飞机的位置
|
||||||
|
for (int j = 0; j < copters.Count; j++)
|
||||||
|
{
|
||||||
|
var copter = copters[j];
|
||||||
|
var fc = copter as FakeCopter;
|
||||||
|
await fc.EmergencyRetAsync(takeoffcentloc, taskcentloc, mindistance, rettime, descending);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task ForceNextTasks()
|
public async Task ForceNextTasks()
|
||||||
{
|
{
|
||||||
@ -2199,6 +2217,15 @@ namespace Plane.FormationCreator.Formation
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
CancellationTokenSource cts ;
|
||||||
|
|
||||||
|
//绕行取消,用于3D绕行计算
|
||||||
|
public void cancel_ABypassBAsync()
|
||||||
|
{
|
||||||
|
if (cts!=null)
|
||||||
|
cts.Cancel(); //取消掉 异步执行的 绕行函数
|
||||||
|
}
|
||||||
|
|
||||||
//新开线程异步调用ABypassB并等待返回
|
//新开线程异步调用ABypassB并等待返回
|
||||||
public async Task<(List<List<FlightRouteV2.Vector3>>,bool)> ABypassBAsync(FlightRouteV2.Vector3[] aVecs, FlightRouteV2.Vector3[] bVecs)
|
public async Task<(List<List<FlightRouteV2.Vector3>>,bool)> ABypassBAsync(FlightRouteV2.Vector3[] aVecs, FlightRouteV2.Vector3[] bVecs)
|
||||||
{
|
{
|
||||||
@ -2207,7 +2234,8 @@ namespace Plane.FormationCreator.Formation
|
|||||||
|
|
||||||
var task = Task.Run(() =>
|
var task = Task.Run(() =>
|
||||||
{
|
{
|
||||||
ret = FlyVecFun.ABypassB(aVecs, bVecs, Routecallback, Cronograma, out isPasstmp);
|
cts = new CancellationTokenSource();
|
||||||
|
ret = FlyVecFun.ABypassB(aVecs, bVecs, Routecallback, Cronograma, cts.Token, out isPasstmp);
|
||||||
});
|
});
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -2852,8 +2880,24 @@ namespace Plane.FormationCreator.Formation
|
|||||||
Message.Show($"经纬方式计算用时:{stopWatch.Elapsed.TotalMilliseconds}ms,总飞行距离{sumlength}米,有{crosscount}个交叉");
|
Message.Show($"经纬方式计算用时:{stopWatch.Elapsed.TotalMilliseconds}ms,总飞行距离{sumlength}米,有{crosscount}个交叉");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//计算一个图案的重心点 (三维的)
|
||||||
//计算中心点 (三维的)
|
private PLLocation CenterGravityLatLng(List<PLLocation> points)
|
||||||
|
{
|
||||||
|
double aLatitude = 0;
|
||||||
|
double aLongitude = 0;
|
||||||
|
double aAlt = 0;
|
||||||
|
foreach (var item in points)
|
||||||
|
{
|
||||||
|
aLatitude += item.Latitude;
|
||||||
|
aLongitude += item.Longitude;
|
||||||
|
aAlt += item.Altitude;
|
||||||
|
}
|
||||||
|
aLatitude = aLatitude / points.Count;
|
||||||
|
aLongitude = aLongitude / points.Count;
|
||||||
|
aAlt = aAlt / points.Count;
|
||||||
|
return new PLLocation(aLatitude, aLongitude, (float)aAlt);
|
||||||
|
}
|
||||||
|
//计算两个图案的共同几何中心点 (三维的)
|
||||||
private PLLocation CenterLatLng(List<PLLocation> point1, List<PLLocation> point2)
|
private PLLocation CenterLatLng(List<PLLocation> point1, List<PLLocation> point2)
|
||||||
{
|
{
|
||||||
PLLocation centerLatLng = new PLLocation(0,0,0);
|
PLLocation centerLatLng = new PLLocation(0,0,0);
|
||||||
@ -3195,8 +3239,30 @@ namespace Plane.FormationCreator.Formation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _IsEmergencyRet=false;
|
||||||
|
public bool IsEmergencyRet
|
||||||
|
{
|
||||||
|
get { return _IsEmergencyRet; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (Set(nameof(IsEmergencyRet), ref _IsEmergencyRet, value))
|
||||||
|
{
|
||||||
|
if (_IsEmergencyRet)
|
||||||
|
{
|
||||||
|
MessageText = "任务紧急返航中!";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageText = "任务运行中";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TimeSpan timeSpan;
|
TimeSpan timeSpan;
|
||||||
DateTime taskStartTime;
|
public DateTime taskStartTime;
|
||||||
public async Task RunTaskAsync()
|
public async Task RunTaskAsync()
|
||||||
{
|
{
|
||||||
if (Tasks.Count == 0) return;
|
if (Tasks.Count == 0) return;
|
||||||
@ -3249,10 +3315,14 @@ namespace Plane.FormationCreator.Formation
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 开始运行模拟任务
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
public async Task RunAsync()
|
public async Task RunAsync()
|
||||||
{
|
{
|
||||||
IsPaused = false;
|
IsPaused = false;
|
||||||
|
IsEmergencyRet = false;
|
||||||
for (int i = CurrentRunningTaskIndex; i < Tasks.Count; i++)
|
for (int i = CurrentRunningTaskIndex; i < Tasks.Count; i++)
|
||||||
{
|
{
|
||||||
var task = Tasks[i];
|
var task = Tasks[i];
|
||||||
@ -3261,6 +3331,10 @@ namespace Plane.FormationCreator.Formation
|
|||||||
}
|
}
|
||||||
AppEx.Current.AppMode = AppMode.RunningTasks;
|
AppEx.Current.AppMode = AppMode.RunningTasks;
|
||||||
StartAvoidingCrash(); //开始碰撞检测
|
StartAvoidingCrash(); //开始碰撞检测
|
||||||
|
|
||||||
|
//告诉所有飞机开始任务--模拟飞机不计算起飞延迟,直接传0
|
||||||
|
foreach (var copter in _copterManager.Copters)
|
||||||
|
await copter.MissionStartAsync(0, 0, 0, 0, 0);
|
||||||
TaskState = TasksStatus.Running;
|
TaskState = TasksStatus.Running;
|
||||||
for (int i = CurrentRunningTaskIndex; i < Tasks.Count; i++)
|
for (int i = CurrentRunningTaskIndex; i < Tasks.Count; i++)
|
||||||
{
|
{
|
||||||
@ -3269,16 +3343,13 @@ namespace Plane.FormationCreator.Formation
|
|||||||
task.Status = FlightTaskStatus.Running;
|
task.Status = FlightTaskStatus.Running;
|
||||||
CurrentRunningTask = task;
|
CurrentRunningTask = task;
|
||||||
CurrentRunningTaskIndex = i;
|
CurrentRunningTaskIndex = i;
|
||||||
|
//显示提示信息
|
||||||
//////////////////显示提示信息
|
|
||||||
int starttime = 0;
|
int starttime = 0;
|
||||||
for (int j = 0; j < task.TaskIndex; j++)
|
for (int j = 0; j < task.TaskIndex; j++)
|
||||||
starttime += GetTaskTime(j);
|
starttime += GetTaskTime(j);
|
||||||
TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(starttime));
|
TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(starttime));
|
||||||
Message.Show($"{ts}:任务{i+1} {task.TaskCnName } 开始执行,需{ GetTaskTime(task.TaskIndex)}秒");
|
Message.Show($"{ts}:任务{i+1} {task.TaskCnName } 开始执行,需{ GetTaskTime(task.TaskIndex)}秒");
|
||||||
/////////////////////////
|
//开始执行任务
|
||||||
|
|
||||||
|
|
||||||
await task.RunAsync().ConfigureAwait(false);
|
await task.RunAsync().ConfigureAwait(false);
|
||||||
// 1. 被暂停时,中断 RunAsync。继续运行时将把此时运行了一半的 CurrentRunningTask 重新运行一遍。
|
// 1. 被暂停时,中断 RunAsync。继续运行时将把此时运行了一半的 CurrentRunningTask 重新运行一遍。
|
||||||
if (IsPaused == true)
|
if (IsPaused == true)
|
||||||
@ -3288,10 +3359,17 @@ namespace Plane.FormationCreator.Formation
|
|||||||
Message.Show($"任务{i + 1} {task.TaskCnName } 暂停执行");
|
Message.Show($"任务{i + 1} {task.TaskCnName } 暂停执行");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//紧急返航中-跳出任务循环
|
||||||
|
if (IsEmergencyRet == true) break;
|
||||||
task.Status = FlightTaskStatus.Stop;
|
task.Status = FlightTaskStatus.Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 正常结束时,重置 CurrentRunningTask、CurrentRunningTaskIndex 和 IsPaused。
|
//紧急返航中-等待返航结束
|
||||||
|
while (IsEmergencyRet) {
|
||||||
|
//延时10ms等待
|
||||||
|
await Task.Delay(10);
|
||||||
|
}
|
||||||
|
// 2. 正常结束时,重置 CurrentRunningTask、CurrentRunningTaskIndex 和 IsPaused。
|
||||||
TaskState = TasksStatus.Stop;
|
TaskState = TasksStatus.Stop;
|
||||||
CurrentRunningTask = null;
|
CurrentRunningTask = null;
|
||||||
CurrentRunningTaskIndex = 0;
|
CurrentRunningTaskIndex = 0;
|
||||||
@ -3306,11 +3384,179 @@ namespace Plane.FormationCreator.Formation
|
|||||||
#endregion Run and pause.
|
#endregion Run and pause.
|
||||||
|
|
||||||
|
|
||||||
|
//计算飞行一段时间后的位置
|
||||||
|
private PLLocation TaskFlyLoc(PLLocation startloc, PLLocation tarloc,int currflytime,int flytime )
|
||||||
|
{
|
||||||
|
PLLocation flyLatLng;
|
||||||
|
if (currflytime >= flytime)
|
||||||
|
{
|
||||||
|
flyLatLng=new PLLocation(tarloc.Latitude, tarloc.Longitude, tarloc.Altitude);
|
||||||
|
return flyLatLng;
|
||||||
|
}
|
||||||
|
double _direction = startloc.CalcDirection2D(tarloc.Latitude, tarloc.Longitude);
|
||||||
|
double _Lng_delta = (float)(Math.Sin(_direction) * GeographyUtils.CalcMetersToLngSpan(tarloc.Latitude));
|
||||||
|
double _Lat_delta = (float)(Math.Cos(_direction) * GeographyUtils.METERS_TO_LAT_SPAN);
|
||||||
|
|
||||||
|
//计算xy和z方向距离
|
||||||
|
float _distance_xy = (float)startloc.CalcDistance2D(tarloc);
|
||||||
|
float _distance_z = tarloc.Altitude - startloc.Altitude;
|
||||||
|
|
||||||
|
float currdis_xy= _distance_xy/ flytime* currflytime;
|
||||||
|
float currdis_z = _distance_z / flytime * currflytime;
|
||||||
|
// 更新位置
|
||||||
|
float Altitude = startloc.Altitude + currdis_z;
|
||||||
|
double Longitude = startloc.Longitude + currdis_xy * _Lng_delta;
|
||||||
|
double Latitude = startloc.Latitude + currdis_xy * _Lat_delta;
|
||||||
|
flyLatLng = new PLLocation(Latitude, Longitude, Altitude);
|
||||||
|
return flyLatLng;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//计算紧急返航数据
|
||||||
|
//rettime :返航时间点--从起飞开始计算的秒数
|
||||||
|
//takeoffcentloc:起飞图案重心点
|
||||||
|
//taskcentloc:返航图案重心点
|
||||||
|
//mindistance:离起飞重心点最近飞机距离
|
||||||
|
//overlapping:两个图案是否有重叠--用来决定飞机是先降低高度还是先横着飞
|
||||||
|
//返回值:是否可以计算返航--起飞不能用这个函数,直接降落
|
||||||
|
public bool EmergencyRet(int rettime, out PLLocation takeoffcentloc, out PLLocation taskcentloc, out double mindistance, out bool overlapping)
|
||||||
|
{
|
||||||
|
mindistance = 0;
|
||||||
|
int starttime = 0;
|
||||||
|
int flyedtasktime = 0;
|
||||||
|
int rettaskindex = -1;
|
||||||
|
int taskflytime = 0;
|
||||||
|
taskcentloc = null;
|
||||||
|
overlapping = false;
|
||||||
|
|
||||||
|
double takeoffmaxlat=0;
|
||||||
|
double takeoffmaxlng = 0;
|
||||||
|
double takeoffminlat = double.MaxValue;
|
||||||
|
double takeoffminlng = double.MaxValue;
|
||||||
|
double taskmaxlat = 0;
|
||||||
|
double taskmaxlng = 0;
|
||||||
|
double taskminlat = double.MaxValue;
|
||||||
|
double taskminlng = double.MaxValue;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Dictionary<int, PLLocation> curTaskPoint = new Dictionary<int, PLLocation>();
|
||||||
|
|
||||||
|
//计算地面起飞矩阵的中心点
|
||||||
|
for (int i = 0; i < _copterManager.Copters.Count; i++)
|
||||||
|
{
|
||||||
|
//起飞任务
|
||||||
|
var curinfo = Tasks[0].SingleCopterInfos[i];
|
||||||
|
PLLocation curLoc = new PLLocation(curinfo.TargetLat, curinfo.TargetLng,0);
|
||||||
|
if (curinfo.TargetLat > takeoffmaxlat)
|
||||||
|
takeoffmaxlat = curinfo.TargetLat;
|
||||||
|
if (curinfo.TargetLng > takeoffmaxlng)
|
||||||
|
takeoffmaxlng = curinfo.TargetLng;
|
||||||
|
if (curinfo.TargetLat < takeoffminlat)
|
||||||
|
takeoffminlat = curinfo.TargetLat;
|
||||||
|
if (curinfo.TargetLng < takeoffminlng)
|
||||||
|
takeoffminlng = curinfo.TargetLng;
|
||||||
|
curTaskPoint.Add(i, curLoc);
|
||||||
|
}
|
||||||
|
takeoffcentloc = CenterGravityLatLng(curTaskPoint.Values.ToList());
|
||||||
|
curTaskPoint.Clear();
|
||||||
|
|
||||||
|
//计算返航时间正在飞行哪个航点,飞了多久
|
||||||
|
for (int i = 0; i < Tasks.Count; i++)
|
||||||
|
{
|
||||||
|
flyedtasktime= GetTaskTime(i);
|
||||||
|
if ((starttime+ flyedtasktime) > rettime)
|
||||||
|
{
|
||||||
|
rettaskindex = i;
|
||||||
|
taskflytime = rettime - starttime;
|
||||||
|
}
|
||||||
|
starttime += flyedtasktime;
|
||||||
|
}
|
||||||
|
//起飞不能用这个函数,直接降落
|
||||||
|
if (rettaskindex<1) return false;
|
||||||
|
mindistance = double.MaxValue;
|
||||||
|
|
||||||
|
//计算悬停图案的重心点
|
||||||
|
for (int i = 0; i < _copterManager.Copters.Count; i++)
|
||||||
|
{
|
||||||
|
var curinfo = Tasks[rettaskindex].SingleCopterInfos[i];
|
||||||
|
var prvcurinfo = Tasks[rettaskindex - 1].SingleCopterInfos[i];
|
||||||
|
PLLocation curLoc;
|
||||||
|
if (taskflytime < Tasks[rettaskindex].FlytoTime)
|
||||||
|
{
|
||||||
|
PLLocation coptercurLoc = new PLLocation(curinfo.TargetLat, curinfo.TargetLng, curinfo.TargetAlt);
|
||||||
|
PLLocation copterprvLoc = new PLLocation(prvcurinfo.TargetLat, prvcurinfo.TargetLng, prvcurinfo.TargetAlt);
|
||||||
|
//计算飞行一段时间后的位置
|
||||||
|
curLoc = TaskFlyLoc(copterprvLoc, coptercurLoc, taskflytime, Tasks[rettaskindex].FlytoTime);
|
||||||
|
}
|
||||||
|
else //正在悬停
|
||||||
|
curLoc = new PLLocation(curinfo.TargetLat, curinfo.TargetLng, 0);
|
||||||
|
|
||||||
|
curTaskPoint.Add(i, curLoc);
|
||||||
|
if (curinfo.TargetLat > taskmaxlat)
|
||||||
|
taskmaxlat = curinfo.TargetLat;
|
||||||
|
if (curinfo.TargetLng > taskmaxlng)
|
||||||
|
taskmaxlng = curinfo.TargetLng;
|
||||||
|
if (curinfo.TargetLat < taskminlat)
|
||||||
|
taskminlat = curinfo.TargetLat;
|
||||||
|
if (curinfo.TargetLng < taskminlng)
|
||||||
|
taskminlng = curinfo.TargetLng;
|
||||||
|
double taskdistance = takeoffcentloc.CalcDistance(curLoc);
|
||||||
|
if (taskdistance < mindistance)
|
||||||
|
mindistance = taskdistance;
|
||||||
|
}
|
||||||
|
taskcentloc = CenterGravityLatLng(curTaskPoint.Values.ToList());
|
||||||
|
curTaskPoint.Clear();
|
||||||
|
|
||||||
|
//判断两个图案是否有重叠
|
||||||
|
overlapping = DoRectanglesOverlap(takeoffminlat, takeoffminlng, takeoffmaxlat, takeoffmaxlng,
|
||||||
|
taskminlat, taskminlng, taskmaxlat, taskmaxlng);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断两个矩形是否有重叠
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="minLat1"></param>
|
||||||
|
/// <param name="minLng1"></param>
|
||||||
|
/// <param name="maxLat1"></param>
|
||||||
|
/// <param name="maxLng1"></param>
|
||||||
|
/// <param name="minLat2"></param>
|
||||||
|
/// <param name="minLng2"></param>
|
||||||
|
/// <param name="maxLat2"></param>
|
||||||
|
/// <param name="maxLng2"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
static bool DoRectanglesOverlap(double minLat1, double minLng1, double maxLat1, double maxLng1,
|
||||||
|
double minLat2, double minLng2, double maxLat2, double maxLng2)
|
||||||
|
{
|
||||||
|
// 判断第一个矩形在第二个矩形的左边或右边
|
||||||
|
if (minLng1 > maxLng2 || minLng2 > maxLng1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断第一个矩形在第二个矩形的上边或下边
|
||||||
|
if (minLat1 > maxLat2 || minLat2 > maxLat1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Dictionary<int, string> AvoidCrashLog = new Dictionary<int, string >();
|
Dictionary<int, string> AvoidCrashLog = new Dictionary<int, string >();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private async void StartAvoidingCrash()
|
private async void StartAvoidingCrash()
|
||||||
{
|
{
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
public enum FlightTaskStatus
|
public enum FlightTaskStatus
|
||||||
{
|
{
|
||||||
Stop,
|
Stop,
|
||||||
Running,
|
Running,
|
||||||
Paused,
|
Paused,
|
||||||
Selected
|
Selected
|
||||||
}
|
}
|
||||||
public enum TasksStatus
|
public enum TasksStatus
|
||||||
{
|
{
|
||||||
Stop,
|
Stop,
|
||||||
Running,
|
Running,
|
||||||
Paused
|
Paused
|
||||||
}
|
}
|
@ -1,262 +1,212 @@
|
|||||||
using Plane.Copters;
|
using Plane.Copters;
|
||||||
using Plane.Geography;
|
using Plane.Geography;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Plane.Windows.Messages;
|
using Plane.Windows.Messages;
|
||||||
|
|
||||||
namespace Plane.FormationCreator.Formation
|
namespace Plane.FormationCreator.Formation
|
||||||
{
|
{
|
||||||
public partial class FlightTask
|
public partial class FlightTask
|
||||||
{
|
{
|
||||||
private bool _StaggerRoutes = true;
|
private bool _StaggerRoutes = true;
|
||||||
|
|
||||||
//是否有交错
|
//是否有交错
|
||||||
public bool StaggerRoutes
|
public bool StaggerRoutes
|
||||||
{
|
{
|
||||||
get { return _StaggerRoutes; }
|
get { return _StaggerRoutes; }
|
||||||
set { Set(nameof(StaggerRoutes), ref _StaggerRoutes, value); }
|
set { Set(nameof(StaggerRoutes), ref _StaggerRoutes, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
//同一个任务每一架飞机的FlytoTime和LoiterTime保持统一
|
//同一个任务每一架飞机的FlytoTime和LoiterTime保持统一
|
||||||
private int _FlytoTime = 10;
|
private int _FlytoTime = 10;
|
||||||
public int FlytoTime
|
public int FlytoTime
|
||||||
{
|
{
|
||||||
get { return _FlytoTime; }
|
get { return _FlytoTime; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value > 4095) value = 4095;
|
if (value > 4095) value = 4095;
|
||||||
if (value < 0) value = 0;
|
if (value < 0) value = 0;
|
||||||
Set(nameof(FlytoTime), ref _FlytoTime, value);
|
Set(nameof(FlytoTime), ref _FlytoTime, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private int _LoiterTime = 1;
|
private int _LoiterTime = 1;
|
||||||
public int LoiterTime
|
public int LoiterTime
|
||||||
{
|
{
|
||||||
get { return _LoiterTime; }
|
get { return _LoiterTime; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value > 4095) value = 4095;
|
if (value > 4095) value = 4095;
|
||||||
if (value < 0) value = 0;
|
if (value < 0) value = 0;
|
||||||
Set(nameof(LoiterTime), ref _LoiterTime, value);
|
Set(nameof(LoiterTime), ref _LoiterTime, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private bool _VerticalLift = false;
|
private bool _VerticalLift = false;
|
||||||
public bool VerticalLift // 垂直升降标志位,后面需要加入即使拖动地图上的飞机,也不会变化经纬度. added by ZJF
|
public bool VerticalLift // 垂直升降标志位,后面需要加入即使拖动地图上的飞机,也不会变化经纬度. added by ZJF
|
||||||
{
|
{
|
||||||
get { return _VerticalLift; }
|
get { return _VerticalLift; }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
int currentIndex = _flightTaskManager.SelectedTaskIndex;
|
int currentIndex = _flightTaskManager.SelectedTaskIndex;
|
||||||
var currentCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos;
|
var currentCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos;
|
||||||
var previousCopterInfos = _flightTaskManager.Tasks[currentIndex - 1].SingleCopterInfos;
|
var previousCopterInfos = _flightTaskManager.Tasks[currentIndex - 1].SingleCopterInfos;
|
||||||
for (int i = 0; i < currentCopterInfos.Count; i++)
|
for (int i = 0; i < currentCopterInfos.Count; i++)
|
||||||
{
|
{
|
||||||
currentCopterInfos[i].TargetLat = previousCopterInfos[i].TargetLat;
|
currentCopterInfos[i].TargetLat = previousCopterInfos[i].TargetLat;
|
||||||
currentCopterInfos[i].TargetLng = previousCopterInfos[i].TargetLng;
|
currentCopterInfos[i].TargetLng = previousCopterInfos[i].TargetLng;
|
||||||
currentCopterInfos[i].TargetAlt = previousCopterInfos[i].TargetAlt;
|
currentCopterInfos[i].TargetAlt = previousCopterInfos[i].TargetAlt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Set(nameof(VerticalLift), ref _VerticalLift, value);
|
Set(nameof(VerticalLift), ref _VerticalLift, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public async Task RunFlyToTaskAsync() // 全部飞到指定航点
|
public async Task RunFlyToTaskAsync() // 全部飞到指定航点
|
||||||
{
|
{
|
||||||
//是否有交错
|
//是否有交错
|
||||||
if (StaggerRoutes)
|
if (StaggerRoutes)
|
||||||
{
|
{
|
||||||
var infos = SingleCopterInfos;
|
var infos = SingleCopterInfos;
|
||||||
var tasks = new Task[infos.Count];
|
var tasks = new Task[infos.Count];
|
||||||
for (int i = 0; i < infos.Count; i++)
|
for (int i = 0; i < infos.Count; i++)
|
||||||
{
|
{
|
||||||
var info = infos[i];
|
var info = infos[i];
|
||||||
|
//为每架飞机创建一个航点任务
|
||||||
tasks[i] = await Task.Factory.StartNew(async () =>
|
tasks[i] = await Task.Factory.StartNew(async () =>
|
||||||
{
|
{
|
||||||
var internalInfo = info;
|
var internalInfo = info;
|
||||||
//if (i1 > 0)
|
await FlyToTaskFlySingleCopterAsync(internalInfo);
|
||||||
//{
|
});
|
||||||
// var prevCopter = infos[i1 - 1].Copter;
|
}
|
||||||
// while (CheckCrossing(infos, i1) &&
|
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||||
// prevCopter.Altitude - copter.Altitude < 2)
|
|
||||||
// {
|
}
|
||||||
// await Task.Delay(25).ConfigureAwait(false);
|
else
|
||||||
// }
|
{
|
||||||
//}
|
await Task.WhenAll(
|
||||||
|
SingleCopterInfos.Select(info => FlyToTaskFlySingleCopterAsync(info))
|
||||||
await FlyToTaskFlySingleCopterAsync(internalInfo);
|
).ConfigureAwait(false);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
|
||||||
|
|
||||||
}
|
// private int RuningTaskRemaining = 0;
|
||||||
else
|
/// <summary>
|
||||||
{
|
/// 单独飞机执行飞行任务
|
||||||
await Task.WhenAll(
|
/// </summary>
|
||||||
SingleCopterInfos.Select(info => FlyToTaskFlySingleCopterAsync(info))
|
/// <param name="info"></param>
|
||||||
).ConfigureAwait(false);
|
/// <returns></returns>
|
||||||
}
|
private async Task FlyToTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
|
||||||
}
|
{
|
||||||
|
DateTime dtNow = DateTime.Now;
|
||||||
|
DateTime dtLastTime = DateTime.Now;
|
||||||
// private int RuningTaskRemaining = 0;
|
TimeSpan ts = dtNow - dtLastTime;
|
||||||
|
|
||||||
private async Task FlyToTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
|
|
||||||
{
|
FlightTask task = _flightTaskManager.CurrentRunningTask;
|
||||||
DateTime dtNow = DateTime.Now;
|
int flyToTime = task.FlytoTime * 1000;
|
||||||
DateTime dtLastTime = DateTime.Now;
|
int loiterTime = task.LoiterTime * 1000;
|
||||||
TimeSpan ts = dtNow - dtLastTime;
|
int taskIndex = _flightTaskManager.CurrentRunningTaskIndex;
|
||||||
|
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||||
|
|
||||||
FlightTask task = _flightTaskManager.CurrentRunningTask;
|
|
||||||
int flyToTime = task.FlytoTime * 1000;
|
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||||
int loiterTime = task.LoiterTime * 1000;
|
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||||
int taskIndex = _flightTaskManager.CurrentRunningTaskIndex;
|
{
|
||||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
await info.Copter.HoverAsync();
|
||||||
|
return;
|
||||||
|
}
|
||||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
|
||||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
await info.Copter.SetShowLEDAsync(info.FlytoShowLED);
|
||||||
{
|
|
||||||
await info.Copter.HoverAsync();
|
if (info.Copter.State != Plane.Copters.CopterState.CommandMode)
|
||||||
return;
|
await info.Copter.GuidAsync();
|
||||||
}
|
|
||||||
|
|
||||||
await info.Copter.SetShowLEDAsync(info.FlytoShowLED);
|
double targetLat = info.TargetLat;
|
||||||
|
double targetLng = info.TargetLng;
|
||||||
if (info.Copter.State != Plane.Copters.CopterState.CommandMode)
|
if (info.IsLandWaypoint)
|
||||||
await info.Copter.GuidAsync();
|
{
|
||||||
|
targetLat = info.Copter.TakeOffPoint.Latitude;
|
||||||
|
targetLng = info.Copter.TakeOffPoint.Longitude;
|
||||||
double targetLat = info.TargetLat;
|
}
|
||||||
double targetLng = info.TargetLng;
|
int flytype = _flightTaskManager.getflytype(taskIndex);
|
||||||
if (info.IsLandWaypoint)
|
//指定目标位置
|
||||||
{
|
await info.Copter.FlyToAsync(targetLat, targetLng, info.TargetAlt, task.FlytoTime, flytype);
|
||||||
targetLat = info.Copter.TakeOffPoint.Latitude;
|
dtNow = DateTime.Now;
|
||||||
targetLng = info.Copter.TakeOffPoint.Longitude;
|
ts = dtNow - dtLastTime;
|
||||||
}
|
//等待时间到达,并执行灯光模拟--不移动飞机,移动飞机是飞机自己计算的
|
||||||
int flytype = _flightTaskManager.getflytype(taskIndex);
|
while (ts.TotalMilliseconds < (flyToTime + loiterTime)) //按时间轴飞:当前任务时间到达后自动飞往下个航点
|
||||||
await info.Copter.FlyToAsync(targetLat, targetLng, info.TargetAlt, task.FlytoTime, flytype);
|
{
|
||||||
// await Task.Delay(10).ConfigureAwait(false);
|
if (_flightTaskManager.IsPaused == true)
|
||||||
|
{
|
||||||
dtNow = DateTime.Now;
|
await info.Copter.HoverAsync();
|
||||||
ts = dtNow - dtLastTime;
|
return;
|
||||||
|
}
|
||||||
// int sendFlyToTimes = 0;
|
await Task.Delay(100).ConfigureAwait(false); //判断是否到达位置10hz
|
||||||
|
//执行灯光模拟
|
||||||
/*
|
if (info.LEDInfos.Count > 0)
|
||||||
//第0个任务为takeoff
|
{
|
||||||
if (taskIndex > 0)
|
string LEDRGB = "";
|
||||||
{
|
List<LEDInfo> LedControl = info.LEDInfos.ToList();
|
||||||
FlightTask prevTask = _flightTaskManager.Tasks[taskIndex - 1];
|
double time = 0;
|
||||||
if (prevTask.TaskType == FlightTaskType.FlyTo && prevTask.LoiterTime == 0)
|
for (int i = 0; i < LedControl.Count; i++)
|
||||||
flyToTime += prevTask.RuningTaskRemaining;
|
{
|
||||||
}
|
|
||||||
*/
|
var led = LedControl[i];
|
||||||
|
time += led.Delay * 1000;
|
||||||
//while (!info.Copter.ArrivedTarget(info.TargetLat, info.TargetLng, info.TargetAlt)) //按航点飞 :所有Copter到达目标点开始飞下个航点
|
if (ts.TotalMilliseconds >= time)
|
||||||
while (ts.TotalMilliseconds < (flyToTime + loiterTime)) //按时间轴飞:当前任务时间到达后自动飞往下个航点
|
LEDRGB = info.LEDInfos[i].LEDRGB;
|
||||||
{
|
else
|
||||||
/*
|
break;
|
||||||
//悬停时间等于0为快速航点 到达之后立即出发下个航点 切时间累积
|
}
|
||||||
if (loiterTime == 0 &&
|
info.Copter.LEDColor = LEDRGB;
|
||||||
info.Copter.ArrivedTarget(info.TargetLat, info.TargetLng, info.TargetAlt))
|
}
|
||||||
{
|
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||||
task.RuningTaskRemaining = flyToTime - (int)ts.TotalMilliseconds;
|
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||||
break;
|
{
|
||||||
}
|
await info.Copter.HoverAsync();
|
||||||
*/
|
return;
|
||||||
if (_flightTaskManager.IsPaused == true)
|
}
|
||||||
{
|
dtNow = DateTime.Now;
|
||||||
await info.Copter.HoverAsync();
|
ts = dtNow - dtLastTime;
|
||||||
return;
|
}
|
||||||
}
|
// await info.Copter.HoverAsync();
|
||||||
await Task.Delay(100).ConfigureAwait(false); //判断是否到达位置10hz
|
if (taskIndex == _flightTaskManager.Tasks.Count() - 1)
|
||||||
|
{
|
||||||
|
await info.Copter.HoverAsync();
|
||||||
|
}
|
||||||
// if (info.LEDInfos.Count > 0)
|
}
|
||||||
// {
|
|
||||||
// string LEDRGB = "";
|
|
||||||
// List<LEDInfo> LedControl = info.LEDInfos.OrderBy(i=>i.Delay).ToList();
|
private static bool CheckCrossing(List<FlightTaskSingleCopterInfo> infos, int currentIndex)
|
||||||
// for (int i = 0; i < LedControl.Count; i++)
|
{
|
||||||
// {
|
var info = infos[currentIndex];
|
||||||
// var led = LedControl[i];
|
for (int i = 0; i < currentIndex; i++)
|
||||||
// if (ts.TotalMilliseconds >= led.Delay * 1000)
|
{
|
||||||
// LEDRGB = info.LEDInfos[i].LEDRGB;
|
var nextInfo = infos[i];
|
||||||
// else
|
if (GeographyUtils.CheckCrossing2D(info.Copter.Latitude, info.Copter.Longitude, info.TargetLat, info.TargetLng,
|
||||||
// break;
|
nextInfo.Copter.Latitude, nextInfo.Copter.Longitude, nextInfo.TargetLat, nextInfo.TargetLng))
|
||||||
// }
|
{
|
||||||
// info.Copter.LEDColor = LEDRGB;
|
return true;
|
||||||
//
|
}
|
||||||
// }
|
}
|
||||||
|
return false;
|
||||||
if (info.LEDInfos.Count > 0)
|
}
|
||||||
{
|
}
|
||||||
string LEDRGB = "";
|
}
|
||||||
List<LEDInfo> LedControl = info.LEDInfos.ToList();
|
|
||||||
double time = 0;
|
|
||||||
for (int i = 0; i < LedControl.Count; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
var led = LedControl[i];
|
|
||||||
time += led.Delay * 1000;
|
|
||||||
if (ts.TotalMilliseconds >= time)
|
|
||||||
LEDRGB = info.LEDInfos[i].LEDRGB;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
info.Copter.LEDColor = LEDRGB;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
|
||||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
|
||||||
{
|
|
||||||
await info.Copter.HoverAsync();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dtNow = DateTime.Now;
|
|
||||||
ts = dtNow - dtLastTime;
|
|
||||||
}
|
|
||||||
// await info.Copter.HoverAsync();
|
|
||||||
if (taskIndex == _flightTaskManager.Tasks.Count() - 1)
|
|
||||||
{
|
|
||||||
await info.Copter.HoverAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static bool CheckCrossing(List<FlightTaskSingleCopterInfo> infos, int currentIndex)
|
|
||||||
{
|
|
||||||
var info = infos[currentIndex];
|
|
||||||
for (int i = 0; i < currentIndex; i++)
|
|
||||||
{
|
|
||||||
var nextInfo = infos[i];
|
|
||||||
if (GeographyUtils.CheckCrossing2D(info.Copter.Latitude, info.Copter.Longitude, info.TargetLat, info.TargetLng,
|
|
||||||
nextInfo.Copter.Latitude, nextInfo.Copter.Longitude, nextInfo.TargetLat, nextInfo.TargetLng))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,487 +1,486 @@
|
|||||||
using Plane.Copters;
|
using Plane.Copters;
|
||||||
using Microsoft.Practices.ServiceLocation;
|
using Microsoft.Practices.ServiceLocation;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Plane.Geography;
|
using Plane.Geography;
|
||||||
|
|
||||||
namespace Plane.FormationCreator.Formation
|
namespace Plane.FormationCreator.Formation
|
||||||
{
|
{
|
||||||
public partial class FlightTask
|
public partial class FlightTask
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
//起飞到第一个航点高度的飞行时间
|
//起飞到第一个航点高度的飞行时间
|
||||||
private byte _TakeOffTime = 10;
|
private byte _TakeOffTime = 10;
|
||||||
public byte TakeOffTime
|
public byte TakeOffTime
|
||||||
{
|
{
|
||||||
get { return _TakeOffTime; }
|
get { return _TakeOffTime; }
|
||||||
set { Set(nameof(TakeOffTime), ref _TakeOffTime, value); }
|
set { Set(nameof(TakeOffTime), ref _TakeOffTime, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
//一架架起飞--未使用
|
//一架架起飞--未使用
|
||||||
public async Task RunTakeOffTaskAsync()
|
public async Task RunTakeOffTaskAsync()
|
||||||
{
|
{
|
||||||
// float takeOffAlt = 15;
|
// float takeOffAlt = 15;
|
||||||
int TaskCount = _flightTaskManager.Tasks.Count();
|
int TaskCount = _flightTaskManager.Tasks.Count();
|
||||||
if (TaskCount > 1)
|
if (TaskCount > 1)
|
||||||
{
|
{
|
||||||
var infos = SingleCopterInfos;
|
var infos = SingleCopterInfos;
|
||||||
// var tasks = new Task[infos.Count];
|
// var tasks = new Task[infos.Count];
|
||||||
var tasksTmp = new Task[infos.Count];
|
var tasksTmp = new Task[infos.Count];
|
||||||
for (int i = 0; i < infos.Count; i++)
|
for (int i = 0; i < infos.Count; i++)
|
||||||
{
|
{
|
||||||
var info = infos[i];
|
var info = infos[i];
|
||||||
|
|
||||||
if (info.takeOffStage == 0) // 第一阶段:起飞到10m
|
if (info.takeOffStage == 0) // 第一阶段:起飞到10m
|
||||||
{
|
{
|
||||||
await TakeOffTaskFlySingleCopterAsync(info);
|
await TakeOffTaskFlySingleCopterAsync(info);
|
||||||
//if (_flightTaskManager.IsPaused == false)
|
//if (_flightTaskManager.IsPaused == false)
|
||||||
//{
|
//{
|
||||||
// info.takeOffStage++;
|
// info.takeOffStage++;
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasksTmp[i] = TakeOffSecondTaskAsync(info); // 第二和第三阶段
|
tasksTmp[i] = TakeOffSecondTaskAsync(info); // 第二和第三阶段
|
||||||
}
|
}
|
||||||
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
|
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
|
||||||
if (_flightTaskManager.IsPaused == false)
|
if (_flightTaskManager.IsPaused == false)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < infos.Count; i++)
|
for (int i = 0; i < infos.Count; i++)
|
||||||
{
|
{
|
||||||
var info = infos[i];
|
var info = infos[i];
|
||||||
info.takeOffStage = 0;
|
info.takeOffStage = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//新版的起飞方案
|
//新版的起飞方案
|
||||||
public async Task NewMutilRunTakeOffTaskAsync()
|
public async Task NewMutilRunTakeOffTaskAsync()
|
||||||
{
|
{
|
||||||
var infos = SingleCopterInfos;
|
var infos = SingleCopterInfos;
|
||||||
var tasksTakeOff = new Task[infos.Count];
|
var tasksTakeOff = new Task[infos.Count];
|
||||||
for (int i = 0; i < infos.Count; i++)
|
for (int i = 0; i < infos.Count; i++)
|
||||||
{
|
{
|
||||||
//tasksTakeOff[i] = NewSingleRunTaskOffTaskAsunc(infos[i]);
|
tasksTakeOff[i] = await Task.Factory.StartNew(async () =>
|
||||||
|
{
|
||||||
|
var internalInfo = infos[i];
|
||||||
tasksTakeOff[i] = await Task.Factory.StartNew(async () =>
|
await NewSingleRunTaskOffTaskAsunc(internalInfo);
|
||||||
{
|
});
|
||||||
var internalInfo = infos[i];
|
}
|
||||||
|
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
||||||
await NewSingleRunTaskOffTaskAsunc(internalInfo);
|
}
|
||||||
});
|
|
||||||
}
|
/// <summary>
|
||||||
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
/// 单独飞机 执行起飞任务
|
||||||
//await Task.Delay(100);
|
/// </summary>
|
||||||
}
|
/// <param name="info"></param>
|
||||||
|
/// <returns></returns>
|
||||||
private async Task NewSingleRunTaskOffTaskAsunc(FlightTaskSingleCopterInfo info)
|
private async Task NewSingleRunTaskOffTaskAsunc(FlightTaskSingleCopterInfo info)
|
||||||
{
|
{
|
||||||
DateTime dtNow = DateTime.Now;
|
DateTime dtNow = DateTime.Now;
|
||||||
DateTime dtLastTime = DateTime.Now;
|
DateTime dtLastTime = DateTime.Now;
|
||||||
TimeSpan ts = dtNow - dtLastTime;
|
TimeSpan ts = dtNow - dtLastTime;
|
||||||
|
|
||||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||||
var copter = info.Copter;
|
var copter = info.Copter;
|
||||||
await copter.UnlockAsync();
|
await copter.UnlockAsync();
|
||||||
//等待起飞时间
|
//等待起飞时间
|
||||||
while ((int)ts.TotalMilliseconds < (int)info.TakeOffWaitTime * 1000)
|
while ((int)ts.TotalMilliseconds < (int)info.TakeOffWaitTime * 1000)
|
||||||
{
|
{
|
||||||
if (_flightTaskManager.IsPaused == true)
|
if (_flightTaskManager.IsPaused == true)
|
||||||
{
|
{
|
||||||
await copter.UnlockAsync();
|
await copter.UnlockAsync();
|
||||||
await info.Copter.HoverAsync();
|
await info.Copter.HoverAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await Task.Delay(100);
|
await Task.Delay(100);
|
||||||
dtNow = DateTime.Now;
|
dtNow = DateTime.Now;
|
||||||
ts = dtNow - dtLastTime;
|
ts = dtNow - dtLastTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
//虚拟飞机5秒后不起飞会自动上锁
|
//虚拟飞机5秒后不起飞会自动上锁
|
||||||
await copter.UnlockAsync();
|
await copter.UnlockAsync();
|
||||||
await copter.TakeOffAsync();
|
await copter.TakeOffAsync();
|
||||||
var copterNextTask = _flightTaskManager.Tasks[TaskIndex + 1].SingleCopterInfos[copterIndex];
|
var copterNextTask = _flightTaskManager.Tasks[TaskIndex + 1].SingleCopterInfos[copterIndex];
|
||||||
float takeOffAlt = copterNextTask.TargetAlt;
|
float takeOffAlt = copterNextTask.TargetAlt;
|
||||||
info.TargetLat = info.Copter.Latitude;
|
info.TargetLat = info.Copter.Latitude;
|
||||||
info.TargetLng = info.Copter.Longitude;
|
info.TargetLng = info.Copter.Longitude;
|
||||||
//info.Copter.takeOffTargetAltitude = takeOffAlt;
|
//info.Copter.takeOffTargetAltitude = takeOffAlt;
|
||||||
FlightTask task = _flightTaskManager.CurrentRunningTask;
|
FlightTask task = _flightTaskManager.CurrentRunningTask;
|
||||||
float takeflytime = task.TakeOffTime - info.TakeOffWaitTime;
|
float takeflytime = task.TakeOffTime - info.TakeOffWaitTime;
|
||||||
//开始往上飞
|
//飞行目标,开始往上飞
|
||||||
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt, takeflytime, 1); //秒
|
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt, takeflytime, 1); //秒
|
||||||
//解锁起飞用暗紫色
|
//解锁起飞用暗紫色
|
||||||
info.Copter.LEDColor = CopterManager.CopterTakeoffColor;
|
info.Copter.LEDColor = CopterManager.CopterTakeoffColor;
|
||||||
|
|
||||||
dtNow = DateTime.Now;
|
dtNow = DateTime.Now;
|
||||||
ts = dtNow - dtLastTime;
|
ts = dtNow - dtLastTime;
|
||||||
|
|
||||||
|
//等待起飞时间完成,并模拟灯光--不移动飞机-飞机自己计算并移动位置
|
||||||
while (ts.TotalMilliseconds < task.TakeOffTime * 1000)
|
while (ts.TotalMilliseconds < task.TakeOffTime * 1000)
|
||||||
{
|
{
|
||||||
if (_flightTaskManager.IsPaused == true)
|
if (_flightTaskManager.IsPaused == true)
|
||||||
{
|
{
|
||||||
await info.Copter.HoverAsync();
|
await info.Copter.HoverAsync();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await Task.Delay(100).ConfigureAwait(false);
|
await Task.Delay(100).ConfigureAwait(false);
|
||||||
dtNow = DateTime.Now;
|
dtNow = DateTime.Now;
|
||||||
ts = dtNow - dtLastTime;
|
ts = dtNow - dtLastTime;
|
||||||
//灯光控制
|
//灯光控制
|
||||||
if (info.LEDInfos.Count > 0)
|
if (info.LEDInfos.Count > 0)
|
||||||
{
|
{
|
||||||
string LEDRGB = "";
|
string LEDRGB = "";
|
||||||
List<LEDInfo> LedControl = info.LEDInfos.ToList();
|
List<LEDInfo> LedControl = info.LEDInfos.ToList();
|
||||||
double time = 0;
|
double time = 0;
|
||||||
for (int i = 0; i < LedControl.Count; i++)
|
for (int i = 0; i < LedControl.Count; i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
var led = LedControl[i];
|
var led = LedControl[i];
|
||||||
time += led.Delay * 1000;
|
time += led.Delay * 1000;
|
||||||
if (ts.TotalMilliseconds >= time)
|
if (ts.TotalMilliseconds >= time)
|
||||||
LEDRGB = info.LEDInfos[i].LEDRGB;
|
LEDRGB = info.LEDInfos[i].LEDRGB;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
info.Copter.LEDColor = LEDRGB;
|
info.Copter.LEDColor = LEDRGB;
|
||||||
///灯光控制结束
|
///灯光控制结束
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//起飞完成用默认颜色
|
//起飞完成用默认颜色
|
||||||
info.Copter.LEDColor = CopterManager.CopterFlyingColor;
|
info.Copter.LEDColor = CopterManager.CopterFlyingColor;
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
//老方案 ----- 按起飞数量起飞
|
||||||
//老方案 ----- 按起飞数量起飞
|
// 几架飞机同时起飞,参数为takeOffCount-----------------使用中
|
||||||
// 几架飞机同时起飞,参数为takeOffCount-----------------使用中
|
//起飞分三个阶段:
|
||||||
//起飞分三个阶段:
|
//1阶段:分批起飞到15米(目前15米高度是飞控起飞航点决定),上一批起飞超过5米下一批开始起飞,
|
||||||
//1阶段:分批起飞到15米(目前15米高度是飞控起飞航点决定),上一批起飞超过5米下一批开始起飞,
|
// 等待全部起飞完成后执行第二阶段,
|
||||||
// 等待全部起飞完成后执行第二阶段,
|
//2阶段:等待高度超过9米(可能已到达15米)然后平飞到第一个航点位置,高度为15米的位置,
|
||||||
//2阶段:等待高度超过9米(可能已到达15米)然后平飞到第一个航点位置,高度为15米的位置,
|
//3阶段:垂直上升到第一个航点指定高度
|
||||||
//3阶段:垂直上升到第一个航点指定高度
|
//
|
||||||
//
|
//修改方案:针对高度
|
||||||
//修改方案:针对高度
|
//1.上升到起飞高度(目前没有地面站设置高度,高度在飞控中)
|
||||||
//1.上升到起飞高度(目前没有地面站设置高度,高度在飞控中)
|
//2.直接飞往第一个航点的高度
|
||||||
//2.直接飞往第一个航点的高度
|
public async Task MutilRunTakeOffTaskAsync()
|
||||||
public async Task MutilRunTakeOffTaskAsync()
|
{
|
||||||
{
|
|
||||||
|
int TaskCount = _flightTaskManager.Tasks.Count();
|
||||||
int TaskCount = _flightTaskManager.Tasks.Count();
|
if (TaskCount > 1)
|
||||||
if (TaskCount > 1)
|
{
|
||||||
{
|
var infos = SingleCopterInfos;
|
||||||
var infos = SingleCopterInfos;
|
|
||||||
|
//不再使用起飞数量 强制设置起飞总数等于所有飞机
|
||||||
//不再使用起飞数量 强制设置起飞总数等于所有飞机
|
int takeOffCount = _copterManager.Copters.Count();
|
||||||
int takeOffCount = _copterManager.Copters.Count();
|
int copterCount = infos.Count;
|
||||||
int copterCount = infos.Count;
|
int integerPart = copterCount / takeOffCount;
|
||||||
int integerPart = copterCount / takeOffCount;
|
int residualPart = copterCount % takeOffCount;
|
||||||
int residualPart = copterCount % takeOffCount;
|
|
||||||
|
// var tasks = new Task[infos.Count];
|
||||||
// var tasks = new Task[infos.Count];
|
var tasksTmp = new Task[infos.Count];
|
||||||
var tasksTmp = new Task[infos.Count];
|
for (int i = 0; i < integerPart; i++)
|
||||||
for (int i = 0; i < integerPart; i++)
|
{
|
||||||
{
|
var tasksTakeOff = new Task[takeOffCount];
|
||||||
var tasksTakeOff = new Task[takeOffCount];
|
//执行n架同时起飞
|
||||||
//执行n架同时起飞
|
for (int j = takeOffCount * i; j < takeOffCount * (i + 1); j++)
|
||||||
for (int j = takeOffCount * i; j < takeOffCount * (i + 1); j++)
|
{
|
||||||
{
|
var info = infos[j];
|
||||||
var info = infos[j];
|
|
||||||
|
int indexTmp = j - takeOffCount * i;
|
||||||
int indexTmp = j - takeOffCount * i;
|
if (info.takeOffStage == 0) // 第一阶段:起飞到15m
|
||||||
if (info.takeOffStage == 0) // 第一阶段:起飞到15m
|
{
|
||||||
{
|
tasksTakeOff[indexTmp] = TakeOffTaskFlySingleCopterAsync(info);
|
||||||
tasksTakeOff[indexTmp] = TakeOffTaskFlySingleCopterAsync(info);
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
tasksTakeOff[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||||
tasksTakeOff[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
}
|
||||||
}
|
}
|
||||||
}
|
//等待多架起飞任务-起飞高度超过5米完成
|
||||||
//等待多架起飞任务-起飞高度超过5米完成
|
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
||||||
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
//加入已起飞飞机的第二第三阶段起飞任务--并不执行
|
||||||
//加入已起飞飞机的第二第三阶段起飞任务--并不执行
|
for (int j = takeOffCount * i; j < takeOffCount * (i + 1); j++)
|
||||||
for (int j = takeOffCount * i; j < takeOffCount * (i + 1); j++)
|
{
|
||||||
{
|
var info = infos[j];
|
||||||
var info = infos[j];
|
tasksTmp[j] = TakeOffSecondTaskAsync(info); // 第二和第三阶段
|
||||||
tasksTmp[j] = TakeOffSecondTaskAsync(info); // 第二和第三阶段
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// 余数架飞机同时起飞
|
||||||
// 余数架飞机同时起飞
|
if (residualPart > 0)
|
||||||
if (residualPart > 0)
|
{
|
||||||
{
|
var tasksTakeOff = new Task[residualPart];
|
||||||
var tasksTakeOff = new Task[residualPart];
|
for (int j = integerPart * takeOffCount; j < takeOffCount * integerPart + residualPart; j++)
|
||||||
for (int j = integerPart * takeOffCount; j < takeOffCount * integerPart + residualPart; j++)
|
{
|
||||||
{
|
var info = infos[j];
|
||||||
var info = infos[j];
|
|
||||||
|
int indexTmp = j - takeOffCount * integerPart;
|
||||||
int indexTmp = j - takeOffCount * integerPart;
|
if (info.takeOffStage == 0) // 第一阶段:起飞到15m
|
||||||
if (info.takeOffStage == 0) // 第一阶段:起飞到15m
|
{
|
||||||
{
|
tasksTakeOff[indexTmp] = TakeOffTaskFlySingleCopterAsync(info);
|
||||||
tasksTakeOff[indexTmp] = TakeOffTaskFlySingleCopterAsync(info);
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
tasksTakeOff[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||||
tasksTakeOff[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
}
|
||||||
}
|
}
|
||||||
}
|
//等待起飞超过5米
|
||||||
//等待起飞超过5米
|
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
||||||
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
|
||||||
|
for (int j = integerPart * takeOffCount; j < takeOffCount * integerPart + residualPart; j++)
|
||||||
for (int j = integerPart * takeOffCount; j < takeOffCount * integerPart + residualPart; j++)
|
{
|
||||||
{
|
var info = infos[j];
|
||||||
var info = infos[j];
|
tasksTmp[j] = TakeOffSecondTaskAsync(info); // 加入第二和第三阶段
|
||||||
tasksTmp[j] = TakeOffSecondTaskAsync(info); // 加入第二和第三阶段
|
}
|
||||||
}
|
}
|
||||||
}
|
//执行并等待所有的第二第三阶段起飞任务完成
|
||||||
//执行并等待所有的第二第三阶段起飞任务完成
|
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
|
||||||
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
|
if (_flightTaskManager.IsPaused == false)
|
||||||
if (_flightTaskManager.IsPaused == false)
|
{
|
||||||
{
|
for (int i = 0; i < infos.Count; i++)
|
||||||
for (int i = 0; i < infos.Count; i++)
|
{
|
||||||
{
|
var info = infos[i];
|
||||||
var info = infos[i];
|
info.takeOffStage = 0;
|
||||||
info.takeOffStage = 0;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||||
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
|
||||||
|
//执行第一阶段解锁起飞任务---使用中
|
||||||
//执行第一阶段解锁起飞任务---使用中
|
private async Task TakeOffTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
|
||||||
private async Task TakeOffTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
|
{
|
||||||
{
|
DateTime dtNow = DateTime.Now;
|
||||||
DateTime dtNow = DateTime.Now;
|
DateTime dtLastTime = DateTime.Now;
|
||||||
DateTime dtLastTime = DateTime.Now;
|
TimeSpan ts = dtNow - dtLastTime;
|
||||||
TimeSpan ts = dtNow - dtLastTime;
|
|
||||||
|
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
var copter = info.Copter;
|
||||||
var copter = info.Copter;
|
var copterNextTask = _flightTaskManager.Tasks[1].SingleCopterInfos[copterIndex];
|
||||||
var copterNextTask = _flightTaskManager.Tasks[1].SingleCopterInfos[copterIndex];
|
|
||||||
|
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
return;
|
||||||
return;
|
|
||||||
|
if (_flightTaskManager.IsPaused == true)
|
||||||
if (_flightTaskManager.IsPaused == true)
|
{
|
||||||
{
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
//设置灯光
|
||||||
//设置灯光
|
await copter.SetShowLEDAsync(true);
|
||||||
await copter.SetShowLEDAsync(true);
|
|
||||||
|
//开始解锁
|
||||||
//开始解锁
|
await copter.UnlockAsync();
|
||||||
await copter.UnlockAsync();
|
for (int i = 0; !copter.IsUnlocked; i++)
|
||||||
for (int i = 0; !copter.IsUnlocked; i++)
|
{
|
||||||
{
|
//if (_flightTaskManager.IsPaused == true)
|
||||||
//if (_flightTaskManager.IsPaused == true)
|
//{
|
||||||
//{
|
// return;
|
||||||
// return;
|
//}
|
||||||
//}
|
//8秒内每1000毫秒尝试解锁一次
|
||||||
//8秒内每1000毫秒尝试解锁一次
|
//解锁间隔一定要超过1s否则导致飞控以后无法解锁
|
||||||
//解锁间隔一定要超过1s否则导致飞控以后无法解锁
|
|
||||||
|
if (i > 320)
|
||||||
if (i > 320)
|
return; //无法解锁后面不用执行了
|
||||||
return; //无法解锁后面不用执行了
|
if (i % (1000 / 25) == 1000 / 25 - 1)
|
||||||
if (i % (1000 / 25) == 1000 / 25 - 1)
|
{
|
||||||
{
|
await copter.UnlockAsync(); // 每 1000 毫秒重试一次。
|
||||||
await copter.UnlockAsync(); // 每 1000 毫秒重试一次。
|
}
|
||||||
}
|
|
||||||
|
await Task.Delay(25).ConfigureAwait(false);
|
||||||
await Task.Delay(25).ConfigureAwait(false);
|
}
|
||||||
}
|
//////解锁完成
|
||||||
//////解锁完成
|
|
||||||
|
// 为了返航,记录家的位置, 应该放在起飞命令
|
||||||
// 为了返航,记录家的位置, 应该放在起飞命令
|
info.TargetLat = info.Copter.Latitude;
|
||||||
info.TargetLat = info.Copter.Latitude;
|
info.TargetLng = info.Copter.Longitude;
|
||||||
info.TargetLng = info.Copter.Longitude;
|
|
||||||
|
//等待起飞时间
|
||||||
//等待起飞时间
|
while (ts.TotalMilliseconds < info.TakeOffWaitTime * 1000 )
|
||||||
while (ts.TotalMilliseconds < info.TakeOffWaitTime * 1000 )
|
{
|
||||||
{
|
await Task.Delay(100);
|
||||||
await Task.Delay(100);
|
dtNow = DateTime.Now;
|
||||||
dtNow = DateTime.Now;
|
ts = dtNow - dtLastTime;
|
||||||
ts = dtNow - dtLastTime;
|
}
|
||||||
}
|
|
||||||
|
//开始起飞
|
||||||
//开始起飞
|
for (int i = 0; i < 5; i++) // added by ZJF
|
||||||
for (int i = 0; i < 5; i++) // added by ZJF
|
{
|
||||||
{
|
await copter.TakeOffAsync();
|
||||||
await copter.TakeOffAsync();
|
await Task.Delay(50).ConfigureAwait(false);
|
||||||
await Task.Delay(50).ConfigureAwait(false);
|
}
|
||||||
}
|
|
||||||
|
// while (copter.Altitude < 4 || copter.State == Copters.CopterState.TakingOff)
|
||||||
// while (copter.Altitude < 4 || copter.State == Copters.CopterState.TakingOff)
|
//低于5米任务一直等待
|
||||||
//低于5米任务一直等待
|
while (copter.Altitude < 5) // 修改起飞逻辑,当高度达到5米时,下一架开始起飞
|
||||||
while (copter.Altitude < 5) // 修改起飞逻辑,当高度达到5米时,下一架开始起飞
|
{
|
||||||
{
|
if (_flightTaskManager.IsPaused == true)
|
||||||
if (_flightTaskManager.IsPaused == true)
|
{
|
||||||
{
|
await info.Copter.HoverAsync();
|
||||||
await info.Copter.HoverAsync();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
await Task.Delay(100).ConfigureAwait(false);
|
||||||
await Task.Delay(100).ConfigureAwait(false);
|
}
|
||||||
}
|
|
||||||
|
/* //先不要这个控制看能否正常工作
|
||||||
/* //先不要这个控制看能否正常工作
|
if (copter.Altitude > 8)
|
||||||
if (copter.Altitude > 8)
|
{
|
||||||
{
|
await info.Copter.GuidAsync();
|
||||||
await info.Copter.GuidAsync();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
*/
|
||||||
*/
|
}
|
||||||
}
|
|
||||||
|
//执行第二第三阶段起飞任务-------------使用中
|
||||||
//执行第二第三阶段起飞任务-------------使用中
|
private async Task TakeOffSecondTaskAsync(FlightTaskSingleCopterInfo info)
|
||||||
private async Task TakeOffSecondTaskAsync(FlightTaskSingleCopterInfo info)
|
{
|
||||||
{
|
|
||||||
|
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
var copterNextTask = _flightTaskManager.Tasks[1].SingleCopterInfos[copterIndex];
|
||||||
var copterNextTask = _flightTaskManager.Tasks[1].SingleCopterInfos[copterIndex];
|
float takeOffAlt = copterNextTask.TargetAlt;// 15; 起飞高度到下个任务的高度
|
||||||
float takeOffAlt = copterNextTask.TargetAlt;// 15; 起飞高度到下个任务的高度
|
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
{
|
||||||
{
|
await info.Copter.HoverAsync();
|
||||||
await info.Copter.HoverAsync();
|
return;
|
||||||
return;
|
} // await Task.Run(async () =>
|
||||||
} // await Task.Run(async () =>
|
// {
|
||||||
// {
|
// 小于9米时等待----按起飞高度算此时可能已到达15米起飞高度
|
||||||
// 小于9米时等待----按起飞高度算此时可能已到达15米起飞高度
|
if (info.takeOffStage == 0)
|
||||||
if (info.takeOffStage == 0)
|
{
|
||||||
{
|
while (info.Copter.Altitude < 9)
|
||||||
while (info.Copter.Altitude < 9)
|
{
|
||||||
{
|
if (_flightTaskManager.IsPaused == true)
|
||||||
if (_flightTaskManager.IsPaused == true)
|
{
|
||||||
{
|
await info.Copter.HoverAsync();
|
||||||
await info.Copter.HoverAsync();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
await Task.Delay(100).ConfigureAwait(false);
|
||||||
await Task.Delay(100).ConfigureAwait(false);
|
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
{
|
||||||
{
|
await info.Copter.HoverAsync();
|
||||||
await info.Copter.HoverAsync();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
}
|
if (_flightTaskManager.IsPaused == false)
|
||||||
if (_flightTaskManager.IsPaused == false)
|
{
|
||||||
{
|
info.takeOffStage++;
|
||||||
info.takeOffStage++;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
DateTime dtNow = DateTime.Now;
|
||||||
DateTime dtNow = DateTime.Now;
|
DateTime dtLastTime = DateTime.Now;
|
||||||
DateTime dtLastTime = DateTime.Now;
|
TimeSpan ts = dtNow - dtLastTime;
|
||||||
TimeSpan ts = dtNow - dtLastTime;
|
|
||||||
|
#region 屏蔽掉第二个阶段直接进入第三个阶 到达起飞高度直接飞往第一个航点
|
||||||
#region 屏蔽掉第二个阶段直接进入第三个阶 到达起飞高度直接飞往第一个航点
|
|
||||||
|
// 第二阶段:超过9米开始水平飞行
|
||||||
// 第二阶段:超过9米开始水平飞行
|
if (info.takeOffStage == 1)
|
||||||
if (info.takeOffStage == 1)
|
{
|
||||||
{
|
//切换到guided模式
|
||||||
//切换到guided模式
|
await info.Copter.GuidAsync();
|
||||||
await info.Copter.GuidAsync();
|
//设置灯光为航点要求的灯光
|
||||||
//设置灯光为航点要求的灯光
|
await info.Copter.SetShowLEDAsync(copterNextTask.FlytoShowLED );
|
||||||
await info.Copter.SetShowLEDAsync(copterNextTask.FlytoShowLED );
|
//异步执行飞到第一个航点高度固定为15米的任务
|
||||||
//异步执行飞到第一个航点高度固定为15米的任务
|
for (int j = 0; j < 3; j++)
|
||||||
for (int j = 0; j < 3; j++)
|
{
|
||||||
{
|
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
|
||||||
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
|
await Task.Delay(10).ConfigureAwait(false);
|
||||||
await Task.Delay(10).ConfigureAwait(false);
|
}
|
||||||
}
|
//直到到达第一个航点并高度15米
|
||||||
//直到到达第一个航点并高度15米
|
while (!info.Copter.ArrivedTarget(info.TargetLat, info.TargetLng, takeOffAlt))
|
||||||
while (!info.Copter.ArrivedTarget(info.TargetLat, info.TargetLng, takeOffAlt))
|
{
|
||||||
{
|
if (_flightTaskManager.IsPaused == true)
|
||||||
if (_flightTaskManager.IsPaused == true)
|
{
|
||||||
{
|
await info.Copter.HoverAsync();
|
||||||
await info.Copter.HoverAsync();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
await Task.Delay(25).ConfigureAwait(false);
|
||||||
await Task.Delay(25).ConfigureAwait(false);
|
|
||||||
|
dtNow = DateTime.Now;
|
||||||
dtNow = DateTime.Now;
|
ts = dtNow - dtLastTime;
|
||||||
ts = dtNow - dtLastTime;
|
//每2秒再异步执行一次到航点高度15米的任务
|
||||||
//每2秒再异步执行一次到航点高度15米的任务
|
if (ts.TotalMilliseconds > 2000)
|
||||||
if (ts.TotalMilliseconds > 2000)
|
{
|
||||||
{
|
for (int j = 0; j < 2; j++)
|
||||||
for (int j = 0; j < 2; j++)
|
{
|
||||||
{
|
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
|
||||||
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
|
await Task.Delay(10).ConfigureAwait(false);
|
||||||
await Task.Delay(10).ConfigureAwait(false);
|
}
|
||||||
}
|
dtLastTime = dtNow;
|
||||||
dtLastTime = dtNow;
|
}
|
||||||
}
|
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
{
|
||||||
{
|
await info.Copter.HoverAsync();
|
||||||
await info.Copter.HoverAsync();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
}
|
if (_flightTaskManager.IsPaused == false)
|
||||||
if (_flightTaskManager.IsPaused == false)
|
{
|
||||||
{
|
info.takeOffStage++; //当前变为2
|
||||||
info.takeOffStage++; //当前变为2
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
dtNow = DateTime.Now;
|
||||||
dtNow = DateTime.Now;
|
dtLastTime = DateTime.Now;
|
||||||
dtLastTime = DateTime.Now;
|
ts = dtNow - dtLastTime;
|
||||||
ts = dtNow - dtLastTime;
|
|
||||||
|
#endregion
|
||||||
#endregion
|
|
||||||
|
info.takeOffStage++;
|
||||||
info.takeOffStage++;
|
|
||||||
|
// 第三阶段:从第一个航点位置15米垂直飞行
|
||||||
// 第三阶段:从第一个航点位置15米垂直飞行
|
if (info.takeOffStage == 2)
|
||||||
if (info.takeOffStage == 2)
|
{
|
||||||
{
|
//执行飞到第一个航点高度为设定目标高度
|
||||||
//执行飞到第一个航点高度为设定目标高度
|
for (int j = 0; j < 3; j++)
|
||||||
for (int j = 0; j < 3; j++)
|
{
|
||||||
{
|
await info.Copter.FlyToAsync(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt);
|
||||||
await info.Copter.FlyToAsync(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt);
|
await Task.Delay(10).ConfigureAwait(false);
|
||||||
await Task.Delay(10).ConfigureAwait(false);
|
}
|
||||||
}
|
//直到到达第一个航点
|
||||||
//直到到达第一个航点
|
while (!info.Copter.ArrivedTarget(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt))
|
||||||
while (!info.Copter.ArrivedTarget(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt))
|
{
|
||||||
{
|
if (_flightTaskManager.IsPaused == true)
|
||||||
if (_flightTaskManager.IsPaused == true)
|
{
|
||||||
{
|
await info.Copter.HoverAsync();
|
||||||
await info.Copter.HoverAsync();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
await Task.Delay(25).ConfigureAwait(false);
|
||||||
await Task.Delay(25).ConfigureAwait(false);
|
|
||||||
|
dtNow = DateTime.Now;
|
||||||
dtNow = DateTime.Now;
|
ts = dtNow - dtLastTime;
|
||||||
ts = dtNow - dtLastTime;
|
//每2秒发一次第一个航点飞行任务
|
||||||
//每2秒发一次第一个航点飞行任务
|
if (ts.TotalMilliseconds > 2000)
|
||||||
if (ts.TotalMilliseconds > 2000)
|
{
|
||||||
{
|
for (int j = 0; j < 2; j++)
|
||||||
for (int j = 0; j < 2; j++)
|
{
|
||||||
{
|
await info.Copter.FlyToAsync(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt);
|
||||||
await info.Copter.FlyToAsync(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt);
|
await Task.Delay(10).ConfigureAwait(false);
|
||||||
await Task.Delay(10).ConfigureAwait(false);
|
}
|
||||||
}
|
dtLastTime = dtNow;
|
||||||
dtLastTime = dtNow;
|
}
|
||||||
}
|
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
{
|
||||||
{
|
await info.Copter.HoverAsync();
|
||||||
await info.Copter.HoverAsync();
|
return;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// });
|
||||||
// });
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,235 +1,238 @@
|
|||||||
<UserControl x:Class="Plane.FormationCreator.Views.ControlPanelView"
|
<UserControl x:Class="Plane.FormationCreator.Views.ControlPanelView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||||
xmlns:fc="clr-namespace:Plane.FormationCreator"
|
xmlns:fc="clr-namespace:Plane.FormationCreator"
|
||||||
xmlns:ec="clr-namespace:Plane.Copters;assembly=PlaneGcsSdk_Private_NET46"
|
xmlns:ec="clr-namespace:Plane.Copters;assembly=PlaneGcsSdk_Private_NET46"
|
||||||
xmlns:vm="clr-namespace:Plane.FormationCreator.ViewModels"
|
xmlns:vm="clr-namespace:Plane.FormationCreator.ViewModels"
|
||||||
xmlns:m="clr-namespace:Plane.FormationCreator.Formation"
|
xmlns:m="clr-namespace:Plane.FormationCreator.Formation"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="300"
|
d:DesignHeight="300"
|
||||||
d:DesignWidth="300">
|
d:DesignWidth="300">
|
||||||
|
|
||||||
<StackPanel Margin="0,0,-8,0">
|
<StackPanel Margin="0,0,-8,0">
|
||||||
<StackPanel.Resources>
|
<StackPanel.Resources>
|
||||||
<Style TargetType="Button"
|
<Style TargetType="Button"
|
||||||
BasedOn="{StaticResource {x:Type Button}}">
|
BasedOn="{StaticResource {x:Type Button}}">
|
||||||
<Setter Property="Margin"
|
<Setter Property="Margin"
|
||||||
Value="0,0,3,5" />
|
Value="0,0,3,5" />
|
||||||
</Style>
|
</Style>
|
||||||
</StackPanel.Resources>
|
</StackPanel.Resources>
|
||||||
|
|
||||||
<!--<TextBlock Text="连接" />
|
<!--<TextBlock Text="连接" />
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
<Button Content="连接"
|
<Button Content="连接"
|
||||||
Command="{Binding ConnectCommand}" />
|
Command="{Binding ConnectCommand}" />
|
||||||
<Button Content="断开"
|
<Button Content="断开"
|
||||||
Command="{Binding DisconnectCommand}" />
|
Command="{Binding DisconnectCommand}" />
|
||||||
</WrapPanel>-->
|
</WrapPanel>-->
|
||||||
|
|
||||||
|
|
||||||
<TabControl Margin="0,0,13,0">
|
<TabControl Margin="0,0,13,0">
|
||||||
<TabItem Header="飞行前准备">
|
<TabItem Header="飞行前准备">
|
||||||
|
|
||||||
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
|
|
||||||
<Button Content="电压检测"
|
<Button Content="电压检测"
|
||||||
Command="{Binding DetectionVoltage}" />
|
Command="{Binding DetectionVoltage}" />
|
||||||
<Button Content="版本检测"
|
<Button Content="版本检测"
|
||||||
Command="{Binding GetVersionsCommand}" />
|
Command="{Binding GetVersionsCommand}" />
|
||||||
<Button Content="通讯版本" Command="{Binding DetectionCommModuleVersion}" />
|
<Button Content="通讯版本" Command="{Binding DetectionCommModuleVersion}" />
|
||||||
<Button Content="统计返回"
|
<Button Content="统计返回"
|
||||||
Command="{Binding DetectionReturnData}" />
|
Command="{Binding DetectionReturnData}" />
|
||||||
<Button Content="通讯统计"
|
<Button Content="通讯统计"
|
||||||
Command="{Binding GetCommsumCommand}" />
|
Command="{Binding GetCommsumCommand}" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="5,5,5,5" Foreground ="Red" VerticalAlignment="Center"
|
Margin="5,5,5,5" Foreground ="Red" VerticalAlignment="Center"
|
||||||
Text="{Binding RTKState}"
|
Text="{Binding RTKState}"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
<Button Content="参数设置"
|
<Button Content="参数设置"
|
||||||
Command="{Binding ParamModify}" />
|
Command="{Binding ParamModify}" />
|
||||||
<Button Content="读入参数"
|
<Button Content="读入参数"
|
||||||
Command="{Binding LoadParamfile}" />
|
Command="{Binding LoadParamfile}" />
|
||||||
<Button Content="状态统计" Command="{Binding ReportGPSTypeCommand}"/>
|
<Button Content="状态统计" Command="{Binding ReportGPSTypeCommand}"/>
|
||||||
<Button Content="飞机校准"
|
<Button Content="飞机校准"
|
||||||
Command="{Binding CalibrationSingleCommand}" />
|
Command="{Binding CalibrationSingleCommand}" />
|
||||||
<Button Content="正式参数" Command="{Binding TurnOffTestLightsCommand}" Visibility="Collapsed" />
|
<Button Content="正式参数" Command="{Binding TurnOffTestLightsCommand}" Visibility="Collapsed" />
|
||||||
|
|
||||||
<Button Content="电机" Visibility="Collapsed"
|
<Button Content="电机" Visibility="Collapsed"
|
||||||
|
|
||||||
Command="{Binding MotorTestCommand}" />
|
Command="{Binding MotorTestCommand}" />
|
||||||
|
|
||||||
|
|
||||||
<Button Content="删除飞机"
|
<Button Content="删除飞机"
|
||||||
|
|
||||||
Command="{Binding DelCommand}" />
|
Command="{Binding DelCommand}" />
|
||||||
|
|
||||||
<Label Visibility="Collapsed" Content="Lat"/>
|
<Label Visibility="Collapsed" Content="Lat"/>
|
||||||
<TextBox Visibility="Collapsed" Text="{Binding LatOffset}" Width="50"/>
|
<TextBox Visibility="Collapsed" Text="{Binding LatOffset}" Width="50"/>
|
||||||
<Label Visibility="Collapsed" Content="Lng"/>
|
<Label Visibility="Collapsed" Content="Lng"/>
|
||||||
<TextBox Visibility="Collapsed" Text="{Binding LngOffset}" Width="50"/>
|
<TextBox Visibility="Collapsed" Text="{Binding LngOffset}" Width="50"/>
|
||||||
<Button Visibility="Collapsed" Content="设置返航点" Command="{Binding RLTOffsetCommand}" />
|
<Button Visibility="Collapsed" Content="设置返航点" Command="{Binding RLTOffsetCommand}" />
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
|
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
<Button Content="写入航点"
|
<Button Content="写入航点"
|
||||||
Command="{Binding WriteMissionCommand}" />
|
Command="{Binding WriteMissionCommand}" />
|
||||||
<Button Content="航点续写"
|
<Button Content="航点续写"
|
||||||
Command="{Binding WriteMissionFailedCommand}" />
|
Command="{Binding WriteMissionFailedCommand}" />
|
||||||
<Button Content="选写航点" Command="{Binding WriteMissionSingleCommand}" />
|
<Button Content="选写航点" Command="{Binding WriteMissionSingleCommand}" />
|
||||||
<Button Content="统计航点"
|
<Button Content="统计航点"
|
||||||
Command="{Binding DetectionMissionData}" />
|
Command="{Binding DetectionMissionData}" />
|
||||||
<TextBox
|
<TextBox
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="55"
|
Width="55"
|
||||||
Margin="5, 5, 5, 5"
|
Margin="5, 5, 5, 5"
|
||||||
HorizontalContentAlignment="Right"
|
HorizontalContentAlignment="Right"
|
||||||
|
|
||||||
Text="{Binding RTKcomvalue, UpdateSourceTrigger=PropertyChanged}" Visibility="Collapsed"
|
Text="{Binding RTKcomvalue, UpdateSourceTrigger=PropertyChanged}" Visibility="Collapsed"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button Content="{Binding RTKbtntxt}"
|
<Button Content="{Binding RTKbtntxt}"
|
||||||
Command="{Binding SendRTKCommand}" Visibility="Collapsed" />
|
Command="{Binding SendRTKCommand}" Visibility="Collapsed" />
|
||||||
|
|
||||||
<Button Content="{Binding NTRIPbtntxt}"
|
<Button Content="{Binding NTRIPbtntxt}"
|
||||||
Command="{Binding SendRTCMCommand}" Visibility="Collapsed"/>
|
Command="{Binding SendRTCMCommand}" Visibility="Collapsed"/>
|
||||||
|
|
||||||
<Button Content="RTK 控制" Command="{Binding OpenRtcmManageCommand}" />
|
<Button Content="RTK 控制" Command="{Binding OpenRtcmManageCommand}" />
|
||||||
|
|
||||||
|
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
|
|
||||||
<TabItem Header="飞行控制">
|
<TabItem Header="飞行控制">
|
||||||
|
|
||||||
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
||||||
<WrapPanel >
|
<WrapPanel >
|
||||||
<Button Content="解锁"
|
<Button Content="解锁"
|
||||||
Command="{Binding UnlockCommand}" />
|
Command="{Binding UnlockCommand}" />
|
||||||
<Button Content="加锁"
|
<Button Content="加锁"
|
||||||
Command="{Binding LockCommand}" />
|
Command="{Binding LockCommand}" />
|
||||||
<Button Content="单独任务"
|
<Button Content="单独任务"
|
||||||
Command="{Binding TakeOffCommand}" />
|
Command="{Binding TakeOffCommand}" />
|
||||||
|
|
||||||
<Button Content="抛物"
|
<Button Content="抛物"
|
||||||
Command="{Binding ThrowoutCommand}" />
|
Command="{Binding ThrowoutCommand}" />
|
||||||
|
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
<Button Content="起飞"
|
<Button Content="起飞"
|
||||||
Command="{Binding GuidAsyncCommand}" />
|
Command="{Binding GuidAsyncCommand}" />
|
||||||
<Button Content="悬停"
|
<Button Content="悬停"
|
||||||
Command="{Binding HoverCommand}" />
|
Command="{Binding HoverCommand}" />
|
||||||
<Button Content="手动"
|
<Button Content="手动"
|
||||||
Command="{Binding FloatCommand}" />
|
Command="{Binding FloatCommand}" />
|
||||||
<Button Content="返航"
|
<Button Content="返航"
|
||||||
Command="{Binding ReturnToLaunchCommand}" />
|
Command="{Binding ReturnToLaunchCommand}" />
|
||||||
<Button Content="降落"
|
<Button Content="降落"
|
||||||
Command="{Binding LandCommand}" />
|
Command="{Binding LandCommand}" />
|
||||||
|
|
||||||
<Button Content="跳过" Visibility="Collapsed"
|
<Button Content="跳过" Visibility="Collapsed"
|
||||||
Command="{Binding FlagCommand}" />
|
Command="{Binding FlagCommand}" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<TextBox Width="50"
|
<TextBox Width="50"
|
||||||
Visibility="Collapsed"
|
Visibility="Collapsed"
|
||||||
Text="{Binding AltP, UpdateSourceTrigger=PropertyChanged}" />
|
Text="{Binding AltP, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
|
|
||||||
|
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
<Button Content="闪灯"
|
<Button Content="闪灯"
|
||||||
Command="{Binding LEDFlickerCommand}" />
|
Command="{Binding LEDFlickerCommand}" />
|
||||||
<Button Content="测试" Visibility="Collapsed"
|
<Button Content="测试" Visibility="Collapsed"
|
||||||
Command="{Binding TestCommand}" />
|
Command="{Binding TestCommand}" />
|
||||||
<Button Content="开灯"
|
<Button Content="开灯"
|
||||||
Command="{Binding LEDOnOffCommand}"
|
Command="{Binding LEDOnOffCommand}"
|
||||||
CommandParameter="0"/>
|
CommandParameter="0"/>
|
||||||
<Button Content="关灯"
|
<Button Content="关灯"
|
||||||
Command="{Binding LEDOnOffCommand}"
|
Command="{Binding LEDOnOffCommand}"
|
||||||
CommandParameter="1"/>
|
CommandParameter="1"/>
|
||||||
<TextBlock Margin="8,-3,5,0" Text="起飞高度" VerticalAlignment="Center"/>
|
<TextBlock Margin="8,-3,5,0" Text="起飞高度" VerticalAlignment="Center"/>
|
||||||
<TextBox VerticalContentAlignment="Center" Margin="0,0,0,5" Width="30" Height="25" Text="{Binding TaskOffAlt}" />
|
<TextBox VerticalContentAlignment="Center" Margin="0,0,0,5" Width="30" Height="25" Text="{Binding TaskOffAlt}" />
|
||||||
<TextBlock Margin="5,-3,5,0" Text="米" VerticalAlignment="Center"/>
|
<TextBlock Margin="5,-3,5,0" Text="米" VerticalAlignment="Center"/>
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
|
|
||||||
<TabItem Header="任务控制">
|
<TabItem Header="任务控制">
|
||||||
|
|
||||||
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
|
|
||||||
<Button Content="全部解锁"
|
<Button Content="全部解锁"
|
||||||
Command="{Binding UnlockAllCommand}"
|
Command="{Binding UnlockAllCommand}"
|
||||||
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}" />
|
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
<Button Content="全部加锁"
|
<Button Content="全部加锁"
|
||||||
Command="{Binding LockAllCommand}" />
|
Command="{Binding LockAllCommand}" />
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
|
|
||||||
<Button Content="开始任务"
|
<Button Content="开始任务"
|
||||||
Command="{Binding MissionStartCommand}"
|
Command="{Binding MissionStartCommand}"
|
||||||
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}"/>
|
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}"/>
|
||||||
<Button Content="暂停任务"
|
<Button Content="暂停任务"
|
||||||
Command="{Binding MissionPauseCommand}" />
|
Command="{Binding MissionPauseCommand}" />
|
||||||
<Button Content="继续任务"
|
<Button Content="继续任务"
|
||||||
Command="{Binding MissionResumeCommand}" />
|
Command="{Binding MissionResumeCommand}" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</WrapPanel>
|
</WrapPanel>
|
||||||
|
|
||||||
<WrapPanel>
|
<WrapPanel>
|
||||||
|
|
||||||
<Button Content="全部降落"
|
<Button Content="全部降落"
|
||||||
Command="{Binding AllLandCommand}" />
|
Command="{Binding AllLandCommand}" />
|
||||||
|
<Button Content="紧急返航"
|
||||||
</WrapPanel>
|
Command="{Binding EmergencyRetCommand}" />
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
</TabItem>
|
</WrapPanel>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
<TabItem Header="飞行报告" Visibility="Collapsed">
|
|
||||||
|
|
||||||
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
|
||||||
|
<TabItem Header="飞行报告" Visibility="Collapsed">
|
||||||
<WrapPanel>
|
|
||||||
|
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
||||||
<Button Content="添加报告"
|
|
||||||
Command="{Binding UnlockAllCommand}"
|
<WrapPanel>
|
||||||
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}" />
|
|
||||||
<Button Content="查看报告"
|
<Button Content="添加报告"
|
||||||
Command="{Binding LockAllCommand}" />
|
Command="{Binding UnlockAllCommand}"
|
||||||
</WrapPanel>
|
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
|
<Button Content="查看报告"
|
||||||
|
Command="{Binding LockAllCommand}" />
|
||||||
|
</WrapPanel>
|
||||||
|
|
||||||
|
|
||||||
</StackPanel>
|
|
||||||
</TabItem>
|
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</TabItem>
|
||||||
</TabControl>
|
|
||||||
</StackPanel>
|
|
||||||
</UserControl>
|
|
||||||
|
</TabControl>
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
||||||
|
Loading…
Reference in New Issue
Block a user