diff --git a/Plane.FormationCreator.sln b/Plane.FormationCreator.sln index ce338a0..5366b41 100644 --- a/Plane.FormationCreator.sln +++ b/Plane.FormationCreator.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34202.233 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 @@ -28,15 +28,9 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlaneGcsSdk.Contract_Shared EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightRoute", "..\FlyTest\FlightRoute\FlightRoute.csproj", "{705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlyBase", "..\FlyCube\FlyBase\FlyBase.csproj", "{626A9BFA-07DE-4063-A178-360EB7057ED6}" +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 @@ -128,4 +122,10 @@ Global 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 diff --git a/Plane.FormationCreator/App.config b/Plane.FormationCreator/App.config index f138028..e7bb9a6 100644 --- a/Plane.FormationCreator/App.config +++ b/Plane.FormationCreator/App.config @@ -1,53 +1,53 @@ - - - - -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - 192.168.1.50 - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + 192.168.1.50 + + + + + + + + + + + + + + + + + + + + + diff --git a/Plane.FormationCreator/App.xaml.cs b/Plane.FormationCreator/App.xaml.cs index ec0aab8..f89c7b6 100644 --- a/Plane.FormationCreator/App.xaml.cs +++ b/Plane.FormationCreator/App.xaml.cs @@ -1,312 +1,313 @@ -using Plane.Communication; -using Plane.Copters; -using Plane.FormationCreator.Formation; -using Plane.Logging; -using Plane.Windows; -using Plane.Windows.Messages; -using GalaSoft.MvvmLight.Ioc; -using Microsoft.Practices.ServiceLocation; -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Diagnostics; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using Plane.CommunicationManagement; -using Plane.FormationCreator.Util; - -namespace Plane.FormationCreator -{ - /// - /// Interaction logic for App.xaml - /// - public partial class App : Application - { - public App() - { - VersionControl.GetSettingFromIni(); - Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US"); - - ServiceLocatorConfigurer.Instance.Configure(); - _logger = ServiceLocator.Current.GetInstance(); - _copterManager = ServiceLocator.Current.GetInstance(); - _formationController = ServiceLocator.Current.GetInstance(); - _mapManager = ServiceLocator.Current.GetInstance(); - - AppDomain.CurrentDomain.AssemblyResolve += (s, e) => - { - var simpleName = new AssemblyName(e.Name).Name; - if (simpleName.EndsWith(".resources")) - { - return null; - } - return LoadAssembly(simpleName); - }; - this.DispatcherUnhandledException += (s, e) => - { - _logger.Log(e.Exception); - // await _formationController.AllStop(); - TcpServerConnectionManager.Instance.StopListening(); - UdpServerConnectionManager.Instance.StopReceiving(); - }; - this.Exit += (s, e) => - { - try - { - // TcpServerConnectionManager.Instance.StopListening(); - UdpServerConnectionManager.Instance.StopReceiving(); - } - catch (Exception ex) - { - // RaiseExceptionThrown(ex); - } - - }; - //new Test().Prepare().Run(); - - - } - - private ILogger _logger; - private CopterManager _copterManager; - private FormationController _formationController; - private MapManager _mapManager; - - private Assembly LoadAssembly(string simpleName) - { - String resourceName = this.GetType().Namespace + ".AssemblyLoadingAndReflection." + simpleName + ".dll"; - using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) - { - Byte[] assemblyData = new Byte[stream.Length]; - stream.Read(assemblyData, 0, assemblyData.Length); - return Assembly.Load(assemblyData); - } - } - - protected override void OnStartup(StartupEventArgs e) - { - base.OnStartup(e); - - var md = Resources.MergedDictionaries; - // md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml") }); - md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml") }); - md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml") }); - md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Colors.xaml") }); - md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Styles.xaml") }); - - md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Plane.Windows.Messages;component/Styles.xaml") }); - - md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles/Colors.xaml") }); - md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles.xaml") }); - /* - new UpdateChecker("http://dl.Plane.com/tools/ver.php?app=FormationCreator", _logger) - .CheckAsync(ver => - { - var currentVersion = this.GetType().Assembly.GetName().Version; - if (currentVersion < ver - && Alert.Show("检测到新版本,请下载。", "更新提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes) - { - Process.Start("http://dl.Plane.com/tools/FormationCreatorSetup.exe"); - this.Shutdown(); - } - }); - */ - System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false; - - MainWindow = new MainWindow(); - MainWindow.Show(); - - - try - { - /* by panxu tcp 不使用了 --使用TCP监听在自动获取IP的情况下,刚开始会导致界面无响应,过一会就好 - TcpServerConnectionManager.Instance.ConnectionEstablished += ConnectionManager_ConnectionEstablished; - if (!TcpServerConnectionManager.Instance.StartListening()) - { - Alert.Show("网络连接不正常,无法连接飞机。"); - return; - } - */ - - 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) - { - Alert.Show("网络连接不正常,无法连接飞机。"); - return; - } - } - - protected override void OnExit(ExitEventArgs e) - { - CommModuleManager.Instance.CloseConnection(); - base.OnExit(e); - } - - - private void Copter_TextReceived(object sender, MessageCreatedEventArgs e) - { - _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); - 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) - }; - int _index; - _index = copters.AddCopter(copter, _copterManager.SortType); - copterStatus.Insert(_index, false); - copter.TextReceived += Copter_TextReceived; - - })); - } - } - else - { - copter.Connection = Connection; - } - if (copter!=null) - await copter.ConnectAsync().ConfigureAwait(false); - } - - private async void ConnectionManager_ConnectionEstablished(object sender, ConnectionEstablishedEventArgs e) - { - await AddOrUpdateCopter(e.RemoteAddress, e.Connection); - } - - private async void CommtionReceivedCopterInfo(object sender, CommunicationReceiveCopterInfoEventArgs e) - { - await UpdateCommCopterInfo(e.Id, e.Package, e.CommModuleVersion); - //await TaskUtils.CompletedTask; - } - - private async void CommCopterDisconnect(object sender, CommunicationCopterDisconnectEventArgs e) - { - await DisconnectCopter(e.Id); - } - - private async void CommCopterconnected(object sender, CommunicationConnectEventArgs e) - { - await AddCommCopter(e.Id); - } - - private async Task DisconnectCopter(int id) - { - var copters = _copterManager.Copters; - var copter = copters.FirstOrDefault(c => c.Id == id.ToString()); - if (copter != null) - { - if (copter is PLCopter) - { - PLCopter plcopter = (PLCopter)copter; - plcopter.CommModuleConnected = false; - } - } - await TaskUtils.CompletedTask; - } - - - private static readonly object locker = new object(); - private async Task AddCommCopter(int id) - { - await Dispatcher.BeginInvoke(new Action(() => - { - 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) - { - Id = id.ToString(), - Name = id.ToString(), - }; - copter.VirtualId = 0; - int _index; - _index = _copterManager.Copters.AddCopter(copter, _copterManager.SortType); - copterStatus.Insert(_index, false); - copter.TextReceived += Copter_TextReceived; - } - } - } - })); - } - - private async Task UpdateCommCopterInfo(int id, byte[] package, byte CommModuleVersion) - { - await AddCommCopter(id); - lock (locker) - { - var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == id.ToString()); - if (copter!= null && copter is PLCopter) - { - PLCopter plcopter = (PLCopter)copter; - if (!plcopter.CommModuleConnected) plcopter.CommModuleConnected = true; - plcopter.InternalCopter.AnalyzeCommMouldePositionIntPacket(package, CommModuleVersion); - plcopter.CommModuleConnected = true; - } - } - - - } - } -} +using Plane.Communication; +using Plane.Copters; +using Plane.FormationCreator.Formation; +using Plane.Logging; +using Plane.Windows; +using Plane.Windows.Messages; +using GalaSoft.MvvmLight.Ioc; +using Microsoft.Practices.ServiceLocation; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; + +using Plane.FormationCreator.Util; +using Plane.CommunicationManagement; + +namespace Plane.FormationCreator +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + public App() + { + VersionControl.GetSettingFromIni(); + Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US"); + + ServiceLocatorConfigurer.Instance.Configure(); + _logger = ServiceLocator.Current.GetInstance(); + _copterManager = ServiceLocator.Current.GetInstance(); + _formationController = ServiceLocator.Current.GetInstance(); + _mapManager = ServiceLocator.Current.GetInstance(); + + AppDomain.CurrentDomain.AssemblyResolve += (s, e) => + { + var simpleName = new AssemblyName(e.Name).Name; + if (simpleName.EndsWith(".resources")) + { + return null; + } + return LoadAssembly(simpleName); + }; + this.DispatcherUnhandledException += (s, e) => + { + _logger.Log(e.Exception); + // await _formationController.AllStop(); + TcpServerConnectionManager.Instance.StopListening(); + UdpServerConnectionManager.Instance.StopReceiving(); + }; + this.Exit += (s, e) => + { + try + { + // TcpServerConnectionManager.Instance.StopListening(); + UdpServerConnectionManager.Instance.StopReceiving(); + } + catch (Exception ex) + { + // RaiseExceptionThrown(ex); + } + + }; + //new Test().Prepare().Run(); + + + } + + private ILogger _logger; + private CopterManager _copterManager; + private FormationController _formationController; + private MapManager _mapManager; + + private Assembly LoadAssembly(string simpleName) + { + String resourceName = this.GetType().Namespace + ".AssemblyLoadingAndReflection." + simpleName + ".dll"; + using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) + { + Byte[] assemblyData = new Byte[stream.Length]; + stream.Read(assemblyData, 0, assemblyData.Length); + return Assembly.Load(assemblyData); + } + } + + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); + + var md = Resources.MergedDictionaries; + // md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml") }); + md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml") }); + md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml") }); + md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Colors.xaml") }); + md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Styles.xaml") }); + + md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Plane.Windows.Messages;component/Styles.xaml") }); + + md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles/Colors.xaml") }); + md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles.xaml") }); + /* + new UpdateChecker("http://dl.Plane.com/tools/ver.php?app=FormationCreator", _logger) + .CheckAsync(ver => + { + var currentVersion = this.GetType().Assembly.GetName().Version; + if (currentVersion < ver + && Alert.Show("检测到新版本,请下载。", "更新提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes) + { + Process.Start("http://dl.Plane.com/tools/FormationCreatorSetup.exe"); + this.Shutdown(); + } + }); + */ + System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false; + + MainWindow = new MainWindow(); + MainWindow.Show(); + + + try + { + /* by panxu tcp 不使用了 --使用TCP监听在自动获取IP的情况下,刚开始会导致界面无响应,过一会就好 + TcpServerConnectionManager.Instance.ConnectionEstablished += ConnectionManager_ConnectionEstablished; + if (!TcpServerConnectionManager.Instance.StartListening()) + { + Alert.Show("网络连接不正常,无法连接飞机。"); + return; + } + */ + + 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) + { + Alert.Show("网络连接不正常,无法连接飞机。"); + return; + } + } + + protected override void OnExit(ExitEventArgs e) + { + CommModuleManager.Instance.CloseConnection(); + base.OnExit(e); + } + + + private void Copter_TextReceived(object sender, MessageCreatedEventArgs e) + { + _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); + 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) + }; + int _index; + _index = copters.AddCopter(copter, _copterManager.SortType); + copterStatus.Insert(_index, false); + copter.TextReceived += Copter_TextReceived; + + })); + } + } + else + { + copter.Connection = Connection; + } + if (copter!=null) + await copter.ConnectAsync().ConfigureAwait(false); + } + + private async void ConnectionManager_ConnectionEstablished(object sender, ConnectionEstablishedEventArgs e) + { + await AddOrUpdateCopter(e.RemoteAddress, e.Connection); + } + + private async void CommtionReceivedCopterInfo(object sender, CommunicationReceiveCopterInfoEventArgs e) + { + await UpdateCommCopterInfo(e.Id, e.Package, e.CommModuleVersion); + //await TaskUtils.CompletedTask; + } + + private async void CommCopterDisconnect(object sender, CommunicationCopterDisconnectEventArgs e) + { + await DisconnectCopter(e.Id); + } + + private async void CommCopterconnected(object sender, CommunicationConnectEventArgs e) + { + await AddCommCopter(e.Id); + } + + private async Task DisconnectCopter(int id) + { + var copters = _copterManager.Copters; + var copter = copters.FirstOrDefault(c => c.Id == id.ToString()); + if (copter != null) + { + if (copter is PLCopter) + { + PLCopter plcopter = (PLCopter)copter; + plcopter.CommModuleConnected = false; + } + } + await TaskUtils.CompletedTask; + } + + + private static readonly object locker = new object(); + private async Task AddCommCopter(int id) + { + await Dispatcher.BeginInvoke(new Action(() => + { + 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) + { + Id = id.ToString(), + Name = id.ToString(), + }; + copter.VirtualId = 0; + int _index; + _index = _copterManager.Copters.AddCopter(copter, _copterManager.SortType); + copterStatus.Insert(_index, false); + copter.TextReceived += Copter_TextReceived; + } + } + } + })); + } + + private async Task UpdateCommCopterInfo(int id, byte[] package, byte CommModuleVersion) + { + await AddCommCopter(id); + lock (locker) + { + var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == id.ToString()); + if (copter!= null && copter is PLCopter) + { + PLCopter plcopter = (PLCopter)copter; + if (!plcopter.CommModuleConnected) plcopter.CommModuleConnected = true; + plcopter.InternalCopter.AnalyzeCommMouldePositionIntPacket(package, CommModuleVersion); + plcopter.CommModuleConnected = true; + } + } + + + } + } +} diff --git a/Plane.FormationCreator/Formation/CopterManager.cs b/Plane.FormationCreator/Formation/CopterManager.cs index 13a7818..8d05899 100644 --- a/Plane.FormationCreator/Formation/CopterManager.cs +++ b/Plane.FormationCreator/Formation/CopterManager.cs @@ -1,870 +1,870 @@ -using Plane.Copters; -using GalaSoft.MvvmLight; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -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 - { - //软件过期时间---过期将无法添加飞机,并自动退出 - public static DateTime Expire_App = DateTime.Parse("2023-12-31"); - //超级用户过期时间--过期将无法使用内置超级用户登录 - public static DateTime Expire_SuperUser = Expire_App; - //允许飞行的飞机数量 - public int EnCopterNumber = 0; - //允许模拟的飞机数量 - public int EnVCopterNumber = 0; - - - - /// - /// 实现排序插入 - /// - /// - public int AddCopter(ICopter entityObject, CopterManager.CopterSortType vSortType) - { - - //新增飞机区域限制:内蒙 -// if (entityObject.Latitude < 37.4307185218 || entityObject.Latitude > 45.6754821756 -// || entityObject.Longitude < 97.3493089056 || entityObject.Longitude > 115.8006783856) -// return 0; - - if (DateTime.UtcNow > Expire_App) - { - 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) - { - Add(entityObject); - _index = 0; - } - 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)) - { - InsertItem(i, entityObject); - isInsret = true; - _index = i; - break; - } - } - else - //按VID排序插入 - { - if (this[i].VirtualId > entityObject.VirtualId) - { - - InsertItem(i, entityObject); - isInsret = true; - _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; - } - } - - - 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) => - { - RaisePropertyChanged(nameof(Copters)); - }; - App.Current.Exit += (sender, e) => - { - 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 ShowCopter = new List(); - - - //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 Copters - //{ - // get - // { - // switch (AppEx.Instance.CurrentMode) - // { - // case AppMode.ControllingCopters: - // default: - // return CoptersForControlling; - // case AppMode.PreparedForRunningTasks: - // case AppMode.ModifyingTask: - // return CoptersForModifyingTask; - // case AppMode.RunningTasks: - // throw new NotImplementedException(); - // } - // } - //} - - - - 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 Mlist = new List(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 Mlist = new List(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 SelectedCopters { get { return _selectedCoptersGetter().Cast(); } } - - /// - /// 注意:为避免多线程操作出问题,每次使用此属性时都会新建一个 List! - /// - public IEnumerable AcceptingControlCopters { get { return SelectedCopters.ToList(); } } - private int _SeletedCopterCount; - public int SeletedCopterCount - { - get { return _SeletedCopterCount; } - set { Set(nameof(SeletedCopterCount), ref _SeletedCopterCount, value); } - } - - private Func _selectedCoptersGetter; - - private Action _selectCopterAction; - - public void SetSelectionDelegates(Func selectedCoptersGetter, Action selectCopterAction) - { - _selectedCoptersGetter = selectedCoptersGetter; - _selectCopterAction = selectCopterAction; - } - - public event EventHandler SelectedCoptersChanged; - - public void RaiseSelectedCoptersChanged(IEnumerable addedCopters, IEnumerable removedCopters) - { - SelectedCoptersChanged?.Invoke(this, new SelectedCoptersChangedEventArgs { AddedCopters = addedCopters, RemovedCopters = removedCopters }); - 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; - } - - - /// - /// 选择飞机 - /// - /// Null表示清除所有选择 - public void Select(ICopter copter) - { - _selectCopterAction(copter); - } - /// - /// 按VID重新排序飞机 - /// - public void sortbyvid(bool displayid=false) - { - List tempCopters = new List(); - tempCopters.AddRange(Copters); - Copters.Clear(); - foreach (var copter in tempCopters) - Copters.AddCopter(copter,SortType); - } - /// - /// 按原始ID重新排序飞机 - /// - public void sortbyid() - { - List tempCopters = new List(); - tempCopters.AddRange(Copters); - Copters.Clear(); - foreach (var copter in tempCopters) - Copters.AddCopter(copter,SortType); - - } - - } - - public class SelectedCoptersChangedEventArgs : EventArgs - { - public IEnumerable AddedCopters { get; set; } - public IEnumerable RemovedCopters { get; set; } - } -} +using Plane.Copters; +using GalaSoft.MvvmLight; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +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 + { + //软件过期时间---过期将无法添加飞机,并自动退出 + 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; + + + + /// + /// 实现排序插入 + /// + /// + public int AddCopter(ICopter entityObject, CopterManager.CopterSortType vSortType) + { + + //新增飞机区域限制:内蒙 +// if (entityObject.Latitude < 37.4307185218 || entityObject.Latitude > 45.6754821756 +// || entityObject.Longitude < 97.3493089056 || entityObject.Longitude > 115.8006783856) +// return 0; + + if (DateTime.UtcNow > Expire_App) + { + 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) + { + Add(entityObject); + _index = 0; + } + 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)) + { + InsertItem(i, entityObject); + isInsret = true; + _index = i; + break; + } + } + else + //按VID排序插入 + { + if (this[i].VirtualId > entityObject.VirtualId) + { + + InsertItem(i, entityObject); + isInsret = true; + _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; + } + } + + + 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) => + { + RaisePropertyChanged(nameof(Copters)); + }; + App.Current.Exit += (sender, e) => + { + 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 ShowCopter = new List(); + + + //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 Copters + //{ + // get + // { + // switch (AppEx.Instance.CurrentMode) + // { + // case AppMode.ControllingCopters: + // default: + // return CoptersForControlling; + // case AppMode.PreparedForRunningTasks: + // case AppMode.ModifyingTask: + // return CoptersForModifyingTask; + // case AppMode.RunningTasks: + // throw new NotImplementedException(); + // } + // } + //} + + + + 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 Mlist = new List(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 Mlist = new List(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 SelectedCopters { get { return _selectedCoptersGetter().Cast(); } } + + /// + /// 注意:为避免多线程操作出问题,每次使用此属性时都会新建一个 List! + /// + public IEnumerable AcceptingControlCopters { get { return SelectedCopters.ToList(); } } + private int _SeletedCopterCount; + public int SeletedCopterCount + { + get { return _SeletedCopterCount; } + set { Set(nameof(SeletedCopterCount), ref _SeletedCopterCount, value); } + } + + private Func _selectedCoptersGetter; + + private Action _selectCopterAction; + + public void SetSelectionDelegates(Func selectedCoptersGetter, Action selectCopterAction) + { + _selectedCoptersGetter = selectedCoptersGetter; + _selectCopterAction = selectCopterAction; + } + + public event EventHandler SelectedCoptersChanged; + + public void RaiseSelectedCoptersChanged(IEnumerable addedCopters, IEnumerable removedCopters) + { + SelectedCoptersChanged?.Invoke(this, new SelectedCoptersChangedEventArgs { AddedCopters = addedCopters, RemovedCopters = removedCopters }); + 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; + } + + + /// + /// 选择飞机 + /// + /// Null表示清除所有选择 + public void Select(ICopter copter) + { + _selectCopterAction(copter); + } + /// + /// 按VID重新排序飞机 + /// + public void sortbyvid(bool displayid=false) + { + List tempCopters = new List(); + tempCopters.AddRange(Copters); + Copters.Clear(); + foreach (var copter in tempCopters) + Copters.AddCopter(copter,SortType); + } + /// + /// 按原始ID重新排序飞机 + /// + public void sortbyid() + { + List tempCopters = new List(); + tempCopters.AddRange(Copters); + Copters.Clear(); + foreach (var copter in tempCopters) + Copters.AddCopter(copter,SortType); + + } + + } + + public class SelectedCoptersChangedEventArgs : EventArgs + { + public IEnumerable AddedCopters { get; set; } + public IEnumerable RemovedCopters { get; set; } + } +} diff --git a/Plane.FormationCreator/Formation/FlightTaskManager.cs b/Plane.FormationCreator/Formation/FlightTaskManager.cs index 89fb93f..b1082f4 100644 --- a/Plane.FormationCreator/Formation/FlightTaskManager.cs +++ b/Plane.FormationCreator/Formation/FlightTaskManager.cs @@ -1,5 +1,4 @@ -using Plane.Collections; -using Plane.Copters; +using Plane.Copters; using Plane.Geography; using Plane.Windows.Messages; using GalaSoft.MvvmLight; @@ -10,14 +9,19 @@ using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; -using Plane.CommunicationManagement; + using FlightRoute; +using FlightRouteV2; using System.IO; using System.Windows.Media.Media3D; using System.Diagnostics; -using Plane.FormationCreator.Util; using System.Collections; using System.Windows; +using System.Threading; +using Plane.CommunicationManagement; +using Microsoft.Practices.ServiceLocation; +using Plane.FormationCreator.ViewModels; +using MahApps.Metro.Controls; namespace Plane.FormationCreator.Formation { @@ -27,7 +31,7 @@ namespace Plane.FormationCreator.Formation { LoadIni(); _copterManager = copterManager; - + //AddTakeOffTask(_copterManager.Copters); _copterManager.Copters.CollectionChanged += (sender, e) => @@ -66,11 +70,11 @@ namespace Plane.FormationCreator.Formation } } } - if (selectedCopter!=null) - selectedCopter.SetShowLEDFlashAsync(1, 100); + if (selectedCopter != null) + selectedCopter.SetShowLEDFlashAsync(1, 100); //if (selectedCopter != null) - //selectedCopter.LEDAsync(); + //selectedCopter.LEDAsync(); }; TaskAdded += (sender, e) => @@ -98,7 +102,7 @@ namespace Plane.FormationCreator.Formation - private string _MessageText="test"; + private string _MessageText = "test"; public string MessageText { get { return _MessageText; } @@ -106,7 +110,7 @@ namespace Plane.FormationCreator.Formation { if (Set(nameof(MessageText), ref _MessageText, value)) { - // _lastUpdateStatusTextTime = DateTime.Now; + // _lastUpdateStatusTextTime = DateTime.Now; } } } @@ -120,7 +124,7 @@ namespace Plane.FormationCreator.Formation { if (Set(nameof(TaskRun_2D), ref _TaskRun_2D, value)) { - + } } } @@ -155,7 +159,7 @@ namespace Plane.FormationCreator.Formation public int GetTaskTime(int TaskIndex) { int tasktime = 0; - if ((Tasks==null)|| TaskIndex> Tasks.Count-1) return tasktime; + if ((Tasks == null) || TaskIndex > Tasks.Count - 1) return tasktime; FlightTask value = Tasks[TaskIndex]; switch (value.TaskType) @@ -165,12 +169,12 @@ namespace Plane.FormationCreator.Formation //降落时间计算前一个任务目标高度最高的飞机的降落时间按1.5米/秒下降 case FlightTaskType.Land: float maxalt = 0.0f; - for (int i = 0; i < Tasks[TaskIndex-1].SingleCopterInfos.Count; i++) + for (int i = 0; i < Tasks[TaskIndex - 1].SingleCopterInfos.Count; i++) { var copterInfo = Tasks[TaskIndex - 1].SingleCopterInfos[i]; if (maxalt < copterInfo.TargetAlt) maxalt = copterInfo.TargetAlt; } - tasktime =(int) Math.Round(maxalt / 1.5,0); + tasktime = (int)Math.Round(maxalt / 1.5, 0); break; } return tasktime; @@ -188,7 +192,7 @@ namespace Plane.FormationCreator.Formation { if (_SelectedTask != value) { - int starttime=0; + int starttime = 0; if (_SelectedTask != null) { @@ -203,7 +207,7 @@ namespace Plane.FormationCreator.Formation value.IsSelected = true; value.IsRightSelected = true; RightSelect(value); - if (TaskState== TasksStatus.Stop) + if (TaskState == TasksStatus.Stop) value.Status = FlightTaskStatus.Selected; for (int i = 0; i < value.TaskIndex; i++) @@ -240,7 +244,7 @@ namespace Plane.FormationCreator.Formation } - Message.ShowStatus($"选中 [{value.TaskIndex+1} {value.TaskCnName }] 从{str}开始执行,需{ GetTaskTime(value.TaskIndex)}秒,共{Tasks.Count}个任务"); + Message.ShowStatus($"选中 [{value.TaskIndex + 1} {value.TaskCnName}] 从{str}开始执行,需{GetTaskTime(value.TaskIndex)}秒,共{Tasks.Count}个任务"); } else Message.ShowStatus($"无任务选中"); @@ -254,18 +258,18 @@ namespace Plane.FormationCreator.Formation { get { return _SelectedTaskIndex; } set { Set(nameof(SelectedTaskIndex), ref _SelectedTaskIndex, value); - // this.SelectedTask = Tasks[value]; + // this.SelectedTask = Tasks[value]; } } - // 右键单击任务,用于隐藏任务图标, added by ZJF + // 右键单击任务,用于隐藏任务图标, added by ZJF private int _RightSelectedTaskIndex; public int RightSelectedTaskIndex { get { return _RightSelectedTaskIndex; } set { Set(nameof(RightSelectedTaskIndex), ref _RightSelectedTaskIndex, value); } } - + private FlightTask _CurrentRunningTask; public FlightTask CurrentRunningTask { @@ -385,11 +389,11 @@ namespace Plane.FormationCreator.Formation public event EventHandler TaskAdded; public event EventHandler TaskDeled; - public void RaiseTaskDeled(FlightTask vDeledTask,int vTaskIndex) + public void RaiseTaskDeled(FlightTask vDeledTask, int vTaskIndex) { try { - TaskDeled?.Invoke(this, new FlightTaskDeledEventArgs { DeledTask = vDeledTask, TaskIndex= vTaskIndex }); + TaskDeled?.Invoke(this, new FlightTaskDeledEventArgs { DeledTask = vDeledTask, TaskIndex = vTaskIndex }); } catch (Exception ex) { @@ -398,7 +402,7 @@ namespace Plane.FormationCreator.Formation } - public void RaiseTaskAdded(FlightTask lastTask ,FlightTask newTask) + public void RaiseTaskAdded(FlightTask lastTask, FlightTask newTask) { try { @@ -451,7 +455,7 @@ namespace Plane.FormationCreator.Formation if (Tasks.Count == 0) AddTakeOffTask(copters); var lastTask = Tasks.LastOrDefault(); - if (SelectedTask !=null) + if (SelectedTask != null) lastTask = SelectedTask; var nullableCenter = copters.GetCenter(); if (nullableCenter == null) return; @@ -501,8 +505,8 @@ namespace Plane.FormationCreator.Formation newTask.SingleCopterInfos.Add(newSingleCopterInfo); } - int selindex = SelectedTaskIndex+1; - Tasks.Insert(SelectedTaskIndex+1, newTask); + int selindex = SelectedTaskIndex + 1; + Tasks.Insert(SelectedTaskIndex + 1, newTask); RaiseTaskAdded(lastTask, newTask); SelectTask(selindex); @@ -511,7 +515,7 @@ namespace Plane.FormationCreator.Formation { SelectedTask.FlytoTime = 2; SelectedTask.LoiterTime = 2; - foreach (FlightTaskSingleCopterInfo info in SelectedTask.SingleCopterInfos) + foreach (FlightTaskSingleCopterInfo info in SelectedTask.SingleCopterInfos) { info.TargetLat = info.Copter.Latitude; info.TargetLng = info.Copter.Longitude; @@ -600,10 +604,10 @@ namespace Plane.FormationCreator.Formation } */ - TasksCleared?.Invoke(this, EventArgs.Empty); - // AddTakeOffTask(_copterManager.Copters); + TasksCleared?.Invoke(this, EventArgs.Empty); + // AddTakeOffTask(_copterManager.Copters); } - //删除选中的任务 + //删除选中的任务 public void DelSelectedTask() { if (SelectedTask == null) return; @@ -613,12 +617,12 @@ namespace Plane.FormationCreator.Formation // ResetTasks(); SelectedTask.SingleCopterInfos.Clear(); Tasks.RemoveAt(SelectedTaskIndex); - RaiseTaskDeled(SelectedTask,SelectedTaskIndex); - + RaiseTaskDeled(SelectedTask, SelectedTaskIndex); + SelectTask(selindex - 1); - - // SelectedTaskIndex = 0; + + // SelectedTaskIndex = 0; } @@ -631,7 +635,7 @@ namespace Plane.FormationCreator.Formation Pause(); int i = 0; //等待暂停或2s超时(80*25ms) - while ((TaskState != TasksStatus.Paused)||(i>80)) + while ((TaskState != TasksStatus.Paused) || (i > 80)) { await Task.Delay(25).ConfigureAwait(false); i++; @@ -643,8 +647,8 @@ namespace Plane.FormationCreator.Formation CurrentRunningTask = null; //起飞任务需要跳过 -// if (CurrentRunningTaskIndex == 0) -// CurrentRunningTaskIndex++; + // if (CurrentRunningTaskIndex == 0) + // CurrentRunningTaskIndex++; CurrentRunningTaskIndex++; await RunTaskAsync(); } @@ -654,10 +658,10 @@ namespace Plane.FormationCreator.Formation public async Task FlyToTasks() { var copters = _copterManager.Copters; - if ((SelectedTaskIndex==-1) ||(TaskState == TasksStatus.Stop)) + if ((SelectedTaskIndex == -1) || (TaskState == TasksStatus.Stop)) return; - int vSelectedTaskIndex= SelectedTaskIndex; + int vSelectedTaskIndex = SelectedTaskIndex; Pause(); int i = 0; @@ -676,7 +680,7 @@ namespace Plane.FormationCreator.Formation CurrentRunningTask = null; CurrentRunningTaskIndex = SelectedTaskIndex; - + //设置所有模拟飞机的位置 for (int j = 0; j < copters.Count; j++) @@ -705,7 +709,7 @@ namespace Plane.FormationCreator.Formation lng = Tasks[0].SingleCopterInfos[j].TargetLng; } else - { + { //用前一个任务目标位置 lat = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].TargetLat; @@ -729,10 +733,10 @@ namespace Plane.FormationCreator.Formation - //起飞任务需要跳过 - // if (CurrentRunningTaskIndex == 0) - // CurrentRunningTaskIndex++; - + //起飞任务需要跳过 + // if (CurrentRunningTaskIndex == 0) + // CurrentRunningTaskIndex++; + await RunTaskAsync(); } } @@ -765,7 +769,7 @@ namespace Plane.FormationCreator.Formation CurrentRunningTask.Status = FlightTaskStatus.Stop; CurrentRunningTask = null; } - + for (int i = 0; i < Tasks.Count; i++) { // 将起飞的阶段标志位都置位0 @@ -779,7 +783,7 @@ namespace Plane.FormationCreator.Formation } } - + } @@ -793,7 +797,7 @@ namespace Plane.FormationCreator.Formation fc.SetProperties( latitude: Tasks[0].SingleCopterInfos[j].TargetLat, longitude: Tasks[0].SingleCopterInfos[j].TargetLng, - altitude: 0 ); + altitude: 0); //设置灯光为默认颜色 fc.LEDColor = CopterManager.CopterDefaultColor;// "000000"; fc.LEDMode = 0; @@ -822,7 +826,7 @@ namespace Plane.FormationCreator.Formation sb.AppendLine($"{i + 1} 0 {x} {y} {z}"); //lines[i] = $"{i+1} {x} {y} {z}"; } - + return sb.ToString().Trim(); } @@ -900,15 +904,15 @@ namespace Plane.FormationCreator.Formation Tasks.Add(newTask); RaiseTaskAdded(lastTask, newTask); } - + } public void ImportDlltoVCopter(string filename) { - Vector3[] vc; + FlightRoute.Vector3[] vc; + - string extname = Path.GetExtension(filename); @@ -927,8 +931,8 @@ namespace Plane.FormationCreator.Formation Alert.Show($"飞机数量不匹配!导入{vc.Count()}架,实际{_copterManager.Copters.Count}"); return; } - int id = 0; - foreach (Vector3 item in vc) + int id = 0; + foreach (FlightRoute.Vector3 item in vc) { Tuple observationLatLng = null; observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( @@ -954,15 +958,15 @@ namespace Plane.FormationCreator.Formation longitude: vlongitude, altitude: (float)item.y / 100); id++; - + } - } + } //导入外部航点 public void ImportDlltoTask(string filename) { - Vector3[] vc; + FlightRoute.Vector3[] vc; string extname = Path.GetExtension(filename); @@ -976,18 +980,18 @@ namespace Plane.FormationCreator.Formation } else return; - if (vc.Count()!= _copterManager.Copters.Count) + if (vc.Count() != _copterManager.Copters.Count) { Alert.Show($"飞机数量不匹配!导入{vc.Count()}架,实际{_copterManager.Copters.Count}"); return; } var lastTask = Tasks.LastOrDefault(); var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = true, FlytoTime = 10, LoiterTime = 1 }; - string vname=Path.GetFileNameWithoutExtension(filename); - if (vname.Length>6) vname= vname.Substring(0, 6); + string vname = Path.GetFileNameWithoutExtension(filename); + if (vname.Length > 6) vname = vname.Substring(0, 6); newTask.TaskCnName = vname; - int id =0; - foreach (Vector3 item in vc) + int id = 0; + foreach (FlightRoute.Vector3 item in vc) { Tuple observationLatLng = null; observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( @@ -1035,10 +1039,10 @@ namespace Plane.FormationCreator.Formation { //去掉前后的"[]" string taskName_temp = taskName.Substring(1); - taskName_temp= taskName_temp.Remove(taskName_temp.Length - 1); + taskName_temp = taskName_temp.Remove(taskName_temp.Length - 1); //新版用":"分割时间 string[] words = taskName_temp.Split(':'); - if (words.Count()==2) + if (words.Count() == 2) { taskName = words[0]; flytime = int.Parse(words[1]); @@ -1095,7 +1099,7 @@ namespace Plane.FormationCreator.Formation Tasks.Add(newTask); RaiseTaskAdded(lastTask, newTask); } - // Alert.Show("导入完成!"); + // Alert.Show("导入完成!"); /* Dictionary PointDic = new Dictionary(); foreach (string line in lines) @@ -1148,7 +1152,7 @@ namespace Plane.FormationCreator.Formation public void ImportBlenderFlyToTask(string blenderVectors) { - string[] lineVectors = blenderVectors.Replace("\r\n","\n").Split('\n'); + string[] lineVectors = blenderVectors.Replace("\r\n", "\n").Split('\n'); var lastTask = Tasks.LastOrDefault(); float alt = lastTask.SingleCopterInfos[0].TargetAlt; @@ -1203,7 +1207,7 @@ namespace Plane.FormationCreator.Formation if (nullableCenter == null) return; var center = nullableCenter.Value; var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = staggerRoutes, FlytoTime = flytoTime, LoiterTime = loiterTime }; - if(taskName != null) newTask.TaskCnName = taskName; + if (taskName != null) newTask.TaskCnName = taskName; // TODO: 王海, 20150801, 处理实际飞行器数目与记录中数目不一致的情况。 for (int i = 0; i < copters.Count; i++) { @@ -1216,9 +1220,9 @@ namespace Plane.FormationCreator.Formation if (isMeter) newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( copter, - (double)singleCopterInfoObj.x, + (double)singleCopterInfoObj.x, (double)singleCopterInfoObj.y, - (float)singleCopterInfoObj.targetAlt - copter.GroundAlt, + (float)singleCopterInfoObj.targetAlt - copter.GroundAlt, (bool)singleCopterInfoObj.isLandWaypoint); else newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( @@ -1228,7 +1232,7 @@ namespace Plane.FormationCreator.Formation var jsonArray = singleCopterInfoObj.ledInfos as Newtonsoft.Json.Linq.JArray; ObservableCollection ledList = jsonArray.ToObject>(); - foreach(LEDInfo info in ledList) + foreach (LEDInfo info in ledList) { newSingleCopterInfo.AddLEDInfo(info); } @@ -1257,7 +1261,7 @@ namespace Plane.FormationCreator.Formation RaiseTaskAdded(lastTask, newTask); } - + private void RestoreTakeOffTask(byte takeOffTime, dynamic singleCopterInfos) { var copters = _copterManager.Copters; @@ -1270,7 +1274,7 @@ namespace Plane.FormationCreator.Formation { var singleCopterInfoObj = singleCopterInfos[i]; takeOffTask.SingleCopterInfos[i].TakeOffWaitTime = (ushort)singleCopterInfoObj.waitTime; - if (singleCopterInfoObj.ledInfos!= null) + if (singleCopterInfoObj.ledInfos != null) { var jsonArray = singleCopterInfoObj.ledInfos as Newtonsoft.Json.Linq.JArray; ObservableCollection ledList = jsonArray.ToObject>(); @@ -1279,7 +1283,7 @@ namespace Plane.FormationCreator.Formation takeOffTask.SingleCopterInfos[i].AddLEDInfo(info); } } - + //Message.Show(((ushort)singleCopterInfoObj.waitTime).ToString()); } } @@ -1305,7 +1309,7 @@ namespace Plane.FormationCreator.Formation } - + //导出任务 (单位:米) public IEnumerable ExportTasksToMeter() @@ -1355,7 +1359,7 @@ namespace Plane.FormationCreator.Formation }; }) }; - + case FlightTaskType.Land: { @@ -1369,7 +1373,7 @@ namespace Plane.FormationCreator.Formation waitTime = info.LandWaitTime }; }) - + }; } default: @@ -1518,7 +1522,7 @@ namespace Plane.FormationCreator.Formation }; }) }; - + case FlightTaskType.Land: { @@ -1532,7 +1536,7 @@ namespace Plane.FormationCreator.Formation waitTime = info.LandWaitTime }; }) - + }; } default: @@ -1544,7 +1548,7 @@ namespace Plane.FormationCreator.Formation //导入任务,可设置导入哪些步骤 - public void ImportTasksindex(dynamic tasks, int startindex,int endindex, bool isMeter) + public void ImportTasksindex(dynamic tasks, int startindex, int endindex, bool isMeter) { var copters = _copterManager.Copters; @@ -1552,22 +1556,22 @@ namespace Plane.FormationCreator.Formation AddTakeOffTask(copters); - int i =1; + int i = 1; foreach (var task in tasks) { - if ((i >= startindex)&& (i <= endindex)) + if ((i >= startindex) && (i <= endindex)) { switch ((FlightTaskType)task.type) { case FlightTaskType.TakeOff: // AddTakeOffTask(copters); // added by ZJF // TakeOffNumAttr = task.takeoffnumber; - // TakeOffNumAttr= task.takeoffnumber; + // TakeOffNumAttr= task.takeoffnumber; RestoreTakeOffTask((byte)task.takeoffTime, task.singleCopterInfos); break; case FlightTaskType.FlyTo: RestoreFlyToTask((bool)task.staggerRoutes, (int)task.flytoTime, (int)task.loiterTime, (string)task.taskname, task.singleCopterInfos, isMeter); - break; + break; case FlightTaskType.Land: RestoreLandTask(task.singleCopterInfos); break; @@ -1617,7 +1621,7 @@ namespace Plane.FormationCreator.Formation } - public double SumFlyLines(List preinfos, List currinfos) + public double SumFlyLines(List preinfos, List currinfos) { double sumdis = 0; for (int i = 0; i < _copterManager.Copters.Count; i++) @@ -1637,8 +1641,8 @@ namespace Plane.FormationCreator.Formation //从2开始自动计算 - // Tasks[1].FlytoTime = 2; - // Tasks[1].LoiterTime = 1; + // Tasks[1].FlytoTime = 2; + // Tasks[1].LoiterTime = 1; for (int taskIndex = 0; taskIndex < Tasks.Count; taskIndex++) SetTaskFlytime(taskIndex); @@ -1681,7 +1685,7 @@ namespace Plane.FormationCreator.Formation speed = curWaypoint.LevelSpeed; break; } - } + } } double maxDistance = 0.0f; string copterName = ""; @@ -1731,7 +1735,7 @@ namespace Plane.FormationCreator.Formation FlightTask prevTask = Tasks[taskIndex - 1]; addspeedmk = prevTask.TaskType == FlightTaskType.FlyTo && prevTask.LoiterTime > 0; bool decspeedmk = (Tasks[taskIndex].LoiterTime > 0); //是否要减速 - + int flytype = 0;//匀速 if (addspeedmk & decspeedmk) flytype = 1; //加减速 @@ -1739,7 +1743,7 @@ namespace Plane.FormationCreator.Formation else if (decspeedmk) flytype = 3; //单减速 return flytype; } - public void SetTaskFlytime_v2(int taskIndex, + public void SetTaskFlytime_v2(int taskIndex, float acc_xy, float acc_z, float defvel_xy, float defvel_up, float defvel_down, bool settime = true) @@ -1768,14 +1772,14 @@ namespace Plane.FormationCreator.Formation var curWaypoint = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); double copter_maxDistance_up = nextWaypoint.TargetAlt; - double time_up = getMinfligthtime((float)copter_maxDistance_up, acc_z, defvel_up, flytimetype); + double time_up = getMinfligthtime((float)copter_maxDistance_up, acc_z, defvel_up, flytimetype); double copter_tasktime = curWaypoint.TakeOffWaitTime + time_up; if (copter_tasktime > tasktime) { tasktime = copter_tasktime; maxDistance_up = copter_maxDistance_up; - copterName= copter.Name; + copterName = copter.Name; waittime = curWaypoint.TakeOffWaitTime; upflytime = time_up; } @@ -1790,7 +1794,7 @@ namespace Plane.FormationCreator.Formation Alert.Show($"任务{taskIndex + 1}时间太长,目前{tasktime}秒不能超255秒,请调整高度或速度", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); return; } else - Tasks[taskIndex].TakeOffTime = (byte)(int)Math.Ceiling(tasktime); + Tasks[taskIndex].TakeOffTime = (byte)(int)Math.Ceiling(tasktime); } } else if (Tasks[taskIndex].TaskType == FlightTaskType.FlyTo) @@ -1817,7 +1821,7 @@ namespace Plane.FormationCreator.Formation { maxDistance_z = Math.Abs(distance_z); } - + if (distance_z > 0) { @@ -1872,7 +1876,7 @@ namespace Plane.FormationCreator.Formation public void SetTaskFlytime(int taskIndex, bool settime = true) { - if (taskIndex== 1) + if (taskIndex == 1) { Message.Show($"2号任务是调整航点,根据现场飞机摆放离设计位置偏差来调整"); return; @@ -1888,7 +1892,7 @@ namespace Plane.FormationCreator.Formation if (Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().IsChangeSpeed) { _defvel_xy = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().LevelSpeed; - _defvel_up= Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().UpSpeed; + _defvel_up = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().UpSpeed; _defvel_down = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().DownSpeed; } @@ -1953,7 +1957,7 @@ namespace Plane.FormationCreator.Formation } }//循环结束 - double time_xy = getMinfligthtime((float)maxDistance_xy, FC_acc_xy, FC_maxvel_xy,flytimetype); + double time_xy = getMinfligthtime((float)maxDistance_xy, FC_acc_xy, FC_maxvel_xy, flytimetype); double time_up = getMinfligthtime((float)maxDistance_up, FC_acc_z, FC_maxvel_up, flytimetype); double time_down = getMinfligthtime((float)maxDistance_down, FC_acc_z, FC_maxvel_down, flytimetype); double tasktime = time_xy; @@ -1986,14 +1990,14 @@ namespace Plane.FormationCreator.Formation Message.Show($"任务{taskIndex + 1}飞行时间{Tasks[taskIndex].FlytoTime}秒更改为{Math.Ceiling(tasktime)}秒"); Tasks[taskIndex].FlytoTime = (int)Math.Ceiling(tasktime); //上取整 } - - - } + + + } } - + } - + return; } @@ -2073,12 +2077,12 @@ namespace Plane.FormationCreator.Formation return realflytime; } - float getMinfligthtime(float Distance, float fc_acc, float fc_maxspeed,int timetype) + float getMinfligthtime(float Distance, float fc_acc, float fc_maxspeed, int timetype) { switch (timetype) - { + { case 0://匀速 - return Distance / fc_maxspeed; + return Distance / fc_maxspeed; case 1: //同时计算加减速 return getMinfligthtime_acc_dec(Distance, fc_acc, fc_maxspeed); case 2: //计算加速 @@ -2107,12 +2111,123 @@ namespace Plane.FormationCreator.Formation return t; } //计算优化线路,采用米计算 - /// - /// 自动生成航线2D和3D都用这个--------目前使用---------------- - /// - /// 3D计算 - /// 是否改变线路的结束点顺序--返回起飞点航线不能交换 - public void OptimizeRouteMeter(bool Is3d=false,bool Ischange=true) + + + static public FlightRouteV2.Vector3[] GetFlyBase3d_V2(Point3D[] vPoints) + { + + FlightRouteV2.Vector3[] ret3d = new FlightRouteV2.Vector3[vPoints.Count()]; + for (int i = 0; i < vPoints.Count(); i++) + { + ret3d[i].X = vPoints[i].X; + ret3d[i].Y = vPoints[i].Y; + ret3d[i].Z = vPoints[i].Z; + } + return ret3d; + + } + + //计算中状态信息 + public void Routecallback(string str) + { + // Application.Current.Dispatcher.InvokeAsync(() => + Application.Current.Dispatcher.Invoke(() => + { + Message.Show(str); + }); + } + //计算进度 + public void Cronograma(int val) + { + // Application.Current.Dispatcher.InvokeAsync(() => + Application.Current.Dispatcher.Invoke(() => + { + ServiceLocator.Current.GetInstance().SysStatusText = "计算进度:"+val+"%"; + }); + } + + //新开线程异步调用ContactABOut并等待返回 + public async Task ContactABOutAsync(FlightRouteV2.Vector3[] aVecs, FlightRouteV2.Vector3[] bVecs) + { + FlightRouteV2.Vector3[] ret=null; + var task = Task.Run(() => + { + ret = FlyVecFun.ContactABOut(aVecs, bVecs, Routecallback); + }); + try + { + await task; + } + catch (System.TimeoutException) + { + Message.Show("目标计算失败"); + } + return ret; + } + //新开线程异步调用ABypassB并等待返回 + public async Task<(List>,bool)> ABypassBAsync(FlightRouteV2.Vector3[] aVecs, FlightRouteV2.Vector3[] bVecs) + { + List> ret = null; + bool isPasstmp = false; + + var task = Task.Run(() => + { + ret = FlyVecFun.ABypassB(aVecs, bVecs, Routecallback, Cronograma, out isPasstmp); + }); + try + { + await task; + } + catch (System.TimeoutException) + { + Message.Show("绕行计算失败"); + } + return (ret,isPasstmp); + + } + + public async Task NormalPullsync(FlightRouteV2.Vector3[] aVecs, FlightRouteV2.Vector3[] bVecs) + { + + FlightRouteV2.Vector3[] ret = null; + + var task = Task.Run(() => + { + ret = FlyVecFun.NormalPull(aVecs, bVecs, Routecallback); + }); + try + { + await task; + } + catch (System.TimeoutException) + { + Message.Show("绕行计算失败"); + } + return ret; + } + + + + public async Task>> CollisionLayersync(FlightRouteV2.Vector3[] aVecs, FlightRouteV2.Vector3[] bVecs,string taskname_a,string taskname_b) + { + List> ret = null; + + var task = Task.Run(() => + { + ret = FlyVecFun.CollisionLayer(aVecs, bVecs, taskname_a, taskname_b, Routecallback); + }); + try + { + await task; + } + catch (System.TimeoutException) + { + Message.Show("2D计算失败"); + } + return ret; + } + + public void OptimizeRouteMeterV1(bool Is3d = false, bool Ischange = true, bool Is3dstagger = false) { Dictionary curTaskPoint = new Dictionary(); Dictionary prevTaskPoint = new Dictionary(); @@ -2135,9 +2250,9 @@ namespace Plane.FormationCreator.Formation if (Is3d) { ArrayList resarray = Util.OptimizeRoute.Gen3DRoute(curTaskPoint.Values.ToArray(), prevTaskPoint.Values.ToArray()); - Vector3[] RouteRes; + FlightRoute.Vector3[] RouteRes; //最终 - RouteRes = (Vector3[])resarray[0]; + RouteRes = (FlightRoute.Vector3[])resarray[0]; for (int i = 0; i < _copterManager.Copters.Count; i++) { @@ -2153,7 +2268,7 @@ namespace Plane.FormationCreator.Formation else { ArrayList resarray = Util.OptimizeRoute.Gen2DRoute(curTaskPoint.Values.ToArray(), prevTaskPoint.Values.ToArray(), Ischange); - Vector3[] RouteRes; + FlightRoute.Vector3[] RouteRes; //有错层,需要插入2个错层任务 if (resarray.Count == 3) { @@ -2162,7 +2277,7 @@ namespace Plane.FormationCreator.Formation AddTask(); //第一个错层 - RouteRes = (Vector3[])resarray[0]; + RouteRes = (FlightRoute.Vector3[])resarray[0]; for (int i = 0; i < _copterManager.Copters.Count; i++) { @@ -2173,10 +2288,10 @@ namespace Plane.FormationCreator.Formation SetTaskFlytime(SelectedTaskIndex); - //第二个错层 + //第二个错层 AddTask(); - RouteRes = (Vector3[])resarray[1]; + RouteRes = (FlightRoute.Vector3[])resarray[1]; for (int i = 0; i < _copterManager.Copters.Count; i++) { @@ -2191,7 +2306,7 @@ namespace Plane.FormationCreator.Formation SelectTask(SelectedTaskIndex + 1); //最终 - RouteRes = (Vector3[])resarray[2]; + RouteRes = (FlightRoute.Vector3[])resarray[2]; for (int i = 0; i < _copterManager.Copters.Count; i++) { @@ -2206,7 +2321,7 @@ namespace Plane.FormationCreator.Formation else { //最终 - RouteRes = (Vector3[])resarray[0]; + RouteRes = (FlightRoute.Vector3[])resarray[0]; for (int i = 0; i < _copterManager.Copters.Count; i++) { @@ -2219,13 +2334,280 @@ namespace Plane.FormationCreator.Formation } } stopWatch.Stop(); - + double sumlength = SumFlyLines(Tasks[SelectedTaskIndex - 1].SingleCopterInfos, SelectedTask.SingleCopterInfos); Message.Show($"计算用时:{stopWatch.Elapsed.TotalMilliseconds}ms,总飞行距离{sumlength}米"); + } - return; + /// + /// 自动生成航线2D和3D都用这个-------V2版使用新的碰撞检测和绕行,用flybase.cs库,只用于新版固件-------------- + /// + /// 3D计算 + /// 是否改变线路的结束点顺序--返回起飞点航线不能交换 + /// 3D是否自动插入拉开层,用于2D画面回起飞矩阵,拉开2D画面 + public async Task OptimizeRouteMeterV2(bool Is3d = false, bool Ischange = true,bool Is3dstagger=false) + { + Dictionary curTaskPoint = new Dictionary(); + Dictionary prevTaskPoint = new Dictionary(); + var stopWatch = new Stopwatch(); + stopWatch.Start(); + + //设置随机数种子 + FlyVecFun.RandomSeed = (int)DateTime.Now.Ticks; + Message.Show($"开始自动生成任务,种子数:{FlyVecFun.RandomSeed}"); + + //获取当前航点与前一航点所有经纬高 + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + //当前任务 + var curinfo = SelectedTask.SingleCopterInfos[i]; + Point3D curLoc = new Point3D(curinfo.X * 100, curinfo.TargetAlt * 100, curinfo.Y * 100); + curTaskPoint.Add(i, curLoc); + + //前一任务 + var prevInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i]; + Point3D prevLoc = new Point3D(prevInfo.X * 100, prevInfo.TargetAlt * 100, prevInfo.Y * 100); + prevTaskPoint.Add(i, prevLoc); + } + string taskname_a = SelectedTaskIndex.ToString() + Tasks[SelectedTaskIndex - 1].TaskCnName; + string taskname_b = (SelectedTaskIndex+1).ToString()+SelectedTask.TaskCnName; + + + FlightRouteV2.Vector3[] aVecs = GetFlyBase3d_V2(prevTaskPoint.Values.ToArray()); + FlightRouteV2.Vector3[] bVecs = GetFlyBase3d_V2(curTaskPoint.Values.ToArray()); + + + List firstMiddleVecs; + List middleVecs; + List lastMiddleVecs; + + //如果是true表示目标图案可以修改ID,false就是按ID飞行 + if (Ischange) + { + //通过交换改变目标航点的对应关系,减少碰撞 + bVecs = await ContactABOutAsync(aVecs, bVecs); + //得到当前航点的名称 + string taskname = SelectedTask.TaskCnName; + int loitertime=SelectedTask.LoiterTime; + DelSelectedTask(); + AddTask(); + SelectedTask.TaskCnName = taskname; + SelectedTask.LoiterTime = loitertime; + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = bVecs[i].X / 100; + SelectedTask.SingleCopterInfos[i].Y = bVecs[i].Z / 100; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)bVecs[i].Y / 100; + } + SetTaskFlytime(SelectedTaskIndex); + } + + + if (Is3d) + { + bool isPass = false; + var result= await ABypassBAsync(aVecs, bVecs); + List> flyret = result.Item1; + isPass= result.Item2; + if ((flyret.Count == 0)&&(!isPass)) + { + FlightRouteV2.Vector3[] cVecs=null; + if (Is3dstagger) + { + Message.Show($"任务{SelectedTaskIndex + 1}无法直接生成3D航线,尝试拉开画面"); + cVecs = await NormalPullsync(aVecs, bVecs); + Message.Show($"任务{SelectedTaskIndex + 1}后插入拉开层..."); + //插入错层航点 + SelectTask(SelectedTaskIndex - 1); + AddTask(); + SelectedTask.LoiterTime = 0; + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = cVecs[i].X / 100; + SelectedTask.SingleCopterInfos[i].Y = cVecs[i].Z / 100; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)cVecs[i].Y / 100; + } + SetTaskFlytime(SelectedTaskIndex); + //选到最后一个航点 + SelectTask(SelectedTaskIndex + 1); + var result1= await ABypassBAsync(cVecs, bVecs); + flyret = result1.Item1; + isPass = result1.Item2; + } + if ((flyret.Count == 0) && (!isPass)) + { + Message.Show($"任务{SelectedTaskIndex + 1}无法生成3D航线"); + return; + } + Message.Show($"任务{SelectedTaskIndex + 1}后插入新层..."); + //插入错层航点 + SelectTask(SelectedTaskIndex - 1); + AddTask(); + SelectedTask.LoiterTime = 0; + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = cVecs[i].X / 100; + SelectedTask.SingleCopterInfos[i].Y = cVecs[i].Z / 100; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)cVecs[i].Y / 100; + } + SetTaskFlytime(SelectedTaskIndex); + //选到最后一个航点 + SelectTask(SelectedTaskIndex + 1); + } + Message.Show($"任务{SelectedTaskIndex + 1}需要再插入{flyret.Count}个中间层"); + switch (flyret.Count) + { + case 1: + middleVecs = flyret[0]; + //选中前一个任务,插入错层 + SelectTask(SelectedTaskIndex - 1); + AddTask(); + SelectedTask.LoiterTime = 0; + //第一个中间航点 + + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = middleVecs[i].X / 100; + SelectedTask.SingleCopterInfos[i].Y = middleVecs[i].Z / 100; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)middleVecs[i].Y / 100; + } + SetTaskFlytime(SelectedTaskIndex); + break; + case 2: + firstMiddleVecs = flyret[0]; + middleVecs = flyret[1]; + //选中前一个任务,插入错层 + SelectTask(SelectedTaskIndex - 1); + AddTask(); + SelectedTask.LoiterTime = 0; + //第一个中间航点 + + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = firstMiddleVecs[i].X / 100; + SelectedTask.SingleCopterInfos[i].Y = firstMiddleVecs[i].Z / 100; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)firstMiddleVecs[i].Y / 100; + } + SetTaskFlytime(SelectedTaskIndex); + + //第二个中间航点 + AddTask(); + SelectedTask.LoiterTime = 0; + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = middleVecs[i].X / 100; + SelectedTask.SingleCopterInfos[i].Y = middleVecs[i].Z / 100; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)middleVecs[i].Y / 100; + } + SetTaskFlytime(SelectedTaskIndex); + break; + case 3: + firstMiddleVecs = flyret[0]; + middleVecs = flyret[1]; + lastMiddleVecs = flyret[2]; + //选中前一个任务,插入错层 + SelectTask(SelectedTaskIndex - 1); + AddTask(); + SelectedTask.LoiterTime = 0; + //第一个中间航点 + + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = firstMiddleVecs[i].X / 100; + SelectedTask.SingleCopterInfos[i].Y = firstMiddleVecs[i].Z / 100; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)firstMiddleVecs[i].Y / 100; + } + SetTaskFlytime(SelectedTaskIndex); + + //第二个中间航点 + AddTask(); + SelectedTask.LoiterTime = 0; + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = middleVecs[i].X / 100; + SelectedTask.SingleCopterInfos[i].Y = middleVecs[i].Z / 100; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)middleVecs[i].Y / 100; + } + SetTaskFlytime(SelectedTaskIndex); + + //第三个中间航点 + AddTask(); + SelectedTask.LoiterTime = 0; + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = lastMiddleVecs[i].X / 100; + SelectedTask.SingleCopterInfos[i].Y = lastMiddleVecs[i].Z / 100; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)lastMiddleVecs[i].Y / 100; + } + SetTaskFlytime(SelectedTaskIndex); + break; + } + + //选中最后一个任务 + SelectTask(SelectedTaskIndex + 1); + //计算最后一个任务时间 + SetTaskFlytime(SelectedTaskIndex); + + }else //计算2D错层--固定两个中间航点 + { + List> flyret = await CollisionLayersync(aVecs, bVecs, taskname_a, taskname_b); + if (flyret.Count == 0) + { + Message.Show($"任务{SelectedTaskIndex + 1}无法生成2D航线"); + return; + } + firstMiddleVecs = flyret[0]; + lastMiddleVecs = flyret[1]; + + SelectTask(SelectedTaskIndex - 1); + + //第一个中间航点 + AddTask(); + SelectedTask.LoiterTime = 0; + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = firstMiddleVecs[i].X / 100; + SelectedTask.SingleCopterInfos[i].Y = firstMiddleVecs[i].Z / 100; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)firstMiddleVecs[i].Y / 100; + } + SetTaskFlytime(SelectedTaskIndex); + //第二个中间航点 + AddTask(); + SelectedTask.LoiterTime = 0; + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = lastMiddleVecs[i].X / 100; + SelectedTask.SingleCopterInfos[i].Y = lastMiddleVecs[i].Z / 100; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)lastMiddleVecs[i].Y / 100; + } + SetTaskFlytime(SelectedTaskIndex); + //选中最后一个任务 + SelectTask(SelectedTaskIndex + 1); + //计算最后一个任务时间 + SetTaskFlytime(SelectedTaskIndex); + } + + stopWatch.Stop(); + Message.Show($"计算用时:{Math.Round(stopWatch.Elapsed.TotalMilliseconds/1000,2)}秒"); + } + + + /// + /// 自动生成航线2D和3D都用这个--------目前使用---------------- + /// + /// 3D计算 + /// 是否改变线路的结束点顺序--返回起飞点航线不能交换 + /// 按个按钮,计算航线2D,计算航线3D,计算返航 + /// 老版本只用2D计算,计算返航要ID对应,Ischange=false + public void OptimizeRouteMeter(bool Is3d=false,bool Ischange=true, bool Is3dstagger = false) + { + if (_copterManager.FC_VER_NO >= 3) + //新固件使用V2版 + OptimizeRouteMeterV2(Is3d, Ischange, Is3dstagger); + else + OptimizeRouteMeterV1(Is3d, Ischange, Is3dstagger); } diff --git a/Plane.FormationCreator/Plane.FormationCreator.csproj b/Plane.FormationCreator/Plane.FormationCreator.csproj index 27aa921..f189981 100644 --- a/Plane.FormationCreator/Plane.FormationCreator.csproj +++ b/Plane.FormationCreator/Plane.FormationCreator.csproj @@ -9,7 +9,7 @@ Properties Plane.FormationCreator FGCS - v4.6 + v4.8 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 @@ -447,9 +447,9 @@ - + {626a9bfa-07de-4063-a178-360eb7057ed6} - FlyBase + FlightRouteV2 {705aab55-ed7a-4856-8f7b-e7a78ed9e39a} @@ -514,6 +514,9 @@ false + + + diff --git a/Plane.FormationCreator/Properties/Resources.Designer.cs b/Plane.FormationCreator/Properties/Resources.Designer.cs index 29c85c9..d74f738 100644 --- a/Plane.FormationCreator/Properties/Resources.Designer.cs +++ b/Plane.FormationCreator/Properties/Resources.Designer.cs @@ -1,73 +1,73 @@ -//------------------------------------------------------------------------------ -// -// 此代码由工具生成。 -// 运行时版本:4.0.30319.42000 -// -// 对此文件的更改可能会导致不正确的行为,并且如果 -// 重新生成代码,这些更改将会丢失。 -// -//------------------------------------------------------------------------------ - -namespace Plane.FormationCreator.Properties { - using System; - - - /// - /// 一个强类型的资源类,用于查找本地化的字符串等。 - /// - // 此类是由 StronglyTypedResourceBuilder - // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 - // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen - // (以 /str 作为命令选项),或重新生成 VS 项目。 - [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 { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// 返回此类使用的缓存的 ResourceManager 实例。 - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Plane.FormationCreator.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// 使用此强类型资源类,为所有资源查找 - /// 重写当前线程的 CurrentUICulture 属性。 - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// 查找 System.Drawing.Bitmap 类型的本地化资源。 - /// - internal static System.Drawing.Bitmap Logo_small { - get { - object obj = ResourceManager.GetObject("Logo_small", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - } -} +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Plane.FormationCreator.Properties { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Plane.FormationCreator.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 重写当前线程的 CurrentUICulture 属性,对 + /// 使用此强类型资源类的所有资源查找执行重写。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// 查找 System.Drawing.Bitmap 类型的本地化资源。 + /// + internal static System.Drawing.Bitmap Logo_small { + get { + object obj = ResourceManager.GetObject("Logo_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Plane.FormationCreator/Properties/Settings.Designer.cs b/Plane.FormationCreator/Properties/Settings.Designer.cs index c0590a9..f18040b 100644 --- a/Plane.FormationCreator/Properties/Settings.Designer.cs +++ b/Plane.FormationCreator/Properties/Settings.Designer.cs @@ -1,38 +1,38 @@ -//------------------------------------------------------------------------------ -// -// 此代码由工具生成。 -// 运行时版本:4.0.30319.42000 -// -// 对此文件的更改可能会导致不正确的行为,并且如果 -// 重新生成代码,这些更改将会丢失。 -// -//------------------------------------------------------------------------------ - -namespace Plane.FormationCreator.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [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()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("192.168.1.50")] - public string IPs { - get { - return ((string)(this["IPs"])); - } - set { - this["IPs"] = value; - } - } - } -} +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace Plane.FormationCreator.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("192.168.1.50")] + public string IPs { + get { + return ((string)(this["IPs"])); + } + set { + this["IPs"] = value; + } + } + } +} diff --git a/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs b/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs index 151d291..ef03365 100644 --- a/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs +++ b/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs @@ -958,7 +958,12 @@ namespace Plane.FormationCreator.ViewModels { return _OptimizeRouteCommandRet ?? (_OptimizeRouteCommandRet = new RelayCommand(async => { - _flightTaskManager.OptimizeRouteMeter(false,false); //采用米计算逻辑和OptimizeRouteNew一样 + if (_copterManager.FC_VER_NO >= 3) + //3D计算,不改变ID,可以错层 + _flightTaskManager.OptimizeRouteMeter(true, false, true); //采用米计算逻辑,用3D生成,不改变ID,可拉开层(2D回起飞矩阵专用) + else + _flightTaskManager.OptimizeRouteMeter(false, false); //采用米计算逻辑,用2D生成,不改变ID,不拉开层 + })); } } diff --git a/Plane.FormationCreator/packages.config b/Plane.FormationCreator/packages.config index a759f4e..f4fc8ea 100644 --- a/Plane.FormationCreator/packages.config +++ b/Plane.FormationCreator/packages.config @@ -1,19 +1,19 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + \ No newline at end of file