支持紧急返航

支持返回飞机错误
飞机有预解锁错误回显示黄色
支持新版低电电压参数
支持重启飞控
支持陀螺仪校准
This commit is contained in:
pxzleo 2024-03-26 22:06:52 +08:00
parent 36875bcdc2
commit af9a86dffd
16 changed files with 1889 additions and 1648 deletions

View File

@ -75,9 +75,16 @@
<lcnv:HeartbeatCountToBrushConverter x:Key="HeartbeatCountToBrushConverter" /> <lcnv:HeartbeatCountToBrushConverter x:Key="HeartbeatCountToBrushConverter" />
<lcnv:AppModeToVisibilityConverter x:Key="AppModeToVisibilityConverter" /> <lcnv:AppModeToVisibilityConverter x:Key="AppModeToVisibilityConverter" />
<lcnv:FlightTaskStatusToFillConverter x:Key="FlightTaskStatusToFillConverter" /> <lcnv:FlightTaskStatusToFillConverter x:Key="FlightTaskStatusToFillConverter" />
<lcnv:ErrorCodeToColorConverter x:Key="ErrorCodeToColorConverter" />
<lcnv:PrecheckToColorConverter x:Key="PrecheckToColorConverter" />
<lcnv:FlightTaskStatusAndTransitionToFillConverter x:Key="FlightTaskStatusAndTransitionToFillConverter" /> <lcnv:FlightTaskStatusAndTransitionToFillConverter x:Key="FlightTaskStatusAndTransitionToFillConverter" />
<lcnv:FlightTaskIsSelectedToEffectConverter x:Key="FlightTaskIsSelectedToEffectConverter" /> <lcnv:FlightTaskIsSelectedToEffectConverter x:Key="FlightTaskIsSelectedToEffectConverter" />
</Application.Resources> </Application.Resources>
</Application> </Application>

View File

