diff --git a/Plane.FormationCreator/App.xaml b/Plane.FormationCreator/App.xaml
index bfd11e6..fdcfb47 100644
--- a/Plane.FormationCreator/App.xaml
+++ b/Plane.FormationCreator/App.xaml
@@ -75,9 +75,16 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Plane.FormationCreator/Converters/HeartbeatCountToBrushConverter.cs b/Plane.FormationCreator/Converters/HeartbeatCountToBrushConverter.cs
index cc64b1d..81f7c99 100644
--- a/Plane.FormationCreator/Converters/HeartbeatCountToBrushConverter.cs
+++ b/Plane.FormationCreator/Converters/HeartbeatCountToBrushConverter.cs
@@ -1,44 +1,87 @@
-using Plane.Copters;
-using Plane.FormationCreator.Formation;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Data;
-using System.Windows.Media;
-
-namespace Plane.FormationCreator.Converters
-{
- public class HeartbeatCountToBrushConverter : IMultiValueConverter
- {
- private static SolidColorBrush _zeroBrush = new SolidColorBrush(Color.FromArgb(125, 125, 125, 125));
- private static SolidColorBrush _oneBrush = Copter.DefaultBrush;
-
- private static SolidColorBrush _FakeCopterBrush = Copter.DefaultFakeBrush;
-
- 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 FakeCopter)
- return _FakeCopterBrush;
-
- if (values[1] is PLCopter)
- return _oneBrush;
-
- var copter = values[1] as Copter;
-
- return copter == null ? _oneBrush : copter.Brush;
- }
-
- public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
- {
- throw new NotSupportedException();
- }
- }
-}
+using Plane.Copters;
+using Plane.FormationCreator.Formation;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+using System.Windows.Media;
+
+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 (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)
+ {
+ throw new NotSupportedException();
+ }
+ }
+}
diff --git a/Plane.FormationCreator/Formation/Copter.cs b/Plane.FormationCreator/Formation/Copter.cs
index b82209f..dd881a3 100644
--- a/Plane.FormationCreator/Formation/Copter.cs
+++ b/Plane.FormationCreator/Formation/Copter.cs
@@ -1,69 +1,75 @@
-using Plane.Copters;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Plane.Communication;
-using System.Threading;
-using System.Windows.Media;
-
-namespace Plane.FormationCreator.Formation
-{
- class Copter : PLCopter
- {
- public Copter(IConnection Connection, SynchronizationContext uiThreadContext) : base(Connection, uiThreadContext,false)
- {
- Brush = _brushes[NextBrushIndex()];
-
- }
-
- public Copter(IConnection Connection, SynchronizationContext uiThreadContext, double lat, double lng) : base(Connection, uiThreadContext, false)
- {
- Brush = _brushes[NextBrushIndex()];
- RecordLat = lat;
- RecordLng = lng;
- Latitude = lat;
- Longitude = lng;
- //RaiseLocationChangedIfNeeded();
- }
-
-
- internal static SolidColorBrush BlueBrush { get; } = new SolidColorBrush(Color.FromRgb(28, 151, 234));
- internal static SolidColorBrush RedBrush { get; } = new SolidColorBrush(Color.FromRgb(255, 100, 100));
- internal static SolidColorBrush GreenBrush { get; } = new SolidColorBrush(Color.FromRgb(100, 255, 100));
- internal static SolidColorBrush YellowBrush { get; } = new SolidColorBrush(Color.FromRgb(255, 215, 0));
-
-
-
- static SolidColorBrush[] _brushes = new[]
- {
- new SolidColorBrush(Color.FromArgb(180, 255, 0, 0)),
- new SolidColorBrush(Color.FromArgb(180, 235, 97, 0)),
- new SolidColorBrush(Color.FromArgb(180, 255, 255, 0)),
- new SolidColorBrush(Color.FromArgb(180, 0, 255, 0)),
- new SolidColorBrush(Color.FromArgb(180, 0, 198, 255)),
- new SolidColorBrush(Color.FromArgb(180, 0, 122, 204)),
- new SolidColorBrush(Color.FromArgb(180, 174, 0, 255))
- };
- static int _brushIndex = 0;
- static int NextBrushIndex()
- {
- return _brushIndex++ % _brushes.Length;
- }
- //真实飞机列表默认颜色
- internal static SolidColorBrush DefaultBrush { get; } = GreenBrush;// new SolidColorBrush(Color.FromRgb(50, 205, 50));
- //虚拟飞机列表默认颜色
- internal static SolidColorBrush DefaultFakeBrush { get; } = BlueBrush;
-
-
-
-
- private SolidColorBrush _Brush;
- public SolidColorBrush Brush
- {
- get { return _Brush ?? DefaultBrush; }
- set { Set(nameof(Brush), ref _Brush, value); }
- }
- }
-}
+using Plane.Copters;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Plane.Communication;
+using System.Threading;
+using System.Windows.Media;
+
+namespace Plane.FormationCreator.Formation
+{
+ class Copter : PLCopter
+ {
+ public Copter(IConnection Connection, SynchronizationContext uiThreadContext) : base(Connection, uiThreadContext,false)
+ {
+ Brush = _brushes[NextBrushIndex()];
+
+ }
+
+ public Copter(IConnection Connection, SynchronizationContext uiThreadContext, double lat, double lng) : base(Connection, uiThreadContext, false)
+ {
+ Brush = _brushes[NextBrushIndex()];
+ RecordLat = lat;
+ RecordLng = lng;
+ Latitude = lat;
+ Longitude = lng;
+ //RaiseLocationChangedIfNeeded();
+ }
+
+
+ internal static SolidColorBrush BlueBrush { get; } = new SolidColorBrush(Color.FromRgb(28, 151, 234));
+ internal static SolidColorBrush RedBrush { get; } = new SolidColorBrush(Color.FromRgb(255, 100, 100));
+ internal static SolidColorBrush GreenBrush { get; } = new SolidColorBrush(Color.FromRgb(100, 255, 100));
+ internal static SolidColorBrush YellowBrush { get; } = new SolidColorBrush(Color.FromRgb(255, 215, 0));
+
+
+
+ static SolidColorBrush[] _brushes = new[]
+ {
+ new SolidColorBrush(Color.FromArgb(180, 255, 0, 0)),
+ new SolidColorBrush(Color.FromArgb(180, 235, 97, 0)),
+ new SolidColorBrush(Color.FromArgb(180, 255, 255, 0)),
+ new SolidColorBrush(Color.FromArgb(180, 0, 255, 0)),
+ new SolidColorBrush(Color.FromArgb(180, 0, 198, 255)),
+ new SolidColorBrush(Color.FromArgb(180, 0, 122, 204)),
+ new SolidColorBrush(Color.FromArgb(180, 174, 0, 255))
+ };
+ static int _brushIndex = 0;
+ static int NextBrushIndex()
+ {
+ return _brushIndex++ % _brushes.Length;
+ }
+ //真实飞机列表默认颜色
+ internal static SolidColorBrush DefaultBrush { get; } = GreenBrush;// new SolidColorBrush(Color.FromRgb(50, 205, 50));
+ //虚拟飞机列表默认颜色
+ internal static SolidColorBrush DefaultFakeBrush { get; } = BlueBrush;
+
+
+
+
+ private SolidColorBrush _Brush;
+ public SolidColorBrush Brush
+ {
+ get {
+ if (CopterPreCheckPass)
+ return _Brush ?? DefaultBrush;
+ else
+ return _Brush ?? YellowBrush;
+
+ }
+ set { Set(nameof(Brush), ref _Brush, value); }
+ }
+ }
+}
diff --git a/Plane.FormationCreator/Formation/FlightTaskManager.cs b/Plane.FormationCreator/Formation/FlightTaskManager.cs
index 820f907..37b857e 100644
--- a/Plane.FormationCreator/Formation/FlightTaskManager.cs
+++ b/Plane.FormationCreator/Formation/FlightTaskManager.cs
@@ -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 TaskAdded;
public event EventHandler TaskDeled;
@@ -601,6 +609,7 @@ namespace Plane.FormationCreator.Formation
+
///
/// 起始点作为参考,设置起始点后飞行写入的数据将为相对坐标
///
@@ -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>,bool)> ABypassBAsync(FlightRouteV2.Vector3[] aVecs, FlightRouteV2.Vector3[] bVecs)
+ public async Task<(List>,bool)> ABypassBAsync(FlightRouteV2.Vector3[] aVecs, FlightRouteV2.Vector3[] bVecs, List mappingId = null)
{
List> 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
///
/// 自动生成航线2D和3D都用这个-------V2版使用新的碰撞检测和绕行,用flybase.cs库,只用于新版固件--------------
///
- /// 3D计算
+ /// 2D/3D计算
/// 是否改变线路的结束点顺序--返回起飞点航线不能交换
/// 3D是否自动插入拉开层,用于2D画面回起飞矩阵,拉开2D画面
public async Task OptimizeRouteMeterV2(bool Is3d = false, bool Ischange = true,bool Is3dstagger=false)
@@ -2417,6 +2426,10 @@ namespace Plane.FormationCreator.Formation
Dictionary prevTaskPoint = new Dictionary();
var stopWatch = new Stopwatch();
stopWatch.Start();
+ //ID映射列表
+ List mappingId = new List();
+
+
//设置随机数种子
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> 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}秒");
+
}
///
/// 开始运行模拟任务
@@ -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;
+ 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
-
+ ///
+ /// 开始碰撞检测
+ ///
private async void StartAvoidingCrash()
{
await Task.Factory.StartNew(AvoidCrashtoshow);
await Task.Factory.StartNew(LoopToAvoidCrash);
}
+
+ ///
+ /// 将碰撞显示到UI
+ ///
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("开始碰撞检测停止");
}
+ ///
+ /// 循环检测碰撞
+ ///
private async void LoopToAvoidCrash()
{
- while (IsPaused == false)
+ while (TaskState != TasksStatus.Stop)
{
try
{
diff --git a/Plane.FormationCreator/Formation/FlightTask_FlyTo.cs b/Plane.FormationCreator/Formation/FlightTask_FlyTo.cs
index 057a0db..9429de0 100644
--- a/Plane.FormationCreator/Formation/FlightTask_FlyTo.cs
+++ b/Plane.FormationCreator/Formation/FlightTask_FlyTo.cs
@@ -183,6 +183,10 @@ namespace Plane.FormationCreator.Formation
await info.Copter.HoverAsync();
return;
}
+ if (_flightTaskManager.IsEmergencyRet == true)
+ {
+ return;
+ }
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
}
diff --git a/Plane.FormationCreator/Formation/FlightTask_TakeOff.cs b/Plane.FormationCreator/Formation/FlightTask_TakeOff.cs
index 9648002..04e1a2e 100644
--- a/Plane.FormationCreator/Formation/FlightTask_TakeOff.cs
+++ b/Plane.FormationCreator/Formation/FlightTask_TakeOff.cs
@@ -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); //秒
diff --git a/Plane.FormationCreator/ModifyParam.xaml.cs b/Plane.FormationCreator/ModifyParam.xaml.cs
index 6146261..e48662d 100644
--- a/Plane.FormationCreator/ModifyParam.xaml.cs
+++ b/Plane.FormationCreator/ModifyParam.xaml.cs
@@ -1,56 +1,65 @@
-using Plane.FormationCreator.Util;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Shapes;
-
-namespace Plane.FormationCreator
-{
- ///
- /// ModifyParam.xaml 的交互逻辑
- ///
- public partial class ModifyParam : Window
- {
- public bool LoadParam = false;
- public ModifyParam()
- {
- InitializeComponent();
-// if (!VersionControl.IsFullVersion)
-// {
-// hide_panel.Visibility = Visibility.Collapsed;
-// textParamName.IsReadOnly = true;
-// btnLoad.Visibility = Visibility.Collapsed;
-//
-// label.Visibility = Visibility.Collapsed;
-// textParamName.Visibility = Visibility.Collapsed;
-// }
- }
-
- private void btnModify_Click(object sender, RoutedEventArgs e)
- {
- LoadParam = false;
- this.DialogResult = true;
- }
-
- private void Modify_Select(object sender, RoutedEventArgs e)
- {
- textParamName.Text = ((Button)sender).Tag.ToString();
- textParamName_cn.Text = ((Button)sender).Content.ToString();
- }
-
- private void btnLoad_Click(object sender, RoutedEventArgs e)
- {
- LoadParam = true;
- this.DialogResult = true;
- }
- }
-}
+using Microsoft.Practices.ServiceLocation;
+using Plane.FormationCreator.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace Plane.FormationCreator
+{
+ ///
+ /// ModifyParam.xaml 的交互逻辑
+ ///
+ public partial class ModifyParam : Window
+ {
+ public bool LoadParam = false;
+ public ModifyParam()
+ {
+ InitializeComponent();
+// if (!VersionControl.IsFullVersion)
+// {
+// hide_panel.Visibility = Visibility.Collapsed;
+// textParamName.IsReadOnly = true;
+// btnLoad.Visibility = Visibility.Collapsed;
+//
+// label.Visibility = Visibility.Collapsed;
+// textParamName.Visibility = Visibility.Collapsed;
+// }
+ }
+
+ private void btnModify_Click(object sender, RoutedEventArgs e)
+ {
+ LoadParam = false;
+ this.DialogResult = true;
+ }
+
+ private void Modify_Select(object sender, RoutedEventArgs e)
+ {
+ Formation.CopterManager _copterManager = ServiceLocator.Current.GetInstance();
+
+ 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();
+ }
+
+ private void btnLoad_Click(object sender, RoutedEventArgs e)
+ {
+ LoadParam = true;
+ this.DialogResult = true;
+ }
+ }
+}
diff --git a/Plane.FormationCreator/Plane.FormationCreator.csproj b/Plane.FormationCreator/Plane.FormationCreator.csproj
index e1de434..8f5af26 100644
--- a/Plane.FormationCreator/Plane.FormationCreator.csproj
+++ b/Plane.FormationCreator/Plane.FormationCreator.csproj
@@ -166,6 +166,8 @@
+
+
diff --git a/Plane.FormationCreator/ViewModels/CalibrationViewModel.cs b/Plane.FormationCreator/ViewModels/CalibrationViewModel.cs
index 36f38e9..926b281 100644
--- a/Plane.FormationCreator/ViewModels/CalibrationViewModel.cs
+++ b/Plane.FormationCreator/ViewModels/CalibrationViewModel.cs
@@ -1,222 +1,263 @@
-using GalaSoft.MvvmLight;
-using GalaSoft.MvvmLight.Command;
-using Microsoft.Practices.ServiceLocation;
-using Plane.CommunicationManagement;
-using Plane.CopterManagement;
-using Plane.Copters;
-using Plane.FormationCreator.Formation;
-using Plane.Windows.Messages;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows.Input;
-
-namespace Plane.FormationCreator.ViewModels
-{
- public class CalibrationViewModel : ViewModelBase
- {
- CommModuleManager commModule = CommModuleManager.Instance;
-
- private CopterManager _copterManager = ServiceLocator.Current.GetInstance();
-
- private string _AccelerometerTips;
- public string AccelerometerTips
- {
- get
- {
- switch (AccelerometerState)
- {
- case AccelerometerStates.Idle:
- _AccelerometerTips = "点击“开始校准”后,开始校准加速计";
- break;
- case AccelerometerStates.Front:
- _AccelerometerTips = "亮紫色: 飞机水平放置(Front)";
- break;
- case AccelerometerStates.Left:
- _AccelerometerTips = "亮黄色:飞机左侧接触地面竖立放置(Left)";
- break;
- case AccelerometerStates.Right:
- _AccelerometerTips = "亮青色:飞机右侧接触地面竖立放置(Right)";
- break;
- case AccelerometerStates.Down:
- _AccelerometerTips = "紫色:飞机机头向下接触地面竖立放置(Down)";
- break;
- case AccelerometerStates.Up:
- _AccelerometerTips = "黄色:飞机机尾向下接触地面竖立放置(Up)";
- break;
- case AccelerometerStates.Back:
- _AccelerometerTips = "青色:飞机翻过来水平放置(Back)";
- break;
- }
- return _AccelerometerTips;
- }
- }
-
- private string _AccelerometerBtnText = "开始校准";
- public string AccelerometerBtnText
- {
- get
- {
- switch (AccelerometerState)
- {
- case AccelerometerStates.Idle:
- _AccelerometerBtnText = "开始校准";
- break;
- default:
- _AccelerometerBtnText = "完成";
- break;
- }
- return _AccelerometerBtnText;
- }
- }
-
- //校准加速计的状态
- public enum AccelerometerStates
- {
- Idle = 0,
- Front = 1,
- Left = 2,
- Right = 3,
- Down = 4,
- Up = 5,
- Back = 6
- }
-
- private AccelerometerStates _AccelerometerState = AccelerometerStates.Idle;
- public AccelerometerStates AccelerometerState
- {
- get { return _AccelerometerState; }
- set
- {
- Set(nameof(AccelerometerState), ref _AccelerometerState, value);
- RaisePropertyChanged(nameof(AccelerometerBtnText));
- RaisePropertyChanged(nameof(AccelerometerTips));
- }
- }
-
- ///
- /// 开始校准加速计
- ///
- private ICommand _CalibrationAccelerometerStartCommand;
- public ICommand CalibrationAccelerometerStartCommand
- {
- get
- {
- return _CalibrationAccelerometerStartCommand ?? (_CalibrationAccelerometerStartCommand = new RelayCommand(async () =>
- {
- if (_copterManager.SelectedCopters.Count() == 0) return;
- await commModule.DoStartPreflightCompassAsync(_copterManager.SelectedCopters);
- }));
- }
- }
-
- ///
- /// 校准加速计下一步
- ///
- private ICommand _CalibrationAccelerometerNextCommand;
- public ICommand CalibrationAccelerometerNextCommand
- {
- get
- {
- return _CalibrationAccelerometerNextCommand ?? (_CalibrationAccelerometerNextCommand = new RelayCommand(async () =>
- {
- if (_copterManager.SelectedCopters.Count() == 0) return;
- await commModule.DoNextPreflightCompassAsync(_copterManager.SelectedCopters);
- }));
- }
- }
-
- private int _CompassPercent;
- public int CompassPercent
- {
- get { return _CompassPercent; }
- set
- {
- Set(nameof(CompassPercent), ref _CompassPercent, value);
- }
- }
-
- public bool IsCalibration { get; set; }
- ///
- /// 校准指南针
- ///
- private ICommand _CalibrationCompassCommand;
- public ICommand CalibrationCompassCommand
- {
- get
- {
- return _CalibrationCompassCommand ?? (_CalibrationCompassCommand = new RelayCommand(async () =>
- {
- if (_copterManager.SelectedCopters.Count() == 0) return;
-
-// ICopter copter = _copterManager.SelectedCopters.FirstOrDefault();
-//
-// short copterId = short.Parse(copter.Name);
- Message.Show("开始校准指南针");
-
- await commModule.DoCalibrationCompassAsync(_copterManager.SelectedCopters);
- await Task.Delay(50).ConfigureAwait(false);
-
- /*支持多飞行机同时校准 不再判断单架的返回值
-
- IsCalibration = true;
- CompassPercent = 0;
- int State = 0; //4:成功 5失败 todo 改为枚举
-
-
- while (IsCalibration && CompassPercent <= 100)
- {
- //两个255的时候表示 当前预留字节代表的意思是校准
- if (copter.Retain[2] == 255 && copter.Retain[3] == 255)
- {
- CompassPercent = copter.Retain[0];
- State = copter.Retain[1];
- if (State == 4 || State == 5)
- break;
- }
-
- await Task.Delay(100);
- }
-
- switch (State)
- {
- case 4:
- Alert.Show($"校准成功,请重新上电{copterId}号", "指南针");
- break;
- case 5:
- Alert.Show("校准失败", "指南针");
- break;
- default:
- break;
- }
-
- IsCalibration = false;
- */
- }));
- }
- }
-
- private ICommand _CancelCalibrationCompassCommand;
- public ICommand CancelCalibrationCompassCommand
- {
- get
- {
- return _CancelCalibrationCompassCommand ?? (_CancelCalibrationCompassCommand = new RelayCommand(async () =>
- {
- if (_copterManager.SelectedCopters.Count() == 1) return;
-
- ICopter copter = _copterManager.SelectedCopters.FirstOrDefault();
-
- short copterId = short.Parse(copter.Name);
- await commModule.DoCancelCalibrationCompassAsync(copterId);
- IsCalibration = false;
- Alert.Show("放弃校准", "指南针");
- }));
- }
- }
- }
-
-
-}
+using GalaSoft.MvvmLight;
+using GalaSoft.MvvmLight.Command;
+using Microsoft.Practices.ServiceLocation;
+using Plane.CommunicationManagement;
+using Plane.CopterManagement;
+using Plane.Copters;
+using Plane.FormationCreator.Formation;
+using Plane.Windows.Messages;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+
+namespace Plane.FormationCreator.ViewModels
+{
+ public class CalibrationViewModel : ViewModelBase
+ {
+ CommModuleManager commModule = CommModuleManager.Instance;
+
+ private CopterManager _copterManager = ServiceLocator.Current.GetInstance();
+
+ private string _AccelerometerTips;
+ public string AccelerometerTips
+ {
+ get
+ {
+ switch (AccelerometerState)
+ {
+ case AccelerometerStates.Idle:
+ _AccelerometerTips = "点击“开始校准”后,开始校准加速计";
+ break;
+ case AccelerometerStates.Front:
+ _AccelerometerTips = "亮紫色: 飞机水平放置(Front)";
+ break;
+ case AccelerometerStates.Left:
+ _AccelerometerTips = "亮黄色:飞机左侧接触地面竖立放置(Left)";
+ break;
+ case AccelerometerStates.Right:
+ _AccelerometerTips = "亮青色:飞机右侧接触地面竖立放置(Right)";
+ break;
+ case AccelerometerStates.Down:
+ _AccelerometerTips = "紫色:飞机机头向下接触地面竖立放置(Down)";
+ break;
+ case AccelerometerStates.Up:
+ _AccelerometerTips = "黄色:飞机机尾向下接触地面竖立放置(Up)";
+ break;
+ case AccelerometerStates.Back:
+ _AccelerometerTips = "青色:飞机翻过来水平放置(Back)";
+ break;
+ }
+ return _AccelerometerTips;
+ }
+ }
+
+ private string _AccelerometerBtnText = "开始校准";
+ public string AccelerometerBtnText
+ {
+ get
+ {
+ switch (AccelerometerState)
+ {
+ case AccelerometerStates.Idle:
+ _AccelerometerBtnText = "开始校准";
+ break;
+ default:
+ _AccelerometerBtnText = "完成";
+ break;
+ }
+ return _AccelerometerBtnText;
+ }
+ }
+
+ //校准加速计的状态
+ public enum AccelerometerStates
+ {
+ Idle = 0,
+ Front = 1,
+ Left = 2,
+ Right = 3,
+ Down = 4,
+ Up = 5,
+ Back = 6
+ }
+
+ private AccelerometerStates _AccelerometerState = AccelerometerStates.Idle;
+ public AccelerometerStates AccelerometerState
+ {
+ get { return _AccelerometerState; }
+ set
+ {
+ Set(nameof(AccelerometerState), ref _AccelerometerState, value);
+ RaisePropertyChanged(nameof(AccelerometerBtnText));
+ RaisePropertyChanged(nameof(AccelerometerTips));
+ }
+ }
+
+ ///
+ /// 开始校准加速计
+ ///
+ private ICommand _CalibrationAccelerometerStartCommand;
+ public ICommand CalibrationAccelerometerStartCommand
+ {
+ get
+ {
+ return _CalibrationAccelerometerStartCommand ?? (_CalibrationAccelerometerStartCommand = new RelayCommand(async () =>
+ {
+ if (_copterManager.SelectedCopters.Count() == 0) return;
+ await commModule.DoStartPreflightCompassAsync(_copterManager.SelectedCopters);
+ }));
+ }
+ }
+
+ ///
+ /// 校准加速计下一步
+ ///
+ private ICommand _CalibrationAccelerometerNextCommand;
+ public ICommand CalibrationAccelerometerNextCommand
+ {
+ get
+ {
+ return _CalibrationAccelerometerNextCommand ?? (_CalibrationAccelerometerNextCommand = new RelayCommand(async () =>
+ {
+ if (_copterManager.SelectedCopters.Count() == 0) return;
+ await commModule.DoNextPreflightCompassAsync(_copterManager.SelectedCopters);
+ }));
+ }
+ }
+
+ private int _CompassPercent;
+ public int CompassPercent
+ {
+ get { return _CompassPercent; }
+ set
+ {
+ Set(nameof(CompassPercent), ref _CompassPercent, value);
+ }
+ }
+
+ public bool IsCalibration { get; set; }
+
+
+ ///
+ /// 重启飞控
+ ///
+ 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);
+ }));
+ }
+ }
+
+
+ ///
+ /// 陀螺仪校准
+ ///
+ 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);
+ }));
+ }
+ }
+
+
+
+ ///
+ /// 校准指南针
+ ///
+ private ICommand _CalibrationCompassCommand;
+ public ICommand CalibrationCompassCommand
+ {
+ get
+ {
+ return _CalibrationCompassCommand ?? (_CalibrationCompassCommand = new RelayCommand(async () =>
+ {
+ if (_copterManager.SelectedCopters.Count() == 0) return;
+
+// ICopter copter = _copterManager.SelectedCopters.FirstOrDefault();
+//
+// short copterId = short.Parse(copter.Name);
+ Message.Show("开始校准指南针");
+
+ await commModule.DoCalibrationCompassAsync(_copterManager.SelectedCopters);
+ await Task.Delay(50).ConfigureAwait(false);
+
+ /*支持多飞行机同时校准 不再判断单架的返回值
+
+ IsCalibration = true;
+ CompassPercent = 0;
+ int State = 0; //4:成功 5失败 todo 改为枚举
+
+
+ while (IsCalibration && CompassPercent <= 100)
+ {
+ //两个255的时候表示 当前预留字节代表的意思是校准
+ if (copter.Retain[2] == 255 && copter.Retain[3] == 255)
+ {
+ CompassPercent = copter.Retain[0];
+ State = copter.Retain[1];
+ if (State == 4 || State == 5)
+ break;
+ }
+
+ await Task.Delay(100);
+ }
+
+ switch (State)
+ {
+ case 4:
+ Alert.Show($"校准成功,请重新上电{copterId}号", "指南针");
+ break;
+ case 5:
+ Alert.Show("校准失败", "指南针");
+ break;
+ default:
+ break;
+ }
+
+ IsCalibration = false;
+ */
+ }));
+ }
+ }
+
+ private ICommand _CancelCalibrationCompassCommand;
+ public ICommand CancelCalibrationCompassCommand
+ {
+ get
+ {
+ return _CancelCalibrationCompassCommand ?? (_CancelCalibrationCompassCommand = new RelayCommand(async () =>
+ {
+ if (_copterManager.SelectedCopters.Count() == 1) return;
+
+ ICopter copter = _copterManager.SelectedCopters.FirstOrDefault();
+
+ short copterId = short.Parse(copter.Name);
+ await commModule.DoCancelCalibrationCompassAsync(copterId);
+ IsCalibration = false;
+ Alert.Show("放弃校准", "指南针");
+ }));
+ }
+ }
+ }
+
+
+}
diff --git a/Plane.FormationCreator/ViewModels/ControlPanelViewModel.cs b/Plane.FormationCreator/ViewModels/ControlPanelViewModel.cs
index 3dd44d9..fc78dbd 100644
--- a/Plane.FormationCreator/ViewModels/ControlPanelViewModel.cs
+++ b/Plane.FormationCreator/ViewModels/ControlPanelViewModel.cs
@@ -394,7 +394,21 @@ namespace Plane.FormationCreator.ViewModels
}));
}
}
+
+ private ICommand _ResetRealMissionCommand;
+ public ICommand ResetRealMissionCommand
+ {
+ get
+ {
+ return _ResetRealMissionCommand ?? (_ResetRealMissionCommand = new RelayCommand(async () =>
+ {
+ FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance();
+ _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();
+
+ 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();
+ 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
diff --git a/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs b/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs
index 2d3d103..7c49e33 100644
--- a/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs
+++ b/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs
@@ -959,8 +959,8 @@ namespace Plane.FormationCreator.ViewModels
return _OptimizeRouteCommandRet ?? (_OptimizeRouteCommandRet = new RelayCommand(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,不拉开层
diff --git a/Plane.FormationCreator/Views/CalibrationWindow.xaml b/Plane.FormationCreator/Views/CalibrationWindow.xaml
index c6d3afc..26c958e 100644
--- a/Plane.FormationCreator/Views/CalibrationWindow.xaml
+++ b/Plane.FormationCreator/Views/CalibrationWindow.xaml
@@ -1,40 +1,44 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plane.FormationCreator/Views/ControlPanelView.xaml b/Plane.FormationCreator/Views/ControlPanelView.xaml
index 0105a49..15a9461 100644
--- a/Plane.FormationCreator/Views/ControlPanelView.xaml
+++ b/Plane.FormationCreator/Views/ControlPanelView.xaml
@@ -202,7 +202,9 @@
Command="{Binding AllLandCommand}" />
-
+
+
diff --git a/Plane.FormationCreator/Views/CopterInfoView.xaml b/Plane.FormationCreator/Views/CopterInfoView.xaml
index 44dbb92..1d2a3ff 100644
--- a/Plane.FormationCreator/Views/CopterInfoView.xaml
+++ b/Plane.FormationCreator/Views/CopterInfoView.xaml
@@ -1,359 +1,331 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plane.FormationCreator/Views/MapView_CopterDrawing.cs b/Plane.FormationCreator/Views/MapView_CopterDrawing.cs
index 3ad650c..c541457 100644
--- a/Plane.FormationCreator/Views/MapView_CopterDrawing.cs
+++ b/Plane.FormationCreator/Views/MapView_CopterDrawing.cs
@@ -1,825 +1,825 @@
-using Plane.Collections;
-using Plane.Copters;
-using Plane.FormationCreator.Formation;
-using Plane.Logging;
-using Microsoft.Practices.ServiceLocation;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-using System.Windows.Media.Effects;
-using System.Windows.Shapes;
-using GMap.NET.WindowsPresentation;
-using GMap.NET;
-using Plane.FormationCreator.Maps;
-using Microsoft.Maps.MapControl.WPF;
-using Plane.FormationCreator.ViewModels;
-
-namespace Plane.FormationCreator.Views
-{
- public partial class MapView
- {
- private class CopterDrawing
- {
- public CopterDrawing(ICopter copter, GoogleMap.GMap map)
- {
- this.Copter = copter;
- _map = map;
- if (copter is Copter)
- {
- _brush = ((Copter)copter).Brush;
- _color = ((SolidColorBrush)_brush).Color;
- }
- else
- {
- _color = _colors[(_colorIndex++ % _colors.Length)];
- _brush = new SolidColorBrush(_color);
- }
-
-
- Color Copterdefaultcolor = (Color)ColorConverter.ConvertFromString("#" + CopterManager.CopterDefaultColor);
-
- _brush = new SolidColorBrush(Copterdefaultcolor);
-
- _flightTaskManager.TasksCleared += (sender, e) =>
- {
- //清除计划航线
- if (Route!=null)
- Route.Points.Clear();
-
-
-// for (int i = this.Route.Locations.Count - 1; i >= 1; i--)
-// {
-// this.Route.Locations.RemoveAt(i);
-// }
- foreach (var wp in this.Waypoints)
- {
- _map.Markers.Remove(wp);
- }
- this.Waypoints.Clear();
- };
-
- //_map.ViewChangeOnFrame += new EventHandler(Map_ViewChanged);
-
-
- //删除任务事件
- _flightTaskManager.TaskDeled += (sender, e) =>
- {
- if (this.Waypoints.Count == 0)
- return;
- // Waypoints没有起飞任务所以-1
- int WaypointsIndex = e.TaskIndex - 1;
- //删除地图上的航点
- var wp = this.Waypoints[WaypointsIndex];
- _map.Markers.Remove(wp);
- //删除航点列表里的航点
- this.Waypoints.RemoveAt(WaypointsIndex);
- };
-
-
- selectMarkup.Width = 7;
- selectMarkup.Height = 7;
- selectMarkup.HorizontalAlignment = HorizontalAlignment.Left;
- selectMarkup.VerticalAlignment = VerticalAlignment.Top;
- selectMarkup.Fill = new SolidColorBrush(Colors.Red); //选中做红色标记
- }
-
- Rectangle selectMarkup = new Rectangle();
-
- static DropShadowEffect _selectedEffect = new DropShadowEffect();
-
- static SolidColorBrush _selectedTaskStroke = new SolidColorBrush(Colors.White);
-
- static Color[] _colors = new Color[]
- {
- Color.FromArgb(180, 255, 0, 0),
- Color.FromArgb(180, 235, 97, 0),
- Color.FromArgb(180, 255, 255, 0),
- Color.FromArgb(180, 0, 255, 0),
- Color.FromArgb(180, 0, 198, 255),
- Color.FromArgb(180, 0, 122, 204),
- Color.FromArgb(180, 174, 0, 255)
- };
-
- static int _colorIndex = 0;
-
- const double COPTER_RADIUS = 12;
- const double WAYPOINT_RADIUS = 6;
-
-
- public ICopter Copter { get; set; }
- public GMapMarker DotMarker { get; set; }
- public Grid DotContainer { get; set; }
- public Polygon Dot { get; set; }
-
- public TextBlock CopterText { get; set; }
-
- public MapPolyline Track { get; set; }
- public Location LastLocation { get; set; }
-
- //计划航线
- public GMapRoute Route { get; set; }
- //某架飞机的地图显示航点列表
- public List Waypoints { get; set; } = new List();
-
- GoogleMap.GMap _map;
- Color _color;
- public Brush _brush;
-
- ILogger _logger = ServiceLocator.Current.GetInstance();
- CopterManager _copterManager = ServiceLocator.Current.GetInstance();
- FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance();
- View3DViewModel _view3DViewModel = ServiceLocator.Current.GetInstance();
-
-
- private void Map_ViewChanged(object sender, MapEventArgs e)
- {
- /*
- for (int index = 1; index < _flightTaskManager.Tasks.Count; index++)
- {
- var info = _flightTaskManager.Tasks[index].SingleCopterInfos.Find(i => i.Copter == this.Copter); ;
- ShapesContainer wpContainer = Waypoints[index - 1]; //起飞任务没有Waypoint;
- Location location = new Location(info.TargetLat, info.TargetLng);
- Point wpPos = _map.LocationToViewportPoint(location);
- wpPos.X -= WAYPOINT_RADIUS;
- wpPos.Y -= WAYPOINT_RADIUS;
- MapLayer.SetPosition(wpContainer, _map.ViewportPointToLocation(wpPos));
- }
- */
-
- }
-
- public void AddOrMoveCopter()
- {
- if (!_flightTaskManager.TaskRun_2D) return; //不在2D模式运行直接退出
- try
- {
- var location = new Microsoft.Maps.MapControl.WPF.Location(Copter.Latitude, Copter.Longitude, Copter.Altitude);
-
- if (this.Dot != null )
- {
- if (Copter is PLCopter && !Copter.IsGpsAccurate)
- this.Dot.Fill = new SolidColorBrush(Color.FromRgb(0, 0, 0));
- else
- this.Dot.Fill = _brush;
-
- if (Copter.LEDColor != null && Copter.LEDColor!="")
- {
- Color color = (Color)ColorConverter.ConvertFromString("#" + Copter.LEDColor);
- _brush = new SolidColorBrush(color);
- if (this.Dot.Fill != _brush)
- {
- this.Dot.Fill = _brush;
- }
- }
-
- }
-
-
- PointLatLng gmapLatLng = new LatLng(location.Latitude, location.Longitude).ToGCJ02();
- GPoint center = _map.FromLatLngToLocal(gmapLatLng);
- bool locationUpdated = true;
- SolidColorBrush blackBrush = new SolidColorBrush();
- if (this.Dot == null)
- {
- Track = new MapPolyline();
- Track.Stroke = _brush;
- Track.StrokeThickness = 3.0;
- Track.Locations = new LocationCollection();
-
- //实时飞行航线
- // _map.Children.Add(Track);
-
- Dot = new Polygon();
-
- Dot.Points.Add(new Point(0, -COPTER_RADIUS));
- Dot.Points.Add(new Point(-COPTER_RADIUS * 2 / 3, COPTER_RADIUS));
- Dot.Points.Add(new Point(COPTER_RADIUS * 2 / 3, COPTER_RADIUS));
-
-
- Dot.Fill = _brush; // new SolidColorBrush(Color.FromArgb(200, 0, 122, 204));
- Dot.StrokeThickness = 1;
- Dot.Width = COPTER_RADIUS * 2;
- Dot.Height = COPTER_RADIUS * 2;
- ToolTip tt = new ToolTip();
- tt.Content = $"Name: {Copter.Name}, Location: {location}";
- Dot.ToolTip = tt;
-
- DotContainer = new Grid { Tag = COPTER_TAG };
- DotContainer.Children.Add(Dot);
-
- //飞机里面的编号
- CopterText = new TextBlock
- {
- Text = Copter.Name,
- Foreground = new SolidColorBrush(Colors.White),
- Margin = new Thickness(-COPTER_RADIUS * 2, -COPTER_RADIUS * 1.5, 0, 0),
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center
- };
-
- DotMarker = new GMapMarker(new PointLatLng(0, 0));
- DotContainer.Children.Add(CopterText);
- DotMarker.Shape = DotContainer;
- _map.Markers.Add(DotMarker);
- //MapLayer.SetZIndex(DotContainer, 100);
-
- this.Route = new GMapRoute(new List() { gmapLatLng, gmapLatLng });
- /*
- Path path = new Path()
- {
- Stroke = new SolidColorBrush(Colors.Red),
- StrokeThickness = 2.0
- };
-
-
- this.Route.Shape = path;
- */
- //显示计划航线
- //_map.Markers.Add(Route);
-
- this.LastLocation = location;
-
- RegisterEventHandlersForDraggingCopter(DotMarker);
- }
- else
- {
- if ((bool)_copterManager.CopterStatus[_copterManager.Copters.IndexOf(Copter)])
- {
- CopterText.Foreground = new SolidColorBrush(Colors.Red);
- }
- else
- {
-
- CopterText.Foreground = new SolidColorBrush(Colors.White);
- }
-
- if (LastLocation != null && location.CalcDistance(LastLocation) < 0.1)
- {
- locationUpdated = false;
- }
- if (locationUpdated)
- {
- //dot.RenderTransform = new RotateTransform(GeographyUtils.CalcDirection2D(lastLocation.Latitude, lastLocation.Longitude, location.Latitude, location.Longitude).RadiansToDegrees());
- (Dot.ToolTip as ToolTip).Content = $"Name: {Copter.Name}, Location: {location}";
- }
- }
-
- switch (_copterManager.SortType)
- {
- case CopterManager.CopterSortType.ByID:
- CopterText.Text = Copter.Name;
- CopterText.Foreground = new SolidColorBrush(Colors.White);
- break;
- case CopterManager.CopterSortType.ByVID:
- case CopterManager.CopterSortType.ByVIDShowAll:
- CopterText.Text = Copter.VirtualId.ToString();
- CopterText.Foreground = new SolidColorBrush(Colors.Yellow);
- break;
- default:
- CopterText.Text = Copter.Name;
- CopterText.Foreground = new SolidColorBrush(Colors.White);
- break;
- }
-
-
-
-
- if (Copter.GetShowLEDAsync())
- blackBrush.Color = Colors.White;
- else
- blackBrush.Color = Colors.Transparent;
- Dot.Stroke = blackBrush;
-
- var trans = Dot.RenderTransform as RotateTransform;
- if (trans == null)
- {
- Dot.RenderTransform = new RotateTransform(Copter.Heading);
- }
- else
- {
- if (trans.Angle != Copter.Heading)
- {
- trans.Angle = Copter.Heading;
- }
- }
-
- if (locationUpdated)
- {
- Track.Locations.Add(location);
- DotMarker.Position = new LatLng(location.Latitude, location.Longitude).ToGCJ02();
- //MapLayer.SetPosition(Dot.Parent, location);
- this.LastLocation = location;
- }
- }
- catch (Exception ex)
- {
- _logger.Log(ex);
- }
- }
-
- public void ChangeBrush(string RGB)
- {
- //Color color = (Color)ColorConverter.ConvertFromString("#" + RGB);
-
- //_brush = new SolidColorBrush(Color.FromRgb(255, 0, 255));
- //this.Dot.Fill = _brush;
- }
-
-
-
- public void ShowWaypoint(int taskIndex)
- {
- var wpIndex = taskIndex - 1; // Waypoints 中没有起飞点。
-
- foreach (var item in this.Waypoints)
- {
- _map.Markers.Remove(item);
- }
- if (wpIndex >= 0 && wpIndex < Waypoints.Count)
- {
-
- //选中的航点
- GMapMarker wpmarker = (GMapMarker)(Waypoints[wpIndex]);
- //航点轮廓变为白色
- // wpmarker.Shape.Stroke = _selectedTaskStroke;
- _map.Markers.Add(wpmarker); //消耗大量时间费时
-
- }
-
- }
-
- public void ShowAllWaypoint()
- {
- foreach (var item in this.Waypoints)
- {
- _map.Markers.Remove(item);
- }
-
- foreach (var item in this.Waypoints)
- {
- _map.Markers.Add(item);
- }
-
-
- }
-
-
-
-
- //加入航点
- public void AddWaypoint(Location location, FlightTaskType type, FlightTask vtask)
- {
- // Add waypoint.
- LatLng gmapLatLng = new LatLng(location.Latitude, location.Longitude);
-
- //创建marker,设定位置
- GMapMarker marker = new GMapMarker(gmapLatLng.ToGCJ02());
-
- //航点默认颜色
- SolidColorBrush Waypoint_brush = new SolidColorBrush(Color.FromRgb(0, 0, 255));
- //makrer的形状,包含一个圆圈和一个选中方块
- ShapesContainer shapesContainer = new ShapesContainer(Waypoint_brush);
-
- shapesContainer.Tag = WAYPOINT_TAG;
- marker.Tag = WAYPOINT_TAG;
- //形状设置为shapesContainer
- marker.Shape = shapesContainer;
- //加入航点列表Waypoints为某架飞机的航点列表
- Waypoints.Insert(vtask.TaskIndex-1,marker);
- //该航点的飞机是否选中
- bool PontisSelected = _copterManager.SelectedCopters.Contains(Copter);
- shapesContainer.Ismark = PontisSelected;
- // 选中飞机在地图上显示一个红色方块---选中时也会调用,这儿可以不调用
- SetEffect(PontisSelected);
-
-
- //_map.Markers.Add(marker); //消耗大量时间费时 ,为了提高效率改为选中才添加见ShowWaypoint
- marker.ZIndex = 100;
- //MapLayer.SetZIndex(shapesContainer, 100);
- //var wpPos = _map.LocationToViewportPoint(location);
- //wpPos.X -= WAYPOINT_RADIUS;
- //wpPos.Y -= WAYPOINT_RADIUS;
- //MapLayer.SetPosition(shapesContainer, _map.ViewportPointToLocation(wpPos));
-
-
- // Register event handlers.
- RegisterEventHandlersForDraggingWaypoint(marker, vtask);
-
- // Register event handlers for task info.
- RegisterEventHandlersForTaskInfo(marker, vtask);
- }
-
- private void RegisterEventHandlersForDraggingCopter(GMapMarker copterMarker)
- {
- Grid copterElement = copterMarker.Shape as Grid;
- var dragMoving = false;
- double offsetX = 0;
- double offsetY = 0;
- copterElement.MouseLeftButtonDown += (sender, e) =>
- {
- _copterManager.Select(this.Copter);
- if (Copter is FakeCopter)
- {
- var posInObject = e.GetPosition(copterElement);
- offsetX = posInObject.X;
- offsetY = posInObject.Y;
-
- dragMoving = true;
- _map.CanDragMap = false;
- }
- };
- _map.MouseMove += (sender, e) =>
- {
- if (dragMoving)
- {
- var pos = e.GetPosition(_map);
- pos.X -= offsetX;
- pos.Y -= offsetY;
- copterMarker.Position = _map.FromLocalToLatLng((int)pos.X, (int)pos.Y);
- //MapLayer.SetPosition(copterElement, _map.ViewportPointToLocation(pos));
-
- //var center = _map.ViewportPointToLocation(pos);
-
-// var routePoint = this.Route.Locations[0];
-// routePoint.Latitude = center.Latitude;
-// routePoint.Longitude = center.Longitude;
-
- var fc = Copter as FakeCopter;
- fc.SetProperties(
- latitude: copterMarker.Position.ToWGS84().Lat,
- longitude: copterMarker.Position.ToWGS84().Lng
- );
- }
- };
- _map.MouseLeftButtonUp += (sender, e) =>
- {
- _map.CanDragMap = true;
- if (dragMoving) dragMoving = false;
- };
- }
-
- private Dictionary selectWayOriginPoint = new Dictionary();
- private Dictionary