Compare commits

..

No commits in common. "Dev" and "能导入C4D的版本" have entirely different histories.

406 changed files with 13856 additions and 394966 deletions

View File

@ -1,12 +1,9 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34202.233
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.FormationCreator", "Plane.FormationCreator\Plane.FormationCreator.csproj", "{61E2F31E-220A-4E3F-A64D-F7CDC2135008}"
ProjectSection(ProjectDependencies) = postProject
{9BFB2123-2239-4A85-B5BC-0328CE7640D7} = {9BFB2123-2239-4A85-B5BC-0328CE7640D7}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.Windows", "..\Plane.Libraries\Plane.Windows\Plane.Windows.csproj", "{06848293-9B17-4068-9B35-44D0ED713CD4}"
EndProject
@ -26,11 +23,13 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlaneGcsSdk_Shared", "..\Pl
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlaneGcsSdk.Contract_Shared", "..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.shproj", "{695733D7-99FF-4707-8C89-474E949CADCB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightRoute", "..\FlyTest\FlightRoute\FlightRoute.csproj", "{9BFB2123-2239-4A85-B5BC-0328CE7640D7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightRouteV2", "..\FlyCube\FlightRouteV2\FlightRouteV2.csproj", "{626A9BFA-07DE-4063-A178-360EB7057ED6}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{0111eb6e-72e3-499c-a3ba-022f5bbc4caf}*SharedItemsImports = 4
..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{2be393dc-21a4-48b3-83fd-f21cbe8b038b}*SharedItemsImports = 13
..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{47141894-ece3-48ca-8dcf-ca751bda231e}*SharedItemsImports = 4
..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{695733d7-99ff-4707-8c89-474e949cadcb}*SharedItemsImports = 13
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
@ -102,30 +101,8 @@ Global
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU
{47141894-ECE3-48CA-8DCF-CA751BDA231E}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.Release|Any CPU.Build.0 = Release|Any CPU
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU
{626A9BFA-07DE-4063-A178-360EB7057ED6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{626A9BFA-07DE-4063-A178-360EB7057ED6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{626A9BFA-07DE-4063-A178-360EB7057ED6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{626A9BFA-07DE-4063-A178-360EB7057ED6}.Release|Any CPU.Build.0 = Release|Any CPU
{626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU
{626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU
{626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU
{626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{0111eb6e-72e3-499c-a3ba-022f5bbc4caf}*SharedItemsImports = 4
..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{2be393dc-21a4-48b3-83fd-f21cbe8b038b}*SharedItemsImports = 13
..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{47141894-ece3-48ca-8dcf-ca751bda231e}*SharedItemsImports = 4
..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{695733d7-99ff-4707-8c89-474e949cadcb}*SharedItemsImports = 13
EndGlobalSection
EndGlobal

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="Plane.FormationCreator.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
<section name="Plane.FormationCreator.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Windows.Interactivity" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0"/>
<assemblyIdentity name="System.Windows.Interactivity" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-1.0.109.0" newVersion="1.0.109.0"/>
<assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.109.0" newVersion="1.0.109.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
@ -36,18 +36,18 @@
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb"/>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6"/>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite.EF6"/>
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6"/>
<remove invariant="System.Data.SQLite"/><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite"/></DbProviderFactories>
<remove invariant="System.Data.SQLite.EF6" />
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
<remove invariant="System.Data.SQLite" /><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories>
</system.data>
</configuration>

View File

@ -11,14 +11,6 @@
ShutdownMode="OnMainWindowClose">
<Application.Resources>
<materialDesign:PackIcon x:Key="ConnectIcon"
x:Shared="False"
Kind="LanConnect"
Foreground="#2196F3" />
<materialDesign:PackIcon x:Key="DisconnectIcon"
x:Shared="False"
Kind="LanDisconnect"
Foreground="White" />
<materialDesign:PackIcon x:Key="CheckIcon"
x:Shared="False"
Kind="Check"
@ -27,7 +19,6 @@
x:Shared="False"
Kind="Close"
Foreground="White" />
<cnv:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
<cnv:BooleanToVisibilityConverter x:Key="InversiveBooleanToVisibilityConverter"
False="Visible"
@ -43,38 +34,13 @@
<cnv:InverseBooleanConverter x:Key="InverseBooleanConverter" />
<cnv:BooleanToStringConverter x:Key="ShowModifyTaskViewButtonContentConverter"
False="【飞行模式】"
True="【设计模式】" />
<cnv:BooleanToStringConverter x:Key="MainColorConverterDes"
False="White"
True="DeepSkyBlue" />
<cnv:BooleanToStringConverter x:Key="MainFontSizeConverterDes"
False="12"
True="14" />
<cnv:BooleanToStringConverter x:Key="MainColorConverterFly"
False="DeepSkyBlue"
True="White" />
<cnv:BooleanToStringConverter x:Key="MainFontSizeConverterFly"
False="14"
True="12" />
<cnv:BooleanToStringConverter x:Key="Show2d3dButtonContentConverter"
False="平面视图"
True="立体视图" />
True="【编辑模式】" />
<cnv:BooleanToResourceConverter x:Key="CheckSignConverter"
FalseKey="CloseIcon"
TrueKey="CheckIcon" />
<cnv:BooleanToResourceConverter x:Key="CheckSignConverter2"
FalseKey="DisconnectIcon"
TrueKey="ConnectIcon" />
FalseKey="CloseIcon"
TrueKey="CheckIcon" />
<cnv:BooleanToStringConverter x:Key="ColorConverter"
False="Red"
True="Green" />
@ -84,16 +50,6 @@
<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>

View File

@ -18,9 +18,8 @@ using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Plane.FormationCreator.Util;
using Plane.CommunicationManagement;
using Plane.FormationCreator.Util;
namespace Plane.FormationCreator
{
@ -31,7 +30,6 @@ namespace Plane.FormationCreator
{
public App()
{
VersionControl.GetSettingFromIni();
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
ServiceLocatorConfigurer.Instance.Configure();
@ -71,7 +69,7 @@ namespace Plane.FormationCreator
};
//new Test().Prepare().Run();
VersionControl.GetVersionFromIni();
}
private ILogger _logger;
@ -135,25 +133,20 @@ namespace Plane.FormationCreator
}
*/
if (VersionControl.ConType == 1)
{
CommModuleManager.Instance.UseTransModule = false;
/*
UdpServerConnectionManager.Instance.ExceptionThrown += (sender, e1) =>
{
_logger.Log(e1.Exception);
};
UdpServerConnectionManager.Instance.ConnectionEstablished += ConnectionManager_ConnectionEstablished;
UdpServerConnectionManager.Instance.StartReceiving();
}
else
{
CommModuleManager.Instance.UseTransModule = true;
*/
//初始化地面站连接
CommModuleManager.Instance.CommunicationReceived += CommtionReceivedCopterInfo;
CommModuleManager.Instance.CommunicationCopterDisconnect += CommCopterDisconnect;
CommModuleManager.Instance.CommunicationConnected += CommCopterconnected;
CommModuleManager.Instance.Connect();
}
}
catch (Exception ex)
@ -174,46 +167,32 @@ namespace Plane.FormationCreator
{
_logger.Log(e.Message );
}
//wifi模式添加飞机
private async Task AddOrUpdateCopter(string ip, IConnection Connection)
{
var copters = _copterManager.Copters;
var copterStatus = _copterManager.CopterStatus;
string[] iparr = ip.Split('.');
string vIPID = String.Format("{0:D3}", int.Parse(iparr[2])) + String.Format("{0:D3}", int.Parse(iparr[3]));
var copter = copters.FirstOrDefault(c => c.Id == vIPID);
var copter = copters.FirstOrDefault(c => c.Id == ip);
if (copter == null)
{
if (!_copterManager.EnAddCopter_Real())
{
UdpServerConnectionManager.Instance.DeleteConnections(ip);
}
else
{
await Dispatcher.BeginInvoke(new Action(() =>
{
copter = new Copter(Connection, SynchronizationContext.Current, _mapManager.Center.Lat, _mapManager.Center.Lng)
{
Id = vIPID,
Name = vIPID // ip.Substring(ip.LastIndexOf('.') + 1)
Id = ip,
Name = ip.Substring(ip.LastIndexOf('.') + 1)
};
int _index;
_index = copters.AddCopter(copter, _copterManager.SortType);
copterStatus.Insert(_index, false);
_index=copters.AddCopter(copter);
copterStatus.Insert(_index,false);
copter.TextReceived += Copter_TextReceived;
}));
}
}
else
{
copter.Connection = Connection;
}
if (copter!=null)
await copter.ConnectAsync().ConfigureAwait(false);
}
@ -262,18 +241,8 @@ namespace Plane.FormationCreator
lock(locker)
{
var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == id.ToString());
if ((copter != null)&&(copter is FakeCopter))
{
_copterManager.Copters.Remove(copter);
copter = null;
}
if (copter == null)
{
if (_copterManager.EnAddCopter_Real())
{
var copterStatus = _copterManager.CopterStatus;
var connection = new CommConnection();
copter = new Copter(connection, SynchronizationContext.Current, _mapManager.Center.Lat, _mapManager.Center.Lng)
@ -281,14 +250,12 @@ namespace Plane.FormationCreator
Id = id.ToString(),
Name = id.ToString(),
};
copter.VirtualId = 0;
int _index;
_index = _copterManager.Copters.AddCopter(copter, _copterManager.SortType);
_index = _copterManager.Copters.AddCopter(copter);
copterStatus.Insert(_index, false);
copter.TextReceived += Copter_TextReceived;
}
}
}
}));
}

View File

@ -41,7 +41,7 @@ namespace Plane.FormationCreator
}
}
private bool _ShowModifyTaskView = false;
private bool _ShowModifyTaskView = true;
public bool ShowModifyTaskView
{
get { return _ShowModifyTaskView; }

View File

@ -17,8 +17,7 @@ namespace Plane.FormationCreator.Converters
{
static DropShadowEffect _effect = new DropShadowEffect
{
//任务选中颜色
Color = Colors.Firebrick, // Colors.LightGray,
Color = Colors.LightGray,
// Color = Colors.White,
Direction = 90,
BlurRadius = 10

View File

@ -26,9 +26,6 @@ namespace Plane.FormationCreator.Converters
if (status == FlightTaskStatus.Paused)
return _PausedFill;
if (status == FlightTaskStatus.Selected)
return _PausedFill;
return _normalFill;
}

View File

@ -15,68 +15,15 @@ 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;
}
if (heartbeatCount % 2 == 0) return _zeroBrush;
var copter = values[1] as Copter;
return copter == null ? _oneBrush : copter.Brush;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)

View File

@ -28,14 +28,6 @@ namespace Plane.FormationCreator.Formation
//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)),
@ -51,24 +43,12 @@ namespace Plane.FormationCreator.Formation
{
return _brushIndex++ % _brushes.Length;
}
//真实飞机列表默认颜色
internal static SolidColorBrush DefaultBrush { get; } = GreenBrush;// new SolidColorBrush(Color.FromRgb(50, 205, 50));
//虚拟飞机列表默认颜色
internal static SolidColorBrush DefaultFakeBrush { get; } = BlueBrush;
internal static SolidColorBrush DefaultBrush { get; } = new SolidColorBrush(Color.FromRgb(28, 151, 234));
private SolidColorBrush _Brush;
public SolidColorBrush Brush
{
get {
if (CopterPreCheckPass)
return _Brush ?? DefaultBrush;
else
return _Brush ?? YellowBrush;
}
get { return _Brush ?? DefaultBrush; }
set { Set(nameof(Brush), ref _Brush, value); }
}
}

View File

@ -8,83 +8,37 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Plane.FormationCreator.Util;
using Microsoft.Practices.ServiceLocation;
using Plane.FormationCreator.ViewModels;
using System.Threading;
using Plane.Communication;
using Plane.Util;
using System.Windows;
using Plane.Windows.Messages;
using System.Reflection;
using System.IO;
namespace Plane.FormationCreator.Formation
{
public class CopterCollection : ObservableCollection<ICopter>
{
//软件过期时间---过期将无法添加飞机,并自动退出
public static DateTime Expire_App = DateTime.Parse("2024-12-31");
//超级用户过期时间--过期将无法使用内置超级用户登录
public static DateTime Expire_SuperUser = Expire_App;
//允许飞行的飞机数量
public int EnCopterNumber = 0;
//允许模拟的飞机数量
public int EnVCopterNumber = 0;
/// <summary>
/// 实现排序插入
/// </summary>
/// <param name="baseSemObjects"></param>
public int AddCopter(ICopter entityObject, CopterManager.CopterSortType vSortType)
public int AddCopter(ICopter entityObject)
{
////给第三方时候限制数量和时间用
DateTime dateTime2019 = DateTime.Parse("2020-01-20");
//新增飞机区域限制:内蒙
// if (entityObject.Latitude < 37.4307185218 || entityObject.Latitude > 45.6754821756
// || entityObject.Longitude < 97.3493089056 || entityObject.Longitude > 115.8006783856)
// return 0;
if (DateTime.UtcNow > Expire_App)
if (DateTime.UtcNow > dateTime2019)
{
throw new NotImplementedException();
}
/*
if (this.Count >= VersionControl.CopterUpperLimit)
{
return 0;
}
//网络登录限制
// if (!VersionControl.IsFullVersion)
{
if (entityObject is FakeCopter)
{
if (this.Count >= EnVCopterNumber)
{
return 0;
}
}
else
{
if (this.Count >= EnCopterNumber)
{
return 0;
}
}
}
*/
int _index = 0;
if (this.Count == 0)
{
@ -93,85 +47,25 @@ namespace Plane.FormationCreator.Formation
}
else
{
//删除重复
// if (entityObject is PLCopter)
// {
for (int i = 0; i < this.Count; i++)
{
if (vSortType == CopterManager.CopterSortType.ByID)
{
if (int.Parse(this[i].Id) == int.Parse(entityObject.Id))
{
if (this[i] is FakeCopter)
Remove(this[i]);
else
{
Message.Show($"无法加入飞机已有重复的真实飞机ID[{this[i].Id}]");
return -1;
}
}
}else
{
if ((entityObject.VirtualId!=0) &&(this[i].VirtualId == entityObject.VirtualId))
{
if (this[i] is FakeCopter)
Remove(this[i]);
else
{
Message.Show($"无法加入飞机已有重复的真实飞机ID[{this[i].VirtualId}]");
return -1;
}
}
}
}
// }
bool isInsret = false;
for (int i = 0; i < this.Count; i++)
{
//按ID排序插入
if (vSortType == CopterManager.CopterSortType.ByID)
{
if (int.Parse(this[i].Id) > int.Parse(entityObject.Id))
if ( int.Parse(this[i].Id) > int.Parse(entityObject.Id))
//if (String.Compare(this[i].Name, entityObject.Name, false) >= 0)
{
InsertItem(i, entityObject);
isInsret = true;
_index = i;
break;
}
}
else
//按VID排序插入
{
if (this[i].VirtualId > entityObject.VirtualId)
{
InsertItem(i, entityObject);
isInsret = true;
_index = i;
_index= i;
break;
}
}
}
if (!isInsret)
{
Add(entityObject);
_index = this.Count()-1 ;
}
}
entityObject.DisplayID = ((vSortType == CopterManager.CopterSortType.ByID) || (vSortType == CopterManager.CopterSortType.ByVIDShowAll));
entityObject.DisplayVirtualId = ((vSortType == CopterManager.CopterSortType.ByVID) || (vSortType == CopterManager.CopterSortType.ByVIDShowAll));
return _index;
}
}
@ -179,36 +73,6 @@ namespace Plane.FormationCreator.Formation
public class CopterManager : ObservableObject
{
const string LoginPage = "checkforapp.php";
// const string supername = "admin";
// const string superpass = "admin0622";
const string supername = "user";
const string superpass = "123456";
const string TEMP_MISSIONFILE = @".\gcs.dat";
//飞控版本控制
public int FC_VER_NO = 1;//"4.1.2" 这个版本以前版本灯光比较少no=1 //"4.5"以后no=2;
//飞控版本控制
public string FC_VER_STRING = "4.1.2以前"; //
//用户级别
const int LEVEL_NORMAL = 1;
const int LEVEL_ADMIN = 0;
//飞机默认颜色
public const string CopterDefaultColor= "1E90FF";
//开始起飞颜色//解锁起飞用暗紫色
public const string CopterTakeoffColor = "FF00FF";
//飞行中颜色
public const string CopterFlyingColor = "32CD32";
private string superDispname = "超级用户";
public CopterManager()
{
AppEx.Current.AppModeChanged += (sender, e) =>
@ -220,37 +84,12 @@ namespace Plane.FormationCreator.Formation
Task.WhenAll(Copters.Select(c => c.DisconnectAsync()));
};
Windows.IniHelper.IniFiles inifilse = new Windows.IniHelper.IniFiles();
string readvalue = "";
int intTemp;
readvalue = inifilse.IniReadvalue("Default", "FC_VER_NO");
if (readvalue != "" && int.TryParse(readvalue, out intTemp))
FC_VER_NO = int.Parse(readvalue);
readvalue = inifilse.IniReadvalue("Default", "FC_VER_STRING");
if (readvalue != "" )
FC_VER_STRING =readvalue;
}
public List<ICopter> ShowCopter = new List<ICopter>();
//3维视图显示比例有些大的图案显示不出来可以缩小
private float _scale3d = 1.0f;
public float scale3d
{
get { return _scale3d; }
set { Set(nameof(scale3d), ref _scale3d, value); }
}
public delegate void NetStatusChanged(bool Logined, string status);
public event NetStatusChanged netStatusChanged;
public CopterCollection Copters { get;} = new CopterCollection();
//标记某飞机是否需要跳过
public ArrayList CopterStatus = new ArrayList();
//public ObservableCollection<ICopter> Copters
//{
@ -270,468 +109,6 @@ namespace Plane.FormationCreator.Formation
// }
//}
private string _Loginstate = "未登录";
public string Loginstate
{
get { return _Loginstate; }
set
{
Set(nameof(Loginstate), ref _Loginstate, value);
netStatusChanged(Logined,Loginstate);
}
}
public enum CopterSortType { ByID, ByVID, ByVIDShowAll };
//排序类型
private CopterSortType _SortType =0;
public CopterSortType SortType
{
get { return _SortType; }
set
{
Set(nameof(SortType), ref _SortType, value);
switch (value)
{
case CopterSortType.ByID:
sortbyid();
break;
case CopterSortType.ByVID:
sortbyvid();
break;
case CopterSortType.ByVIDShowAll:
sortbyvid(true);
break;
default:
sortbyid();
break;
}
}
}
public void ReSort()
{
SortType = _SortType;
}
private int _EnCopterNumber = 0;
public int EnCopterNumber
{
get { return _EnCopterNumber; }
set
{
Set(nameof(EnCopterNumber), ref _EnCopterNumber, value);
Copters.EnCopterNumber = EnCopterNumber;
}
}
private int _EnVCopterNumber = 0;
public int EnVCopterNumber
{
get { return _EnVCopterNumber; }
set
{
Set(nameof(EnVCopterNumber), ref _EnVCopterNumber, value);
Copters.EnVCopterNumber = EnVCopterNumber;
}
}
private bool _Logined = false;
public bool Logined
{
get { return _Logined; }
set
{
Set(nameof(Logined), ref _Logined, value);
netStatusChanged(Logined, Loginstate);
}
}
private string _UserName = "";
private string _UserDisplayName = "";
public string RTK_URL = "";
public void NetLogined(string UserName,string UserDisplayName,int vEnCopterNumber,int vEnVCopterNumber,int userlever=1)
{
_UserName = UserName;
EnCopterNumber = vEnCopterNumber;
EnVCopterNumber = vEnVCopterNumber;
_UserDisplayName = UserDisplayName;
string dis_EnCopterNumber ="<"+ EnCopterNumber.ToString()+">";
string dis_EnVCopterNumber = "<" + EnVCopterNumber.ToString() + ">";
if (EnCopterNumber == -1) dis_EnCopterNumber = "<无限>";
if (EnVCopterNumber == -1) dis_EnVCopterNumber = "<无限>";
Loginstate ="["+ UserDisplayName + "] 模拟飞机:"+ dis_EnVCopterNumber + "架,真实飞机:"+ dis_EnCopterNumber + "架";
Logined = true;
VersionControl.SetUserLever(userlever);
if (UserName != supername)
{
Task.Run(async () =>
{
while (Logined)
{
NetActivePost();
//30秒一次保持活跃
await Task.Delay(30 * 1000).ConfigureAwait(false);
}
}).ConfigureAwait(false);
}
}
public void GetRTKURL()
{
if (_UserName == "") return;
// 发送请求
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
sbUrl.Append(VersionControl.ServerURL + LoginPage);
sbUrl.Append("?");
sbUrl.Append("username=" + _UserName);
sbUrl.Append("&clientname=" + System.Net.Dns.GetHostName());
sbUrl.Append("&type=GetRTK");
sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
String strUrl = sbUrl.ToString();
string errorstr;
new AsynDataUtils().AsynGetData(strUrl, ResultCallBack_rtk, out errorstr);
}
public void ReleaseRTKURL()
{
if (_UserName == "") return;
// 发送请求
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
sbUrl.Append(VersionControl.ServerURL + LoginPage);
sbUrl.Append("?");
sbUrl.Append("username=" + _UserName);
sbUrl.Append("&clientname=" + System.Net.Dns.GetHostName());
sbUrl.Append("&type=RelRTK");
sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
String strUrl = sbUrl.ToString();
string errorstr;
new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
}
private void NetActivePost()
{
// 发送请求
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
sbUrl.Append(VersionControl.ServerURL+ LoginPage);
sbUrl.Append("?");
sbUrl.Append("username=" + _UserName);
sbUrl.Append("&type=Active");
String strUrl = sbUrl.ToString();
string errorstr;
new AsynDataUtils().AsynGetData(strUrl, null,out errorstr);
}
private void NetLogoutPost()
{
// 发送请求
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
sbUrl.Append(VersionControl.ServerURL + LoginPage);
sbUrl.Append("?");
sbUrl.Append("username=" + _UserName);
sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
sbUrl.Append("&type=Logout");
sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
String strUrl = sbUrl.ToString();
string errorstr;
new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
}
public void NetLogout()
{
if (Logined)
NetLogoutPost();
Logined = false;
EnCopterNumber = 0;
EnVCopterNumber = 0;
_UserDisplayName = "";
_UserName = "";
VersionControl.SetUserLever(LEVEL_NORMAL);
Loginstate = "未登录";
}
//本地飞行任务日志 提交到服务器
public void Net_PostTempMission()
{
string filePath = TEMP_MISSIONFILE;
string[] Missionstrs = { };
try
{
if (File.Exists(filePath))
{
Missionstrs = File.ReadAllLines(filePath);
List<String> Mlist = new List<string>(Missionstrs);
string upstr = "";
foreach (var mstr in Mlist)
upstr = upstr + mstr + "|";
Net_PostTempMission(upstr);
Mlist.Clear();
File.WriteAllLines(TEMP_MISSIONFILE, Mlist);
}
}
catch (Exception ex)
{
}
}
//保存飞行任务日志临时到本地
public void Net_WriteTempMission(DateTime MissionTime, double OriginLng, double OriginLat)
{
string filePath = TEMP_MISSIONFILE;
string[] Missionstrs = { };
try
{
if (File.Exists(filePath))
Missionstrs = File.ReadAllLines(filePath);
List<String> Mlist = new List<string>(Missionstrs);
Mlist.Add(MissionTime.ToString() + ";" + OriginLng.ToString() + ";" + OriginLat.ToString() + ";" + Copters.Count().ToString()
+ ";" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
File.WriteAllLines(TEMP_MISSIONFILE, Mlist);
}
catch (Exception ex)
{
}
}
//提交飞行记录
public void Net_LogStartMission(DateTime MissionTime,double OriginLng, double OriginLat)
{
Net_WriteTempMission(MissionTime, OriginLng, OriginLat);
Net_PostStartMission(MissionTime, OriginLng, OriginLat);
}
//提交飞行记录
public void Net_PostStartMission(DateTime MissionTime, double OriginLng, double OriginLat)
{
// 发送请求
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
sbUrl.Append(VersionControl.ServerURL + LoginPage);
sbUrl.Append("?");
sbUrl.Append("username=" + _UserName);
sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
sbUrl.Append("&type=StartMission");
sbUrl.Append("&mtime=" + MissionTime.ToString());
sbUrl.Append("&orgLng=" + OriginLng.ToString());
sbUrl.Append("&orgLat=" + OriginLat.ToString());
sbUrl.Append("&coptercount=" + Copters.Count().ToString());
sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
String strUrl = sbUrl.ToString();
string errorstr;
new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
}
//提交本地飞行记录
public void Net_PostTempMission(string missstr)
{
// 发送请求
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
sbUrl.Append(VersionControl.ServerURL + LoginPage);
sbUrl.Append("?");
sbUrl.Append("username=" + _UserName);
sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
sbUrl.Append("&type=TempMission");
sbUrl.Append("&Mission=" + missstr);
String strUrl = sbUrl.ToString();
string errorstr;
new AsynDataUtils().AsynGetData(strUrl, null, out errorstr);
}
private string tempuser;
private string tempPassword;
private bool tempSavePassword;
//在这个方法里面接收回调的返回信息
private void DataResultCallBack(string data,bool haveerror)
{
if (haveerror)
{
Loginstate = "登录失败,"+ data;
return;
}
if (data == "")
{
Loginstate = "登录失败,请检查网络连接";
return;
}
string[] arr = data.Split(';');
string loginret = arr[0];
if (loginret == "Login ok")
{
if (arr.Length!= 5)
{
Alert.Show("系统版本不正确!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
string UserDisplayName = arr[1];
int vEnCopterNumber = int.Parse(arr[2]);
int vEnVCopterNumber = int.Parse(arr[3]);
int userlevel = int.Parse(arr[4]);
NetLogined(tempuser, UserDisplayName, vEnCopterNumber, vEnVCopterNumber, userlevel);
VersionControl.SaveLogininfoToIni(tempuser, tempPassword, tempSavePassword);
Net_PostTempMission();
//MessageBox.Show(UserDisplayName + " 登录成功!", "登录提示");
}
else
if (loginret == "username error")
{
NetLogout();
Alert.Show("账号错误!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
}
else
if (loginret == "password error")
{
NetLogout();
Alert.Show("密码错误!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
}
else
if (loginret == "replogin error")
{
NetLogout();
Alert.Show("该账号已在其他地方登录!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
}else
{
NetLogout();
Alert.Show("登录失败:"+ data, "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
public void NetLogoin(string username,string password,bool savepassword)
{
Logined = false;
//超级用户,无限制
if ((username== supername) && (password== superpass) &&(DateTime.UtcNow < CopterCollection.Expire_SuperUser) )
{
// NetLogined(supername, superDispname, -1, -1, LEVEL_ADMIN);
NetLogined(supername, superDispname,6, 300, LEVEL_NORMAL);
VersionControl.SaveLogininfoToIni(supername, superpass, savepassword); //超级密码是否保存---不要就不保存
return;
}
tempuser = username;
tempPassword = password;
tempSavePassword = savepassword;
// 发送请求
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
sbUrl.Append(VersionControl.ServerURL + LoginPage);
sbUrl.Append("?");
sbUrl.Append("username=" + username);
sbUrl.Append("&" + "password=" + password);
sbUrl.Append("&type=Login");
sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
sbUrl.Append("&" + "clientname=" + System.Net.Dns.GetHostName());
String strUrl = sbUrl.ToString();
string errorstr;
if (new AsynDataUtils().AsynGetData(strUrl, DataResultCallBack, out errorstr))
Loginstate = "登录中...";
else Loginstate = "登录失败,"+ errorstr;
}
private void ResultCallBack_rtk(string data, bool haveerror)
{
if (haveerror)
{
MessageBox.Show("获取RTK账号失败" + data, "错误");
return;
}
if (data == "")
{
MessageBox.Show("获取RTK账号失败请检查网络", "错误");
return;
}
string[] arr = data.Split(';');
string loginret = arr[0];
if (loginret == "ok")
{
RTK_URL = arr[1];
}
else
MessageBox.Show(loginret, "错误");
}
//在这个方法里面接收回调的返回信息
private void DataResultCallBack_changepassword(string data, bool haveerror)
{
if (haveerror)
{
MessageBox.Show("更改失败," + data, "提示");
return;
}
if (data == "")
{
MessageBox.Show("更改失败,请检查网络", "提示");
return;
}
string[] arr = data.Split(';');
string loginret = arr[0];
if (loginret == "chpassword ok")
{
MessageBox.Show( "密码更改成功!", "提示");
}
else
if (loginret == "username error")
{
MessageBox.Show("账号错误!", "提示");
}
else
if (loginret == "password error")
{
MessageBox.Show("原密码错误!", "提示");
}
}
public void NetChangePassword(string username, string oldpassword, string newpassword)
{
tempuser = username;
tempPassword = oldpassword;
// 发送请求
StringBuilder sbUrl = new StringBuilder(); // 请求URL内容
sbUrl.Append(VersionControl.ServerURL + LoginPage);
sbUrl.Append("?");
sbUrl.Append("username=" + username);
sbUrl.Append("&password=" + oldpassword);
sbUrl.Append("&clientname=" + System.Net.Dns.GetHostName());
sbUrl.Append("&type=Chpassword");
sbUrl.Append("&ver=" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
sbUrl.Append("&newpassword=" + newpassword);
String strUrl = sbUrl.ToString();
string errorstr;
if (!new AsynDataUtils().AsynGetData(strUrl, DataResultCallBack_changepassword, out errorstr))
MessageBox.Show("更改失败," + errorstr, "提示");
}
public bool shiftkeydown;
public IEnumerable<ICopter> SelectedCopters { get { return _selectedCoptersGetter().Cast<ICopter>(); } }
@ -764,70 +141,6 @@ namespace Plane.FormationCreator.Formation
SeletedCopterCount = SelectedCopters.Count();
}
public async Task ClearCopters()
{
foreach (var copter in Copters)
{
await copter.DisconnectAsync();
}
await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
Copters.Clear();
CopterStatus.Clear();
//wifi
if (VersionControl.ConType==1)
UdpServerConnectionManager.Instance.ClearConnections();
}
public async Task DelSelCopters()
{
if (AcceptingControlCopters == null || AcceptingControlCopters.Count() ==0)
{
return;
}
foreach (var copter in AcceptingControlCopters)
{
await copter.DisconnectAsync();
if(Copters.Contains(copter))
{
Copters.Remove(copter);
}
//标记是否跳过,这个已经没用了,随便删除第一个
CopterStatus.RemoveAt(0);
}
await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
//wifi
// if (VersionControl.ConType == 1)
// UdpServerConnectionManager.Instance.ClearConnections();
}
public bool EnAddCopter_Real()
{
if (EnCopterNumber == -1) return true;
else
return Copters.Count < EnCopterNumber;
}
public bool EnAddCopter_Fake()
{
if (EnVCopterNumber == -1) return true;
else
return Copters.Count < EnVCopterNumber;
}
/// <summary>
/// 选择飞机
/// </summary>
@ -836,29 +149,6 @@ namespace Plane.FormationCreator.Formation
{
_selectCopterAction(copter);
}
/// <summary>
/// 按VID重新排序飞机
/// </summary>
public void sortbyvid(bool displayid=false)
{
List<ICopter> tempCopters = new List<ICopter>();
tempCopters.AddRange(Copters);
Copters.Clear();
foreach (var copter in tempCopters)
Copters.AddCopter(copter,SortType);
}
/// <summary>
/// 按原始ID重新排序飞机
/// </summary>
public void sortbyid()
{
List<ICopter> tempCopters = new List<ICopter>();
tempCopters.AddRange(Copters);
Copters.Clear();
foreach (var copter in tempCopters)
Copters.AddCopter(copter,SortType);
}
}

View File

@ -53,7 +53,6 @@ namespace Plane.FormationCreator.Formation
public static double DistanceTo(this ICopter copter, ICopter copter2)
{
return GeographyUtils.CalcDistance(copter.Latitude, copter.Longitude, copter.Altitude, copter2.Latitude, copter2.Longitude, copter2.Altitude);
//return GeographyUtils.CalcDistance_simple(copter.Latitude, copter.Longitude, copter.Altitude, copter2.Latitude, copter2.Longitude, copter2.Altitude);
}
public static double InPlaneDistanceTo(this ICopter copter, double targetLat, double targetLng)
@ -82,10 +81,8 @@ namespace Plane.FormationCreator.Formation
public static bool IsTooCloseTo(this ICopter copter, ICopter copter2, out double distance)
{
// distance = 0;
// return false; //效果图用 不检测碰撞
distance = Math.Round(copter.DistanceTo(copter2), 2) ;
//return false; //效果图用 不检测碰撞
if (copter.Altitude < 3 || copter2.Altitude < 3)
return false;

View File

@ -35,10 +35,13 @@ namespace Plane.FormationCreator.Formation
get { return _TaskType; }
set
{
Set(nameof(TaskType), ref _TaskType, value);
//if (_TaskType != value)
{
RaisePropertyChanged(nameof(TaskTypeIndex));
RaisePropertyChanged(nameof(TaskCnName));
}
}
}
@ -73,13 +76,7 @@ namespace Plane.FormationCreator.Formation
//name = (TaskIndex + 1).ToString() + "." + name;
return name;
}
set {
Set(nameof(TaskCnName), ref _TaskName, value);
RaisePropertyChanged(nameof(TaskCnName));
}
set { Set(nameof(TaskCnName), ref _TaskName, value); }
}
public int TaskTypeIndex
@ -122,21 +119,6 @@ namespace Plane.FormationCreator.Formation
}
}
private bool _IsTransition=false;
public bool IsTransition
{
get { return _IsTransition; }
set {
Set(nameof(IsTransition), ref _IsTransition, value);
if ((value)&& (TaskCnName == "航点"))
TaskCnName = "过度";
}
}
private bool _IsSelected;
public bool IsSelected
{
@ -163,11 +145,7 @@ namespace Plane.FormationCreator.Formation
get { return _ModifyingSingleCopterInfo; }
set { Set(nameof(ModifyingSingleCopterInfo), ref _ModifyingSingleCopterInfo, value); }
}
/// <summary>
/// 实际执行某一个任务--包含等待
/// </summary>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public async Task RunAsync()
{
switch (TaskType)
@ -175,9 +153,27 @@ namespace Plane.FormationCreator.Formation
case FlightTaskType.FlyTo:
await RunFlyToTaskAsync().ConfigureAwait(false);
break;
case FlightTaskType.Turn:
await RunTurnTaskAsync().ConfigureAwait(false);
break;
case FlightTaskType.Circle:
await RunCircleTaskAsync().ConfigureAwait(false);
break;
case FlightTaskType.SimpleCircle:
await RunSimpleCircleTaskAsync().ConfigureAwait(false);
break;
case FlightTaskType.Loiter:
await RunLoiterTimeTaskAsync().ConfigureAwait(false);
break;
case FlightTaskType.TakeOff:
//多架同时起飞
//await MutilRunTakeOffTaskAsync().ConfigureAwait(false);
await NewMutilRunTakeOffTaskAsync().ConfigureAwait(false);
break;
case FlightTaskType.ReturnToLand: // Added by ZJF
//多架同时返航
await MutilRunReturnToLandTaskAsync().ConfigureAwait(false);
break;
case FlightTaskType.Land:
await MutilLandTaskAsync().ConfigureAwait(false);
break;
@ -190,6 +186,12 @@ namespace Plane.FormationCreator.Formation
public enum FlightTaskType
{
FlyTo = 0,
Turn = 1,
Circle = 2,
Loiter = 3, // 加入悬停时间选项
// LEDAction = 4,
ReturnToLand = 4, // added by ZJF. 20160315
SimpleCircle = 5,
Land = 6,
TakeOff = 100
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Plane.Copters;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTaskSingleCopterInfo
{
public static FlightTaskSingleCopterInfo CreateForCircleTask(ICopter copter, LatLng latLngOffset, float targetAlt, short centerDirectionDeg, int radius, int rate, int turns, ushort channel3)
{
var info = new FlightTaskSingleCopterInfo(copter)
{
LatLngOffset = latLngOffset,
TargetAlt = targetAlt,
CenterDirectionDeg = centerDirectionDeg,
Radius = radius,
Rate = rate,
Turns = turns,
Channel3 = channel3
};
return info;
}
private short _CenterDirectionDeg;
public short CenterDirectionDeg
{
get { return _CenterDirectionDeg; }
set { Set(nameof(CenterDirectionDeg), ref _CenterDirectionDeg, value); }
}
private int _Radius = 1000;
/// <summary>
/// 圆的半径,单位为厘米。
/// </summary>
public int Radius
{
get { return _Radius; }
set { Set(nameof(Radius), ref _Radius, value); }
}
private int _Rate = 20;
/// <summary>
/// 转圈的角速度,单位为 deg/s范围为 -90 到 90。
/// </summary>
public int Rate
{
get { return _Rate; }
set { Set(nameof(Rate), ref _Rate, value); }
}
private int _Turns = 1;
public int Turns
{
get { return _Turns; }
set { Set(nameof(Turns), ref _Turns, value); }
}
private ushort _Channel3 = 1500;
public ushort Channel3
{
get { return _Channel3; }
set { Set(nameof(Channel3), ref _Channel3, value); }
}
}
}

View File

@ -61,16 +61,7 @@ namespace Plane.FormationCreator.Formation
public bool IsLandWaypoint
{
get { return _IsLandWaypoint; }
set {
Set(nameof(IsLandWaypoint), ref _IsLandWaypoint, value);
if (_flightTaskManager.SelectedTask == null) return;
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos)
{
info._IsLandWaypoint = _IsLandWaypoint;
}
}
set { Set(nameof(IsLandWaypoint), ref _IsLandWaypoint, value); }
}
private bool _IsChangeSpeed = false;
@ -81,15 +72,7 @@ namespace Plane.FormationCreator.Formation
public bool IsChangeSpeed
{
get {return _IsChangeSpeed; }
set {
Set(nameof(IsChangeSpeed), ref _IsChangeSpeed, value);
if (_flightTaskManager.SelectedTask == null) return;
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos)
{
info._IsChangeSpeed = _IsChangeSpeed;
}
}
set { Set(nameof(IsChangeSpeed), ref _IsChangeSpeed, value); }
}
@ -100,14 +83,7 @@ namespace Plane.FormationCreator.Formation
public float LevelSpeed
{
get { return _LevelSpeed; }
set {
Set(nameof(LevelSpeed), ref _LevelSpeed, value);
if (_flightTaskManager.SelectedTask == null) return;
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos)
{
info._LevelSpeed = _LevelSpeed;
}
}
set { Set(nameof(LevelSpeed), ref _LevelSpeed, value); }
}
@ -118,14 +94,7 @@ namespace Plane.FormationCreator.Formation
public float UpSpeed
{
get { return _UpSpeed; }
set {
Set(nameof(UpSpeed), ref _UpSpeed, value);
if (_flightTaskManager.SelectedTask == null) return;
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos)
{
info._UpSpeed = _UpSpeed;
}
}
set { Set(nameof(UpSpeed), ref _UpSpeed, value); }
}
private float _DownSpeed = 1.5f;
@ -135,14 +104,7 @@ namespace Plane.FormationCreator.Formation
public float DownSpeed
{
get { return _DownSpeed; }
set {
Set(nameof(DownSpeed), ref _DownSpeed, value);
if (_flightTaskManager.SelectedTask == null) return;
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos)
{
info._DownSpeed = _DownSpeed;
}
}
set { Set(nameof(DownSpeed), ref _DownSpeed, value); }
}
/*

View File

@ -1,24 +1,18 @@
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Plane.CommunicationManagement;
using GalaSoft.MvvmLight.Command;
using Plane.Copters;
using Plane.Windows.Messages;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Media;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTaskSingleCopterInfo
{
public static FlightTaskSingleCopterInfo CreateForFlyToTask(ICopter copter)
{
var info = new FlightTaskSingleCopterInfo(copter)
@ -33,23 +27,18 @@ namespace Plane.FormationCreator.Formation
LEDInfo LedInfo = new LEDInfo();
LEDInfos.Add(LedInfo);
LedInfo.RemoveEvent += new LEDInfo.RemoveEventHandler(LEDRemove);
LedInfo.PropertyChanged += (sender, e) =>{RefLEDSumTime();};
RefLEDSumTime();
}
public void AddLEDInfo(LEDInfo LedInfo)
{
LEDInfos.Add(LedInfo);
LedInfo.RemoveEvent += new LEDInfo.RemoveEventHandler(LEDRemove);
LedInfo.PropertyChanged += (sender, e) => { RefLEDSumTime(); };
RefLEDSumTime();
}
public void LEDRemove(object sender)
{
LEDInfo LedInfo = sender as LEDInfo;
LEDInfos.Remove(LedInfo);
RefLEDSumTime();
}
@ -65,11 +54,9 @@ namespace Plane.FormationCreator.Formation
return _AddLEDCommand ?? (_AddLEDCommand = new RelayCommand<double>(async =>
{
AddLEDInfo();
}));
}
}
private CommModuleManager _commModuleManager = CommModuleManager.Instance;
private ICommand _SetAllCopterLEDCommand;
public ICommand SetAllCopterLEDCommand
@ -95,82 +82,6 @@ namespace Plane.FormationCreator.Formation
}
}
public void RefLEDSumTime()
{
float _ledSumTime = 0;
foreach (LEDInfo led in LEDInfos)
{
_ledSumTime += (float)led.Delay;
}
LEDSumTime =(float) Math.Round(_ledSumTime, 1);
}
//灯光总时长
private float _LEDSumTime = 0;
public float LEDSumTime
{
get { return _LEDSumTime; }
set { Set(nameof(LEDSumTime), ref _LEDSumTime, value); }
}
bool LEDTestRun = false;
/*
private string _TestLEDtxt = "测试";
public string TestLEDtxt
{
get { return _TestLEDtxt; }
set { Set(nameof(TestLEDtxt), ref _TestLEDtxt, value); }
}
*/
/*
LEDMode 0 = "常亮"
1="同步闪烁(单色)" />
2 = "异步闪烁(随机)" />
3="渐亮" />
4 = "渐暗" />
5="呼吸灯" />
6 = "同步闪烁(随机)" />
7="异步闪烁(单色)" />
8 = "拉烟" />(50 ? )
*/
//测试灯光
private ICommand _TestCopterLEDCommand;
public ICommand TestCopterLEDCommand
{
get
{
return _TestCopterLEDCommand ?? (_TestCopterLEDCommand = new RelayCommand<double>(async =>
{
if (!LEDTestRun)
{
Task.Run(() =>
{
LEDTestRun = true;
foreach (LEDInfo vLEDInfo in LEDInfos)
{
Thread.Sleep((int)(vLEDInfo.Delay * 1000));
if (!LEDTestRun) break;
_commModuleManager.LED_TaskAsync(vLEDInfo.LEDMode, vLEDInfo.LEDInterval, vLEDInfo.LEDTimes, vLEDInfo.LEDRGB, this.Copter);
}
//LEDTestRun = false;
});
}else
{
LEDTestRun = false;
_commModuleManager.LED_TaskAsync(255, 0, 0, "000000", this.Copter);
_commModuleManager.LED_TaskAsync(255, 0, 0, "000000", this.Copter);
_commModuleManager.LED_TaskAsync(255, 0, 0, "000000", this.Copter);
}
}));
}
}
private ICommand _SetSelectedCopterLEDCommand;
@ -201,23 +112,13 @@ namespace Plane.FormationCreator.Formation
}
}
public class LEDInfo :INotifyPropertyChanged
public class LEDInfo
{
private double delay = 1; //灯光延时 单位100ms 从当前任务开为0延时几秒后设置LED
private int ledmode = 0; //灯光模式 0常亮 1闪烁 2随机闪烁(RGB无意义)
private float ledInterval = 0; //闪烁延时 单位:秒
private int ledrate = 0; //为了和以前文件兼容自动转为ledInterval
private int ledrate = 0; //闪烁延时 单位100ms
private int ledtimes = 0; //次数 (预留、暂取消其意义)
private string ledRGB = "FFFFFF"; //灯光颜色
private SolidColorBrush _DrawRGB = new SolidColorBrush(Color.FromRgb(0xFF, 0xFF, 0xFF));
protected internal virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
public LEDInfo()
{
@ -228,16 +129,13 @@ namespace Plane.FormationCreator.Formation
{
delay = led.delay;
ledmode = led.ledmode;
ledInterval = led.ledInterval;
LEDRGB = led.ledRGB;
ledrate = led.ledrate;
ledRGB = led.ledRGB;
}
public double Delay
{
get { return delay; }
set {
delay = Math.Round(value, 1);
OnPropertyChanged("delay");
}
set { delay = value; }
}
public int LEDMode
@ -245,25 +143,11 @@ namespace Plane.FormationCreator.Formation
get { return ledmode; }
set { ledmode = value; }
}
public float LEDInterval
{
get { return ledInterval; }
set { ledInterval = value;
if (ledInterval != 0)
ledrate = (int)Math.Round(1 / ledInterval); //用于兼容老版本
}
}
public int LEDRate
{
get { return ledrate; }
set { ledrate = value;
if ((ledrate!=0)&&(ledInterval==0))
ledInterval = 1 / ledrate;
set { ledrate = value; }
}
}
public int LEDTimes
{
get { return ledtimes; }
@ -273,28 +157,8 @@ namespace Plane.FormationCreator.Formation
public string LEDRGB
{
get { return ledRGB; }
set {
ledRGB = value;
DrawRGB.Color= (Color)ColorConverter.ConvertFromString("#" + ledRGB);
set { ledRGB = value; }
}
}
[Newtonsoft.Json.JsonIgnore]
public SolidColorBrush DrawRGB
{
get
{
return _DrawRGB;
}
set
{
_DrawRGB = value;
}
}
public delegate void RemoveEventHandler(object sender);
public event RemoveEventHandler RemoveEvent;

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Plane.Copters;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTaskSingleCopterInfo
{
public static FlightTaskSingleCopterInfo CreateForLoiterTimeTask(ICopter copter, LatLng latLngOffset, float targetAlt)
{
var info = new FlightTaskSingleCopterInfo(copter)
{
LatLngOffset = latLngOffset,
TargetAlt = targetAlt
};
return info;
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Plane.Copters;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTaskSingleCopterInfo
{
// This file is added by ZJF
public static FlightTaskSingleCopterInfo CreateForReturnToLandTask(ICopter copter, float targetAlt)
{
var info = new FlightTaskSingleCopterInfo(copter)
{
TargetAlt = targetAlt
};
return info;
}
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Plane.Copters;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTaskSingleCopterInfo
{
public static FlightTaskSingleCopterInfo CreateForSimpleCircleTask(ICopter copter, LatLng latLngOffset, float targetAlt, int rate, int turns, ushort channel3)
{
var info = new FlightTaskSingleCopterInfo(copter)
{
LatLngOffset = latLngOffset,
TargetAlt = targetAlt,
Rate = rate,
Turns = turns,
Channel3 = channel3
};
return info;
}
}
}

View File

@ -13,9 +13,7 @@ namespace Plane.FormationCreator.Formation
{
var info = new FlightTaskSingleCopterInfo(copter)
{
TargetAlt = targetAlt,
TargetLat = copter.Latitude,
TargetLng=copter.Longitude
TargetAlt = targetAlt
};
return info;
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Plane.Copters;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTaskSingleCopterInfo
{
public static FlightTaskSingleCopterInfo CreateForTurnTask(ICopter copter, LatLng latLngOffset, float targetAlt, short targetHeading)
{
var info = new FlightTaskSingleCopterInfo(copter)
{
LatLngOffset = latLngOffset,
TargetAlt = targetAlt,
TargetHeading = targetHeading
};
return info;
}
private short _TargetHeading;
public short TargetHeading
{
get { return _TargetHeading; }
set { Set(nameof(TargetHeading), ref _TargetHeading, value); }
}
}
}

View File

@ -2,8 +2,7 @@
{
Stop,
Running,
Paused,
Selected
Paused
}
public enum TasksStatus
{

View File

@ -0,0 +1,137 @@
using Plane.Copters;
using Plane.Geography;
using Plane.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTask
{
public async Task RunCircleTaskAsync()
{
// 林俊清, 20150922, 首先一起调好方向。
await Task.WhenAll(
SingleCopterInfos.Select(info =>
{
int copterIndex = SingleCopterInfos.IndexOf(info);
// 当该飞机被标记时,跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
return Task.Run(()=> { });
info.TargetHeading = info.CenterDirectionDeg;
return TurnTaskFlySingleCopterAsync(info);
})
).ConfigureAwait(false);
await Task.WhenAll(
SingleCopterInfos.Select(info => CircleTaskFlySingleCopterAsync(info))
).ConfigureAwait(false);
}
private async Task CircleTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
{
// 林俊清, 20150907, 目前不对 Circle 进行仿真。
if (info.Copter is FakeCopter)
{
await Task.Delay(1000);
return;
}
int copterIndex = SingleCopterInfos.IndexOf(info);
// 当该飞机被标记时,跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
return;
await info.Copter.SetParamAsync("CIRCLE_RADIUS", info.Radius);
await info.Copter.SetParamAsync("CIRCLE_RATE", info.Rate);
var center = GeographyUtils.CalcLatLngSomeMetersAway2D(info.Copter.Latitude, info.Copter.Longitude, info.CenterDirectionDeg, 10);
await info.Copter.CircleAsync();
while (info.Copter.State != Copters.CopterState.Circling)
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(25).ConfigureAwait(false);
}
await info.Copter.SetChannelsAsync(ch3: info.Channel3);
for (int i = info.Turns; i > 0; i--)
{
//// 等待一段时间,让飞行器飞出一段距离。
//for (int i = 0; i < 3000 / 25; i++)
//{
// if (_flightTaskManager.IsPaused == true)
// {
// info.Copter.Hover();
// return;
// }
// await Task.Delay(25).ConfigureAwait(false);
//}
//var log = new StringBuilder(1024);
//var lastLogTime = DateTime.Now;
bool step1 = false;
while (true)
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
var angle = info.Radius == 0 ? NormalizeAngleDeg(info.Copter.Heading - info.CenterDirectionDeg) : GetNormalizedAngleDeg(info, center);
//log.AppendLine($"{angle} {step1}");
if (!step1)
{
if (angle > 100 && angle < 330)
{
step1 = true;
//log.AppendLine($"step1 is true now.");
}
}
else if (angle > 340 || angle < 5)
{
//log.AppendLine("break");
break;
}
//if (lastLogTime.AddSeconds(10) < DateTime.Now)
//{
// Logger.Instance.Log(log.ToString());
// log.Clear();
// lastLogTime = DateTime.Now;
//}
await Task.Delay(25).ConfigureAwait(false);
}
//Logger.Instance.Log(log.ToString());
}
await info.Copter.HoverAsync();
}
private static double GetNormalizedAngleDeg(FlightTaskSingleCopterInfo info, Tuple<double, double> center)
{
var angle = info.Copter.InPlaneDirectionToDeg(center.Item1, center.Item2) - info.CenterDirectionDeg;
return NormalizeAngleDeg(angle);
}
private static double NormalizeAngleDeg(double angle)
{
while (true)
{
if (angle < 0) angle += 360;
else if (angle >= 360) angle -= 360;
else break;
}
return angle;
}
}
}

View File

@ -32,7 +32,7 @@ namespace Plane.FormationCreator.Formation
Set(nameof(FlytoTime), ref _FlytoTime, value);
}
}
private int _LoiterTime = 1;
private int _LoiterTime = 10;
public int LoiterTime
{
get { return _LoiterTime; }
@ -86,10 +86,20 @@ namespace Plane.FormationCreator.Formation
for (int i = 0; i < infos.Count; i++)
{
var info = infos[i];
//为每架飞机创建一个航点任务
tasks[i] = await Task.Factory.StartNew(async () =>
{
var internalInfo = info;
//if (i1 > 0)
//{
// var prevCopter = infos[i1 - 1].Copter;
// while (CheckCrossing(infos, i1) &&
// prevCopter.Altitude - copter.Altitude < 2)
// {
// await Task.Delay(25).ConfigureAwait(false);
// }
//}
await FlyToTaskFlySingleCopterAsync(internalInfo);
});
}
@ -105,12 +115,8 @@ namespace Plane.FormationCreator.Formation
}
// private int RuningTaskRemaining = 0;
/// <summary>
/// 单独飞机执行飞行任务
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
private int RuningTaskRemaining = 0;
private async Task FlyToTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
{
DateTime dtNow = DateTime.Now;
@ -138,6 +144,15 @@ namespace Plane.FormationCreator.Formation
await info.Copter.GuidAsync();
/*
for (int i = 0; i < 5; i++)
{
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, info.TargetAlt);
await Task.Delay(10).ConfigureAwait(false);
}
*/
double targetLat = info.TargetLat;
double targetLng = info.TargetLng;
if (info.IsLandWaypoint)
@ -145,21 +160,59 @@ namespace Plane.FormationCreator.Formation
targetLat = info.Copter.TakeOffPoint.Latitude;
targetLng = info.Copter.TakeOffPoint.Longitude;
}
int flytype = _flightTaskManager.getflytype(taskIndex);
//指定目标位置
await info.Copter.FlyToAsync(targetLat, targetLng, info.TargetAlt, task.FlytoTime, flytype);
//发送目标航点1次
await info.Copter.FlyToAsync(targetLat, targetLng, info.TargetAlt);
await Task.Delay(10).ConfigureAwait(false);
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
//等待时间到达,并执行灯光模拟--不移动飞机,移动飞机是飞机自己计算的
int sendFlyToTimes = 0;
//第0个任务为takeoff
if (taskIndex > 0)
{
FlightTask prevTask = _flightTaskManager.Tasks[taskIndex - 1];
if (prevTask.TaskType == FlightTaskType.FlyTo && prevTask.LoiterTime == 0)
flyToTime += prevTask.RuningTaskRemaining;
}
//while (!info.Copter.ArrivedTarget(info.TargetLat, info.TargetLng, info.TargetAlt)) //按航点飞 所有Copter到达目标点开始飞下个航点
while (ts.TotalMilliseconds < (flyToTime + loiterTime)) //按时间轴飞:当前任务时间到达后自动飞往下个航点
{
//悬停时间等于0为快速航点 到达之后立即出发下个航点 切时间累积
if (loiterTime == 0 &&
info.Copter.ArrivedTarget(info.TargetLat, info.TargetLng, info.TargetAlt))
{
task.RuningTaskRemaining = flyToTime - (int)ts.TotalMilliseconds;
break;
}
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(100).ConfigureAwait(false); //判断是否到达位置10hz
//执行灯光模拟
await Task.Delay(10).ConfigureAwait(false); //判断是否到达位置10hz
// if (info.LEDInfos.Count > 0)
// {
// string LEDRGB = "";
// List<LEDInfo> LedControl = info.LEDInfos.OrderBy(i=>i.Delay).ToList();
// for (int i = 0; i < LedControl.Count; i++)
// {
// var led = LedControl[i];
// if (ts.TotalMilliseconds >= led.Delay * 1000)
// LEDRGB = info.LEDInfos[i].LEDRGB;
// else
// break;
// }
// info.Copter.LEDColor = LEDRGB;
//
// }
if (info.LEDInfos.Count > 0)
{
string LEDRGB = "";
@ -176,6 +229,21 @@ namespace Plane.FormationCreator.Formation
break;
}
info.Copter.LEDColor = LEDRGB;
}
if (ts.TotalMilliseconds / 10 > sendFlyToTimes) // 每500ms发送一遍指点坐标
{
sendFlyToTimes++;
for (int i = 0; i < 2; i++)
{
await info.Copter.FlyToAsync(targetLat, targetLng, info.TargetAlt);
await Task.Delay(10).ConfigureAwait(false);
}
//dtLastTime = dtNow;
}
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
@ -183,10 +251,6 @@ namespace Plane.FormationCreator.Formation
await info.Copter.HoverAsync();
return;
}
if (_flightTaskManager.IsEmergencyRet == true)
{
return;
}
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
}

View File

@ -36,34 +36,8 @@ namespace Plane.FormationCreator.Formation
DateTime dtLastTime = DateTime.Now;
TimeSpan ts = dtNow - dtLastTime;
int waittime = (int)info.LandWaitTime * 1000;
while (ts.TotalMilliseconds < waittime)
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(100).ConfigureAwait(true);
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
}
await Task.Delay(waittime).ConfigureAwait(false);
await info.Copter.LandAsync();
while ((info.Copter.Altitude>0.0f))
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(100).ConfigureAwait(true);
}
}
}
}

View File

@ -0,0 +1,723 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTask
{
private float _LoiterTimeAttr = 0.0f;
public float LoiterTimeAttr
{
get { return _LoiterTimeAttr; }
set
{
Set(nameof(LoiterTimeAttr), ref _LoiterTimeAttr, value);
}
}
// 改变机头
private bool _ChangeYaw = false;
public bool ChangeYaw
{
get { return _ChangeYaw; }
set
{
Set(nameof(ChangeYaw), ref _ChangeYaw, value);
}
}
// 机头方向0为北顺时针360
private float _HeadYaw = 1.0f;
public float HeadYaw
{
get { return _HeadYaw; }
set
{
Set(nameof(HeadYaw), ref _HeadYaw, value);
}
}
// LED灯闪烁
private bool _flashAttr = false;
public bool flashAttr
{
get { return _flashAttr; }
set
{
Set(nameof(flashAttr), ref _flashAttr, value);
}
}
// LED闪烁次数
private float _flashPeriodAttr = 1.0f;
public float flashPeriodAttr
{
get { return _flashPeriodAttr; }
set
{
Set(nameof(flashPeriodAttr), ref _flashPeriodAttr, value);
}
}
private string Name2Index(string name) // 获取指定copter名字对应的序号
{
int index = -1;
for (int i = 0; i < SingleCopterInfos.Count; i++)
{
if (name.Equals(SingleCopterInfos[i].Copter.Name))
{
return i.ToString();
}
}
return index.ToString();
}
// 闪烁的飞机名字编号
private string _flashCopterNameArray = "";
public string flashCopterNameArray
{
get { return _flashCopterNameArray; }
set
{
Set(nameof(flashCopterNameArray), ref _flashCopterNameArray, value);
flashCopterIndexArray = "";
string[] copterArray = flashCopterNameArray.Split(',');
for (int i = 0; i < copterArray.Length; i++)
{
flashCopterIndexArray += Name2Index(copterArray[i])+',';
}
}
}
// 闪烁的飞机序号编号
private string _flashCopterIndexArray = "";
public string flashCopterIndexArray
{
get { return _flashCopterIndexArray; }
set
{
Set(nameof(flashCopterIndexArray), ref _flashCopterIndexArray, value);
}
}
// LED走马灯
private bool _oneByOneAttr = false;
public bool oneByOneAttr
{
get { return _oneByOneAttr; }
set
{
Set(nameof(oneByOneAttr), ref _oneByOneAttr, value);
}
}
// LED走马灯次数
private float _oneByOnePeriodAttr = 1.0f;
public float oneByOnePeriodAttr
{
get { return _oneByOnePeriodAttr; }
set
{
Set(nameof(oneByOnePeriodAttr), ref _oneByOnePeriodAttr, value);
}
}
private int[] columnFirst = {0, 1, 2, 3, 4 };
private int[] columnSecond = { 5, 6, 7, 8, 9 };
private int[] columnThird = { 10, 11, 12, 13, 14 };
private int[] columnFourth = { 15, 16, 17, 18, 19 };
private int[] columnFive = { 20, 21, 22, 23, 24 };
private int[] columnSix = { 25, 26, 27, 28, 29 };
private int[] rowFirst = { 0, 5, 10, 15, 20, 25 };
private int[] rowSecond = { 1, 6, 11, 16, 21, 26 };
private int[] rowThird = { 2, 7, 12, 17, 22, 27 };
private int[] rowFourth = { 3, 8, 13, 18, 23, 28 };
private int[] rowFive = { 4, 9, 14, 19, 24, 29 };
private int[] rowFirstForEight = { 0, 1, 2, 3 };
private int[] rowSecondForEight = { 4, 5, 6, 7 };
private int[] doubleColumnFirst = { 0, 1, 2, 3, 4, 25, 26, 27, 28, 29 };
private int[] doubleColumnSecond = { 5, 6, 7, 8, 9, 20, 21, 22, 23, 24 };
private int[] doubleColumnThird = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
private int[] circleFirst = { 0, 1, 2, 3, 4, 9, 14, 19, 24, 29, 28, 27, 26, 25, 20, 15, 10, 5 };
private int[] circleSecond = { 6, 7, 8, 13, 18, 23, 22, 21, 16, 11 };
private int[] circleThird = { 12, 17 };
private int[] lineFirst = { 4 };
private int[] lineSecond = { 3, 9 };
private int[] lineThird = { 2, 8, 14 };
private int[] lineFourth = { 1, 7, 13, 19 };
private int[] lineFive = { 0, 6, 12, 18, 24 };
private int[] lineSix = { 5, 11, 17, 23, 29 };
private int[] lineSeven = { 10, 16, 22, 28 };
private int[] lineEight = { 15, 21, 27 };
private int[] lineNine = { 20, 26 };
private int[] lineTen = { 25 };
public async Task RunLoiterTimeTaskAsync()
{
if (ChangeYaw)
{
await Task.WhenAll(SingleCopterInfos.Select(info => SetCopterYawAsync(info,HeadYaw)));
}
// 判断flashPeriodAttr, oneByOnePeriodAttr的值执行不同的闪烁模式
// 当flashPeriodAttr小于10正常闪烁即没有预制闪烁模式
// 当flashPeriodAttr大于等于10小于20执行预制闪烁模式
// 当flashPeriodAttr大于等于20 改变飞控闪烁模式以oneByOnePeriodAttr作为周期值
//LEDFlashPlanAsync需要30架飞机
if ((flashPeriodAttr >= 10.0f) && (flashPeriodAttr < 20.0f))
{
await LEDFlashPlanAsync();
return;
}
//需要固件支持
if (flashPeriodAttr >= 20.0f)
{
await LEDFlashParaModifyPlanAsync();
return;
}
var infos = SingleCopterInfos;
if (flashAttr) // LED闪烁显示效果
{
if (flashCopterIndexArray.Equals(""))
return;
string[] copterArray = flashCopterIndexArray.Split(',');
var tasks_selected = new Task[copterArray.Length];
// LED灯全灭
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
await Task.Delay(1000).ConfigureAwait(false);
// 选中的飞机LED灯全亮
for (int i = 0; i < copterArray.Length; i++)
{
int index = int.Parse(copterArray[i]);
var info = infos[index];
tasks_selected[i] = await Task.Factory.StartNew(async () =>
{
var internalInfo = info;
await LEDFlashTaskFlySingleCopterAsync(internalInfo, true);
});
}
await Task.WhenAll(tasks_selected).ConfigureAwait(false);
await Task.Delay(3000).ConfigureAwait(false);
// LED灯全亮
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
//延时等待
//判断是否下一步
DateTime start = DateTime.Now;
while (true)
{
if (_flightTaskManager.IsPaused == true)
{
await Task.WhenAll(SingleCopterInfos.Select(info => (info.Copter.HoverAsync())));
return;
}
DateTime end = DateTime.Now;
TimeSpan ts = end - start;
//等待指定时间
if (ts.TotalMilliseconds > LoiterTimeAttr * 1000)
break;
await Task.Delay(20).ConfigureAwait(false);
}
}
else if (oneByOneAttr) // LED走马灯显示效果
{
if (flashCopterNameArray.Equals(""))
return;
string[] copterArray = flashCopterIndexArray.Split(',');
//LED全灭
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
await Task.Delay(1000).ConfigureAwait(false);
// LED灯一个接一个全亮
for (int i = 0; i < copterArray.Length; i++)
{
if (copterArray[i] == "") break;
int index = int.Parse(copterArray[i]);
var info = infos[index];
await LEDFlashTaskFlySingleCopterAsync(info, true);
await Task.Delay(200).ConfigureAwait(false);
}
await Task.Delay(1000).ConfigureAwait(false);
//////////////////全部闪烁一次
// LED灯全亮
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
await Task.Delay(200).ConfigureAwait(false);
// LED灯全灭
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
await Task.Delay(200).ConfigureAwait(false);
/////////////////////////////////////
//////////////////全部闪烁一次
// LED灯全亮
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
await Task.Delay(200).ConfigureAwait(false);
// LED灯全灭
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
await Task.Delay(200).ConfigureAwait(false);
/////////////////////////////////////
//////////////////全部闪烁一次
// LED灯全亮
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
await Task.Delay(200).ConfigureAwait(false);
// LED灯全灭
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
await Task.Delay(200).ConfigureAwait(false);
/////////////////////////////////////
// LED灯全亮
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
//延时等待
//判断是否下一步
DateTime start = DateTime.Now;
while (true)
{
if (_flightTaskManager.IsPaused == true)
{
await Task.WhenAll(SingleCopterInfos.Select(info => (info.Copter.HoverAsync())));
return;
}
DateTime end = DateTime.Now;
TimeSpan ts = end - start;
//等待指定时间
if (ts.TotalMilliseconds > LoiterTimeAttr * 1000)
break;
await Task.Delay(20).ConfigureAwait(false);
}
}
else // 没有LED显示效果只等待
{
//判断是否下一步
DateTime start = DateTime.Now;
while (true)
{
if (_flightTaskManager.IsPaused == true)
{
await Task.WhenAll(SingleCopterInfos.Select(info => (info.Copter.HoverAsync())));
return;
}
DateTime end = DateTime.Now;
TimeSpan ts = end - start;
//等待指定时间
if (ts.TotalMilliseconds > LoiterTimeAttr * 1000)
break;
await Task.Delay(20).ConfigureAwait(false);
}
}
}
private async Task LEDFlashParaModifyPlanAsync()
{
/*
await LEDFlashParaModifyAsync(rowFirstForEight);
await Task.Delay(500).ConfigureAwait(false);
await LEDFlashParaModifyAsync(rowSecondForEight);
await Task.Delay(500).ConfigureAwait(false);
*/
int copterCount = SingleCopterInfos.Count();
int[] intArray = new int[copterCount];
for (int ii=0; ii<copterCount; ii++)
{
intArray[ii] = ii;
}
await LEDFlashParaModifyAsync(intArray);
/*
await LEDFlashParaModifyAsync(rowFirst);
await Task.Delay(500).ConfigureAwait(false);
await LEDFlashParaModifyAsync(rowSecond);
await Task.Delay(500).ConfigureAwait(false);
await LEDFlashParaModifyAsync(rowThird);
await Task.Delay(500).ConfigureAwait(false);
await LEDFlashParaModifyAsync(rowFourth);
await Task.Delay(500).ConfigureAwait(false);
await LEDFlashParaModifyAsync(rowFive);
await Task.Delay(500).ConfigureAwait(false);
*/
}
private async Task LEDFlashParaModifyAsync(int[] LEDArray)
{
var infos = SingleCopterInfos;
var tasks_selected = new Task[LEDArray.Length];
for (int i = 0; i < LEDArray.Length; i++)
{
var info = infos[LEDArray[i]];
tasks_selected[i] = await Task.Factory.StartNew(async () =>
{
var internalInfo = info;
await LEDParaModifySingleCopterAsync(internalInfo, oneByOnePeriodAttr);
});
}
await Task.WhenAll(tasks_selected).ConfigureAwait(false);
}
private async Task SetCopterYawAsync(FlightTaskSingleCopterInfo info, float headyaw)
{
var copter = info.Copter;
// await Task.Delay(200).ConfigureAwait(false);
int copterIndex = SingleCopterInfos.IndexOf(info);
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
var tasks = new Task[1];
tasks[0] = Task.Run(async () =>
{
try
{
await copter.SetMobileControlAsync(yaw: headyaw);
while (!copter.ArrivedHeading((short)headyaw))
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(25).ConfigureAwait(false);
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
}
}
catch (TimeoutException ex)
{
_logger.Log($"SetYAWtimeout, {ex.Message}, CopterId: {copter.Id}。");
}
});
await Task.WhenAll(tasks).ConfigureAwait(false);
}
private async Task LEDParaModifySingleCopterAsync(FlightTaskSingleCopterInfo info, float count)
{
var copter = info.Copter;
int copterIndex = SingleCopterInfos.IndexOf(info);
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
var tasks = new Task[1];
tasks[0] = Task.Run(async () =>
{
try
{
if (count == 1.0)
await copter.SetShowLEDAsync(true);
else
await copter.SetShowLEDAsync(false);
//await copter.SetParamAsync("NTF_SHOWLED", count, 5000);
}
catch (TimeoutException ex)
{
_logger.Log($"SetShowLEDAsync 超时, {ex.Message}, CopterId: {copter.Id}。");
}
});
/*
var tasks = new Task[2];
tasks[0] = Task.Run(async () =>
{
try
{
await copter.SetParamAsync("NOTI_GPSLED", count, 5000);
}
catch (TimeoutException ex)
{
_logger.Log($"NOTI_GPSLED 超时, {ex.Message}, CopterId: {copter.Id}。");
}
});
tasks[1] = Task.Run(async () =>
{
try
{
await copter.SetParamAsync("NOTI_ARMLED", count, 5000);
}
catch (TimeoutException ex)
{
_logger.Log($"NOTI_ARMLED 超时, {ex.Message}, CopterId: {copter.Id}。");
}
});
*/
await Task.WhenAll(tasks).ConfigureAwait(false);
}
/**
* isOn为trueisOn为false
*/
private async Task LEDFlashTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info, bool isOn)
{
var copter = info.Copter;
int copterIndex = SingleCopterInfos.IndexOf(info);
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
// float gpsLed = await c.GetParamAsync("NOTI_GPSLED");
/*
float ledControl = 0.0f; //关灯
if (isOn)
{
ledControl = 1.0f; //长亮
}
*/
var tasks = new Task[1];
tasks[0] = Task.Run(async () =>
{
try
{
await copter.SetShowLEDAsync(isOn);
// await copter.SetParamAsync("NTF_SHOWLED", ledControl, 5000);
}
catch (TimeoutException ex)
{
_logger.Log($"SetShowLED 超时, {ex.Message}, CopterId: {copter.Id}。");
}
});
/*
var tasks = new Task[2];
tasks[0] = Task.Run(async () =>
{
try
{
await copter.SetParamAsync("NOTI_GPSLED", ledControl, 5000);
}
catch (TimeoutException ex)
{
_logger.Log($"NOTI_GPSLED 超时, {ex.Message}, CopterId: {copter.Id}。");
}
});
tasks[1] = Task.Run(async () =>
{
try
{
await copter.SetParamAsync("NOTI_ARMLED", ledControl, 5000);
}
catch (TimeoutException ex)
{
_logger.Log($"NOTI_ARMLED 超时, {ex.Message}, CopterId: {copter.Id}。");
}
});
*/
await Task.WhenAll(tasks).ConfigureAwait(false);
}
private async Task LEDFlashPlanAsync()
{
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
await Task.Delay(500).ConfigureAwait(false);
await LEDColumnFlashAsync();
await Task.Delay(500).ConfigureAwait(false);
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
await Task.Delay(500).ConfigureAwait(false);
await LEDDoubleColumnFlashAsync();
await Task.Delay(500).ConfigureAwait(false);
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
await Task.Delay(500).ConfigureAwait(false);
await LEDLineFlashAsync();
await Task.Delay(500).ConfigureAwait(false);
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
await Task.Delay(500).ConfigureAwait(false);
await LEDCircleFlashAsync();
await Task.Delay(500).ConfigureAwait(false);
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
await Task.Delay(200).ConfigureAwait(false);
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
await Task.Delay(200).ConfigureAwait(false);
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
await Task.Delay(200).ConfigureAwait(false);
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
await Task.Delay(200).ConfigureAwait(false);
}
// 一排一排闪烁 需要30架飞机6排一排5架一排排闪灯
private async Task LEDColumnFlashAsync()
{
await LEDArrayFlashAsync(columnFirst);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(columnSecond);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(columnThird);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(columnFourth);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(columnFive);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(columnSix);
await Task.Delay(200).ConfigureAwait(false);
}
// 以圆圈收缩形式显示
private async Task LEDCircleFlashAsync()
{
await LEDArrayFlashAsync(circleFirst);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(circleSecond);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(circleThird);
await Task.Delay(200).ConfigureAwait(false);
}
// 两列同时闪烁
private async Task LEDDoubleColumnFlashAsync()
{
await LEDArrayFlashAsync(doubleColumnFirst);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(doubleColumnSecond);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(doubleColumnThird);
await Task.Delay(200).ConfigureAwait(false);
}
// 斜线方式闪烁
private async Task LEDLineFlashAsync()
{
await LEDArrayFlashAsync(lineFirst);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(lineSecond);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(lineThird);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(lineFourth);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(lineFive);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(lineSix);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(lineSeven);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(lineEight);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(lineNine);
await Task.Delay(200).ConfigureAwait(false);
await LEDArrayFlashAsync(lineTen);
await Task.Delay(200).ConfigureAwait(false);
}
private async Task LEDArrayFlashAsync(int[] LEDArray)
{
var infos = SingleCopterInfos;
var tasks_selected = new Task[LEDArray.Length];
for (int i = 0; i < LEDArray.Length; i++)
{
var info = infos[LEDArray[i]];
tasks_selected[i] = await Task.Factory.StartNew(async () =>
{
var internalInfo = info;
await LEDFlashTaskFlySingleCopterAsync(internalInfo, true);
});
}
await Task.WhenAll(tasks_selected).ConfigureAwait(false);
}
}
}

View File

@ -0,0 +1,489 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTask
{
private float _RTLAlt = 20.0f;
public float RTLAlt
{
get { return _RTLAlt; }
set { Set(nameof(RTLAlt), ref _RTLAlt, value); }
}
private int _RetNumAttr = 1;
public int RetNumAttr
{
get { return _RetNumAttr; }
set
{
Set(nameof(RetNumAttr), ref _RetNumAttr, value);
}
}
public async Task RunReturnToLandTaskAsync()
{
int TaskCount = _flightTaskManager.Tasks.Count();
if (TaskCount > 1)
{
var infos = SingleCopterInfos;
// var infos = SingleCopterInfos.OrderByDescending(i => i.TargetAlt).ToList();
var tasks = new Task[infos.Count];
var tasksTmp = new Task[infos.Count];
for (int i = 0; i < infos.Count; i++)
{
var info = infos[i];
// var copter = info.Copter;
if (info.RTLStage <= 1) // 当前阶段小于等于1时进入
{
await ReturnToLandTaskFlySingleCopterAsync(info);
}
tasksTmp[i] = ReturnToLandSecondTaskAsync(info);
}
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
if (_flightTaskManager.IsPaused == false)
{
for (int i = 0; i < infos.Count; i++)
{
var info = infos[i];
info.RTLStage = 0;
}
}
}
}
public async Task MutilRunReturnToLandTaskAsync()
{
int TaskCount = _flightTaskManager.Tasks.Count();
if (TaskCount > 1)
{
var infos = SingleCopterInfos;
int copterCount = infos.Count;
int integerPart = copterCount / RetNumAttr;
int residualPart = copterCount % RetNumAttr;
var tasksTmp = new Task[infos.Count];
//整数部分执行返航降落
for (int i = 0; i < integerPart; i++)
{
var tasksRetutn = new Task[RetNumAttr*2];
//设置返航任务
for (int j = RetNumAttr * i; j < RetNumAttr * (i + 1); j++)
{
var info = infos[j];
int indexTmp = j - RetNumAttr * i;
// var copter = info.Copter;
if (info.RTLStage <= 1) // 当前阶段小于等于1时进入
{
tasksRetutn[indexTmp] = ReturnToLandTaskFlySingleCopterAsync(info);
}
else
{
tasksRetutn[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
}
}
//设置降落任务
if (i > 0)
{
for (int j = RetNumAttr * (i - 1); j < RetNumAttr * (i); j++)
{
var info = infos[j];
int indexTmp = RetNumAttr+ j - RetNumAttr * (i-1);
// var copter = info.Copter;
if (info.RTLStage == 2) // 当前阶段小于等于1时进入
{
tasksRetutn[indexTmp] = ReturnToLandSecondTaskAsync(info);
}
else
{
tasksRetutn[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
}
}
}
else {
//第一波返航,降落任务为空
for (int j = RetNumAttr * (i +1); j < RetNumAttr * (i+2); j++)
{
int indexTmp = j - RetNumAttr * i;
tasksRetutn[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
}
}
//开始执行这波返航和上波降落
await Task.WhenAll(tasksRetutn).ConfigureAwait(false);
//上波降落后设置为0
if (_flightTaskManager.IsPaused == false)
{
if (i > 0)
{
for (int j = RetNumAttr * (i - 1); j < RetNumAttr * (i); j++)
{
var info = infos[j];
info.RTLStage = 0;
}
}
}
}
if (residualPart > 0)
{
var tasksreturn = new Task[residualPart+ RetNumAttr];
//余数部分开始返航
for (int j = integerPart * RetNumAttr; j < RetNumAttr * integerPart + residualPart; j++)
{
var info = infos[j];
int indexTmp = j - RetNumAttr * integerPart;
// var copter = info.Copter;
if (info.RTLStage <= 1) // 当前阶段小于等于1时进入
{
tasksreturn[indexTmp] = ReturnToLandTaskFlySingleCopterAsync(info);
}
else
{
tasksreturn[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
}
}
//无余数的整数部分最后一波开始降落
// var tasksLastland = new Task[RetNumAttr];
for (int j = RetNumAttr * (integerPart - 1); j < RetNumAttr * (integerPart); j++)
{
var info = infos[j];
int indexTmp = RetNumAttr + j - RetNumAttr * integerPart;
// var copter = info.Copter;
if (info.RTLStage == 2) // 当前阶段小于等于1时进入
{
tasksreturn[residualPart + indexTmp] = ReturnToLandSecondTaskAsync(info);
}
else
{
tasksreturn[residualPart+indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
}
}
//开始执行降落和返航
await Task.WhenAll(tasksreturn).ConfigureAwait(false);
//降落后设置为0
if (_flightTaskManager.IsPaused == false)
{
for (int j = RetNumAttr * (integerPart - 1); j < RetNumAttr * (integerPart); j++)
{
var info = infos[j];
info.RTLStage = 0;
}
}
//最后余数部分降落
var tasksRetutn1 = new Task[residualPart];
for (int j = integerPart * RetNumAttr; j < RetNumAttr * integerPart + residualPart; j++)
{
var info = infos[j];
int indexTmp = j - RetNumAttr * integerPart;
// var copter = info.Copter;
if (info.RTLStage == 2) // 当前阶段小于等于1时进入
{
tasksRetutn1[indexTmp] = ReturnToLandSecondTaskAsync(info);
}
else
{
tasksRetutn1[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
}
}
await Task.WhenAll(tasksRetutn1).ConfigureAwait(false);
if (_flightTaskManager.IsPaused == false)
{
for (int j = integerPart * RetNumAttr; j < RetNumAttr * integerPart + residualPart; j++)
{
var info = infos[j];
info.RTLStage = 0;
}
}
}
else
{
//无余数的整数部分最后一波开始降落
var tasksLastland = new Task[RetNumAttr];
for (int j = RetNumAttr * (integerPart - 1); j < RetNumAttr * (integerPart); j++)
{
var info = infos[j];
int indexTmp = RetNumAttr + j - RetNumAttr * integerPart;
// var copter = info.Copter;
if (info.RTLStage == 2) // 当前阶段小于等于1时进入
{
tasksLastland[indexTmp] = ReturnToLandSecondTaskAsync(info);
}
else
{
tasksLastland[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
}
}
await Task.WhenAll(tasksLastland).ConfigureAwait(false);
//降落后设置为0
if (_flightTaskManager.IsPaused == false)
{
for (int j = RetNumAttr * (integerPart - 1); j < RetNumAttr * (integerPart); j++)
{
var info = infos[j];
info.RTLStage = 0;
}
}
}
}
}
//原地下降高度到15米然后返回起飞点
private async Task ReturnToLandTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
{
float takeOffAlt = RTLAlt;
int TaskCount = _flightTaskManager.Tasks.Count();
int copterIndex = SingleCopterInfos.IndexOf(info);
var copter = info.Copter;
var copterPreviousTask = _flightTaskManager.Tasks[TaskCount-2].SingleCopterInfos[copterIndex]; // 倒数第二步的目标位置
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
DateTime dtNow = DateTime.Now;
DateTime dtLastTime = DateTime.Now;
TimeSpan ts = dtNow - dtLastTime;
// 第一阶段:垂直飞行
if (info.RTLStage == 0)
{
for (int j = 0; j < 3; j++)
{
await info.Copter.FlyToAsync(copterPreviousTask.TargetLat, copterPreviousTask.TargetLng, takeOffAlt);
}
while (!info.Copter.ArrivedTarget(copterPreviousTask.TargetLat, copterPreviousTask.TargetLng, takeOffAlt))
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(25).ConfigureAwait(false);
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
if (ts.TotalMilliseconds > 1000)
{
for (int j = 0; j < 2; j++)
{
await info.Copter.FlyToAsync(copterPreviousTask.TargetLat, copterPreviousTask.TargetLng, takeOffAlt);
}
dtLastTime = dtNow;
}
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
}
info.RTLStage++;
}
dtNow = DateTime.Now;
dtLastTime = DateTime.Now;
ts = dtNow - dtLastTime;
var copterFirstTask = _flightTaskManager.Tasks[0].SingleCopterInfos[copterIndex]; // 第一步记录的家位置
// 第二阶段:水平飞行
if (info.RTLStage == 1)
{
for (int j = 0; j < 3; j++)
{
await info.Copter.FlyToAsync(copterFirstTask.TargetLat, copterFirstTask.TargetLng, takeOffAlt);
}
while (!info.Copter.ArrivedTarget(copterFirstTask.TargetLat, copterFirstTask.TargetLng, takeOffAlt))
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(25).ConfigureAwait(false);
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
if (ts.TotalMilliseconds > 1000)
{
for (int j = 0; j < 2; j++)
{
await info.Copter.FlyToAsync(copterFirstTask.TargetLat, copterFirstTask.TargetLng, takeOffAlt);
}
dtLastTime = dtNow;
}
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
}
info.RTLStage++;
}
}
//在起飞点上空从15米降落到4米然后切land模式
private async Task ReturnToLandSecondTaskAsync(FlightTaskSingleCopterInfo info)
{
// await Task.Run(async () =>
// {
int copterIndex = SingleCopterInfos.IndexOf(info);
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
DateTime dtNow = DateTime.Now;
DateTime dtLastTime = DateTime.Now;
TimeSpan ts = dtNow - dtLastTime;
float landAlt = 4.0f; // 飞机降落到4m再切land模式
var copterFirstTask = _flightTaskManager.Tasks[0].SingleCopterInfos[copterIndex]; // 第一步记录的家位置
// 第三阶段
if (info.RTLStage == 2)
{
for (int j = 0; j < 3; j++)
{
await info.Copter.FlyToAsync(copterFirstTask.TargetLat, copterFirstTask.TargetLng, landAlt);
}
while (!info.Copter.ArrivedTarget(copterFirstTask.TargetLat, copterFirstTask.TargetLng, landAlt))
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(25).ConfigureAwait(false);
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
if (ts.TotalMilliseconds > 1000)
{
for (int j = 0; j < 2; j++)
{
await info.Copter.FlyToAsync(copterFirstTask.TargetLat, copterFirstTask.TargetLng, landAlt);
}
dtLastTime = dtNow;
}
// 当该飞机被标记时,悬停并跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
{
await info.Copter.HoverAsync();
return;
}
}
info.RTLStage++;
}
// 切到land模式
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
var copter = info.Copter;
if (info.RTLStage == 3) // 下降过程
{
for (int j = 0; j < 5; j++) // added by ZJF
{
// await copter.ReturnToLaunchAsync();
await copter.LandAsync(); // 修改为降落模式
await Task.Delay(10);
}
}
// });
}
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTask
{
public async Task RunSimpleCircleTaskAsync()
{
var center = SingleCopterInfos.Select(info => info.Copter).GetCenter().Value;
// 林俊清, 20150921, 自动计算圆心方向和半径,然后直接调用普通画圈的方法。
foreach (var info in SingleCopterInfos)
{
info.CenterDirectionDeg = (short)info.Copter.InPlaneDirectionToDeg(center.Lat, center.Lng);
info.Radius = (int)(info.Copter.InPlaneDistanceTo(center.Lat, center.Lng) * 100);
}
await RunCircleTaskAsync().ConfigureAwait(false);
}
}
}

View File

@ -13,6 +13,16 @@ namespace Plane.FormationCreator.Formation
{
private int _TakeOffNumAttr = 1;
public int TakeOffNumAttr
{
get { return _TakeOffNumAttr; }
set
{
Set(nameof(TakeOffNumAttr), ref _TakeOffNumAttr, value);
}
}
//起飞到第一个航点高度的飞行时间
private byte _TakeOffTime = 10;
public byte TakeOffTime
@ -66,20 +76,20 @@ namespace Plane.FormationCreator.Formation
var tasksTakeOff = new Task[infos.Count];
for (int i = 0; i < infos.Count; i++)
{
//tasksTakeOff[i] = NewSingleRunTaskOffTaskAsunc(infos[i]);
tasksTakeOff[i] = await Task.Factory.StartNew(async () =>
{
var internalInfo = infos[i];
await NewSingleRunTaskOffTaskAsunc(internalInfo);
});
}
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
//await Task.Delay(100);
}
/// <summary>
/// 单独飞机 执行起飞任务
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
private async Task NewSingleRunTaskOffTaskAsunc(FlightTaskSingleCopterInfo info)
{
DateTime dtNow = DateTime.Now;
@ -105,25 +115,29 @@ namespace Plane.FormationCreator.Formation
//虚拟飞机5秒后不起飞会自动上锁
await copter.UnlockAsync();
for (int i = 0; i < 5; i++) // added by ZJF
{
await copter.TakeOffAsync();
await Task.Delay(50).ConfigureAwait(false);
}
var copterNextTask = _flightTaskManager.Tasks[TaskIndex + 1].SingleCopterInfos[copterIndex];
float takeOffAlt = copterNextTask.TargetAlt;
info.TargetLat = info.Copter.Latitude;
info.TargetLng = info.Copter.Longitude;
//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); //秒
//解锁起飞用暗紫色
info.Copter.LEDColor = CopterManager.CopterTakeoffColor;
for (int j = 0; j < 3; j++)
{
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
await Task.Delay(10).ConfigureAwait(false);
}
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
FlightTask task = _flightTaskManager.CurrentRunningTask;
//等待起飞时间完成,并模拟灯光--不移动飞机-飞机自己计算并移动位置
while (ts.TotalMilliseconds < task.TakeOffTime * 1000)
{
if (_flightTaskManager.IsPaused == true)
@ -134,28 +148,7 @@ namespace Plane.FormationCreator.Formation
await Task.Delay(100).ConfigureAwait(false);
dtNow = DateTime.Now;
ts = dtNow - dtLastTime;
//灯光控制
if (info.LEDInfos.Count > 0)
{
string LEDRGB = "";
List<LEDInfo> LedControl = info.LEDInfos.ToList();
double time = 0;
for (int i = 0; i < LedControl.Count; i++)
{
var led = LedControl[i];
time += led.Delay * 1000;
if (ts.TotalMilliseconds >= time)
LEDRGB = info.LEDInfos[i].LEDRGB;
else
break;
}
info.Copter.LEDColor = LEDRGB;
///灯光控制结束
}
}
//起飞完成用默认颜色
info.Copter.LEDColor = CopterManager.CopterFlyingColor;
}

View File

@ -0,0 +1,41 @@
using Plane.Copters;
using Plane.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Plane.FormationCreator.Formation
{
public partial class FlightTask
{
public async Task RunTurnTaskAsync()
{
await Task.WhenAll(
SingleCopterInfos.Select(info => TurnTaskFlySingleCopterAsync(info))
).ConfigureAwait(false);
}
private async Task TurnTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
{
int copterIndex = SingleCopterInfos.IndexOf(info);
// 当该飞机被标记时,跳过飞行任务
if ((bool)_copterManager.CopterStatus[copterIndex])
return;
await info.Copter.SetMobileControlAsync(yaw: info.TargetHeading);
while (!info.Copter.ArrivedHeading(info.TargetHeading))
{
if (_flightTaskManager.IsPaused == true)
{
await info.Copter.HoverAsync();
return;
}
await Task.Delay(25).ConfigureAwait(false);
}
await info.Copter.HoverAsync();
}
}
}

View File

@ -133,16 +133,15 @@ namespace Plane.FormationCreator.Formation
// {
//_copterManager.Select(_copterManager.Copters[copterIndex]);
ICopter copter = null;
// try
// {
// copter = _copterManager.Copters.First(o => o.Name == (copterIndex + 1).ToString());
// }
// catch (Exception)
// {
// continue;
// }
string strcoptername = _copterManager.Copters[copterIndex].Name;
copter = _copterManager.Copters.FirstOrDefault(o => o.Name == strcoptername);
// try
// {
// copter = _copterManager.Copters.First(o => o.Name == (copterIndex + 1).ToString());
// }
// catch (Exception)
// {
// continue;
// }
copter = _copterManager.Copters.FirstOrDefault(o => o.Name == (copterIndex + 1).ToString());
if (copter != null)
{
_copterManager.Select(copter);

View File

@ -1,8 +1,6 @@
using GalaSoft.MvvmLight;
using Microsoft.Practices.ServiceLocation;
using Newtonsoft.Json.Linq;
using Plane.CommunicationManagement;
using Plane.FormationCreator.ViewModels;
using Plane.Util;
using Plane.Windows.IniHelper;
using Plane.Windows.Messages;
@ -10,12 +8,10 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Threading;
@ -24,107 +20,20 @@ namespace Plane.FormationCreator.Formation
public class RtcmManager: ObservableObject
{
private rtcm3 rtcm = new rtcm3();
// ubx detection
private static Ubx ubx_m8p = new Ubx();
static nmea nmea = new nmea();
private Hashtable msgseen = new Hashtable();
private ICommsSerial comPort;
private ICommsSerial RecomPort;
private CommModuleManager _commModuleManager = CommModuleManager.Instance;
public ObservableCollection<RtcmInfo> rtcmInfoList { get; } = new ObservableCollection<RtcmInfo>();
private ControlPanelViewModel ControlPanelVM = ServiceLocator.Current.GetInstance<ControlPanelViewModel>();
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
private bool _rtcmthreadrun = false;
private bool _smallrtcmdata = false; //减少传输数据--用于带宽不够的通讯模块-对数传广播无效
// rtcm发送类型0:直接发送,
// 11秒只发一种卫星1秒发GPS,第2秒发北斗第3秒发格洛纳斯其他数据随来随发
/*
//F9P作为基站默认推荐的消息
RTCM 1005 RTK ARP
RTCM 1074 GPS MSM4
RTCM 1084 MSM4
RTCM 1094 MSM4
RTCM 1124 MSM4
RTCM 1230 GLONASS
RTCM 3.3
RTCM 3.3 GLONASS (RTCM 1230) 线(RTCM 1033)使RTK GLONASS
RTCM 1005 RTCM 1006
使使 MSM4 MSM7
RTCM RTCM MSM
*/
private int _resendtocom = 1;
const int MSG_GPS = 1074;
const int MSG_GLONASS = 1084;
const int MSG_Beidou = 1124;
const int MSG_BasePos = 1005;
const int MSG_REV = 1033;
const int MSG_GLONASS_PHASE = 1230;
const int MSG_GALILEO = 1094;
public string rtcm_typename(int msgtype)
{
string typename = "Rtcm" + msgtype;
switch (msgtype)
{
case MSG_GPS:
typename = "GPS(G)";
break;
case MSG_GLONASS:
typename = "GLONASS(R)";
break;
case MSG_GLONASS_PHASE:
typename = "GLONASS相位差";
break;
case MSG_Beidou:
typename = "北斗(B)";
break;
//位置5秒发一次就可以了
case MSG_BasePos:
typename = "基站位置";
break;
case MSG_REV: //这个没必要发
typename = "版本";
break;
case MSG_GALILEO: //这个没必要发-移动端默认配置不收这个卫星
typename = "伽利略(E)";
break;
}
return typename;
}
public bool Rtcmthreadrun
{
get { return _rtcmthreadrun; }
set {
Set(nameof(Rtcmthreadrun), ref _rtcmthreadrun, value);
var _RtcmInfoViewModel = ServiceLocator.Current.GetInstance<RtcmInfoViewModel>();
_RtcmInfoViewModel.SetRTKStatestr();
}
set { Set(nameof(Rtcmthreadrun), ref _rtcmthreadrun, value); }
}
public bool SmallRtcmData
{
get { return _smallrtcmdata; }
set
{
Set(nameof(SmallRtcmData), ref _smallrtcmdata, value);
var _RtcmInfoViewModel = ServiceLocator.Current.GetInstance<RtcmInfoViewModel>();
_RtcmInfoViewModel.SetRTKStatestr();
}
}
//接收速率
private int bps;
//发送速率
private int bpsusefull;
private int _bps = 0;
@ -209,18 +118,6 @@ namespace Plane.FormationCreator.Formation
get { return _stationTime; }
set { Set(nameof(StationTime), ref _stationTime, value); }
}
private bool _sesendtocom;
public bool ResendToCom
{
get { return _sesendtocom; }
set {
Set(nameof(ResendToCom), ref _sesendtocom, value);
var _RtcmInfoViewModel = ServiceLocator.Current.GetInstance<RtcmInfoViewModel>();
_RtcmInfoViewModel.SetRTKStatestr();
}
}
private DispatcherTimer dispatcherTimer = null;
public RtcmManager()
@ -232,7 +129,6 @@ namespace Plane.FormationCreator.Formation
dispatcherTimer.Start();
}
//用于刷新界面,显示消息状态,基站和卫星是否有效等---1HZ
private void OnTimedEvent(object sender, EventArgs e)
{
BaseState = baseTime > DateTime.Now;
@ -259,7 +155,7 @@ namespace Plane.FormationCreator.Formation
}
//显示卫星信号强度条
private void Rtcm_ObsMessage(object sender, EventArgs e)
{
List<rtcm3.ob> obs = sender as List<rtcm3.ob>;
@ -289,7 +185,6 @@ namespace Plane.FormationCreator.Formation
partRtcmInfos[i].Sys = obs[i].sys;
partRtcmInfos[i].Prn = obs[i].prn;
partRtcmInfos[i].Snr = obs[i].snr;
partRtcmInfos[i].Snr2 = obs[i].snr2;
}
}
@ -300,23 +195,21 @@ namespace Plane.FormationCreator.Formation
return SerialPort.GetPortNames();
}
public async Task Open(string CMB_serialport)
{
if (CMB_serialport == "") return;
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
switch (CMB_serialport)
switch(CMB_serialport)
{
case "千寻":
//检测原点
// FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
if (_flightTaskManager.OriginLat == 0 && _flightTaskManager.OriginLng == 0)
{
Alert.Show("作为参照的原点未设置无法发送RTCM", "提示");
return;
}
//ini里面的固定千寻账号
//千寻账号
string messagetips = "格式http://差分账号:差分密码@域名:端口/坐标系\r\n例如http://account:password@rtk.ntrip.qxwz.com:8002/RTCM32_GGB";
string url = "";
@ -327,42 +220,6 @@ namespace Plane.FormationCreator.Formation
//构造
comPort = new CommsNTRIP(url, _flightTaskManager.OriginLat, _flightTaskManager.OriginLng);
break;
case "魔方基站":
//检测原点
if (_flightTaskManager.OriginLat == 0 && _flightTaskManager.OriginLng == 0)
{
Alert.Show("作为参照的原点未设置无法发送RTCM", "提示");
return;
}
/* //ini里面的固定千寻账号
//千寻账号
string messagetips = "格式http://差分账号:差分密码@域名:端口/坐标系\r\n例如http://account:password@rtk.ntrip.qxwz.com:8002/RTCM32_GGB";
string url = "";
IniFiles inifilse = new IniFiles();
url = inifilse.IniReadvalue("Default", "RTKurl");
if (PlaneMessageBox.OnShow(messagetips, "发送RTK", ref url) == false) return;
inifilse.IniWritevalue("Default", "RTKurl", url);
*/
//通过网络得到千寻账号
if (_copterManager.RTK_URL == "")
{
//得到千寻账号
_copterManager.GetRTKURL();
//等到返回5秒
DateTime Tthen = DateTime.UtcNow;
do
{
Application.DoEvents();
} while ((_copterManager.RTK_URL == "") || (Tthen.AddSeconds(2) > DateTime.UtcNow));
}
if (_copterManager.RTK_URL != "")
{
//构造
comPort = new CommsNTRIP(_copterManager.RTK_URL, _flightTaskManager.OriginLat, _flightTaskManager.OriginLng);
}
break;
default:
comPort = new SerialPort();
@ -371,15 +228,7 @@ namespace Plane.FormationCreator.Formation
break;
}
msgseen.Clear();
try
{
comPort.Open();
}
catch (Exception ex)
{
Alert.Show("数据端口打开失败:"+ ex.Message, "提示");
}
if (comPort.IsOpen)
{
Rtcmthreadrun = true;
@ -387,65 +236,25 @@ namespace Plane.FormationCreator.Formation
}
}
public async Task Close(string CMB_serialport)
public async Task Close()
{
//如果需要关闭转发端口
_commModuleManager.CloseResendRtcmserial();
await _commModuleManager.CloseRtcmLoop();
Rtcmthreadrun = false;
comPort.Close();
switch (CMB_serialport)
{
case "魔方基站":
{
//释放千寻账号
_copterManager.ReleaseRTKURL();
}
break;
}
BaseState = false;
GpsState = false;
GlonassState = false;
BeidouState = false;
rtcmInfoList.Clear();
_copterManager.RTK_URL = "";
}
private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long CurrentTimeMillis()
{
return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
}
//发送RTK数据线程循环
private async Task RtcmLoop()
{
int reconnecttimeout = 10;
DateTime lastrecv = DateTime.MinValue;
DateTime unow = DateTime.UtcNow;
long last_send_pos = CurrentTimeMillis()- 5000;//5秒发一次就可以了
bool Ensend = false;
bool second_sended = false; //当前秒是否已发
int last_second = 0; //当前秒
//新版本打包发送模式
//await _commModuleManager.StartRtcmLoop();
Plane.Windows.Messages.Message.Show("RTCM发送开始............");
await _commModuleManager.StartRtcmLoop();
while (Rtcmthreadrun)
{
// Console.WriteLine(string.Format("{0:T} 1", DateTime.Now));
try
{
try
{
unow=DateTime.UtcNow;
if ((unow - lastrecv).TotalSeconds > reconnecttimeout || !comPort.IsOpen)
if ((DateTime.Now - lastrecv).TotalSeconds > reconnecttimeout || !comPort.IsOpen)
{
if (comPort is CommsNTRIP)
{
@ -454,230 +263,53 @@ namespace Plane.FormationCreator.Formation
{
comPort.Close();
comPort.Open();
Plane.Windows.Messages.Message.Show("RTCM数据超时或端口被关闭重新打开");
}
// reset timer
lastrecv = unow;
lastrecv = DateTime.Now;
}
}
catch { }
if (!comPort.IsOpen)
{
comPort.Open();
Plane.Windows.Messages.Message.Show("RTCM端口已被关闭再次打开");
// return;
return;
}
/////////////////////////////////重写发送RTCM数据部分---23/10/18 by panxu
///
// limit to 180 byte packet if using new packet
//rtcm size=180
byte[] buffer = new byte[180];
while (comPort.BytesToRead > 0)
{
int read = comPort.Read(buffer, 0, Math.Min(buffer.Length, comPort.BytesToRead));
//Console.WriteLine(string.Format("{0:T} - read:{1:D}", DateTime.UtcNow, read));
if (read > 0)
lastrecv = DateTime.UtcNow;
bps += read; //接收速率bps,byte需要*8到bit
// check for valid rtcm/sbp/ubx packets
lastrecv = DateTime.Now;
bps += read;
for (int a = 0; a < read; a++)
{
int seenmsg = -1;
// rtcm and not can
// rtcm
if ((seenmsg = rtcm.Read(buffer[a])) > 0)
{
// Console.WriteLine(string.Format("{0:T}------------RTCM Send {1:D}", DateTime.Now, rtcm.length));
ubx_m8p.resetParser();
nmea.resetParser();
string msgshowname = rtcm_typename(seenmsg);
//Plane.Windows.Messages.Message.Show("--收到[" + seenmsg + "]:"+ msgshowname+" ,长度:"+ rtcm.length);
//直接发送
if (!SmallRtcmData)
{
//发送到飞机
// Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + "--通讯模块发送Rtcm长度: " + (ushort)rtcm.length + " 类型: " + msgshowname + " (" + seenmsg + ")");
await _commModuleManager.InjectGpsDataAsync(rtcm.packet, (ushort)rtcm.length, ResendToCom);
//累加消息数量,用于界面显示
bpsusefull += rtcm.length;
}
else
//为了减少发送数据量:
//11秒只发一种卫星1秒发GPS,第2秒发北斗第3秒发格洛纳斯其他数据随来随发
{
await _commModuleManager.InjectGpsRTCMDataAsync(rtcm.packet, rtcm.length);
Ensend = false; //是否发送
//第1秒是gps,第2秒是GLONASS第3秒是 Beidou
//1秒内可能发送多个同一种类型的数据看数据大小和原始频率
long curr_s = CurrentTimeMillis() / 1000;
int sendtype = (int)(curr_s % 3);
if (last_second!= sendtype) //新一秒
{
second_sended = false; //设置未发送
last_second = sendtype; //设置秒数
}
//这些类型数据需要分秒发或者不发(MSG_REV)
if ((seenmsg == MSG_GPS) ||
//(seenmsg == MSG_GLONASS) ||
//(seenmsg == MSG_GLONASS_PHASE) ||
(seenmsg == MSG_Beidou) ||
(seenmsg == MSG_BasePos)
)
{
switch (sendtype)
{
case 0: //第1秒只发GPS
if ((!second_sended) && (seenmsg == MSG_GPS))
{
second_sended = true;
Ensend = true;
// Plane.Windows.Messages.Message.Show("发送GPS:" + rtcm.length+"字节");
}
string msgname = "Rtcm" + seenmsg;
break;
case 1://第2秒只发GLONASS
if ((!second_sended) && ((seenmsg == MSG_GLONASS)))// || (MSG_GPS == MSG_GLONASS_PHASE)))
{
second_sended = true;
Ensend = true;
// Plane.Windows.Messages.Message.Show("发送GLONASS:" + rtcm.length + "字节");
}
break;
case 2://空白
if ((!second_sended) && ((seenmsg == MSG_Beidou)))
{
second_sended = true;
Ensend = true;
//Plane.Windows.Messages.Message.Show("发送北斗:" + rtcm.length + "字节");
}
break;
/*
case 3://第4秒是 Beidou
if ((!second_sended) && ((seenmsg == MSG_Beidou)))
{
second_sended = true;
Ensend = true;
//Plane.Windows.Messages.Message.Show("发送北斗:" + rtcm.length + "字节");
}
break;
*/
}
if ((seenmsg == MSG_BasePos))////这些直接发
{
Ensend = true;
//Plane.Windows.Messages.Message.Show("发送位置:" + rtcm.length + "字节");
}
}
//else Ensend = true; ////其他类型数据不发
/*
switch (seenmsg)
{
case MSG_GPS:
if (sendtype == 0) //第1秒是gps,
Ensend = true;
break;
case MSG_GLONASS:
case MSG_GLONASS_PHASE:
if (sendtype == 1) //第2秒是GLONASS
Ensend = true;
break;
case MSG_Beidou:
if (sendtype == 2) //第3秒是 Beidou
Ensend = true;
break;
//位置4秒发一次就可以了
case MSG_BasePos:
{
long curr_send_pos = CurrentTimeMillis();
if ((curr_send_pos - last_send_pos) > 4000)
{
last_send_pos = curr_send_pos;
Ensend = true;
}
}
break;
case MSG_REV: //这个没必要发
Ensend = false;
break;
default: //其他类型数据随到随发
Ensend = true;
break;
}
*/
if (Ensend)
{
//Console.WriteLine(DateTime.UtcNow.ToString("HH:mm:ss") + "--通讯模块发送Rtcm长度: " + (ushort)rtcm.length + " 类型: " + msgshowname + " (" + seenmsg + ")");
await _commModuleManager.InjectGpsDataAsync(rtcm.packet, (ushort)rtcm.length, ResendToCom);
//累加消息数量,用于界面显示
bpsusefull += rtcm.length;
}
}
string msgname = rtcm_typename(seenmsg);
if (!msgseen.ContainsKey(msgname))
msgseen[msgname] = 0;
msgseen[msgname] = (int)msgseen[msgname] + 1;
//检测基站定位状态和卫星定位状态,用于在界面上显示
await ExtractBasePos(seenmsg);
//await seenRTCM(seenmsg);
}
// ubx
if ((seenmsg = ubx_m8p.Read(buffer[a])) > 0)
}
await Task.Delay(10);
}
catch(Exception ex)
{
//Console.WriteLine(string.Format("{0:T}----------------------------ubx_m8p ", DateTime.UtcNow));
rtcm.resetParser();
nmea.resetParser();
/*
//Ubx协议数据不用显示
string msgname = "Ubx" + seenmsg.ToString("X4");
if (!msgseen.ContainsKey(msgname))
msgseen[msgname] = 0;
msgseen[msgname] = (int)msgseen[msgname] + 1;
*/
}
// nmea
if ((seenmsg = nmea.Read(buffer[a])) > 0)
{
//Console.WriteLine(string.Format("{0:T}----------------------------nmea ", DateTime.UtcNow));
rtcm.resetParser();
ubx_m8p.resetParser();
/*
//NMEA协议数据不用显示
string msgname = "NMEA";
if (!msgseen.ContainsKey(msgname))
msgseen[msgname] = 0;
msgseen[msgname] = (int)msgseen[msgname] + 1;
*/
}
}
////////////////////////////解析/发送RTCM结束
await Task.Delay(20);
}
await Task.Delay(20); //新增加关键延迟,要不然界面会出现卡死现象
}
catch (Exception ex)
{
//Plane.Windows.Messages.Message.Show("RTCM异常:" + ex.Message);
/*
StackFrame sf = new System.Diagnostics.StackTrace(ex, true).GetFrame(0);
Plane.Windows.Messages.Message.Show("RTCM异常:"+ ex.Message+" 行:" +
sf.GetFileLineNumber() + " 文件:"+ sf.GetFileName());
*/
Message.Show(ex.Message);
}
}
Plane.Windows.Messages.Message.Show("RTCM发送停止............");
Rtcmthreadrun = false;
}
@ -762,7 +394,7 @@ namespace Plane.FormationCreator.Formation
}
catch (Exception ex)
{
Plane.Windows.Messages.Message.Show(ex.Message);
Message.Show(ex.Message);
}
await Task.Delay(1);
@ -774,7 +406,6 @@ namespace Plane.FormationCreator.Formation
private char sys;
private byte prn;
private byte snr;
private byte snr2;
public RtcmInfo()
{
@ -798,10 +429,5 @@ namespace Plane.FormationCreator.Formation
get { return snr; }
set { Set(nameof(Snr), ref snr, value); }
}
public byte Snr2
{
get { return snr2; }
set { Set(nameof(Snr2), ref snr2, value); }
}
}
}

View File

@ -13,15 +13,12 @@
WindowTransitionsEnabled="False"
FontFamily="Microsoft YaHei"
WindowState="Maximized"
Title="飞行魔方无人机编队控制系统 V2.0"
Title="无人机编队控制中心"
PreviewKeyDown="MetroWindow_PreviewKeyDown"
PreviewKeyUp="MetroWindow_PreviewKeyUp"
Style="{StaticResource VSWindowStyleKey}"
Width="1920"
Height="1080"
Closing="Window_Closing"
Loaded="Window_Loaded"
>
Width="800"
Height="600">
<c:MetroWindow.Resources>
<Style TargetType="Separator"
@ -46,48 +43,17 @@
<c:MetroWindow.RightWindowCommands>
<c:WindowCommands>
<Button Content="{Binding LoginDisp}"
Command="{Binding LoginCommand}" />
<Button Content="飞行面板"
Foreground="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource MainColorConverterFly}}"
FontSize="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource MainFontSizeConverterFly}}"
Command="{Binding HideModifyTaskViewCommand}" />
<Button Content="设计面板"
Foreground="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource MainColorConverterDes}}"
FontSize="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource MainFontSizeConverterDes}}"
Command="{Binding ShowModifyTaskViewCommand}" />
<Button Content="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource ShowModifyTaskViewButtonContentConverter}}"
Command="{Binding ShowOrHideModifyTaskViewCommand}" Visibility="Collapsed" />
<Button Content="平面编辑"
Foreground="{Binding b2DMapMode, Converter={StaticResource MainColorConverterDes}}"
FontSize="{Binding b2DMapMode, Converter={StaticResource MainFontSizeConverterDes}}"
Command="{Binding Map2DCommand}"/>
<Button Content="实景效果"
Foreground="{Binding b2DMapMode, Converter={StaticResource MainColorConverterFly}}"
FontSize="{Binding b2DMapMode, Converter={StaticResource MainFontSizeConverterFly}}"
Command="{Binding Map3DCommand}"/>
<Button Content="{Binding b2DMapMode, Converter={StaticResource Show2d3dButtonContentConverter}}"
Command="{Binding ChangeMapModeCommand}" Visibility="Collapsed"/>
Command="{Binding ShowOrHideModifyTaskViewCommand}" />
<Button Content="切换地图"
Command="{Binding ChangeMapModeCommand}"/>
<Button Content="重启监听"
Visibility="Collapsed"
Command="{Binding RestartListeningCommand}" />
<Button Content="{Binding SwitchVelocityModeButtonContent}"
Command="{Binding SwitchVelocityModeCommand}"
Visibility="Collapsed"/>
<!--// 王海, 20150930, 不分这些模式了。
<!--// 林俊清, 20150930, 不分这些模式了。
<Button Content="进入任务模式"
Command="{Binding SwitchAppModeCommand}"
CommandParameter="{x:Static m:AppMode.PreparedForRunningTasks}"
@ -105,7 +71,7 @@
Visibility="Collapsed"
Click="btnRefreshMap_Click" />
<Button Name="btnConnect"
Content="设置"
Content="连接"
Click="btnConnect_Click" />
<Menu Name="menuTask" Background="Transparent" VerticalAlignment="Center" >
@ -132,17 +98,11 @@
Command="{Binding ImportTasksCommand}"/>
<StackPanel VerticalAlignment="Center" Margin="0,8,0,8" Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
<TextBlock Foreground="#969696" VerticalAlignment="Center" Text="起始步骤:"/>
<TextBox VerticalAlignment="Center" Width="40" Margin="0,0,5,0"
<TextBox VerticalAlignment="Bottom" Width="40"
Text="{Binding txtStarindex, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Foreground="#969696" VerticalAlignment="Center" Text="截止:"/>
<TextBox VerticalAlignment="Center" Width="40" Margin="0,0,5,0"
<TextBox VerticalAlignment="Bottom" Width="40"
Text="{Binding txtendindex, UpdateSourceTrigger=PropertyChanged}"/>
<CheckBox Content="飞机位置" Grid.Column="1" Margin="0,8,0,8" Foreground="#969696"
IsChecked="{Binding isimpCopterLoc}" />
</StackPanel>
<Button BorderThickness="1" BorderBrush="#FFFFFF" Content="导入分组信息" Margin="25,8,0,8" Grid.Row="2"
Command="{Binding ImportGroupCommand}"/>
@ -171,7 +131,7 @@
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Margin="1" d:IsHidden="True">
<Grid Margin="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="73*" />
<ColumnDefinition Width="27*" MinWidth="360" />
@ -179,19 +139,20 @@
<Grid Margin="0,0,10,0"
Width="Auto" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1371*"/>
<ColumnDefinition Width="13*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<v:MapView x:Name="map" Grid.RowSpan="3" Margin="0,0,0,0" />
<v:View3D x:Name="map3D" Visibility="Collapsed" Grid.RowSpan="3" Margin="0,0,0,0"/>
<TabControl SelectedIndex="{Binding MapMode,UpdateSourceTrigger=PropertyChanged}" Grid.RowSpan="3">
<TabItem Visibility="Collapsed">
<v:MapView x:Name="map"/>
</TabItem >
<TabItem Visibility="Collapsed">
<v:View3D/>
</TabItem>
</TabControl>
<Grid Grid.Row="1" HorizontalAlignment="Right">
<WrapPanel Orientation="Vertical">
@ -224,10 +185,10 @@
Visibility="{Binding Source={x:Static local:AppEx.Current}, Path=AppMode, Converter={StaticResource AppModeToVisibilityConverter}, ConverterParameter=TaskBarView}" />
</Grid>
<Viewbox Stretch="Fill" Grid.Column="1" Margin="0,0,0,0">
<DockPanel>
<Grid Margin="0,0,0,0"
>
Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
@ -239,7 +200,7 @@
<StackPanel Grid.Row="1">
<StackPanel Grid.Row="2"
Visibility="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource InversiveBooleanToVisibilityConverter}}">
<Separator Grid.ColumnSpan="2" Margin="0,5,5,5"/>
<Separator Grid.ColumnSpan="2" />
<v:ControlPanelView />
</StackPanel>
@ -252,73 +213,40 @@
<StackPanel Grid.Row="2"
Visibility="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource InversiveBooleanToVisibilityConverter}}">
<Separator Grid.ColumnSpan="2" Margin="0,0,5,5" />
<Separator Grid.ColumnSpan="2" />
<v:CopterInfoView DataContext="{Binding Path=CopterListViewModel.SelectedCopter}" />
</StackPanel>
</Grid>
</DockPanel>
</Viewbox>
</Grid>
<Border Grid.Row="1"
Background="{StaticResource WhiteBrush}">
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Margin="10,4"
Text="{Binding Message}" Width="480" MouseUp="LogShowHide"/>
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" Margin="0,8" BorderBrush="LightGray" BorderThickness="1"/>
<TextBlock Margin="10,4" Width="280" Text="{Binding SysStatusText}" />
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" Margin="0,8" BorderBrush="LightGray" BorderThickness="1"/>
<TextBlock Margin="10,4" Width="210"
Text="{Binding ControlPanelViewModelData.RTKState}" />
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" Margin="0,8" BorderBrush="LightGray" BorderThickness="1"/>
<TextBlock Margin="4"
Text="{Binding Message}" MouseUp="LogShowHide"/>
<TextBlock Margin="4"
Text="{Binding CopterListViewModel.SelectedCopter.StatusText}" />
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock Text="{Binding Loginstate}" Margin="0,4,14,0"/>
<TextBlock Text="广播端口:" Margin="4"/>
<ContentPresenter Margin="0,4,4,0" Content="{Binding BoardcastPortOpened, Converter={StaticResource CheckSignConverter2}, Mode=OneWay}" />
<TextBlock Text="通信连接:" Margin="4"/>
<ContentPresenter Margin="0,4,14,0" Content="{Binding CommunicationModuleConnected, Converter={StaticResource CheckSignConverter2}, Mode=OneWay}" />
<ContentPresenter Content="{Binding CommunicationModuleConnected, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
</StackPanel>
</Grid>
</Border>
<Grid x:Name="logGrid" Height="900" VerticalAlignment="Top" HorizontalAlignment="Left" Visibility="Hidden" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="20" MaxWidth="800" Width="500"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<DockPanel Grid.Row="0" Grid.Column="0">
<TextBox x:Name="logTextBox" Height="900" Width="800" Background="#FF2D2D2D"
<TextBox Name="logTextBox" Height="700" Width="600" Background="#FF2D2D2D"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Visibility="Hidden"
Text="{Binding Logs}"
ScrollViewer.VerticalScrollBarVisibility="Auto"
TextChanged="LogTextChange"
IsReadOnly="True"
TextWrapping="Wrap"
FontSize="14"
ContextMenu="{StaticResource LogMenu}"/>
</DockPanel>
<GridSplitter Grid.Row="0" Grid.Column="1" Width="3" Margin="0,0,0,0" Background="MidnightBlue"
VerticalAlignment="Stretch" HorizontalAlignment="Center" />
</Grid>
</Grid>
</c:MetroWindow>

View File

@ -21,7 +21,6 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Plane.CommunicationManagement;
using System.Reflection;
namespace Plane.FormationCreator
{
@ -35,10 +34,6 @@ namespace Plane.FormationCreator
InitializeComponent();
this.DataContext = ServiceLocator.Current.GetInstance<MainViewModel>();
// this.OnClosing += Window_Closing;
//改到设置窗口显示版本信息
// var version = Assembly.GetExecutingAssembly().GetName().Version;
// Title = "飞行魔方无人机编队控制系统 V" + version.ToString() + "编译时间[" + System.IO.File.GetLastWriteTime(this.GetType().Assembly.Location).ToString() + "]";
//ShowConnectDialog();
@ -58,32 +53,8 @@ namespace Plane.FormationCreator
{
loginWindow = new ConnectWindow();
}
loginWindow.ShowDialog ();
loginWindow.Show();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
bool waitnet = _copterManager.Logined;
_copterManager.NetLogout();
//等待网络退出
if (waitnet)
System.Threading.Thread.Sleep(1000);
/*
MessageBoxResult result = MessageBox.Show("Do you really want to exit?", "", MessageBoxButton.YesNo);
if (result == MessageBoxResult.No)
{
e.Cancel = true;
}
*/
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ServiceLocator.Current.GetInstance<MainViewModel>().LoginCommand.Execute(this);
}
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
@ -110,7 +81,7 @@ namespace Plane.FormationCreator
};
var point = PointToScreen(Mouse.GetPosition(this));
point.X = Math.Min(point.X, SystemParameters.WorkArea.Width - connectWindow.Width - 30);
point.Y = Math.Min(point.Y+10, SystemParameters.WorkArea.Height - connectWindow.Height - 30);
point.Y = Math.Min(point.Y, SystemParameters.WorkArea.Height - connectWindow.Height - 30);
connectWindow.Left = point.X;
connectWindow.Top = point.Y;
@ -138,8 +109,6 @@ namespace Plane.FormationCreator
{
case Key.LeftCtrl:
case Key.RightCtrl:
case Key.LeftAlt:
{
var copters = _copterManager.AcceptingControlCopters;
Shiftkeydown = true;
@ -424,8 +393,6 @@ namespace Plane.FormationCreator
switch (e.Key)
{
case Key.LeftCtrl:
case Key.RightCtrl:
case Key.LeftAlt:
{
Shiftkeydown = false;
_copterManager.shiftkeydown = false;
@ -514,20 +481,15 @@ namespace Plane.FormationCreator
{
MainViewModel vm = DataContext as MainViewModel;
LogWindow logWindows = new LogWindow(vm.Messages);
logWindows.ShowDialog();
logWindows.Show();
}
private void LogShowHide(object sender, MouseButtonEventArgs e)
{
if (logGrid.Visibility == Visibility.Visible)
logGrid.Visibility = Visibility.Hidden;
if (logTextBox.Visibility == Visibility.Visible)
logTextBox.Visibility = Visibility.Hidden;
else
{
logGrid.Height = Math.Max(map.ActualHeight, map3D.ActualHeight) - ((TaskBarView)TaskbarControl).TasksControl.ActualHeight;
logTextBox.Height = logGrid.Height;
logGrid.Visibility = Visibility.Visible;
}
logTextBox.Visibility = Visibility.Visible;
}
private void LogTextChange(object sender, TextChangedEventArgs e)

View File

@ -1,5 +1,4 @@
using Microsoft.Practices.ServiceLocation;
using Plane.FormationCreator.Util;
using Plane.FormationCreator.Util;
using System;
using System.Collections.Generic;
using System.Linq;
@ -44,15 +43,7 @@ namespace Plane.FormationCreator
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.Text = ((Button)sender).Tag.ToString();
textParamName_cn.Text = ((Button)sender).Content.ToString();
}

View File

@ -9,28 +9,13 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Plane.FormationCreator</RootNamespace>
<AssemblyName>FGCS</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -53,7 +38,6 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\FGCS.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>gcs.ico</ApplicationIcon>
@ -107,9 +91,7 @@
<HintPath>..\packages\MaterialDesignThemes.1.4.0.473\lib\net45\MaterialDesignThemes.Wpf.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Expression.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Unnoficial.Microsoft.Expression.Drawing.1.0.0\lib\Microsoft.Expression.Drawing.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Expression.Drawing, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Maps.MapControl.WPF, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Maps.MapControl.WPF.1.0.0.3\lib\net40-Client\Microsoft.Maps.MapControl.WPF.dll</HintPath>
<Private>True</Private>
@ -167,17 +149,20 @@
<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" />
<Compile Include="Converters\HeartbeatCountToBrushConverter.cs" />
<Compile Include="Formation\AppMode.cs" />
<Compile Include="Formation\Copter.cs" />
<Compile Include="Formation\FlightTaskSingleCopterInfo_Land.cs" />
<Compile Include="Formation\FlightTaskSingleCopterInfo_LED.cs" />
<Compile Include="Formation\FlightTaskSingleCopterInfo_LoiterTime.cs" />
<Compile Include="Formation\FlightTaskSingleCopterInfo_ReturnToLand.cs" />
<Compile Include="Formation\FlightTaskSingleCopterInfo_SimpleCircle.cs" />
<Compile Include="Formation\FlightTaskSingleCopterInfo_Turn.cs" />
<Compile Include="Formation\FlightTaskSingleCopterInfo_TakeOff.cs" />
<Compile Include="Formation\FlightTask_Circle.cs" />
<Compile Include="Formation\FlightTaskSingleCopterInfo_Circle.cs" />
<Compile Include="Formation\Extensions.cs" />
<Compile Include="Formation\FlightTask.cs" />
<Compile Include="Formation\FlightTaskSingleCopterInfo.cs" />
@ -185,6 +170,10 @@
<Compile Include="Formation\FlightTask_FlyTo.cs" />
<Compile Include="Formation\FlightTaskSingleCopterInfo_FlyTo.cs" />
<Compile Include="Formation\FlightTask_Land.cs" />
<Compile Include="Formation\FlightTask_LoiterTime.cs" />
<Compile Include="Formation\FlightTask_ReturnToLand.cs" />
<Compile Include="Formation\FlightTask_SimpleCircle.cs" />
<Compile Include="Formation\FlightTask_Turn.cs" />
<Compile Include="Formation\FormationController.cs" />
<Compile Include="Formation\CopterManager.cs" />
<Compile Include="Formation\GroupManager.cs" />
@ -208,19 +197,14 @@
<Compile Include="ServiceLocatorConfigurer.cs" />
<Compile Include="Test.cs" />
<Compile Include="CalculationLogLatDistance.cs" />
<Compile Include="Util\AsynDataUtils.cs" />
<Compile Include="Util\CommNTRIP.cs" />
<Compile Include="Util\CommsSerialPort.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Util\ICommsSerial.cs" />
<Compile Include="Util\ICorrections.cs" />
<Compile Include="Util\nmea.cs" />
<Compile Include="Util\OptimizeRoute.cs" />
<Compile Include="Util\ParamFile.cs" />
<Compile Include="Util\PasswordBoxHelper.cs" />
<Compile Include="Util\rtcm3.cs" />
<Compile Include="Util\ubx_m8p.cs" />
<Compile Include="Util\VersionControl.cs" />
<Compile Include="ViewModels\CalibrationViewModel.cs" />
<Compile Include="ViewModels\ConfigVirtualIdViewModel.cs" />
@ -228,8 +212,6 @@
<Compile Include="ViewModels\ControlPanelViewModel.cs" />
<Compile Include="ViewModels\CopterListViewModel.cs" />
<Compile Include="ViewModels\GroupsViewModel.cs" />
<Compile Include="ViewModels\ChangePasswordView.cs" />
<Compile Include="ViewModels\LoginViewModel.cs" />
<Compile Include="ViewModels\MainViewModel.cs" />
<Compile Include="ViewModels\MapViewModel.cs" />
<Compile Include="ViewModels\ModifyTaskViewModel.cs" />
@ -261,15 +243,6 @@
<Compile Include="Views\ConnectWindow.xaml.cs">
<DependentUpon>ConnectWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ChangePasswordView.xaml.cs">
<DependentUpon>ChangePasswordView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\InputDialog.xaml.cs">
<DependentUpon>InputDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Views\LoginView.xaml.cs">
<DependentUpon>LoginView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\LogWindow.xaml.cs">
<DependentUpon>LogWindow.xaml</DependentUpon>
</Compile>
@ -409,18 +382,6 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ChangePasswordView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\InputDialog.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\LoginView.xaml">
<SubType>Form</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\LogWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -451,14 +412,6 @@
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\FlyCube\FlightRouteV2\FlightRouteV2.csproj">
<Project>{626a9bfa-07de-4063-a178-360eb7057ed6}</Project>
<Name>FlightRouteV2</Name>
</ProjectReference>
<ProjectReference Include="..\..\FlyTest\FlightRoute\FlightRoute.csproj">
<Project>{705aab55-ed7a-4856-8f7b-e7a78ed9e39a}</Project>
<Name>FlightRoute</Name>
</ProjectReference>
<ProjectReference Include="..\..\Plane.Libraries\Plane.Logging\Plane.Logging.csproj">
<Project>{9c2cafda-cf1d-4565-b797-398376fcd346}</Project>
<Name>Plane.Logging</Name>
@ -497,30 +450,6 @@
<ItemGroup>
<Resource Include="bg.jpg" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Logo_small.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\logo_big.png" />
</ItemGroup>
<ItemGroup>
<None Include="SplashScreen2.png" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.6">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.6 %28x86 和 x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Connected Services\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\System.Data.SQLite.Core.1.0.109.1\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.109.1\build\net46\System.Data.SQLite.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View File

@ -10,9 +10,9 @@ using System.Windows;
[assembly: AssemblyTitle("GroupGCSMain")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("北京飞行魔方科技有限公司")]
[assembly: AssemblyProduct("无人机编队地面控制系统")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GroupGCS")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@ -51,5 +51,5 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.2.0.*")]
[assembly: AssemblyFileVersion("2.2.0.0")]
[assembly: AssemblyVersion("2.0.0.0")]
[assembly: AssemblyFileVersion("2.0.0.0")]

View File

@ -1,8 +1,5 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Plane.FormationCreator.Properties">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/FGCS;component/Styles/Window.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

View File

@ -19,7 +19,7 @@ namespace Plane.FormationCreator.Properties {
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
@ -47,8 +47,8 @@ namespace Plane.FormationCreator.Properties {
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// 使用此强类型资源类,为所有资源查找
/// 重写当前线程的 CurrentUICulture 属性
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
@ -59,15 +59,5 @@ namespace Plane.FormationCreator.Properties {
resourceCulture = value;
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap Logo_small {
get {
object obj = ResourceManager.GetObject("Logo_small", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@ -46,7 +46,7 @@
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
@ -60,7 +60,6 @@
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
@ -69,10 +68,9 @@
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
@ -87,10 +85,9 @@
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
@ -112,13 +109,9 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Logo_small" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Logo_small.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@ -12,7 +12,7 @@ namespace Plane.FormationCreator.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -34,8 +34,6 @@ namespace Plane.FormationCreator
_container.Register<View3DViewModel>();
_container.Register<ModifyTaskViewModel>();
_container.Register<CalibrationViewModel>();
_container.Register<LoginViewModel>();
_container.Register<ChangePasswordViewModel>();
_container.Register<GroupsViewModel>();
_container.Register<RtcmInfoViewModel>();
_container.Register<ConfigVirtualIdViewModel>();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 125 KiB

View File

@ -1,72 +0,0 @@
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Plane.Util
{
public class AsynDataUtils
{
public delegate void DataResultCallBack(string data,bool haveerror);
DataResultCallBack _callback;
bool haveerror;
string errorstr;
public bool AsynGetData(string tagUrl, DataResultCallBack callback, out string verrorstr)
{
haveerror = false;
errorstr = "";
try
{
_callback = callback;
AsyncGetWithWebRequest(tagUrl, new AsyncCallback(ReadCallback));
}
catch (Exception ex)
{
errorstr += ex.Message;
haveerror = true;
Console.WriteLine(ex.Message);
}
verrorstr = errorstr;
return !haveerror;
}
private void ReadCallback(IAsyncResult asynchronousResult)
{
try
{
string DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
var request = (HttpWebRequest)asynchronousResult.AsyncState;
request.Timeout = 5000;
request.Method = "GET";
request.UserAgent = DefaultUserAgent;
var response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
using (var streamReader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default ))
{
var resultString = streamReader.ReadToEnd();
Console.WriteLine(resultString);
if (_callback != null)
{
_callback(resultString,false);
}
}
}
catch (Exception ex)
{
if (_callback != null)
{
_callback(ex.Message, true);
}
Console.WriteLine(ex.Message);
}
}
private void AsyncGetWithWebRequest(string url, AsyncCallback callback)
{
var request = (HttpWebRequest)System.Net.WebRequest.Create(new Uri(url));
request.BeginGetResponse(callback, request);
}
}
}

View File

@ -188,21 +188,22 @@ namespace Plane.Util
{
if (lat != 0 || lng != 0)
{
DateTime currentUtcTime = DateTime.UtcNow;
if (_lastnmea.AddSeconds(30) < currentUtcTime)
if (_lastnmea.AddSeconds(30) < DateTime.Now)
{
double latdms = (int)lat + ((lat - (int)lat) * .6f);
double lngdms = (int)lng + ((lng - (int)lng) * .6f);
var line = string.Format(System.Globalization.CultureInfo.InvariantCulture,
"$GP{0},{1:HHmmss.ff},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14}", "GGA",
currentUtcTime, Math.Abs(latdms * 100).ToString("0000.00"), lat < 0 ? "S" : "N",
DateTime.Now.ToUniversalTime(), Math.Abs(latdms * 100).ToString("0000.00"), lat < 0 ? "S" : "N",
Math.Abs(lngdms * 100).ToString("00000.00"), lng < 0 ? "W" : "E", 1, 10,
1, alt.ToString("0.00"), "M", 0, "M", "0.0", "0");
string checksum = GetChecksum(line);
WriteLine(line + "*" + checksum);
_lastnmea = currentUtcTime;
_lastnmea = DateTime.Now;
}
}
@ -260,7 +261,7 @@ namespace Plane.Util
retrys--;
}
throw new Exception("网络RTK基站通讯已关闭!");
throw new Exception("The ntrip is closed");
}
}

View File

@ -1,512 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System.Threading;
namespace Plane.Util
{
public class SerialPort : System.IO.Ports.SerialPort, ICommsSerial
{
static object locker = new object();
public new bool DtrEnable { get { return base.DtrEnable; } set { if (base.DtrEnable == value) return; if (ispx4(base.PortName)) return; base.DtrEnable = value; } }
public new bool RtsEnable { get { return base.RtsEnable; } set { if (base.RtsEnable == value) return; if (ispx4(base.PortName)) return; base.RtsEnable = value; } }
/*
protected override void Dispose(bool disposing)
{
try
{
try
{
Type mytype = typeof(System.IO.Ports.SerialPort);
FieldInfo field = mytype.GetField("internalSerialStream", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
{
Stream stream = (Stream)field.GetValue(this);
if (stream != null)
{
try
{
stream.Dispose();
}
catch (Exception ex) { Console.WriteLine("1 " + ex.ToString()); }
stream = null;
}
}
}
catch (Exception ex) { Console.WriteLine("2 " + ex.ToString()); }
base.Dispose(disposing);
}
catch (Exception ex) { Console.WriteLine("3 " + ex.ToString()); }
}
*/
public new void Open()
{
// 500ms write timeout - win32 api default
this.WriteTimeout = 500;
if (base.IsOpen)
return;
try
{
// this causes element not found with bluetooth devices.
if (BaudRate > 115200)
{
Console.WriteLine("Doing SerialPortFixer");
SerialPortFixer.Execute(this.PortName);
Console.WriteLine("Done SerialPortFixer");
}
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
if (PortName.StartsWith("/"))
if (!File.Exists(PortName))
throw new Exception("No such device");
try
{
base.Open();
}
catch {
try { Close(); }
catch { }
throw;
}
}
public new void Close()
{
base.Close();
}
public void toggleDTR()
{
if (ispx4(this.PortName))
{
Console.WriteLine("PX4 - no DTR");
return;
}
bool open = this.IsOpen;
Console.WriteLine("toggleDTR " + this.IsOpen);
try
{
if (!open)
this.Open();
}
catch { }
base.DtrEnable = false;
base.RtsEnable = false;
System.Threading.Thread.Sleep(50);
base.DtrEnable = true;
base.RtsEnable = true;
System.Threading.Thread.Sleep(50);
try
{
if (!open)
this.Close();
}
catch { }
Console.WriteLine("toggleDTR done " + this.IsOpen);
}
public new static string[] GetPortNames()
{
// prevent hammering
lock (locker)
{
List<string> allPorts = new List<string>();
if (Directory.Exists("/dev/"))
{
// cleanup now
GC.Collect();
// mono is failing in here on linux "too many open files"
try
{
if (Directory.Exists("/dev/serial/by-id/"))
allPorts.AddRange(Directory.GetFiles("/dev/serial/by-id/", "*"));
}
catch { }
try
{
allPorts.AddRange(Directory.GetFiles("/dev/", "ttyACM*"));
}
catch { }
try
{
allPorts.AddRange(Directory.GetFiles("/dev/", "ttyUSB*"));
}
catch { }
try
{
allPorts.AddRange(Directory.GetFiles("/dev/", "rfcomm*"));
}
catch { }
try
{
allPorts.AddRange(Directory.GetFiles("/dev/", "*usb*"));
}
catch { }
}
string[] ports = null;
try
{
ports = System.IO.Ports.SerialPort.GetPortNames()
.Select(p => p.TrimEnd())
.Select(FixBlueToothPortNameBug)
.ToArray();
}
catch { }
if (ports != null)
allPorts.AddRange(ports);
return allPorts.ToArray();
}
}
static Dictionary<string, string> comportnamecache = new Dictionary<string, string>();
public static string GetNiceName(string port)
{
// make sure we are exclusive
lock (locker)
{
portnamenice = "";
if (comportnamecache.ContainsKey(port))
{
return comportnamecache[port];
}
try
{
CallWithTimeout(new Action<string>(GetName), 1000, port);
}
catch
{
}
comportnamecache[port] = portnamenice;
return (string)portnamenice.Clone();
}
}
static string portnamenice = "";
static void GetName(string port)
{
try
{
/*
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_SerialPort"); // Win32_USBControllerDevice
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
{
foreach (ManagementObject obj2 in searcher.Get())
{
//DeviceID
if (obj2.Properties["DeviceID"].Value.ToString().ToUpper() == port.ToUpper())
{
portnamenice = obj2.Properties["Name"].Value.ToString();
return;
}
}
}
*/
}
catch { }
portnamenice = "";
}
static void CallWithTimeout(Action<string> action, int timeoutMilliseconds, string data)
{
Thread threadToKill = null;
Action wrappedAction = () =>
{
threadToKill = Thread.CurrentThread;
action(data);
};
IAsyncResult result = wrappedAction.BeginInvoke(null, null);
if (result.AsyncWaitHandle.WaitOne(timeoutMilliseconds))
{
wrappedAction.EndInvoke(result);
}
else
{
threadToKill.Abort();
throw new TimeoutException();
}
}
internal bool ispx4(string port)
{
return false;
}
// .NET bug: sometimes bluetooth ports are enumerated with bogus characters
// eg 'COM10' becomes 'COM10c' - one workaround is to remove the non numeric
// char. Annoyingly, sometimes a numeric char is added, which means this
// does not work in all cases.
// See http://connect.microsoft.com/VisualStudio/feedback/details/236183/system-io-ports-serialport-getportnames-error-with-bluetooth
private static string FixBlueToothPortNameBug(string portName)
{
if (!portName.StartsWith("COM"))
return portName;
var newPortName = "COM"; // Start over with "COM"
foreach (var portChar in portName.Substring(3).ToCharArray()) // Remove "COM", put the rest in a character array
{
if (char.IsDigit(portChar))
newPortName += portChar.ToString(); // Good character, append to portName
// else
//log.WarnFormat("Bad (Non Numeric) character in port name '{0}' - removing", portName);
}
return newPortName;
}
}
public sealed class SerialPortFixer : IDisposable
{
public static void Execute(string portName)
{
using (new SerialPortFixer(portName))
{
}
}
#region IDisposable Members
public void Dispose()
{
if (m_Handle != null)
{
m_Handle.Dispose();
m_Handle = null;
}
GC.SuppressFinalize(this);
}
#endregion
#region Implementation
private const int DcbFlagAbortOnError = 14;
private const int CommStateRetries = 10;
private SafeFileHandle m_Handle;
private SerialPortFixer(string portName)
{
const int dwFlagsAndAttributes = 0x40000000;
const int dwAccess = unchecked((int)0xC0000000); if ((portName == null) || !portName.StartsWith("COM", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("Invalid Serial Port", "portName");
}
SafeFileHandle hFile = NativeMethods.CreateFile(@"\\.\" + portName, dwAccess, 0, IntPtr.Zero, 3, dwFlagsAndAttributes,
IntPtr.Zero);
if (hFile.IsInvalid)
{
WinIoError();
}
try
{
int fileType = NativeMethods.GetFileType(hFile);
if ((fileType != 2) && (fileType != 0))
{
throw new ArgumentException("Invalid Serial Port", "portName");
}
m_Handle = hFile;
InitializeDcb();
}
catch
{
hFile.Dispose();
m_Handle = null;
throw;
}
}
private static class NativeMethods
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId,
StringBuilder lpBuffer, int nSize, IntPtr arguments);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool GetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool SetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool ClearCommError(SafeFileHandle hFile, ref int lpErrors, ref Comstat lpStat);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode,
IntPtr securityAttrs, int dwCreationDisposition,
int dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern int GetFileType(SafeFileHandle hFile);
}
private void InitializeDcb()
{
Dcb dcb = new Dcb();
GetCommStateNative(ref dcb);
dcb.Flags &= ~(1u << DcbFlagAbortOnError);
SetCommStateNative(ref dcb);
}
private static string GetMessage(int errorCode)
{
StringBuilder lpBuffer = new StringBuilder(0x200);
if (
NativeMethods.FormatMessage(0x3200, new HandleRef(null, IntPtr.Zero), errorCode, 0, lpBuffer, lpBuffer.Capacity,
IntPtr.Zero) != 0)
{
return lpBuffer.ToString();
}
return "Unknown Error";
}
private static int MakeHrFromErrorCode(int errorCode)
{
return (int)(0x80070000 | (uint)errorCode);
}
private static void WinIoError()
{
int errorCode = Marshal.GetLastWin32Error();
throw new IOException(GetMessage(errorCode), MakeHrFromErrorCode(errorCode));
}
private void GetCommStateNative(ref Dcb lpDcb)
{
int commErrors = 0;
Comstat comStat = new Comstat();
for (int i = 0; i < CommStateRetries; i++)
{
if (!NativeMethods.ClearCommError(m_Handle, ref commErrors, ref comStat))
{
WinIoError();
}
if (NativeMethods.GetCommState(m_Handle, ref lpDcb))
{
break;
}
if (i == CommStateRetries - 1)
{
WinIoError();
}
}
}
private void SetCommStateNative(ref Dcb lpDcb)
{
int commErrors = 0;
Comstat comStat = new Comstat(); for (int i = 0; i < CommStateRetries; i++)
{
if (!NativeMethods.ClearCommError(m_Handle, ref commErrors, ref comStat))
{
WinIoError();
}
if (NativeMethods.SetCommState(m_Handle, ref lpDcb))
{
break;
}
if (i == CommStateRetries - 1)
{
WinIoError();
}
}
}
#region Nested type: COMSTAT
[StructLayout(LayoutKind.Sequential)]
private struct Comstat
{
public readonly uint Flags;
public readonly uint cbInQue;
public readonly uint cbOutQue;
}
#endregion
#region Nested type: DCB
/*
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa363214(v=vs.85).aspx
DWORD fBinary :1;
DWORD fParity :1;
DWORD fOutxCtsFlow :1;
DWORD fOutxDsrFlow :1;
DWORD fDtrControl :2;
DWORD fDsrSensitivity :1;
DWORD fTXContinueOnXoff :1;
DWORD fOutX :1;
DWORD fInX :1;
DWORD fErrorChar :1;
DWORD fNull :1;
DWORD fRtsControl :2;
DWORD fAbortOnError :1;
DWORD fDummy2 :17;
*/
[StructLayout(LayoutKind.Sequential)]
public struct Dcb
{
public readonly uint DCBlength;
public readonly uint BaudRate;
public uint Flags;
public readonly ushort wReserved;
public readonly ushort XonLim;
public readonly ushort XoffLim;
public readonly byte ByteSize;
public readonly byte Parity;
public readonly byte StopBits;
public readonly byte XonChar;
public readonly byte XoffChar;
public readonly byte ErrorChar;
public readonly byte EofChar;
public readonly byte EvtChar;
public readonly ushort wReserved1;
}
#endregion
#endregion
}
}

View File

@ -1,86 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
namespace Plane.Util
{
/// <summary>
/// 为PasswordBox控件的Password增加绑定功能
/// </summary>
public static class PasswordBoxHelper
{
public static readonly DependencyProperty PasswordProperty =
DependencyProperty.RegisterAttached("Password",
typeof(string), typeof(PasswordBoxHelper),
new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged));
public static readonly DependencyProperty AttachProperty =
DependencyProperty.RegisterAttached("Attach",
typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false, Attach));
private static readonly DependencyProperty IsUpdatingProperty =
DependencyProperty.RegisterAttached("IsUpdating", typeof(bool),
typeof(PasswordBoxHelper));
public static void SetAttach(DependencyObject dp, bool value)
{
dp.SetValue(AttachProperty, value);
}
public static bool GetAttach(DependencyObject dp)
{
return (bool)dp.GetValue(AttachProperty);
}
public static string GetPassword(DependencyObject dp)
{
return (string)dp.GetValue(PasswordProperty);
}
public static void SetPassword(DependencyObject dp, string value)
{
dp.SetValue(PasswordProperty, value);
}
private static bool GetIsUpdating(DependencyObject dp)
{
return (bool)dp.GetValue(IsUpdatingProperty);
}
private static void SetIsUpdating(DependencyObject dp, bool value)
{
dp.SetValue(IsUpdatingProperty, value);
}
private static void OnPasswordPropertyChanged(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
passwordBox.PasswordChanged -= PasswordChanged;
if (!(bool)GetIsUpdating(passwordBox))
{
passwordBox.Password = (string)e.NewValue;
}
passwordBox.PasswordChanged += PasswordChanged;
}
private static void Attach(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
if (passwordBox == null)
return;
if ((bool)e.OldValue)
{
passwordBox.PasswordChanged -= PasswordChanged;
}
if ((bool)e.NewValue)
{
passwordBox.PasswordChanged += PasswordChanged;
}
}
private static void PasswordChanged(object sender, RoutedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
SetIsUpdating(passwordBox, true);
SetPassword(passwordBox, passwordBox.Password);
SetIsUpdating(passwordBox, false);
}
}
}

View File

@ -1,9 +1,7 @@
using Plane.Windows.IniHelper;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
@ -11,7 +9,6 @@ namespace Plane.FormationCreator.Util
{
public static class VersionControl
{
private static string DefaultServrURL= "http://111.229.174.37:81/login/";
public static int Version = 0;
/// <summary>
/// 是否是完整版本 仅在Version = 255时为完整版本
@ -23,34 +20,13 @@ namespace Plane.FormationCreator.Util
/// </summary>
public static int CopterUpperLimit = 50;
public static string Username = "";
public static string Password = "";
public static bool IssavePassword = false;
public static string ServerURL = "";
public static int ConType = 0; //通讯模块
public static void SetUserLever(int vuserlever)
{
if (vuserlever==0)
//管理员
IsFullVersion = true;
else
IsFullVersion = false;
}
public static void GetSettingFromIni()
public static void GetVersionFromIni()
{
IniFiles iniFiles = new IniFiles();
int intTemp;
bool boolTemp;
string readvalue;
//完整版本和更多飞机数量通过网络授权或者超级用户得到
/*
readvalue = iniFiles.IniReadvalue("Version", "Version");
if (readvalue != "" && int.TryParse(readvalue, out intTemp))
Version = int.Parse(readvalue);
@ -59,108 +35,6 @@ namespace Plane.FormationCreator.Util
readvalue = iniFiles.IniReadvalue("Version", "CopterUpperLimit");
if (readvalue != "" && int.TryParse(readvalue, out intTemp))
CopterUpperLimit = int.Parse(readvalue);
*/
readvalue = iniFiles.IniReadvalue("Login", "Username");
if (readvalue != "")
Username = readvalue;
readvalue = Decrypt(iniFiles.IniReadvalue("Login", "Password"));
if (readvalue != "")
Password = readvalue;
readvalue = iniFiles.IniReadvalue("Login", "issavePassword");
if (readvalue != "" && bool.TryParse(readvalue, out boolTemp))
IssavePassword = bool.Parse(readvalue);
readvalue = iniFiles.IniReadvalue("Default", "Server");
if (readvalue != "")
ServerURL = readvalue;
else
ServerURL = DefaultServrURL;
readvalue = iniFiles.IniReadvalue("Default", "ConType");
if (readvalue != "")
ConType = int.Parse(readvalue);
else
ConType = 0;
}
public static void SaveLogininfoToIni(string username,string password,bool issavepassword)
{
Username = username;
Password = password;
IssavePassword = issavepassword;
IniFiles iniFiles = new IniFiles();
iniFiles.IniWritevalue("Login", "Username", username);
if (issavepassword)
iniFiles.IniWritevalue("Login", "Password", Encrypt(password));
else
iniFiles.IniWritevalue("Login", "Password", "");
iniFiles.IniWritevalue("Login", "issavepassword", issavepassword.ToString());
}
static string encryptKey = "fxmf";//字符串加密密钥(注意密钥只能是4位)
private static string Encrypt(string str)
{//加密字符串
try
{
byte[] key = Encoding.Unicode.GetBytes(encryptKey);//密钥
byte[] data = Encoding.Unicode.GetBytes(str);//待加密字符串
DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();//加密、解密对象
MemoryStream MStream = new MemoryStream();//内存流对象
//用内存流实例化加密流对象
CryptoStream CStream = new CryptoStream(MStream, descsp.CreateEncryptor(key, key), CryptoStreamMode.Write);
CStream.Write(data, 0, data.Length);//向加密流中写入数据
CStream.FlushFinalBlock();//将数据压入基础流
byte[] temp = MStream.ToArray();//从内存流中获取字节序列
CStream.Close();//关闭加密流
MStream.Close();//关闭内存流
return Convert.ToBase64String(temp);//返回加密后的字符串
}
catch
{
return str;
}
}
private static string Decrypt(string str)
{//解密字符串
try
{
byte[] key = Encoding.Unicode.GetBytes(encryptKey);//密钥
byte[] data = Convert.FromBase64String(str);//待解密字符串
DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();//加密、解密对象
MemoryStream MStream = new MemoryStream();//内存流对象
//用内存流实例化解密流对象
CryptoStream CStream = new CryptoStream(MStream, descsp.CreateDecryptor(key, key), CryptoStreamMode.Write);
CStream.Write(data, 0, data.Length);//向加密流中写入数据
CStream.FlushFinalBlock();//将数据压入基础流
byte[] temp = MStream.ToArray();//从内存流中获取字节序列
CStream.Close();//关闭加密流
MStream.Close();//关闭内存流
return Encoding.Unicode.GetString(temp);//返回解密后的字符串
}
catch
{
return str;
}
}
}
}

View File

@ -1,123 +0,0 @@
using System;
using uint8_t = System.Byte;
using uint16_t = System.UInt16;
using int32_t = System.Int32;
using uint32_t = System.UInt32;
using int8_t = System.SByte;
using System.Runtime.InteropServices;
namespace Plane.Util
{
public class nmea : ICorrections
{
int step = 0;
public byte[] buffer = new byte[1024 * 1];
int payloadlen = 0;
int msglencount = 0;
public int length
{
get
{
return 2 + 2 + 2 + 2 + payloadlen; // header2, class,subclass,length2,data,crc2
}
}
public byte[] packet
{
get
{
return buffer;
}
}
public bool resetParser()
{
step = 0;
return true;
}
public int Read(byte data)
{
switch (step)
{
default:
case 0:
if (data == '$')
{
step = 1;
msglencount = 0;
buffer[0] = data;
}
break;
case 1:
if (data == 'G')
{
buffer[1] = data;
step++;
}
else
step = 0;
break;
case 2:
if (msglencount > 1000)
{
step = 0;
}
buffer[msglencount + 2] = data;
msglencount++;
if(data == '\n')
{
var line = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, msglencount + 2);
string[] items = line.Trim().Split(',', '*');
if (items[items.Length-1] == GetChecksum(line))
{
return 1;
}
step = 0;
}
break;
}
return -1;
}
// Calculates the checksum for a sentence
string GetChecksum(string sentence)
{
// Loop through all chars to get a checksum
int Checksum = 0;
foreach (char Character in sentence.ToCharArray())
{
switch (Character)
{
case '$':
// Ignore the dollar sign
break;
case '*':
// Stop processing before the asterisk
return Checksum.ToString("X2");
default:
// Is this the first value for the checksum?
if (Checksum == 0)
{
// Yes. Set the checksum to the value
Checksum = Convert.ToByte(Character);
}
else
{
// No. XOR the checksum with this character's value
Checksum = Checksum ^ Convert.ToByte(Character);
}
break;
}
}
// Return the checksum formatted as a two-character hexadecimal
return Checksum.ToString("X2");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,573 +0,0 @@
using System;
using uint8_t = System.Byte;
using uint16_t = System.UInt16;
using int32_t = System.Int32;
using uint32_t = System.UInt32;
using int8_t = System.SByte;
using System.Runtime.InteropServices;
using System.Threading;
namespace Plane.Util
{
public class Ubx : ICorrections
{
int step = 0;
public byte[] buffer = new byte[1024 * 8];
int payloadlen = 0;
int msglencount = 0;
public byte @class
{
get { return buffer[2]; }
}
public byte subclass
{
get { return buffer[3]; }
}
public int length
{
get
{
return 2 + 2 + 2 + 2 + payloadlen; // header2, class,subclass,length2,data,crc2
}
}
public byte[] packet
{
get { return buffer; }
}
public bool resetParser()
{
step = 0;
return true;
}
public int Read(byte data)
{
switch (step)
{
default:
case 0:
if (data == 0xb5)
{
step = 1;
buffer[0] = data;
}
break;
case 1:
if (data == 0x62)
{
buffer[1] = data;
step++;
}
else
step = 0;
break;
case 2:
buffer[2] = data;
step++;
break;
case 3:
buffer[3] = data;
step++;
break;
case 4:
buffer[4] = data;
payloadlen = data;
step++;
break;
case 5:
buffer[5] = data;
step++;
payloadlen += (data << 8);
msglencount = 0;
// reset on oversize packet
if (payloadlen > buffer.Length)
step = 0;
break;
case 6:
if (msglencount < (payloadlen))
{
buffer[msglencount + 6] = data;
msglencount++;
if (msglencount == payloadlen)
step++;
}
break;
case 7:
buffer[msglencount + 6] = data;
step++;
break;
case 8:
buffer[msglencount + 6 + 1] = data;
var crc = ubx_checksum(buffer, payloadlen + 6);
var crcpacket = new byte[] { buffer[msglencount + 6], data };
if (crc[0] == crcpacket[0] && crc[1] == crcpacket[1])
{
step = 0;
return (@class << 8) + subclass;
}
step = 0;
break;
}
return -1;
}
private static byte[] ubx_checksum(byte[] packet, int size, int offset = 2)
{
uint a = 0x00;
uint b = 0x00;
var i = offset;
while (i < size)
{
a += packet[i++];
b += a;
}
var ans = new byte[2];
ans[0] = (byte)(a & 0xFF);
ans[1] = (byte)(b & 0xFF);
return ans;
}
public static byte[] generate(byte cl, byte subclass, byte[] payload)
{
var data = new byte[2 + 2 + 2 + 2 + payload.Length];
data[0] = 0xb5;
data[1] = 0x62;
data[2] = cl;
data[3] = subclass;
data[4] = (byte)(payload.Length & 0xff);
data[5] = (byte)((payload.Length >> 8) & 0xff);
Array.ConstrainedCopy(payload, 0, data, 6, payload.Length);
var checksum = ubx_checksum(data, data.Length - 2);
data[data.Length - 2] = checksum[0];
data[data.Length - 1] = checksum[1];
return data;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ubx_mon_ver
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
public byte[] swVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public Byte[] hwVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
public byte[] extension;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ubx_mon_hw
{
public int pinSel;
public int pinBank;
public int pinDir;
public int pinVal;
public ushort noisePerMS;
public ushort agcCnt;
public byte aStatus;
public byte aPower;
public byte flags;
public byte reserved1;
public int usedMask;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public byte[] VP;
public byte jamInd;
public ushort reserved3;
public int pinIrq;
public int pullH;
public int pullL;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ubx_nav_pvt
{
public uint32_t itow;
public uint16_t year;
public uint8_t month, day, hour, min, sec;
public uint8_t valid;
public uint32_t t_acc;
public int32_t nano;
public uint8_t fix_type;
public uint8_t flags;
public uint8_t flags2;
public uint8_t num_sv;
public int32_t lon, lat;
public int32_t height, h_msl;
public uint32_t h_acc, v_acc;
public int32_t velN, velE, velD, gspeed;
public int32_t head_mot;
public uint32_t s_acc;
public uint32_t head_acc;
public uint16_t p_dop;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public uint8_t[] reserved1;
public uint32_t headVeh;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public uint8_t[] reserved2;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ubx_nav_svin
{
public uint8_t version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public uint8_t[] reserved1;
public uint32_t iTOW;
public uint32_t dur;
public int32_t meanX;
public int32_t meanY;
public int32_t meanZ;
public int8_t meanXHP;
public int8_t meanYHP;
public int8_t meanZHP;
public uint8_t reserved2;
public uint32_t meanAcc;
public uint32_t obs;
public uint8_t valid;
public uint8_t active;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public uint8_t[] reserved3;
public double[] getECEF()
{
var X = meanX / 100.0 + meanXHP * 0.0001;
var Y = meanY / 100.0 + meanYHP * 0.0001;
var Z = meanZ / 100.0 + meanZHP * 0.0001;
return new double[] { X, Y, Z };
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ubx_nav_velned
{
public uint iTOW;
public int velN;
public int velE;
public int velD;
public uint speed;
public uint gSpeed;
public int heading;
public uint sAcc;
public uint cAcc;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ubx_cfg_nav5_getset_s
{
public uint16_t mask;
public uint8_t dynModel;
public uint8_t fixMode;
public int32_t fixedAlt;
public uint32_t fixedAltVar;
public int8_t minElev;
public uint8_t drLimit;
public uint16_t pDop;
public uint16_t tDop;
public uint16_t pAcc;
public uint16_t tAcc;
public uint8_t staticHoldThresh;
public uint8_t dgnssTimeout;
public uint8_t cnoThreshNumSVs;
public uint8_t cnoThresh;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public uint8_t[] reserved1;
public uint16_t staticHoldMaxDist;
public uint8_t utcStandard;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public uint8_t[] reserved2;
}
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 40)]
public struct ubx_cfg_tmode3
{
public ubx_cfg_tmode3(double lat, double lng, double alt, double acc = 0.001)
{
version = 0;
reserved1 = 0;
if (Math.Abs(lat) > 90)
{
flags = 2; // fixed mode ecef
ecefXorLat = (int)(lat * 100);
ecefYorLon = (int)(lng * 100);
ecefZorAlt = (int)(alt * 100);
ecefXOrLatHP = (sbyte)((lat * 100 - ecefXorLat) * 100.0);
ecefYOrLonHP = (sbyte)((lng * 100 - ecefYorLon) * 100.0);
ecefZOrAltHP = (sbyte)((alt * 100 - ecefZorAlt) * 100.0);
}
else
{
flags = 256 + 2; // lla + fixed mode
ecefXorLat = (int)(lat * 1e7);
ecefYorLon = (int)(lng * 1e7);
ecefZorAlt = (int)(alt * 100.0);
ecefXOrLatHP = (sbyte)((lat * 1e7 - ecefXorLat) * 100.0);
ecefYOrLonHP = (sbyte)((lng * 1e7 - ecefYorLon) * 100.0);
ecefZOrAltHP = (sbyte)((alt * 100.0 - ecefZorAlt) * 100.0);
}
reserved2 = 0;
fixedPosAcc = (uint)(acc * 1000.0);
svinMinDur = 60;
svinAccLimit = 2000;
reserved3 = new byte[8];
}
public ubx_cfg_tmode3(uint DurationS, double AccLimit)
{
version = 0;
reserved1 = 0;
flags = 1; // surveyin mode
ecefXorLat = 0;
ecefYorLon = 0;
ecefZorAlt = 0;
ecefXOrLatHP = (sbyte)0;
ecefYOrLonHP = (sbyte)0;
ecefZOrAltHP = (sbyte)0;
reserved2 = 0;
fixedPosAcc = 0;
svinMinDur = DurationS;
svinAccLimit = (uint)(AccLimit * 10000);
reserved3 = new byte[8];
}
public static ubx_cfg_tmode3 Disable
{
get
{
return new ubx_cfg_tmode3()
{
flags = 0, // disable
reserved3 = new byte[8]
};
}
}
public static implicit operator byte[] (ubx_cfg_tmode3 input)
{
return null;// MavlinkUtil.StructureToByteArray(input);
}
public enum modeflags
{
Disabled = 0,
SurveyIn = 1,
FixedECEF = 2,
LLA = 256,
FixedLLA = 258
}
public byte version;
public byte reserved1;
public ushort flags;
public int ecefXorLat; // 1e7
public int ecefYorLon;
public int ecefZorAlt;
public sbyte ecefXOrLatHP;
public sbyte ecefYOrLonHP;
public sbyte ecefZOrAltHP;
public byte reserved2;
public uint fixedPosAcc;
public uint svinMinDur;
public uint svinAccLimit;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] reserved3;
public void SetupM8P(ICommsSerial port, bool m8p_130plus = false, bool movingbase = false)
{
port.BaseStream.Flush();
var bauds = new[] { port.BaudRate, 9600, 38400, 57600, 115200, 230400, 460800 };
// change the baudrate
foreach (var baud in bauds)
{
port.BaudRate = baud;
System.Threading.Thread.Sleep(50);
// U = bit 01010101 - often used for autobaud
port.Write("UU");
// port config - 460800 - uart1
var packet = generate(0x6, 0x00, new byte[]
{
0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x00, 0x08,
0x07, 0x00, 0x23, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00
});
port.Write(packet, 0, packet.Length);
port.BaseStream.Flush();
System.Threading.Thread.Sleep(100);
}
{
// port config - usb
var packet = generate(0x6, 0x00, new byte[]
{
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x23, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00
});
port.Write(packet, 0, packet.Length);
System.Threading.Thread.Sleep(300);
port.BaseStream.Flush();
port.BaudRate = 460800;
}
{
// set rate to 1hz
var packet = generate(0x6, 0x8, new byte[] { 0xE8, 0x03, 0x01, 0x00, 0x01, 0x00 });
port.Write(packet, 0, packet.Length);
System.Threading.Thread.Sleep(200);
// set navmode to stationary
{
packet = generate(0x6, 0x24,
new byte[]
{
0xFF, 0xFF, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x0F, 0x00, 0xFA,
0x00,
0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x23, 0x10, 0x27, 0x00, 0x00, 0x00,
0x00,
0x00, 0x00, 0x00, 0x00
});
port.Write(packet, 0, packet.Length);
System.Threading.Thread.Sleep(200);
}
}
// turn off all nmea
for (int a = 0; a <= 0xf; a++)
{
if (a == 0xb || a == 0xc || a == 0xe)
continue;
turnon_off(port, 0xf0, (byte)a, 0);
}
// mon-ver
poll_msg(port, 0xa, 0x4);
// surveyin msg - for feedback
turnon_off(port, 0x01, 0x3b, 1);
// pvt msg - for feedback
turnon_off(port, 0x01, 0x07, 1);
// 1005 - 5s
turnon_off(port, 0xf5, 0x05, 5);
byte rate1 = 1;
byte rate2 = 0;
if (m8p_130plus)
{
rate1 = 0;
rate2 = 1;
}
// 1074 - 1s
turnon_off(port, 0xf5, 0x4a, rate2);
// 1077 - 1s
turnon_off(port, 0xf5, 0x4d, rate1);
// 1084 - 1s
turnon_off(port, 0xf5, 0x54, rate2);
// 1087 - 1s
turnon_off(port, 0xf5, 0x57, rate1);
// 1094 - 1s
turnon_off(port, 0xf5, 0x5e, rate2);
// 1097 - 1s
turnon_off(port, 0xf5, 0x61, rate1);
// 1124 - 1s
turnon_off(port, 0xf5, 0x7c, rate2);
// 1127 - 1s
turnon_off(port, 0xf5, 0x7f, rate1);
// 4072
turnon_off(port, 0xf5, 0xFE, 0);
// 1230 - 5s
turnon_off(port, 0xf5, 0xE6, 5);
// NAV-VELNED - 1s
turnon_off(port, 0x01, 0x12, 1);
// rxm-raw/rawx - 1s
turnon_off(port, 0x02, 0x15, 1);
turnon_off(port, 0x02, 0x10, 1);
// rxm-sfrb/sfrb - 2s
turnon_off(port, 0x02, 0x13, 2);
turnon_off(port, 0x02, 0x11, 2);
// mon-hw - 2s
turnon_off(port, 0x0a, 0x09, 2);
System.Threading.Thread.Sleep(100);
}
public void turnon_off(ICommsSerial port, byte clas, byte subclass, byte every_xsamples)
{
byte[] datastruct1 = { clas, subclass, 0, every_xsamples, 0, every_xsamples, 0, 0 };
var packet = generate(0x6, 0x1, datastruct1);
port.Write(packet, 0, packet.Length);
System.Threading.Thread.Sleep(10);
}
public void poll_msg(ICommsSerial port, byte clas, byte subclass)
{
byte[] datastruct1 = { };
var packet = generate(clas, subclass, datastruct1);
port.Write(packet, 0, packet.Length);
System.Threading.Thread.Sleep(10);
}
}
}
}

View File

@ -139,47 +139,6 @@ namespace Plane.FormationCreator.ViewModels
}
public bool IsCalibration { get; set; }
/// <summary>
/// 重启飞控
/// </summary>
private ICommand _RestartFCCommand;
public ICommand RestartFCCommand
{
get
{
return _RestartFCCommand ?? (_RestartFCCommand = new RelayCommand(async () =>
{
if (_copterManager.SelectedCopters.Count() == 0) return;
Message.Show("重启飞控");
await commModule.DoRestartFCAsync(_copterManager.SelectedCopters);
await Task.Delay(50).ConfigureAwait(false);
}));
}
}
/// <summary>
/// 陀螺仪校准
/// </summary>
private ICommand _CalibrationPreflightCommand;
public ICommand CalibrationPreflightCommand
{
get
{
return _CalibrationPreflightCommand ?? (_CalibrationPreflightCommand = new RelayCommand(async () =>
{
if (_copterManager.SelectedCopters.Count() == 0) return;
Message.Show("开始校准陀螺仪");
await commModule.DoCalibrationPreflightAsync(_copterManager.SelectedCopters);
await Task.Delay(50).ConfigureAwait(false);
}));
}
}
/// <summary>
/// 校准指南针
/// </summary>

View File

@ -1,150 +0,0 @@
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.Practices.ServiceLocation;
using Plane.FormationCreator.Formation;
using Plane.FormationCreator.Util;
using Plane.FormationCreator.Views;
using Plane.Util;
using Plane.Windows.Messages;
using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace Plane.FormationCreator.ViewModels
{
/// <summary>
/// This class contains properties that a View can data bind to.
/// <para>
/// See http://www.galasoft.ch/mvvm
/// </para>
/// </summary>
public class ChangePasswordViewModel : ViewModelBase
{
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
private MainViewModel _MainViewModel=ServiceLocator.Current.GetInstance<MainViewModel>();
/// <summary>
/// Initializes a new instance of the LoginViewModel class.
/// </summary>
public ChangePasswordViewModel()
{
NewPassword = "";
OldPassword = "";
NewPassword1 = "";
Username = "";
}
private string _Username="";
public string Username
{
get { return _Username; }
set
{
Set(nameof(Username), ref _Username, value);
}
}
private string _OldPassword = "";
public string OldPassword
{
get { return _OldPassword; }
set
{
Set(nameof(OldPassword), ref _OldPassword, value);
}
}
private string _NewPassword = "";
public string NewPassword
{
get { return _NewPassword; }
set
{
Set(nameof(NewPassword), ref _NewPassword, value);
}
}
private string _NewPassword1 = "";
public string NewPassword1
{
get { return _NewPassword1; }
set
{
Set(nameof(NewPassword1), ref _NewPassword1, value);
}
}
private ICommand _ExitCommand;
public ICommand ExitCommand
{
get
{
return _ExitCommand ?? (_ExitCommand = new RelayCommand<ChangePasswordView>(wd =>
{
if (wd != null)
{
NewPassword = "";
OldPassword = "";
NewPassword1 = "";
Username = "";
wd.Close();
}
}));
}
}
private ICommand _ChangePasswordCommand;
public ICommand ChangePasswordCommand
{
get
{
return _ChangePasswordCommand ?? (_ChangePasswordCommand = new RelayCommand<ChangePasswordView>(wd =>
{
if (Username.Trim() == "")
{
Alert.Show("请输入账号!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (OldPassword=="")
{
Alert.Show("请输入原密码!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (NewPassword.Length<6)
{
Alert.Show("新密码长度不能低于6位", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (NewPassword != NewPassword1)
{
Alert.Show("两次新密码不相同!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
_copterManager.NetChangePassword(Username.Trim(), OldPassword, NewPassword);
//wd.Close();
}));
}
}
}
}

View File

@ -1,336 +0,0 @@
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Plane.Copters;
using Plane.FormationCreator.Formation;
using Plane.Geography;
using Plane.Windows.Messages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Microsoft.Practices.ServiceLocation;
using System.IO;
namespace Plane.FormationCreator.ViewModels
{
public class ConfigVirtualIdViewModel : ViewModelBase
{
CopterManager _copterManager;
public ConfigVirtualIdViewModel(CopterManager copterManager)
{
_copterManager = copterManager;
}
private int _SingleVirtualId = 0;
public int SingleVirtualId
{
get { return _SingleVirtualId; }
set { Set(nameof(SingleVirtualId), ref _SingleVirtualId, value); }
}
/// <summary>
/// 清除所有编号
/// </summary>
private ICommand _ClearVirtualIdCommand;
public ICommand ClearVirtualIdCommand
{
get
{
return _ClearVirtualIdCommand ?? (_ClearVirtualIdCommand = new RelayCommand(() =>
{
foreach (var c in _copterManager.Copters)
{
c.VirtualId = 0;
}
Message.Show($"已清除所有飞机编号");
}));
}
}
/// <summary>
/// 清除所有编号
/// </summary>
private ICommand _SaveVirtualIdCommand;
public ICommand SaveVirtualIdCommand
{
get
{
return _SaveVirtualIdCommand ?? (_SaveVirtualIdCommand = new RelayCommand(() =>
{
string Savestr = "";
foreach (var c in _copterManager.Copters)
{
Savestr += c.Id + "=" + c.VirtualId + ';';
}
StreamWriter writer = new StreamWriter("vid.dat");
writer.Write(Savestr);
writer.Close();
Message.Show($"保存成功");
}));
}
}
/// <summary>
/// 清除所有编号
/// </summary>
private ICommand _LoadVirtualIdCommand;
public ICommand LoadVirtualIdCommand
{
get
{
return _LoadVirtualIdCommand ?? (_LoadVirtualIdCommand = new RelayCommand(() =>
{
if (!File.Exists("vid.dat"))
return;
// string str = System.IO.File.ReadAllText(@"vid.dat");
string str = File.ReadAllText("vid.dat");
string[] arr = str.Split(';');
foreach (string s in arr)
{
string[] arrs = s.Split('=');
var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == arrs[0]);
if (copter != null)
{
copter.VirtualId = int.Parse(arrs[1]);
}
}
_copterManager.SortType = CopterManager.CopterSortType.ByVID;// .sortbyvid();
Message.Show($"读入成功");
}));
}
}
/// <summary>
/// 设置单个虚拟ID
/// </summary>
private ICommand _SetSingleVirtualIdCommand;
public ICommand SetSingleVirtualIdCommand
{
get
{
return _SetSingleVirtualIdCommand ?? (_SetSingleVirtualIdCommand = new RelayCommand(() =>
{
if (SingleVirtualId <= 0)
{
System.Windows.MessageBox.Show("编号必须大于0");
return;
}
if (_copterManager.AcceptingControlCopters.Count() == 1)
{
var copter = _copterManager.AcceptingControlCopters.FirstOrDefault();
copter.VirtualId = SingleVirtualId;
Message.Show($"飞机{copter.Name} 设置编号={SingleVirtualId}");
}
_copterManager.ReSort();
}));
}
}
private ICommand _AutoLocationNumsCommand;
public ICommand AutoLocationNumsCommand
{
get
{
//目前方案是
//1.保证所有没有正确定位的飞机都人工编号,
//2.然后选中3架飞机1号飞机第一排任意飞机第一列任意飞机尽量远离1号机
//3.开始计算
return _AutoLocationNumsCommand ?? (_AutoLocationNumsCommand = new RelayCommand( () =>
{
//飞机摆放最小间距
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
float StepDis_Row = _flightTaskManager.ColumnDistance; //行内间距-列间距
float StepDis_Col = _flightTaskManager.RowDistance ; //列间距-行间距
float FindDis =Math.Min(StepDis_Row, StepDis_Col)*0.8f; //查找半径
//如果选中的飞机总数大于2--需要2-3架用来确认行列方向只有一行飞机就选2架多行需要3架
if (_copterManager.AcceptingControlCopters.Count() >= 2)
{
var copters = _copterManager.AcceptingControlCopters.ToList();
var firstCopter = copters[0];
var secondCopter = copters[1];
ICopter thirdCopter=null;
if (_copterManager.AcceptingControlCopters.Count() > 2)
{
thirdCopter = copters[2];
Message.Show($"选中了3架飞机将自动查找所有行列的飞机");
}
else
Message.Show($"选中了2架飞机将查找一行飞机");
//行角度(1,2) 用于查找每行的飞机位置
float RowDirect = (float)GeographyUtils.RadToDeg(firstCopter.CalcDirection2D(secondCopter));
//列角度(1,3) 用于查找每行第一架飞机
float ColDirect = 0;
if (thirdCopter!=null)
ColDirect = (float)GeographyUtils.RadToDeg(firstCopter.CalcDirection2D(thirdCopter));
ICopter FindedCopter = firstCopter;
ICopter LastCopter = firstCopter;
ILocation2D LastRowHewadCopter = firstCopter;
Message.Show($"开始查找飞机:行角度{RowDirect},列角度{ColDirect},列间距{StepDis_Row},行间距{StepDis_Col},查找半径{FindDis}米...");
firstCopter.VirtualId = 1;
int rowindex = 1;
while (FindedCopter!=null)
{
//按一行找飞机
FindedCopter = FindNextCopter(LastCopter, RowDirect, StepDis_Row, FindDis);
//一行找不到了 找下一行的前3架飞机
if ((FindedCopter == null) && (thirdCopter != null))
{
rowindex++;
FindedCopter = FindNextColHeadCopter(out LastRowHewadCopter, LastRowHewadCopter, ColDirect, StepDis_Col, RowDirect, StepDis_Row, 3, FindDis);
if (FindedCopter != null)
Message.Show($"开始第{rowindex}行--找到飞机");
else
Message.Show($"开始第{rowindex}行--无飞机");
}
//如果找到了分配ID
if (FindedCopter != null)
{
FindedCopter.VirtualId = GetVID(LastCopter.VirtualId);
// Message.Show($"分配ID={FindedCopter.Id}飞机VID:={FindedCopter.VirtualId}");
LastCopter = FindedCopter;
}else
{
Message.Show($"未找到飞机,自动分配结束");
}
}
}
_copterManager.ReSort();
}));
}
}
//根据位置和查找范围查找飞机
private ICopter FindCopteratLoc(ILocation2D startLoc, float findDis)
{
ICopter retCopter = null;
ICopter foundCopter = null;
double mindis = 1000;
//所有没有虚拟ID的飞机
List<ICopter> NoVIDCopters = _copterManager.Copters.Where(o => o.VirtualId == 0).ToList();
//找距离startLoc最近的飞机
foreach (var copter in NoVIDCopters)
{
//计算这些飞机和startLoc的距离
double temp = startLoc.CalcDistance2D(copter);
//找最近的飞机
if (temp < mindis)
{
mindis = temp;
foundCopter = copter;
}
}
//如果找到的最近的飞机小于查找半径就认为找到了
if (mindis < findDis)
retCopter = foundCopter;
return retCopter;
}
//根据VID查找飞机
private ICopter FindCopteratVID(int VID)
{
List<ICopter> HaveVIDCopters = _copterManager.Copters.Where(o => o.VirtualId == VID).ToList();
if (HaveVIDCopters.Count==1)
return HaveVIDCopters[0];
return null;
}
//计算VID,找下一个没有提前分配的VID
private int GetVID(int VirtualId)
{
int retvid = VirtualId+1;
ICopter Copter = FindCopteratVID(retvid);
while (Copter!=null)
Copter = FindCopteratVID(++retvid);
return retvid;
}
/// <summary>
/// 按方向步长等找下一架飞机
/// </summary>
/// <param name="Copter">起始飞机</param>
/// <param name="Direct">方向</param>
/// <param name="findstep">步长</param>
/// <param name="finddis">查找半径</param>
/// <returns>找到的飞机</returns>
private ICopter FindNextCopter(ILocation2D Copter, float Direct,float findstep,float finddis,int findstepnum=5)
{
ICopter FindedCopter = null;
ILocation2D FindLoc = null;
int step = 1;
while ((FindedCopter == null) && (step <= findstepnum))
{
//查找下一个飞机应在摆放的位置
FindLoc = Copter.CalcLatLngSomeMetersAway2D(Direct, findstep * step++);
//该位置是否有飞机
FindedCopter = FindCopteratLoc(FindLoc, finddis);
}
return FindedCopter;
}
/// <summary>
///按方向步长等找下一行的第一架飞机同时输出该行第一个应该摆放飞机的位置
/// </summary>
/// <param name="HeadLoc">输出第一架飞机应该在的位置</param>
/// <param name="Copter">起始飞机</param>
/// <param name="ColDirect">列角度</param>
/// <param name="Colstep">列步长</param>
/// <param name="RowDirect">行角度</param>
/// <param name="Rowstep">行步长</param>
/// <param name="Rowstepnum">行查找深度</param>
/// <param name="finddis">位置查找范围</param>
/// <returns>找到的飞机</returns>
private ICopter FindNextColHeadCopter(out ILocation2D HeadLoc, ILocation2D Copter, float ColDirect, float Colstep,
float RowDirect, float Rowstep, int Rowstepnum,float finddis, int Colfindstepnum = 5)
{
ICopter FindedCopter = null;
HeadLoc = null;
int step = 1;
while ((FindedCopter == null) && (step <= Colfindstepnum))
{
//查找下一行第一架飞机应在摆放的位置
HeadLoc = Copter.CalcLatLngSomeMetersAway2D(ColDirect, Colstep * step++);
//该位置是否有飞机
FindedCopter = FindCopteratLoc(HeadLoc, finddis);
//如果没有飞机,横着找找行有没飞机
if (FindedCopter==null)
FindedCopter=FindNextCopter(HeadLoc, RowDirect, Rowstep, finddis, Rowstepnum);
}
return FindedCopter;
}
}
}

View File

@ -24,32 +24,16 @@ using Plane.CommunicationManagement;
using Plane.Protocols;
using Microsoft.Practices.ServiceLocation;
using System.Windows.Media;
using Plane.FormationCreator.Views;
using System.Collections.ObjectModel;
using Plane.Util;
using System.IO.Ports;
using SerialPort = Plane.Util.SerialPort;
namespace Plane.FormationCreator.ViewModels
{
public class ConnectViewModel : ViewModelBase
{
public ConnectViewModel(CopterManager copterManager)
{
_copterManager = copterManager;
RefreshPorts();
}
public void RefreshPorts()
{
serialRePorts.Clear();
string[] commports = SerialPort.GetPortNames();
foreach (var item in commports)
{
serialRePorts.Add(item);
}
}
private CommModuleManager _commModuleManager = CommModuleManager.Instance;
private CopterManager _copterManager;
private const int PORT = 5250;
@ -82,16 +66,6 @@ namespace Plane.FormationCreator.ViewModels
set { Set(nameof(IsProcessing), ref _IsProcessing, value); }
}
public ObservableCollection<string> serialRePorts { get; } = new ObservableCollection<string>();
private string _serialPortResend;
public string SerialPortResend
{
get { return _serialPortResend; }
set { Set(nameof(SerialPortResend), ref _serialPortResend, value); }
}
private ICommand _ConnectCommand;
public ICommand ConnectCommand
{
@ -104,66 +78,6 @@ namespace Plane.FormationCreator.ViewModels
));
}
}
RtcmInfoViewModel _rtcmInfoViewModel = ServiceLocator.Current.GetInstance<RtcmInfoViewModel>();
private ICommand _Openboardport;
public ICommand Openboardport
{
get
{
return _Openboardport ?? (_Openboardport = new RelayCommand<string>(async connectionType =>
{
if (btnBoardPortStr== "关闭广播端口")
{
//关闭广播端口
//正在发送rtcm数据并且使用了广播端口
if (_rtcmInfoViewModel.RtcmManager.Rtcmthreadrun&& _rtcmInfoViewModel.ResendToComMK)
{
if (Alert.Show("正在使用广播端口发送RTCM数据关闭后广播端口将停止发送,继续吗?", "警告", MessageBoxButton.OKCancel, MessageBoxImage.Warning)
== MessageBoxResult.OK)
{
// _rtcmInfoViewModel.ResendToComMK = false;
}
else
{
return;
}
}
//关闭同时清除广播端口,这样就不会重试打开
_commModuleManager.CloseResendRtcmserial(true);
btnBoardPortStr = "打开广播端口";
BoardPortStatusStr = _commModuleManager.BoardPortStatusStr;
Message.BoardOpen(false);
}
else
{ //打开广播端口
if ((SerialPortResend != null))
{
if (!_commModuleManager.OpenResendRtcmserial(SerialPortResend))
{
Alert.Show($"打开串口失败", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
btnBoardPortStr = "关闭广播端口";
Message.BoardOpen(true);
}
BoardPortStatusStr = _commModuleManager.BoardPortStatusStr;
}
else
{
Alert.Show($"请选择需要广播的端口", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
return;
}
}
_rtcmInfoViewModel.SetRTKStatestr();
}
));
}
}
private ICommand _SendCommand;
public ICommand SendCommand
@ -172,7 +86,7 @@ namespace Plane.FormationCreator.ViewModels
{
return _SendCommand ?? (_SendCommand = new RelayCommand(async () =>
{
await SendCommandAsync(CopterSum);
await SendCommandAsync(CopterNum);
}
));
}
@ -211,43 +125,13 @@ namespace Plane.FormationCreator.ViewModels
set { Set(nameof(CopterNum), ref _CopterNum, value); }
}
public float scale3d
{
get { return _copterManager.scale3d ; }
set { _copterManager.scale3d = value;}
}
private int _CopterSum=100;
public int CopterSum
{
get { return _CopterSum; }
set { Set(nameof(CopterSum), ref _CopterSum, value); }
}
private string _CopterColor = "330033";
private string _CopterColor = "";
public string CopterColor
{
get { return _CopterColor; }
set { Set(nameof(CopterColor), ref _CopterColor, value); }
}
private string _BoardPortStatusStr = "广播端口未打开";
public string BoardPortStatusStr
{
get { return _BoardPortStatusStr; }
set { Set(nameof(BoardPortStatusStr), ref _BoardPortStatusStr, value); }
}
private string _btnBoardPortStr = "打开广播端口";
public string btnBoardPortStr
{
get { return _btnBoardPortStr; }
set { Set(nameof(btnBoardPortStr), ref _btnBoardPortStr, value); }
}
private ICommand _WriteIdCommand;
public ICommand WriteIdCommand
{
@ -329,46 +213,6 @@ namespace Plane.FormationCreator.ViewModels
}));
}
}
private ICommand _ChangepasswordCommand;
public ICommand ChangepasswordCommand
{
get
{
return _ChangepasswordCommand ?? (_ChangepasswordCommand = new RelayCommand( () =>
{
ChangePasswordView changePasswordView = new ChangePasswordView();
changePasswordView.ShowDialog();
}));
}
}
private ICommand _TestModuleCommand;
public ICommand TestModuleCommand
{
get
{
return _TestModuleCommand ?? (_TestModuleCommand = new RelayCommand(async () =>
{
await commModule.TestModule((short)scale3d);
}));
}
}
private ICommand _SetModulePowerCommand;
public ICommand SetModulePowerCommand
{
get
{
return _SetModulePowerCommand ?? (_SetModulePowerCommand = new RelayCommand(async () =>
{
int mPower = int.Parse(CopterColor);
await commModule.SetModulePower((short)CopterNum, (short)mPower);
}));
}
}
private ICommand _CommDataAsync;
public ICommand CommDataAsync
@ -383,44 +227,17 @@ namespace Plane.FormationCreator.ViewModels
}
}
private ICommand _TestPWMCommandAsync;
public ICommand TestPWMCommandAsync
{
get
{
return _TestPWMCommandAsync ?? (_TestPWMCommandAsync = new RelayCommand(async () =>
{
try
{
int channel = 10; //固定10是控制PWM舵机
await commModule.TestFire((short)CopterNum, channel);
}
catch
{ }
}
));
}
}
private ICommand _TestFireCommandAsync;
public ICommand TestFireCommandAsync
{
get
{
return _TestFireCommandAsync ?? (_TestFireCommandAsync = new RelayCommand(async () =>
{
try
{
int channel = int.Parse(CopterColor);
if (channel >= 0 && channel <= 4)
await commModule.TestFire((short)CopterNum, channel);
}
catch
{ }
}
));
}
}
@ -434,7 +251,7 @@ namespace Plane.FormationCreator.ViewModels
IMission LEDMission = Mission.CreateLEDControlMission(
(int)(ledInfo.Delay * 10),
ledInfo.LEDMode,
ledInfo.LEDInterval,
ledInfo.LEDRate,
0, //ledInfo.LEDTimes,
color.R,
color.G,

View File

@ -28,7 +28,7 @@ namespace Plane.FormationCreator.ViewModels
{
// serialport
internal static IConnection Rtkport ;
private static System.Threading.Thread thrtk;
private static bool trkthreadrun = false;
private static bool rtcmthreadrun = false;
@ -119,25 +119,7 @@ namespace Plane.FormationCreator.ViewModels
{
return _DetectionVoltage ?? (_DetectionVoltage = new RelayCommand(async () =>
{
float minVol;
InputDialog inputDialog = new InputDialog("最低检测电压( 0 恢复灯光):", "15.6");
if (inputDialog.ShowDialog() == true)
minVol = float.Parse(inputDialog.Answer);
else return;
//测试电池
await _commModuleManager.TestBattery((short)0, minVol);
if (minVol == 0.0) return;
Message.Show("---请检查飞机灯光---");
Message.Show(string.Format("---绿 色 电压高于 {0:F2}v (单节高于 {1:F2}v)--- ", minVol, minVol / 4.0f));
Message.Show(string.Format("---黄 色 电压低于 {0:F2}v (单节低于 {1:F2}v)--- ", minVol, minVol / 4.0f));
Message.Show(string.Format("---棕 色 电压低于 {0:F2}v (单节低于 {1:F2}v)--- ", minVol - 0.2, (minVol - 0.2) / 4.0f));
Message.Show(string.Format("---洋红色 电压低于 {0:F2}v (单节低于 {1:F2}v)--- ", minVol - 0.4, (minVol - 0.4) / 4.0f));
Message.Show(string.Format("---亮红色 电压低于 {0:F2}v (单节低于 {1:F2}v)--- ", minVol - 0.6, (minVol - 0.6) / 4.0f));
Message.Show("---输入0恢复灯光---");
Message.Show("--------------开始检测单机电压--------------");
Message.Show("--------------开始检测电压--------------");
Dictionary<string, float> dic_voltage = new Dictionary<string, float>();
await Task.WhenAll(_copterManager.Copters.Select(async c =>
{
@ -153,43 +135,22 @@ namespace Plane.FormationCreator.ViewModels
float voltageAverage = voltageSum / 5;
if (name != null && name != "")
{
lock (locker)
lock(locker)
{
dic_voltage.Add(name, voltageAverage);
}
}
})).ConfigureAwait(false);
await Task.Run(async () => {
Dictionary<string, float> dic_voltage_Order = dic_voltage.OrderByDescending(o => o.Value).ToDictionary(o => o.Key, o => o.Value);
bool showch = false;
ICopter vcopter = null;
_copterManager.shiftkeydown = true;
//清除选择
_copterManager.Select(null);
foreach (KeyValuePair<string, float> kv in dic_voltage_Order)
{
if ((!showch) && (minVol > 0.00) && (kv.Value <= minVol))
{
Message.Show(string.Format("以下飞机电压低于[{0}V单节{1:F2}]", minVol, minVol / 4));
showch = true;
}
Message.Show(string.Format("{0} --> 5秒平均电压{1:F2},单节{2:F2}", kv.Key, kv.Value, kv.Value / 4));
//选中低电压飞机
if ((minVol > 0.00) && (kv.Value <= minVol))
{
vcopter = _copterManager.Copters.FirstOrDefault(o => o.Name == kv.Key);
if (vcopter != null)
_copterManager.Select(vcopter); //需要访问UI线程
}
Message.Show(string.Format("{0} --> 5秒平均电压{1}", kv.Key, kv.Value));
await Task.Delay(5).ConfigureAwait(false);
}
await Task.Delay(500).ConfigureAwait(false);
_copterManager.shiftkeydown = false;
Message.Show(string.Format("----检测电压完成,检测总数:{0}----", dic_voltage.Count));
//todo:增加电压阈值变成不同颜色灯
}).ConfigureAwait(false);
}));
}
}
@ -257,7 +218,7 @@ namespace Plane.FormationCreator.ViewModels
Array.Reverse(test);
string data = string.Join(".", test);
string copters = string.Join(",", kv.Value.ToArray());
Message.Show(string.Format("返回数据{0}({1}){2}", data, kv.Key,copters));
Message.Show(string.Format("返回数据{0}{1}", data, copters));
await Task.Delay(5).ConfigureAwait(false);
}
Message.Show("----统计完成----");
@ -277,9 +238,6 @@ namespace Plane.FormationCreator.ViewModels
if (_copterManager.Copters.Count > 0)
{
Dictionary<string, List<string>> GPSTypes = new Dictionary<string, List<string>>();
Dictionary<string, List<string>> Heading = new Dictionary<string, List<string>>();
foreach (var copter in _copterManager.Copters)
{
string name = copter.Name;
@ -291,39 +249,12 @@ namespace Plane.FormationCreator.ViewModels
}
else
GPSTypes[copter.GpsFixType.ToString()].Add(name);
if (!Heading.Keys.Contains(copter.Heading.ToString()))
{
List<string> copterNames = new List<string>();
copterNames.Add(name);
Heading.Add(copter.Heading.ToString(), copterNames);
}
else
Heading[copter.Heading.ToString()].Add(name);
}
Message.Show($"==定位状态==");
foreach (var item in GPSTypes)
{
Message.Show($"{item.Key}:{string.Join(",", item.Value)}");
Message.Show($"------------");
}
Message.Show($"==机头方向==");
//从小到大排个序
Dictionary<string, List<string>> SortedHeading = Heading.OrderBy(p => p.Key).ToDictionary(p => p.Key, o => o.Value);
foreach (var item in SortedHeading)
{
Message.Show($"{item.Key} 度:{string.Join(",", item.Value)}");
Message.Show($"------------");
}
}
await Task.Delay(10);
}));
@ -383,7 +314,6 @@ namespace Plane.FormationCreator.ViewModels
{
return _AllLandCommand ?? (_AllLandCommand = new RelayCommand(async () =>
{
_commModuleManager.SetAllCoptersForWifi(_copterManager.Copters);
await _commModuleManager.LandAsync();
/*
await Task.WhenAll(_copterManager.Copters.Select(async c =>
@ -395,86 +325,6 @@ 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;
}));
}
}
/// <summary>
/// 紧急返航:计算当前图案中心点,起飞图案中心点,图案距离起飞图案中心点最近距离
/// 条件:任务已经开始,且飞行器已经飞行
/// 可用于模拟和实际飞行,
/// 1首先需要导入最后的飞行任务文件
/// 2实际飞机需要执行解锁和开始任务
/// 3模拟任务需要开始任务并且暂停任务才能计算
/// </summary>
private ICommand _EmergencyRetCommand;
public ICommand EmergencyRetCommand
{
get
{
return _EmergencyRetCommand ?? (_EmergencyRetCommand = new RelayCommand(async () =>
{
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=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;
}
//模拟测试
if (_flightTaskManager.TaskState != TasksStatus.Stop)
await _flightTaskManager.sim_DoMissionEmergencyRetAsync(takeoffcentloc, taskcentloc, (float)mindistance, rettime, overlapping);
for (int i = 0; i < 10; i++)
{
await _commModuleManager.DoMissionEmergencyRetAsync(takeoffcentloc,taskcentloc,(float)mindistance, rettime, overlapping);
}
}));
}
}
private ICommand _LEDFlickerCommand;
public ICommand LEDFlickerCommand
{
@ -487,30 +337,6 @@ namespace Plane.FormationCreator.ViewModels
}
}
private ICommand _DelCommand;
public ICommand DelCommand
{
get
{
return _DelCommand ?? (_DelCommand = new RelayCommand(async () =>
{
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
if (_copterManager.AcceptingControlCopters != null && _copterManager.AcceptingControlCopters.Count() > 0)
{
if (_flightTaskManager.Tasks.Count > 0)
{
Alert.Show("有航点任务无法删除飞机,请先清除航点!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
await _copterManager.DelSelCopters();
}
}));
}
}
private ICommand _MotorTestCommand;
public ICommand MotorTestCommand
{
@ -583,13 +409,11 @@ namespace Plane.FormationCreator.ViewModels
// await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.UnlockAsync()));
for (int i = 0; i < 3; i++)
{
_commModuleManager.SetAllCoptersForWifi(_copterManager.Copters);
await _commModuleManager.UnlockAsync();
await Task.Delay(1000).ConfigureAwait(false);
}
await Task.Delay(100);
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
AllowMissionStart = (_flightTaskManager.TaskState_real == TasksStatus.Stop);
AllowMissionStart = true;
/*
await Task.WhenAll(_copterManager.Copters.Select(async c => {
@ -712,7 +536,6 @@ namespace Plane.FormationCreator.ViewModels
if (Alert.Show("您确定要上锁吗?飞行器将无视转速,立即强制停止运转!!!", "警告", MessageBoxButton.OKCancel, MessageBoxImage.Warning)
== MessageBoxResult.OK)
{
_commModuleManager.SetAllCoptersForWifi(_copterManager.Copters);
await _commModuleManager.LockAsync(_copterManager.AcceptingControlCopters);
//await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.LockAsync()));
}
@ -728,72 +551,7 @@ namespace Plane.FormationCreator.ViewModels
{
return _TakeOffCommand ?? (_TakeOffCommand = new RelayCommand(async () =>
{
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
if (_flightTaskManager.OriginLat == 0 && _flightTaskManager.OriginLng == 0)
{
Alert.Show("作为参照的原点未设置,无法开始任务!", "提示");
return;
}
//飞机用UTC时间日志用本地时间记录
DateTime MissionTime = DateTime.UtcNow.AddSeconds(5);
DateTime MissionTime_log = DateTime.Now.AddSeconds(5);
Message.Show("任务开始:" + MissionTime_log.ToString());
IEnumerable<ICopter> selcopters = _copterManager.AcceptingControlCopters;
//循环3次 发送起飞命令 避免通信问题
for (int i = 0; i < 20; i++)
{
/*await _commModuleManager.DoMissionStartAsync(_copterManager.Copters,
MissionTime.Hour,
MissionTime.Minute,
MissionTime.Second,
_flightTaskManager.OriginLng,
_flightTaskManager.OriginLat
);
*/
await _commModuleManager.DoMissionStartAsync(selcopters,
MissionTime.Hour,
MissionTime.Minute,
MissionTime.Second,
_flightTaskManager.OriginLng,
_flightTaskManager.OriginLat
);
/* await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.MissionStartAsync(
MissionTime.Hour,
MissionTime.Minute,
MissionTime.Second,
_flightTaskManager.OriginLng,
_flightTaskManager.OriginLat
)));
*/
await Task.Delay(20).ConfigureAwait(false);
}
//_copterManager.Net_LogStartMission(MissionTime_log, _flightTaskManager.OriginLng, _flightTaskManager.OriginLat);
Alert.Show("所有选中飞机开始执行航点任务。请勿多次开始任务!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
}));
}
}
private ICommand _ThrowoutCommand;
public ICommand ThrowoutCommand
{
get
{
return _ThrowoutCommand ?? (_ThrowoutCommand = new RelayCommand( () =>
{
// await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.UnlockAsync()));
if (_copterManager.AcceptingControlCopters != null && _copterManager.AcceptingControlCopters.Count() > 0)
_commModuleManager.ThrowoutAsync(_copterManager.AcceptingControlCopters);
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select(copter => copter.TakeOffAsync()));
}));
}
}
@ -853,18 +611,7 @@ namespace Plane.FormationCreator.ViewModels
}));
}
}
private ICommand _GetCommsumCommand;
public ICommand GetCommsumCommand
{
get
{
return _GetCommsumCommand ?? (_GetCommsumCommand = new RelayCommand(async () =>
{
//if (_copterManager.AcceptingControlCopters != null && _copterManager.AcceptingControlCopters.Count() > 0)
await _commModuleManager.GetCommsumAsync();
}));
}
}
//打开校准界面
private ICommand _CalibrationSingleCommand;
public ICommand CalibrationSingleCommand
@ -902,52 +649,8 @@ namespace Plane.FormationCreator.ViewModels
foreach (string name in paramlist.Keys)
{
float value = float.Parse( paramlist[name].ToString());
//写5次
for (int i = 0; i < 5; i++)
{
if (_copterManager.AcceptingControlCopters.Count() < _copterManager.Copters.Count)
await _commModuleManager.SetParamAsync(name, value, _copterManager.AcceptingControlCopters);
else if (_copterManager.AcceptingControlCopters.Count() == _copterManager.Copters.Count)
{
_commModuleManager.SetAllCoptersForWifi(_copterManager.Copters);
await _commModuleManager.SetParamAsync(name, value);
}
// await Task.WhenAll(_copterManager.AcceptingControlCopters.Select
// (copter => copter.SetParamAsync(name, value)));
}
await Task.Delay(2000);
//发送读取5次
for (int i = 0; i < 5; i++)
{
if (_copterManager.AcceptingControlCopters.Count() < _copterManager.Copters.Count)
await _commModuleManager.ReadParamAsnyc(name, _copterManager.AcceptingControlCopters);
else if (_copterManager.AcceptingControlCopters.Count() == _copterManager.Copters.Count)
await _commModuleManager.ReadParamAsnyc(name);
}
await Task.Delay(1000);
//开始检查飞机返回参数是否正确
foreach (ICopter copter in _copterManager.AcceptingControlCopters)
{
if (value != copter.RetainInt)
{
ifallok = false;
Alert.Show(copter.Id + "参数[" + name + "]设置失败,读取的值是[" + copter.RetainInt + "]", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
await Task.WhenAll(_copterManager.AcceptingControlCopters.Select
(copter => copter.SetParamAsync(name, value)));
/*
await Task.WhenAll(
@ -965,7 +668,6 @@ namespace Plane.FormationCreator.ViewModels
));
*/
}
if (ifallok)
@ -997,20 +699,11 @@ namespace Plane.FormationCreator.ViewModels
{
float paramvalue = Convert.ToSingle(ModifyParamWindow.textParamValue.Text);
int num = 0;
int writeTime = 0;
//连续写5次为了都写成功
for ( writeTime=0; writeTime<5; writeTime++)
{
if (_copterManager.AcceptingControlCopters.Count() < _copterManager.Copters.Count)
num = await _commModuleManager.SetParamAsync(paramstr, paramvalue, _copterManager.AcceptingControlCopters);
else if (_copterManager.AcceptingControlCopters.Count() == _copterManager.Copters.Count)
{
_commModuleManager.SetAllCoptersForWifi(_copterManager.Copters);
num = await _commModuleManager.SetParamAsync(paramstr, paramvalue);
}
}
Alert.Show($"广播完成! 序列号从:{num-writeTime+1}到{num}");
Alert.Show($"广播完成! 当前序列号:{num}");
}
else
{
@ -1059,7 +752,7 @@ namespace Plane.FormationCreator.ViewModels
return _TurnOffTestLightsCommand ?? (_TurnOffTestLightsCommand = new RelayCommand(async () =>
{
int num = 0;
//正式飞行
//var o = new { NTF_G_RTLOFF = 1 };
num = await _commModuleManager.SetMultipleParamAsync(
"NTF_G_RTLOFF", "1",
"FS_GCS_ENABLE", "0",
@ -1067,27 +760,7 @@ namespace Plane.FormationCreator.ViewModels
"WAYPOINT_GLED", "0",
"FS_BATT_VOLTAGE", "14.2",
"RTL_ALT","3000",
"RTL_ALT_MAX","5000",
"FC_LOG_LEVEL", "0",
"FC_LOG_TYPE", "0",
"FS_GPS_RTL", "4");
//测试飞行
/*
num = await _commModuleManager.SetMultipleParamAsync(
"NTF_G_RTLOFF", "0",
"FS_GCS_ENABLE", "1",
"NTF_G_RTKTEST", "1",
"WAYPOINT_GLED", "1",
"FS_BATT_VOLTAGE", "14.2",
"RTL_ALT", "3000",
"RTL_ALT_MAX", "5000",
"FC_LOG_LEVEL","3",
"FC_LOG_TYPE", "1",
"FS_GPS_RTL", "4"
);
*/
"RTL_ALT_MAX","5000");
Alert.Show($"广播完成! 当前序列号:{num}");
}));
}
@ -1205,8 +878,6 @@ namespace Plane.FormationCreator.ViewModels
if (packet != null && packet.Length > 0)
{
//Message.Show($"{DateTime.Now.ToString("HH:mm:ss fff")}---packet.length = {packet.Length}");
//新方案的RTK发送用于双频
int read = packet.Length;
if (read > 0)
{
@ -1221,12 +892,6 @@ namespace Plane.FormationCreator.ViewModels
}
}
}
//稳定方案的rtk发送用于单频
//_commModuleManager.SetAllCoptersForWifi(_copterManager.Copters);
//await _commModuleManager.InjectGpsDataAsync(packet, (ushort)packet.Length);
}
await Task.Delay(10).ConfigureAwait(false);
@ -1341,7 +1006,6 @@ namespace Plane.FormationCreator.ViewModels
}
}
/*
rtcm3 rtcm3 = new rtcm3();
private async Task AnalysisRendRrcmData(byte[] buffer, int length)
{
@ -1356,7 +1020,6 @@ namespace Plane.FormationCreator.ViewModels
}
await Task.Delay(1);
}
*/
private ICommand _LandCommand;
@ -1485,30 +1148,16 @@ 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());
int utchour = DateTime.UtcNow.AddSeconds(5).Hour;
int utcminute = DateTime.UtcNow.AddSeconds(5).Minute;
int utcsecond = DateTime.UtcNow.AddSeconds(5).Second;
Message.Show("开始任务");
//循环3次 发送起飞命令 避免通信问题
for (int i = 0; i < 20; i++) //20
for (int i = 0; i < 10; i++)
{
await _commModuleManager.DoMissionStartAsync(null,
MissionTime.Hour,
MissionTime.Minute,
MissionTime.Second,
await _commModuleManager.DoMissionStartAsync(utchour,
utcminute,
utcsecond,
_flightTaskManager.OriginLng,
_flightTaskManager.OriginLat
);
@ -1525,10 +1174,8 @@ namespace Plane.FormationCreator.ViewModels
}
*/
await Task.Delay(20).ConfigureAwait(false);
await Task.Delay(10).ConfigureAwait(false);
}
_copterManager.Net_LogStartMission(MissionTime_log, _flightTaskManager.OriginLng, _flightTaskManager.OriginLat);
Alert.Show("所有飞机开始执行航点任务。请勿多次开始任务!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
}));
}
@ -1596,14 +1243,6 @@ namespace Plane.FormationCreator.ViewModels
Alert.Show("作为参照的原点未设置,无法写入相对位置!", "提示");
return;
}
var _RtcmInfoViewModel = ServiceLocator.Current.GetInstance<RtcmInfoViewModel>();
if (_RtcmInfoViewModel.RtcmManager.Rtcmthreadrun)
{
Alert.Show("RTK数据正在发送将自动关闭", "提示");
await _RtcmInfoViewModel.RtcmManager.Close(_RtcmInfoViewModel.SerialPortsSelectdValue);
}
int taskcount = _flightTaskManager.Tasks.Count;
if (taskcount < 2) return;
foreach (var copter in _copterManager.AcceptingControlCopters)
@ -1629,13 +1268,6 @@ namespace Plane.FormationCreator.ViewModels
Alert.Show("作为参照的原点未设置,无法写入相对位置!", "提示");
return;
}
var _RtcmInfoViewModel = ServiceLocator.Current.GetInstance<RtcmInfoViewModel>();
if (_RtcmInfoViewModel.RtcmManager.Rtcmthreadrun)
{
Alert.Show("RTK数据正在发送将自动关闭", "提示");
await _RtcmInfoViewModel.RtcmManager.Close(_RtcmInfoViewModel.SerialPortsSelectdValue);
}
int coptercount = _copterManager.Copters.Count;
int taskcount = _flightTaskManager.Tasks.Count;
if (taskcount < 2) return;
@ -1670,19 +1302,9 @@ namespace Plane.FormationCreator.ViewModels
int taskcount = _flightTaskManager.Tasks.Count;
if (taskcount < 2) return;
var _RtcmInfoViewModel = ServiceLocator.Current.GetInstance<RtcmInfoViewModel>();
if (_RtcmInfoViewModel.RtcmManager.Rtcmthreadrun)
{
Alert.Show("RTK数据正在发送将自动关闭", "提示");
await _RtcmInfoViewModel.RtcmManager.Close(_RtcmInfoViewModel.SerialPortsSelectdValue);
}
Alert.Show("开始写入航点,飞机绿色成功红色失败!(先关灯再开灯可恢复飞机灯光)", "提示");
_commModuleManager.ClearMissionWriteState();
for (int i = 0; i < coptercount; i++)
{
//虚拟飞机不用写航点跳过
if (_copterManager.Copters[i] is FakeCopter) continue;
///写航线开始
await CollectMissions(i).ConfigureAwait(false);
}
@ -1692,7 +1314,7 @@ namespace Plane.FormationCreator.ViewModels
}
/// <summary>
/// 用通讯模块 写入航点信息
/// 收集航点信息
/// </summary>
/// <param name="i">copterIndex</param>
/// <returns></returns>
@ -1711,14 +1333,14 @@ namespace Plane.FormationCreator.ViewModels
switch (_flightTaskManager.Tasks[j].TaskType)
{
case FlightTaskType.TakeOff:
//int takeofftime = (int)(_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetAlt / 2.5 + 5);
int takeofftime = (int)(_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetAlt / 2.5 + 5);
missions.AddRange(CreateLEDMissions(_flightTaskManager.Tasks[j].SingleCopterInfos[i].LEDInfos));
missions.Add(Mission.CreateTakeoffMission(
_flightTaskManager.Tasks[j].SingleCopterInfos[i].TakeOffWaitTime, //起飞等待时间
_flightTaskManager.Tasks[j].TakeOffTime, //起飞时间
_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetLat - _flightTaskManager.OriginLat, //位置没用
_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetLng - _flightTaskManager.OriginLng, //位置没用
_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetAlt - groudAlt) //下一个航点的高度
_flightTaskManager.Tasks[j].SingleCopterInfos[i].TakeOffWaitTime,
_flightTaskManager.Tasks[j].TakeOffTime,
_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetLat - _flightTaskManager.OriginLat,
_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetLng - _flightTaskManager.OriginLng,
_flightTaskManager.Tasks[j + 1].SingleCopterInfos[i].TargetAlt - groudAlt)
);
break;
@ -1735,7 +1357,6 @@ namespace Plane.FormationCreator.ViewModels
double Lat = _flightTaskManager.Tasks[j].SingleCopterInfos[i].TargetLat - _flightTaskManager.OriginLat;
double Lng = _flightTaskManager.Tasks[j].SingleCopterInfos[i].TargetLng - _flightTaskManager.OriginLng;
//如果是返航点,位置写入固定值,这样直接返回起飞点
if (_flightTaskManager.Tasks[j].SingleCopterInfos[i].IsLandWaypoint)
{
Lat = 90;
@ -1750,6 +1371,11 @@ namespace Plane.FormationCreator.ViewModels
_flightTaskManager.Tasks[j].SingleCopterInfos[i].TargetAlt - groudAlt)
);
break;
case FlightTaskType.Loiter:
break;
case FlightTaskType.ReturnToLand:
missions.Add(Mission.CreateReturnToLaunchMission());
break;
case FlightTaskType.Land:
missions.AddRange(CreateLEDMissions(_flightTaskManager.Tasks[j].SingleCopterInfos[i].LEDInfos));
@ -1762,38 +1388,20 @@ namespace Plane.FormationCreator.ViewModels
break;
}
}
//186是通讯模块的限制--张伟那边
if (missions.Count > 186)
{
Message.Show($"飞机:{_copterManager.Copters[i].VirtualId} 航点数量超过186请减少再重写该飞机!");
}
else
{
//虚拟ID在排序时已经变为ID了直接按ID写入
// var targetCopter = _copterManager.Copters.FirstOrDefault(o => o.VirtualId == (i+1));
// bool result = await _commModuleManager.WriteMissionListAsync(targetCopter, missions);
bool result = await _commModuleManager.WriteMissionListAsync(_copterManager.Copters[i], missions);
var targetCopter = _copterManager.Copters.FirstOrDefault(o => o.VirtualId == (i+1));
bool result = await _commModuleManager.WriteMissionListAsync(short.Parse(targetCopter.Id), missions);
//CommWriteMissinState state = new CommWriteMissinState(result);
//_commModuleManager.missionWriteState.Add(int.Parse(_copterManager.Copters[i].Id), state);
if (!result)
{
if (_copterManager.SortType == CopterManager.CopterSortType.ByVID)
Message.Show($"飞机:{_copterManager.Copters[i].VirtualId} 通信模块传输失败!");
else
Message.Show($"飞机:{_copterManager.Copters[i].Id} 通信模块传输失败!");
}
else
{
if (_copterManager.SortType == CopterManager.CopterSortType.ByVID)
Message.Show($"飞机:{_copterManager.Copters[i].VirtualId} 通信模块传输完成!");
else
Message.Show($"飞机:{_copterManager.Copters[i].Id} 通信模块传输完成!");
}
await Task.Delay(500).ConfigureAwait(false);
}
}
catch (Exception ex)
{
Message.Show(ex.ToString());
@ -1806,38 +1414,13 @@ namespace Plane.FormationCreator.ViewModels
List<IMission> missions = new List<IMission>();
foreach (LEDInfo ledInfo in LEDInfos)
{
float ledinterval=0;
Color color = (Color)ColorConverter.ConvertFromString("#" + ledInfo.LEDRGB);
int ledMode = ledInfo.LEDMode;
//拉烟任务模式ID是50需要改为50
if (_copterManager.FC_VER_NO == 1)
{
//老版本是闪烁频率,且不能为小数
ledinterval = ledInfo.LEDInterval;
//老版本ledMode == 8 对应拉烟飞控对应50,ledinterval对应通道号
if (ledMode==8) ledMode = 50;
}
else
{
//新版本飞控 是闪烁间隔单位是100ms地面站还是频率可以有1位小数,用户输入0.5hz 飞控应该是(1/0.5)*10=20
ledinterval = (1 / ledInfo.LEDInterval);
//新版本 ledMode=16是抛物飞控对应50ledinterval对应10 --固定的
if (ledMode == 16)
{
ledMode = 50;
ledinterval = 10;
}
else //新版本ledMode == 15 对应拉烟飞控对应50,ledinterval对应通道号
if (ledMode == 15)
{
ledMode = 50;
}
}
if (ledMode == 8) ledMode = 50;
IMission LEDMission = Mission.CreateLEDControlMission(
(int)(ledInfo.Delay * 10),
ledMode,
ledinterval,
ledInfo.LEDRate,
0, //ledInfo.LEDTimes,
color.R,
color.G,

View File

@ -21,7 +21,6 @@ using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Linq;
using Plane.Windows.Messages;
using Plane.Collections;
namespace Plane.FormationCreator.ViewModels
{
@ -93,12 +92,6 @@ namespace Plane.FormationCreator.ViewModels
get { return _IntervalNum; }
set { Set(nameof(IntervalNum), ref _IntervalNum, value); }
}
private int _RowNum;
public int RowNum
{
get { return _RowNum; }
set { Set(nameof(RowNum), ref _RowNum, value); }
}
private int _ContinuousNum;
public int ContinuousNum
@ -117,19 +110,6 @@ namespace Plane.FormationCreator.ViewModels
public ObservableCollection<string[]> CopterGroups { get; } = new ObservableCollection<string[]>();
private int getNextcopterindex( int currindex)
{
//每行数量
int colcount = _flightTaskManager.ColumnCount;
int newind = currindex;
for (int i = 0;i< IntervalNum;i++)
{
newind +=1;
if ((newind % colcount) == 0)
newind += RowNum * colcount;
}
return newind;
}
private ICommand _IntervalSelectCoptersCommand;
public ICommand IntervalSelectCoptersCommand
@ -145,21 +125,6 @@ namespace Plane.FormationCreator.ViewModels
_copterManager.Select(null);
int index = _copterManager.Copters.IndexOf(copter);
_copterManager.shiftkeydown = true;
int colcount = _flightTaskManager.ColumnCount;
for (; index < _copterManager.Copters.Count; index= getNextcopterindex( index) )
{
for (int i = 0; i < ContinuousNum; i++)
{
if (index >= _copterManager.Copters.Count) break;
_copterManager.Select(_copterManager.Copters[index]);
index += 1;
if ((index % colcount) == 0)
index += RowNum * colcount;
getNextcopterindex(index);
}
}
/*
for (; index < _copterManager.Copters.Count; index += IntervalNum)
{
for (int i = 0; i < ContinuousNum; i++)
@ -169,7 +134,6 @@ namespace Plane.FormationCreator.ViewModels
index++;
}
}
*/
_copterManager.shiftkeydown = false;
}));
@ -195,44 +159,6 @@ namespace Plane.FormationCreator.ViewModels
}
}
private ICommand _SortbyVIdCommand;
public ICommand SortbyVIdCommand
{
get
{
return _SortbyVIdCommand ?? (_SortbyVIdCommand = new RelayCommand( () =>
{
_copterManager.SortType = CopterManager.CopterSortType.ByVID;
//强制刷新飞机显示
// _copterManager.Copters.ForEach(copter => copter.RefreashLoc());
}));
}
}
private ICommand _SortbyIdCommand;
public ICommand SortbyIdCommand
{
get
{
return _SortbyIdCommand ?? (_SortbyVIdCommand = new RelayCommand(() =>
{
_copterManager.SortType = CopterManager.CopterSortType.ByID;
//强制刷新飞机显示
// _copterManager.Copters.ForEach(copter => copter.RefreashLoc());
}));
}
}
private ICommand _ShowAllCoptersCommand;
public ICommand ShowAllCoptersCommand
{
@ -247,31 +173,25 @@ namespace Plane.FormationCreator.ViewModels
}
}
bool showVirtualId = false;
private ICommand _ShowAllIDCommand;
public ICommand ShowAllIDCommand
private ICommand _SwitchIdVirtualIdCommand;
public ICommand SwitchIdVirtualIdCommand
{
get
{
return _ShowAllIDCommand ?? (_ShowAllIDCommand = new RelayCommand(() =>
return _SwitchIdVirtualIdCommand ?? (_SwitchIdVirtualIdCommand = new RelayCommand(async () =>
{
_copterManager.SortType = CopterManager.CopterSortType.ByVIDShowAll;
//强制刷新飞机显示
// _copterManager.Copters.ForEach(copter => copter.RefreashLoc());
showVirtualId = !showVirtualId;
foreach (var copter in _copterManager.Copters)
{
copter.DisplayVirtualId = showVirtualId;
}
await Task.Delay(10);
}));
}
}
private ICommand _AddVirtualCopterCommand;
public ICommand AddVirtualCopterCommand
{
@ -280,10 +200,10 @@ namespace Plane.FormationCreator.ViewModels
return _AddVirtualCopterCommand ?? (_AddVirtualCopterCommand = new RelayCommand<int>(async addcount =>
{
//给第三方时候限制数量用
// if (_copterManager.Copters.Count() >= VersionControl.CopterUpperLimit)
/// {
// return;
// }
if (_copterManager.Copters.Count() >= VersionControl.CopterUpperLimit)
{
return;
}
var center = _mapManager.Center;
string id;
@ -303,14 +223,13 @@ namespace Plane.FormationCreator.ViewModels
//内蒙地区
// if (center.Lat < 37.4307185218 || center.Lat > 45.6754821756
// || center.Lng < 97.3493089056 || center.Lng > 115.8006783856)
// return ;
// if (center.Lat < 37.4307185218 || center.Lat > 45.6754821756
// || center.Lng < 97.3493089056 || center.Lng > 115.8006783856)
// return ;
LatLng? colLatLng = new LatLng(center.Lat, center.Lng);
LatLng? colLatLng = new LatLng(center.Lat, center.Lng); ;
for (int i = 0; i < addcount; ++i, ++_virtualCopterId)
{
@ -328,7 +247,7 @@ namespace Plane.FormationCreator.ViewModels
else
{
if (currcol < colnum)
targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Value.Lat, colLatLng.Value.Lng , orientation + 90, (currcol * coldis));
targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Value.Lat, colLatLng.Value.Lng , orientation + 90, currcol * coldis);
else
{
currrow++;
@ -338,17 +257,7 @@ namespace Plane.FormationCreator.ViewModels
colheadLatLng = targetLatLng;
}
/*
//随机位置偏差40cm
Random r1 = new Random();
float rdrad= ((float)r1.Next(0, 360));
float rddis = ((float)r1.Next(-40, 40) / 100.0f);
targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(targetLatLng.Item1, targetLatLng.Item2, rdrad, rddis);
*/
_lastVirtualCopterLocation = new LatLng(targetLatLng.Item1, targetLatLng.Item2);
_lastVirtualCopterLocation= new LatLng(targetLatLng.Item1, targetLatLng.Item2);
}
currcol++;
@ -362,8 +271,7 @@ namespace Plane.FormationCreator.ViewModels
*/
if (_copterManager.EnAddCopter_Fake())
{
var copter = new FakeCopter(SynchronizationContext.Current);
copter.SetProperties(
latitude: _lastVirtualCopterLocation.Value.Lat,
@ -371,19 +279,11 @@ namespace Plane.FormationCreator.ViewModels
id: id,
name: id
);
if (_copterManager.FC_VER_NO >= 3)
copter.FlightControlMode = 1;
else copter.FlightControlMode = 0;
//不再预先分配VID
// copter.VirtualId = _virtualCopterId;
await copter.ConnectAsync();
await copter.GetCopterDataAsync();
_copterManager.Copters.AddCopter(copter);
_copterManager.CopterStatus.Add(false);
_copterManager.Copters.AddCopter(copter, _copterManager.SortType);
}
}
if (_flightTaskManager.OriginLat == 0 && _flightTaskManager.OriginLng == 0)
_flightTaskManager.SetOriginal();
}));
}
}
@ -456,8 +356,6 @@ namespace Plane.FormationCreator.ViewModels
return _ClearCoptersCommand ?? (_ClearCoptersCommand = new RelayCommand(async () =>
{
_flightTaskManager.Pause();
await _copterManager.ClearCopters();
/*
foreach (var copter in _copterManager.Copters)
{
await copter.DisconnectAsync();
@ -465,19 +363,12 @@ namespace Plane.FormationCreator.ViewModels
await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
_copterManager.Copters.Clear();
_copterManager.CopterStatus.Clear();
*/
_mapManager.ClearCopters();
_view3DManager.ClearCopters();
_flightTaskManager.ClearTasks();
// UdpServerConnectionManager.Instance.ClearConnections();
//UdpServerConnectionManager.Instance.ClearConnections();
_virtualCopterId = 1;
_lastVirtualCopterLocation = null;
_flightTaskManager.OriginLat = 0;
_flightTaskManager.OriginLng = 0;
_flightTaskManager.ObserverLat = 0;
_flightTaskManager.ObserverLng = 0;
}));
}
}

View File

@ -1,123 +0,0 @@
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.Practices.ServiceLocation;
using Plane.FormationCreator.Formation;
using Plane.FormationCreator.Util;
using Plane.FormationCreator.Views;
using Plane.Util;
using Plane.Windows.Messages;
using System;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace Plane.FormationCreator.ViewModels
{
/// <summary>
/// This class contains properties that a View can data bind to.
/// <para>
/// See http://www.galasoft.ch/mvvm
/// </para>
/// </summary>
public class LoginViewModel : ViewModelBase
{
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
private MainViewModel _MainViewModel=ServiceLocator.Current.GetInstance<MainViewModel>();
/// <summary>
/// Initializes a new instance of the LoginViewModel class.
/// </summary>
public LoginViewModel()
{
Username = VersionControl.Username;
SavePassword = VersionControl.IssavePassword;
if (SavePassword)
Password = VersionControl.Password;
}
private string _Username="";
public string Username
{
get { return _Username; }
set
{
Set(nameof(Username), ref _Username, value);
}
}
private string _Password = "";
public string Password
{
get { return _Password; }
set
{
Set(nameof(Password), ref _Password, value);
}
}
private bool _SavePassword = false;
public bool SavePassword
{
get { return _SavePassword; }
set
{
Set(nameof(SavePassword), ref _SavePassword, value);
}
}
private ICommand _ExitCommand;
public ICommand ExitCommand
{
get
{
return _ExitCommand ?? (_ExitCommand = new RelayCommand<LoginView>(wd =>
{
if (wd != null)
{
wd.Close();
}
}));
}
}
private ICommand _LoginCommand;
public ICommand LoginCommand
{
get
{
return _LoginCommand ?? (_LoginCommand = new RelayCommand<LoginView>(wd =>
{
if (Username.Trim() == "")
{
Alert.Show("请输入账号!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
if (Password == "")
{
Alert.Show("请输入密码!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
_copterManager.NetLogoin(Username.Trim(), Password, SavePassword);
if (!SavePassword) Password = "";
wd.Close();
}));
}
}
}
}

View File

@ -14,11 +14,6 @@ using Microsoft.Practices.ServiceLocation;
using System.IO;
using Newtonsoft.Json;
using Plane.Geography;
using Plane.FormationCreator.Views;
using System.Windows;
using Plane.Collections;
using Plane.Copters;
using Newtonsoft.Json.Linq;
namespace Plane.FormationCreator.ViewModels
{
@ -28,22 +23,12 @@ namespace Plane.FormationCreator.ViewModels
{
_copterListViewModel = copterListViewModel;
//状态信息
Plane.Windows.Messages.Message.ConfigureStatus(showAction: msg => this.SysStatusText = msg);
//日志信息
Plane.Windows.Messages.Message.Configure(showAction: msg => this.Message = msg);
//连接信息
Plane.Windows.Messages.Message.Configure(connectAction: connected => this.CommunicationModuleConnected = connected);
//广播是否打开
Plane.Windows.Messages.Message.Configureboard(boardportAction: opened => this.BoardcastPortOpened = opened);
this.SwitchVelocityModeButtonContent = GetSwitchVelocityModeButtonContent();
AppEx.Current.PropertyChanged += AppEx_PropertyChanged;
_copterManager.netStatusChanged += CopterManagernetStatusChanged;
ControlPanelViewModelData = ServiceLocator.Current.GetInstance<ControlPanelViewModel>();
}
private CopterListViewModel _copterListViewModel;
@ -54,8 +39,6 @@ namespace Plane.FormationCreator.ViewModels
public AppEx AppEx { get; } = AppEx.Current;
private void AppEx_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
switch (e.PropertyName)
@ -68,14 +51,6 @@ namespace Plane.FormationCreator.ViewModels
}
}
private void CopterManagernetStatusChanged(bool Logined, string status)
{
Loginstate = status;
if (Logined)
LoginDisp = "注销";
else LoginDisp = "登录";
}
private string _SwitchVelocityModeButtonContent;
public string SwitchVelocityModeButtonContent
{
@ -93,18 +68,6 @@ namespace Plane.FormationCreator.ViewModels
Logs += (Environment.NewLine + value);
}
}
private ControlPanelViewModel _controlPanelViewModelData;
public ControlPanelViewModel ControlPanelViewModelData
{
get { return _controlPanelViewModelData; }
set
{
Set(nameof(ControlPanelViewModelData), ref _controlPanelViewModelData, value);
}
}
// public ControlPanelViewModel ControlPanelViewModelData = ServiceLocator.Current.GetInstance<ControlPanelViewModel>();
private bool _CommunicationModuleConnected;
public bool CommunicationModuleConnected
@ -116,29 +79,6 @@ namespace Plane.FormationCreator.ViewModels
}
}
private bool _BoardcastPortOpened=false;
public bool BoardcastPortOpened
{
get { return _BoardcastPortOpened; }
set
{
Set(nameof(BoardcastPortOpened), ref _BoardcastPortOpened, value);
}
}
private string _SysStatusText="系统信息";
public string SysStatusText
{
get { return _SysStatusText; }
set
{
Set(nameof(SysStatusText), ref _SysStatusText, value);
}
}
private List<string> _MessageList = new List<string>();
public string Messages
@ -201,75 +141,6 @@ namespace Plane.FormationCreator.ViewModels
}
}
private string _Loginstate = "未登录";
public string Loginstate
{
get { return _copterManager.Loginstate ; }
set
{
Set(nameof(Loginstate), ref _Loginstate, value);
}
}
private ICommand _LoginCommand;
public ICommand LoginCommand
{
get
{
return _LoginCommand ?? (_LoginCommand = new RelayCommand(() =>
{
if (!_copterManager.Logined)
{
LoginView loginview = new LoginView();
loginview.ShowDialog();
}
else
{
if (_copterManager.Copters.Count() > 0)
{
if (Alert.Show("注销将导致飞机全部清除,您确定要继续吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning)
== MessageBoxResult.Cancel)
return;
}
_copterListViewModel.ClearCoptersCommand.Execute(null);
_copterManager.NetLogout();
}
}));
}
}
private ICommand _ShowModifyTaskViewCommand;
public ICommand ShowModifyTaskViewCommand
{
get
{
return _ShowModifyTaskViewCommand ?? (_ShowModifyTaskViewCommand = new RelayCommand(() =>
{
AppEx.Current.ShowModifyTaskView = true;
}));
}
}
private ICommand _HideModifyTaskViewCommand;
public ICommand HideModifyTaskViewCommand
{
get
{
return _HideModifyTaskViewCommand ?? (_HideModifyTaskViewCommand = new RelayCommand(() =>
{
AppEx.Current.ShowModifyTaskView =false;
}));
}
}
private ICommand _ShowOrHideModifyTaskViewCommand;
public ICommand ShowOrHideModifyTaskViewCommand
{
@ -289,72 +160,6 @@ namespace Plane.FormationCreator.ViewModels
set { Set(nameof(MapMode), ref _MapMode, value); }
}
private bool _b2DMapMode = true;
public bool b2DMapMode
{
get { return _b2DMapMode; }
set { Set(nameof(b2DMapMode), ref _b2DMapMode, value); }
}
private string _LoginDisp = "登录";
public string LoginDisp
{
get { return _LoginDisp; }
set { Set(nameof(LoginDisp), ref _LoginDisp, value); }
}
private ICommand _Map2DCommand;
public ICommand Map2DCommand
{
get
{
return _Map2DCommand ?? (_Map2DCommand = new RelayCommand(() =>
{
MainWindow mainw = (MainWindow)App.Current.MainWindow;
mainw.map.Visibility = System.Windows.Visibility.Visible;
mainw.map3D.Visibility = System.Windows.Visibility.Collapsed;
MapMode = 0;
b2DMapMode = true;
_flightTaskManager.TaskRun_2D = b2DMapMode; //2D模式模拟显示
//强制刷新飞机位置
_copterManager.Copters.ForEach(copter => copter.RefreashLoc());
}));
}
}
private ICommand _Map3DCommand;
public ICommand Map3DCommand
{
get
{
return _Map3DCommand ?? (_Map3DCommand = new RelayCommand(() =>
{
MainWindow mainw = (MainWindow)App.Current.MainWindow;
mainw.map.Visibility = System.Windows.Visibility.Collapsed;
mainw.map3D.Visibility = System.Windows.Visibility.Visible;
MapMode = 1;
b2DMapMode = false;
_flightTaskManager.TaskRun_2D = b2DMapMode; //3D模式模拟显示
mainw.map3D.ResetCamera();
}));
}
}
private ICommand _ChangeMapModeCommand;
public ICommand ChangeMapModeCommand
{
@ -362,29 +167,10 @@ namespace Plane.FormationCreator.ViewModels
{
return _ChangeMapModeCommand ?? (_ChangeMapModeCommand = new RelayCommand(() =>
{
MainWindow mainw =(MainWindow) App.Current.MainWindow;
if (MapMode == 0)
{
mainw.map.Visibility = System.Windows.Visibility.Collapsed;
mainw.map3D.Visibility = System.Windows.Visibility.Visible;
MapMode = 1;
b2DMapMode = false;
_flightTaskManager.TaskRun_2D = b2DMapMode; //3D模式模拟显示
}
else
{
mainw.map.Visibility = System.Windows.Visibility.Visible;
mainw.map3D.Visibility = System.Windows.Visibility.Collapsed;
MapMode = 0;
b2DMapMode = true;
_flightTaskManager.TaskRun_2D = b2DMapMode; //2D模式模拟显示
}
//强制刷新飞机位置
_copterManager.Copters.ForEach(copter => copter.RefreashLoc());
}));
}
}
@ -397,22 +183,6 @@ namespace Plane.FormationCreator.ViewModels
set { Set(nameof(OnlyImpotWaypointS), ref _OnlyImpotWaypointS, value); }
}
//导入飞机的位置
private bool _isimpCopterLoc =true;
public bool isimpCopterLoc
{
get { return _isimpCopterLoc; }
set { Set(nameof(isimpCopterLoc), ref _isimpCopterLoc, value); }
}
//导出飞机和航点等
private ICommand _ExportTasksCommand;
public ICommand ExportTasksCommand
{
@ -425,7 +195,7 @@ namespace Plane.FormationCreator.ViewModels
Alert.Show("作为参照的原点未设置,无法导出相对位置!", "提示");
return;
}
bool isToMeter = false;
var dialog = new SaveFileDialog
{
DefaultExt = "fcgm",
@ -435,16 +205,11 @@ namespace Plane.FormationCreator.ViewModels
{
IEnumerable<object> taskObject;
string extension = Path.GetExtension(dialog.FileName);
isToMeter = (extension == ".fcgm");
if (isToMeter)
if (extension == ".fcgm")
taskObject = _flightTaskManager.ExportTasksToMeter();
else
taskObject = _flightTaskManager.ExportTasks();
string exportedText;
if (OnlyImpotWaypointS)
@ -454,15 +219,11 @@ namespace Plane.FormationCreator.ViewModels
else
{
var groupObject = _groupManager.ExportGroups();
var locateObject = ExportLocate(isToMeter);
var locateObject = ExportLocate();
object obj = new
{
ID="flycube.com",
ver = "2.0",
coptercount = _copterManager.Copters.Count,
taskcount = _flightTaskManager.Tasks.Count,
groups = groupObject,
locate = locateObject,
tasks = taskObject
@ -479,41 +240,21 @@ namespace Plane.FormationCreator.ViewModels
}
}
private List<object> ExportLocate(bool isToMeter)
private List<object> ExportLocate()
{
List<object> locateList = new List<object>();
foreach (var copter in _copterManager.Copters)
{
double[] locate = new double[3];
if (isToMeter)
{
double x = GeographyUtils.CalcDistance(_flightTaskManager.OriginLat, _flightTaskManager.OriginLng, 0,
_flightTaskManager.OriginLat, copter.Longitude, 0);
if (copter.Longitude < _flightTaskManager.OriginLng) x = -x;
double y = GeographyUtils.CalcDistance(_flightTaskManager.OriginLat, _flightTaskManager.OriginLng, 0,
copter.Latitude, _flightTaskManager.OriginLng, 0);
if (copter.Latitude < _flightTaskManager.OriginLat) y = -y;
locate[0] = x;
locate[1] = y;
}
else
{
//为了和老版本兼容
locate[1] = copter.Longitude - _flightTaskManager.OriginLng;
locate[0] = copter.Latitude - _flightTaskManager.OriginLat;
}
locate[1] = copter.Longitude - _flightTaskManager.OriginLng;
locate[2] = copter.GroundAlt;
locateList.Add(locate);
}
return locateList;
}
private int _txtStarindex = 0;
public int txtStarindex
{
@ -528,7 +269,6 @@ namespace Plane.FormationCreator.ViewModels
set { Set(nameof(txtendindex), ref _txtendindex, value); }
}
//导入航点
private ICommand _ImportTasksCommand;
public ICommand ImportTasksCommand
{
@ -550,8 +290,7 @@ namespace Plane.FormationCreator.ViewModels
{
string extension = Path.GetExtension(dialog.FileName);
bool isMeter = extension == ".fcgm";
int _startindex = txtStarindex;
int _endindex = txtendindex;
@ -561,31 +300,10 @@ namespace Plane.FormationCreator.ViewModels
dynamic taskinfo = null;
if (importInfo is Newtonsoft.Json.Linq.JObject)
{
int ? filecoptercount = importInfo.coptercount;
string ver = importInfo.ver;
string ID = importInfo.ID;
if ((ID!=null)&&(ID!="flycube.com"))
{
Alert.Show($"文件格式不正确", "提示");
return;
}
if ((filecoptercount != null)&&(filecoptercount != _copterManager.Copters.Count ))
{
Alert.Show($"导入的飞机数量不符!导入飞机{filecoptercount},实际飞机{ _copterManager.Copters.Count}", "提示");
return;
}
taskinfo = importInfo.tasks;
if (importInfo.locate != null)
{
//老版本无论是fcgm还是fcg格式这个地方都存的经纬差新版fcgm才用米为单位保存
if ((ver != null) && (ver == "2.0"))
ImportCoptersLocate(importInfo.locate, isMeter);
else
ImportCoptersLocate(importInfo.locate, false);
ImportCoptersLocate(importInfo.locate);
}
if (importInfo.groups != null)
{
@ -599,21 +317,8 @@ namespace Plane.FormationCreator.ViewModels
//int task Newtonsoft.Json.Linq.JArray
if (taskinfo.Count == 0)
{
Alert.Show($"导入的文件没有飞行任务!", "提示");
return;
}
if ((taskinfo[0].singleCopterInfos.Count != _copterManager.Copters.Count))
{
Alert.Show($"导入的飞机数量不符!导入飞机{taskinfo[0].singleCopterInfos.Count},实际飞机{ _copterManager.Copters.Count}", "提示");
return;
}
string extension = Path.GetExtension(dialog.FileName);
bool isMeter = extension == ".fcgm";
if ((txtStarindex == 0) && (txtendindex == 0))
@ -632,7 +337,6 @@ namespace Plane.FormationCreator.ViewModels
}
// Alert.Show("导入完成!", "提示");
}));
}
}
@ -707,53 +411,15 @@ namespace Plane.FormationCreator.ViewModels
}
}
private void ImportCoptersLocate(dynamic coptersLocate,bool isMeter)
private void ImportCoptersLocate(dynamic coptersLocate)
{
//if (Newtonsoft.Json.Linq.JArray)
try
{
int index = 0;
bool loadxyLocate = isimpCopterLoc;
foreach (var locate in coptersLocate)
{
_copterManager.Copters[index].GroundAlt = Convert.ToSingle(locate[2]);
//虚拟飞机将读入保存时的位置
if (loadxyLocate&&(_copterManager.Copters[index] is FakeCopter))
{
var fc = _copterManager.Copters[index] as FakeCopter;
if (isMeter)
{
Tuple<double, double> observationLatLng = null;
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
_flightTaskManager.OriginLat,
_flightTaskManager.OriginLng,
90,
Convert.ToSingle(locate[0]));
double TargetLng = observationLatLng.Item2;
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
_flightTaskManager.OriginLat,
_flightTaskManager.OriginLng,
0,
Convert.ToSingle(locate[1]));
double TargetLat = observationLatLng.Item1;
fc.SetProperties(
latitude: TargetLat,
longitude: TargetLng
);
}else
{
double TargetLng = _flightTaskManager.OriginLng + Convert.ToSingle(locate[1]);
double TargetLat = _flightTaskManager.OriginLat + Convert.ToSingle(locate[0]);
fc.SetProperties(
latitude:TargetLat,
longitude: TargetLng
);
}
}
index++;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,5 @@
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.Practices.ServiceLocation;
using Plane.CommunicationManagement;
using Plane.FormationCreator.Formation;
using Plane.Windows.Messages;
using System;
@ -10,7 +8,6 @@ using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace Plane.FormationCreator.ViewModels
@ -20,41 +17,9 @@ namespace Plane.FormationCreator.ViewModels
private RtcmManager _rtcmManager;
public RtcmManager RtcmManager { get { return _rtcmManager; } }
//方式
public ObservableCollection<string> serialPorts { get; } = new ObservableCollection<string>();
private CommModuleManager _commModuleManager = CommModuleManager.Instance;
public string BoardPortsStatus
{
get
{
return _commModuleManager.BoardPortStatusStr;
}
}
private ControlPanelViewModel ControlPanelVM = ServiceLocator.Current.GetInstance<ControlPanelViewModel>();
public void SetRTKStatestr()
{
string rtksstr = "";
// ResendToCom
if (_rtcmManager.Rtcmthreadrun)
{
rtksstr = "RTK发送中 ";
if (_rtcmManager.SmallRtcmData)
rtksstr += ",低带宽模式 ";
if (_rtcmManager.ResendToCom && _commModuleManager.Recomisopen)
rtksstr += ",双通道模式 ";
rtksstr += "...";
}
else
rtksstr = "RTK未发送";
ControlPanelVM.RTKState = rtksstr;
}
private string _serialPortsSelectdValue;
public string SerialPortsSelectdValue
{
@ -64,57 +29,15 @@ namespace Plane.FormationCreator.ViewModels
}
private bool _smalldatamk;
public bool SmalldataMK
{
get { return _smalldatamk; }
set
{
Set(nameof(SmalldataMK), ref _smalldatamk, value);
_rtcmManager.SmallRtcmData= value;
}
}
private bool _resendtocommk=true;
public bool ResendToComMK
{
get { return _resendtocommk; }
set
{
if (value)
{
//发送
if (_commModuleManager.last_reserialport == "")
{
Alert.Show($"先在设置里打开广播端口", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
}else
if (!_commModuleManager.Recomisopen)
{
Alert.Show($"广播端口未打开,无法发送", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
Set(nameof(ResendToComMK), ref _resendtocommk, value);
_rtcmManager.ResendToCom = value;
}
}
public RtcmInfoViewModel(RtcmManager rtcmManager)
{
_rtcmManager = rtcmManager;
serialPorts.Add("魔方基站");
serialPorts.Add("千寻");
string[] commports = _rtcmManager.GetPortNames();
foreach (var item in commports)
{
serialPorts.Add(item);
}
serialPorts.Add("千寻");
SerialPortsSelectdValue = serialPorts[0];
}
@ -124,13 +47,12 @@ namespace Plane.FormationCreator.ViewModels
{
string lastSelectValue = SerialPortsSelectdValue;
serialPorts.Clear();
serialPorts.Add("魔方基站");
serialPorts.Add("千寻");
string[] commports = _rtcmManager.GetPortNames();
foreach (var item in commports)
{
serialPorts.Add(item);
}
serialPorts.Add("千寻");
if (serialPorts.Contains(lastSelectValue))
SerialPortsSelectdValue = lastSelectValue;
}
@ -142,13 +64,10 @@ namespace Plane.FormationCreator.ViewModels
{
return _ConnectRtcmCommand ?? (_ConnectRtcmCommand = new RelayCommand(async() =>
{
//是否转发到特定端口
string resendserial = "";
_rtcmManager.ResendToCom = ResendToComMK;
if (!_rtcmManager.Rtcmthreadrun)
await _rtcmManager.Open(SerialPortsSelectdValue);
else
await _rtcmManager.Close(SerialPortsSelectdValue);
await _rtcmManager.Close();
}));
}
}

View File

@ -42,9 +42,8 @@ namespace Plane.FormationCreator.ViewModels
{
get
{
return _ClearTasksCommand ?? (_ClearTasksCommand = new RelayCommand(async () =>
return _ClearTasksCommand ?? (_ClearTasksCommand = new RelayCommand(() =>
{
await _flightTaskManager.ResetTasks();
_flightTaskManager.ClearTasks();
}));
}
@ -66,54 +65,6 @@ namespace Plane.FormationCreator.ViewModels
}
}
private ICommand _renametaskCommand;
public ICommand renametaskCommand
{
get
{
return _renametaskCommand ?? (_renametaskCommand = new RelayCommand( () =>
{
FlightTask task = _flightTaskManager.SelectedTask;
if ((task==null) ||(task.TaskType != FlightTaskType.FlyTo)) return;
string newName = task.TaskCnName;
if (PlaneMessageBox.OnShow("请输入新的名称", "重命名", ref newName))
{
task.TaskCnName = newName;
}
}));
}
}
private ICommand _DelTaskCommand;
public ICommand DelTaskCommand
{
get
{
return _DelTaskCommand ?? (_DelTaskCommand = new RelayCommand(() =>
{
// _flightTaskManager
// FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
_flightTaskManager.DelSelectedTask();
}));
}
}
private ICommand _SetOriginCommand;
public ICommand SetOriginCommand
{

View File

@ -51,16 +51,6 @@ namespace Plane.FormationCreator.ViewModels
case nameof(FlightTaskManager.SelectedTaskIndex):
SelectTask();
break;
case nameof(FlightTaskManager.RightSelectedTaskIndex): // 单击右键触发清除航点
int taskIndexTmp = Math.Abs(_flightTaskManager.RightSelectedTaskIndex);
if (_flightTaskManager.Tasks[taskIndexTmp].IsRightSelected)
{
if (waypointGroup == null) waypointGroup = new Model3DGroup();
waypointGroup.Children.Clear();
}
else SelectTask();
break;
default:
break;
}
@ -93,7 +83,6 @@ namespace Plane.FormationCreator.ViewModels
planeModel3Ds.Clear();
planeGroup.Children.Clear();
observationLatLng = null;
SelectTask();
}
private void Copter_LocationChanged(object sender, EventArgs e)
@ -110,18 +99,19 @@ namespace Plane.FormationCreator.ViewModels
}
private Dictionary<ICopter, GeometryModel3D> planeModel3Ds = new Dictionary<ICopter, GeometryModel3D>();
private Tuple<double, double> observationLatLng = null;
Tuple<double, double> observationLatLng = null;
//得到观测位置
//observationLatLng 观察点坐标,第一列的中间再往前2个中间距离)
//观测点的位置放到最后排飞机的中间位置
private void getobservationpos()
private void AddOrMove3DCopter(ICopter copter)
{
observationLatLng = new Tuple<double, double>(_flightTaskManager.ObserverLat, _flightTaskManager.ObserverLng);
/*
//var copternum1 = _copterManager.Copters.FirstOrDefault();
if (_flightTaskManager.OriginLat == 0 || _flightTaskManager.OriginLng == 0)
return;
//第一列到中间的距离
float midColDistance = (_flightTaskManager.ColumnCount - 1) * _flightTaskManager.ColumnDistance / 2;
if (observationLatLng == null)
{
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
_flightTaskManager.OriginLat,
_flightTaskManager.OriginLng,
@ -131,67 +121,42 @@ namespace Plane.FormationCreator.ViewModels
observationLatLng.Item1,
observationLatLng.Item2,
_flightTaskManager.Orientation + 180,
midColDistance * 4);
*/
midColDistance * 2);
}
private void AddOrMove3DCopter(ICopter copter)
{
if (_flightTaskManager.TaskRun_2D) return; //不在3D模式运行直接退出
//var copternum1 = _copterManager.Copters.FirstOrDefault();
if (_flightTaskManager.OriginLat == 0 || _flightTaskManager.OriginLng == 0)
return;
//得到观测位置
if (observationLatLng == null)
{
getobservationpos();
}
//没有这架飞机就加入
if (!planeModel3Ds.ContainsKey(copter))
{
//观测点的位置放到最后排飞机的中间位置
var meshBuilderwaypoint = new MeshBuilder(false, false);
//meshBuilderwaypoint.AddTriangle(new Point3D(-0.1, -0.1, 0), new Point3D(0.1, -0.1, 0), new Point3D(0, 0.2, 0));
//飞机点的大小形状
meshBuilderwaypoint.AddSphere(new Point3D(0, 0, 0), 0.3* _copterManager.scale3d);
meshBuilderwaypoint.AddSphere(new Point3D(0, 0, 0), 0.2);
var meshwaypoint = meshBuilderwaypoint.ToMesh(true);
//离观测点距离y
double y = GeographyUtils.CalcDistance(0, observationLatLng.Item1, 0, 0, copter.Latitude, 0) / 2;
if (observationLatLng.Item1 > copter.Latitude) y = -y;
//离观测点距离x
double x = GeographyUtils.CalcDistance(observationLatLng.Item2, 0, 0, copter.Longitude, 0, 0) / 2;
if (observationLatLng.Item2 > copter.Longitude) x = -x;
//离观测点距离z
double z = copter.Altitude + 0.1;
x *= _copterManager.scale3d;
y *= _copterManager.scale3d;
z *= _copterManager.scale3d;
Color color ;
if (copter.LEDColor != null && copter.LEDColor != "")
color = (Color)ColorConverter.ConvertFromString("#" + copter.LEDColor);
else
color = (Color)ColorConverter.ConvertFromString("#" + CopterManager.CopterDefaultColor);
var model3D = new GeometryModel3D
{
Geometry = meshwaypoint,
Transform = new TranslateTransform3D(x, y, z),
Material = new DiffuseMaterial(new SolidColorBrush(color)),
//Material = MaterialHelper.CreateMaterial(color),
// BackMaterial = MaterialHelper.CreateMaterial(color)
Transform = new TranslateTransform3D(x, y, copter.Altitude + 0.1),
Material = MaterialHelper.CreateMaterial(Color.FromRgb(238, 210, 238)),
BackMaterial = MaterialHelper.CreateMaterial(Color.FromRgb(238, 210, 238))
};
planeModel3Ds.Add(copter, model3D);
planeGroup.Children.Add(model3D);
}
//有飞机在视图里就移动位置
else
{
//计算和观测点的相对位置
double y = GeographyUtils.CalcDistance(0, observationLatLng.Item1, 0, 0, copter.Latitude, 0) / 2;
if (observationLatLng.Item1 > copter.Latitude) y = -y;
@ -202,45 +167,24 @@ namespace Plane.FormationCreator.ViewModels
x = Math.Round(x, 2);//按照四舍五入的国际标准
y = Math.Round(y, 2);
double z = Math.Round(copter.Altitude / 2, 2);
x *= _copterManager.scale3d;
y *= _copterManager.scale3d;
z *= _copterManager.scale3d;
//移动飞机到新位置
GeometryModel3D panle3D = planeModel3Ds[copter];
if (x != panle3D.Transform.Value.OffsetX || y != panle3D.Transform.Value.OffsetY || z != panle3D.Transform.Value.OffsetZ)
{
var trans = panle3D.Transform as TranslateTransform3D;
trans.OffsetX = x;
trans.OffsetY = y;
trans.OffsetZ = z;
panle3D.Transform = new TranslateTransform3D(x, y, z);
}
//设置灯光
Color color;
if (copter.LEDColor != null && copter.LEDColor != "")
{
color = (Color)ColorConverter.ConvertFromString("#" + copter.LEDColor);
Color color = (Color)ColorConverter.ConvertFromString("#" + copter.LEDColor);
panle3D.Material = MaterialHelper.CreateMaterial(color);
// panle3D.BackMaterial = MaterialHelper.CreateMaterial(color);
panle3D.BackMaterial = MaterialHelper.CreateMaterial(color);
}
/*
// Color color;
if (copter.LEDShowColor != null)
{
Color currcolor = System.Windows.Media.Color.FromArgb(
copter.LEDShowColor.A, copter.LEDShowColor.R, copter.LEDShowColor.G, copter.LEDShowColor.B);
{
((panle3D.Material as DiffuseMaterial).Brush as SolidColorBrush).Color = currcolor;
}
}
*/
}
//Message.Show("添加3D飞机" + copter.Name);
}
@ -251,20 +195,23 @@ namespace Plane.FormationCreator.ViewModels
waypointGroup.Children.Clear();
if (_flightTaskManager.SelectedTaskIndex > 0)
{
//观测点的位置放到最后排飞机的中间位置
Tuple<double, double> observationLatLng;
//得到观测位置
if (observationLatLng == null)
{
getobservationpos();
}
//列的中间位置
float midDistance = (_flightTaskManager.ColumnCount - 1) * _flightTaskManager.ColumnDistance / 2;
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
_flightTaskManager.OriginLat, _flightTaskManager.OriginLng, _flightTaskManager.Orientation + 90, midDistance);
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
observationLatLng.Item1, observationLatLng.Item2, _flightTaskManager.Orientation + 180, midDistance * 2);
//modelGroup.Children.Clear();
var meshBuilderwaypoint = new MeshBuilder(false, false);
//航点的大小形状
meshBuilderwaypoint.AddSphere(new Point3D(0, 0, 0), 0.2* _copterManager.scale3d);
meshBuilderwaypoint.AddSphere(new Point3D(0, 0, 0), 0.2);
var meshwaypoint = meshBuilderwaypoint.ToMesh(true);
var greenMaterial = MaterialHelper.CreateMaterial(Color.FromRgb(50,50,255));
var greenMaterial = MaterialHelper.CreateMaterial(Color.FromRgb(0,255,0));
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].SingleCopterInfos)
{
@ -274,16 +221,12 @@ namespace Plane.FormationCreator.ViewModels
double x = GeographyUtils.CalcDistance(observationLatLng.Item2, 0, 0, info.TargetLng, 0, 0)/2;
if (observationLatLng.Item2 > info.TargetLng) x = -x;
double z = info.TargetAlt / 2;
x *= _copterManager.scale3d;
y *= _copterManager.scale3d;
z *= _copterManager.scale3d;
waypointGroup.Children.Add(new GeometryModel3D
{
Geometry = meshwaypoint,
Transform = new TranslateTransform3D(x, y, z),
Transform = new TranslateTransform3D(x, y, info.TargetAlt/2),
Material = greenMaterial,
BackMaterial = greenMaterial
});

View File

@ -6,8 +6,8 @@
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
Title="校准" Height="329" Width="455">
<Grid Margin="0,0,0,7">
Title="校准" Height="320" Width="450">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="70*"/>
<RowDefinition Height="30*"/>
@ -25,16 +25,12 @@
</StackPanel>
<StackPanel Grid.Row="1" Margin="10,0,10,10">
<Label Content="其他" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
<Label Content="指南针" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
<WrapPanel HorizontalAlignment="Center">
<Button Content="放弃校准" Width="100" Margin="10, 0"
Command="{Binding CancelCalibrationCompassCommand}" Visibility="Collapsed"/>
<Button Content="校准指南针" Width="120"
<Button Content="开始校准" Width="100" Margin="10, 0"
Command="{Binding CalibrationCompassCommand}"/>
<Button Content="校准陀螺仪" Width="120" Margin="20, 0"
Command="{Binding CalibrationPreflightCommand}"/>
<Button Content="重启飞控" Width="100" Margin="10, 0"
Command="{Binding RestartFCCommand}"/>
<Button Content="放弃校准" Width="100" Margin="10, 0"
Command="{Binding CancelCalibrationCompassCommand}"/>
</WrapPanel>
<ProgressBar Margin="0,20" Height="18" Width="220" Value="{Binding CompassPercent, UpdateSourceTrigger=PropertyChanged}"/>

View File

@ -1,77 +0,0 @@
<Window x:Class="Plane.FormationCreator.Views.ChangePasswordView"
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:ignore="http://www.galasoft.ch/ignore"
xmlns:Helper="clr-namespace:Plane.Util"
mc:Ignorable="d ignore" Height="316.504" Width="490.433" Title="更改登录密码" ResizeMode="NoResize" WindowStartupLocation="CenterScreen"
>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Content="账号:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" />
<TextBox
Margin="10"
Width="120" VerticalContentAlignment="Center"
Text="{Binding Username, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left"
Grid.Row="0" Grid.Column="1"/>
<Label Content="原密码:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right" />
<PasswordBox
x:Name="passwordBox"
Margin="10"
Width="120"
HorizontalAlignment="Left" VerticalContentAlignment="Center" Grid.Row="1" Grid.Column="1"
PasswordChar="*"
MaxLength="20"
Helper:PasswordBoxHelper.Attach="True"
Helper:PasswordBoxHelper.Password="{Binding Path=OldPassword ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<Label Content="新密码:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Right" />
<PasswordBox
x:Name="newpasswordBox"
Margin="10"
Width="120"
HorizontalAlignment="Left" VerticalContentAlignment="Center" Grid.Row="2" Grid.Column="1"
PasswordChar="*"
MaxLength="20"
Helper:PasswordBoxHelper.Attach="True"
Helper:PasswordBoxHelper.Password="{Binding Path=NewPassword ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<Label Content="再次输入新密码:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="3" Grid.Column="0" HorizontalAlignment="Right" />
<PasswordBox
x:Name="newpasswordBox1"
Margin="10"
Width="120"
HorizontalAlignment="Left" VerticalContentAlignment="Center" Grid.Row="3" Grid.Column="1"
PasswordChar="*"
MaxLength="20"
Helper:PasswordBoxHelper.Attach="True"
Helper:PasswordBoxHelper.Password="{Binding Path=NewPassword1 ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="取消" Grid.Row="4" Grid.Column="0" Margin="10,5,10,5" Height="40" Width="80" IsCancel="True"
Command="{Binding ExitCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" />
<Button Content="更改" Grid.Row="4" Grid.Column="1" Margin="50,5,10,5" Height="40" Width="80" IsDefault="True"
Command="{Binding ChangePasswordCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" />
</Grid>
</Window>

View File

@ -1,24 +0,0 @@
using Microsoft.Practices.ServiceLocation;
using Plane.FormationCreator.ViewModels;
using System.Windows;
using System.Windows.Controls;
namespace Plane.FormationCreator.Views
{
/// <summary>
/// Description for ChangePasswordView.
/// </summary>
public partial class ChangePasswordView : Window
{
/// <summary>
/// Initializes a new instance of the ChangePasswordView class.
/// </summary>
public ChangePasswordView()
{
InitializeComponent();
ChangePasswordViewModel loginViewModel = ServiceLocator.Current.GetInstance<ChangePasswordViewModel>();
this.DataContext = loginViewModel;
}
}
}

View File

@ -1,42 +0,0 @@
<UserControl x:Class="Plane.FormationCreator.Views.ConfigVirtualIdView"
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"
mc:Ignorable="d"
BorderThickness="1"
Background="#FF2D2D2D" Width="340" Height="260" BorderBrush="#FF006595">
<Grid>
<StackPanel>
<StackPanel>
<TextBlock Margin="10,5" Text="手动编号"/>
<TextBlock Margin="10,5" Text="选中单架无人机输入虚拟ID后点击设置"/>
<StackPanel Margin="10,0" Orientation="Horizontal" HorizontalAlignment="Center">
<TextBox Margin="0,5" Width="80" VerticalAlignment="Center"
Text="{Binding SingleVirtualId}"/>
<Button Margin="10,5" Width="100" Content = "设置编号" VerticalAlignment="Center"
Command="{Binding SetSingleVirtualIdCommand}"/>
</StackPanel>
</StackPanel>
<StackPanel>
<TextBlock Margin="10,5" Text="自动编号"/>
<StackPanel Margin="10,0" >
<TextBlock Margin="0,5" TextWrapping = "Wrap" Height="auto" Text="请按顺序选择2-3架飞机分别是1号机第一行任意飞机第一列任意飞机(如只有一行不用选),自动配置前必须:1.设置行间距和列间距2.把不在正确位置的飞机手动编号"/>
<Button Margin="0,0,0,0" Width="100" Content = "自动编号" VerticalAlignment="Center"
Command="{Binding AutoLocationNumsCommand}"/>
</StackPanel>
</StackPanel>
<StackPanel Margin="5" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Margin="5" Width="95" Content = "清除编号" Command="{Binding ClearVirtualIdCommand}"/>
<Button Margin="5" Width="95" Content = "保存编号" Command="{Binding SaveVirtualIdCommand}"/>
<Button Margin="5" Width="95" Content = "读入编号" Command="{Binding LoadVirtualIdCommand}"/>
</StackPanel>
</StackPanel>
</Grid>
</UserControl>

View File

@ -1,31 +0,0 @@
using Microsoft.Practices.ServiceLocation;
using Plane.FormationCreator.ViewModels;
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.Navigation;
using System.Windows.Shapes;
namespace Plane.FormationCreator.Views
{
/// <summary>
/// ConfigVirtualIdView.xaml 的交互逻辑
/// </summary>
public partial class ConfigVirtualIdView : UserControl
{
public ConfigVirtualIdView()
{
InitializeComponent();
this.DataContext = ServiceLocator.Current.GetInstance<ConfigVirtualIdViewModel>();
}
}
}

View File

@ -7,102 +7,157 @@
xmlns:c="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:ec="clr-namespace:Plane.Windows.Controls;assembly=Plane.Windows"
mc:Ignorable="d"
Title=""
Width="565.58"
Height="325.107"
Title="连接"
Width="432.175"
Height="300.371"
WindowStartupLocation="CenterScreen"
FontFamily="Microsoft YaHei"
ResizeMode="NoResize" >
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Height="Auto" Width="Auto" >
ResizeMode="NoResize">
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid.Resources>
<Style TargetType="Label"
BasedOn="{StaticResource {x:Type Label}}">
<Setter Property="HorizontalAlignment"
Value="Right" />
<Setter Property="VerticalAlignment"
Value="Center" />
</Style>
<Style TargetType="ComboBox"
BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="HorizontalAlignment"
Value="Left" />
<Setter Property="VerticalAlignment"
Value="Center" />
<Setter Property="Width"
Value="150" />
</Style>
<Style TargetType="TextBox"
BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="HorizontalAlignment"
Value="Left" />
<Setter Property="VerticalAlignment"
Value="Center" />
<Setter Property="Width"
Value="150" />
</Style>
<Style TargetType="PasswordBox"
BasedOn="{StaticResource {x:Type PasswordBox}}">
<Setter Property="HorizontalAlignment"
Value="Left" />
<Setter Property="VerticalAlignment"
Value="Center" />
<Setter Property="MinWidth"
Value="150" />
</Style>
<Style TargetType="Button"
BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="HorizontalAlignment"
Value="Center" />
<Setter Property="VerticalAlignment"
Value="Center" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition Height="30" />
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Left"
Grid.Row="0" >
<TextBlock Margin="5" VerticalAlignment="Center" Text="ID:" />
<TextBox Width="30" VerticalContentAlignment="Center" Text="{Binding CopterNum}" Margin="5,5,5,5" />
<TextBlock Margin="5" VerticalAlignment="Center" Text="参数:" />
<TextBox Width="56" VerticalContentAlignment="Center" Text="{Binding CopterColor}" Margin="5,5,5,5"/>
<Button Content="对频" Width="67" Margin="5,5,5,5" Command="{Binding Path=WriteIdCommand}" ToolTip="ID框输入新编号" />
<Button Content="闪灯 " Width="67" Margin="5,5,5,5" Command="{Binding CommDataAsync}" ToolTip="参数为十六进制颜色"/>
<Button Content="拉烟" Width="67" Margin="5,5,5,5" Command="{Binding TestFireCommandAsync}" ToolTip="参数为通道号1-4"/>
<Button Content="抛物" Width="67" Margin="5,5,5,5" Command="{Binding TestPWMCommandAsync}" ToolTip="接入舵机控制"/>
<Button Content="功率" Width="67" Margin="5,5,5,5" Command="{Binding SetModulePowerCommand}" ToolTip="设置模块回传功率"/>
</StackPanel>
<Label Target="{Binding ElementName=txtIPs}" Visibility="Collapsed"
Content="IP" />
<TextBox Name="txtIPs"
Grid.Column="2"
AcceptsReturn="True"
MinHeight="200"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Visibility="Collapsed"
Text="{Binding IPs, UpdateSourceTrigger=PropertyChanged}" />
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Left"
HorizontalAlignment="Center"
Grid.Row="1"
Name="panel4" >
<Button Content="立体缩放" Width="90" Margin="5,5,5,5" Command="{Binding UpdateAllCopterCommand}"></Button>
<TextBlock Margin="5" VerticalAlignment="Center" Text="比例/模块号:" />
<TextBox Width="30" VerticalContentAlignment="Center" Text="{Binding scale3d}" Margin="5,5,5,5" />
<Button Content="更改密码" Width="90" Margin="5,5,5,5" Command="{Binding ChangepasswordCommand}"></Button>
<Button Content="测试模块" Width="90" Margin="5,5,5,5" Command="{Binding TestModuleCommand}" ToolTip="测试地面站通讯模块1-8"></Button>
Grid.ColumnSpan="3"
Name="panel1">
<ec:ProgressButton HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="10"
Content="连接 _TCP"
IsDefault="True"
IsProcessing="{Binding IsProcessing}"
Command="{Binding Path=ConnectCommand}" />
<ec:ProgressButton HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="10"
Content="连接 _UDP"
IsDefault="True"
IsProcessing="{Binding IsProcessing}"
Command="{Binding Path=ConnectCommand}"
CommandParameter="UDP"/>
<ec:ProgressButton HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="10"
Content="连接串口"
IsProcessing="{Binding IsProcessing}"
Command="{Binding Path=ConnectCommand}"
CommandParameter="SerialPort" />
<!--<ec:ProgressButton Name="btnConnectUdp"
Grid.Row="1"
Grid.ColumnSpan="3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="10"
Content="连接 _UDP"
IsDefault="True"
IsProcessing="{Binding IsProcessing}"
Command="{Binding Path=ConnectCommand}"
CommandParameter="UDP" />-->
<Button Content="关闭TCP" Margin="5" Command="{Binding CloseCommand}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Grid.Row="2" Name="panel7" >
<Button Content="{Binding btnBoardPortStr}" Width="115" Margin="5,5,5,5" Command="{Binding Openboardport}"/>
<ComboBox Width="90" Height="25" Foreground="White" SelectedIndex="0"
ItemsSource="{Binding serialRePorts, Mode=OneWay}"
SelectedValue="{Binding SerialPortResend}"
DropDownOpened="ComboBox_DropDownOpened"/>
<TextBlock Margin="10,5,5,5" VerticalAlignment="Center" Text="{Binding BoardPortStatusStr}" />
</StackPanel>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Left"
HorizontalAlignment="Center"
Grid.Row="2"
Grid.ColumnSpan="3"
Name="panel2">
<Button Content="通信模块状态" Margin="5" Command="{Binding Path=StateInquireCommand}"/>
<Button Content="设置总数" Margin="5" Command="{Binding Path=SendCommand}" />
<Button Content="切换写航点" Margin="5" Command="{Binding Path=ChangeWriteMissionCommand}" />
</StackPanel>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center"
Grid.Row="3"
Name="panel2" >
<TextBlock Margin="5" VerticalAlignment="Center" Text="总数:" />
<TextBox Width="45" VerticalContentAlignment="Center" Text="{Binding CopterSum}" Margin="5,5,5,5" />
<Button Content="设置总数" Width="90" Margin="5,5,5,5" Command="{Binding Path=SendCommand}" />
<Button Content="切换写航点" Width="90" Margin="5,5,5,5" Command="{Binding Path=ChangeWriteMissionCommand}" />
<Button Content="通信状态" Width="90" Margin="5,5,5,5" Command="{Binding StateInquireCommand}"/>
Grid.ColumnSpan="3">
<TextBox Margin="2,5,5,5" Width="30" Text="{Binding CopterNum}"></TextBox>
<Button Content=" 对频 " Margin="5,5,0,5" Command="{Binding Path=WriteIdCommand}" />
<Button Content="闪灯" Margin="5" Command="{Binding CommDataAsync}"/>
<Button Content="拉烟" Margin="5" Command="{Binding TestFireCommandAsync}"/>
<TextBox Width="80" Text="{Binding CopterColor}"/>
</StackPanel>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Left"
HorizontalAlignment="Center"
Grid.Row="4"
Name="panel3" >
<Button Content="空中升级" Width="90" Margin="5,5,5,5" Command="{Binding UpdateAllCopterCommand}"></Button>
<Button Content="搜索飞机" Width="90" Margin="5,5,5,5" Command="{Binding QueryAllCopterCommand}"/>
Grid.ColumnSpan="3"
Name="panel3">
<Button Content="空中升级" Margin="5" Command="{Binding UpdateAllCopterCommand}"></Button>
<Button Content="搜索飞机" Margin="5" Command="{Binding QueryAllCopterCommand}"/>
</StackPanel>
<Image Margin="0,0,0,0" x:Name="image1" Grid.RowSpan="2" Grid.Row="5" Source="/Resources/Logo_small.png" HorizontalAlignment="Left" />
<TextBlock Margin="5" Grid.Row="6" x:Name="about_ver" HorizontalAlignment="Right" VerticalAlignment="Bottom" Text="版本V2.0.1213" />
<TextBlock Margin="5" Grid.Row="7" HorizontalAlignment="Right" x:Name="about_buildtm" VerticalAlignment="Bottom" Text="编译日期2020.12.12" />
</Grid>
</c:MetroWindow>

View File

@ -16,7 +16,6 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Plane.FormationCreator.Util;
using System.Reflection;
namespace Plane.FormationCreator.Views
{
@ -42,24 +41,12 @@ namespace Plane.FormationCreator.Views
if (!VersionControl.IsFullVersion)
{
//panel1.Visibility = Visibility.Collapsed;
panel1.Visibility = Visibility.Collapsed;
panel2.Visibility = Visibility.Collapsed;
panel3.Visibility = Visibility.Collapsed;
}
CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
var version = Assembly.GetExecutingAssembly().GetName().Version;
about_ver.Text = "版本:" + version.ToString() + "(飞控兼容:" + _copterManager.FC_VER_STRING + ")";
about_buildtm .Text= "编译时间:" + System.IO.File.GetLastWriteTime(this.GetType().Assembly.Location).ToString();
//txtIPs.Focus();
}
ConnectViewModel _ConnectViewModel = ServiceLocator.Current.GetInstance<ConnectViewModel>();
private void ComboBox_DropDownOpened(object sender, EventArgs e)
{
_ConnectViewModel.RefreshPorts();
txtIPs.Focus();
}
}
}

View File

@ -12,7 +12,7 @@
d:DesignHeight="300"
d:DesignWidth="300">
<StackPanel Margin="0,0,-8,0">
<StackPanel>
<StackPanel.Resources>
<Style TargetType="Button"
BasedOn="{StaticResource {x:Type Button}}">
@ -29,121 +29,37 @@
Command="{Binding DisconnectCommand}" />
</WrapPanel>-->
<TabControl Margin="0,0,13,0">
<TabItem Header="飞行前准备">
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
<TextBlock Text="飞行控制"
Margin="5,0,0,8"/>
<WrapPanel>
<Button Content="电压检测"
Command="{Binding DetectionVoltage}" />
<Button Content="版本检测"
Command="{Binding GetVersionsCommand}" />
<Button Content="通讯版本" Command="{Binding DetectionCommModuleVersion}" />
<Button Content="统计返回"
Command="{Binding DetectionReturnData}" />
<Button Content="通讯统计"
Command="{Binding GetCommsumCommand}" />
</WrapPanel>
<WrapPanel>
<Button Content="参数设置"
Command="{Binding ParamModify}" />
<Button Content="读入参数"
Command="{Binding LoadParamfile}" />
<Button Content="状态统计" Command="{Binding ReportGPSTypeCommand}"/>
<Button Content="飞机校准"
Command="{Binding CalibrationSingleCommand}" />
<Button Content="正式参数" Command="{Binding TurnOffTestLightsCommand}" Visibility="Collapsed" />
<Button Content="电机" Visibility="Collapsed"
Command="{Binding MotorTestCommand}" />
<Button Content="删除飞机"
Command="{Binding DelCommand}" />
<Label Visibility="Collapsed" Content="Lat"/>
<TextBox Visibility="Collapsed" Text="{Binding LatOffset}" Width="50"/>
<Label Visibility="Collapsed" Content="Lng"/>
<TextBox Visibility="Collapsed" Text="{Binding LngOffset}" Width="50"/>
<Button Visibility="Collapsed" Content="设置返航点" Command="{Binding RLTOffsetCommand}" />
</WrapPanel>
<WrapPanel>
<Button Content="写入航点"
Command="{Binding WriteMissionCommand}" />
<Button Content="航点续写"
Command="{Binding WriteMissionFailedCommand}" />
<Button Content="选写航点" Command="{Binding WriteMissionSingleCommand}" />
<Button Content="统计航点"
Command="{Binding DetectionMissionData}" />
<TextBox
Grid.Column="1"
Width="55"
Margin="5, 5, 5, 5"
HorizontalContentAlignment="Right"
Text="{Binding RTKcomvalue, UpdateSourceTrigger=PropertyChanged}" Visibility="Collapsed"
/>
<Button Content="{Binding RTKbtntxt}"
Command="{Binding SendRTKCommand}" Visibility="Collapsed" />
<Button Content="{Binding NTRIPbtntxt}"
Command="{Binding SendRTCMCommand}" Visibility="Collapsed"/>
<Button Content="RTK 控制" Command="{Binding OpenRtcmManageCommand}" />
</WrapPanel>
</StackPanel>
</TabItem>
<TabItem Header="飞行控制">
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
<WrapPanel >
<Button Content="解锁"
Command="{Binding UnlockCommand}" />
<Button Content="加锁"
Command="{Binding LockCommand}" />
<Button Content="单独任务"
<Button Content="起飞" Visibility="Collapsed"
Command="{Binding TakeOffCommand}" />
<Button Content="抛物"
Command="{Binding ThrowoutCommand}" />
</WrapPanel>
<WrapPanel>
<Button Content="起飞"
Command="{Binding GuidAsyncCommand}" />
<Button Content="悬停"
Command="{Binding HoverCommand}" />
<Button Content="手动"
Command="{Binding FloatCommand}" />
<Button Content="参数"
Command="{Binding ParamModify}" />
<Button Content="参数文件" Visibility="Collapsed"
Command="{Binding LoadParamfile}" />
<Button Content="版本"
Command="{Binding GetVersionsCommand}" />
<Button Content="校准"
Command="{Binding CalibrationSingleCommand}" />
</WrapPanel>
<WrapPanel>
<Button Content="返航"
Command="{Binding ReturnToLaunchCommand}" />
<Button Content="降落"
Command="{Binding LandCommand}" />
<Button Content="上锁"
Command="{Binding LockCommand}" />
<Button Content="跳过" Visibility="Collapsed"
Command="{Binding FlagCommand}" />
<TextBox Width="50"
Visibility="Collapsed"
Text="{Binding AltP, UpdateSourceTrigger=PropertyChanged}" />
</WrapPanel>
<WrapPanel>
<Button Content="闪灯"
Command="{Binding LEDFlickerCommand}" />
<Button Content="测试" Visibility="Collapsed"
@ -154,31 +70,54 @@
<Button Content="关灯"
Command="{Binding LEDOnOffCommand}"
CommandParameter="1"/>
<TextBlock Margin="8,-3,5,0" Text="起飞高度" VerticalAlignment="Center"/>
<TextBox VerticalContentAlignment="Center" Margin="0,0,0,5" Width="30" Height="25" Text="{Binding TaskOffAlt}" />
<TextBlock Margin="5,-3,5,0" Text="米" VerticalAlignment="Center"/>
<Button Content="电机"
Command="{Binding MotorTestCommand}" />
<TextBox Width="50"
Visibility="Collapsed"
Text="{Binding AltP, UpdateSourceTrigger=PropertyChanged}" />
</WrapPanel>
</StackPanel>
</TabItem>
<TabItem Header="任务控制">
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
<WrapPanel>
<Button Content="选写航点"
Command="{Binding WriteMissionSingleCommand}" />
<Button Content="定位统计"
Command="{Binding ReportGPSTypeCommand}"/>
<Button Content="统计模块"
Command="{Binding DetectionCommModuleVersion}" />
<Button Content="正式参数"
Command="{Binding TurnOffTestLightsCommand}"
/>
<TextBlock Margin="5,0,3,0" Text="起飞高度" VerticalAlignment="Center"></TextBlock>
<TextBox Width="30" Height="26" Text="{Binding TaskOffAlt}"
/>
<Label Visibility="Collapsed">Lat</Label>
<TextBox Visibility="Collapsed" Text="{Binding LatOffset}" Width="50"/>
<Label Visibility="Collapsed">Lng</Label>
<TextBox Visibility="Collapsed" Text="{Binding LngOffset}" Width="50"/>
<Button Visibility="Collapsed" Content="设置返航点"
Command="{Binding RLTOffsetCommand}" />
</WrapPanel>
<Separator/>
<WrapPanel>
<Button Content="全部降落"
Command="{Binding AllLandCommand}" />
<Button Content="全部加锁"
Command="{Binding LockAllCommand}" />
<Button Content="检测电压"
Command="{Binding DetectionVoltage}" />
<Button Content="统计返回"
Command="{Binding DetectionReturnData}" />
<Button Content="统计航点"
Command="{Binding DetectionMissionData}" />
</WrapPanel>
<WrapPanel>
<Button Content="写入航点"
Command="{Binding WriteMissionCommand}" />
<Button Content="全部解锁"
Command="{Binding UnlockAllCommand}"
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="全部加锁"
Command="{Binding LockAllCommand}" />
</WrapPanel>
<WrapPanel>
<Button Content="开始任务"
Command="{Binding MissionStartCommand}"
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}"/>
@ -186,50 +125,67 @@
Command="{Binding MissionPauseCommand}" />
<Button Content="继续任务"
Command="{Binding MissionResumeCommand}" />
</WrapPanel>
<WrapPanel>
<Button Content="航点续写"
Command="{Binding WriteMissionFailedCommand}" />
<TextBox
Grid.Column="1"
Width="55"
Margin="5, 5, 5, 5"
HorizontalContentAlignment="Right"
Text="{Binding RTKcomvalue, UpdateSourceTrigger=PropertyChanged}"
/>
<Button Content="全部降落"
Command="{Binding AllLandCommand}" />
<Button Content="紧急返航"
Command="{Binding EmergencyRetCommand}" />
<Button Content="{Binding Path=RTKbtntxt}"
Command="{Binding SendRTKCommand}" />
<Button Content="重设任务"
Command="{Binding ResetRealMissionCommand}" />
<Button Content="{Binding Path=NTRIPbtntxt}"
Command="{Binding SendRTCMCommand}"/>
<Button Content="RTK" Command="{Binding OpenRtcmManageCommand}" />
<TextBlock
Margin="5,5,5,5"
Text="{Binding Path=RTKState}"
/>
</WrapPanel>
</StackPanel>
</TabItem>
<TabItem Header="飞行报告" Visibility="Collapsed">
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
<!--// 林俊清, 20150920, 目前不再使用 FormationController删除相关按钮。
<StackPanel Visibility="{Binding Source={x:Static fc:AppEx.Current}, Path=AppMode, Converter={StaticResource AppModeToVisibilityConverter}, ConverterParameter=ControlPanelView_Formation}">
<TextBlock Text="任务" />
<WrapPanel>
<Button Content="添加报告"
Command="{Binding UnlockAllCommand}"
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="查看报告"
Command="{Binding LockAllCommand}" />
<Button Content="飞到50米高"
Command="{Binding FlyToAltitudeCommand}"
CommandParameter="50" />
<Button Content="飞到15米高"
Command="{Binding FlyToAltitudeCommand}"
CommandParameter="15" />
<Button Content="Test"
Command="{Binding TestCommand}" />
</WrapPanel>
</StackPanel>
</TabItem>
</TabControl>
-->
<!--<WrapPanel>
<Button Content="画圈"
Command="{Binding FlyInCircleCommand}" />
<Button Content="绕队列中心画圈"
Command="{Binding FlyAroundCenterOfCoptersCommand}" />
<Button Content="Test"
Command="{Binding TestCommand}" />
<Button Content="画矩形"
Command="{Binding FlyInRectangleCommand}"
Visibility="Collapsed" />
</WrapPanel>
<WrapPanel>
<Button Content="飞到一条竖线画圈"
Command="{Binding FlyToVerticalLineAndMakeCircleCommand}" />
</WrapPanel>-->
<!--
<WrapPanel>
<Button Content="停止"
Command="{Binding StopTaskCommand}" />
</WrapPanel>
</StackPanel>-->
</StackPanel>
</UserControl>

View File

@ -7,7 +7,7 @@
mc:Ignorable="d"
d:DesignHeight="300"
BorderThickness="1"
Background="#FF2D2D2D" Width="340">
Background="#FF2D2D2D" Width="464">
<UserControl.BorderBrush>
<SolidColorBrush Color="{DynamicResource {x:Static SystemColors.ActiveBorderColorKey}}"/>
</UserControl.BorderBrush>
@ -17,7 +17,7 @@
<Label Margin="5,0,0,0" Content="属性设置" VerticalAlignment="Center"/>
<Separator></Separator>
<StackPanel Margin="5,0,0,5" Orientation="Horizontal" HorizontalAlignment="Left">
<Label Margin="0" Content="摆放高度(米)" ></Label>
<Label Margin="0" Content="摆放高度" ></Label>
<TextBox
Margin="30,0"
Width="80"

View File

@ -6,7 +6,7 @@
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
mc:Ignorable="d"
BorderThickness="1"
Background="#FF2D2D2D" Width="340" Height="300">
Background="#FF2D2D2D" Width="464" Height="300">
<UserControl.BorderBrush>
<SolidColorBrush Color="{DynamicResource {x:Static SystemColors.ActiveBorderColorKey}}"/>
</UserControl.BorderBrush>
@ -14,14 +14,14 @@
<StackPanel Orientation="Vertical">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition />
<ColumnDefinition Width="80"/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Margin="5,0" Content="分组设置" HorizontalAlignment="Left" />
<Label Margin="0,0" Grid.Column="1" Content="最后选中:" HorizontalAlignment="Left"/>
<Label Margin="0,0" Grid.Column="1" Content="{Binding GroupManager.LastSelectedGroup}" HorizontalAlignment="Right"/>
<Button Margin="0,0" Grid.Column="2" Content="添加" HorizontalAlignment="Right"
<Label Margin="15,0" Grid.Column="1" Content="最后选中:" HorizontalAlignment="Left"/>
<Label Grid.Column="1" Content="{Binding GroupManager.LastSelectedGroup}" HorizontalAlignment="Right"/>
<Button Margin="5,0" Grid.Column="2" Content="添加分组" HorizontalAlignment="Right"
Command="{Binding Path=GroupManager.AddGroupsCommand}"/>
</Grid>
<Separator></Separator>
@ -48,9 +48,9 @@
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Width="95" Text="{Binding groupName,UpdateSourceTrigger=PropertyChanged}"/>
<Button Margin="5,0,0,0" Width="65" Content="删除" Command="{Binding RemoveGroupCommand}"/>
<Button Margin="5,0,0,0" Width="65" Content="设置" Command="{Binding SetGroupCoptersCommand}"/>
<Button Margin="5,0,0,0" Width="65" Content="选中" Command="{Binding SelectCoptersCommand}"/>
<Button Margin="20,0,0,0" Width="90" Content="删除" Command="{Binding RemoveGroupCommand}"/>
<Button Margin="20,0,0,0" Width="90" Content="设置" Command="{Binding SetGroupCoptersCommand}"/>
<Button Margin="20,0,0,0" Width="90" Content="选中" Command="{Binding SelectCoptersCommand}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>

View File

@ -10,177 +10,9 @@
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"
@ -204,7 +36,7 @@
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" >
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<Style TargetType="ComboBox"
BasedOn="{StaticResource CopterInfo_ComboBox}" />
@ -214,9 +46,7 @@
<StackPanel>
<TextBlock Text="ID" />
<TextBlock Width="30" Text="{Binding Path=Id}" />
<TextBlock Text="VID" />
<TextBlock Width="30" Text="{Binding Path=VirtualId}" />
<TextBlock Text="{Binding Path=Id}" />
</StackPanel>
<StackPanel>
<TextBlock Text="已连接:" />
@ -254,19 +84,36 @@
<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="预检查状态:" />
<TextBlock Text="{Binding CopterPreCheckPassStr}"
Foreground="{Binding CopterPreCheckPass, Converter={StaticResource PrecheckToColorConverter}}" />
</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">
@ -276,13 +123,28 @@
<Style TargetType="StackPanel"
BasedOn="{StaticResource CopterInfo_StackPanel}" />
</StackPanel.Resources>
<StackPanel Visibility="Hidden">
<TextBlock Text="电压值:" />
<TextBlock Text="{Binding Path=Voltage}" />
</StackPanel>
<StackPanel>
<TextBlock Text="电压值:" />
<Slider x:Name="sldChannel3"
Width="100"
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>
@ -303,29 +165,23 @@
<TextBlock Text="{Binding Longitude}" />
</StackPanel>
<StackPanel>
<TextBlock Text="通信模块版本" />
<TextBlock Text="{Binding CommModuleVersion}" />
<TextBlock Text="通道3" />
<TextBlock Text="{Binding Channel3}" />
</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]}" />
<TextBlock Text="通道4" />
<TextBlock Text="{Binding Channel4}" />
</StackPanel>
<StackPanel>
<TextBlock Text="定位精度:" />
<TextBlock Text="{Binding GpsHdop, StringFormat=0.##}" />
</StackPanel>
<StackPanel >
<TextBlock Text="最后异常" />
<TextBlock Text="{Binding CopterErrorString}"/>
<StackPanel>
<TextBlock Text="通信模块" />
<TextBlock Text="{Binding CommModuleVersion}" />
</StackPanel>
</StackPanel>
</Grid>
</StackPanel>
</UserControl>

View File

@ -38,10 +38,10 @@ namespace Plane.FormationCreator.Views
var copter = sldChannel3.DataContext as ICopter;
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
if (copter == null || copter != selectedCopter) return; // copter != selectedCopter 说明正在切换 copter。
var vol = (ushort)e.NewValue;
if (vol<15)
var newCh3 = (ushort)e.NewValue;
if (Math.Abs(copter.Channel3 - newCh3) > 5)
{
// sldChannel3.co
await copter.SetChannelsAsync(ch3: newCh3);
}
}
catch { }

View File

@ -10,30 +10,21 @@
d:DesignHeight="600"
d:DesignWidth="300">
<UserControl.Resources>
<ContextMenu x:Key="CoptersMenu" >
<MenuItem Header="显示当前选中"
<MenuItem Header="只显示当前选中"
Foreground="White"
Command="{Binding OnlyShowSelectedCoptersCommand}"/>
<MenuItem Header="显示所有飞机"
Foreground="White"
Command="{Binding ShowAllCoptersCommand}"/>
<MenuItem Header="所有编号(虚拟排序)"
<MenuItem Header="显示自动编号"
Foreground="White"
Command="{Binding ShowAllIDCommand}"/>
<MenuItem Header="虚拟编号(虚拟排序)"
Foreground="White"
Command="{Binding SortbyVIdCommand}"/>
<MenuItem Header="真实编号(真实排序)"
Foreground="White"
Command="{Binding SortbyIdCommand}"/>
Command="{Binding SwitchIdVirtualIdCommand}"/>
</ContextMenu>
</UserControl.Resources>
<Grid Width="550">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="540"/>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
@ -69,31 +60,24 @@
</MultiBinding>
</Rectangle.Fill>
</Rectangle>
<TextBlock MaxWidth="50" Visibility="{Binding DisplayID, Converter={StaticResource BooleanToVisibilityConverter}}"
<TextBlock MaxWidth="100"
Text="{Binding Name}" />
<TextBlock Margin="2,0,0,0" MaxWidth="5" Visibility="{Binding DisplayVirtualId, Converter={StaticResource BooleanToVisibilityConverter}}"
Text="[" />
<TextBlock MaxWidth="50" Visibility="{Binding DisplayVirtualId, Converter={StaticResource BooleanToVisibilityConverter}}"
Margin="0,0,0,0"
Foreground="Yellow"
<TextBlock MaxWidth="100"
Margin="2,0,0,0"
Foreground="Red"
Text="{Binding VirtualId}" />
<TextBlock Margin="0,0,0,0" MaxWidth="5" Visibility="{Binding DisplayVirtualId, Converter={StaticResource BooleanToVisibilityConverter}}"
Text="]" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Row="1" Margin="0,5,0,5"
<StackPanel Grid.Row="1" Margin="0,0,0,5"
Orientation="Horizontal">
<Button Content="间隔选" Command="{Binding IntervalSelectCoptersCommand}"/>
<Button Content="间隔选" Command="{Binding IntervalSelectCoptersCommand}"/>
<TextBlock Text="连选数量" Margin="5,5,0,0"/>
<TextBox Width="30" Margin="5,0" VerticalContentAlignment="Center" Text="{Binding ContinuousNum}"/>
<TextBox Width="30" Margin="5,0,0,0" Text="{Binding ContinuousNum}"/>
<TextBlock Text="间隔数量" Margin="5,5,0,0"/>
<TextBox Width="30" Margin="5,0" VerticalContentAlignment="Center" Text="{Binding IntervalNum}"/>
<TextBlock Text="间隔排数" Margin="5,5,0,0"/>
<TextBox Width="30" Margin="5,0" VerticalContentAlignment="Center" Text="{Binding RowNum}"/>
<TextBox Width="30" Margin="5,0,0,0" Text="{Binding IntervalNum}"/>
<TextBlock Text="选中个数" Margin="5,5,0,0"/>
<TextBlock Width="30" Margin="5,5,0,0" Text="{Binding CopterManager.SeletedCopterCount, UpdateSourceTrigger=PropertyChanged}"/>
@ -120,7 +104,7 @@
Margin="5,0,0,0"
Command="{Binding ShowLackCopterNumsCommand}"/>
<Button Content="自动编号"
Margin="5,0,0,0" Visibility="Collapsed"
Margin="5,0,0,0"
Command="{Binding AutoLocationNumsCommand}"/>
<Button Content="设置"
Margin="5,0,5,0"

View File

@ -16,8 +16,6 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.Windows.Threading;
namespace Plane.FormationCreator.Views
{
@ -46,30 +44,6 @@ namespace Plane.FormationCreator.Views
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
private void SelectitemMessage(ICopter copter)
{
////需要访问UI线程可能在其他线程里面
Dispatcher dispatcher = Dispatcher.FromThread(Thread.CurrentThread);
if (dispatcher != null)
{
if (copter == null)
{
lvwDrones.SelectedItems.Clear();
}
else
{
if (!_copterManager.shiftkeydown)
{
lvwDrones.SelectedItems.Clear();
lvwDrones.SelectedItem = copter;
}
else
lvwDrones.SelectedItems.Add(copter);
}
}else
lvwDrones.Dispatcher.BeginInvoke(new Action(() =>
{
if (copter == null)
{
lvwDrones.SelectedItems.Clear();
@ -85,7 +59,6 @@ namespace Plane.FormationCreator.Views
lvwDrones.SelectedItems.Add(copter);
}
}));
}

View File

@ -1,30 +0,0 @@
<Window x:Class="Plane.FormationCreator.Views.InputDialog"
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:ignore="http://www.galasoft.ch/ignore"
Title="输入窗口" SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen"
ContentRendered="Window_ContentRendered" ResizeMode="NoResize">
<Grid Margin="15">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="/FGCS;component/Resources/logo_big.png" Width="40" Height="40" Grid.RowSpan="2" Margin="20,0" />
<Label Name="lblQuestion" Grid.Column="1">最低更换电压:</Label>
<TextBox Name="txtAnswer" Grid.Column="1" Grid.Row="1" MinWidth="250">15.6</TextBox>
<WrapPanel Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Right" Margin="0,15,0,0">
<Button IsDefault="True" Name="btnDialogOk" Click="btnDialogOk_Click" MinWidth="60" Margin="0,0,10,0">确定</Button>
<Button IsCancel="True" MinWidth="60">取消</Button>
</WrapPanel>
</Grid>
</Window>

View File

@ -1,31 +0,0 @@
using System;
using System.Windows;
namespace Plane.FormationCreator.Views
{
public partial class InputDialog : Window
{
public InputDialog(string question, string defaultAnswer = "")
{
InitializeComponent();
lblQuestion.Content = question;
txtAnswer.Text = defaultAnswer;
}
private void btnDialogOk_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
private void Window_ContentRendered(object sender, EventArgs e)
{
txtAnswer.SelectAll();
txtAnswer.Focus();
}
public string Answer
{
get { return txtAnswer.Text; }
}
}
}

View File

@ -1,58 +0,0 @@
<Window x:Class="Plane.FormationCreator.Views.LoginView"
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:ignore="http://www.galasoft.ch/ignore"
xmlns:Helper="clr-namespace:Plane.Util"
mc:Ignorable="d ignore" Height="253.421" Width="463.894" Title="飞行魔方地面控制中心" ResizeMode="NoResize" WindowStartupLocation="CenterScreen"
>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Content="账号:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="0" Grid.Column="0" />
<TextBox
Margin="10"
Width="120" VerticalContentAlignment="Center"
Text="{Binding Username, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left"
Grid.Row="0" Grid.Column="1"/>
<Label Content="密码:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="1" Grid.Column="0" />
<PasswordBox
x:Name="passwordBox"
Margin="10"
Width="120"
HorizontalAlignment="Left" VerticalContentAlignment="Center" Grid.Row="1" Grid.Column="1"
PasswordChar="*"
MaxLength="20"
Helper:PasswordBoxHelper.Attach="True"
Helper:PasswordBoxHelper.Password="{Binding Path=Password ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="取消" Grid.Row="2" Grid.Column="0" Margin="10,5,10,5" Height="40" Width="80" IsCancel="True"
Command="{Binding ExitCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" />
<Button Content="登录" Grid.Row="2" Grid.Column="1" Margin="50,5,10,5" Height="40" Width="80" IsDefault="True"
Command="{Binding LoginCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" />
<CheckBox x:Name="checkBox" Content="保存密码" Grid.Column="1" HorizontalAlignment="Right" Margin="0,18.033,-85.353,12.168" Grid.Row="1" Width="75.353"
IsChecked="{Binding SavePassword}"/>
<Label x:Name="about_ver" Content="版本:" HorizontalContentAlignment="Right" Margin="0,10,-85,0" Grid.Row="3" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
</Grid>
</Window>

View File

@ -1,30 +0,0 @@
using Microsoft.Practices.ServiceLocation;
using Plane.FormationCreator.Formation;
using Plane.FormationCreator.ViewModels;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
namespace Plane.FormationCreator.Views
{
/// <summary>
/// Description for LoginView.
/// </summary>
public partial class LoginView : Window
{
/// <summary>
/// Initializes a new instance of the LoginView class.
/// </summary>
public LoginView()
{
InitializeComponent();
LoginViewModel loginViewModel = ServiceLocator.Current.GetInstance<LoginViewModel>();
this.DataContext = loginViewModel;
var version = Assembly.GetExecutingAssembly().GetName().Version;
CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
about_ver.Content = "版本:" + version.ToString() + "(飞控兼容:"+ _copterManager.FC_VER_STRING + ")";
}
}
}

View File

@ -41,16 +41,16 @@
>
<CheckBox Grid.Row="0" Content="所有航点" Margin="5,5,0,0"
Click="showallpoint_Checked"
Foreground="White" IsChecked="True" Visibility="Collapsed"
/>
<CheckBox Grid.Row="0" Content="飞行航线" Margin="5,5,0,0"
Click="showpanline_Checked"
Foreground="White" IsChecked="True"
/>
<CheckBox Grid.Row="0" Content="计划航线" Margin="5,5,0,0"
Click="showpanline_Checked"
Foreground="White"
/>
<CheckBox Grid.Row="0" Content="实时航线" Margin="5,5,0,0"
Foreground="White"
Click="showrealtimeline_Checked" Visibility="Collapsed" />
Click="showrealtimeline_Checked" />
<ComboBox x:Name="MapSelectionComboBox"
HorizontalAlignment="Right"

View File

@ -41,33 +41,25 @@ namespace Plane.FormationCreator.Views
/// </summary>
public partial class MapView : UserControl
{
public void initmap()
{
gmap.MinZoom = 2; //最小缩放
gmap.MaxZoom = 30; //最大缩放
gmap.Zoom = 19; //当前缩放
gmap.ShowCenter = true; //不显示中心十字点
gmap.DragButton = MouseButton.Middle; //中键拖拽地图
}
public MapView()
{
InitializeComponent();
this.DataContext = ServiceLocator.Current.GetInstance<MapViewModel>();
gmap.MapProvider = GMapProviders.BingHybridMap; //google china 地图
initmap();
gmap.MinZoom = 2; //最小缩放
gmap.MaxZoom = 30; //最大缩放
gmap.Zoom = 19; //当前缩放
gmap.ShowCenter = false; //不显示中心十字点
gmap.DragButton = MouseButton.Middle; //左键拖拽地图
gmap.Position = new LatLng(40.07734857737275, 116.34323845862502).ToGCJ02();
_mapManager.MapView = this;
_mapManager.SetCenterGetter(() => new LatLng { Lat = gmap.Position.ToWGS84().Lat, Lng = gmap.Position.ToWGS84().Lng });
_flightTaskManager.TaskAdded += FlightTaskManager_TaskAdded;
_flightTaskManager.TaskDeled += FlightTaskManager_TaskDeled;
_flightTaskManager.OnOriginalSet += FlightTaskManager_SetOriginal;
/*
Task.Factory.StartNew(async () =>
{
int delay = 500;
@ -81,7 +73,7 @@ namespace Plane.FormationCreator.Views
await Task.Delay(delay);
}
});
*/
_copterManager.SelectedCoptersChanged += (sender, e) =>
{
//if (AppEx.Instance.CurrentMode.IsForTasks())
@ -95,18 +87,11 @@ namespace Plane.FormationCreator.Views
{
switch (e.PropertyName)
{
//选中任务时触发
case nameof(FlightTaskManager.SelectedTaskIndex):
//_copterDrawings有多少架飞机航点
foreach (var item in _copterDrawings)
{
var copterDrawing = item.Value;
//设置选中的航点白边和下面任务块的白影
copterDrawing.ShowWaypoint(_flightTaskManager.SelectedTaskIndex);
copterDrawing.SetTaskEffect(_flightTaskManager.SelectedTaskIndex);
//画计划航线
copterDrawing.ResetRoute(_flightTaskManager.SelectedTaskIndex);
}
break;
@ -140,6 +125,29 @@ namespace Plane.FormationCreator.Views
gmap.MouseDoubleClick += async (sender, e) =>
{
e.Handled = true;
//// Test
//var pos = map.ViewportPointToLocation(e.GetPosition(map));
//AddOrMoveCopter(new FakeCopter(pos.Latitude, pos.Longitude));
// 林俊清, 20150930, AppMode 存在意义已不大;只有正在运行任务的时候才不允许指点。
//if (AppEx.Current.AppMode != AppMode.ControllingCopters) return;
if (_flightTaskManager.IsPaused == false) return;
var copters = _copterManager.AcceptingControlCopters;
if (!copters.Any()) return;
Point clickPoint = e.GetPosition(gmap);
var pos = gmap.FromLocalToLatLng((int)clickPoint.X, (int)clickPoint.Y);
var centerLat = copters.Average(c => c.Latitude);
var centerLng = copters.Average(c => c.Longitude);
var latDelta = pos.Lat - centerLat;
var lngDelta = pos.Lng - centerLng;
await Task.WhenAll(copters.Select(copter => copter.FlyToAsync(copter.Latitude + latDelta, copter.Longitude + lngDelta, copter.Altitude)));
};
var center = _appConfig.Center;
@ -162,19 +170,6 @@ namespace Plane.FormationCreator.Views
originalMarker.Position = gmap.FromLocalToLatLng((int)wpPos.X, (int)wpPos.Y);
//MapLayer.SetPosition(original, gmap.ViewportPointToLocation(wpPos));
}
if (observerMarker != null && gmap.Markers.Contains(observerMarker))
{
PointLatLng location = new LatLng(_flightTaskManager.ObserverLat, _flightTaskManager.ObserverLng).ToGCJ02();
GPoint wpPos = gmap.FromLatLngToLocal(location);
//Point wpPos = gmap.LocationToViewportPoint(location);
wpPos.X -= (long)ORIGIN_RADIUS;
wpPos.Y -= (long)ORIGIN_RADIUS;
observerMarker.Position = gmap.FromLocalToLatLng((int)wpPos.X, (int)wpPos.Y);
//MapLayer.SetPosition(original, gmap.ViewportPointToLocation(wpPos));
}
};
GMapMarker rectangleMarker = null;
@ -268,9 +263,6 @@ namespace Plane.FormationCreator.Views
gmap.MouseMove += new MouseEventHandler(OriginalMove);
gmap.MouseLeftButtonUp += new MouseButtonEventHandler(OriginalMouseUp);
gmap.MouseMove += new MouseEventHandler(observerMove);
gmap.MouseLeftButtonUp += new MouseButtonEventHandler(observerMouseUp);
}
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
@ -281,7 +273,6 @@ namespace Plane.FormationCreator.Views
const string COPTER_TAG = "Copter";
const string WAYPOINT_TAG = "Waypoint";
const string ORIGINALPOINT_TAG = "Originalpoint";
const string OBSERVER_TAG = "Observerpoint";
public void Refresh()
{
@ -331,8 +322,6 @@ namespace Plane.FormationCreator.Views
private void Copter_LocationChanged(object sender, EventArgs e)
{
if (!_flightTaskManager.TaskRun_2D) return; //不在3D模式运行直接退出
var copter = sender as ICopter;
if (App.Current.CheckAccess())
{
@ -363,19 +352,6 @@ namespace Plane.FormationCreator.Views
}
}
public void ShowAllWaypoint()
{
foreach (var item in _copterDrawings)
{
var copterDrawing = item.Value;
copterDrawing.ShowAllWaypoint();
}
}
public void ClearCopters()
{
/*
@ -393,11 +369,6 @@ namespace Plane.FormationCreator.Views
*/
gmap.Markers.Clear();
//_copterManager.Copters.ForEach(copter => _copterDrawings[copter]=null );
_copterDrawings.Clear();
}
@ -419,29 +390,14 @@ namespace Plane.FormationCreator.Views
private void FlightTaskManager_TaskAdded(object sender, FlightTaskAddedEventArgs e)
{
//给每个任务在地图上添加航点
foreach (var info in e.AddedTask.SingleCopterInfos)
{
var drawingInfo = _copterDrawings[info.Copter];
//计算位置
var location = new Microsoft.Maps.MapControl.WPF.Location(info.TargetLat, info.TargetLng, info.TargetAlt);
//添加航点
drawingInfo.AddWaypoint(location, e.AddedTask.TaskType,e.AddedTask);
drawingInfo.AddWaypoint(location, e.AddedTask.TaskType);
}
}
private void FlightTaskManager_TaskDeled(object sender, FlightTaskDeledEventArgs e)
{
//清除每架飞机的这个任务的航点
// foreach (var info in e.DeledTask.SingleCopterInfos)
// {
// _copterDrawings[info.Copter].Waypoints.RemoveAt(e.TaskIndex);
// }
}
GMapMarker observerMarker = null;
Microsoft.Expression.Shapes.RegularPolygon observer = null;
GMapMarker originalMarker = null;
Microsoft.Expression.Shapes.RegularPolygon original = null;
const double ORIGIN_RADIUS = 12;
@ -480,131 +436,8 @@ namespace Plane.FormationCreator.Views
_flightTaskManager.OriginLng = location.Lng;
original.MouseLeftButtonDown += new MouseButtonEventHandler(OriginalMouseDown);
///加入或者改变观测点用于3D模拟
if (gmap.Markers.Contains(observerMarker))
gmap.Markers.Remove(observerMarker);
observer = new Microsoft.Expression.Shapes.RegularPolygon
{
Tag = OBSERVER_TAG,
Fill = new SolidColorBrush(Color.FromArgb(200, 3, 155, 3)),
Stroke = new SolidColorBrush(Color.FromArgb(200, 3, 80, 238)),
StrokeThickness = 1,
Width = ORIGIN_RADIUS *2,
Height = ORIGIN_RADIUS * 2,
InnerRadius = 1,
PointCount = 6,
};
if (_flightTaskManager.ObserverLat == 0)
{
Tuple<double, double> observationLatLng = null;
//第一列到中间的距离
float midColDistance = (_flightTaskManager.ColumnCount - 1) * _flightTaskManager.ColumnDistance / 2;
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
_flightTaskManager.OriginLat,
_flightTaskManager.OriginLng,
_flightTaskManager.Orientation + 90,
midColDistance);
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
observationLatLng.Item1,
observationLatLng.Item2,
_flightTaskManager.Orientation + 180,
midColDistance * 4);
_flightTaskManager.ObserverLat = observationLatLng.Item1;
_flightTaskManager.ObserverLng = observationLatLng.Item2;
}
//_flightTaskManager.ObserverLat = _flightTaskManager.OriginLat;
//_flightTaskManager.ObserverLng = _flightTaskManager.OriginLng;
PointLatLng Observerlocation = new LatLng(_flightTaskManager.ObserverLat, _flightTaskManager.ObserverLng).ToGCJ02();
GPoint opoint = gmap.FromLatLngToLocal(Observerlocation);
opoint.X -= (long)ORIGIN_RADIUS;
opoint.Y -= (long)ORIGIN_RADIUS;
mapLocation = gmap.FromLocalToLatLng((int)opoint.X, (int)opoint.Y);
observerMarker = new GMapMarker(mapLocation);
observerMarker.ZIndex = 200;
observerMarker.Shape = observer;
observerDrag = false;
observer.MouseLeftButtonDown += new MouseButtonEventHandler(observerMouseDown);
gmap.Markers.Add(observerMarker);
}
private bool observerDrag = false;
double observerX = 0;
double observerY = 0;
private void observerMouseDown(object sender, MouseButtonEventArgs e)
{
observerDrag = true;
gmap.CanDragMap = false;
var originPoint = e.GetPosition(gmap);
observerX = originPoint.X;
observerX = originPoint.Y;
var posInObject = e.GetPosition(observer);
wpOffsetX = posInObject.X;
wpOffsetY = posInObject.Y;
}
private void observerMove(object sender, MouseEventArgs e)
{
if (observerDrag)
{
Point eventPos = e.GetPosition(gmap);
var leftTopPos = new Point(eventPos.X - wpOffsetX, eventPos.Y - wpOffsetY);
observerMarker.Position = gmap.FromLocalToLatLng((int)leftTopPos.X, (int)leftTopPos.Y);
//MapLayer.SetPosition(original, map.ViewportPointToLocation(leftTopPos));
}
}
private void observerMouseUp(object sender, MouseButtonEventArgs e)
{
if (observerDrag)
{
Point eventPos = e.GetPosition(gmap);
var centrePos = new Point(eventPos.X - wpOffsetX + ORIGIN_RADIUS, eventPos.Y - wpOffsetY + ORIGIN_RADIUS);
PointLatLng location = gmap.FromLocalToLatLng((int)centrePos.X, (int)centrePos.Y);
_flightTaskManager.ObserverLat = location.Lat;
_flightTaskManager.ObserverLng = location.Lng;
// original.ToolTip = location.ToString();
//Clipboard.SetDataObject(string.Format("{0},{1}", location.Lat, location.Lng), true);
observerDrag = false;
gmap.CanDragMap = true;
}
}
private bool originaDrag = false;
double originX = 0;
double originY = 0;
@ -668,7 +501,11 @@ namespace Plane.FormationCreator.Views
break;
}
initmap();
gmap.MinZoom = 2; //最小缩放
gmap.MaxZoom = 30; //最大缩放
gmap.Zoom = 19; //当前缩放
gmap.ShowCenter = false; //不显示中心十字点
gmap.DragButton = MouseButton.Left; //左键拖拽地图
/*
switch ((e.AddedItems[0] as FrameworkElement).Tag.ToString())
@ -722,8 +559,7 @@ namespace Plane.FormationCreator.Views
foreach (var item in _copterDrawings)
{
var copterDrawing = item.Value;
_flightTaskManager.showroute = chk.IsChecked??false;
copterDrawing.UpdateShowroute();
copterDrawing.SetShowroute(chk.IsChecked);
}
}
@ -737,6 +573,9 @@ namespace Plane.FormationCreator.Views
}
}
private void RemoveTileLayers()
{
/*
@ -778,6 +617,8 @@ namespace Plane.FormationCreator.Views
grid_bg.Background = ib;
gmap.Opacity = 0.5;
}
}
}

View File

@ -40,18 +40,11 @@ namespace Plane.FormationCreator.Views
_brush = new SolidColorBrush(_color);
}
Color Copterdefaultcolor = (Color)ColorConverter.ConvertFromString("#" + CopterManager.CopterDefaultColor);
_brush = new SolidColorBrush(Copterdefaultcolor);
_brush = new SolidColorBrush(Color.FromRgb(45,45,45));
_flightTaskManager.TasksCleared += (sender, e) =>
{
//清除计划航线
if (Route!=null)
Route.Points.Clear();
// for (int i = this.Route.Locations.Count - 1; i >= 1; i--)
// {
// this.Route.Locations.RemoveAt(i);
@ -66,26 +59,11 @@ namespace Plane.FormationCreator.Views
//_map.ViewChangeOnFrame += new EventHandler<MapEventArgs>(Map_ViewChanged);
//删除任务事件
_flightTaskManager.TaskDeled += (sender, e) =>
{
if (this.Waypoints.Count == 0)
return;
// Waypoints没有起飞任务所以-1
int WaypointsIndex = e.TaskIndex - 1;
//删除地图上的航点
var wp = this.Waypoints[WaypointsIndex];
_map.Markers.Remove(wp);
//删除航点列表里的航点
this.Waypoints.RemoveAt(WaypointsIndex);
};
selectMarkup.Width = 7;
selectMarkup.Height = 7;
selectMarkup.HorizontalAlignment = HorizontalAlignment.Left;
selectMarkup.VerticalAlignment = VerticalAlignment.Top;
selectMarkup.Fill = new SolidColorBrush(Colors.Red); //选中做红色标记
selectMarkup.Fill = new SolidColorBrush(Colors.Black);
}
Rectangle selectMarkup = new Rectangle();
@ -121,9 +99,7 @@ namespace Plane.FormationCreator.Views
public MapPolyline Track { get; set; }
public Location LastLocation { get; set; }
//计划航线
public GMapRoute Route { get; set; }
//某架飞机的地图显示航点列表
public List<GMapMarker> Waypoints { get; set; } = new List<GMapMarker>();
GoogleMap.GMap _map;
@ -155,7 +131,6 @@ namespace Plane.FormationCreator.Views
public void AddOrMoveCopter()
{
if (!_flightTaskManager.TaskRun_2D) return; //不在2D模式运行直接退出
try
{
var location = new Microsoft.Maps.MapControl.WPF.Location(Copter.Latitude, Copter.Longitude, Copter.Altitude);
@ -229,16 +204,13 @@ namespace Plane.FormationCreator.Views
//MapLayer.SetZIndex(DotContainer, 100);
this.Route = new GMapRoute(new List<PointLatLng>() { gmapLatLng, gmapLatLng });
/*
Path path = new Path()
{
Stroke = new SolidColorBrush(Colors.Red),
Stroke = _brush,
StrokeThickness = 2.0
};
this.Route.Shape = path;
*/
//显示计划航线
//_map.Markers.Add(Route);
@ -269,26 +241,18 @@ namespace Plane.FormationCreator.Views
}
}
switch (_copterManager.SortType)
if (Copter.DisplayVirtualId)
{
case CopterManager.CopterSortType.ByID:
CopterText.Text = Copter.Name;
CopterText.Foreground = new SolidColorBrush(Colors.White);
break;
case CopterManager.CopterSortType.ByVID:
case CopterManager.CopterSortType.ByVIDShowAll:
CopterText.Text = Copter.VirtualId.ToString();
CopterText.Foreground = new SolidColorBrush(Colors.Yellow);
break;
default:
CopterText.Foreground = new SolidColorBrush(Colors.Red);
}
else
{
CopterText.Text = Copter.Name;
CopterText.Foreground = new SolidColorBrush(Colors.White);
break;
}
if (Copter.GetShowLEDAsync())
blackBrush.Color = Colors.White;
else
@ -330,75 +294,18 @@ namespace Plane.FormationCreator.Views
//this.Dot.Fill = _brush;
}
public void ShowWaypoint(int taskIndex)
{
var wpIndex = taskIndex - 1; // Waypoints 中没有起飞点。
foreach (var item in this.Waypoints)
{
_map.Markers.Remove(item);
}
if (wpIndex >= 0 && wpIndex < Waypoints.Count)
{
//选中的航点
GMapMarker wpmarker = (GMapMarker)(Waypoints[wpIndex]);
//航点轮廓变为白色
// wpmarker.Shape.Stroke = _selectedTaskStroke;
_map.Markers.Add(wpmarker); //消耗大量时间费时
}
}
public void ShowAllWaypoint()
{
foreach (var item in this.Waypoints)
{
_map.Markers.Remove(item);
}
foreach (var item in this.Waypoints)
{
_map.Markers.Add(item);
}
}
//加入航点
public void AddWaypoint(Location location, FlightTaskType type, FlightTask vtask)
public void AddWaypoint(Location location, FlightTaskType type)
{
// Add waypoint.
LatLng gmapLatLng = new LatLng(location.Latitude, location.Longitude);
//创建marker,设定位置
GMapMarker marker = new GMapMarker(gmapLatLng.ToGCJ02());
//航点默认颜色
SolidColorBrush Waypoint_brush = new SolidColorBrush(Color.FromRgb(0, 0, 255));
//makrer的形状包含一个圆圈和一个选中方块
ShapesContainer shapesContainer = new ShapesContainer(Waypoint_brush);
ShapesContainer shapesContainer = new ShapesContainer(_brush);
shapesContainer.Tag = WAYPOINT_TAG;
marker.Tag = WAYPOINT_TAG;
//形状设置为shapesContainer
marker.Shape = shapesContainer;
//加入航点列表Waypoints为某架飞机的航点列表
Waypoints.Insert(vtask.TaskIndex-1,marker);
//该航点的飞机是否选中
bool PontisSelected = _copterManager.SelectedCopters.Contains(Copter);
shapesContainer.Ismark = PontisSelected;
// 选中飞机在地图上显示一个红色方块---选中时也会调用,这儿可以不调用
SetEffect(PontisSelected);
//_map.Markers.Add(marker); //消耗大量时间费时 为了提高效率改为选中才添加见ShowWaypoint
Waypoints.Add(marker);
_map.Markers.Add(marker);
marker.ZIndex = 100;
//MapLayer.SetZIndex(shapesContainer, 100);
//var wpPos = _map.LocationToViewportPoint(location);
@ -406,12 +313,13 @@ namespace Plane.FormationCreator.Views
//wpPos.Y -= WAYPOINT_RADIUS;
//MapLayer.SetPosition(shapesContainer, _map.ViewportPointToLocation(wpPos));
SetEffect(_copterManager.SelectedCopters.Contains(Copter));
// Register event handlers.
RegisterEventHandlersForDraggingWaypoint(marker, vtask);
RegisterEventHandlersForDraggingWaypoint(marker, taskIndex: Waypoints.Count);
// Register event handlers for task info.
RegisterEventHandlersForTaskInfo(marker, vtask);
RegisterEventHandlersForTaskInfo(marker, taskIndex: Waypoints.Count);
}
private void RegisterEventHandlersForDraggingCopter(GMapMarker copterMarker)
@ -465,7 +373,7 @@ namespace Plane.FormationCreator.Views
private Dictionary<ICopter, GPoint> selectWayOriginPoint = new Dictionary<ICopter, GPoint>();
private Dictionary<object, bool> _dictDraggingWp = new Dictionary<object, bool>();
private void RegisterEventHandlersForDraggingWaypoint(GMapMarker wpMarker, FlightTask vtask)
private void RegisterEventHandlersForDraggingWaypoint(GMapMarker wpMarker, int taskIndex)
{
Grid wp = wpMarker.Shape as Grid;
_dictDraggingWp[wp] = false;
@ -478,11 +386,11 @@ namespace Plane.FormationCreator.Views
//判断点击的航点
//非SelectedTask中的航点 或者 当前SelectedTask中未选择的航点 单选拖动
//否则多选拖动
if (_flightTaskManager.SelectedTask != vtask || !_copterManager.SelectedCopters.Contains(this.Copter))
if (_flightTaskManager.SelectedTaskIndex != taskIndex || !_copterManager.SelectedCopters.Contains(this.Copter))
{
//_copterManager.Select(null);
_copterManager.Select(this.Copter);
_flightTaskManager.SelectTask(vtask.TaskIndex);
_flightTaskManager.Select(taskIndex, this.Copter);
}
var originPoint = e.GetPosition(_map);
@ -508,7 +416,7 @@ namespace Plane.FormationCreator.Views
};
wp.MouseRightButtonDown += (sender, e) =>
{
_flightTaskManager.RightSelect(vtask.TaskIndex, this.Copter);
_flightTaskManager.RightSelect(taskIndex, this.Copter);
};
_map.MouseMove += (sender, e) =>
{
@ -554,10 +462,10 @@ namespace Plane.FormationCreator.Views
};
}
private void RegisterEventHandlersForTaskInfo(GMapMarker marker, FlightTask vtask)
private void RegisterEventHandlersForTaskInfo(GMapMarker marker, int taskIndex)
{
var wp = marker.Shape as ShapesContainer;
var info = vtask.SingleCopterInfos.FirstOrDefault(i => i.Copter == this.Copter);
var info = _flightTaskManager.Tasks[taskIndex].SingleCopterInfos.FirstOrDefault(i => i.Copter == this.Copter);
if (info == null) return;
info.PropertyChanged += (sender, e) =>
{
@ -576,13 +484,9 @@ namespace Plane.FormationCreator.Views
// var routePoint = Route.Points[1];
// routePoint.Lat = info.TargetLat;
// routePoint.Lng = info.TargetLng;
if (Route != null)
{
if (Route.Points.Count>1)
Route.Points.RemoveAt(1);
Route.Points.Add(marker.Position);
this.Route.RegenerateShape(_map);
}
//routePoint.Altitude = info.TargetAlt;
}
break;
@ -606,24 +510,20 @@ namespace Plane.FormationCreator.Views
//_map.ViewChangeOnFrame -= Map_ViewChanged;
}
//显示或隐藏计划线路
public void UpdateShowroute()
public void SetShowroute(bool? showroute)
{
if (_flightTaskManager.showroute)
if (showroute ?? false )
{
if (_copterManager.ShowCopter.Count > 0)
{
if (_copterManager.ShowCopter.Contains(Copter))
{
if (!_map.Markers.Contains(this.Route))
_map.Markers.Add(this.Route);
Route.ZIndex = 99;
}
}
else
{
//将计划线路加入地图
if (!_map.Markers.Contains(this.Route))
_map.Markers.Add(this.Route);
Route.ZIndex = 99;
}
@ -632,8 +532,7 @@ namespace Plane.FormationCreator.Views
}
else
{
//将计划线路从地图移除
if (_map.Markers.Contains(this.Route))
if(_map.Markers.Contains(this.Route))
_map.Markers.Remove(this.Route);
}
@ -647,19 +546,18 @@ namespace Plane.FormationCreator.Views
// _map.Children.Remove(Track);
}
//选中飞机在地图上显示一个红色方块
public void SetEffect(bool selected)
{
if (selected)
{
if ((DotContainer!=null)&&(!DotContainer.Children.Contains(selectMarkup)))
if (!DotContainer.Children.Contains(selectMarkup))
DotContainer.Children.Add(selectMarkup);
}
else
{
if ((DotContainer != null) && (DotContainer.Children.Contains(selectMarkup)))
if (DotContainer.Children.Contains(selectMarkup))
DotContainer.Children.Remove(selectMarkup);
}
@ -675,69 +573,47 @@ namespace Plane.FormationCreator.Views
*/
}
//添加计划航线---只显示两个点
public void ResetRoute(int taskIndex)
{
var wpIndex = taskIndex - 1; // Waypoints 中没有起飞点。
if (Route == null) return;
Route.Points.Clear();
if (wpIndex >= 0 && wpIndex < Waypoints.Count)
{
//起始点时
var info1 = _flightTaskManager.Tasks[wpIndex].SingleCopterInfos.Find(i => i.Copter == this.Copter);
var info2 = _flightTaskManager.Tasks[taskIndex].SingleCopterInfos.Find(i => i.Copter == this.Copter);
PointLatLng loc1 = new LatLng(info1.TargetLat, info1.TargetLng).ToGCJ02();
PointLatLng loc2 = new LatLng(info2.TargetLat, info2.TargetLng).ToGCJ02();
Route.Points.Add(loc1); //起始点
Route.Points.Add(loc2); //结束点
}
Path path = new Path()
{
Stroke = new SolidColorBrush(Colors.Red),
StrokeThickness = 2.0
};
Route.Shape = path;
Route.Points.Add(loc1);
Route.Points.Add(loc2);
//if (0)
Route.RegenerateShape(_map);
UpdateShowroute();
}
}
//设置选中任务航点为白色外框
public void SetTaskEffect(int taskIndex)
{
var wpIndex = taskIndex - 1; // Waypoints 中没有起飞点。
if (wpIndex >= 0 && wpIndex < Waypoints.Count)
{
//清除所有白色轮廓
Waypoints.ForEach(p => ((ShapesContainer)(p.Shape)).wp.Stroke = null);
//选中的航点
var wp = ((ShapesContainer)(Waypoints[wpIndex].Shape)).wp;
//航点轮廓变为白色
wp.Stroke = _selectedTaskStroke;
}
}
// 右击任务时触发
//显示或者隐藏任务航点
public void SetTaskRightEffect(int taskIndex, bool flag)
{
var wpIndex = taskIndex - 1; // Waypoints 中没有起飞点。
if (wpIndex >= 0 && wpIndex < Waypoints.Count)
{
var wp = Waypoints[wpIndex].Shape as ShapesContainer;
//计划航线
UIElement RouteShape = null;
if ((Route != null) && (Route.Shape != null))
RouteShape = Route.Shape;
if (!flag)
{
wp.Visibility = Visibility.Hidden;
if (RouteShape!=null)
RouteShape.Visibility= Visibility.Hidden;
}
else
{
@ -747,22 +623,15 @@ namespace Plane.FormationCreator.Views
if (_copterManager.ShowCopter.Contains(Copter))
{
wp.Visibility = Visibility.Visible;
if (RouteShape != null)
RouteShape.Visibility = Visibility.Visible;
}
else
{
wp.Visibility = Visibility.Hidden;
if (RouteShape != null)
RouteShape.Visibility = Visibility.Hidden;
}
}
else
{
wp.Visibility = Visibility.Visible;
//3d模式Route可能为空
if (RouteShape != null)
RouteShape.Visibility = Visibility.Visible;
}
//var info = _flightTaskManager.Tasks[taskIndex].SingleCopterInfos.Find(i => i.Copter == this.Copter);
@ -772,7 +641,6 @@ namespace Plane.FormationCreator.Views
}
}
//航点选中方块
public class ShapesContainer : Grid
{
const double WAYPOINT_RADIUS = 6;
@ -794,7 +662,6 @@ namespace Plane.FormationCreator.Views
mark.HorizontalAlignment = HorizontalAlignment.Left;
mark.VerticalAlignment = VerticalAlignment.Top;
mark.Fill = new SolidColorBrush(Colors.GreenYellow);
this.Children.Add(mark);
mark.Visibility = Visibility.Hidden;
@ -803,10 +670,8 @@ namespace Plane.FormationCreator.Views
//public MapPolygon
private bool isMarked;
public Ellipse wp;
//航点选中方块
public Rectangle mark;
//航点是否选中
public bool Ismark
{
get

View File

@ -26,11 +26,20 @@
Value="Horizontal" />
</Style>
</StackPanel.Resources>
<TextBlock Margin="5" Text="起飞任务" Height="20" VerticalAlignment="Center" />
<TextBlock Margin="5" Text="起飞任务"/>
<Separator/>
<StackPanel Visibility="Collapsed">
<TextBlock Text="起飞数量:" Margin="5,10,5,0" />
<TextBox x:Name="txttakeoff"
Width="25"
Margin="0,10,5,0"
VerticalContentAlignment="Center"
Text="{Binding FlightTaskManager.TakeOffNumAttr, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<Separator Margin="5,0,5,0" />
<Grid Margin="5" DataContext="{Binding FlightTaskManager.SelectedTask.ModifyingSingleCopterInfo}">
<Separator />
<Grid DataContext="{Binding FlightTaskManager.SelectedTask.ModifyingSingleCopterInfo}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
@ -43,17 +52,17 @@
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Margin="5" Text="起飞延时" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBlock Margin="5" Text="起飞延时"/>
<TextBox Margin="5" Grid.Column="2"
Text="{Binding TakeOffWaitTime, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="应用所选" Margin="5" Grid.Column="3"
Command="{Binding SetSelTakeOffWaitCommand}"/>
<Separator Margin="5,5,5,5" Grid.Row="1" Grid.ColumnSpan="4"/>
<Separator Grid.Row="1" Grid.ColumnSpan="4"/>
<TextBlock Margin="5" Text="随机时间" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBox Margin="5" Grid.Row="2" Grid.Column="1" Text="{Binding TakeOffMinTime}"/>
<TextBox Margin="5" Grid.Row="2" Grid.Column="2" Text="{Binding TakeOffMaxTime}"/>
<Button Margin="5" Content="应用所选" Grid.Row="2" Grid.Column="3"
<TextBlock Text="随机时间" Grid.Row="2"/>
<TextBox Margin="10,0" Grid.Row="2" Grid.Column="1" Text="{Binding TakeOffMinTime}"/>
<TextBox Margin="10,0" Grid.Row="2" Grid.Column="2" Text="{Binding TakeOffMaxTime}"/>
<Button Margin="10,0" Content="应用所选" Grid.Row="2" Grid.Column="3"
Command="{Binding SetRandomOffWaitDelayCommand}"/>
</Grid>
@ -67,44 +76,17 @@
</Style>
</StackPanel.Resources>
<StackPanel>
<TextBlock Margin="0,5,5,0" Text="所有:" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Button Margin="0,5,5,0" Content="导入航点" Command="{Binding ImportWayPointCommand}"
<TextBlock Margin="5" Text="航点任务"/>
<Button Content="导入航点" Command="{Binding ImportWayPointCommand}"
Visibility="Collapsed"/>
<Button Margin="0,5,5,0" Content="2D航线" Width="82" Command="{Binding OptimizeRouteCommand}"
<Button Content="优化路线" Command="{Binding OptimizeRouteCommand}"
/>
<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="3D对应" Width="82" Command="{Binding OptimizeRouteCommandRet3D}"
/>
<Button Margin="0,5,5,0" Content="导出到C4D" Width="105" Command="{Binding ExportWayPointCommand}"/>
</StackPanel>
<StackPanel>
<Button Content="回前一任务"
Margin="40,5,5,0" Width="105"
Command="{Binding BackToPreviousTaskPoint}" />
<Button Content="回前一高度"
Margin="0,5,5,0" Width="105"
Command="{Binding PrealtCommand}" />
<Button Content="回起飞点"
Margin="0,5,5,0" Width="105"
Command="{Binding BackTakeOffPointCommand}" />
<Button Margin="0,5,5,0" Content="计算时间" Width="105" Command="{Binding AutoWayPointTmCommand}"/>
<Button Content="导入航点" Command="{Binding ImportBlenderWayPointCommand}"/>
<Button Content="导出航点" Command="{Binding ExportWayPointCommand}"/>
</StackPanel>
<Separator Margin="5,5,5,0" />
<Separator Margin="0,1"/>
<StackPanel>
<TextBlock Text="选中:" Margin="0,5,5,0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Button Content="上边对齐"
Margin="0,5,5,0"
Command="{Binding LevelAlignmentCommand}" />
@ -117,12 +99,14 @@
<Button Content="垂直均分"
Margin="0,5,5,0"
Command="{Binding VerticlAverageCommand}" />
<Button Content="回起飞点"
Margin="0,5,5,0"
Command="{Binding BackTakeOffPointCommand}" />
</StackPanel>
<StackPanel>
<Button Content="水平旋转"
Margin="40,5,5,0"
Margin="0,5,5,0"
Command="{Binding LevelRotateCommand}"
CommandParameter="{Binding ElementName=txtAlignmentLine, Path=Text}"/>
<Button Content="垂直旋转"
@ -130,63 +114,71 @@
Command="{Binding VerticlRotateCommand}"
CommandParameter="{Binding ElementName=txtAlignmentLine, Path=Text}"/>
<Button Content="整体旋转"
Margin="0,5,5,0"
Command="{Binding TaskRotateCommand}"
CommandParameter="{Binding ElementName=txtAlignmentLine, Path=Text}"/>
<TextBox x:Name="txtAlignmentLine"
Width="30"
Width="35"
Margin="0,5,5,0"
Text="0"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Right"/>
<TextBlock Text="度" Margin="0, 10, 5, 0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Button Content="调整大小"
VerticalContentAlignment="Center" />
<TextBlock Text="度" Margin="0, 10, 5, 0"/>
<Button Content="回上一任务"
Margin="0,5,5,0"
Command="{Binding BackToPreviousTaskPoint}" />
</StackPanel>
<StackPanel>
<Button Content="缩放比例"
Margin="0,5,5,0"
Command="{Binding ScaleCommand}"
CommandParameter="{Binding ElementName=txtScaleVale, Path=Text}"/>
<TextBox x:Name="txtScaleVale"
Width="35"
Margin="0,5,5,0"
Text="100"
Width="30"
Margin="0,5,5,0"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Right" />
<TextBlock Text="%" Margin="0, 10, 5, 0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</StackPanel>
<StackPanel>
<Button Content="调整高度"
Margin="0,5,5,0"
Command="{Binding ModiSelectedAltCommand}"/>
<Button Content="移动航点"
Margin="0,5,5,0"
Command="{Binding ModiSelectedPosCommand}" />
<TextBox
Grid.Column="1"
Width="30"
Margin="0,5,5,0"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Right"
Text="{Binding Modialtvalue, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="米 方向" Margin="0, 10, 5, 0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBox Grid.Column="1"
Width="30"
Margin="0,5,5,0"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Right"
Text="{Binding directionvalue, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="度" Margin="0, 10, 5, 0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<Button Content="最小点距"
VerticalContentAlignment="Center" />
<TextBlock Text="%" Margin="0, 10, 5, 0"/>
<Button Content="最小距离"
Margin="0,5,5,0"
Command="{Binding calDistinceCommand}"/>
<Button Content="最长航距"
Margin="0,5,5,0"
Command="{Binding MaxDistinceAndTimeCommand}"/>
<Button Content="前一高度"
Margin="0,5,5,0"
Command="{Binding PrealtCommand}" />
</StackPanel>
<StackPanel>
<Button Content="整体提高"
Margin="0,5,5,0"
Command="{Binding ModiAltCommand}"/>
<Button Content="整体移动"
Margin="0,5,5,0"
Command="{Binding ModiAllPosCommand}" />
<TextBox
Grid.Column="1"
Width="30"
Margin="0, 5, 5, 0"
HorizontalContentAlignment="Right"
Text="{Binding Modialtvalue, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="米 方向" Margin="0, 10, 5, 0"/>
<TextBox Grid.Column="1"
Width="30"
Margin="0, 5, 5, 0"
HorizontalContentAlignment="Right"
Text="{Binding directionvalue, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="度" Margin="0, 10, 5, 0"/>
<Button Content="提高" Margin="0,5,5,0" Command="{Binding ModiSelectedAltCommand}"/>
<Button Content="移动" Margin="0,5,5,0" Command="{Binding ModiSelectedPosCommand}"/>
</StackPanel>
<Separator Margin="0,5,5,0" />
<Separator Margin="0,2" />
<Grid Margin="0,2"
@ -205,36 +197,33 @@
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="纬度: " VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBlock Text="纬度: " />
<TextBox Grid.Column="2"
Grid.ColumnSpan="2"
Margin="0,5,5,0"
Margin="0,2,0,0"
Text="{Binding TargetLat, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Left"
<TextBlock Grid.Row="1"
Text="经度: " />
<TextBox Grid.Row="1"
Grid.Column="2"
Grid.ColumnSpan="2"
Margin="0,5,5,0"
Margin="0,2,0,0"
Text="{Binding TargetLng, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left"
<TextBlock Grid.Row="2"
Text="高度: " />
<TextBox Grid.Row="2"
Height="24"
Grid.Column="2"
Margin="0,5,5,0"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Left"
Margin="0,2,0,0"
Text="{Binding TargetAlt, UpdateSourceTrigger=PropertyChanged}" />
<Button Grid.Row="2"
Content="应用到所选"
Grid.Column="3" Margin="0,5,5,0"
Grid.Column="3" Margin="0,2,0,0"
Command="{Binding SetAllCopterAltCommand}"/>
</Grid>
<Separator Margin="0,5,5,5"/>
<Separator Margin="0,2"/>
<Grid Margin="0,2,0,0"
DataContext="{Binding FlightTaskManager.SelectedTask.ModifyingSingleCopterInfo}"
IsEnabled="{Binding CanModifySingleCopterInfo}" >
@ -244,12 +233,12 @@
</Grid.ColumnDefinitions>
<CheckBox Content="返航点" ToolTip="勾选后航点仅高度有用,经纬度无效,无视原点自动飞回起飞点" Margin="0,5,0,0" IsChecked="{Binding IsLandWaypoint,UpdateSourceTrigger=PropertyChanged}" />
<Button Content="影响所有飞机" Margin="0,2,5,0" IsEnabled="False" Command="{Binding SetIsLandCommand}" Grid.Column="1"/>
<CheckBox Content="返航点" ToolTip="勾选后航点仅高度有用,经纬度无效,无视原点自动飞回起飞点" Margin="0,2,0,0" IsChecked="{Binding IsLandWaypoint,UpdateSourceTrigger=PropertyChanged}" />
<Button Content="应用到所选" Margin="0,2,0,0" Command="{Binding SetIsLandCommand}" Grid.Column="1"/>
</Grid>
<Separator Margin="0,5,5,5" />
<Separator/>
<Grid Margin="0,2"
DataContext="{Binding FlightTaskManager.SelectedTask.ModifyingSingleCopterInfo}"
IsEnabled="{Binding CanModifySingleCopterInfo}" >
@ -262,20 +251,20 @@
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<CheckBox Content="改变最大速度" Margin="0,3"
<CheckBox Content="改变速度" Margin="0,2"
IsChecked="{Binding IsChangeSpeed, UpdateSourceTrigger=PropertyChanged}"/>
<StackPanel Margin="0,0" Grid.Column="1">
<TextBlock Text="水平" Margin="0,0,5,5" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBox Width="45" Margin="5,0,5,5" VerticalAlignment ="Center"
<StackPanel Margin="0,2" Grid.Column="1">
<TextBlock Text="水平"/>
<TextBox Width="45" Margin="5,0,0,5"
Text="{Binding LevelSpeed, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="上升" Margin="0,0,5,5" VerticalAlignment="Center" HorizontalAlignment="Left" />
<TextBox Width="45" Margin="5,0,0,5" VerticalAlignment="Center"
<TextBlock Text="上升" Margin="15,0,0,0"/>
<TextBox Width="45" Margin="5,0,0,5"
Text="{Binding UpSpeed, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="下降" Margin="5,0,0,5" VerticalAlignment="Center" HorizontalAlignment="Left" />
<TextBox Width="45" Margin="5,0,5,5" VerticalAlignment="Center"
<TextBlock Text="下降" Margin="15,0,0,0"/>
<TextBox Width="45" Margin="5,0,0,5"
Text="{Binding DownSpeed, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<Button Content="改变后需重新计算飞行时间" IsEnabled="False" Margin="5,0,5,5" Grid.Row="1" Grid.Column="1" Command="{Binding SetIsChangeCommand}"/>
<Button Content="应用到所选" Grid.Row="1" Grid.Column="1" Command="{Binding SetIsChangeCommand}"/>
</Grid>
</StackPanel>
@ -288,9 +277,9 @@
Value="Horizontal" />
</Style>
</StackPanel.Resources>
<TextBlock Margin="5" Text="降落任务" VerticalAlignment="Center" HorizontalAlignment="Left" />
<Separator Margin="5,0,5,5" />
<Grid Margin="5" DataContext="{Binding FlightTaskManager.SelectedTask.ModifyingSingleCopterInfo}"
<TextBlock Margin="5" Text="降落任务"/>
<Separator/>
<Grid DataContext="{Binding FlightTaskManager.SelectedTask.ModifyingSingleCopterInfo}"
IsEnabled="{Binding CanModifySingleCopterInfo}" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
@ -298,7 +287,7 @@
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Margin="5" Text="降落延时" VerticalAlignment="Center" HorizontalAlignment="Left" />
<TextBlock Margin="5" Text="降落延时"/>
<TextBox Margin="5" Grid.Column="2"
Text="{Binding LandWaitTime, UpdateSourceTrigger=PropertyChanged}"/>
@ -312,166 +301,75 @@
</TabItem>
<TabItem Header="灯光设计">
<StackPanel>
<StackPanel x:Name="lightDesign">
<StackPanel Orientation="Horizontal" Margin="0,5,0,5" >
<TextBlock Margin="5,7,0,0" Text="扫光颜色"/>
<TextBox Height="25" Margin="5,3,5,3" Width="55" Text="{Binding ChangeRGB, UpdateSourceTrigger=PropertyChanged}"
ToolTip="灯带或跑马灯扫过的颜色"
Foreground="Black"
Background="{Binding DrawChangeRGB, UpdateSourceTrigger=PropertyChanged}"
MouseDoubleClick="TextBox_MouseDoubleClick"/>
<TextBlock Margin="0,7,0,0" Text="方向"/>
<TextBox Height="25"
ToolTip="默认90度表示从左到右扫过0度从下向上扫"
Margin="5,3,0,3" Width="30" Text="{Binding BeltDirection}"/>
<TextBlock Margin="5,7,0,0" Text="变换颜色"/>
<TextBox Margin="5,5,40,3" Width="60" Text="{Binding ChangeRGB}"/>
<TextBlock Margin="5,7,0,0" Text="起始时间"/>
<TextBox Height="25"
ToolTip="扫光开始时间"
Margin="5,3,0,3" Width="30" Text="{Binding BeginTime}"/>
<TextBox Margin="5,5,0,3" Width="30" Text="{Binding BeginTime}"/>
<TextBlock Margin="5,7,0,0" Text="结束时间"/>
<TextBox Height="25" Margin="5,3,0,3" Width="30" Text="{Binding EndTime}"
ToolTip="扫光完成时间" />
<TextBlock Margin="5,7,0,0" Text="分段"/>
<TextBox Height="25" Margin="5,3,0,3" Width="30" Text="{Binding AverageSum}"
ToolTip="图案分成几段扫过,段数越多灯带越窄,同样时间扫得越快" />
<Button Width="78" Content="灯带" Margin="10,0,0,0"
ToolTip="选择的飞机用一个光带扫过"
<TextBox Margin="5,5,0,3" Width="30" Text="{Binding EndTime}"/>
<TextBlock Margin="5,7,0,0" Text="分层"/>
<TextBox Margin="5,5,0,3" Width="30" Text="{Binding AverageSum}"/>
<Button Width="80" Content="灯带" Margin="10,0,0,0"
Command="{Binding SetHorseRaceLampCommand}" HorizontalAlignment="Right"/>
</StackPanel>
<Grid >
<StackPanel Orientation="Horizontal" Margin="0,2,0,0">
<TextBlock Margin="5,7,0,0" Text="结束颜色"/>
<TextBox Height="25" Margin="5,3,40,3" Width="55" Text="{Binding EndRGB, UpdateSourceTrigger=PropertyChanged}" ToolTip="设置为0表示扫过后回到原色"
Foreground="Black"
Background="{Binding DrawEndRGB, UpdateSourceTrigger=PropertyChanged}"
<TextBox Margin="5,5,40,3" Width="60" Text="{Binding EndRGB}" ToolTip="设置为0表示变换后回到原色"/>
<TextBlock Margin="5,7,0,0" Text="起始时间"/>
<TextBox Margin="5,5,0,3" Width="30" Text="{Binding StrokesTime}"/>
<TextBlock Margin="5,7,0,0" Text="频率•"/>
<TextBox Margin="5,5,0,3" Width="30" Text="{Binding IntervalTime}"/>
<TextBlock Margin="5,7,0,0" Text="œ˜变换数量"/>
<TextBox Margin="5,5,0,3" Width="30" Text="{Binding SingleNum}"/>
MouseDoubleClick="TextBox_MouseDoubleClick"/>
<TextBlock Margin="29,7,0,0" Text="起始时间"/>
<TextBox Height="25" Margin="5,3,0,3" Width="30" Text="{Binding StrokesTime}"
ToolTip="跑马灯开始时间" />
<TextBlock Margin="5,7,0,0" Text="œ˜扫光数量"/>
<TextBox Height="25" Margin="5,3,0,3" Width="30" Text="{Binding SingleNum}"
ToolTip="一次扫光改变颜色的数量" />
<TextBlock Margin="5,7,0,0" Text="间隔•"/>
<TextBox Height="25" Margin="5,3,0,3" Width="30" Text="{Binding IntervalTime}"
ToolTip="下一个扫光的间隔(秒)" />
<Button Width="78" Content="跑马灯" Margin="10,0,0,0"
Command="{Binding SetStrokesLampCommamd}" HorizontalAlignment="Right"
ToolTip="根据航点选择的顺序改变为扫光的颜色,经过扫光的航点变为结束颜色"
/>
<Button Width="80" Content="跑马灯" Margin="10,0,0,0"
Command="{Binding SetStrokesLampCommamd}" HorizontalAlignment="Right"/>
</StackPanel>
</Grid>
<Separator Margin="5,5,5,5" />
<Separator/>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="5,7,3,0" Text="时间"/>
<TextBox Height="25" Margin="5,2,3,3" Width="30" Text="{Binding GradientRampTime}"
ToolTip="开始时间" />
<TextBlock Margin="5,7,3,0" Text="方向"/>
<TextBox Height="25" Margin="5,2,5,3" Width="30" Text="{Binding GradualDirection}"
ToolTip="默认90度表示从左到右渐变0度从下向上渐变" />
<TextBlock Margin="5,7,3,0" Text="起始颜色"/>
<TextBox Height="25" Margin="5,2,3,3" Width="55" Text="{Binding LeftRGB, UpdateSourceTrigger=PropertyChanged}"
Foreground="Black"
ToolTip="渐变起始颜色"
Background="{Binding DrawLeftRGB, UpdateSourceTrigger=PropertyChanged}"
MouseDoubleClick="TextBox_MouseDoubleClick"/>
<TextBlock Margin="5,7,3,0" Text="结束颜色"/>
<TextBox Height="25" Margin="5,2,7,3" Width="55" Text="{Binding RightRGB, UpdateSourceTrigger=PropertyChanged}"
Foreground="Black"
ToolTip="渐变结束颜色"
Background="{Binding DrawRightRGB, UpdateSourceTrigger=PropertyChanged}"
MouseDoubleClick="TextBox_MouseDoubleClick"/>
<Button Margin="42,0,0,3" Width="78" Content="渐变灯"
ToolTip="自动生成渐变过度颜色"
<TextBlock Margin="5,7,0,0" Text="时间"/>
<TextBox Margin="5,5,0,3" Width="30" Text="{Binding GradientRampTime}"/>
<TextBlock Margin="5,7,0,0" Text="起始色"/>
<TextBox Margin="5,5,0,3" Width="60" Text="{Binding LeftRGB}"/>
<TextBlock Margin="5,7,0,0" Text="结束色"/>
<TextBox Margin="5,5,0,3" Width="60" Text="{Binding RightRGB}"/>
<Button Margin="10,5,0,3" Width="120" Content="设置渐变灯"
Command="{Binding SetGradientRampCommand}" />
</StackPanel>
<Separator Margin="5,5,5,5" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0,12,0" >
<Button Margin="5,0,0,3" Content="最长时间" Width="90"
ToolTip="查询所有选择飞机最长灯光时间"
Command="{Binding QueryMAXTimeCommand}" />
<TextBlock Margin="5,7,3,0" Text="时间对齐"/>
<TextBox Height="25" Margin="5,2,3,3" Width="30" Text="{Binding AlignmentTime}"
ToolTip="对齐时间(秒)" />
<Button Margin="5,0,0,3" Content="对齐" Width="78"
ToolTip="所有飞机灯光时间对齐到指定秒数,便于做第二个灯带或跑马灯"
Command="{Binding AlignmentTimeCommand}" />
<Separator/>
</StackPanel>
<Separator Margin="5,5,5,5" />
</StackPanel>
</TabItem>
<TabItem Header="灯光列表">
<StackPanel>
<StackPanel DataContext="{Binding FlightTaskManager.SelectedTask.ModifyingSingleCopterInfo}">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="45*"/>
<ColumnDefinition Width="61*"/>
<ColumnDefinition Width="61*"/>
<ColumnDefinition Width="61*"/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="0,0,0,0" >
<TextBlock Text="总时长:" Margin="5,7,2,2" VerticalAlignment="Center" Height="15"/>
<TextBlock Text="{Binding LEDSumTime}" Margin="0,7,2,2" VerticalAlignment="Center" Height="15"/>
<TextBlock Text="秒" Margin="0,7,10,2" VerticalAlignment="Center" Height="15"/>
</StackPanel>
<Grid Grid.Column="1" Grid.ColumnSpan="3" VerticalAlignment="Center" Height="34">
<TextBlock Text="灯光控制" Margin="5, 10, 5, 0" VerticalAlignment="Center"/>
<Grid Grid.Column="1" Grid.ColumnSpan="3" VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Content="应用全部" VerticalAlignment="Center"
<Button Content="应用到全部" VerticalAlignment="Center"
Margin="0,5,5,0"
Command="{Binding SetAllCopterLEDCommand}" />
<Button Content="应用所选" VerticalAlignment="Center"
<Button Content="应用到所选" VerticalAlignment="Center"
Margin="0,5,5,0"
Grid.Column="1"
Command="{Binding SetSelectedCopterLEDCommand}" />
<Button Content="测试/停止" VerticalAlignment="Center"
Margin="0,5,5,0"
Grid.Column="2"
Visibility="Collapsed"
Command="{Binding TestCopterLEDCommand}"
/>
<Button Content="添加" VerticalAlignment="Center"
Grid.Column="3"
Grid.Column="2"
Margin="0,5,5,0"
Command="{Binding AddLEDCommand}" />
</Grid>
@ -482,8 +380,8 @@
Grid.Row="1"
Grid.ColumnSpan="2"
MinHeight="100"
Height="346"
MaxHeight="400"
Height="Auto"
MaxHeight="280"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ItemsSource="{Binding Path= LEDInfos}">
@ -500,59 +398,40 @@
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:Name="LEDTemplate">
<DataTemplate>
<StackPanel Margin="0,5,0,0" Orientation="Horizontal" >
<TextBlock Text="类型" Margin="0,0,0,0" VerticalAlignment="Center" ></TextBlock>
<ComboBox x:Name="cmbTemplateLEDMode" Height="25" MinWidth="125" Width="110" Margin="5,0,0,0" Foreground="White" VerticalContentAlignment="Center"
SelectedIndex="{Binding Path=LEDMode}"
Loaded="OnCBLoaded" Initialized="cmbTemplateLEDMode_Initialized"
>
<ComboBox MinWidth="125" Width="125" Margin="5,0,0,0" Foreground="White" VerticalContentAlignment="Center"
SelectedIndex="{Binding Path=LEDMode}">
<ComboBox.ItemContainerStyle>
<Style>
<Setter Property="ComboBoxItem.Foreground" Value="White"/>
</Style>
</ComboBox.ItemContainerStyle>
<ComboBoxItem Content="代码里面动态添加--这里数量要够" />
<ComboBoxItem Content="常亮" />
<ComboBoxItem Content="同步闪烁(单色)" />
<ComboBoxItem Content="异步闪烁(随机)" />
<ComboBoxItem Content="渐亮" />
<ComboBoxItem Content="渐暗" />
<ComboBoxItem Content="呼吸灯(单色)" />
<ComboBoxItem Content="呼吸灯" />
<ComboBoxItem Content="同步闪烁(随机)" />
<ComboBoxItem Content="异步闪烁(单色)" />
<ComboBoxItem Content="拉烟"/>
<ComboBoxItem Content="拉烟"/>
<ComboBoxItem Content="拉烟"/>
<ComboBoxItem Content="拉烟"/>
<ComboBoxItem Content="拉烟"/>
<ComboBoxItem Content="拉烟"/>
<ComboBoxItem Content="拉烟"/>
<ComboBoxItem Content="拉烟"/>
<ComboBoxItem Content="拉烟"/>
<ComboBoxItem Content="拉烟"/>
</ComboBox>
<TextBlock Text="时间" Margin="12,0,0,0" VerticalAlignment="Center"></TextBlock>
<TextBox Height="25" MinWidth="40" MaxWidth="45" Margin="5,0,0,0"
ToolTip="相对延迟时间,最小0.1秒"
<TextBox MinWidth="40" MaxWidth="45" Margin="5,0,0,0"
ToolTip="单位:秒最小设置0.1秒"
Text="{Binding Delay,UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="频率" Margin="12,0,0,0" VerticalAlignment="Center"></TextBlock>
<TextBox Height="25" MinWidth="35" MaxWidth="40" Margin="5,0,0,0"
ToolTip="单位:HZ最小设置0.1HZ"
Text="{Binding Path=LEDInterval, UpdateSourceTrigger=PropertyChanged}" />
<TextBox MinWidth="40" MaxWidth="45" Margin="5,0,0,0"
Text="{Binding Path=LEDRate, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="颜色" Margin="12,0,0,0" VerticalAlignment="Center"></TextBlock>
<TextBox Height="25" Margin="5,0,0,0" MinWidth="50" Width="55"
Text="{Binding LEDRGB, UpdateSourceTrigger=PropertyChanged}"
Foreground="Black"
Background="{Binding DrawRGB, UpdateSourceTrigger=PropertyChanged}"
MouseDoubleClick="TextBox_MouseDoubleClick"
/>
<TextBox Margin="5,0,0,0" MinWidth="50" Width="50"
Text="{Binding LEDRGB, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="删除" Margin="12,0,0,0"
Command="{Binding RemoveLEDCommand}"/>
@ -564,121 +443,6 @@
</ItemsControl>
</StackPanel>
</StackPanel>
</TabItem>
<TabItem Header="设计工具" Margin="-2,-2,-2,0">
<StackPanel>
<StackPanel x:Name="PanelDesign1">
<StackPanel Orientation="Horizontal" Margin="0,5,0,5" >
<Button Width="120" Margin="10,5,0,5" Content="导入外部航点" Command="{Binding ImportBlenderWayPointCommand}"/>
<Button Width="120" Margin="10,5,0,5" Content="导入起飞位置" Command="{Binding ImportBlenderCopterPosCommand}"/>
<Button Width="120" Content="计算飞行时间" Margin="10,5,0,5"
Command="{Binding AutoWayPointAllTmCommand}" HorizontalAlignment="Right" />
<Button Width="120" Content="检查飞行时间" Margin="10,5,0,5"
Command="{Binding CheckTmCommand}" HorizontalAlignment="Right" />
<Button Width="120" Content="飞行图案" Margin="10,5,0,5"
Command="{Binding SetHorseRaceLampCommand}" Visibility="Collapsed" HorizontalAlignment="Right" Height="26"/>
</StackPanel>
<Separator Margin="5,0,5,0" />
</StackPanel>
<StackPanel x:Name="PanelDesign2">
<StackPanel Orientation="Horizontal" Margin="0,5,0,5" >
<TextBlock Text="开始任务" Margin="10, 5, 5, 0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBox
Width="35"
Margin="6,5,0,5" Height="26"
HorizontalContentAlignment="Right"
Text="{Binding taskstartno, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="结束任务" Margin="20, 5, 5, 0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBox
Width="35"
Margin="0,5,0,5" Height="26"
HorizontalContentAlignment="Right"
Text="{Binding taskendno, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,5" >
<Button Content="水平旋转" Width="120"
Margin="10,5,0,5" Height="26"
ToolTip="用于整体飞行方向调整,地面飞机矩阵同时旋转"
Command="{Binding TaskRotateCommand}"
CommandParameter="{Binding ElementName=txtAlignmentLine1, Path=Text}"/>
<Button Content="垂直旋转" Width="120"
Margin="10,5,5,5" Height="26"
ToolTip="用于多个任务同时倾斜角度,旋转中心为各任务的共同中心,各任务图案位置尽量重叠"
Command="{Binding MitTaskVrotationCommand}"
CommandParameter="{Binding ElementName=txtAlignmentLine1, Path=Text}" />
<TextBox x:Name="txtAlignmentLine1"
Width="40"
Margin="6,5,0,5" Height="26"
HorizontalContentAlignment="Right"
VerticalContentAlignment="Center"
Text="{Binding taskdirection, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="度" Margin="10, 5, 5, 0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,5" >
<Button Content="调整高度"
Width="120"
Margin="10,5,0,5" Height="26"
Command="{Binding ModiAltCommand}"
CommandParameter="{Binding ElementName=txtModialtvalue, Path=Text}"
/>
<Button Content="移动"
Width="120"
Margin="10,5,0,5" Height="26"
Command="{Binding ModiAllPosCommand}"
CommandParameter="{Binding ElementName=txtModialtvalue, Path=Text}"
/>
<TextBox x:Name="txtModialtvalue"
Grid.Column="1"
Width="40"
Margin="10,5,0,5" Height="26"
HorizontalContentAlignment="Right"
Text="0"/>
<TextBlock Text="米 方向" Margin="10, 5, 5, 0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBox Grid.Column="1" x:Name="txtdirectionvalue"
Width="40"
Margin="0,5,0,5" Height="26"
HorizontalContentAlignment="Right"
Text="{Binding directionvalueall, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="度" Margin="5, 5, 5, 0" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
<Separator Margin="5,0,5,0" />
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,5" >
<Button Content="显示所有航点" Width="120"
Margin="10,5,0,5" Height="26"
Command="{Binding ShowallTaskpointCommand}"
/>
<Button Content="计算任务数" Width="120"
Margin="10,5,0,5" Height="26"
Command="{Binding CheckMissionCountCommand}"
/>
</StackPanel>
</StackPanel>
</TabItem>

View File

@ -17,48 +17,20 @@ using System.Windows.Navigation;
using System.Windows.Shapes;
using Plane.Geography;
using Plane.FormationCreator.Util;
using System.Drawing;
namespace Plane.FormationCreator.Views
{
/// <summary>
/// Interaction logic for ModifyTaskView.xaml
/// </summary>
public partial class ModifyTaskView : UserControl
{
private int[] defcolor= { 255, 65280, 16711680, 65535 , 16711935, 16776960,0 };
ModifyTaskViewModel _modifyTaskViewModel = ServiceLocator.Current.GetInstance<ModifyTaskViewModel>();
CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
private childItem FindVisualChild<childItem>(DependencyObject obj)
where childItem : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is childItem)
{
return (childItem)child;
}
else
{
childItem childOfChild = FindVisualChild<childItem>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}
public ModifyTaskView()
{
InitializeComponent();
this.DataContext = _modifyTaskViewModel;
if (!VersionControl.IsFullVersion)
{
//lightDesign.Visibility = Visibility.Collapsed;
@ -67,15 +39,6 @@ namespace Plane.FormationCreator.Views
private void Button_Click(object sender, RoutedEventArgs e)
{
/*
DependencyObject myListItem = LEDItems.ItemContainerGenerator.ContainerFromItem(LEDItems.Items.CurrentItem);
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListItem);
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
ComboBox ledcomb = (ComboBox)myDataTemplate.FindName("cmbTemplateLEDMode", myContentPresenter);
// ledcomb.SelectedIndex = 2;
*/
// distanceCopters.Text;
/*
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
@ -99,81 +62,5 @@ namespace Plane.FormationCreator.Views
void OnCBLoaded(object sender, EventArgs e)
{
}
private void TextBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
System.Windows.Forms.ColorDialog colorDialog = new System.Windows.Forms.ColorDialog();
colorDialog.CustomColors = defcolor;
try
{
colorDialog.Color = ColorTranslator.FromHtml("#" + (sender as TextBox).Text);
}
catch (Exception)
{
colorDialog.Color = System.Drawing.Color.White;
}
if (colorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
defcolor = colorDialog.CustomColors;
(sender as TextBox).Text = String.Format("{0:X2}", colorDialog.Color.R) +
String.Format("{0:X2}", colorDialog.Color.G) +
String.Format("{0:X2}", colorDialog.Color.B);
}
}
private void cmbTemplateLEDMode_Initialized(object sender, EventArgs e)
{
int selind = 0;
ComboBox cb = (ComboBox)sender;
selind = cb.SelectedIndex;
cb.Items.Clear();
if (_copterManager.FC_VER_NO == 1)
{
cb.Items.Add("常亮"); //0
cb.Items.Add("同步闪烁(单色)"); //1
cb.Items.Add("异步闪烁(随机)"); //2
cb.Items.Add("渐亮"); //3
cb.Items.Add("渐暗"); //4
cb.Items.Add("呼吸灯(单色)"); //5
cb.Items.Add("同步闪烁(随机)"); //6
cb.Items.Add("异步闪烁(单色)"); //7
cb.Items.Add("拉烟"); //8
}
else
{
cb.Items.Add("常亮"); //0
cb.Items.Add("同步闪烁(单色)"); //1
cb.Items.Add("异步闪烁(随机)"); //2
cb.Items.Add("同步闪烁(随机)"); //3
cb.Items.Add("异步闪烁(单色)"); //4
cb.Items.Add("渐亮"); //5
cb.Items.Add("渐暗"); //6
cb.Items.Add("同步呼吸灯(单色)"); //7
cb.Items.Add("同步呼吸灯(随机色)"); //8
cb.Items.Add("异步呼吸(单色)"); //9
cb.Items.Add("异步呼吸(随机色)"); //10
cb.Items.Add("变色(单色)"); //11
cb.Items.Add("变色(随机)"); //12
cb.Items.Add("异步变色(单色)"); //13
cb.Items.Add("异步变色(随机)"); //14
cb.Items.Add("拉烟"); //15
cb.Items.Add("抛物"); //16
}
cb.SelectedIndex = selind;
}
}
}

View File

@ -5,76 +5,42 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
xmlns:c="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d" d:DesignWidth="800"
Height="426" Width="1500" WindowStartupLocation="CenterScreen" Background="#FF2D2D2D" BorderBrush="#FF039AF0" Title="RTK控制" ResizeMode="NoResize">
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="800"
Height="350" Width="1500" WindowStartupLocation="CenterScreen" Background="#FF2D2D2D" BorderBrush="#FF039AF0">
<Grid Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Margin="5" Orientation="Horizontal" VerticalAlignment="Center">
<Border Margin="10,5" BorderBrush="#FFB9B8B8" BorderThickness="1">
<StackPanel Margin="0" Orientation="Vertical">
<StackPanel Margin="0" Orientation="Horizontal">
<ComboBox Width="120" Height="25" Foreground="White" SelectedIndex="0"
Margin="10" ItemsSource="{Binding serialPorts, Mode=OneWay}"
ItemsSource="{Binding serialPorts, Mode=OneWay}"
SelectedValue="{Binding SerialPortsSelectdValue}"
DropDownOpened="ComboBox_DropDownOpened"/>
<Button Margin="6" Width="90" Height="28"
<Button Margin="6" Width="80" Height="28"
Content="{Binding RtcmManager.Rtcmthreadrun,Converter={StaticResource SendConverter}}"
Command="{Binding ConnectRtcmCommand}"/>
<Label Margin="6,6,0,6" Height="28" Content="卫星数:"/>
<Label Margin="6,6,0,6" Height="28" Content="数:"/>
<Label Margin="0,6,6,6" Height="28" Content="{Binding RtcmManager.rtcmInfoList.Count,UpdateSourceTrigger=PropertyChanged}"></Label>
</StackPanel>
<StackPanel Margin="6,0,0,2" Orientation="Horizontal">
<CheckBox x:Name="checkBox" Content="双通道模式 (同时发到广播端口)"
Margin="4,5,5,0" Width="190"
IsChecked="{Binding ResendToComMK}"/>
<CheckBox x:Name="cBsmalldata" Content="低带宽模式"
Margin="20,5,5,0" Width="95"
IsChecked="{Binding SmalldataMK}"/>
</StackPanel>
<StackPanel Margin="6,0,0,2" Orientation="Horizontal">
<TextBlock Margin="23,1,0,0" Text="{Binding BoardPortsStatus}"/>
</StackPanel>
</StackPanel>
</Border>
<Border Margin="10,5" BorderBrush="#FFB9B8B8" BorderThickness="1">
<StackPanel Margin="5" Orientation="Vertical">
<StackPanel Margin="5" Orientation="Horizontal">
<TextBlock Text="接收速率: "/>
<TextBlock Text="Input data rate "/>
<TextBlock TextAlignment="Right" Width="30"
Text="{Binding RtcmManager.Bps}"/>
<TextBlock Text=" 字节/秒;发送速率:"/>
<TextBlock Text=" bps: put data rate "/>
<TextBlock TextAlignment="Right" Width="30"
Text="{Binding RtcmManager.Bpsusefull}"/>
<TextBlock Text=" 字节/秒"/>
<TextBlock Text=" bps sent"/>
</StackPanel>
<StackPanel Margin="5" Orientation="Horizontal">
<TextBlock Text="消息: "/>
<TextBlock Text="{Binding RtcmManager.Messages_seen}"/>
<TextBlock Text="Messages seen "/>
<TextBlock Text="{Binding RtcmManager.Messages_seen}"
/>
</StackPanel>
<StackPanel Margin="0" Orientation="Horizontal">
<TextBlock Margin="5" Text="L1信号强度"/>
<Rectangle Margin="0,0,15,0" Width="20" Height="20" Fill="#3EBE55"/>
<TextBlock Margin="5" Text="L2信号强度"/>
<Rectangle Margin="0,0,15,0" Width="20" Height="20" Fill="#ACACEC"/>
<TextBlock Margin="5" Text="L1/L2重合"/>
<Rectangle Margin="0,0,15,0" Width="20" Height="20" Fill="#04845C"/>
</StackPanel>
</StackPanel>
@ -83,21 +49,21 @@
<Border Margin="10,5" BorderBrush="#FFB9B8B8" BorderThickness="1">
<StackPanel Margin="5" Width="488">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="5" Text="基站位置"/>
<TextBlock Margin="5" Text="Base"/>
<Rectangle Margin="0,0,15,0" Width="20" Height="20"
Fill="{Binding RtcmManager.BaseState,Converter={StaticResource ColorConverter}}"/>
<TextBlock Margin="5" Text="Gps"/>
<Rectangle Margin="0,0,15,0" Width="20" Height="20"
Fill="{Binding RtcmManager.GpsState ,Converter={StaticResource ColorConverter}}"/>
Fill="{Binding RtcmManager.GlonassState,Converter={StaticResource ColorConverter}}"/>
<TextBlock Margin="5" Text="Glonass"/>
<Rectangle Margin="0,0,15,0" Width="20" Height="20"
Fill="{Binding RtcmManager.GlonassState,Converter={StaticResource ColorConverter}}"/>
<TextBlock Margin="5" Text="北斗"/>
Fill="{Binding RtcmManager.GpsState,Converter={StaticResource ColorConverter}}"/>
<TextBlock Margin="5" Text="Beidou"/>
<Rectangle Margin="0,0,15,0" Width="20" Height="20"
Fill="{Binding RtcmManager.BeidouState,Converter={StaticResource ColorConverter}}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" >
<TextBlock Margin="5" Text="RTCM 位置"/>
<TextBlock Margin="5" Text="RTCM Base"/>
<TextBlock Margin="2,5" Text="{Binding RtcmManager.StationLat}"/>
<TextBlock Margin="2,5" Text="{Binding RtcmManager.StationLng}"/>
<TextBlock Margin="2,5" Text="{Binding RtcmManager.StationAlt}"/>
@ -107,12 +73,10 @@
</StackPanel>
</Border>
</StackPanel>
<ItemsControl Grid.Row="1"
ItemsSource="{Binding Path = RtcmManager.rtcmInfoList}" Margin="0,0.333,-0.333,-80" Height="303" VerticalAlignment="Top"
ItemsSource="{Binding Path = RtcmManager.rtcmInfoList}"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
@ -131,28 +95,13 @@
Minimum="25"
Maximum="55"
Grid.RowSpan="2"
Value="{Binding Snr, UpdateSourceTrigger=PropertyChanged}"
/>
<ProgressBar x:Name="BarSnr2"
Margin="0.5"
Orientation="Vertical"
Minimum="25"
Maximum="55"
Grid.RowSpan="2"
Foreground="Blue"
Value="{Binding Snr2, UpdateSourceTrigger=PropertyChanged}"
Opacity="0.25"
/>
<StackPanel Orientation ="Vertical" VerticalAlignment="Top" HorizontalAlignment="Center">
Value="{Binding Snr, UpdateSourceTrigger=PropertyChanged}"/>
<StackPanel Orientation ="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<StackPanel Orientation ="Horizontal">
<TextBlock Text="{Binding Sys,UpdateSourceTrigger=PropertyChanged}" Foreground="Black"></TextBlock>
<TextBlock Text="{Binding Prn,UpdateSourceTrigger=PropertyChanged}" Foreground="Black"></TextBlock>
</StackPanel>
<TextBlock Margin="0,5,0,0" Text="{Binding Snr,UpdateSourceTrigger=PropertyChanged}" Foreground="Black"></TextBlock>
<TextBlock Margin="0,5,0,0" Text="{Binding Snr2,UpdateSourceTrigger=PropertyChanged}" Foreground="Blue" ></TextBlock>
<TextBlock Margin="0,20,0,0" Text="{Binding Snr,UpdateSourceTrigger=PropertyChanged}" Foreground="Black"></TextBlock>
</StackPanel>
<StackPanel Grid.Row="1" Orientation ="Vertical" HorizontalAlignment="Center">
<Line Stroke="Red" X2="1000" StrokeThickness="3" />

View File

@ -5,20 +5,20 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
mc:Ignorable="d"
Title="设置摆放" Height="290.592" Width="364.628" WindowStartupLocation="CenterScreen" WindowStyle="ToolWindow" ResizeMode="NoResize">
<Grid Margin="90,35,90,20">
Title="设置摆放" Height="301.595" Width="364.628" WindowStartupLocation="CenterScreen" WindowStyle="ToolWindow" ResizeMode="NoResize">
<Grid Margin="90,45">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition Height="32"/>
<RowDefinition Height="32"/>
<RowDefinition Height="32"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition Height="28"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Content="每数量" Margin="5,2"></Label>
<Label Content="每数量" Margin="5,2"></Label>
<TextBox Name="textboxColNum" Grid.Column="1" Margin="5" Width="80" ></TextBox>
<Label Content="列间距" Margin="5,2" Grid.Row="1"></Label>

View File

@ -21,15 +21,15 @@
Command="{Binding RunTasksCommand}">
<Button.Template>
<ControlTemplate>
<Grid Width="40"
Height="40"
<Grid Width="30"
Height="30"
Background="#00FFFFFF"
VerticalAlignment="Bottom">
<ed:RegularPolygon Fill="MidnightBlue"
<ed:RegularPolygon Fill="Black"
InnerRadius="1"
PointCount="3"
Width="40"
Height="40"
Width="30"
Height="30"
Stretch="Fill"
Stroke="Gray">
<ed:RegularPolygon.RenderTransform>
@ -37,7 +37,7 @@
<ScaleTransform />
<SkewTransform />
<RotateTransform Angle="90" />
<TranslateTransform X="40" />
<TranslateTransform X="30" />
</TransformGroup>
</ed:RegularPolygon.RenderTransform>
</ed:RegularPolygon>
@ -51,20 +51,20 @@
Command="{Binding PauseTasksCommand}">
<Button.Template>
<ControlTemplate>
<Grid Width="40"
Height="40"
<Grid Width="30"
Height="30"
VerticalAlignment="Bottom"
Background="#00FFFFFF">
<Rectangle Fill="Red"
<Rectangle Fill="Black"
HorizontalAlignment="Left"
Width="15"
Height="40"
Width="10"
Height="30"
Stroke="Gray" />
<Rectangle Fill="Red"
<Rectangle Fill="Black"
Margin="0,0,3,0"
HorizontalAlignment="Right"
Width="15"
Height="40"
Width="10"
Height="30"
Stroke="Gray" />
</Grid>
</ControlTemplate>
@ -90,8 +90,8 @@
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border
Width="88"
<Border Background="{Binding Status, Converter={StaticResource FlightTaskStatusToFillConverter}}"
Width="85"
Height="19"
BorderThickness="1"
BorderBrush="Black"
@ -99,12 +99,6 @@
MouseLeftButtonDown="TaskLeftButtonDown"
MouseLeftButtonUp="SelectTask"
MouseRightButtonUp="HideTask">
<Border.Background>
<MultiBinding Converter="{StaticResource FlightTaskStatusAndTransitionToFillConverter}">
<Binding Path="Status" />
<Binding Path="IsTransition" />
</MultiBinding>
</Border.Background>
<WrapPanel VerticalAlignment="Center"
HorizontalAlignment="Center" >
@ -126,66 +120,53 @@
</ItemsControl.ItemTemplate>
</ItemsControl>
<Grid Grid.Column="2" >
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="28"/>
</Grid.RowDefinitions>
<StackPanel Height="120" Background="#FF2D2D2D" VerticalAlignment="Bottom">
<StackPanel Height="100" Background="#FF2D2D2D" VerticalAlignment="Bottom">
<TextBlock x:Name="hintaddtask" Margin="0,25,0,0" Text="请添加或选择飞行任务" Visibility="Collapsed" FontSize="18" TextAlignment="Center"/>
<TabControl x:Name="tasktabcont"
<TabControl
DataContext="{Binding FlightTaskManager.SelectedTask}"
SelectedIndex="{Binding TaskTypeIndex,UpdateSourceTrigger=PropertyChanged}">
<TabItem Header="1 起飞" x:Name="takeoffpage">
<TabItem Header="起飞">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="起飞时间" Margin="2" VerticalAlignment="Center"/>
<TextBox Grid.Column="1" Margin="2" VerticalAlignment="Center"
<TextBlock Text="起飞时间"/>
<TextBox Grid.Column="1" Margin="2"
Text="{Binding TakeOffTime, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</TabItem>
<TabItem x:Name="flytopage" >
<TabItem.Header>
<Label x:Name="flytoLabel" Content="航点" HorizontalAlignment="Stretch" MouseLeftButtonDown="TaskLabelLeftButtonDown"
ToolTip="双击修改名称" />
</TabItem.Header>
<TabItem Header="航点">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Margin="2" Text="飞行时间: " VerticalAlignment="Center" />
<TextBox Grid.Column="1" Margin="2" VerticalAlignment="Center"
<TextBlock Grid.Row="0" Text="飞行时间: " />
<TextBox Grid.Column="1" Margin="2"
MaxLength="4"
Text="{Binding FlytoTime, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Grid.Row="1" Margin="2" Text="悬停时间: " VerticalAlignment="Center" />
<TextBox Grid.Row="1" Grid.Column="1" Margin="2" VerticalAlignment="Center"
<TextBlock Grid.Row="1" Text="悬停时间: " />
<TextBox Grid.Row="1" Grid.Column="1" Margin="2"
MaxLength="4"
Text="{Binding LoiterTime, UpdateSourceTrigger=PropertyChanged}" />
<CheckBox Grid.Row="2" Grid.Column="2" x:Name="tranBox" Content="过度航点" HorizontalAlignment="Left" Width="75.353"
IsChecked="{Binding IsTransition}"/>
</Grid>
</TabItem>
<TabItem Header="降落" x:Name="landpage">
<TabItem Header="降落">
<Grid Margin="10" >
<Grid.RowDefinitions>
<RowDefinition />
@ -203,27 +184,21 @@
<StackPanel Grid.Row="1"
Orientation="Horizontal"
VerticalAlignment="Bottom">
<Button Content="添加" x:Name="addtaskbtn"
<Button Content="添加任务"
Background="#232323"
Command="{Binding AddTaskCommand}" />
<Button Content="删除"
Background="#232323"
Command="{Binding DelTaskCommand}" />
<Button Content="清除"
<Button Content="清除任务"
Background="#232323"
Command="{Binding ClearTasksCommand}" />
<Button Content="重置"
<Button Content="重置任务"
Background="#232323"
Command="{Binding ResetTasksCommand}" />
<Button Content="更名" Visibility="Collapsed"
<Button Content="强制下一步"
Background="#232323"
Command="{Binding renametaskCommand}" />
<Button Content="原点"
Command="{Binding NextTasksCommand}" />
<Button Content="重设原点"
Background="#232323"
Command="{Binding SetOriginCommand}" />
<!--<Button Content="保存" />
<Button Content="取消" />-->
</StackPanel>

View File

@ -28,164 +28,102 @@ namespace Plane.FormationCreator.Views
InitializeComponent();
this.DataContext = ServiceLocator.Current.GetInstance<TaskBarViewModel>();
hintaddtask.Visibility = Visibility.Visible;
tasktabcont.Visibility = Visibility.Collapsed;
_flightTaskManager.TaskTypeChanged += (sender, e) =>
{
if (e.ChangedFlightTask.TaskType == FlightTaskType.Land)
addtaskbtn.IsEnabled = false;
else addtaskbtn.IsEnabled = true;
};
_flightTaskManager.TaskcnNameChanged += (sender, e) =>
{
if (e.ChangedFlightTask.TaskType == FlightTaskType.Land)
flytoLabel.Content = (_flightTaskManager.SelectedTaskIndex + 1) + " 航点";
else
flytoLabel.Content = (_flightTaskManager.SelectedTaskIndex + 1) + " " + _flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].TaskCnName;
};
_flightTaskManager.PropertyChanged += (sender, e) =>
{
if (_flightTaskManager.SelectedTaskIndex == -1) return;
switch (e.PropertyName)
{
//选中任务时触发--控制任务类型选项卡的显示和是否允许加入新任务
case nameof(FlightTaskManager.SelectedTaskIndex):
if (_flightTaskManager.Tasks.Count == 0)
{
tasktabcont.Visibility = Visibility.Collapsed;
hintaddtask.Visibility = Visibility.Visible;
addtaskbtn.IsEnabled = true;
}
else
{
hintaddtask.Visibility = Visibility.Collapsed;
tasktabcont.Visibility = Visibility.Visible;
//刷新任务编号--可能删除了任务
TasksControl.Items.Refresh();
//起飞任务
if (_flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].TaskType == FlightTaskType.TakeOff)
{
takeoffpage.Visibility = Visibility.Visible;
landpage.Visibility = Visibility.Collapsed;
flytopage.Visibility = Visibility.Collapsed;
}else
//选中中间的任务
if (_flightTaskManager.SelectedTaskIndex < (_flightTaskManager.Tasks.Count - 1))
{
takeoffpage.Visibility = Visibility.Collapsed;
landpage.Visibility = Visibility.Collapsed;
flytopage.Visibility = Visibility.Visible;
flytoLabel.Content = (_flightTaskManager.SelectedTaskIndex+1)+" "+ _flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].TaskCnName;
//允许添加中途任务
addtaskbtn.IsEnabled = true;
}
else
//最后一个任务--只有最后一个任务能设置成降落-防止中途降落
{
takeoffpage.Visibility = Visibility.Collapsed;
landpage.Visibility = Visibility.Visible;
flytopage.Visibility = Visibility.Visible;
//如果不是降落任务
if (_flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].TaskType != FlightTaskType.Land)
{
addtaskbtn.IsEnabled = true;
flytoLabel.Content = (_flightTaskManager.SelectedTaskIndex + 1) + " " + _flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].TaskCnName;
}
else
{
flytoLabel.Content = (_flightTaskManager.SelectedTaskIndex + 1) + " 航点";
addtaskbtn.IsEnabled = false;
}
}
}
break;
// case nameof(FlightTaskManager.SelectedTask .TaskTypeIndex):
default:
break;
}
};
}
private FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
//用于直接飞到航点
public void TaskLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount > 1)
{
_flightTaskManager.FlyToTasks();
}
}
//用于更名
public void TaskLabelLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount > 1)
{
FlightTask task = _flightTaskManager.SelectedTask;
if ((task == null) || (task.TaskType != FlightTaskType.FlyTo)) return;
var elem = sender as FrameworkElement;
var task = elem.DataContext as FlightTask;
if (task.TaskType != FlightTaskType.FlyTo) return;
TasksControl.Focus();
string newName = task.TaskCnName;
if (PlaneMessageBox.OnShow("请输入新的名称", "重命名", ref newName))
{
task.TaskCnName = newName;
}
}
}
//选择任务
private void SelectTask(object sender, MouseButtonEventArgs e)
{
var elem = sender as FrameworkElement;
var task = elem.DataContext as FlightTask;
//if (task.TaskType != FlightTaskType.TakeOff) // 不让选起飞任务。 现在可以选择起飞任务
{
_flightTaskManager.Select(task);
}
}
//以前的右键隐藏航点,已不用
public void setRightSelect(FlightTask task, bool vRightSelect)
{
// var borderBrush = new SolidColorBrush(vRightSelect ? Colors.Gray : Colors.OrangeRed);
var borderBrush = new SolidColorBrush( Colors.OrangeRed);
if (task.TaskType == FlightTaskType.TakeOff) return;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(TasksControl); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(TasksControl, i);
if (child != null && child is FrameworkElement)
{
var taskdata = (child as FrameworkElement).DataContext as FlightTask;
if (taskdata == task)
{
if (child is Rectangle)
{
(child as Rectangle).Stroke = borderBrush;
}
else if (child is Border)
{
(child as Border).BorderBrush = borderBrush;
}
}
}
}
/*
if (elem is Rectangle)
{
(elem as Rectangle).Stroke = borderBrush;
}
else if (elem is Border)
{
(elem as Border).BorderBrush = borderBrush;
}
*/
}
//右键功能 ---隐藏航点
private void HideTask(object sender, MouseButtonEventArgs e)
{
var elem = sender as FrameworkElement;
var task = elem.DataContext as FlightTask;
_flightTaskManager.RightSelect(task);
setRightSelect(task, true);
// int a = _flightTaskManager.RightSelectedTaskIndex;
if (task.TaskType != FlightTaskType.TakeOff) // 不让选起飞任务。
{
var borderBrush = new SolidColorBrush(task.IsRightSelected ? Colors.Gray : Colors.OrangeRed);
if (elem is Rectangle)
{
(elem as Rectangle).Stroke = borderBrush;
}
else if (elem is Border)
{
(elem as Border).BorderBrush = borderBrush;
}
_flightTaskManager.RightSelect(task);
}
}

View File

@ -31,15 +31,20 @@ namespace Plane.FormationCreator.Views
{
InitializeComponent();
ResetCamera();
var camera = view3d.Camera as PerspectiveCamera;
camera.Position = new Point3D(0, 0, 0);
camera.LookDirection = new Vector3D(0, 1, 0);
camera.UpDirection = new Vector3D(0, 0, 1);
camera.FieldOfView = 120;
_flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
_view3DManager = ServiceLocator.Current.GetInstance<View3DViewModel>();
this.DataContext = _view3DManager;
//view3d.ShowCameraInfo = true;
//view3d.ShowFieldOfView = true;
}
public void ResetCamera()
private void ResetCamera_Click(object sender, RoutedEventArgs e)
{
// view3d.CameraController.CameraPosition = new Point3D(0, 40, 1);
// view3d.CameraController.CameraUpDirection = new Vector3D(0, -1, 10);
@ -48,29 +53,12 @@ namespace Plane.FormationCreator.Views
// view3d.CameraController.CameraRotationMode = CameraRotationMode.Turntable;
var camera = view3d.Camera as PerspectiveCamera;
camera.Position = new Point3D(0, 0, 1);
//用于朝向180度
// camera.LookDirection = new Vector3D(-0.025, -0.911, 0.411);
//用于朝向9度
camera.LookDirection = new Vector3D(0, 1, 0.8);
camera.UpDirection = new Vector3D(0.011, 0.411, 0.912);
//用于0度
//camera.LookDirection = new Vector3D(0, 1, 0);
//camera.UpDirection = new Vector3D(0,0, 1);
camera.Position = new Point3D(0, 0, 0);
camera.LookDirection = new Vector3D(0, 1, 0);
camera.UpDirection = new Vector3D(0, 0, 1);
camera.FieldOfView = 120;
_view3DManager.Clear3DCopters();
//for test 用来确定上面的参数
//view3d.ShowCameraInfo = true;
//view3d.ShowFieldOfView = true;
}
private void ResetCamera_Click(object sender, RoutedEventArgs e)
{
ResetCamera();
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Some files were not shown because too many files have changed in this diff Show More