@ -1,44 +1,87 @@
using Plane.Copters; using Plane.Copters;
using Plane.FormationCreator.Formation; using Plane.FormationCreator.Formation;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Data; using System.Windows.Data;
using System.Windows.Media; using System.Windows.Media;
namespace Plane.FormationCreator.Converters namespace Plane.FormationCreator.Converters
{ {
public class HeartbeatCountToBrushConverter : IMultiValueConverter public class HeartbeatCountToBrushConverter : IMultiValueConverter
{ {
private static SolidColorBrush _zeroBrush = new SolidColorBrush(Color.FromArgb(125, 125, 125, 125)); private static SolidColorBrush _zeroBrush = new SolidColorBrush(Color.FromArgb(125, 125, 125, 125));
private static SolidColorBrush _oneBrush = Copter.DefaultBrush;
private static SolidColorBrush _zeroBrush_fault = new SolidColorBrush(Color.FromRgb(160, 140, 0));
private static SolidColorBrush _FakeCopterBrush = Copter.DefaultFakeBrush;
private static SolidColorBrush _oneBrush = Copter.DefaultBrush;
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{ private static SolidColorBrush _FakeCopterBrush = Copter.DefaultFakeBrush;
if (values[0] == DependencyProperty.UnsetValue) return _zeroBrush; private static SolidColorBrush _PreCheckNopassBrush = Copter.YellowBrush;
var heartbeatCount = (ulong)values[0]; private static SolidColorBrush _NoconnectedBrush = Copter.RedBrush;
if (heartbeatCount % 2 == 0) return _zeroBrush;
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
if (values[1] is FakeCopter) {
return _FakeCopterBrush; if (values[0] == DependencyProperty.UnsetValue) return _zeroBrush;
var heartbeatCount = (ulong)values[0];
if (values[1] is PLCopter) /* //绑定的是心跳,所以连接断开时不会调用这个转换器
return _oneBrush; //如果是真飞机,并且断开了,直接显示红色
if (values[1] is PLCopter)
var copter = values[1] as Copter; {
var plcopter = values[1] as PLCopter;
return copter == null ? _oneBrush : copter.Brush; if (!plcopter.CommModuleConnected)
} return _NoconnectedBrush;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) */
{
throw new NotSupportedException();
}
} //用于显示收到心跳的闪烁
} 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();
}
}
}

View File

@ -1,69 +1,75 @@
using Plane.Copters; using Plane.Copters;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Plane.Communication; using Plane.Communication;
using System.Threading; using System.Threading;
using System.Windows.Media; using System.Windows.Media;
namespace Plane.FormationCreator.Formation namespace Plane.FormationCreator.Formation
{ {
class Copter : PLCopter class Copter : PLCopter
{ {
public Copter(IConnection Connection, SynchronizationContext uiThreadContext) : base(Connection, uiThreadContext,false) public Copter(IConnection Connection, SynchronizationContext uiThreadContext) : base(Connection, uiThreadContext,false)
{ {
Brush = _brushes[NextBrushIndex()]; Brush = _brushes[NextBrushIndex()];
} }
public Copter(IConnection Connection, SynchronizationContext uiThreadContext, double lat, double lng) : base(Connection, uiThreadContext, false) public Copter(IConnection Connection, SynchronizationContext uiThreadContext, double lat, double lng) : base(Connection, uiThreadContext, false)
{ {
Brush = _brushes[NextBrushIndex()]; Brush = _brushes[NextBrushIndex()];
RecordLat = lat; RecordLat = lat;
RecordLng = lng; RecordLng = lng;
Latitude = lat; Latitude = lat;
Longitude = lng; Longitude = lng;
//RaiseLocationChangedIfNeeded(); //RaiseLocationChangedIfNeeded();
} }
internal static SolidColorBrush BlueBrush { get; } = new SolidColorBrush(Color.FromRgb(28, 151, 234)); 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 RedBrush { get; } = new SolidColorBrush(Color.FromRgb(255, 100, 100));
internal static SolidColorBrush GreenBrush { get; } = new SolidColorBrush(Color.FromRgb(100, 255, 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)); internal static SolidColorBrush YellowBrush { get; } = new SolidColorBrush(Color.FromRgb(255, 215, 0));
static SolidColorBrush[] _brushes = new[] static SolidColorBrush[] _brushes = new[]
{ {
new SolidColorBrush(Color.FromArgb(180, 255, 0, 0)), new SolidColorBrush(Color.FromArgb(180, 255, 0, 0)),
new SolidColorBrush(Color.FromArgb(180, 235, 97, 0)), new SolidColorBrush(Color.FromArgb(180, 235, 97, 0)),
new SolidColorBrush(Color.FromArgb(180, 255, 255, 0)), new SolidColorBrush(Color.FromArgb(180, 255, 255, 0)),
new SolidColorBrush(Color.FromArgb(180, 0, 255, 0)), new SolidColorBrush(Color.FromArgb(180, 0, 255, 0)),
new SolidColorBrush(Color.FromArgb(180, 0, 198, 255)), new SolidColorBrush(Color.FromArgb(180, 0, 198, 255)),
new SolidColorBrush(Color.FromArgb(180, 0, 122, 204)), new SolidColorBrush(Color.FromArgb(180, 0, 122, 204)),
new SolidColorBrush(Color.FromArgb(180, 174, 0, 255)) new SolidColorBrush(Color.FromArgb(180, 174, 0, 255))
}; };
static int _brushIndex = 0; static int _brushIndex = 0;
static int NextBrushIndex() static int NextBrushIndex()
{ {
return _brushIndex++ % _brushes.Length; return _brushIndex++ % _brushes.Length;
} }
//真实飞机列表默认颜色 //真实飞机列表默认颜色
internal static SolidColorBrush DefaultBrush { get; } = GreenBrush;// new SolidColorBrush(Color.FromRgb(50, 205, 50)); internal static SolidColorBrush DefaultBrush { get; } = GreenBrush;// new SolidColorBrush(Color.FromRgb(50, 205, 50));
//虚拟飞机列表默认颜色 //虚拟飞机列表默认颜色
internal static SolidColorBrush DefaultFakeBrush { get; } = BlueBrush; internal static SolidColorBrush DefaultFakeBrush { get; } = BlueBrush;
private SolidColorBrush _Brush; private SolidColorBrush _Brush;
public SolidColorBrush Brush public SolidColorBrush Brush
{ {
get { return _Brush ?? DefaultBrush; } get {
set { Set(nameof(Brush), ref _Brush, value); } if (CopterPreCheckPass)
} return _Brush ?? DefaultBrush;
} else
} return _Brush ?? YellowBrush;
}
set { Set(nameof(Brush), ref _Brush, value); }
}
}
}

View File

@ -26,6 +26,7 @@ using Newtonsoft.Json.Linq;
using GMap.NET.MapProviders; using GMap.NET.MapProviders;
using GMap.NET; using GMap.NET;
using static Plane.FormationCreator.CalculationLogLatDistance; using static Plane.FormationCreator.CalculationLogLatDistance;
using Plane.CopterManagement;
namespace Plane.FormationCreator.Formation namespace Plane.FormationCreator.Formation
{ {
@ -412,6 +413,13 @@ namespace Plane.FormationCreator.Formation
get { return _TaskState; } get { return _TaskState; }
private set { Set(nameof(TaskState), ref _TaskState, value); } 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<FlightTaskAddedEventArgs> TaskAdded;
public event EventHandler<FlightTaskDeledEventArgs> TaskDeled; public event EventHandler<FlightTaskDeledEventArgs> TaskDeled;
@ -601,6 +609,7 @@ namespace Plane.FormationCreator.Formation
/// <summary> /// <summary>
/// 起始点作为参考,设置起始点后飞行写入的数据将为相对坐标 /// 起始点作为参考,设置起始点后飞行写入的数据将为相对坐标
/// </summary> /// </summary>
@ -796,7 +805,7 @@ namespace Plane.FormationCreator.Formation
Pause(); Pause();
//等待暂停或2s超时(80*25ms) //等待暂停或2s超时(80*25ms)
int k = 0; int k = 0;
while ((TaskState != TasksStatus.Paused) || (k > 80)) while ((TaskState != TasksStatus.Paused) && (k < 80))
{ {
await Task.Delay(25).ConfigureAwait(false); await Task.Delay(25).ConfigureAwait(false);
k++; k++;
@ -2227,7 +2236,7 @@ namespace Plane.FormationCreator.Formation
} }
//新开线程异步调用ABypassB并等待返回 //新开线程异步调用ABypassB并等待返回
public async Task<(List<List<FlightRouteV2.Vector3>>,bool)> ABypassBAsync(FlightRouteV2.Vector3[] aVecs, FlightRouteV2.Vector3[] bVecs) public async Task<(List<List<FlightRouteV2.Vector3>>,bool)> ABypassBAsync(FlightRouteV2.Vector3[] aVecs, FlightRouteV2.Vector3[] bVecs, List<int> mappingId = null)
{ {
List<List<FlightRouteV2.Vector3>> ret = null; List<List<FlightRouteV2.Vector3>> ret = null;
bool isPasstmp = false; bool isPasstmp = false;
@ -2235,7 +2244,7 @@ namespace Plane.FormationCreator.Formation
var task = Task.Run(() => var task = Task.Run(() =>
{ {
cts = new CancellationTokenSource(); 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 try
{ {
@ -2277,7 +2286,7 @@ namespace Plane.FormationCreator.Formation
var task = Task.Run(() => var task = Task.Run(() =>
{ {
ret = FlyVecFun.CollisionLayer(aVecs, bVecs, taskname_a, taskname_b, Routecallback); ret = FlyVecFun.CollisionLayer(aVecs, bVecs, Routecallback);
}); });
try try
{ {
@ -2408,7 +2417,7 @@ namespace Plane.FormationCreator.Formation
/// <summary> /// <summary>
/// 自动生成航线2D和3D都用这个-------V2版使用新的碰撞检测和绕行用flybase.cs库只用于新版固件-------------- /// 自动生成航线2D和3D都用这个-------V2版使用新的碰撞检测和绕行用flybase.cs库只用于新版固件--------------
/// </summary> /// </summary>
/// <param name="Is3d">3D计算</param> /// <param name="Is3d">2D/3D计算</param>
/// <param name="Ischange">是否改变线路的结束点顺序--返回起飞点航线不能交换</param> /// <param name="Ischange">是否改变线路的结束点顺序--返回起飞点航线不能交换</param>
/// <param name="Is3dstagger">3D是否自动插入拉开层用于2D画面回起飞矩阵拉开2D画面</param> /// <param name="Is3dstagger">3D是否自动插入拉开层用于2D画面回起飞矩阵拉开2D画面</param>
public async Task OptimizeRouteMeterV2(bool Is3d = false, bool Ischange = true,bool Is3dstagger=false) 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>(); Dictionary<int, Point3D> prevTaskPoint = new Dictionary<int, Point3D>();
var stopWatch = new Stopwatch(); var stopWatch = new Stopwatch();
stopWatch.Start(); stopWatch.Start();
//ID映射列表
List<int> mappingId = new List<int>();
//设置随机数种子 //设置随机数种子
FlyVecFun.RandomSeed = (int)DateTime.Now.Ticks; FlyVecFun.RandomSeed = (int)DateTime.Now.Ticks;
@ -2435,6 +2448,8 @@ namespace Plane.FormationCreator.Formation
var prevInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i]; var prevInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i];
Point3D prevLoc = new Point3D(prevInfo.X * 100, prevInfo.TargetAlt * 100, prevInfo.Y * 100); Point3D prevLoc = new Point3D(prevInfo.X * 100, prevInfo.TargetAlt * 100, prevInfo.Y * 100);
prevTaskPoint.Add(i, prevLoc); 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_a = SelectedTaskIndex.ToString() + Tasks[SelectedTaskIndex - 1].TaskCnName;
string taskname_b = (SelectedTaskIndex+1).ToString()+SelectedTask.TaskCnName; string taskname_b = (SelectedTaskIndex+1).ToString()+SelectedTask.TaskCnName;
@ -2473,7 +2488,9 @@ namespace Plane.FormationCreator.Formation
if (Is3d) if (Is3d)
{ {
bool isPass = false; bool isPass = false;
var result= await ABypassBAsync(aVecs, bVecs);
var result= await ABypassBAsync(aVecs, bVecs, mappingId);
List<List<FlightRouteV2.Vector3>> flyret = result.Item1; List<List<FlightRouteV2.Vector3>> flyret = result.Item1;
isPass= result.Item2; isPass= result.Item2;
if ((flyret.Count == 0)&&(!isPass)) if ((flyret.Count == 0)&&(!isPass))
@ -2483,6 +2500,12 @@ namespace Plane.FormationCreator.Formation
{ {
Message.Show($"任务{SelectedTaskIndex + 1}无法直接生成3D航线尝试拉开画面"); Message.Show($"任务{SelectedTaskIndex + 1}无法直接生成3D航线尝试拉开画面");
cVecs = await NormalPullsync(aVecs, bVecs); cVecs = await NormalPullsync(aVecs, bVecs);
if (cVecs == null)
{
Message.Show($"任务不满足拉开条件,退出");
return;
}
Message.Show($"任务{SelectedTaskIndex + 1}后插入拉开层..."); Message.Show($"任务{SelectedTaskIndex + 1}后插入拉开层...");
//插入错层航点 //插入错层航点
SelectTask(SelectedTaskIndex - 1); SelectTask(SelectedTaskIndex - 1);
@ -2498,7 +2521,7 @@ namespace Plane.FormationCreator.Formation
SetTaskFlytime(SelectedTaskIndex); SetTaskFlytime(SelectedTaskIndex);
//选到最后一个航点 //选到最后一个航点
SelectTask(SelectedTaskIndex + 1); SelectTask(SelectedTaskIndex + 1);
var result1= await ABypassBAsync(cVecs, bVecs); var result1= await ABypassBAsync(cVecs, bVecs, mappingId);
flyret = result1.Item1; flyret = result1.Item1;
isPass = result1.Item2; 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() public async Task RunTaskAsync()
{ {
if (Tasks.Count == 0) return; if (Tasks.Count == 0) return;
@ -3290,7 +3368,12 @@ namespace Plane.FormationCreator.Formation
if (CurrentRunningTaskIndex == 0) if (CurrentRunningTaskIndex == 0)
{ {
taskStartTime = DateTime.Now; if (!SimRunTask(DateTime.Now))
{
Alert.Show($"模拟任务已经开始,请先停止任务!");
return;
}
Message.Show($"{DateTime.Now.ToString("HH:mm:ss")}:任务开始"); Message.Show($"{DateTime.Now.ToString("HH:mm:ss")}:任务开始");
} }
@ -3307,13 +3390,16 @@ namespace Plane.FormationCreator.Formation
await RunAsync(); await RunAsync();
taskflyTime = DateTime.Now - _taskStartTime;
if ((IsPaused ?? false) == false) if ((IsPaused ?? false) == false)
{ {
timeSpan = DateTime.Now - taskStartTime;
Message.Show($"{DateTime.Now.ToString("HH:mm:ss")}:任务结束"); 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> /// <summary>
/// 开始运行模拟任务 /// 开始运行模拟任务
@ -3330,12 +3416,13 @@ namespace Plane.FormationCreator.Formation
task.Status = FlightTaskStatus.Stop; task.Status = FlightTaskStatus.Stop;
} }
AppEx.Current.AppMode = AppMode.RunningTasks; AppEx.Current.AppMode = AppMode.RunningTasks;
StartAvoidingCrash(); //开始碰撞检测
//告诉所有飞机开始任务--模拟飞机不计算起飞延迟直接传0 //告诉所有飞机开始任务--模拟飞机不计算起飞延迟直接传0
foreach (var copter in _copterManager.Copters) foreach (var copter in _copterManager.Copters)
await copter.MissionStartAsync(0, 0, 0, 0, 0); await copter.MissionStartAsync(0, 0, 0, 0, 0);
TaskState = TasksStatus.Running; TaskState = TasksStatus.Running;
StartAvoidingCrash(); //开始碰撞检测
for (int i = CurrentRunningTaskIndex; i < Tasks.Count; i++) for (int i = CurrentRunningTaskIndex; i < Tasks.Count; i++)
{ {
var task = Tasks[i]; var task = Tasks[i];
@ -3474,6 +3561,7 @@ namespace Plane.FormationCreator.Formation
{ {
rettaskindex = i; rettaskindex = i;
taskflytime = rettime - starttime; taskflytime = rettime - starttime;
break;
} }
starttime += flyedtasktime; starttime += flyedtasktime;
} }
@ -3495,7 +3583,7 @@ namespace Plane.FormationCreator.Formation
curLoc = TaskFlyLoc(copterprvLoc, coptercurLoc, taskflytime, Tasks[rettaskindex].FlytoTime); curLoc = TaskFlyLoc(copterprvLoc, coptercurLoc, taskflytime, Tasks[rettaskindex].FlytoTime);
} }
else //正在悬停 else //正在悬停
curLoc = new PLLocation(curinfo.TargetLat, curinfo.TargetLng, 0); curLoc = new PLLocation(curinfo.TargetLat, curinfo.TargetLng, curinfo.TargetAlt);
curTaskPoint.Add(i, curLoc); curTaskPoint.Add(i, curLoc);
if (curinfo.TargetLat > taskmaxlat) if (curinfo.TargetLat > taskmaxlat)
@ -3557,15 +3645,22 @@ namespace Plane.FormationCreator.Formation
/// <summary>
/// 开始碰撞检测
/// </summary>
private async void StartAvoidingCrash() private async void StartAvoidingCrash()
{ {
await Task.Factory.StartNew(AvoidCrashtoshow); await Task.Factory.StartNew(AvoidCrashtoshow);
await Task.Factory.StartNew(LoopToAvoidCrash); await Task.Factory.StartNew(LoopToAvoidCrash);
} }
/// <summary>
/// 将碰撞显示到UI
/// </summary>
private async void AvoidCrashtoshow() private async void AvoidCrashtoshow()
{ {
while (IsPaused == false) Message.Show("开始碰撞检测");
while (TaskState != TasksStatus.Stop) //IsPaused == false
{ {
try try
{ {
@ -3585,10 +3680,14 @@ namespace Plane.FormationCreator.Formation
await Task.Delay(100).ConfigureAwait(false); await Task.Delay(100).ConfigureAwait(false);
} }
} }
Message.Show("开始碰撞检测停止");
} }
/// <summary>
/// 循环检测碰撞
/// </summary>
private async void LoopToAvoidCrash() private async void LoopToAvoidCrash()
{ {
while (IsPaused == false) while (TaskState != TasksStatus.Stop)
{ {
try try
{ {

View File

@ -183,6 +183,10 @@ namespace Plane.FormationCreator.Formation
await info.Copter.HoverAsync(); await info.Copter.HoverAsync();
return; return;
} }
if (_flightTaskManager.IsEmergencyRet == true)
{
return;
}
dtNow = DateTime.Now; dtNow = DateTime.Now;
ts = dtNow - dtLastTime; ts = dtNow - dtLastTime;
} }

View File

@ -112,6 +112,8 @@ namespace Plane.FormationCreator.Formation
info.TargetLng = info.Copter.Longitude; info.TargetLng = info.Copter.Longitude;
//info.Copter.takeOffTargetAltitude = takeOffAlt; //info.Copter.takeOffTargetAltitude = takeOffAlt;
FlightTask task = _flightTaskManager.CurrentRunningTask; FlightTask task = _flightTaskManager.CurrentRunningTask;
if (task==null)
return;
float takeflytime = task.TakeOffTime - info.TakeOffWaitTime; float takeflytime = task.TakeOffTime - info.TakeOffWaitTime;
//飞行目标,开始往上飞 //飞行目标,开始往上飞
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt, takeflytime, 1); //秒 await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt, takeflytime, 1); //秒

View File

@ -1,56 +1,65 @@
using Plane.FormationCreator.Util; using Microsoft.Practices.ServiceLocation;
using System; using Plane.FormationCreator.Util;
using System.Collections.Generic; using System;
using System.Linq; using System.Collections.Generic;
using System.Text; using System.Linq;
using System.Threading.Tasks; using System.Text;
using System.Windows; using System.Threading.Tasks;
using System.Windows.Controls; using System.Windows;
using System.Windows.Data; using System.Windows.Controls;
using System.Windows.Documents; using System.Windows.Data;
using System.Windows.Input; using System.Windows.Documents;
using System.Windows.Media; using System.Windows.Input;
using System.Windows.Media.Imaging; using System.Windows.Media;
using System.Windows.Shapes; using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Plane.FormationCreator
{ namespace Plane.FormationCreator
/// <summary> {
/// ModifyParam.xaml 的交互逻辑 /// <summary>
/// </summary> /// ModifyParam.xaml 的交互逻辑
public partial class ModifyParam : Window /// </summary>
{ public partial class ModifyParam : Window
public bool LoadParam = false; {
public ModifyParam() public bool LoadParam = false;
{ public ModifyParam()
InitializeComponent(); {
// if (!VersionControl.IsFullVersion) InitializeComponent();
// { // if (!VersionControl.IsFullVersion)
// hide_panel.Visibility = Visibility.Collapsed; // {
// textParamName.IsReadOnly = true; // hide_panel.Visibility = Visibility.Collapsed;
// btnLoad.Visibility = Visibility.Collapsed; // textParamName.IsReadOnly = true;
// // btnLoad.Visibility = Visibility.Collapsed;
// label.Visibility = Visibility.Collapsed; //
// textParamName.Visibility = Visibility.Collapsed; // label.Visibility = Visibility.Collapsed;
// } // textParamName.Visibility = Visibility.Collapsed;
} // }
}
private void btnModify_Click(object sender, RoutedEventArgs e)
{ private void btnModify_Click(object sender, RoutedEventArgs e)
LoadParam = false; {
this.DialogResult = true; LoadParam = false;
} this.DialogResult = true;
}
private void Modify_Select(object sender, RoutedEventArgs e)
{ private void Modify_Select(object sender, RoutedEventArgs e)
textParamName.Text = ((Button)sender).Tag.ToString(); {
textParamName_cn.Text = ((Button)sender).Content.ToString(); Formation.CopterManager _copterManager = ServiceLocator.Current.GetInstance<Formation.CopterManager>();
}
String strParamName = ((Button)sender).Tag.ToString();
private void btnLoad_Click(object sender, RoutedEventArgs e) if (strParamName == "FS_BATT_VOLTAGE")
{ {
LoadParam = true; if (_copterManager.FC_VER_NO >= 3)
this.DialogResult = true; 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;
}
}
}

View File

@ -166,6 +166,8 @@
<Compile Include="AppEx.cs" /> <Compile Include="AppEx.cs" />
<Compile Include="AppConfig.cs" /> <Compile Include="AppConfig.cs" />
<Compile Include="Converters\AppModeToVisibilityConverter.cs" /> <Compile Include="Converters\AppModeToVisibilityConverter.cs" />
<Compile Include="Converters\PrecheckToColorConverter.cs" />
<Compile Include="Converters\ErrorCodeToColorConverter.cs" />
<Compile Include="Converters\FlightTaskIsSelectedToEffectConverter.cs" /> <Compile Include="Converters\FlightTaskIsSelectedToEffectConverter.cs" />
<Compile Include="Converters\FlightTaskStatusAndTransitionToFillConverter.cs" /> <Compile Include="Converters\FlightTaskStatusAndTransitionToFillConverter.cs" />
<Compile Include="Converters\FlightTaskStatusToFillConverter.cs" /> <Compile Include="Converters\FlightTaskStatusToFillConverter.cs" />

View File

@ -1,222 +1,263 @@
using GalaSoft.MvvmLight; using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command; using GalaSoft.MvvmLight.Command;
using Microsoft.Practices.ServiceLocation; using Microsoft.Practices.ServiceLocation;
using Plane.CommunicationManagement; using Plane.CommunicationManagement;
using Plane.CopterManagement; using Plane.CopterManagement;
using Plane.Copters; using Plane.Copters;
using Plane.FormationCreator.Formation; using Plane.FormationCreator.Formation;
using Plane.Windows.Messages; using Plane.Windows.Messages;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
namespace Plane.FormationCreator.ViewModels namespace Plane.FormationCreator.ViewModels
{ {
public class CalibrationViewModel : ViewModelBase public class CalibrationViewModel : ViewModelBase
{ {
CommModuleManager commModule = CommModuleManager.Instance; CommModuleManager commModule = CommModuleManager.Instance;
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>(); private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
private string _AccelerometerTips; private string _AccelerometerTips;
public string AccelerometerTips public string AccelerometerTips
{ {
get get
{ {
switch (AccelerometerState) switch (AccelerometerState)
{ {
case AccelerometerStates.Idle: case AccelerometerStates.Idle:
_AccelerometerTips = "点击“开始校准”后,开始校准加速计"; _AccelerometerTips = "点击“开始校准”后,开始校准加速计";
break; break;
case AccelerometerStates.Front: case AccelerometerStates.Front:
_AccelerometerTips = "亮紫色: 飞机水平放置(Front)"; _AccelerometerTips = "亮紫色: 飞机水平放置(Front)";
break; break;
case AccelerometerStates.Left: case AccelerometerStates.Left:
_AccelerometerTips = "亮黄色:飞机左侧接触地面竖立放置(Left)"; _AccelerometerTips = "亮黄色:飞机左侧接触地面竖立放置(Left)";
break; break;
case AccelerometerStates.Right: case AccelerometerStates.Right:
_AccelerometerTips = "亮青色:飞机右侧接触地面竖立放置(Right)"; _AccelerometerTips = "亮青色:飞机右侧接触地面竖立放置(Right)";
break; break;
case AccelerometerStates.Down: case AccelerometerStates.Down:
_AccelerometerTips = "紫色:飞机机头向下接触地面竖立放置(Down)"; _AccelerometerTips = "紫色:飞机机头向下接触地面竖立放置(Down)";
break; break;
case AccelerometerStates.Up: case AccelerometerStates.Up:
_AccelerometerTips = "黄色:飞机机尾向下接触地面竖立放置(Up)"; _AccelerometerTips = "黄色:飞机机尾向下接触地面竖立放置(Up)";
break; break;
case AccelerometerStates.Back: case AccelerometerStates.Back:
_AccelerometerTips = "青色:飞机翻过来水平放置(Back)"; _AccelerometerTips = "青色:飞机翻过来水平放置(Back)";
break; break;
} }
return _AccelerometerTips; return _AccelerometerTips;
} }
} }
private string _AccelerometerBtnText = "开始校准"; private string _AccelerometerBtnText = "开始校准";
public string AccelerometerBtnText public string AccelerometerBtnText
{ {
get get
{ {
switch (AccelerometerState) switch (AccelerometerState)
{ {
case AccelerometerStates.Idle: case AccelerometerStates.Idle:
_AccelerometerBtnText = "开始校准"; _AccelerometerBtnText = "开始校准";
break; break;
default: default:
_AccelerometerBtnText = "完成"; _AccelerometerBtnText = "完成";
break; break;
} }
return _AccelerometerBtnText; return _AccelerometerBtnText;
} }
} }
//校准加速计的状态 //校准加速计的状态
public enum AccelerometerStates public enum AccelerometerStates
{ {
Idle = 0, Idle = 0,
Front = 1, Front = 1,
Left = 2, Left = 2,
Right = 3, Right = 3,
Down = 4, Down = 4,
Up = 5, Up = 5,
Back = 6 Back = 6
} }
private AccelerometerStates _AccelerometerState = AccelerometerStates.Idle; private AccelerometerStates _AccelerometerState = AccelerometerStates.Idle;
public AccelerometerStates AccelerometerState public AccelerometerStates AccelerometerState
{ {
get { return _AccelerometerState; } get { return _AccelerometerState; }
set set
{ {
Set(nameof(AccelerometerState), ref _AccelerometerState, value); Set(nameof(AccelerometerState), ref _AccelerometerState, value);
RaisePropertyChanged(nameof(AccelerometerBtnText)); RaisePropertyChanged(nameof(AccelerometerBtnText));
RaisePropertyChanged(nameof(AccelerometerTips)); RaisePropertyChanged(nameof(AccelerometerTips));
} }
} }
/// <summary> /// <summary>
/// 开始校准加速计 /// 开始校准加速计
/// </summary> /// </summary>
private ICommand _CalibrationAccelerometerStartCommand; private ICommand _CalibrationAccelerometerStartCommand;
public ICommand CalibrationAccelerometerStartCommand public ICommand CalibrationAccelerometerStartCommand
{ {
get get
{ {
return _CalibrationAccelerometerStartCommand ?? (_CalibrationAccelerometerStartCommand = new RelayCommand(async () => return _CalibrationAccelerometerStartCommand ?? (_CalibrationAccelerometerStartCommand = new RelayCommand(async () =>
{ {
if (_copterManager.SelectedCopters.Count() == 0) return; if (_copterManager.SelectedCopters.Count() == 0) return;
await commModule.DoStartPreflightCompassAsync(_copterManager.SelectedCopters); await commModule.DoStartPreflightCompassAsync(_copterManager.SelectedCopters);
})); }));
} }
} }
/// <summary> /// <summary>
/// 校准加速计下一步 /// 校准加速计下一步
/// </summary> /// </summary>
private ICommand _CalibrationAccelerometerNextCommand; private ICommand _CalibrationAccelerometerNextCommand;
public ICommand CalibrationAccelerometerNextCommand public ICommand CalibrationAccelerometerNextCommand
{ {
get get
{ {
return _CalibrationAccelerometerNextCommand ?? (_CalibrationAccelerometerNextCommand = new RelayCommand(async () => return _CalibrationAccelerometerNextCommand ?? (_CalibrationAccelerometerNextCommand = new RelayCommand(async () =>
{ {
if (_copterManager.SelectedCopters.Count() == 0) return; if (_copterManager.SelectedCopters.Count() == 0) return;
await commModule.DoNextPreflightCompassAsync(_copterManager.SelectedCopters); await commModule.DoNextPreflightCompassAsync(_copterManager.SelectedCopters);
})); }));
} }
} }
private int _CompassPercent; private int _CompassPercent;
public int CompassPercent public int CompassPercent
{ {
get { return _CompassPercent; } get { return _CompassPercent; }
set set
{ {
Set(nameof(CompassPercent), ref _CompassPercent, value); Set(nameof(CompassPercent), ref _CompassPercent, value);
} }
} }
public bool IsCalibration { get; set; } public bool IsCalibration { get; set; }
/// <summary>
/// 校准指南针
/// </summary> /// <summary>
private ICommand _CalibrationCompassCommand; /// 重启飞控
public ICommand CalibrationCompassCommand /// </summary>
{ private ICommand _RestartFCCommand;
get public ICommand RestartFCCommand
{ {
return _CalibrationCompassCommand ?? (_CalibrationCompassCommand = new RelayCommand(async () => get
{ {
if (_copterManager.SelectedCopters.Count() == 0) return; return _RestartFCCommand ?? (_RestartFCCommand = new RelayCommand(async () =>
{
// ICopter copter = _copterManager.SelectedCopters.FirstOrDefault(); if (_copterManager.SelectedCopters.Count() == 0) return;
// Message.Show("重启飞控");
// short copterId = short.Parse(copter.Name); await commModule.DoRestartFCAsync(_copterManager.SelectedCopters);
Message.Show("开始校准指南针"); await Task.Delay(50).ConfigureAwait(false);
}));
await commModule.DoCalibrationCompassAsync(_copterManager.SelectedCopters); }
await Task.Delay(50).ConfigureAwait(false); }
/*
/// <summary>
IsCalibration = true; /// 陀螺仪校准
CompassPercent = 0; /// </summary>
int State = 0; //4成功 5失败 todo 改为枚举 private ICommand _CalibrationPreflightCommand;
public ICommand CalibrationPreflightCommand
{
while (IsCalibration && CompassPercent <= 100) get
{ {
//两个255的时候表示 当前预留字节代表的意思是校准 return _CalibrationPreflightCommand ?? (_CalibrationPreflightCommand = new RelayCommand(async () =>
if (copter.Retain[2] == 255 && copter.Retain[3] == 255) {
{ if (_copterManager.SelectedCopters.Count() == 0) return;
CompassPercent = copter.Retain[0]; Message.Show("开始校准陀螺仪");
State = copter.Retain[1]; await commModule.DoCalibrationPreflightAsync(_copterManager.SelectedCopters);
if (State == 4 || State == 5) await Task.Delay(50).ConfigureAwait(false);
break; }));
} }
}
await Task.Delay(100);
}
switch (State) /// <summary>
{ /// 校准指南针
case 4: /// </summary>
Alert.Show($"校准成功,请重新上电{copterId}号", "指南针"); private ICommand _CalibrationCompassCommand;
break; public ICommand CalibrationCompassCommand
case 5: {
Alert.Show("校准失败", "指南针"); get
break; {
default: return _CalibrationCompassCommand ?? (_CalibrationCompassCommand = new RelayCommand(async () =>
break; {
} if (_copterManager.SelectedCopters.Count() == 0) return;
IsCalibration = false; // ICopter copter = _copterManager.SelectedCopters.FirstOrDefault();
*/ //
})); // short copterId = short.Parse(copter.Name);
} Message.Show("开始校准指南针");
}
await commModule.DoCalibrationCompassAsync(_copterManager.SelectedCopters);
private ICommand _CancelCalibrationCompassCommand; await Task.Delay(50).ConfigureAwait(false);
public ICommand CancelCalibrationCompassCommand
{ /*
get
{ IsCalibration = true;
return _CancelCalibrationCompassCommand ?? (_CancelCalibrationCompassCommand = new RelayCommand(async () => CompassPercent = 0;
{ int State = 0; //4成功 5失败 todo 改为枚举
if (_copterManager.SelectedCopters.Count() == 1) return;
ICopter copter = _copterManager.SelectedCopters.FirstOrDefault(); while (IsCalibration && CompassPercent <= 100)
{
short copterId = short.Parse(copter.Name); //两个255的时候表示 当前预留字节代表的意思是校准
await commModule.DoCancelCalibrationCompassAsync(copterId); if (copter.Retain[2] == 255 && copter.Retain[3] == 255)
IsCalibration = false; {
Alert.Show("放弃校准", "指南针"); 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("放弃校准", "指南针");
}));
}
}
}
}

View File

@ -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; private ICommand _EmergencyRetCommand;
public ICommand EmergencyRetCommand public ICommand EmergencyRetCommand
{ {
@ -402,23 +416,45 @@ namespace Plane.FormationCreator.ViewModels
{ {
return _EmergencyRetCommand ?? (_EmergencyRetCommand = new RelayCommand(async () => return _EmergencyRetCommand ?? (_EmergencyRetCommand = new RelayCommand(async () =>
{ {
if (Alert.Show("您确定要紧急返航吗?紧急返航可能导致飞行器碰撞!!!!", "警告", MessageBoxButton.OKCancel, MessageBoxImage.Warning)
!= MessageBoxResult.OK)
return; //计算当前图案中心点,起飞图案中心点,图案距离起飞图案中心点最近距离
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>(); 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 takeoffcentloc;
PLLocation taskcentloc; PLLocation taskcentloc;
double mindistance; //单位米 double mindistance; //单位米
bool overlapping; //图案否重叠 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)) if (!_flightTaskManager.EmergencyRet(rettime,out takeoffcentloc,out taskcentloc, out mindistance,out overlapping))
{ {
Alert.Show("紧急返航数据计算失败!", "提示"); Alert.Show("紧急返航数据计算失败!", "提示");
return; return;
} }
rettime += 5; //加5秒延迟用于通讯重复有些飞机通讯不成功多次发送才收到比别的飞机慢
//模拟测试 //模拟测试
if (_flightTaskManager.TaskState != TasksStatus.Stop) if (_flightTaskManager.TaskState != TasksStatus.Stop)
await _flightTaskManager.sim_DoMissionEmergencyRetAsync(takeoffcentloc, taskcentloc, (float)mindistance, rettime, overlapping); 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(1000).ConfigureAwait(false);
} }
await Task.Delay(100); 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 => { await Task.WhenAll(_copterManager.Copters.Select(async c => {
@ -1440,9 +1477,22 @@ namespace Plane.FormationCreator.ViewModels
Alert.Show("作为参照的原点未设置,无法开始任务!", "提示"); Alert.Show("作为参照的原点未设置,无法开始任务!", "提示");
return; return;
} }
if (_flightTaskManager.Tasks.Count == 0 )
{
if (Alert.Show("没有导入任务,紧急返航功能不能使用,继续吗?", "警告", MessageBoxButton.OKCancel, MessageBoxImage.Warning)
!= MessageBoxResult.OK)
return;
}
//飞机用UTC时间日志用本地时间记录 //飞机用UTC时间日志用本地时间记录
DateTime MissionTime = DateTime.UtcNow.AddSeconds(5); DateTime MissionTime = DateTime.UtcNow.AddSeconds(5);
DateTime MissionTime_log = DateTime.Now.AddSeconds(5); DateTime MissionTime_log = DateTime.Now.AddSeconds(5);
if (!_flightTaskManager.RealRunTask(MissionTime))
{
Alert.Show("任务已经开始,请先重设任务!", "提示");
return;
}
AllowMissionStart = false;
Message.Show("任务开始:" + MissionTime_log.ToString()); Message.Show("任务开始:" + MissionTime_log.ToString());
//循环3次 发送起飞命令 避免通信问题 //循环3次 发送起飞命令 避免通信问题
for (int i = 0; i < 20; i++) //20 for (int i = 0; i < 20; i++) //20

View File

@ -959,8 +959,8 @@ namespace Plane.FormationCreator.ViewModels
return _OptimizeRouteCommandRet ?? (_OptimizeRouteCommandRet = new RelayCommand<int>(async => return _OptimizeRouteCommandRet ?? (_OptimizeRouteCommandRet = new RelayCommand<int>(async =>
{ {
if (_copterManager.FC_VER_NO >= 3) if (_copterManager.FC_VER_NO >= 3)
//3D计算不改变ID可以错层 //2D计算不改变ID不用错层
_flightTaskManager.OptimizeRouteMeter(false, false, true); //采用米计算逻辑用3D生成不改变ID可拉开层(2D回起飞矩阵专用) _flightTaskManager.OptimizeRouteMeter(false, false, false); //采用米计算逻辑用3D生成不改变ID可拉开层(2D回起飞矩阵专用)
else else
_flightTaskManager.OptimizeRouteMeter(false, false); //采用米计算逻辑用2D生成不改变ID不拉开层 _flightTaskManager.OptimizeRouteMeter(false, false); //采用米计算逻辑用2D生成不改变ID不拉开层
@ -978,7 +978,7 @@ namespace Plane.FormationCreator.ViewModels
{ {
if (_copterManager.FC_VER_NO >= 3) if (_copterManager.FC_VER_NO >= 3)
//3D计算不改变ID可以错层 //3D计算不改变ID可以错层
_flightTaskManager.OptimizeRouteMeter(true, false, false); //采用米计算逻辑用3D生成不改变ID拉开层(3D回起飞矩阵专用) _flightTaskManager.OptimizeRouteMeter(true, false, true); //采用米计算逻辑用3D生成不改变ID拉开层(3D回起飞矩阵专用,结束必须是矩阵)
else else
_flightTaskManager.OptimizeRouteMeter(false, false); //采用米计算逻辑用2D生成不改变ID不拉开层 _flightTaskManager.OptimizeRouteMeter(false, false); //采用米计算逻辑用2D生成不改变ID不拉开层

View File

@ -1,40 +1,44 @@
<Window x:Class="Plane.FormationCreator.Views.CalibrationWindow" <Window x:Class="Plane.FormationCreator.Views.CalibrationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Plane.FormationCreator.Views" xmlns:local="clr-namespace:Plane.FormationCreator.Views"
mc:Ignorable="d" mc:Ignorable="d"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
Title="校准" Height="320" Width="450"> Title="校准" Height="329" Width="455">
<Grid> <Grid Margin="0,0,0,7">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="70*"/> <RowDefinition Height="70*"/>
<RowDefinition Height="30*"/> <RowDefinition Height="30*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<StackPanel Margin="10" > <StackPanel Margin="10" >
<Label Content="加速计" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/> <Label Content="加速计" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
<WrapPanel HorizontalAlignment="Center"> <WrapPanel HorizontalAlignment="Center">
<Button Content="开始校准" Width="100" Margin="10, 0" <Button Content="开始校准" Width="100" Margin="10, 0"
Command="{Binding CalibrationAccelerometerStartCommand}"/> Command="{Binding CalibrationAccelerometerStartCommand}"/>
<Button Content="下一步" Width="100" Margin="10, 0" <Button Content="下一步" Width="100" Margin="10, 0"
Command="{Binding CalibrationAccelerometerNextCommand}"/> Command="{Binding CalibrationAccelerometerNextCommand}"/>
</WrapPanel> </WrapPanel>
<Label Margin="0,10" Content="亮紫色:飞机水平放置(Front)&#13;亮黄色:飞机左侧接触地面竖立放置(Left)&#13;亮青色:飞机右侧接触地面竖立放置(Right)&#13;紫色:飞机机头向下接触地面竖立放置(Down)&#13;黄色:飞机机尾向下接触地面竖立放置(Up)&#13;青色:飞机翻过来水平放置(Back)" HorizontalContentAlignment="Center"/> <Label Margin="0,10" Content="亮紫色:飞机水平放置(Front)&#13;亮黄色:飞机左侧接触地面竖立放置(Left)&#13;亮青色:飞机右侧接触地面竖立放置(Right)&#13;紫色:飞机机头向下接触地面竖立放置(Down)&#13;黄色:飞机机尾向下接触地面竖立放置(Up)&#13;青色:飞机翻过来水平放置(Back)" HorizontalContentAlignment="Center"/>
</StackPanel> </StackPanel>
<StackPanel Grid.Row="1" Margin="10,0,10,10"> <StackPanel Grid.Row="1" Margin="10,0,10,10">
<Label Content="指南针" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/> <Label Content="其他" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
<WrapPanel HorizontalAlignment="Center"> <WrapPanel HorizontalAlignment="Center">
<Button Content="开始校准" Width="100" Margin="10, 0" <Button Content="放弃校准" Width="100" Margin="10, 0"
Command="{Binding CalibrationCompassCommand}"/> Command="{Binding CancelCalibrationCompassCommand}" Visibility="Collapsed"/>
<Button Content="放弃校准" Width="100" Margin="10, 0" <Button Content="校准指南针" Width="120"
Command="{Binding CancelCalibrationCompassCommand}" Visibility="Collapsed"/> Command="{Binding CalibrationCompassCommand}"/>
</WrapPanel> <Button Content="校准陀螺仪" Width="120" Margin="20, 0"
<ProgressBar Margin="0,20" Height="18" Width="220" Value="{Binding CompassPercent, UpdateSourceTrigger=PropertyChanged}"/> Command="{Binding CalibrationPreflightCommand}"/>
<Button Content="重启飞控" Width="100" Margin="10, 0"
Command="{Binding RestartFCCommand}"/>
</StackPanel> </WrapPanel>
</Grid> <ProgressBar Margin="0,20" Height="18" Width="220" Value="{Binding CompassPercent, UpdateSourceTrigger=PropertyChanged}"/>
</Window>
</StackPanel>
</Grid>
</Window>

View File

@ -202,7 +202,9 @@
Command="{Binding AllLandCommand}" /> Command="{Binding AllLandCommand}" />
<Button Content="紧急返航" <Button Content="紧急返航"
Command="{Binding EmergencyRetCommand}" /> Command="{Binding EmergencyRetCommand}" />
<Button Content="重设任务"
Command="{Binding ResetRealMissionCommand}" />
</WrapPanel> </WrapPanel>
</StackPanel> </StackPanel>

View File

@ -1,359 +1,331 @@
<UserControl x:Class="Plane.FormationCreator.Views.CopterInfoView" <UserControl x:Class="Plane.FormationCreator.Views.CopterInfoView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Plane.FormationCreator.Views" xmlns:local="clr-namespace:Plane.FormationCreator.Views"
xmlns:ec="clr-namespace:Plane.Copters;assembly=PlaneGcsSdk_Private_NET46" xmlns:ec="clr-namespace:Plane.Copters;assembly=PlaneGcsSdk_Private_NET46"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="300" d:DesignHeight="300"
d:DesignWidth="300" d:DesignWidth="300"
d:DataContext="{d:DesignInstance Type=ec:FakeCopter, IsDesignTimeCreatable=True}"> d:DataContext="{d:DesignInstance Type=ec:FakeCopter, IsDesignTimeCreatable=True}">
<UserControl.Resources>
<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 x:Key="SliderBackground" StartPoint="0,0" EndPoint="0,1">
</LinearGradientBrush> <GradientStop Offset="0" Color="#59ccfc"/>
<LinearGradientBrush x:Key="SliderThumb" StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0.5" Color="#00b3fe"/>
<GradientStop Offset="0" Color="#FFD9D3E8"/> <GradientStop Offset="1" Color="#59ccfc"/>
<!--<GradientStop Offset="1" Color="#dfdfdf"/>--> </LinearGradientBrush>
</LinearGradientBrush> <LinearGradientBrush x:Key="SliderThumb" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush x:Key="SliderText" StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0" Color="#FFD9D3E8"/>
<GradientStop Offset="0" Color="#7cce45"/> <!--<GradientStop Offset="1" Color="#dfdfdf"/>-->
<GradientStop Offset="1" Color="#4ea017"/> </LinearGradientBrush>
</LinearGradientBrush> <LinearGradientBrush x:Key="SliderText" StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#7cce45"/>
<!--Slider模板--> <GradientStop Offset="1" Color="#4ea017"/>
<Style x:Key="Slider_RepeatButton" TargetType="RepeatButton"> </LinearGradientBrush>
<Setter Property="Focusable" Value="false" />
<Setter Property="Template"> <!--Slider模板-->
<Setter.Value> <Style x:Key="Slider_RepeatButton" TargetType="RepeatButton">
<ControlTemplate TargetType="RepeatButton"> <Setter Property="Focusable" Value="false" />
<Border Background="{StaticResource SliderBackground}" /> <Setter Property="Template">
</ControlTemplate> <Setter.Value>
</Setter.Value> <ControlTemplate TargetType="RepeatButton">
</Setter> <Border Background="{StaticResource SliderBackground}" />
</Style> </ControlTemplate>
</Setter.Value>
<Style x:Key="Slider_RepeatButton1" TargetType="RepeatButton"> </Setter>
<Setter Property="Focusable" Value="false" /> </Style>
<Setter Property="Template">
<Setter.Value> <Style x:Key="Slider_RepeatButton1" TargetType="RepeatButton">
<ControlTemplate TargetType="RepeatButton"> <Setter Property="Focusable" Value="false" />
<Border Background="Transparent" /> <Setter Property="Template">
</ControlTemplate> <Setter.Value>
</Setter.Value> <ControlTemplate TargetType="RepeatButton">
</Setter> <Border Background="Transparent" />
</Style> </ControlTemplate>
</Setter.Value>
<Style x:Key="Slider_Thumb" TargetType="Thumb"> </Setter>
<Setter Property="Focusable" Value="false" /> </Style>
<Setter Property="Template">
<Setter.Value> <Style x:Key="Slider_Thumb" TargetType="Thumb">
<ControlTemplate TargetType="Thumb"> <Setter Property="Focusable" Value="false" />
<Grid> <Setter Property="Template">
<Grid.ColumnDefinitions> <Setter.Value>
<ColumnDefinition/> <ControlTemplate TargetType="Thumb">
<ColumnDefinition/> <Grid>
</Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<Border Background="{StaticResource SliderBackground}"/> <ColumnDefinition/>
<Border Grid.ColumnSpan="2" CornerRadius="4" Background="{StaticResource SliderThumb}" Width="15"> <ColumnDefinition/>
<!--<TextBlock Text="||" HorizontalAlignment="Center" VerticalAlignment="Center"/>--> </Grid.ColumnDefinitions>
</Border> <Border Background="{StaticResource SliderBackground}"/>
</Grid> <Border Grid.ColumnSpan="2" CornerRadius="4" Background="{StaticResource SliderThumb}" Width="15">
</ControlTemplate> <!--<TextBlock Text="||" HorizontalAlignment="Center" VerticalAlignment="Center"/>-->
</Setter.Value> </Border>
</Setter> </Grid>
</Style> </ControlTemplate>
</Setter.Value>
<Style x:Key="Slider_CustomStyle" TargetType="Slider"> </Setter>
<Setter Property="Focusable" Value="false" /> </Style>
<Setter Property="Template">
<Setter.Value> <Style x:Key="Slider_CustomStyle" TargetType="Slider">
<ControlTemplate TargetType="Slider"> <Setter Property="Focusable" Value="false" />
<Grid> <Setter Property="Template">
<!--<Grid.ColumnDefinitions> <Setter.Value>
<ColumnDefinition Width="80"/> <ControlTemplate TargetType="Slider">
<ColumnDefinition/> <Grid>
<ColumnDefinition Width="40"/> <!--<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>--> <ColumnDefinition Width="80"/>
<Grid.Effect> <ColumnDefinition/>
<DropShadowEffect BlurRadius="10" ShadowDepth="1" /> <ColumnDefinition Width="40"/>
</Grid.Effect> </Grid.ColumnDefinitions>-->
<!--<Border HorizontalAlignment="Right" BorderBrush="Gray" BorderThickness="1,1,0,1" Background="{StaticResource SliderText}" Width="80" CornerRadius="8,0,0,8"/>--> <Grid.Effect>
<!--<Border Grid.Column="2" HorizontalAlignment="Right" BorderBrush="Gray" BorderThickness="0,1,1,1" Background="{StaticResource SliderText}" Width="40" CornerRadius="0,8,8,0"/>--> <DropShadowEffect BlurRadius="10" ShadowDepth="1" />
<!--<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Tag}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14"/>--> </Grid.Effect>
<!--<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 HorizontalAlignment="Right" BorderBrush="Gray" BorderThickness="1,1,0,1" Background="{StaticResource SliderText}" Width="80" CornerRadius="8,0,0,8"/>-->
<Border Grid.Column="1" BorderBrush="Gray" BorderThickness="1" 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"/>-->
<Track Grid.Column="1" Name="PART_Track"> <!--<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Tag}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14"/>-->
<Track.DecreaseRepeatButton> <!--<TextBlock Grid.Column="2" Text="{Binding ElementName=PART_Track,Path=Value,StringFormat=\{0:N0\}}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" DataContext="{Binding}" />-->
<RepeatButton Style="{StaticResource Slider_RepeatButton}" <Border Grid.Column="1" BorderBrush="Gray" BorderThickness="1" CornerRadius="8,0,0,8">
Command="Slider.DecreaseLarge"/> <Track Grid.Column="1" Name="PART_Track">
</Track.DecreaseRepeatButton> <Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton> <RepeatButton Style="{StaticResource Slider_RepeatButton}"
<RepeatButton Style="{StaticResource Slider_RepeatButton1}" Command="Slider.DecreaseLarge"/>
Command="Slider.IncreaseLarge"/> </Track.DecreaseRepeatButton>
</Track.IncreaseRepeatButton> <Track.IncreaseRepeatButton>
<Track.Thumb> <RepeatButton Style="{StaticResource Slider_RepeatButton1}"
<Thumb Style="{StaticResource Slider_Thumb}"/> Command="Slider.IncreaseLarge"/>
</Track.Thumb> </Track.IncreaseRepeatButton>
</Track> <Track.Thumb>
</Border> <Thumb Style="{StaticResource Slider_Thumb}"/>
</Grid> </Track.Thumb>
</ControlTemplate> </Track>
</Setter.Value> </Border>
</Setter> </Grid>
</Style> </ControlTemplate>
</UserControl.Resources> </Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel>
<TextBlock Text="飞行信息" />
<Grid>
<Grid.Resources> <StackPanel>
<Style x:Key="CopterInfo_ComboBox" <TextBlock Text="飞行信息" />
TargetType="ComboBox" <Grid>
BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="MinWidth" <Grid.Resources>
Value="120" /> <Style x:Key="CopterInfo_ComboBox"
<Setter Property="VerticalAlignment" TargetType="ComboBox"
Value="Center" /> BasedOn="{StaticResource {x:Type ComboBox}}">
</Style> <Setter Property="MinWidth"
<Style x:Key="CopterInfo_StackPanel" Value="120" />
TargetType="StackPanel"> <Setter Property="VerticalAlignment"
<Setter Property="Orientation" Value="Center" />
Value="Horizontal" /> </Style>
<Setter Property="Margin" <Style x:Key="CopterInfo_StackPanel"
Value="0,2" /> TargetType="StackPanel">
</Style> <Setter Property="Orientation"
</Grid.Resources> Value="Horizontal" />
<Setter Property="Margin"
<Grid.ColumnDefinitions> Value="0,2" />
<ColumnDefinition Width="180" /> </Style>
<ColumnDefinition Width="Auto" /> </Grid.Resources>
</Grid.ColumnDefinitions>
<Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical"> <ColumnDefinition Width="180" />
<StackPanel.Resources> <ColumnDefinition Width="Auto" />
<Style TargetType="ComboBox" </Grid.ColumnDefinitions>
BasedOn="{StaticResource CopterInfo_ComboBox}" />
<Style TargetType="StackPanel" <StackPanel Orientation="Vertical" >
BasedOn="{StaticResource CopterInfo_StackPanel}" /> <StackPanel.Resources>
</StackPanel.Resources> <Style TargetType="ComboBox"
BasedOn="{StaticResource CopterInfo_ComboBox}" />
<StackPanel> <Style TargetType="StackPanel"
<TextBlock Text="ID" /> BasedOn="{StaticResource CopterInfo_StackPanel}" />
<TextBlock Width="30" Text="{Binding Path=Id}" /> </StackPanel.Resources>
<TextBlock Text="VID" />
<TextBlock Width="30" Text="{Binding Path=VirtualId}" /> <StackPanel>
</StackPanel> <TextBlock Text="ID" />
<StackPanel> <TextBlock Width="30" Text="{Binding Path=Id}" />
<TextBlock Text="已连接:" /> <TextBlock Text="VID" />
<ContentPresenter Content="{Binding CommModuleConnected, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" /> <TextBlock Width="30" Text="{Binding Path=VirtualId}" />
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="已解锁:" /> <TextBlock Text="已连接:" />
<ContentPresenter Content="{Binding IsUnlocked, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" /> <ContentPresenter Content="{Binding CommModuleConnected, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="心跳数:" /> <TextBlock Text="已解锁:" />
<TextBlock Text="{Binding Path=HeartbeatCount}" /> <ContentPresenter Content="{Binding IsUnlocked, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="卫星数:" /> <TextBlock Text="心跳数:" />
<TextBlock Text="{Binding Path=SatCount}" /> <TextBlock Text="{Binding Path=HeartbeatCount}" />
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="方向:" /> <TextBlock Text="卫星数:" />
<TextBlock Text="{Binding Path=Heading}" /> <TextBlock Text="{Binding Path=SatCount}" />
</StackPanel> </StackPanel>
<!--<StackPanel> <StackPanel>
<TextBlock Text="Yaw" /> <TextBlock Text="方向:" />
<TextBlock Text="{Binding Path=Yaw, StringFormat=0.##}" /> <TextBlock Text="{Binding Path=Heading}" />
</StackPanel> </StackPanel>
<StackPanel> <!--<StackPanel>
<TextBlock Text="纬度:" /> <TextBlock Text="Yaw" />
<TextBlock Text="{Binding Path=Latitude}" /> <TextBlock Text="{Binding Path=Yaw, StringFormat=0.##}" />
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="经度:" /> <TextBlock Text="纬度:" />
<TextBlock Text="{Binding Path=Longitude}" /> <TextBlock Text="{Binding Path=Latitude}" />
</StackPanel>--> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="高度:" /> <TextBlock Text="经度:" />
<TextBlock Text="{Binding Altitude, StringFormat=0.##}" /> <TextBlock Text="{Binding Path=Longitude}" />
</StackPanel> </StackPanel>-->
<StackPanel> <StackPanel>
<TextBlock Text="距离:" /> <TextBlock Text="高度:" />
<TextBlock Text="{Binding FlightDistance, StringFormat=0.##}" /> <TextBlock Text="{Binding Altitude, StringFormat=0.##}" />
</StackPanel> </StackPanel>
<StackPanel>
<TextBlock Text="锁定类型:" /> <StackPanel>
<TextBlock Text="{Binding GpsFixType}" /> <TextBlock Text="锁定类型:" />
</StackPanel> <TextBlock Text="{Binding GpsFixType}" />
<StackPanel> </StackPanel>
<TextBlock Text="返回数据:" /> <StackPanel>
<StackPanel ToolTip="{Binding RetainInt}"> <TextBlock Text="预检查状态:" />
<TextBlock Text="{Binding Retain[3]}" /> <TextBlock Text="{Binding CopterPreCheckPassStr}"
<TextBlock Text="." /> Foreground="{Binding CopterPreCheckPass, Converter={StaticResource PrecheckToColorConverter}}" />
<TextBlock Text="{Binding Retain[2]}" /> </StackPanel>
<TextBlock Text="." /> </StackPanel>
<TextBlock Text="{Binding Retain[1]}" />
<TextBlock Text="." />
<TextBlock Text="{Binding Retain[0]}" /> <StackPanel Grid.Row="1"
</StackPanel> Grid.Column="1"
Orientation="Vertical">
<StackPanel.Resources>
</StackPanel> <Style TargetType="ComboBox"
BasedOn="{StaticResource CopterInfo_ComboBox}" />
<!-- <Style TargetType="StackPanel"
<StackPanel> BasedOn="{StaticResource CopterInfo_StackPanel}" />
<TextBlock Text="固件版本:" /> </StackPanel.Resources>
<TextBlock Text="{Binding FirmwareVersionText}" /> <StackPanel Visibility="Hidden">
</StackPanel>--> <TextBlock Text="电压值:" />
</StackPanel> <TextBlock Text="{Binding Path=Voltage}" />
</StackPanel>
<StackPanel Grid.Row="1"
Grid.Column="1" <StackPanel>
Orientation="Vertical"> <TextBlock Text="电压值:" />
<StackPanel.Resources> <TextBlock Text="{Binding Path=Voltage}" />
<Style TargetType="ComboBox" </StackPanel>
BasedOn="{StaticResource CopterInfo_ComboBox}" /> <StackPanel>
<Style TargetType="StackPanel" <TextBlock Text="剩余电量:" />
BasedOn="{StaticResource CopterInfo_StackPanel}" /> <TextBlock Text="{Binding Path=BatteryPer}" />
</StackPanel.Resources> <TextBlock Text="%" />
</StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="电压:" /> <TextBlock Text="状态:" />
<Slider x:Name="sldChannel3" <TextBlock Text="{Binding Path=CommModuleMode}" />
Width="75" </StackPanel>
Minimum="1100" <StackPanel>
Maximum="1900" <TextBlock Text="纬度:" />
Value="{Binding Channel3, Mode=OneWay}" <TextBlock Text="{Binding Latitude}" />
ValueChanged="sldChannel3_ValueChanged"> </StackPanel>
<Slider.Resources> <StackPanel>
<ResourceDictionary> <TextBlock Text="经度:" />
<ResourceDictionary.MergedDictionaries> <TextBlock Text="{Binding Longitude}" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" /> </StackPanel>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" /> <StackPanel>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Blue.xaml" /> <TextBlock Text="通信模块版本:" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" /> <TextBlock Text="{Binding CommModuleVersion}" />
</ResourceDictionary.MergedDictionaries> </StackPanel>
</ResourceDictionary> <StackPanel>
</Slider.Resources> <TextBlock Text="返回数据:" />
</Slider> <StackPanel Margin="0,0,0,0" Height="14" ToolTip="{Binding RetainInt}">
</StackPanel> <TextBlock Margin="0,-1,0,0" Text="{Binding Retain[3]}" />
<StackPanel> <TextBlock Margin="0,-1,0,0" Text="." />
<TextBlock Text="电压值:" /> <TextBlock Margin="0,-1,0,0" Text="{Binding Retain[2]}" />
<TextBlock Text="{Binding Path=Voltage}" /> <TextBlock Margin="0,-1,0,0" Text="." />
</StackPanel> <TextBlock Margin="0,-1,0,0" Text="{Binding Retain[1]}" />
<StackPanel> <TextBlock Margin="0,-1,0,0" Text="." />
<TextBlock Text="剩余电量:" /> <TextBlock Margin="0,-1,0,0" Text="{Binding Retain[0]}" />
<TextBlock Text="{Binding Path=BatteryPer}" /> </StackPanel>
<TextBlock Text="%" /> </StackPanel>
</StackPanel>
<StackPanel> <StackPanel >
<TextBlock Text="状态:" /> <TextBlock Text="最后异常:" />
<TextBlock Text="{Binding Path=CommModuleMode}" /> <TextBlock Text="{Binding CopterErrorString}"/>
</StackPanel> </StackPanel>
<StackPanel>
<TextBlock Text="纬度:" /> </StackPanel>
<TextBlock Text="{Binding Latitude}" /> </Grid>
</StackPanel>
<StackPanel> </StackPanel>
<TextBlock Text="经度:" /> </UserControl>
<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>

File diff suppressed because it is too large Load Diff

View File

@ -74,9 +74,9 @@
/> />
<Button Margin="0,5,5,0" Content="3D航线" Width="82" Command="{Binding OptimizeRouteCommand3D}" <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}"
/> />