Plane.FormationCreator/Plane.FormationCreator/Formation/FlightTask_TakeOff.cs
2020-03-02 17:05:09 +08:00

477 lines
18 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.Copters;
using Microsoft.Practices.ServiceLocation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Plane.Geography;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTask
{
//起飞到第一个航点高度的飞行时间
private byte _TakeOffTime = 10;
public byte TakeOffTime
{
get { return _TakeOffTime; }
set { Set(nameof(TakeOffTime), ref _TakeOffTime, value); }
}
//一架架起飞--未使用
public async Task RunTakeOffTaskAsync()
{
// float takeOffAlt = 15;
int TaskCount = _flightTaskManager.Tasks.Count();
if (TaskCount > 1)
{
var infos = SingleCopterInfos;
// var tasks = new Task[infos.Count];
var tasksTmp = new Task[infos.Count];
for (int i = 0; i < infos.Count; i++)
{
var info = infos[i];
if (info.takeOffStage == 0) // 第一阶段起飞到10m
{
await TakeOffTaskFlySingleCopterAsync(info);
//if (_flightTaskManager.IsPaused == false)
//{
// info.takeOffStage++;
//}
}
tasksTmp[i] = TakeOffSecondTaskAsync(info); // 第二和第三阶段
}
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
if (_flightTaskManager.IsPaused == false)
{
for (int i = 0; i < infos.Count; i++)
{
var info = infos[i];
info.takeOffStage = 0;
}
}
}
}
//新版的起飞方案
public async Task NewMutilRunTakeOffTaskAsync()
{
var infos = SingleCopterInfos;
var tasksTakeOff = new Task[infos.Count];
for (int i = 0; i < infos.Count; i++)
{
//tasksTakeOff[i] = NewSingleRunTaskOffTaskAsunc(infos[i]);
tasksTakeOff[i] = await Task.Factory.StartNew(async () =>
{
var internalInfo = infos[i];
await NewSingleRunTaskOffTaskAsunc(internalInfo);
});
}
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
//await Task.Delay(100);
}
private async Task NewSingleRunTaskOffTaskAsunc(FlightTaskSingleCopterInfo info)
{
DateTime dtNow = DateTime.Now;
DateTime dtLastTime = DateTime.Now;
TimeSpan ts = dtNow - dtLastTime;
int copterIndex = SingleCopterInfos.IndexOf(info);
var copter = info.Copter;
await copter.UnlockAsync();
//等待起飞时间
while ((int)ts.TotalMilliseconds < (int)info.TakeOffWaitTime * 1000)
{
if (_flightTaskManager.IsPaused == true)
{
await copter.UnlockAsync();
await info.Copter.HoverAsync();
return;
}
await Task.Delay(100);
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
}
//虚拟飞机5秒后不起飞会自动上锁
await copter.UnlockAsync();
for (int i = 0; i < 5; i++) // added by ZJF
{
await copter.TakeOffAsync();
await Task.Delay(50).ConfigureAwait(false);
}
var copterNextTask = _flightTaskManager.Tasks[TaskIndex + 1].SingleCopterInfos[copterIndex];
float takeOffAlt = copterNextTask.TargetAlt;
info.TargetLat = info.Copter.Latitude;
info.TargetLng = info.Copter.Longitude;
// for (int j = 0; j < 3; j++)
// {
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
// await Task.Delay(10).ConfigureAwait(false);
// }
//解锁起飞用暗紫色
info.Copter.LEDColor = "FF00FF";
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
FlightTask task = _flightTaskManager.CurrentRunningTask;
while (ts.TotalMilliseconds < task.TakeOffTime * 1000)
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(100).ConfigureAwait(false);
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
}
//起飞完成用暗蓝色
info.Copter.LEDColor = "0000FF";
}
//老方案 ----- 按起飞数量起飞
// 几架飞机同时起飞参数为takeOffCount-----------------使用中
//起飞分三个阶段:
//1阶段分批起飞到15米(目前15米高度是飞控起飞航点决定)上一批起飞超过5米下一批开始起飞
// 等待全部起飞完成后执行第二阶段,
//2阶段等待高度超过9米(可能已到达15米)然后平飞到第一个航点位置,高度为15米的位置
//3阶段垂直上升到第一个航点指定高度
//
//修改方案:针对高度
//1.上升到起飞高度(目前没有地面站设置高度,高度在飞控中)
//2.直接飞往第一个航点的高度
public async Task MutilRunTakeOffTaskAsync()
{
int TaskCount = _flightTaskManager.Tasks.Count();
if (TaskCount > 1)
{
var infos = SingleCopterInfos;
//不再使用起飞数量 强制设置起飞总数等于所有飞机
int takeOffCount = _copterManager.Copters.Count();
int copterCount = infos.Count;
int integerPart = copterCount / takeOffCount;
int residualPart = copterCount % takeOffCount;
// var tasks = new Task[infos.Count];
var tasksTmp = new Task[infos.Count];
for (int i = 0; i < integerPart; i++)
{
var tasksTakeOff = new Task[takeOffCount];
//执行n架同时起飞
for (int j = takeOffCount * i; j < takeOffCount * (i + 1); j++)
{
var info = infos[j];
int indexTmp = j - takeOffCount * i;
if (info.takeOffStage == 0) // 第一阶段起飞到15m
{
tasksTakeOff[indexTmp] = TakeOffTaskFlySingleCopterAsync(info);
}
else
{
tasksTakeOff[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
}
}
//等待多架起飞任务-起飞高度超过5米完成
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
//加入已起飞飞机的第二第三阶段起飞任务--并不执行
for (int j = takeOffCount * i; j < takeOffCount * (i + 1); j++)
{
var info = infos[j];
tasksTmp[j] = TakeOffSecondTaskAsync(info); // 第二和第三阶段
}
}
// 余数架飞机同时起飞
if (residualPart > 0)
{
var tasksTakeOff = new Task[residualPart];
for (int j = integerPart * takeOffCount; j < takeOffCount * integerPart + residualPart; j++)
{
var info = infos[j];
int indexTmp = j - takeOffCount * integerPart;
if (info.takeOffStage == 0) // 第一阶段起飞到15m
{
tasksTakeOff[indexTmp] = TakeOffTaskFlySingleCopterAsync(info);
}
else
{
tasksTakeOff[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
}
}
//等待起飞超过5米
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
for (int j = integerPart * takeOffCount; j < takeOffCount * integerPart + residualPart; j++)
{
var info = infos[j];
tasksTmp[j] = TakeOffSecondTaskAsync(info); // 加入第二和第三阶段
}
}
//执行并等待所有的第二第三阶段起飞任务完成
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
if (_flightTaskManager.IsPaused == false)
{
for (int i = 0; i < infos.Count; i++)
{
var info = infos[i];
info.takeOffStage = 0;
}
}
}
}
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
//执行第一阶段解锁起飞任务---使用中
private async Task TakeOffTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
{
DateTime dtNow = DateTime.Now;
DateTime dtLastTime = DateTime.Now;
TimeSpan ts = dtNow - dtLastTime;
int copterIndex = SingleCopterInfos.IndexOf(info);
var copter = info.Copter;
var copterNextTask = _flightTaskManager.Tasks[1].SingleCopterInfos[copterIndex];
if ((bool)_copterManager.CopterStatus[copterIndex])
return;
if (_flightTaskManager.IsPaused == true)
{
return;
}
//设置灯光
await copter.SetShowLEDAsync(true);
//开始解锁
await copter.UnlockAsync();
for (int i = 0; !copter.IsUnlocked; i++)
{
//if (_flightTaskManager.IsPaused == true)
//{
// return;
//}
//8秒内每1000毫秒尝试解锁一次
//解锁间隔一定要超过1s否则导致飞控以后无法解锁
if (i > 320)
return; //无法解锁后面不用执行了
if (i % (1000 / 25) == 1000 / 25 - 1)
{
await copter.UnlockAsync(); // 每 1000 毫秒重试一次。
}
await Task.Delay(25).ConfigureAwait(false);
}
//////解锁完成
// 为了返航,记录家的位置, 应该放在起飞命令
info.TargetLat = info.Copter.Latitude;
info.TargetLng = info.Copter.Longitude;
//等待起飞时间
while (ts.TotalMilliseconds < info.TakeOffWaitTime * 1000 )
{
await Task.Delay(100);
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
}
//开始起飞
for (int i = 0; i < 5; i++) // added by ZJF
{
await copter.TakeOffAsync();
await Task.Delay(50).ConfigureAwait(false);
}
// while (copter.Altitude < 4 || copter.State == Copters.CopterState.TakingOff)
//低于5米任务一直等待
while (copter.Altitude < 5) // 修改起飞逻辑当高度达到5米时下一架开始起飞
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(100).ConfigureAwait(false);
}
/* //先不要这个控制看能否正常工作
if (copter.Altitude > 8)
{
await info.Copter.GuidAsync();
return;
}
*/
}
//执行第二第三阶段起飞任务-------------使用中
private async Task TakeOffSecondTaskAsync(FlightTaskSingleCopterInfo info)
{
int copterIndex = SingleCopterInfos.IndexOf(info);
var copterNextTask = _flightTaskManager.Tasks[1].SingleCopterInfos[copterIndex];
float takeOffAlt = copterNextTask.TargetAlt;// 15; 起飞高度到下个任务的高度
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
} // await Task.Run(async () =>
// {
// 小于9米时等待----按起飞高度算此时可能已到达15米起飞高度
if (info.takeOffStage == 0)
{
while (info.Copter.Altitude < 9)
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(100).ConfigureAwait(false);
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
}
if (_flightTaskManager.IsPaused == false)
{
info.takeOffStage++;
}
}
DateTime dtNow = DateTime.Now;
DateTime dtLastTime = DateTime.Now;
TimeSpan ts = dtNow - dtLastTime;
#region
// 第二阶段超过9米开始水平飞行
if (info.takeOffStage == 1)
{
//切换到guided模式
await info.Copter.GuidAsync();
//设置灯光为航点要求的灯光
await info.Copter.SetShowLEDAsync(copterNextTask.FlytoShowLED );
//异步执行飞到第一个航点高度固定为15米的任务
for (int j = 0; j < 3; j++)
{
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
await Task.Delay(10).ConfigureAwait(false);
}
//直到到达第一个航点并高度15米
while (!info.Copter.ArrivedTarget(info.TargetLat, info.TargetLng, takeOffAlt))
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(25).ConfigureAwait(false);
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
//每2秒再异步执行一次到航点高度15米的任务
if (ts.TotalMilliseconds > 2000)
{
for (int j = 0; j < 2; j++)
{
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
await Task.Delay(10).ConfigureAwait(false);
}
dtLastTime = dtNow;
}
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
}
if (_flightTaskManager.IsPaused == false)
{
info.takeOffStage++; //当前变为2
}
}
dtNow = DateTime.Now;
dtLastTime = DateTime.Now;
ts = dtNow - dtLastTime;
#endregion
info.takeOffStage++;
// 第三阶段从第一个航点位置15米垂直飞行
if (info.takeOffStage == 2)
{
//执行飞到第一个航点高度为设定目标高度
for (int j = 0; j < 3; j++)
{
await info.Copter.FlyToAsync(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt);
await Task.Delay(10).ConfigureAwait(false);
}
//直到到达第一个航点
while (!info.Copter.ArrivedTarget(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt))
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(25).ConfigureAwait(false);
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
//每2秒发一次第一个航点飞行任务
if (ts.TotalMilliseconds > 2000)
{
for (int j = 0; j < 2; j++)
{
await info.Copter.FlyToAsync(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt);
await Task.Delay(10).ConfigureAwait(false);
}
dtLastTime = dtNow;
}
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
}
}
// });
}
}
}