支持紧急返航
支持返回飞机错误 飞机有预解锁错误回显示黄色 支持新版低电电压参数 支持重启飞控 支持陀螺仪校准
This commit is contained in:
parent
36875bcdc2
commit
af9a86dffd
@ -75,9 +75,16 @@
|
||||
<lcnv:HeartbeatCountToBrushConverter x:Key="HeartbeatCountToBrushConverter" />
|
||||
<lcnv:AppModeToVisibilityConverter x:Key="AppModeToVisibilityConverter" />
|
||||
<lcnv:FlightTaskStatusToFillConverter x:Key="FlightTaskStatusToFillConverter" />
|
||||
<lcnv:ErrorCodeToColorConverter x:Key="ErrorCodeToColorConverter" />
|
||||
|
||||
<lcnv:PrecheckToColorConverter x:Key="PrecheckToColorConverter" />
|
||||
|
||||
<lcnv:FlightTaskStatusAndTransitionToFillConverter x:Key="FlightTaskStatusAndTransitionToFillConverter" />
|
||||
|
||||
<lcnv:FlightTaskIsSelectedToEffectConverter x:Key="FlightTaskIsSelectedToEffectConverter" />
|
||||
|
||||
|
||||
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
@ -15,25 +15,68 @@ namespace Plane.FormationCreator.Converters
|
||||
public class HeartbeatCountToBrushConverter : IMultiValueConverter
|
||||
{
|
||||
private static SolidColorBrush _zeroBrush = new SolidColorBrush(Color.FromArgb(125, 125, 125, 125));
|
||||
|
||||
private static SolidColorBrush _zeroBrush_fault = new SolidColorBrush(Color.FromRgb(160, 140, 0));
|
||||
|
||||
private static SolidColorBrush _oneBrush = Copter.DefaultBrush;
|
||||
|
||||
private static SolidColorBrush _FakeCopterBrush = Copter.DefaultFakeBrush;
|
||||
private static SolidColorBrush _PreCheckNopassBrush = Copter.YellowBrush;
|
||||
private static SolidColorBrush _NoconnectedBrush = Copter.RedBrush;
|
||||
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values[0] == DependencyProperty.UnsetValue) return _zeroBrush;
|
||||
var heartbeatCount = (ulong)values[0];
|
||||
if (heartbeatCount % 2 == 0) return _zeroBrush;
|
||||
/* //绑定的是心跳,所以连接断开时不会调用这个转换器
|
||||
//如果是真飞机,并且断开了,直接显示红色
|
||||
if (values[1] is PLCopter)
|
||||
{
|
||||
var plcopter = values[1] as PLCopter;
|
||||
if (!plcopter.CommModuleConnected)
|
||||
return _NoconnectedBrush;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//用于显示收到心跳的闪烁
|
||||
if (heartbeatCount % 2 == 0)
|
||||
{
|
||||
//真飞机如果异常显示暗淡黄色
|
||||
if (values[1] is PLCopter)
|
||||
{
|
||||
var plcopter = values[1] as PLCopter;
|
||||
if (plcopter.CopterPreCheckPass)
|
||||
return _zeroBrush;
|
||||
else return _zeroBrush_fault;
|
||||
|
||||
}
|
||||
else
|
||||
return _zeroBrush;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (values[1] is FakeCopter)
|
||||
{
|
||||
var fkcopter = values[1] as FakeCopter;
|
||||
if (fkcopter.CopterPreCheckPass)
|
||||
return _FakeCopterBrush;
|
||||
else return _PreCheckNopassBrush;
|
||||
}
|
||||
|
||||
if (values[1] is PLCopter)
|
||||
{
|
||||
var plcopter = values[1] as PLCopter;
|
||||
if (plcopter.CopterPreCheckPass)
|
||||
return _oneBrush;
|
||||
else return _PreCheckNopassBrush;
|
||||
|
||||
}
|
||||
var copter = values[1] as Copter;
|
||||
|
||||
return copter == null ? _oneBrush : copter.Brush;
|
||||
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
|
@ -62,7 +62,13 @@ namespace Plane.FormationCreator.Formation
|
||||
private SolidColorBrush _Brush;
|
||||
public SolidColorBrush Brush
|
||||
{
|
||||
get { return _Brush ?? DefaultBrush; }
|
||||
get {
|
||||
if (CopterPreCheckPass)
|
||||
return _Brush ?? DefaultBrush;
|
||||
else
|
||||
return _Brush ?? YellowBrush;
|
||||
|
||||
}
|
||||
set { Set(nameof(Brush), ref _Brush, value); }
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ using Newtonsoft.Json.Linq;
|
||||
using GMap.NET.MapProviders;
|
||||
using GMap.NET;
|
||||
using static Plane.FormationCreator.CalculationLogLatDistance;
|
||||
using Plane.CopterManagement;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
@ -412,6 +413,13 @@ namespace Plane.FormationCreator.Formation
|
||||
get { return _TaskState; }
|
||||
private set { Set(nameof(TaskState), ref _TaskState, value); }
|
||||
}
|
||||
//真实飞行任务状态
|
||||
private TasksStatus _TaskState_real = TasksStatus.Stop;
|
||||
public TasksStatus TaskState_real
|
||||
{
|
||||
get { return _TaskState_real; }
|
||||
private set { Set(nameof(TaskState_real), ref _TaskState_real, value);}
|
||||
}
|
||||
|
||||
public event EventHandler<FlightTaskAddedEventArgs> TaskAdded;
|
||||
public event EventHandler<FlightTaskDeledEventArgs> TaskDeled;
|
||||
@ -601,6 +609,7 @@ namespace Plane.FormationCreator.Formation
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 起始点作为参考,设置起始点后飞行写入的数据将为相对坐标
|
||||
/// </summary>
|
||||
@ -796,7 +805,7 @@ namespace Plane.FormationCreator.Formation
|
||||
Pause();
|
||||
//等待暂停或2s超时(80*25ms)
|
||||
int k = 0;
|
||||
while ((TaskState != TasksStatus.Paused) || (k > 80))
|
||||
while ((TaskState != TasksStatus.Paused) && (k < 80))
|
||||
{
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
k++;
|
||||
@ -2227,7 +2236,7 @@ namespace Plane.FormationCreator.Formation
|
||||
}
|
||||
|
||||
//新开线程异步调用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, List<int> mappingId = null)
|
||||
{
|
||||
List<List<FlightRouteV2.Vector3>> ret = null;
|
||||
bool isPasstmp = false;
|
||||
@ -2235,7 +2244,7 @@ namespace Plane.FormationCreator.Formation
|
||||
var task = Task.Run(() =>
|
||||
{
|
||||
cts = new CancellationTokenSource();
|
||||
ret = FlyVecFun.ABypassB(aVecs, bVecs, Routecallback, Cronograma, cts.Token, out isPasstmp);
|
||||
ret = FlyVecFun.ABypassB(aVecs, bVecs, Routecallback, Cronograma, cts.Token, out isPasstmp, mappingId);
|
||||
});
|
||||
try
|
||||
{
|
||||
@ -2277,7 +2286,7 @@ namespace Plane.FormationCreator.Formation
|
||||
|
||||
var task = Task.Run(() =>
|
||||
{
|
||||
ret = FlyVecFun.CollisionLayer(aVecs, bVecs, taskname_a, taskname_b, Routecallback);
|
||||
ret = FlyVecFun.CollisionLayer(aVecs, bVecs, Routecallback);
|
||||
});
|
||||
try
|
||||
{
|
||||
@ -2408,7 +2417,7 @@ namespace Plane.FormationCreator.Formation
|
||||
/// <summary>
|
||||
/// 自动生成航线2D和3D都用这个-------V2版使用新的碰撞检测和绕行,用flybase.cs库,只用于新版固件--------------
|
||||
/// </summary>
|
||||
/// <param name="Is3d">3D计算</param>
|
||||
/// <param name="Is3d">2D/3D计算</param>
|
||||
/// <param name="Ischange">是否改变线路的结束点顺序--返回起飞点航线不能交换</param>
|
||||
/// <param name="Is3dstagger">3D是否自动插入拉开层,用于2D画面回起飞矩阵,拉开2D画面</param>
|
||||
public async Task OptimizeRouteMeterV2(bool Is3d = false, bool Ischange = true,bool Is3dstagger=false)
|
||||
@ -2417,6 +2426,10 @@ namespace Plane.FormationCreator.Formation
|
||||
Dictionary<int, Point3D> prevTaskPoint = new Dictionary<int, Point3D>();
|
||||
var stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
//ID映射列表
|
||||
List<int> mappingId = new List<int>();
|
||||
|
||||
|
||||
|
||||
//设置随机数种子
|
||||
FlyVecFun.RandomSeed = (int)DateTime.Now.Ticks;
|
||||
@ -2435,6 +2448,8 @@ namespace Plane.FormationCreator.Formation
|
||||
var prevInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i];
|
||||
Point3D prevLoc = new Point3D(prevInfo.X * 100, prevInfo.TargetAlt * 100, prevInfo.Y * 100);
|
||||
prevTaskPoint.Add(i, prevLoc);
|
||||
//3D计算需要ID映射
|
||||
mappingId.Add(int.Parse(_copterManager.Copters[i].Id));
|
||||
}
|
||||
string taskname_a = SelectedTaskIndex.ToString() + Tasks[SelectedTaskIndex - 1].TaskCnName;
|
||||
string taskname_b = (SelectedTaskIndex+1).ToString()+SelectedTask.TaskCnName;
|
||||
@ -2473,7 +2488,9 @@ namespace Plane.FormationCreator.Formation
|
||||
if (Is3d)
|
||||
{
|
||||
bool isPass = false;
|
||||
var result= await ABypassBAsync(aVecs, bVecs);
|
||||
|
||||
|
||||
var result= await ABypassBAsync(aVecs, bVecs, mappingId);
|
||||
List<List<FlightRouteV2.Vector3>> flyret = result.Item1;
|
||||
isPass= result.Item2;
|
||||
if ((flyret.Count == 0)&&(!isPass))
|
||||
@ -2483,6 +2500,12 @@ namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
Message.Show($"任务{SelectedTaskIndex + 1}无法直接生成3D航线,尝试拉开画面");
|
||||
cVecs = await NormalPullsync(aVecs, bVecs);
|
||||
if (cVecs == null)
|
||||
{
|
||||
Message.Show($"任务不满足拉开条件,退出");
|
||||
return;
|
||||
}
|
||||
|
||||
Message.Show($"任务{SelectedTaskIndex + 1}后插入拉开层...");
|
||||
//插入错层航点
|
||||
SelectTask(SelectedTaskIndex - 1);
|
||||
@ -2498,7 +2521,7 @@ namespace Plane.FormationCreator.Formation
|
||||
SetTaskFlytime(SelectedTaskIndex);
|
||||
//选到最后一个航点
|
||||
SelectTask(SelectedTaskIndex + 1);
|
||||
var result1= await ABypassBAsync(cVecs, bVecs);
|
||||
var result1= await ABypassBAsync(cVecs, bVecs, mappingId);
|
||||
flyret = result1.Item1;
|
||||
isPass = result1.Item2;
|
||||
}
|
||||
@ -3260,9 +3283,64 @@ namespace Plane.FormationCreator.Formation
|
||||
|
||||
}
|
||||
}
|
||||
//任务飞行时长ms
|
||||
private TimeSpan _taskflyTime ;
|
||||
public TimeSpan taskflyTime
|
||||
{
|
||||
get { return _taskflyTime; }
|
||||
set { Set(nameof(taskflyTime), ref _taskflyTime, value); }
|
||||
}
|
||||
|
||||
//真实任务飞行时长ms
|
||||
private TimeSpan _taskflyTime_real;
|
||||
public TimeSpan taskflyTime_real
|
||||
{
|
||||
get { return _taskflyTime_real; }
|
||||
set { Set(nameof(taskflyTime_real), ref _taskflyTime_real, value); }
|
||||
}
|
||||
|
||||
private DateTime _taskStartTime;
|
||||
private DateTime _taskStartTime_real;
|
||||
|
||||
public DateTime TaskStartTime_real
|
||||
{
|
||||
get { return _taskStartTime_real; }
|
||||
|
||||
}
|
||||
public bool RealRunTask(DateTime taskStartTime)
|
||||
{
|
||||
if (TaskState_real == TasksStatus.Stop)
|
||||
//根据传入时间设置真实起飞时间
|
||||
{
|
||||
_taskStartTime_real = taskStartTime;
|
||||
TaskState_real = TasksStatus.Running;
|
||||
Message.Show($"{taskStartTime.ToString("HH:mm:ss")}:真实任务开始");
|
||||
return true;
|
||||
}else
|
||||
Message.Show($"任务已经开始");
|
||||
return false;
|
||||
}
|
||||
|
||||
public void RealResetTask()
|
||||
{
|
||||
TaskState_real = TasksStatus.Stop;
|
||||
|
||||
}
|
||||
|
||||
public bool SimRunTask(DateTime taskStartTime)
|
||||
{
|
||||
if (TaskState== TasksStatus.Stop)
|
||||
//根据传入时间设置真实起飞时间
|
||||
{
|
||||
_taskStartTime = taskStartTime;
|
||||
Message.Show($"{taskStartTime.ToString("HH:mm:ss")}:默认任务开始");
|
||||
return true;
|
||||
} else
|
||||
Message.Show($"任务已经开始");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
TimeSpan timeSpan;
|
||||
public DateTime taskStartTime;
|
||||
public async Task RunTaskAsync()
|
||||
{
|
||||
if (Tasks.Count == 0) return;
|
||||
@ -3290,7 +3368,12 @@ namespace Plane.FormationCreator.Formation
|
||||
|
||||
if (CurrentRunningTaskIndex == 0)
|
||||
{
|
||||
taskStartTime = DateTime.Now;
|
||||
if (!SimRunTask(DateTime.Now))
|
||||
{
|
||||
Alert.Show($"模拟任务已经开始,请先停止任务!");
|
||||
return;
|
||||
}
|
||||
|
||||
Message.Show($"{DateTime.Now.ToString("HH:mm:ss")}:任务开始");
|
||||
}
|
||||
|
||||
@ -3307,13 +3390,16 @@ namespace Plane.FormationCreator.Formation
|
||||
|
||||
|
||||
await RunAsync();
|
||||
taskflyTime = DateTime.Now - _taskStartTime;
|
||||
|
||||
if ((IsPaused ?? false) == false)
|
||||
{
|
||||
timeSpan = DateTime.Now - taskStartTime;
|
||||
Message.Show($"{DateTime.Now.ToString("HH:mm:ss")}:任务结束");
|
||||
Message.Show($"总时长 = {timeSpan.Minutes}分{timeSpan.Seconds}秒");
|
||||
|
||||
Message.Show($"总时长 = {taskflyTime.Minutes}分{taskflyTime.Seconds}秒");
|
||||
}
|
||||
else
|
||||
Message.Show($"任务暂停,总时长 = {taskflyTime.TotalSeconds}秒");
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 开始运行模拟任务
|
||||
@ -3330,12 +3416,13 @@ namespace Plane.FormationCreator.Formation
|
||||
task.Status = FlightTaskStatus.Stop;
|
||||
}
|
||||
AppEx.Current.AppMode = AppMode.RunningTasks;
|
||||
StartAvoidingCrash(); //开始碰撞检测
|
||||
|
||||
//告诉所有飞机开始任务--模拟飞机不计算起飞延迟,直接传0
|
||||
foreach (var copter in _copterManager.Copters)
|
||||
await copter.MissionStartAsync(0, 0, 0, 0, 0);
|
||||
TaskState = TasksStatus.Running;
|
||||
StartAvoidingCrash(); //开始碰撞检测
|
||||
|
||||
for (int i = CurrentRunningTaskIndex; i < Tasks.Count; i++)
|
||||
{
|
||||
var task = Tasks[i];
|
||||
@ -3474,6 +3561,7 @@ namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
rettaskindex = i;
|
||||
taskflytime = rettime - starttime;
|
||||
break;
|
||||
}
|
||||
starttime += flyedtasktime;
|
||||
}
|
||||
@ -3495,7 +3583,7 @@ namespace Plane.FormationCreator.Formation
|
||||
curLoc = TaskFlyLoc(copterprvLoc, coptercurLoc, taskflytime, Tasks[rettaskindex].FlytoTime);
|
||||
}
|
||||
else //正在悬停
|
||||
curLoc = new PLLocation(curinfo.TargetLat, curinfo.TargetLng, 0);
|
||||
curLoc = new PLLocation(curinfo.TargetLat, curinfo.TargetLng, curinfo.TargetAlt);
|
||||
|
||||
curTaskPoint.Add(i, curLoc);
|
||||
if (curinfo.TargetLat > taskmaxlat)
|
||||
@ -3557,15 +3645,22 @@ namespace Plane.FormationCreator.Formation
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 开始碰撞检测
|
||||
/// </summary>
|
||||
private async void StartAvoidingCrash()
|
||||
{
|
||||
await Task.Factory.StartNew(AvoidCrashtoshow);
|
||||
await Task.Factory.StartNew(LoopToAvoidCrash);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将碰撞显示到UI
|
||||
/// </summary>
|
||||
private async void AvoidCrashtoshow()
|
||||
{
|
||||
while (IsPaused == false)
|
||||
Message.Show("开始碰撞检测");
|
||||
while (TaskState != TasksStatus.Stop) //IsPaused == false
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -3585,10 +3680,14 @@ namespace Plane.FormationCreator.Formation
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
Message.Show("开始碰撞检测停止");
|
||||
}
|
||||
/// <summary>
|
||||
/// 循环检测碰撞
|
||||
/// </summary>
|
||||
private async void LoopToAvoidCrash()
|
||||
{
|
||||
while (IsPaused == false)
|
||||
while (TaskState != TasksStatus.Stop)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -183,6 +183,10 @@ namespace Plane.FormationCreator.Formation
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
if (_flightTaskManager.IsEmergencyRet == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
}
|
||||
|
@ -112,6 +112,8 @@ namespace Plane.FormationCreator.Formation
|
||||
info.TargetLng = info.Copter.Longitude;
|
||||
//info.Copter.takeOffTargetAltitude = takeOffAlt;
|
||||
FlightTask task = _flightTaskManager.CurrentRunningTask;
|
||||
if (task==null)
|
||||
return;
|
||||
float takeflytime = task.TakeOffTime - info.TakeOffWaitTime;
|
||||
//飞行目标,开始往上飞
|
||||
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt, takeflytime, 1); //秒
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Plane.FormationCreator.Util;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using Plane.FormationCreator.Util;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -43,7 +44,15 @@ namespace Plane.FormationCreator
|
||||
|
||||
private void Modify_Select(object sender, RoutedEventArgs e)
|
||||
{
|
||||
textParamName.Text = ((Button)sender).Tag.ToString();
|
||||
Formation.CopterManager _copterManager = ServiceLocator.Current.GetInstance<Formation.CopterManager>();
|
||||
|
||||
String strParamName = ((Button)sender).Tag.ToString();
|
||||
if (strParamName == "FS_BATT_VOLTAGE")
|
||||
{
|
||||
if (_copterManager.FC_VER_NO >= 3)
|
||||
strParamName = "BATT_LOW_VOLT";
|
||||
}
|
||||
textParamName.Text = strParamName;
|
||||
textParamName_cn.Text = ((Button)sender).Content.ToString();
|
||||
}
|
||||
|
||||
|
@ -166,6 +166,8 @@
|
||||
<Compile Include="AppEx.cs" />
|
||||
<Compile Include="AppConfig.cs" />
|
||||
<Compile Include="Converters\AppModeToVisibilityConverter.cs" />
|
||||
<Compile Include="Converters\PrecheckToColorConverter.cs" />
|
||||
<Compile Include="Converters\ErrorCodeToColorConverter.cs" />
|
||||
<Compile Include="Converters\FlightTaskIsSelectedToEffectConverter.cs" />
|
||||
<Compile Include="Converters\FlightTaskStatusAndTransitionToFillConverter.cs" />
|
||||
<Compile Include="Converters\FlightTaskStatusToFillConverter.cs" />
|
||||
|
@ -139,6 +139,47 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}
|
||||
|
||||
public bool IsCalibration { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 重启飞控
|
||||
/// </summary>
|
||||
private ICommand _RestartFCCommand;
|
||||
public ICommand RestartFCCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _RestartFCCommand ?? (_RestartFCCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
Message.Show("重启飞控");
|
||||
await commModule.DoRestartFCAsync(_copterManager.SelectedCopters);
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 陀螺仪校准
|
||||
/// </summary>
|
||||
private ICommand _CalibrationPreflightCommand;
|
||||
public ICommand CalibrationPreflightCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CalibrationPreflightCommand ?? (_CalibrationPreflightCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
Message.Show("开始校准陀螺仪");
|
||||
await commModule.DoCalibrationPreflightAsync(_copterManager.SelectedCopters);
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 校准指南针
|
||||
/// </summary>
|
||||
|
@ -395,6 +395,20 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private ICommand _ResetRealMissionCommand;
|
||||
public ICommand ResetRealMissionCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ResetRealMissionCommand ?? (_ResetRealMissionCommand = new RelayCommand(async () =>
|
||||
{
|
||||
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
|
||||
_flightTaskManager.RealResetTask();
|
||||
AllowMissionStart = true;
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
private ICommand _EmergencyRetCommand;
|
||||
public ICommand EmergencyRetCommand
|
||||
{
|
||||
@ -402,23 +416,45 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
return _EmergencyRetCommand ?? (_EmergencyRetCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (Alert.Show("您确定要紧急返航吗?紧急返航可能导致飞行器碰撞!!!!", "警告", MessageBoxButton.OKCancel, MessageBoxImage.Warning)
|
||||
!= MessageBoxResult.OK)
|
||||
return; //计算当前图案中心点,起飞图案中心点,图案距离起飞图案中心点最近距离
|
||||
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
|
||||
|
||||
if (_flightTaskManager.Tasks.Count==0)
|
||||
{
|
||||
Alert.Show("没有航点无法紧急返航!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((_flightTaskManager.TaskState_real == TasksStatus.Stop)
|
||||
&&((_flightTaskManager.IsPaused ?? false) == false))
|
||||
{
|
||||
Alert.Show("先暂停任务!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
//if (Alert.Show("您确定要紧急返航吗?紧急返航可能导致飞行器碰撞!!!!", "警告", MessageBoxButton.OKCancel, MessageBoxImage.Warning)
|
||||
// != MessageBoxResult.OK)
|
||||
// return;
|
||||
|
||||
//计算当前图案中心点,起飞图案中心点,图案距离起飞图案中心点最近距离
|
||||
//计算无人机返航方向和最近的飞机距离
|
||||
PLLocation takeoffcentloc;
|
||||
PLLocation taskcentloc;
|
||||
double mindistance; //单位米
|
||||
bool overlapping; //图案否重叠
|
||||
int rettime= (int)(DateTime.Now - _flightTaskManager.taskStartTime).TotalSeconds;
|
||||
int rettime=0;
|
||||
if (_flightTaskManager.TaskState_real!= TasksStatus.Stop)
|
||||
//计算实际飞行时间
|
||||
rettime = (int)(DateTime.UtcNow - _flightTaskManager.TaskStartTime_real).TotalSeconds;
|
||||
else
|
||||
if (_flightTaskManager.TaskState!= TasksStatus.Stop)
|
||||
//计算模拟飞行时间
|
||||
rettime = (int)_flightTaskManager.taskflyTime.TotalSeconds;
|
||||
|
||||
|
||||
if (!_flightTaskManager.EmergencyRet(rettime,out takeoffcentloc,out taskcentloc, out mindistance,out overlapping))
|
||||
{
|
||||
Alert.Show("紧急返航数据计算失败!", "提示");
|
||||
return;
|
||||
}
|
||||
rettime += 5; //加5秒延迟用于通讯重复,有些飞机通讯不成功多次发送才收到,比别的飞机慢
|
||||
|
||||
//模拟测试
|
||||
if (_flightTaskManager.TaskState != TasksStatus.Stop)
|
||||
await _flightTaskManager.sim_DoMissionEmergencyRetAsync(takeoffcentloc, taskcentloc, (float)mindistance, rettime, overlapping);
|
||||
@ -544,7 +580,8 @@ namespace Plane.FormationCreator.ViewModels
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
}
|
||||
await Task.Delay(100);
|
||||
AllowMissionStart = true;
|
||||
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
|
||||
AllowMissionStart = (_flightTaskManager.TaskState_real == TasksStatus.Stop);
|
||||
|
||||
/*
|
||||
await Task.WhenAll(_copterManager.Copters.Select(async c => {
|
||||
@ -1440,9 +1477,22 @@ namespace Plane.FormationCreator.ViewModels
|
||||
Alert.Show("作为参照的原点未设置,无法开始任务!", "提示");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_flightTaskManager.Tasks.Count == 0 )
|
||||
{
|
||||
if (Alert.Show("没有导入任务,紧急返航功能不能使用,继续吗?", "警告", MessageBoxButton.OKCancel, MessageBoxImage.Warning)
|
||||
!= MessageBoxResult.OK)
|
||||
return;
|
||||
}
|
||||
//飞机用UTC时间,日志用本地时间记录
|
||||
DateTime MissionTime = DateTime.UtcNow.AddSeconds(5);
|
||||
DateTime MissionTime_log = DateTime.Now.AddSeconds(5);
|
||||
if (!_flightTaskManager.RealRunTask(MissionTime))
|
||||
{
|
||||
Alert.Show("任务已经开始,请先重设任务!", "提示");
|
||||
return;
|
||||
}
|
||||
AllowMissionStart = false;
|
||||
Message.Show("任务开始:" + MissionTime_log.ToString());
|
||||
//循环3次 发送起飞命令 避免通信问题
|
||||
for (int i = 0; i < 20; i++) //20
|
||||
|
@ -959,8 +959,8 @@ namespace Plane.FormationCreator.ViewModels
|
||||
return _OptimizeRouteCommandRet ?? (_OptimizeRouteCommandRet = new RelayCommand<int>(async =>
|
||||
{
|
||||
if (_copterManager.FC_VER_NO >= 3)
|
||||
//3D计算,不改变ID,可以错层
|
||||
_flightTaskManager.OptimizeRouteMeter(false, false, true); //采用米计算逻辑,用3D生成,不改变ID,可拉开层(2D回起飞矩阵专用)
|
||||
//2D计算,不改变ID,不用错层
|
||||
_flightTaskManager.OptimizeRouteMeter(false, false, false); //采用米计算逻辑,用3D生成,不改变ID,可拉开层(2D回起飞矩阵专用)
|
||||
else
|
||||
_flightTaskManager.OptimizeRouteMeter(false, false); //采用米计算逻辑,用2D生成,不改变ID,不拉开层
|
||||
|
||||
@ -978,7 +978,7 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
if (_copterManager.FC_VER_NO >= 3)
|
||||
//3D计算,不改变ID,可以错层
|
||||
_flightTaskManager.OptimizeRouteMeter(true, false, false); //采用米计算逻辑,用3D生成,不改变ID,不拉开层(3D回起飞矩阵专用)
|
||||
_flightTaskManager.OptimizeRouteMeter(true, false, true); //采用米计算逻辑,用3D生成,不改变ID,拉开层(3D回起飞矩阵专用,结束必须是矩阵)
|
||||
else
|
||||
_flightTaskManager.OptimizeRouteMeter(false, false); //采用米计算逻辑,用2D生成,不改变ID,不拉开层
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
mc:Ignorable="d"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="校准" Height="320" Width="450">
|
||||
<Grid>
|
||||
Title="校准" Height="329" Width="455">
|
||||
<Grid Margin="0,0,0,7">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="70*"/>
|
||||
<RowDefinition Height="30*"/>
|
||||
@ -25,12 +25,16 @@
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1" Margin="10,0,10,10">
|
||||
<Label Content="指南针" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
<Label Content="其他" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
<WrapPanel HorizontalAlignment="Center">
|
||||
<Button Content="开始校准" Width="100" Margin="10, 0"
|
||||
Command="{Binding CalibrationCompassCommand}"/>
|
||||
<Button Content="放弃校准" Width="100" Margin="10, 0"
|
||||
Command="{Binding CancelCalibrationCompassCommand}" Visibility="Collapsed"/>
|
||||
<Button Content="校准指南针" Width="120"
|
||||
Command="{Binding CalibrationCompassCommand}"/>
|
||||
<Button Content="校准陀螺仪" Width="120" Margin="20, 0"
|
||||
Command="{Binding CalibrationPreflightCommand}"/>
|
||||
<Button Content="重启飞控" Width="100" Margin="10, 0"
|
||||
Command="{Binding RestartFCCommand}"/>
|
||||
</WrapPanel>
|
||||
<ProgressBar Margin="0,20" Height="18" Width="220" Value="{Binding CompassPercent, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
|
@ -203,6 +203,8 @@
|
||||
<Button Content="紧急返航"
|
||||
Command="{Binding EmergencyRetCommand}" />
|
||||
|
||||
<Button Content="重设任务"
|
||||
Command="{Binding ResetRealMissionCommand}" />
|
||||
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
|
@ -12,9 +12,12 @@
|
||||
d:DataContext="{d:DesignInstance Type=ec:FakeCopter, IsDesignTimeCreatable=True}">
|
||||
|
||||
|
||||
|
||||
<UserControl.Resources>
|
||||
|
||||
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
</Style>
|
||||
|
||||
|
||||
|
||||
@ -177,6 +180,7 @@
|
||||
<StackPanel>
|
||||
<TextBlock Text="飞行信息" />
|
||||
<Grid>
|
||||
|
||||
<Grid.Resources>
|
||||
<Style x:Key="CopterInfo_ComboBox"
|
||||
TargetType="ComboBox"
|
||||
@ -250,36 +254,19 @@
|
||||
<TextBlock Text="高度:" />
|
||||
<TextBlock Text="{Binding Altitude, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="距离:" />
|
||||
<TextBlock Text="{Binding FlightDistance, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="锁定类型:" />
|
||||
<TextBlock Text="{Binding GpsFixType}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="返回数据:" />
|
||||
<StackPanel ToolTip="{Binding RetainInt}">
|
||||
<TextBlock Text="{Binding Retain[3]}" />
|
||||
<TextBlock Text="." />
|
||||
<TextBlock Text="{Binding Retain[2]}" />
|
||||
<TextBlock Text="." />
|
||||
<TextBlock Text="{Binding Retain[1]}" />
|
||||
<TextBlock Text="." />
|
||||
<TextBlock Text="{Binding Retain[0]}" />
|
||||
<TextBlock Text="预检查状态:" />
|
||||
<TextBlock Text="{Binding CopterPreCheckPassStr}"
|
||||
Foreground="{Binding CopterPreCheckPass, Converter={StaticResource PrecheckToColorConverter}}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<!--
|
||||
<StackPanel>
|
||||
<TextBlock Text="固件版本:" />
|
||||
<TextBlock Text="{Binding FirmwareVersionText}" />
|
||||
</StackPanel>-->
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Orientation="Vertical">
|
||||
@ -289,27 +276,11 @@
|
||||
<Style TargetType="StackPanel"
|
||||
BasedOn="{StaticResource CopterInfo_StackPanel}" />
|
||||
</StackPanel.Resources>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="电压:" />
|
||||
<Slider x:Name="sldChannel3"
|
||||
Width="75"
|
||||
Minimum="1100"
|
||||
Maximum="1900"
|
||||
Value="{Binding Channel3, Mode=OneWay}"
|
||||
ValueChanged="sldChannel3_ValueChanged">
|
||||
<Slider.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Blue.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Slider.Resources>
|
||||
</Slider>
|
||||
<StackPanel Visibility="Hidden">
|
||||
<TextBlock Text="电压值:" />
|
||||
<TextBlock Text="{Binding Path=Voltage}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="电压值:" />
|
||||
<TextBlock Text="{Binding Path=Voltage}" />
|
||||
@ -331,29 +302,30 @@
|
||||
<TextBlock Text="经度:" />
|
||||
<TextBlock Text="{Binding Longitude}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="通道3:" />
|
||||
<TextBlock Text="{Binding Channel3}" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="通道4:" />
|
||||
<TextBlock Text="{Binding Channel4}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="定位精度:" />
|
||||
<TextBlock Text="{Binding GpsHdop, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="通信模块版本:" />
|
||||
<TextBlock Text="{Binding CommModuleVersion}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="返回数据:" />
|
||||
<StackPanel Margin="0,0,0,0" Height="14" ToolTip="{Binding RetainInt}">
|
||||
<TextBlock Margin="0,-1,0,0" Text="{Binding Retain[3]}" />
|
||||
<TextBlock Margin="0,-1,0,0" Text="." />
|
||||
<TextBlock Margin="0,-1,0,0" Text="{Binding Retain[2]}" />
|
||||
<TextBlock Margin="0,-1,0,0" Text="." />
|
||||
<TextBlock Margin="0,-1,0,0" Text="{Binding Retain[1]}" />
|
||||
<TextBlock Margin="0,-1,0,0" Text="." />
|
||||
<TextBlock Margin="0,-1,0,0" Text="{Binding Retain[0]}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel >
|
||||
<TextBlock Text="最后异常:" />
|
||||
<TextBlock Text="{Binding CopterErrorString}"/>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
@ -74,9 +74,9 @@
|
||||
/>
|
||||
<Button Margin="0,5,5,0" Content="3D航线" Width="82" Command="{Binding OptimizeRouteCommand3D}"
|
||||
/>
|
||||
<Button Margin="0,5,5,0" Content="2D返航" Width="82" Command="{Binding OptimizeRouteCommandRet}"
|
||||
<Button Margin="0,5,5,0" Content="2D对应" Width="82" Command="{Binding OptimizeRouteCommandRet}"
|
||||
/>
|
||||
<Button Margin="0,5,5,0" Content="3D返航" Width="82" Command="{Binding OptimizeRouteCommandRet3D}"
|
||||
<Button Margin="0,5,5,0" Content="3D对应" Width="82" Command="{Binding OptimizeRouteCommandRet3D}"
|
||||
/>
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user