支持紧急返航
支持返回飞机错误 飞机有预解锁错误回显示黄色 支持新版低电电压参数 支持重启飞控 支持陀螺仪校准
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>
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
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,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
|
||||
{
|
||||
/// <summary>
|
||||
/// ModifyParam.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// ModifyParam.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
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<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();
|
||||
}
|
||||
|
||||
private void btnLoad_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
LoadParam = true;
|
||||
this.DialogResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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" />
|
||||
|
@ -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<CopterManager>();
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始校准加速计
|
||||
/// </summary>
|
||||
private ICommand _CalibrationAccelerometerStartCommand;
|
||||
public ICommand CalibrationAccelerometerStartCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CalibrationAccelerometerStartCommand ?? (_CalibrationAccelerometerStartCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
await commModule.DoStartPreflightCompassAsync(_copterManager.SelectedCopters);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校准加速计下一步
|
||||
/// </summary>
|
||||
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; }
|
||||
/// <summary>
|
||||
/// 校准指南针
|
||||
/// </summary>
|
||||
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<CopterManager>();
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始校准加速计
|
||||
/// </summary>
|
||||
private ICommand _CalibrationAccelerometerStartCommand;
|
||||
public ICommand CalibrationAccelerometerStartCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CalibrationAccelerometerStartCommand ?? (_CalibrationAccelerometerStartCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
await commModule.DoStartPreflightCompassAsync(_copterManager.SelectedCopters);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校准加速计下一步
|
||||
/// </summary>
|
||||
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; }
|
||||
|
||||
|
||||
/// <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>
|
||||
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("放弃校准", "指南针");
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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>();
|
||||
_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,不拉开层
|
||||
|
||||
|
@ -1,40 +1,44 @@
|
||||
<Window x:Class="Plane.FormationCreator.Views.CalibrationWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
mc:Ignorable="d"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="校准" Height="320" Width="450">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="70*"/>
|
||||
<RowDefinition Height="30*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Margin="10" >
|
||||
<Label Content="加速计" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
<WrapPanel HorizontalAlignment="Center">
|
||||
<Button Content="开始校准" Width="100" Margin="10, 0"
|
||||
Command="{Binding CalibrationAccelerometerStartCommand}"/>
|
||||
<Button Content="下一步" Width="100" Margin="10, 0"
|
||||
Command="{Binding CalibrationAccelerometerNextCommand}"/>
|
||||
</WrapPanel>
|
||||
<Label Margin="0,10" Content="亮紫色:飞机水平放置(Front) 亮黄色:飞机左侧接触地面竖立放置(Left) 亮青色:飞机右侧接触地面竖立放置(Right) 紫色:飞机机头向下接触地面竖立放置(Down) 黄色:飞机机尾向下接触地面竖立放置(Up) 青色:飞机翻过来水平放置(Back)" HorizontalContentAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1" Margin="10,0,10,10">
|
||||
<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"/>
|
||||
</WrapPanel>
|
||||
<ProgressBar Margin="0,20" Height="18" Width="220" Value="{Binding CompassPercent, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
<Window x:Class="Plane.FormationCreator.Views.CalibrationWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
mc:Ignorable="d"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="校准" Height="329" Width="455">
|
||||
<Grid Margin="0,0,0,7">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="70*"/>
|
||||
<RowDefinition Height="30*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Margin="10" >
|
||||
<Label Content="加速计" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
<WrapPanel HorizontalAlignment="Center">
|
||||
<Button Content="开始校准" Width="100" Margin="10, 0"
|
||||
Command="{Binding CalibrationAccelerometerStartCommand}"/>
|
||||
<Button Content="下一步" Width="100" Margin="10, 0"
|
||||
Command="{Binding CalibrationAccelerometerNextCommand}"/>
|
||||
</WrapPanel>
|
||||
<Label Margin="0,10" Content="亮紫色:飞机水平放置(Front) 亮黄色:飞机左侧接触地面竖立放置(Left) 亮青色:飞机右侧接触地面竖立放置(Right) 紫色:飞机机头向下接触地面竖立放置(Down) 黄色:飞机机尾向下接触地面竖立放置(Up) 青色:飞机翻过来水平放置(Back)" HorizontalContentAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1" Margin="10,0,10,10">
|
||||
<Label Content="其他" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
<WrapPanel HorizontalAlignment="Center">
|
||||
<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}"/>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
@ -202,7 +202,9 @@
|
||||
Command="{Binding AllLandCommand}" />
|
||||
<Button Content="紧急返航"
|
||||
Command="{Binding EmergencyRetCommand}" />
|
||||
|
||||
|
||||
<Button Content="重设任务"
|
||||
Command="{Binding ResetRealMissionCommand}" />
|
||||
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
|
@ -1,359 +1,331 @@
|
||||
<UserControl x:Class="Plane.FormationCreator.Views.CopterInfoView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
xmlns:ec="clr-namespace:Plane.Copters;assembly=PlaneGcsSdk_Private_NET46"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="300"
|
||||
d:DataContext="{d:DesignInstance Type=ec:FakeCopter, IsDesignTimeCreatable=True}">
|
||||
|
||||
|
||||
<UserControl.Resources>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!--笔刷-->
|
||||
<LinearGradientBrush x:Key="SliderBackground" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Offset="0" Color="#59ccfc"/>
|
||||
<GradientStop Offset="0.5" Color="#00b3fe"/>
|
||||
<GradientStop Offset="1" Color="#59ccfc"/>
|
||||
</LinearGradientBrush>
|
||||
<LinearGradientBrush x:Key="SliderThumb" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Offset="0" Color="#FFD9D3E8"/>
|
||||
<!--<GradientStop Offset="1" Color="#dfdfdf"/>-->
|
||||
</LinearGradientBrush>
|
||||
<LinearGradientBrush x:Key="SliderText" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Offset="0" Color="#7cce45"/>
|
||||
<GradientStop Offset="1" Color="#4ea017"/>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<!--Slider模板-->
|
||||
<Style x:Key="Slider_RepeatButton" TargetType="RepeatButton">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RepeatButton">
|
||||
<Border Background="{StaticResource SliderBackground}" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Slider_RepeatButton1" TargetType="RepeatButton">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RepeatButton">
|
||||
<Border Background="Transparent" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Slider_Thumb" TargetType="Thumb">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Thumb">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Background="{StaticResource SliderBackground}"/>
|
||||
<Border Grid.ColumnSpan="2" CornerRadius="4" Background="{StaticResource SliderThumb}" Width="15">
|
||||
<!--<TextBlock Text="||" HorizontalAlignment="Center" VerticalAlignment="Center"/>-->
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Slider_CustomStyle" TargetType="Slider">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Slider">
|
||||
<Grid>
|
||||
<!--<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="40"/>
|
||||
</Grid.ColumnDefinitions>-->
|
||||
<Grid.Effect>
|
||||
<DropShadowEffect BlurRadius="10" ShadowDepth="1" />
|
||||
</Grid.Effect>
|
||||
<!--<Border HorizontalAlignment="Right" BorderBrush="Gray" BorderThickness="1,1,0,1" Background="{StaticResource SliderText}" Width="80" CornerRadius="8,0,0,8"/>-->
|
||||
<!--<Border Grid.Column="2" HorizontalAlignment="Right" BorderBrush="Gray" BorderThickness="0,1,1,1" Background="{StaticResource SliderText}" Width="40" CornerRadius="0,8,8,0"/>-->
|
||||
<!--<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Tag}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14"/>-->
|
||||
<!--<TextBlock Grid.Column="2" Text="{Binding ElementName=PART_Track,Path=Value,StringFormat=\{0:N0\}}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" DataContext="{Binding}" />-->
|
||||
<Border Grid.Column="1" BorderBrush="Gray" BorderThickness="1" CornerRadius="8,0,0,8">
|
||||
<Track Grid.Column="1" Name="PART_Track">
|
||||
<Track.DecreaseRepeatButton>
|
||||
<RepeatButton Style="{StaticResource Slider_RepeatButton}"
|
||||
Command="Slider.DecreaseLarge"/>
|
||||
</Track.DecreaseRepeatButton>
|
||||
<Track.IncreaseRepeatButton>
|
||||
<RepeatButton Style="{StaticResource Slider_RepeatButton1}"
|
||||
Command="Slider.IncreaseLarge"/>
|
||||
</Track.IncreaseRepeatButton>
|
||||
<Track.Thumb>
|
||||
<Thumb Style="{StaticResource Slider_Thumb}"/>
|
||||
</Track.Thumb>
|
||||
</Track>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="飞行信息" />
|
||||
<Grid>
|
||||
<Grid.Resources>
|
||||
<Style x:Key="CopterInfo_ComboBox"
|
||||
TargetType="ComboBox"
|
||||
BasedOn="{StaticResource {x:Type ComboBox}}">
|
||||
<Setter Property="MinWidth"
|
||||
Value="120" />
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Center" />
|
||||
</Style>
|
||||
<Style x:Key="CopterInfo_StackPanel"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="Orientation"
|
||||
Value="Horizontal" />
|
||||
<Setter Property="Margin"
|
||||
Value="0,2" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="180" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Orientation="Vertical">
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="ComboBox"
|
||||
BasedOn="{StaticResource CopterInfo_ComboBox}" />
|
||||
<Style TargetType="StackPanel"
|
||||
BasedOn="{StaticResource CopterInfo_StackPanel}" />
|
||||
</StackPanel.Resources>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="ID:" />
|
||||
<TextBlock Width="30" Text="{Binding Path=Id}" />
|
||||
<TextBlock Text="VID:" />
|
||||
<TextBlock Width="30" Text="{Binding Path=VirtualId}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="已连接:" />
|
||||
<ContentPresenter Content="{Binding CommModuleConnected, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="已解锁:" />
|
||||
<ContentPresenter Content="{Binding IsUnlocked, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="心跳数:" />
|
||||
<TextBlock Text="{Binding Path=HeartbeatCount}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="卫星数:" />
|
||||
<TextBlock Text="{Binding Path=SatCount}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="方向:" />
|
||||
<TextBlock Text="{Binding Path=Heading}" />
|
||||
</StackPanel>
|
||||
<!--<StackPanel>
|
||||
<TextBlock Text="Yaw:" />
|
||||
<TextBlock Text="{Binding Path=Yaw, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="纬度:" />
|
||||
<TextBlock Text="{Binding Path=Latitude}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="经度:" />
|
||||
<TextBlock Text="{Binding Path=Longitude}" />
|
||||
</StackPanel>-->
|
||||
<StackPanel>
|
||||
<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]}" />
|
||||
</StackPanel>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<!--
|
||||
<StackPanel>
|
||||
<TextBlock Text="固件版本:" />
|
||||
<TextBlock Text="{Binding FirmwareVersionText}" />
|
||||
</StackPanel>-->
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Orientation="Vertical">
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="ComboBox"
|
||||
BasedOn="{StaticResource CopterInfo_ComboBox}" />
|
||||
<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>
|
||||
<StackPanel>
|
||||
<TextBlock Text="电压值:" />
|
||||
<TextBlock Text="{Binding Path=Voltage}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="剩余电量:" />
|
||||
<TextBlock Text="{Binding Path=BatteryPer}" />
|
||||
<TextBlock Text="%" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="状态:" />
|
||||
<TextBlock Text="{Binding Path=CommModuleMode}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="纬度:" />
|
||||
<TextBlock Text="{Binding Latitude}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<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>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
<UserControl x:Class="Plane.FormationCreator.Views.CopterInfoView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
xmlns:ec="clr-namespace:Plane.Copters;assembly=PlaneGcsSdk_Private_NET46"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="300"
|
||||
d:DataContext="{d:DesignInstance Type=ec:FakeCopter, IsDesignTimeCreatable=True}">
|
||||
|
||||
|
||||
|
||||
<UserControl.Resources>
|
||||
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
</Style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!--笔刷-->
|
||||
<LinearGradientBrush x:Key="SliderBackground" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Offset="0" Color="#59ccfc"/>
|
||||
<GradientStop Offset="0.5" Color="#00b3fe"/>
|
||||
<GradientStop Offset="1" Color="#59ccfc"/>
|
||||
</LinearGradientBrush>
|
||||
<LinearGradientBrush x:Key="SliderThumb" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Offset="0" Color="#FFD9D3E8"/>
|
||||
<!--<GradientStop Offset="1" Color="#dfdfdf"/>-->
|
||||
</LinearGradientBrush>
|
||||
<LinearGradientBrush x:Key="SliderText" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Offset="0" Color="#7cce45"/>
|
||||
<GradientStop Offset="1" Color="#4ea017"/>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<!--Slider模板-->
|
||||
<Style x:Key="Slider_RepeatButton" TargetType="RepeatButton">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RepeatButton">
|
||||
<Border Background="{StaticResource SliderBackground}" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Slider_RepeatButton1" TargetType="RepeatButton">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RepeatButton">
|
||||
<Border Background="Transparent" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Slider_Thumb" TargetType="Thumb">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Thumb">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Background="{StaticResource SliderBackground}"/>
|
||||
<Border Grid.ColumnSpan="2" CornerRadius="4" Background="{StaticResource SliderThumb}" Width="15">
|
||||
<!--<TextBlock Text="||" HorizontalAlignment="Center" VerticalAlignment="Center"/>-->
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Slider_CustomStyle" TargetType="Slider">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Slider">
|
||||
<Grid>
|
||||
<!--<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="40"/>
|
||||
</Grid.ColumnDefinitions>-->
|
||||
<Grid.Effect>
|
||||
<DropShadowEffect BlurRadius="10" ShadowDepth="1" />
|
||||
</Grid.Effect>
|
||||
<!--<Border HorizontalAlignment="Right" BorderBrush="Gray" BorderThickness="1,1,0,1" Background="{StaticResource SliderText}" Width="80" CornerRadius="8,0,0,8"/>-->
|
||||
<!--<Border Grid.Column="2" HorizontalAlignment="Right" BorderBrush="Gray" BorderThickness="0,1,1,1" Background="{StaticResource SliderText}" Width="40" CornerRadius="0,8,8,0"/>-->
|
||||
<!--<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Tag}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14"/>-->
|
||||
<!--<TextBlock Grid.Column="2" Text="{Binding ElementName=PART_Track,Path=Value,StringFormat=\{0:N0\}}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" DataContext="{Binding}" />-->
|
||||
<Border Grid.Column="1" BorderBrush="Gray" BorderThickness="1" CornerRadius="8,0,0,8">
|
||||
<Track Grid.Column="1" Name="PART_Track">
|
||||
<Track.DecreaseRepeatButton>
|
||||
<RepeatButton Style="{StaticResource Slider_RepeatButton}"
|
||||
Command="Slider.DecreaseLarge"/>
|
||||
</Track.DecreaseRepeatButton>
|
||||
<Track.IncreaseRepeatButton>
|
||||
<RepeatButton Style="{StaticResource Slider_RepeatButton1}"
|
||||
Command="Slider.IncreaseLarge"/>
|
||||
</Track.IncreaseRepeatButton>
|
||||
<Track.Thumb>
|
||||
<Thumb Style="{StaticResource Slider_Thumb}"/>
|
||||
</Track.Thumb>
|
||||
</Track>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="飞行信息" />
|
||||
<Grid>
|
||||
|
||||
<Grid.Resources>
|
||||
<Style x:Key="CopterInfo_ComboBox"
|
||||
TargetType="ComboBox"
|
||||
BasedOn="{StaticResource {x:Type ComboBox}}">
|
||||
<Setter Property="MinWidth"
|
||||
Value="120" />
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Center" />
|
||||
</Style>
|
||||
<Style x:Key="CopterInfo_StackPanel"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="Orientation"
|
||||
Value="Horizontal" />
|
||||
<Setter Property="Margin"
|
||||
Value="0,2" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="180" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Orientation="Vertical" >
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="ComboBox"
|
||||
BasedOn="{StaticResource CopterInfo_ComboBox}" />
|
||||
<Style TargetType="StackPanel"
|
||||
BasedOn="{StaticResource CopterInfo_StackPanel}" />
|
||||
</StackPanel.Resources>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="ID:" />
|
||||
<TextBlock Width="30" Text="{Binding Path=Id}" />
|
||||
<TextBlock Text="VID:" />
|
||||
<TextBlock Width="30" Text="{Binding Path=VirtualId}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="已连接:" />
|
||||
<ContentPresenter Content="{Binding CommModuleConnected, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="已解锁:" />
|
||||
<ContentPresenter Content="{Binding IsUnlocked, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="心跳数:" />
|
||||
<TextBlock Text="{Binding Path=HeartbeatCount}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="卫星数:" />
|
||||
<TextBlock Text="{Binding Path=SatCount}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="方向:" />
|
||||
<TextBlock Text="{Binding Path=Heading}" />
|
||||
</StackPanel>
|
||||
<!--<StackPanel>
|
||||
<TextBlock Text="Yaw:" />
|
||||
<TextBlock Text="{Binding Path=Yaw, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="纬度:" />
|
||||
<TextBlock Text="{Binding Path=Latitude}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="经度:" />
|
||||
<TextBlock Text="{Binding Path=Longitude}" />
|
||||
</StackPanel>-->
|
||||
<StackPanel>
|
||||
<TextBlock Text="高度:" />
|
||||
<TextBlock Text="{Binding Altitude, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="锁定类型:" />
|
||||
<TextBlock Text="{Binding GpsFixType}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="预检查状态:" />
|
||||
<TextBlock Text="{Binding CopterPreCheckPassStr}"
|
||||
Foreground="{Binding CopterPreCheckPass, Converter={StaticResource PrecheckToColorConverter}}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
<StackPanel Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Orientation="Vertical">
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="ComboBox"
|
||||
BasedOn="{StaticResource CopterInfo_ComboBox}" />
|
||||
<Style TargetType="StackPanel"
|
||||
BasedOn="{StaticResource CopterInfo_StackPanel}" />
|
||||
</StackPanel.Resources>
|
||||
<StackPanel Visibility="Hidden">
|
||||
<TextBlock Text="电压值:" />
|
||||
<TextBlock Text="{Binding Path=Voltage}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="电压值:" />
|
||||
<TextBlock Text="{Binding Path=Voltage}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="剩余电量:" />
|
||||
<TextBlock Text="{Binding Path=BatteryPer}" />
|
||||
<TextBlock Text="%" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="状态:" />
|
||||
<TextBlock Text="{Binding Path=CommModuleMode}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="纬度:" />
|
||||
<TextBlock Text="{Binding Latitude}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="经度:" />
|
||||
<TextBlock Text="{Binding Longitude}" />
|
||||
</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>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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