diff --git a/Plane.FormationCreator.sln b/Plane.FormationCreator.sln index 9c5dad5..ce338a0 100644 --- a/Plane.FormationCreator.sln +++ b/Plane.FormationCreator.sln @@ -1,121 +1,131 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.FormationCreator", "Plane.FormationCreator\Plane.FormationCreator.csproj", "{61E2F31E-220A-4E3F-A64D-F7CDC2135008}" - ProjectSection(ProjectDependencies) = postProject - {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A} = {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A} - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.Windows", "..\Plane.Libraries\Plane.Windows\Plane.Windows.csproj", "{06848293-9B17-4068-9B35-44D0ED713CD4}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.Reflection", "..\Plane.Libraries\Plane.Reflection\Plane.Reflection.csproj", "{98755514-C2E9-4ABE-8A25-007804577558}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.Windows.Messages", "..\Plane.Libraries\Plane.Windows.Messages\Plane.Windows.Messages.csproj", "{413C18E2-235F-4E15-B5C1-633657DE5D7A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.Logging", "..\Plane.Libraries\Plane.Logging\Plane.Logging.csproj", "{9C2CAFDA-CF1D-4565-B797-398376FCD346}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane", "..\Plane.Libraries\Plane\Plane.csproj", "{6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk_Private_NET46", "..\Plane.Sdk3\PlaneGcsSdk_Private_NET46\PlaneGcsSdk_Private_NET46.csproj", "{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk.Contract_Private", "..\Plane.Sdk3\PlaneGcsSdk.Contract_Private\PlaneGcsSdk.Contract_Private.csproj", "{47141894-ECE3-48CA-8DCF-CA751BDA231E}" -EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlaneGcsSdk_Shared", "..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.shproj", "{2BE393DC-21A4-48B3-83FD-F21CBE8B038B}" -EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlaneGcsSdk.Contract_Shared", "..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.shproj", "{695733D7-99FF-4707-8C89-474E949CADCB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightRoute", "..\FlyTest\FlightRoute\FlightRoute.csproj", "{705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}" -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 - v4.0-Debug|Any CPU = v4.0-Debug|Any CPU - v4.0-Release|Any CPU = v4.0-Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.Debug|Any CPU.Build.0 = Debug|Any CPU - {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.Release|Any CPU.ActiveCfg = Release|Any CPU - {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.Release|Any CPU.Build.0 = Release|Any CPU - {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU - {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU - {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU - {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU - {06848293-9B17-4068-9B35-44D0ED713CD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {06848293-9B17-4068-9B35-44D0ED713CD4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {06848293-9B17-4068-9B35-44D0ED713CD4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {06848293-9B17-4068-9B35-44D0ED713CD4}.Release|Any CPU.Build.0 = Release|Any CPU - {06848293-9B17-4068-9B35-44D0ED713CD4}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU - {06848293-9B17-4068-9B35-44D0ED713CD4}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU - {06848293-9B17-4068-9B35-44D0ED713CD4}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU - {06848293-9B17-4068-9B35-44D0ED713CD4}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU - {98755514-C2E9-4ABE-8A25-007804577558}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {98755514-C2E9-4ABE-8A25-007804577558}.Debug|Any CPU.Build.0 = Debug|Any CPU - {98755514-C2E9-4ABE-8A25-007804577558}.Release|Any CPU.ActiveCfg = Release|Any CPU - {98755514-C2E9-4ABE-8A25-007804577558}.Release|Any CPU.Build.0 = Release|Any CPU - {98755514-C2E9-4ABE-8A25-007804577558}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU - {98755514-C2E9-4ABE-8A25-007804577558}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU - {98755514-C2E9-4ABE-8A25-007804577558}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU - {98755514-C2E9-4ABE-8A25-007804577558}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU - {413C18E2-235F-4E15-B5C1-633657DE5D7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {413C18E2-235F-4E15-B5C1-633657DE5D7A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {413C18E2-235F-4E15-B5C1-633657DE5D7A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {413C18E2-235F-4E15-B5C1-633657DE5D7A}.Release|Any CPU.Build.0 = Release|Any CPU - {413C18E2-235F-4E15-B5C1-633657DE5D7A}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU - {413C18E2-235F-4E15-B5C1-633657DE5D7A}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU - {413C18E2-235F-4E15-B5C1-633657DE5D7A}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU - {413C18E2-235F-4E15-B5C1-633657DE5D7A}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU - {9C2CAFDA-CF1D-4565-B797-398376FCD346}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9C2CAFDA-CF1D-4565-B797-398376FCD346}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9C2CAFDA-CF1D-4565-B797-398376FCD346}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9C2CAFDA-CF1D-4565-B797-398376FCD346}.Release|Any CPU.Build.0 = Release|Any CPU - {9C2CAFDA-CF1D-4565-B797-398376FCD346}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9C2CAFDA-CF1D-4565-B797-398376FCD346}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU - {9C2CAFDA-CF1D-4565-B797-398376FCD346}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU - {9C2CAFDA-CF1D-4565-B797-398376FCD346}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU - {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.Release|Any CPU.Build.0 = Release|Any CPU - {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU - {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU - {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU - {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|Any CPU.Build.0 = Release|Any CPU - {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU - {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU - {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU - {47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|Any CPU.Build.0 = Release|Any CPU - {47141894-ECE3-48CA-8DCF-CA751BDA231E}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU - {47141894-ECE3-48CA-8DCF-CA751BDA231E}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU - {47141894-ECE3-48CA-8DCF-CA751BDA231E}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU - {47141894-ECE3-48CA-8DCF-CA751BDA231E}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU - {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.Release|Any CPU.Build.0 = Release|Any CPU - {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU - {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU - {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU - {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.FormationCreator", "Plane.FormationCreator\Plane.FormationCreator.csproj", "{61E2F31E-220A-4E3F-A64D-F7CDC2135008}" + ProjectSection(ProjectDependencies) = postProject + {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A} = {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.Windows", "..\Plane.Libraries\Plane.Windows\Plane.Windows.csproj", "{06848293-9B17-4068-9B35-44D0ED713CD4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.Reflection", "..\Plane.Libraries\Plane.Reflection\Plane.Reflection.csproj", "{98755514-C2E9-4ABE-8A25-007804577558}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.Windows.Messages", "..\Plane.Libraries\Plane.Windows.Messages\Plane.Windows.Messages.csproj", "{413C18E2-235F-4E15-B5C1-633657DE5D7A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.Logging", "..\Plane.Libraries\Plane.Logging\Plane.Logging.csproj", "{9C2CAFDA-CF1D-4565-B797-398376FCD346}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane", "..\Plane.Libraries\Plane\Plane.csproj", "{6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk_Private_NET46", "..\Plane.Sdk3\PlaneGcsSdk_Private_NET46\PlaneGcsSdk_Private_NET46.csproj", "{0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaneGcsSdk.Contract_Private", "..\Plane.Sdk3\PlaneGcsSdk.Contract_Private\PlaneGcsSdk.Contract_Private.csproj", "{47141894-ECE3-48CA-8DCF-CA751BDA231E}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlaneGcsSdk_Shared", "..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.shproj", "{2BE393DC-21A4-48B3-83FD-F21CBE8B038B}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlaneGcsSdk.Contract_Shared", "..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.shproj", "{695733D7-99FF-4707-8C89-474E949CADCB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightRoute", "..\FlyTest\FlightRoute\FlightRoute.csproj", "{705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlyBase", "..\FlyCube\FlyBase\FlyBase.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 + v4.0-Debug|Any CPU = v4.0-Debug|Any CPU + v4.0-Release|Any CPU = v4.0-Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.Debug|Any CPU.Build.0 = Debug|Any CPU + {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.Release|Any CPU.ActiveCfg = Release|Any CPU + {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.Release|Any CPU.Build.0 = Release|Any CPU + {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU + {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU + {61E2F31E-220A-4E3F-A64D-F7CDC2135008}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU + {06848293-9B17-4068-9B35-44D0ED713CD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {06848293-9B17-4068-9B35-44D0ED713CD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {06848293-9B17-4068-9B35-44D0ED713CD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {06848293-9B17-4068-9B35-44D0ED713CD4}.Release|Any CPU.Build.0 = Release|Any CPU + {06848293-9B17-4068-9B35-44D0ED713CD4}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {06848293-9B17-4068-9B35-44D0ED713CD4}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU + {06848293-9B17-4068-9B35-44D0ED713CD4}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU + {06848293-9B17-4068-9B35-44D0ED713CD4}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU + {98755514-C2E9-4ABE-8A25-007804577558}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {98755514-C2E9-4ABE-8A25-007804577558}.Debug|Any CPU.Build.0 = Debug|Any CPU + {98755514-C2E9-4ABE-8A25-007804577558}.Release|Any CPU.ActiveCfg = Release|Any CPU + {98755514-C2E9-4ABE-8A25-007804577558}.Release|Any CPU.Build.0 = Release|Any CPU + {98755514-C2E9-4ABE-8A25-007804577558}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {98755514-C2E9-4ABE-8A25-007804577558}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU + {98755514-C2E9-4ABE-8A25-007804577558}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU + {98755514-C2E9-4ABE-8A25-007804577558}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU + {413C18E2-235F-4E15-B5C1-633657DE5D7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {413C18E2-235F-4E15-B5C1-633657DE5D7A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {413C18E2-235F-4E15-B5C1-633657DE5D7A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {413C18E2-235F-4E15-B5C1-633657DE5D7A}.Release|Any CPU.Build.0 = Release|Any CPU + {413C18E2-235F-4E15-B5C1-633657DE5D7A}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {413C18E2-235F-4E15-B5C1-633657DE5D7A}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU + {413C18E2-235F-4E15-B5C1-633657DE5D7A}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU + {413C18E2-235F-4E15-B5C1-633657DE5D7A}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU + {9C2CAFDA-CF1D-4565-B797-398376FCD346}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C2CAFDA-CF1D-4565-B797-398376FCD346}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C2CAFDA-CF1D-4565-B797-398376FCD346}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C2CAFDA-CF1D-4565-B797-398376FCD346}.Release|Any CPU.Build.0 = Release|Any CPU + {9C2CAFDA-CF1D-4565-B797-398376FCD346}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C2CAFDA-CF1D-4565-B797-398376FCD346}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU + {9C2CAFDA-CF1D-4565-B797-398376FCD346}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU + {9C2CAFDA-CF1D-4565-B797-398376FCD346}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU + {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.Release|Any CPU.Build.0 = Release|Any CPU + {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU + {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU + {6CCE2AEB-3B38-4C00-B32D-433A990AE2AD}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU + {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.Release|Any CPU.Build.0 = Release|Any CPU + {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU + {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU + {0111EB6E-72E3-499C-A3BA-022F5BBC4CAF}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU + {47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47141894-ECE3-48CA-8DCF-CA751BDA231E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47141894-ECE3-48CA-8DCF-CA751BDA231E}.Release|Any CPU.Build.0 = Release|Any CPU + {47141894-ECE3-48CA-8DCF-CA751BDA231E}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47141894-ECE3-48CA-8DCF-CA751BDA231E}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU + {47141894-ECE3-48CA-8DCF-CA751BDA231E}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU + {47141894-ECE3-48CA-8DCF-CA751BDA231E}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU + {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.Release|Any CPU.Build.0 = Release|Any CPU + {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU + {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU + {705AAB55-ED7A-4856-8F7B-E7A78ED9E39A}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU + {626A9BFA-07DE-4063-A178-360EB7057ED6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {626A9BFA-07DE-4063-A178-360EB7057ED6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {626A9BFA-07DE-4063-A178-360EB7057ED6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {626A9BFA-07DE-4063-A178-360EB7057ED6}.Release|Any CPU.Build.0 = Release|Any CPU + {626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU + {626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU + {626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU + {626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Plane.FormationCreator/Formation/FlightTaskManager.cs b/Plane.FormationCreator/Formation/FlightTaskManager.cs index d0eae8d..89fb93f 100644 --- a/Plane.FormationCreator/Formation/FlightTaskManager.cs +++ b/Plane.FormationCreator/Formation/FlightTaskManager.cs @@ -1,3021 +1,3066 @@ -using Plane.Collections; -using Plane.Copters; -using Plane.Geography; -using Plane.Windows.Messages; -using GalaSoft.MvvmLight; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Plane.CommunicationManagement; -using FlightRoute; -using System.IO; -using System.Windows.Media.Media3D; -using System.Diagnostics; -using Plane.FormationCreator.Util; -using System.Collections; -using System.Windows; - -namespace Plane.FormationCreator.Formation -{ - public class FlightTaskManager : ObservableObject - { - public FlightTaskManager(CopterManager copterManager) - { - LoadIni(); - _copterManager = copterManager; - - //AddTakeOffTask(_copterManager.Copters); - - _copterManager.Copters.CollectionChanged += (sender, e) => - { - // TODO: 王海, 20150724, 需要改为正确的做法(清除旧飞机的任务,补充新飞机的任务)。 - //AddTakeOffTask(e.NewItems?.Cast()); - }; - - _copterManager.SelectedCoptersChanged += (sender, e) => - { - if (_copterManager.AcceptingControlCopters != null && _copterManager.AcceptingControlCopters.Count() == 1) - CommModuleManager.Instance.LED_FlickerAsync(_copterManager.AcceptingControlCopters); - - /* - foreach (ICopter copter in _copterManager.AcceptingControlCopters) - { - copter.LEDAsync(); - } - */ - - // TODO: 王海, 20150803, 处理选中多个飞行器的情况。 - if (_copterManager.SelectedCopters.Count() > 1) - { - return; - } - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - - foreach (var task in Tasks) - { - foreach (var info in task.SingleCopterInfos) - { - if (info.Copter == selectedCopter) - { - task.ModifyingSingleCopterInfo = info; - break; - } - } - } - if (selectedCopter!=null) - selectedCopter.SetShowLEDFlashAsync(1, 100); - - //if (selectedCopter != null) - //selectedCopter.LEDAsync(); - }; - - TaskAdded += (sender, e) => - { - // TODO: 王海, 20150803, 处理选中多个飞行器的情况。 - if (_copterManager.SelectedCopters.Count() > 1) - { - return; - } - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - - var task = e.AddedTask; - foreach (var info in task.SingleCopterInfos) - { - if (info.Copter == selectedCopter) - { - task.ModifyingSingleCopterInfo = info; - break; - } - } - }; - } - - private CopterManager _copterManager; - - - - private string _MessageText="test"; - public string MessageText - { - get { return _MessageText; } - set - { - if (Set(nameof(MessageText), ref _MessageText, value)) - { - // _lastUpdateStatusTextTime = DateTime.Now; - } - } - } - - - private bool _TaskRun_2D = true; - public bool TaskRun_2D - { - get { return _TaskRun_2D; } - set - { - if (Set(nameof(TaskRun_2D), ref _TaskRun_2D, value)) - { - - } - } - } - - private void AddTakeOffTask(IEnumerable copters) - { - if (copters == null || !copters.Any()) return; - - bool takeOffTaskExisted = Tasks.Count >= 1; - FlightTask takeOffTask; - if (takeOffTaskExisted) - { - takeOffTask = Tasks[0]; - } - else - { - takeOffTask = new FlightTask(FlightTaskType.TakeOff); - Tasks.Add(takeOffTask); - RaiseTaskAdded(null, takeOffTask); - //TaskAdded?.Invoke(this, new FlightTaskAddedEventArgs { AddedTask = takeOffTask }); - } - foreach (var copter in copters) - { - takeOffTask.SingleCopterInfos.Add(FlightTaskSingleCopterInfo.CreateForTakeOffTask(copter, targetAlt: 15)); - } - } - - public ObservableCollection Tasks { get; } = new ObservableCollection(); - - - - public int GetTaskTime(int TaskIndex) - { - int tasktime = 0; - if ((Tasks==null)|| TaskIndex> Tasks.Count-1) return tasktime; - - FlightTask value = Tasks[TaskIndex]; - switch (value.TaskType) - { - case FlightTaskType.TakeOff: tasktime = value.TakeOffTime; ; break; - case FlightTaskType.FlyTo: tasktime = value.FlytoTime + value.LoiterTime; break; - //降落时间计算前一个任务目标高度最高的飞机的降落时间按1.5米/秒下降 - case FlightTaskType.Land: - float maxalt = 0.0f; - 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); - break; - } - return tasktime; - - } - - - - - private FlightTask _SelectedTask; - public FlightTask SelectedTask - { - get { return _SelectedTask; } - set - { - if (_SelectedTask != value) - { - int starttime=0; - - if (_SelectedTask != null) - { - - _SelectedTask.IsSelected = false; - if (TaskState == TasksStatus.Stop) - _SelectedTask.Status = FlightTaskStatus.Stop; - } - - if (value != null) - { - value.IsSelected = true; - value.IsRightSelected = true; - RightSelect(value); - if (TaskState== TasksStatus.Stop) - value.Status = FlightTaskStatus.Selected; - - for (int i = 0; i < value.TaskIndex; i++) - starttime += GetTaskTime(i); - - TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(starttime)); - string str = ""; - if (ts.Hours > 0) - { - str = ts.Hours.ToString() + "小时" + ts.Minutes.ToString() + "分" + ts.Seconds + "秒"; - } - if (ts.Hours == 0 && ts.Minutes > 0) - { - str = ts.Minutes.ToString() + "分" + ts.Seconds + "秒"; - } - if (ts.Hours == 0 && ts.Minutes == 0) - { - str = ts.Seconds + "秒"; - } - - if (value.ModifyingSingleCopterInfo == null) - { - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - - foreach (var info in value.SingleCopterInfos) - { - if (info.Copter == selectedCopter) - { - value.ModifyingSingleCopterInfo = info; - break; - } - } - - } - - - Message.ShowStatus($"选中 [{value.TaskIndex+1} {value.TaskCnName }] 从{str}开始执行,需{ GetTaskTime(value.TaskIndex)}秒,共{Tasks.Count}个任务"); - } - else Message.ShowStatus($"无任务选中"); - - } - Set(nameof(SelectedTask), ref _SelectedTask, value); - } - } - - private int _SelectedTaskIndex; - public int SelectedTaskIndex - { - get { return _SelectedTaskIndex; } - set { Set(nameof(SelectedTaskIndex), ref _SelectedTaskIndex, value); - // this.SelectedTask = Tasks[value]; - } - } - - // 右键单击任务,用于隐藏任务图标, 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 - { - get { return _CurrentRunningTask; } - private set { Set(nameof(CurrentRunningTask), ref _CurrentRunningTask, value); } - } - - private int _CurrentRunningTaskIndex; - public int CurrentRunningTaskIndex - { - get { return _CurrentRunningTaskIndex; } - private set { Set(nameof(CurrentRunningTaskIndex), ref _CurrentRunningTaskIndex, value); } - } - - private int _ColumnCount = 5; - public int ColumnCount - { - get { return _ColumnCount; } - set { Set(nameof(ColumnCount), ref _ColumnCount, value); } - } - - - private float _ColumnDistance = 4.0f; - public float ColumnDistance - { - get { return _ColumnDistance; } - set { Set(nameof(ColumnDistance), ref _ColumnDistance, value); } - } - - private float _RowDistance = 4.0f; - public float RowDistance - { - get { return _RowDistance; } - set { Set(nameof(RowDistance), ref _RowDistance, value); } - } - - private int _Orientation = 0; - public int Orientation - { - get { return _Orientation; } - set { Set(nameof(Orientation), ref _Orientation, value); } - } - - //水平加速度 - private float _FC_acc_xy = 0; - public float FC_acc_xy - { - get { return _FC_acc_xy; } - set { Set(nameof(FC_acc_xy), ref _FC_acc_xy, value); } - } - //垂直加速度 - private float _FC_acc_z = 0; - public float FC_acc_z - { - get { return _FC_acc_z; } - set { Set(nameof(FC_acc_z), ref _FC_acc_z, value); } - } - - //水平最大速度 - private float _FC_maxvel_xy = 0; - public float FC_maxvel_xy - { - get { return _FC_maxvel_xy; } - set { Set(nameof(FC_maxvel_xy), ref _FC_maxvel_xy, value); } - } - - //上升最大速度 - private float _FC_maxvel_up = 0; - public float FC_maxvel_up - { - get { return _FC_maxvel_up; } - set { Set(nameof(FC_maxvel_up), ref _FC_maxvel_up, value); } - } - //下降最大速度 - private float _FC_maxvel_down = 0; - public float FC_maxvel_down - { - get { return _FC_maxvel_down; } - set { Set(nameof(FC_maxvel_down), ref _FC_maxvel_down, value); } - } - - - //水平默认速度 - private float _FC_defvel_xy = 0; - public float FC_defvel_xy - { - get { return _FC_defvel_xy; } - set { Set(nameof(FC_defvel_xy), ref _FC_defvel_xy, value); } - } - - //上升默认速度 - private float _FC_defvel_up = 0; - public float FC_defvel_up - { - get { return _FC_defvel_up; } - set { Set(nameof(FC_defvel_up), ref _FC_defvel_up, value); } - } - //下降默认速度 - private float _FC_defvel_down = 0; - public float FC_defvel_down - { - get { return _FC_defvel_down; } - set { Set(nameof(FC_defvel_down), ref _FC_defvel_down, value); } - } - - - - - - private TasksStatus _TaskState = TasksStatus.Stop; - public TasksStatus TaskState - { - get { return _TaskState; } - private set { Set(nameof(TaskState), ref _TaskState, value); } - } - - public event EventHandler TaskAdded; - public event EventHandler TaskDeled; - - public void RaiseTaskDeled(FlightTask vDeledTask,int vTaskIndex) - { - try - { - TaskDeled?.Invoke(this, new FlightTaskDeledEventArgs { DeledTask = vDeledTask, TaskIndex= vTaskIndex }); - } - catch (Exception ex) - { - //RaiseExceptionThrown(ex); - } - - - } - public void RaiseTaskAdded(FlightTask lastTask ,FlightTask newTask) - { - try - { - TaskAdded?.Invoke(this, new FlightTaskAddedEventArgs { LastTask = lastTask, AddedTask = newTask }); - } - catch (Exception ex) - { - //RaiseExceptionThrown(ex); - } - newTask.PropertyChanged += (sender, e) => - { - switch (e.PropertyName) - { - case nameof(FlightTask.TaskTypeIndex): - case nameof(FlightTask.TaskCnName): - TaskTypeChanged?.Invoke(this, new FlightTaskTypeChangedEventArgs((FlightTask)sender)); - TaskcnNameChanged?.Invoke(this, new FlightTaskcnNameChangedEventArgs((FlightTask)sender)); - break; - default: - break; - } - }; - } - - - - - public event EventHandler OnOriginalSet; - - public event EventHandler SingleCopterInfoChanged; - - public void RaiseSingleCopterTaskChanged(FlightTaskSingleCopterInfo singleCopterInfo) - { - SingleCopterInfoChanged?.Invoke(this, new SingleCopterInfoChangedEventArgs(singleCopterInfo)); - } - - - public event EventHandler TaskTypeChanged; - public event EventHandler TaskcnNameChanged; - - public event EventHandler TasksCleared; - - public void AddTask() - { - //if (AppEx.Instance.CurrentMode == AppMode.PreparedForRunningTasks) - { - var copters = _copterManager.Copters; - if (!copters.Any()) return; - AppEx.Current.AppMode = AppMode.ModifyingTask; - if (Tasks.Count == 0) - AddTakeOffTask(copters); - var lastTask = Tasks.LastOrDefault(); - if (SelectedTask !=null) - lastTask = SelectedTask; - var nullableCenter = copters.GetCenter(); - if (nullableCenter == null) return; - var center = nullableCenter.Value; - var newTask = new FlightTask(FlightTaskType.FlyTo); - int coptindex = 0; - - int colnum = ColumnCount; //自动生成列数=4 - float coldis = ColumnDistance;//列相距5米 - float rowdis = RowDistance;//行相距5米 - float matrixdis = 20; //生成方阵距离30米 - int orientation = Orientation; - - int currcol = 0; //当前列号 - int currrow = 0; //当前行 - Tuple colLatLng = new Tuple(0, 0); - Tuple targetLatLng = new Tuple(0, 0); - FlightTaskSingleCopterInfo lastSingleCopterInfo = null; - FlightTaskSingleCopterInfo preSingleCopterInfo = null; - - foreach (var copter in copters) - { - preSingleCopterInfo = lastTask.SingleCopterInfos.Find(info => info.Copter == copter); - if (coptindex == 0) - { - lastSingleCopterInfo = lastTask.SingleCopterInfos.Find(info => info.Copter == copter); - targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(lastSingleCopterInfo.TargetLat, lastSingleCopterInfo.TargetLng, orientation, matrixdis); - colLatLng = targetLatLng; - } - else - { - if (currcol < colnum) - targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Item1, colLatLng.Item2, orientation + 90, currcol * coldis); - else - { - currrow++; - currcol = 0; - targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Item1, colLatLng.Item2, orientation + 180, rowdis); - colLatLng = targetLatLng; - } - } - currcol++; - coptindex++; - - - var newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask(copter, targetLatLng.Item1, targetLatLng.Item2, preSingleCopterInfo.TargetAlt); - newTask.SingleCopterInfos.Add(newSingleCopterInfo); - - } - int selindex = SelectedTaskIndex+1; - Tasks.Insert(SelectedTaskIndex+1, newTask); - RaiseTaskAdded(lastTask, newTask); - SelectTask(selindex); - - //第一个航点,回起飞点 - if (Tasks.Count == 2) - { - SelectedTask.FlytoTime = 2; - SelectedTask.LoiterTime = 2; - foreach (FlightTaskSingleCopterInfo info in SelectedTask.SingleCopterInfos) - { - info.TargetLat = info.Copter.Latitude; - info.TargetLng = info.Copter.Longitude; - } - } - - /* - Tasks.Add(newTask); - RaiseTaskAdded(lastTask, newTask); - SelectedTask = newTask; - SelectedTaskIndex = Tasks.Count - 1; - */ - - - - } - } - - //是否显示计划航线 - private bool _showroute = true; - public bool showroute - { - get { return _showroute; } - set { Set(nameof(showroute), ref _showroute, value); } - } - - private double _OriginLat = 0; - public double OriginLat - { - get { return _OriginLat; } - set { Set(nameof(OriginLat), ref _OriginLat, value); } - } - - private double _OriginLng = 0; - public double OriginLng - { - get { return _OriginLng; } - set { Set(nameof(OriginLng), ref _OriginLng, value); } - } - - private double _ObserverLat = 0; - public double ObserverLat - { - get { return _ObserverLat; } - set { Set(nameof(ObserverLat), ref _ObserverLat, value); } - } - - private double _ObserverLng = 0; - public double ObserverLng - { - get { return _ObserverLng; } - set { Set(nameof(ObserverLng), ref _ObserverLng, value); } - } - - - - - - /// - /// 起始点作为参考,设置起始点后飞行写入的数据将为相对坐标 - /// - public void SetOriginal() - { - OnOriginalSet?.Invoke(this, new FlightTaskAddedOriginalEventArgs { Lat = OriginLat, Lng = OriginLng }); - } - - - public void ClearTasks() - { - ResetTasks(); - this.Tasks.Clear(); - SelectedTask = null; - SelectedTaskIndex = 0; - //取消删除事件 - /* - if (TaskDeled != null) - { - Delegate[] dels = TaskDeled.GetInvocationList(); - if (dels != null) - { - foreach (Delegate d in dels) - { - TaskDeled -= d as EventHandler; - } - } - } - */ - - TasksCleared?.Invoke(this, EventArgs.Empty); - // AddTakeOffTask(_copterManager.Copters); - } - //删除选中的任务 - public void DelSelectedTask() - { - if (SelectedTask == null) return; - if (SelectedTask.TaskType == FlightTaskType.TakeOff) return; - int selindex = SelectedTaskIndex; - - // ResetTasks(); - SelectedTask.SingleCopterInfos.Clear(); - Tasks.RemoveAt(SelectedTaskIndex); - RaiseTaskDeled(SelectedTask,SelectedTaskIndex); - - SelectTask(selindex - 1); - - - // SelectedTaskIndex = 0; - } - - - - public async Task ForceNextTasks() - { - if (CurrentRunningTaskIndex == Tasks.Count - 1) - return; - - Pause(); - int i = 0; - //等待暂停或2s超时(80*25ms) - while ((TaskState != TasksStatus.Paused)||(i>80)) - { - await Task.Delay(25).ConfigureAwait(false); - i++; - } - - if (TaskState == TasksStatus.Paused) - { - CurrentRunningTask.Status = FlightTaskStatus.Stop; - CurrentRunningTask = null; - - //起飞任务需要跳过 -// if (CurrentRunningTaskIndex == 0) -// CurrentRunningTaskIndex++; - CurrentRunningTaskIndex++; - await RunTaskAsync(); - } - } - - //指定任务开始模拟 - public async Task FlyToTasks() - { - var copters = _copterManager.Copters; - if ((SelectedTaskIndex==-1) ||(TaskState == TasksStatus.Stop)) - return; - - int vSelectedTaskIndex= SelectedTaskIndex; - - Pause(); - int i = 0; - //等待暂停或2s超时(80*25ms) - while ((TaskState != TasksStatus.Paused) || (i > 80)) - { - await Task.Delay(25).ConfigureAwait(false); - i++; - } - if (SelectedTaskIndex == -1) - return; - - if (TaskState == TasksStatus.Paused) - { - CurrentRunningTask.Status = FlightTaskStatus.Stop; - CurrentRunningTask = null; - CurrentRunningTaskIndex = SelectedTaskIndex; - - - - //设置所有模拟飞机的位置 - for (int j = 0; j < copters.Count; j++) - { - var copter = copters[j]; - var fc = copter as FakeCopter; - float targalt = 0.0f; - double lat = 0.0f; - double lng = 0.0f; - - //飞机回到前一个任务位置, - - //起飞任务直接用当前起飞任务位置 - if (Tasks[SelectedTaskIndex].TaskType == FlightTaskType.TakeOff) - { - lat = Tasks[SelectedTaskIndex].SingleCopterInfos[j].TargetLat; - lng = Tasks[SelectedTaskIndex].SingleCopterInfos[j].TargetLng; - targalt = 0.0f; - } - else - { - //返航点直接设置起飞位置 - if (Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].IsLandWaypoint) - { - lat = Tasks[0].SingleCopterInfos[j].TargetLat; - lng = Tasks[0].SingleCopterInfos[j].TargetLng; - } - else - { - - //用前一个任务目标位置 - lat = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].TargetLat; - lng = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].TargetLng; - } - - //如果前一个是起飞任务,没有目标高度,用当前的 - if (Tasks[SelectedTaskIndex - 1].TaskType == FlightTaskType.TakeOff) - targalt = Tasks[SelectedTaskIndex].SingleCopterInfos[j].TargetAlt; - else - targalt = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].TargetAlt; - } - fc.SetProperties( - latitude: lat, - longitude: lng, - altitude: targalt - - ); - - } - - - - //起飞任务需要跳过 - // if (CurrentRunningTaskIndex == 0) - // CurrentRunningTaskIndex++; - - await RunTaskAsync(); - } - } - - - - - - public async Task ResetTasks() - { - var copters = _copterManager.Copters; - if (Tasks.Count == 0) return; - if (TaskState == TasksStatus.Running) - { - - Pause(); - //等待暂停或2s超时(80*25ms) - int k = 0; - while ((TaskState != TasksStatus.Paused) || (k > 80)) - { - await Task.Delay(25).ConfigureAwait(false); - k++; - } - } - TaskState = TasksStatus.Stop; - - CurrentRunningTaskIndex = 0; - if (CurrentRunningTask != null) - { - CurrentRunningTask.Status = FlightTaskStatus.Stop; - CurrentRunningTask = null; - } - - for (int i = 0; i < Tasks.Count; i++) - { - // 将起飞的阶段标志位都置位0 - if (Tasks[i].TaskType == FlightTaskType.TakeOff) - { - var infos = Tasks[i].SingleCopterInfos; - for (int j = 0; j < infos.Count; j++) - { - var info = infos[j]; - info.takeOffStage = 0; - } - } - - - } - - - //设置所有模拟飞机的位置 - for (int j = 0; j < copters.Count; j++) - { - var copter = copters[j]; - var fc = copter as FakeCopter; - if (fc != null) - { - fc.SetProperties( - latitude: Tasks[0].SingleCopterInfos[j].TargetLat, - longitude: Tasks[0].SingleCopterInfos[j].TargetLng, - altitude: 0 ); - //设置灯光为默认颜色 - fc.LEDColor = CopterManager.CopterDefaultColor;// "000000"; - fc.LEDMode = 0; - fc.LEDInterval = 0; - } - } - - } - - public string ExportC4DFlytoTask() - { - int count = SelectedTask.SingleCopterInfos.Count(); - //string[] lines = new string[count]; - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < count; i++) - { - var singleCopterInfo = SelectedTask.SingleCopterInfos[i]; - double x = 100 * GeographyUtils.CalcDistance(OriginLat, OriginLng, 0, - OriginLat, singleCopterInfo.TargetLng, 0); - if (singleCopterInfo.TargetLng < OriginLng) x = -x; - double y = 100 * singleCopterInfo.TargetAlt; - - double z = 100 * GeographyUtils.CalcDistance(OriginLat, OriginLng, 0, - singleCopterInfo.TargetLat, OriginLng, 0); - if (singleCopterInfo.TargetLat < OriginLat) z = -z; - sb.AppendLine($"{i + 1} 0 {x} {y} {z}"); - //lines[i] = $"{i+1} {x} {y} {z}"; - } - - return sb.ToString().Trim(); - } - - - public void ImportC4DFlytoVCopter(string txt) - { - string[] lines = txt.Replace("\r\n", "\n").Split('\n'); - - if (lines.Length % (_copterManager.Copters.Count + 1) != 0) - { - Alert.Show("文件内容错误!"); - return; - } - - int taskCount = lines.Length / (_copterManager.Copters.Count + 1); - int startIndex; - string line; - Dictionary PointDic; - for (int i = 0; i < taskCount; i++) - { - startIndex = i * (_copterManager.Copters.Count + 1); - string taskName = lines[startIndex]; - PointDic = new Dictionary(); - for (int j = 0; j < _copterManager.Copters.Count; j++) - { - line = lines[startIndex + j + 1]; - string[] parameters = line.Split(' '); - int id = Convert.ToInt32(parameters[0]); - string frame = parameters[1]; - string[] point = new string[3]; - point[0] = parameters[1]; //左右 经度 - point[1] = parameters[2]; //上下 高度 - point[2] = parameters[3]; //前后 纬度 - PointDic.Add(id, point); - } - - var lastTask = Tasks.LastOrDefault(); - var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = true, FlytoTime = 10, LoiterTime = 1 }; - newTask.TaskCnName = taskName; - for (int k = 0; k < PointDic.Count; k++) - { - string[] point = PointDic[k + 1]; - - //string frame = parameters[1]; - string x = point[0]; //左右 经度 - string y = point[1]; //上下 高度 - string z = point[2]; //前后 纬度 - Tuple observationLatLng = null; - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - OriginLat, - OriginLng, - 90, - Convert.ToSingle(x) / 100); - - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - observationLatLng.Item1, - observationLatLng.Item2, - 0, - Convert.ToSingle(z) / 100); - - var fc = _copterManager.Copters[k] as FakeCopter; - double vlatitude = observationLatLng.Item1; - double vlongitude = observationLatLng.Item2; - - - fc.SetProperties( - latitude: vlatitude, - longitude: vlongitude, - altitude: Convert.ToSingle(y) / 100); - - - - - } - Tasks.Add(newTask); - RaiseTaskAdded(lastTask, newTask); - } - - - } - - public void ImportDlltoVCopter(string filename) - { - Vector3[] vc; - - - - - string extname = Path.GetExtension(filename); - if (extname == ".svg") - { - vc = FlyBase.svgToPos(filename); - } - else if (extname == ".obj") - { - vc = FlyBase.objToPos(filename); - } - else return; - - if (vc.Count() != _copterManager.Copters.Count) - { - Alert.Show($"飞机数量不匹配!导入{vc.Count()}架,实际{_copterManager.Copters.Count}"); - return; - } - int id = 0; - foreach (Vector3 item in vc) - { - Tuple observationLatLng = null; - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - OriginLat, - OriginLng, - 90, - (float)item.x / 100); - - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - observationLatLng.Item1, - observationLatLng.Item2, - 0, - (float)item.z / 100); - - - var fc = _copterManager.Copters[id] as FakeCopter; - double vlatitude = observationLatLng.Item1;// - OriginLat; - double vlongitude = observationLatLng.Item2;// - OriginLng; - - - fc.SetProperties( - latitude: vlatitude, - longitude: vlongitude, - altitude: (float)item.y / 100); - id++; - - } - } - - - //导入外部航点 - public void ImportDlltoTask(string filename) - { - Vector3[] vc; - - - string extname = Path.GetExtension(filename); - if (extname == ".svg") - { - vc = FlyBase.svgToPos(filename); - } - else if (extname == ".obj") - { - vc = FlyBase.objToPos(filename); - } - else return; - - 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); - newTask.TaskCnName = vname; - int id =0; - foreach (Vector3 item in vc) - { - Tuple observationLatLng = null; - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - OriginLat, - OriginLng, - 90, - (float)item.x / 100); - - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - observationLatLng.Item1, - observationLatLng.Item2, - 0, - (float)item.z / 100); - - var thisSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( - _copterManager.Copters[id++], new LatLng(observationLatLng.Item1 - OriginLat, observationLatLng.Item2 - OriginLng), - (float)item.y / 100, false); - newTask.SingleCopterInfos.Add(thisSingleCopterInfo); - } - Tasks.Add(newTask); - RaiseTaskAdded(lastTask, newTask); - } - - - public void ImportC4DFlytoTask(string txt) - { - string[] lines = txt.Replace("\r\n", "\n").Split('\n'); - - if (lines.Length % (_copterManager.Copters.Count + 1) != 0) - { - Alert.Show("文件内容错误!"); - return; - } - - int taskCount = lines.Length / (_copterManager.Copters.Count + 1); - int startIndex; - int flytime = 10; - string line; - Dictionary PointDic; - for (int i = 0; i < taskCount; i++) - { - startIndex = i * (_copterManager.Copters.Count + 1); - string taskName = lines[startIndex]; - if (taskName != "") - { - //去掉前后的"[]" - string taskName_temp = taskName.Substring(1); - taskName_temp= taskName_temp.Remove(taskName_temp.Length - 1); - //新版用":"分割时间 - string[] words = taskName_temp.Split(':'); - if (words.Count()==2) - { - taskName = words[0]; - flytime = int.Parse(words[1]); - if (flytime == -1) //第一个航点是-1 先设置成0 后面计算时间 - flytime = 0; - - } - } - - PointDic = new Dictionary(); - for (int j = 0; j < _copterManager.Copters.Count; j++) - { - line = lines[startIndex + j + 1]; - string[] parameters = line.Split(' '); - int id = Convert.ToInt32(parameters[0]); - string frame = parameters[1]; - string[] point = new string[3]; - point[0] = parameters[1]; //左右 经度 - point[1] = parameters[2]; //上下 高度 - point[2] = parameters[3]; //前后 纬度 - PointDic.Add(id, point); - } - - var lastTask = Tasks.LastOrDefault(); - var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = true, FlytoTime = flytime, LoiterTime = 0 }; - newTask.TaskCnName = taskName; - for (int k = 0; k < PointDic.Count; k++) - { - string[] point = PointDic[k + 1]; - - //string frame = parameters[1]; - string x = point[0]; //左右 经度 - string y = point[1]; //上下 高度 - string z = point[2]; //前后 纬度 - Tuple observationLatLng = null; - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - OriginLat, - OriginLng, - 90, - Convert.ToSingle(x) / 100); - - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - observationLatLng.Item1, - observationLatLng.Item2, - 0, - Convert.ToSingle(z) / 100); - - var thisSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( - _copterManager.Copters[k], new LatLng(observationLatLng.Item1 - OriginLat, observationLatLng.Item2 - OriginLng), - Convert.ToSingle(y) / 100, false); - newTask.SingleCopterInfos.Add(thisSingleCopterInfo); - - } - Tasks.Add(newTask); - RaiseTaskAdded(lastTask, newTask); - } - // Alert.Show("导入完成!"); - /* - Dictionary PointDic = new Dictionary(); - foreach (string line in lines) - { - string[] parameters = line.Split(' '); - int id = Convert.ToInt32(parameters[0]); - string frame = parameters[1]; - string[] point = new string[3]; - point[0] = parameters[1]; //左右 经度 - point[1] = parameters[2]; //上下 高度 - point[2] = parameters[3]; //前后 纬度 - PointDic.Add(id, point); - } - - - var lastTask = Tasks.LastOrDefault(); - var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = true, FlytoTime = 10, LoiterTime = 10 }; - for (int i = 0; i < PointDic.Count; i++) - { - string[] point = PointDic[i + 1]; - - //string frame = parameters[1]; - string x = point[0]; //左右 经度 - string y = point[1]; //上下 高度 - string z = point[2]; //前后 纬度 - Tuple observationLatLng = null; - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - OriginLat, - OriginLng, - 90, - Convert.ToSingle(x) / 100); - - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - observationLatLng.Item1, - observationLatLng.Item2, - 0, - Convert.ToSingle(z) / 100); - - var thisSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( - _copterManager.Copters[i], new LatLng(observationLatLng.Item1 - OriginLat, observationLatLng.Item2 - OriginLng), - Convert.ToSingle(y)/100, false); - newTask.SingleCopterInfos.Add(thisSingleCopterInfo); - - } - Tasks.Add(newTask); - TaskAdded?.Invoke(this, new FlightTaskAddedEventArgs { LastTask = lastTask, AddedTask = newTask }); - */ - - } - - public void ImportBlenderFlyToTask(string blenderVectors) - { - string[] lineVectors = blenderVectors.Replace("\r\n","\n").Split('\n'); - - var lastTask = Tasks.LastOrDefault(); - float alt = lastTask.SingleCopterInfos[0].TargetAlt; - double lat = lastTask.SingleCopterInfos[0].LatLngOffset.Lat; - double lng = lastTask.SingleCopterInfos[0].LatLngOffset.Lng; - - - foreach (var item in lineVectors) - { - string vector = item.Replace("Vector((", "").Replace("))", ""); - var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = true, FlytoTime = 1, LoiterTime = 0 }; - - string[] vectors = vector.Split(','); - double x = double.Parse(vectors[1]); - double y = double.Parse(vectors[0]); - int x_directionDegrees = x > 0 ? 90 : -90; - int y_directionDegrees = y > 0 ? 0 : 180; - - Tuple observationLatLng = null; - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - lat, - lng, - 90, - (float)x); - - observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - observationLatLng.Item1, - observationLatLng.Item2, - 0, - (float)y); - - - var newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( - _copterManager.Copters[0], new LatLng((double)observationLatLng.Item1, - (double)observationLatLng.Item2), alt, false); - - newTask.SingleCopterInfos.Add(newSingleCopterInfo); - Tasks.Add(newTask); - RaiseTaskAdded(lastTask, newTask); - Message.Show(vector); - } - } - - public void RestoreFlyToTask(bool staggerRoutes, int flytoTime, int loiterTime, string taskName, dynamic singleCopterInfos, bool isMeter) - { - var copters = _copterManager.Copters; - float tagalt = 15; - if (!copters.Any()) return; - AppEx.Current.AppMode = AppMode.ModifyingTask; - var lastTask = Tasks.LastOrDefault(); - var nullableCenter = copters.GetCenter(); - 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; - // TODO: 王海, 20150801, 处理实际飞行器数目与记录中数目不一致的情况。 - for (int i = 0; i < copters.Count; i++) - { - var copter = copters[i]; - FlightTaskSingleCopterInfo newSingleCopterInfo; - if (i < singleCopterInfos.Count) - { - var singleCopterInfoObj = singleCopterInfos[i]; - tagalt = (float)singleCopterInfoObj.targetAlt; - if (isMeter) - newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( - copter, - (double)singleCopterInfoObj.x, - (double)singleCopterInfoObj.y, - (float)singleCopterInfoObj.targetAlt - copter.GroundAlt, - (bool)singleCopterInfoObj.isLandWaypoint); - else - newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( - copter, - new LatLng((double)singleCopterInfoObj.latOffset, (double)singleCopterInfoObj.lngOffset), - (float)singleCopterInfoObj.targetAlt - copter.GroundAlt, (bool)singleCopterInfoObj.isLandWaypoint); - - var jsonArray = singleCopterInfoObj.ledInfos as Newtonsoft.Json.Linq.JArray; - ObservableCollection ledList = jsonArray.ToObject>(); - foreach(LEDInfo info in ledList) - { - newSingleCopterInfo.AddLEDInfo(info); - } - if (singleCopterInfoObj.isChangeSpeed != null) - { - bool isChangeSpeed = (bool)singleCopterInfoObj.isChangeSpeed; - if (isChangeSpeed) - { - newSingleCopterInfo.IsChangeSpeed = isChangeSpeed; - newSingleCopterInfo.LevelSpeed = (float)singleCopterInfoObj.levelSpeed; - newSingleCopterInfo.UpSpeed = (float)singleCopterInfoObj.upSpeed; - newSingleCopterInfo.DownSpeed = (float)singleCopterInfoObj.downSpeed; - } - } - } - else - { - //实际飞机比保存的任务计划的飞机多,多的飞机设置默认航点 - newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask - (copter, (double)copter.Latitude, (double)copter.Longitude, tagalt); - - } - newTask.SingleCopterInfos.Add(newSingleCopterInfo); - } - Tasks.Add(newTask); - RaiseTaskAdded(lastTask, newTask); - } - - - private void RestoreTakeOffTask(byte takeOffTime, dynamic singleCopterInfos) - { - var copters = _copterManager.Copters; - if (copters == null || !copters.Any()) return; - AppEx.Current.AppMode = AppMode.ModifyingTask; - var lastTask = Tasks.LastOrDefault(); - FlightTask takeOffTask = Tasks[0]; - takeOffTask.TakeOffTime = takeOffTime; - for (int i = 0; i < copters.Count; i++) - { - var singleCopterInfoObj = singleCopterInfos[i]; - takeOffTask.SingleCopterInfos[i].TakeOffWaitTime = (ushort)singleCopterInfoObj.waitTime; - if (singleCopterInfoObj.ledInfos!= null) - { - var jsonArray = singleCopterInfoObj.ledInfos as Newtonsoft.Json.Linq.JArray; - ObservableCollection ledList = jsonArray.ToObject>(); - foreach (LEDInfo info in ledList) - { - takeOffTask.SingleCopterInfos[i].AddLEDInfo(info); - } - } - - //Message.Show(((ushort)singleCopterInfoObj.waitTime).ToString()); - } - } - - private void RestoreLandTask(dynamic singleCopterInfos) - { - var copters = _copterManager.Copters; - if (copters == null || !copters.Any()) return; - AppEx.Current.AppMode = AppMode.ModifyingTask; - var lastTask = Tasks.LastOrDefault(); - - var LandTask = new FlightTask(FlightTaskType.Land); - for (int i = 0; i < copters.Count; i++) - { - var copter = copters[i]; - FlightTaskSingleCopterInfo newSingleCopterInfo; - var singleCopterInfoObj = singleCopterInfos[i]; - newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForLandTask(copter, (int)singleCopterInfoObj.waitTime); - LandTask.SingleCopterInfos.Add(newSingleCopterInfo); - } - Tasks.Add(LandTask); - RaiseTaskAdded(lastTask, LandTask); - - } - - - - //导出任务 (单位:米) - public IEnumerable ExportTasksToMeter() - { - var tasks = Tasks.Select(task => - { - var type = task.TaskType; - switch (type) - { - case FlightTaskType.TakeOff: - return new { - type = type, - takeoffnumber = 1,// TakeOffNumAttr, - takeoffTime = task.TakeOffTime, - singleCopterInfos = task.SingleCopterInfos.Select(info => - { - return new - { - waitTime = info.TakeOffWaitTime, - ledInfos = info.LEDInfos - }; - }) - }; - case FlightTaskType.FlyTo: - return new - { - type = type, - staggerRoutes = task.StaggerRoutes, - flytoTime = task.FlytoTime, - loiterTime = task.LoiterTime, - taskname = task.TaskCnName, - singleCopterInfos = task.SingleCopterInfos.Select(info => - { - var offset = info.LatLngOffset; - return new - { - x = info.X, - y = info.Y, - targetAlt = info.TargetAlt + info.Copter.GroundAlt, //导出时加上地面摆放高度,导入后若没有摆放高度,模拟就会清楚的看到高度错误 - //showLED = info.FlytoShowLED, - ledInfos = info.LEDInfos, - isLandWaypoint = info.IsLandWaypoint, - isChangeSpeed = info.IsChangeSpeed, - levelSpeed = info.LevelSpeed, - upSpeed = info.UpSpeed, - downSpeed = info.DownSpeed - }; - }) - }; - - - case FlightTaskType.Land: - { - return new - { - type = type, - singleCopterInfos = task.SingleCopterInfos.Select(info => - { - return new - { - waitTime = info.LandWaitTime - }; - }) - - }; - } - default: - throw new NotImplementedException(type + " task export not implemented."); - } - }); - return tasks; - } - - //导出任务 - public IEnumerable ExportTasks() - { - // For reference. - //var tasks = new object[] - //{ - // new - // { - // type = FlightTaskType.TakeOff, - // }, - // new - // { - // type = FlightTaskType.FlyTo, - // staggerRoutes = false, - // singleCopterInfos = new object[] { - // new { - // latOffset = 0.0001, - // lngOffset = 0.0001, - // targetAlt = 10 - // }, - // new { - // latOffset = 0.0003, - // lngOffset = 0.0003, - // targetAlt = 15 - // } - // } - // }, - // new - // { - // type = FlightTaskType.Turn, - // singleCopterInfos = new object[] { - // new { - // latOffset = 0.0001, - // lngOffset = 0.0001, - // targetAlt = 10, - // targetHeading = 90 - // }, - // new { - // latOffset = 0.0001, - // lngOffset = 0.0001, - // targetAlt = 10, - // targetHeading = 270 - // } - // } - // }, - // new - // { - // type = FlightTaskType.Circle, - // singleCopterInfos = new object[] { - // new { - // latOffset = 0.0001, - // lngOffset = 0.0001, - // targetAlt = 10, - // centerDirectionDeg = 90, - // radius = 1000, - // rate = 20, - // turns = 1, - // channel3 = 1500 - // }, - // new { - // latOffset = 0.0003, - // lngOffset = 0.0003, - // targetAlt = 15, - // centerDirectionDeg = 270, - // radius = 1000, - // rate = 20, - // turns = 1, - // channel3 = 1500 - // } - // } - // }, - // new - // { - // type = FlightTaskType.SimpleCircle, - // singleCopterInfos = new object[] { - // new { - // latOffset = 0.0001, - // lngOffset = 0.0001, - // targetAlt = 10, - // rate = 20, - // turns = 1, - // channel3 = 1500 - // }, - // new { - // latOffset = 0.0003, - // lngOffset = 0.0003, - // targetAlt = 15, - // rate = 20, - // turns = 1, - // channel3 = 1500 - // } - // } - // } - //}; - var tasks = Tasks.Select(task => - { - var type = task.TaskType; - switch (type) - { - case FlightTaskType.TakeOff: - return new { - type = type, - takeoffnumber = 1,//TakeOffNumAttr, - takeoffTime = task.TakeOffTime, - singleCopterInfos = task.SingleCopterInfos.Select(info => - { - return new - { - waitTime = info.TakeOffWaitTime, - ledInfos = info.LEDInfos - }; - }) - }; - case FlightTaskType.FlyTo: - return new - { - type = type, - staggerRoutes = task.StaggerRoutes, - flytoTime = task.FlytoTime, - loiterTime = task.LoiterTime, - taskname = task.TaskCnName, - singleCopterInfos = task.SingleCopterInfos.Select(info => - { - var offset = info.LatLngOffset; - return new - { - latOffset = offset.Lat, - lngOffset = offset.Lng, - targetAlt = info.TargetAlt + info.Copter.GroundAlt, //导出时加上地面摆放高度,导入后若没有摆放高度,模拟就会清楚的看到高度错误 - //showLED = info.FlytoShowLED, - ledInfos = info.LEDInfos, - isLandWaypoint = info.IsLandWaypoint, - isChangeSpeed = info.IsChangeSpeed, - levelSpeed = info.LevelSpeed, - upSpeed = info.UpSpeed, - downSpeed = info.DownSpeed - }; - }) - }; - - - case FlightTaskType.Land: - { - return new - { - type = type, - singleCopterInfos = task.SingleCopterInfos.Select(info => - { - return new - { - waitTime = info.LandWaitTime - }; - }) - - }; - } - default: - throw new NotImplementedException(type + " task export not implemented."); - } - }); - return tasks; - } - - - //导入任务,可设置导入哪些步骤 - public void ImportTasksindex(dynamic tasks, int startindex,int endindex, bool isMeter) - { - var copters = _copterManager.Copters; - - if (Tasks.Count == 0) - AddTakeOffTask(copters); - - - int i =1; - foreach (var task in tasks) - { - if ((i >= startindex)&& (i <= endindex)) - { - switch ((FlightTaskType)task.type) - { - case FlightTaskType.TakeOff: - // AddTakeOffTask(copters); // added by ZJF - // 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; - case FlightTaskType.Land: - RestoreLandTask(task.singleCopterInfos); - break; - } - } - i++; - } - } - - - //计算中心点 (三维的) - private Point3D CenterFormMeter(List point1, List point2) - { - Point3D centerPoint = new Point3D(0, 0, 0); - if (point1.Count != point2.Count) return centerPoint; - - double minX = point1[0].X; - double maxX = point1[0].X; - - double minY = point1[0].Y; - double maxY = point1[0].Y; - - - double minZ = point1[0].Z; - double maxZ = point1[0].Z; - - - - int count = point1.Count; - for (int i = 0; i < count; i++) - { - minX = Math.Min(minX, Math.Min(point1[i].X, point2[i].X)); - maxX = Math.Max(maxX, Math.Min(point1[i].X, point2[i].X)); - - minY = Math.Min(minY, Math.Min(point1[i].Y, point2[i].Y)); - maxY = Math.Max(maxY, Math.Max(point1[i].Y, point2[i].Y)); - - minZ = Math.Min(minZ, Math.Min(point1[i].Z, point2[i].Z)); - maxZ = Math.Max(maxZ, Math.Max(point1[i].Z, point2[i].Z)); - - - } - centerPoint.X = (minX + maxX) / 2; - centerPoint.Y = (minY + maxY) / 2; - centerPoint.Z = (minZ + maxZ) / 2; - return centerPoint; - } - - - public double SumFlyLines(List preinfos, List currinfos) - { - double sumdis = 0; - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - //当前任务 - Point3D preLoc = new Point3D(preinfos[i].X, preinfos[i].Y, preinfos[i].TargetAlt); - Point3D curLoc = new Point3D(currinfos[i].X, currinfos[i].Y, currinfos[i].TargetAlt); - //算距离 - sumdis += Point3D.Subtract(curLoc, preLoc).Length; - } - return sumdis; - } - public void SetAllTaskFlytime() - { - //起飞航点0需要单独计算 - //第一个航点1,是调整航点根据地面摆放情况调整,默认2+1秒 - //从2开始自动计算 - Tasks[1].FlytoTime = 2; - for (int taskIndex = 2; taskIndex < Tasks.Count; taskIndex++) - SetTaskFlytime(taskIndex); - Message.Show($"任务时间计算执行完成----"); - } - public void CheckAllTaskFlytime() - { - if (_copterManager.FC_VER_NO < 3) - { - Alert.Show("不支持的功能", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); - return; - } - //第一个航点1,是调整航点根据地面摆放情况调整,默认2+1秒 - //从2开始检查 - for (int taskIndex = 2; taskIndex < Tasks.Count; taskIndex++) - CheckTaskFlytime(taskIndex); - Message.Show($"任务检测执行完成----"); - } - - public void SetTaskFlytime_v1(int taskIndex, bool settime = true) - { - double speed = 5.0f; //默认速度 - - if ((taskIndex > 0) && (taskIndex < Tasks.Count) && (Tasks[taskIndex].TaskType == FlightTaskType.FlyTo)) - { - if (_copterManager.Copters.Count() > 0) - { - - //计算之前航点有没改变速度,有就取最后一次速度 - //if (currspeed == -1.0) - { - for (int _taskIndex = taskIndex - 1; _taskIndex > 1; _taskIndex--) - - { - var curWaypoint = Tasks[_taskIndex].SingleCopterInfos.FirstOrDefault(); - if ((curWaypoint.IsChangeSpeed)) - { - speed = curWaypoint.LevelSpeed; - break; - } - } - } - double maxDistance = 0.0f; - string copterName = ""; - foreach (var copter in _copterManager.Copters) - { - var prevWaypoint = Tasks[taskIndex - 1].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); - var curWaypoint = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); - if ((curWaypoint.IsChangeSpeed) && (curWaypoint.LevelSpeed == -1)) - { - Message.Show($"任务{taskIndex + 1}飞机编号:{copter.Id}是自动速度,无法计算时间!"); - return; - } - - //当前航点是否改变速度,有就取修改的速度 - if (curWaypoint.IsChangeSpeed) - { - - speed = curWaypoint.LevelSpeed; - - } - - double distance = GeographyUtils.CalcDistance( - prevWaypoint.TargetLat, prevWaypoint.TargetLng, prevWaypoint.TargetAlt, - curWaypoint.TargetLat, curWaypoint.TargetLng, curWaypoint.TargetAlt); - if (distance > maxDistance) - { - maxDistance = distance; - copterName = copter.Name; - // speed = curWaypoint.LevelSpeed; - } - } - - double time = CalculateFlyIime(maxDistance, speed); - Message.Show($"任务{taskIndex + 1}最大航点间距 = {Math.Round(maxDistance, 2)}米, 水平速度={Math.Round(speed, 2)}, 飞行时间 = {Math.Round(time, 2)}秒, 飞机编号:{copterName}"); - if (settime) - Tasks[taskIndex].FlytoTime = (int)Math.Round(time, 2); - } - } - - return; - } - - - public int getflytype(int taskIndex) - { - bool addspeedmk = false; //是否要加速 - 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; //加减速 - else if (addspeedmk) flytype = 2; //单加速 - else if (decspeedmk) flytype = 3; //单减速 - return flytype; - } - public void SetTaskFlytime_v2(int taskIndex, - float acc_xy, float acc_z, - float defvel_xy, float defvel_up, float defvel_down, - bool settime = true) - { - if ((taskIndex > 0) && (taskIndex < Tasks.Count) && (Tasks[taskIndex].TaskType == FlightTaskType.FlyTo)) - { - if (_copterManager.Copters.Count() > 0) - { - string copterName = ""; - double maxDistance_xy = 0.0f; - double maxDistance_z = 0.0f; - double maxDistance_up = 0.0f; - double maxDistance_down = 0.0f; - string copterName_xy = ""; - string copterName_up = ""; - string copterName_down = ""; - int flytimetype = getflytype(taskIndex); - foreach (var copter in _copterManager.Copters) - { - var prevWaypoint = Tasks[taskIndex - 1].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); - var curWaypoint = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); - - double distance_xy = GeographyUtils.CalcDistance( - prevWaypoint.TargetLat, prevWaypoint.TargetLng, 0, - curWaypoint.TargetLat, curWaypoint.TargetLng, 0); - double distance_z = curWaypoint.TargetAlt - prevWaypoint.TargetAlt; - - - if (distance_xy > maxDistance_xy) - { - maxDistance_xy = distance_xy; - copterName_xy = copter.Name; - } - - if (Math.Abs(distance_z) > maxDistance_z) - { - maxDistance_z = Math.Abs(distance_z); - } - - - if (distance_z > 0) - { - if (distance_z > maxDistance_up) - { - maxDistance_up = distance_z; - copterName_up = copter.Name; - } - } - else - { - if (-distance_z > maxDistance_down) - { - maxDistance_down = -distance_z; - copterName_down = copter.Name; - } - } - }//循环结束 - - double time_xy = getMinfligthtime((float)maxDistance_xy, acc_xy, defvel_xy, flytimetype); - double time_up = getMinfligthtime((float)maxDistance_up, acc_z, defvel_up, flytimetype); - double time_down = getMinfligthtime((float)maxDistance_down, acc_z, defvel_down, flytimetype); - double tasktime = time_xy; - copterName = copterName_xy; - string divstr = "水平"; - if (time_up > tasktime) - { - tasktime = time_up; - copterName = copterName_up; - divstr = "上升"; - } - - if (time_down > tasktime) - { - tasktime = time_down; - copterName = copterName_down; - divstr = "下降"; - } - tasktime = Math.Max(time_xy, time_up); - tasktime = Math.Max(tasktime, time_down); - Message.Show($"任务{taskIndex + 1}距离:水平{Math.Round(maxDistance_xy, 2)}米;垂直:{Math.Round(maxDistance_z, 2)}米, " + - $"最长耗时:{Math.Round(tasktime, 2)}秒,用于{divstr}飞行,编号:{copterName}" - ); - if (settime) - Tasks[taskIndex].FlytoTime = (int)(int)Math.Ceiling(tasktime); - } - } - - return; - - } - - public void SetTaskFlytime(int taskIndex, bool settime = true) - { - if (taskIndex <= 1) - { - Message.Show($"无法估计起飞或2号任务飞行时间,请根据现场情况调整"); - return; - } - - if (_copterManager.FC_VER_NO >= 3) - { - float _acc_xy = FC_acc_xy; - float _acc_z = FC_acc_z; - float _defvel_xy = FC_defvel_xy; - float _defvel_up = FC_defvel_up; - float _defvel_down = FC_defvel_down; - if (Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().IsChangeSpeed) - { - _defvel_xy = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().LevelSpeed; - _defvel_up= Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().UpSpeed; - _defvel_down = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().DownSpeed; - } - - SetTaskFlytime_v2(taskIndex, _acc_xy, _acc_z, _defvel_xy, _defvel_up, _defvel_down, settime); - } - else SetTaskFlytime_v1(taskIndex, settime); - } - //新版本才有的功能,老版本直接提示推出了 - public void CheckTaskFlytime(int taskIndex) - { - if ((taskIndex > 0) && (taskIndex < Tasks.Count) && (Tasks[taskIndex].TaskType == FlightTaskType.FlyTo)) - { - if (_copterManager.Copters.Count() > 0) - { - string copterName = ""; - double maxDistance_xy = 0.0f; - double maxDistance_z = 0.0f; - double maxDistance_up = 0.0f; - double maxDistance_down = 0.0f; - string copterName_xy = ""; - string copterName_up = ""; - string copterName_down = ""; - int flytimetype = getflytype(taskIndex); - foreach (var copter in _copterManager.Copters) - { - var prevWaypoint = Tasks[taskIndex - 1].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); - var curWaypoint = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); - - double distance_xy = GeographyUtils.CalcDistance( - prevWaypoint.TargetLat, prevWaypoint.TargetLng, 0, - curWaypoint.TargetLat, curWaypoint.TargetLng, 0); - double distance_z = curWaypoint.TargetAlt - prevWaypoint.TargetAlt; - - - if (distance_xy > maxDistance_xy) - { - maxDistance_xy = distance_xy; - copterName_xy = copter.Name; - } - - if (Math.Abs(distance_z) > maxDistance_z) - { - maxDistance_z = Math.Abs(distance_z); - } - - - if (distance_z > 0) - { - if (distance_z > maxDistance_up) - { - maxDistance_up = distance_z; - copterName_up = copter.Name; - } - } - else - { - if (-distance_z > maxDistance_down) - { - maxDistance_down = -distance_z; - copterName_down = copter.Name; - } - } - }//循环结束 - - 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; - copterName = copterName_xy; - string divstr = "水平"; - if (time_up > tasktime) - { - tasktime = time_up; - copterName = copterName_up; - divstr = "上升"; - } - - if (time_down > tasktime) - { - tasktime = time_down; - copterName = copterName_down; - divstr = "下降"; - } - tasktime = Math.Max(time_xy, time_up); - tasktime = Math.Max(tasktime, time_down); - if (Tasks[taskIndex].FlytoTime < tasktime) - { - - Message.Show($"任务{taskIndex + 1}距离:水平{Math.Round(maxDistance_xy, 2)}米;垂直:{Math.Round(maxDistance_z, 2)}米, " + - $"目前飞行时间:{Tasks[taskIndex].FlytoTime}秒,最少需要:{Math.Round(tasktime, 2)}秒,用于{divstr}飞行,编号:{copterName}" - ); - if (Alert.Show($"任务{taskIndex + 1}时间过短,目前{Tasks[taskIndex].FlytoTime}秒至少{Math.Round(tasktime, 2)}秒才能全部飞到目标,需要更改吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning) - == MessageBoxResult.OK) - { - Message.Show($"任务{taskIndex + 1}飞行时间{Tasks[taskIndex].FlytoTime}秒更改为{Math.Ceiling(tasktime)}秒"); - Tasks[taskIndex].FlytoTime = (int)Math.Ceiling(tasktime); //上取整 - } - - - } - } - - - } - - return; - - } - - float fabsf(float vvalue) - { - return Math.Abs(vvalue); - - } - float sqrt(float vvalue) - { - return (float)Math.Sqrt(vvalue); - - } - - - //单算加速或减速和匀速部分的最小飞行时间 - float getMinfligthtime_acc(float Distance, float fc_acc, float fc_maxspeed) - { - float fDis = fabsf(Distance); // 总距离 - float facc = fabsf(fc_acc); // 减速度 - - // 物体开始时即以最大速度运动,不考虑加速过程 - float vel = fc_maxspeed; - - // 计算减速所需的时间和距离 - // 减速时间 (从最大速度减速到0) - float dectime = vel / facc; - // 减速阶段覆盖的距离 - float decdis = (vel * dectime) - (0.5f * facc * dectime * dectime); - - // 判断是否有足够的距离进行减速 - if (decdis >= fDis) - { - // 如果减速所需距离已经超过或等于总距离,调整最大速度 - // 使用公式 v^2 = u^2 + 2as 解出 v - vel = (float)Math.Sqrt(2 * facc * fDis); - // 重新计算减速时间 - dectime = vel / facc; - } - - // 计算匀速阶段时间 - float unftime = 0.0f; - if (decdis < fDis) - { - // 如果有剩余距离进行匀速运动 - unftime = (fDis - decdis) / vel; - } - - // 总飞行时间 = 匀速阶段时间 + 减速阶段时间 - return unftime + dectime; - } - float getMinfligthtime_acc_dec(float Distance, float fc_acc, float fc_maxspeed) - { - if ((Distance == 0) || (fc_acc == 0) || (fc_maxspeed == 0)) return 0; - float fDis = fabsf(Distance); - float facc = fabsf(fc_acc); - - float realflytime = 0.0f; - //计算一半的距离 - float hafdis = (fDis / 2); - //计算最大速度 - float vel = (float)sqrt(2 * facc * hafdis); - //如果速度超过最大速度 - if (vel > fc_maxspeed) - //使用最大速度 - vel = fc_maxspeed; - //加速时间 - float acctim = vel / facc; - //加速距离 - float accdis = vel * vel / (2 * facc); - //匀速段时间 - float vtime = (hafdis - accdis) / vel; - //到一半的时间 - float haftime = acctim + vtime; - realflytime = haftime * 2; - return realflytime; - } - - float getMinfligthtime(float Distance, float fc_acc, float fc_maxspeed,int timetype) - { - switch (timetype) - { - case 0://匀速 - return Distance / fc_maxspeed; - case 1: //同时计算加减速 - return getMinfligthtime_acc_dec(Distance, fc_acc, fc_maxspeed); - case 2: //计算加速 - case 3://计算减速 - return getMinfligthtime_acc(Distance, fc_acc, fc_maxspeed); - default: - return 0; - } - } - - public static double CalculateFlyIime(double s, double v) - { - double t; - double a = 1; //加速度1米每秒 - double at = v / a; - double a_s = 0.5f * a * at * at; - if (a_s > (s / 2)) //还没到特定速度就到了中点了 - { - t = (float)System.Math.Sqrt(s / a) * 2; - } - else - { - t = (s - a_s * 2) / v + at * 2; - } - - return t; - } //计算优化线路,采用米计算 - - /// - /// 自动生成航线2D和3D都用这个--------目前使用---------------- - /// - /// 3D计算 - /// 是否改变线路的结束点顺序--返回起飞点航线不能交换 - public void OptimizeRouteMeter(bool Is3d=false,bool Ischange=true) - { - Dictionary curTaskPoint = new Dictionary(); - Dictionary prevTaskPoint = new Dictionary(); - var stopWatch = new Stopwatch(); - stopWatch.Start(); - //获取当前航点与前一航点所有经纬高 - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - //当前任务 - var curinfo = SelectedTask.SingleCopterInfos[i]; - Point3D curLoc = new Point3D(curinfo.X, curinfo.Y, curinfo.TargetAlt); - curTaskPoint.Add(i, curLoc); - - //前一任务 - var prevInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i]; - Point3D prevLoc = new Point3D(prevInfo.X, prevInfo.Y, prevInfo.TargetAlt); - prevTaskPoint.Add(i, prevLoc); - } - //Dictionary RouteRes = Util.OptimizeRoute.GenRoute(curTaskPoint, prevTaskPoint); - if (Is3d) - { - ArrayList resarray = Util.OptimizeRoute.Gen3DRoute(curTaskPoint.Values.ToArray(), prevTaskPoint.Values.ToArray()); - Vector3[] RouteRes; - //最终 - RouteRes = (Vector3[])resarray[0]; - - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - SelectedTask.SingleCopterInfos[i].X = RouteRes[i].x; - SelectedTask.SingleCopterInfos[i].Y = RouteRes[i].y; - SelectedTask.SingleCopterInfos[i].TargetAlt = (float)RouteRes[i].z; - } - - SetTaskFlytime(SelectedTaskIndex); - - - } - else - { - ArrayList resarray = Util.OptimizeRoute.Gen2DRoute(curTaskPoint.Values.ToArray(), prevTaskPoint.Values.ToArray(), Ischange); - Vector3[] RouteRes; - //有错层,需要插入2个错层任务 - if (resarray.Count == 3) - { - //选中前一个任务,插入错层 - SelectTask(SelectedTaskIndex - 1); - AddTask(); - - //第一个错层 - RouteRes = (Vector3[])resarray[0]; - - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - SelectedTask.SingleCopterInfos[i].X = RouteRes[i].x; - SelectedTask.SingleCopterInfos[i].Y = RouteRes[i].y; - SelectedTask.SingleCopterInfos[i].TargetAlt = (float)RouteRes[i].z; - } - SetTaskFlytime(SelectedTaskIndex); - - - //第二个错层 - AddTask(); - - RouteRes = (Vector3[])resarray[1]; - - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - SelectedTask.SingleCopterInfos[i].X = RouteRes[i].x; - SelectedTask.SingleCopterInfos[i].Y = RouteRes[i].y; - SelectedTask.SingleCopterInfos[i].TargetAlt = (float)RouteRes[i].z; - } - - SetTaskFlytime(SelectedTaskIndex); - - - SelectTask(SelectedTaskIndex + 1); - - //最终 - RouteRes = (Vector3[])resarray[2]; - - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - SelectedTask.SingleCopterInfos[i].X = RouteRes[i].x; - SelectedTask.SingleCopterInfos[i].Y = RouteRes[i].y; - SelectedTask.SingleCopterInfos[i].TargetAlt = (float)RouteRes[i].z; - } - SetTaskFlytime(SelectedTaskIndex); - - - } - else - { - //最终 - RouteRes = (Vector3[])resarray[0]; - - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - SelectedTask.SingleCopterInfos[i].X = RouteRes[i].x; - SelectedTask.SingleCopterInfos[i].Y = RouteRes[i].y; - SelectedTask.SingleCopterInfos[i].TargetAlt = (float)RouteRes[i].z; - } - SetTaskFlytime(SelectedTaskIndex); - - } - } - stopWatch.Stop(); - - double sumlength = SumFlyLines(Tasks[SelectedTaskIndex - 1].SingleCopterInfos, SelectedTask.SingleCopterInfos); - - Message.Show($"计算用时:{stopWatch.Elapsed.TotalMilliseconds}ms,总飞行距离{sumlength}米"); - - - return; - } - - - - - //计算优化线路,采用经纬度计算 - public void OptimizeRouteNew() - { - Dictionary curTaskPoint = new Dictionary(); - Dictionary prevTaskPoint = new Dictionary(); - - var stopWatch = new Stopwatch(); - stopWatch.Start(); - //获取当前航点与前一航点所有经纬高 - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - //当前任务 - var curinfo = SelectedTask.SingleCopterInfos[i]; - PLLocation curLoc = new PLLocation(curinfo.TargetLat, curinfo.TargetLng, curinfo.TargetAlt); - curTaskPoint.Add(i, curLoc); - - //前一任务 - var prevInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i]; - PLLocation prevLoc = new PLLocation(prevInfo.TargetLat, prevInfo.TargetLng, prevInfo.TargetAlt); - prevTaskPoint.Add(i, prevLoc); - } - - - // int sss = Plane.AutoLine.CalAutoLine(curTaskPoint, prevTaskPoint); - - // Message.Show($"中心点:{sss}"); - - double farDistance; - double nearDistance; - int index; - - Dictionary recordLatLng = new Dictionary(); - while (curTaskPoint.Count > 0) - { - farDistance = double.MinValue; - PLLocation centerLatLng = CenterLatLng(curTaskPoint.Values.ToList(), prevTaskPoint.Values.ToList()); - index = 0; - //计算两个列表距离中心最远距离 - // Message.Show($"有{curTaskPoint.Count}个点,当前中心点:{centerLatLng.Longitude},{centerLatLng.Latitude},{centerLatLng.Altitude}"); - double distance1; - bool farIsCurTaskPoint = true; - - foreach (var item in curTaskPoint) - { - distance1 =Math.Round(GeographyUtils.CalcDistance(centerLatLng,item.Value),4); - if (distance1 > farDistance) - { - index = item.Key; - farDistance = distance1; - farIsCurTaskPoint = true; - // Message.Show($"调整距离{farDistance}是{farIsCurTaskPoint}的{index}"); - - } - } - - foreach (var item in prevTaskPoint) - { - distance1 = Math.Round(GeographyUtils.CalcDistance(centerLatLng,item.Value),4); - if (distance1 > farDistance) - { - index = item.Key; - farDistance = distance1; - farIsCurTaskPoint = false; - // Message.Show($"调整距离{farDistance}是{farIsCurTaskPoint}的{index}"); - - } - } - // Message.Show($"最远{farDistance}是{farIsCurTaskPoint}的{index}"); - - - - double tempDistance1; - nearDistance = double.MaxValue; - int nearIndex = 0; - if (farIsCurTaskPoint) - { - //最远的航点在当前任务 - foreach (var item in prevTaskPoint) - { - tempDistance1 = Math.Round(GeographyUtils.CalcDistance(curTaskPoint[index],item.Value),4); - if (tempDistance1 < nearDistance) - { - nearDistance = tempDistance1; - nearIndex = item.Key; - } - } - //最远的航点在当前任务 - // Message.Show($"最远是当前任务{index}距离它最近的前一任务点:ind={nearIndex},记录前一任务序号和当前任务位置"); - - recordLatLng.Add(nearIndex, curTaskPoint[index]); - curTaskPoint.Remove(index); - prevTaskPoint.Remove(nearIndex); - - } - else - { - //最远的航点在前一任务 - double prevLat = prevTaskPoint[index].Latitude; - double prevLng = prevTaskPoint[index].Longitude; - float prevAlt = prevTaskPoint[index].Altitude; - //最远的航点在当前任务 - //Message.Show($"最远点在前一任务:ind={index},距离{farDistance}"); - foreach (var item in curTaskPoint) - { - tempDistance1 = Math.Round(GeographyUtils.CalcDistance(prevTaskPoint[index],item.Value),4); - if (tempDistance1 < nearDistance) - { - nearDistance = tempDistance1; - nearIndex = item.Key; - } - } - // Message.Show($"最远是前一任务{index}距离它最近的当前任务点:ind={nearIndex},记录前一任务序号和当前任务位置"); - recordLatLng.Add(index, curTaskPoint[nearIndex]); - curTaskPoint.Remove(nearIndex); - prevTaskPoint.Remove(index); - } - - - } - - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - SelectedTask.SingleCopterInfos[i].TargetLat = recordLatLng[i].Latitude; - SelectedTask.SingleCopterInfos[i].TargetLng = recordLatLng[i].Longitude ; - SelectedTask.SingleCopterInfos[i].TargetAlt = recordLatLng[i].Altitude; - } - stopWatch.Stop(); - double sumlength = SumFlyLines(Tasks[SelectedTaskIndex - 1].SingleCopterInfos, SelectedTask.SingleCopterInfos); - - - - - double Dist; - int crosscount = 0; - for (int i = 0; i < _copterManager.Copters.Count; i++) - - { - for (int j = i + 1; j < _copterManager.Copters.Count; j++) - { - - - Dist = Util.OptimizeRoute.SqureDistanceSegmentToSegment( - new Point3D(Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i].X, - Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i].Y, - Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i].TargetAlt), - - new Point3D(Tasks[SelectedTaskIndex].SingleCopterInfos[i].X, - Tasks[SelectedTaskIndex].SingleCopterInfos[i].Y, - Tasks[SelectedTaskIndex].SingleCopterInfos[i].TargetAlt), - - new Point3D(Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].X, - Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].Y, - Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].TargetAlt), - - new Point3D(Tasks[SelectedTaskIndex].SingleCopterInfos[j].X, - Tasks[SelectedTaskIndex].SingleCopterInfos[j].Y, - Tasks[SelectedTaskIndex].SingleCopterInfos[j].TargetAlt) - ); - //交叉 - if (Dist < 0.01) - { - crosscount++; - // Message.Show($"飞机{i}和飞机{j}有交叉,距离{Dist}"); - - - } - } - - - } - - - - - - - - - - - - - - - - - - - - Message.Show($"经纬方式计算用时:{stopWatch.Elapsed.TotalMilliseconds}ms,总飞行距离{sumlength}米,有{crosscount}个交叉"); - - } - - //计算中心点 (三维的) - private PLLocation CenterLatLng(List point1, List point2) - { - PLLocation centerLatLng = new PLLocation(0,0,0); - if (point1.Count != point2.Count) return centerLatLng; - - double minLat = point1[0].Latitude; - double maxLat = point1[0].Latitude; - - double minLng = point1[0].Longitude; - double maxLng = point1[0].Longitude; - - - double minAlt = point1[0].Altitude; - double maxAlt = point1[0].Altitude; - - - - int count = point1.Count; - for (int i = 0; i < count; i++) - { - minLat = Math.Min(minLat, Math.Min(point1[i].Latitude, point2[i].Latitude)); - maxLat = Math.Max(maxLat, Math.Min(point1[i].Latitude, point2[i].Latitude)); - - minLng = Math.Min(minLng, Math.Min(point1[i].Longitude, point2[i].Longitude)); - maxLng = Math.Max(maxLng, Math.Max(point1[i].Longitude, point2[i].Longitude)); - - minAlt = Math.Min(minAlt, Math.Min(point1[i].Altitude, point2[i].Altitude)); - maxAlt = Math.Max(maxAlt, Math.Max(point1[i].Altitude, point2[i].Altitude)); - - - } - centerLatLng.Latitude = (minLat + maxLat) / 2; - centerLatLng.Longitude = (minLng + maxLng) / 2; - centerLatLng.Altitude =(float)(minAlt + maxAlt) / 2; - return centerLatLng; - } - - public void OptimizeRoute2() - { - double minLat = SelectedTask.SingleCopterInfos[0].TargetLat; - double maxLat = SelectedTask.SingleCopterInfos[0].TargetLat; - double minLng = SelectedTask.SingleCopterInfos[0].TargetLng; - double maxLng = SelectedTask.SingleCopterInfos[0].TargetLng; - - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - var curinfo = SelectedTask.SingleCopterInfos[i]; - //recordLatLng.Add(i, new LatLng(curinfo.TargetLat, curinfo.TargetLng)); - var lastInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i]; - minLat = Math.Min(minLat, Math.Min(curinfo.TargetLat, lastInfo.TargetLat)); - maxLat = Math.Max(maxLat, Math.Max(curinfo.TargetLat, lastInfo.TargetLat)); - - minLng = Math.Min(minLng, Math.Min(curinfo.TargetLng, lastInfo.TargetLng)); - maxLng = Math.Max(maxLng, Math.Max(curinfo.TargetLng, lastInfo.TargetLng)); - } - double CenterLat = (maxLat + minLat) / 2; - double CenterLng = (maxLng + minLng) / 2; - - Message.Show($"中心点:{CenterLat} {CenterLng}"); - - Dictionary distanceDic = new Dictionary(); - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - var curinfo = SelectedTask.SingleCopterInfos[i]; - var lastInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i]; - - - double distance1 = GeographyUtils.CalcDistance(CenterLat, CenterLng, 1, - curinfo.TargetLat, curinfo.TargetLng, 1); - //int[] nums = new int[] { SelectedTaskIndex, i}; - int nums = SelectedTaskIndex << 16 ^ i; - distanceDic.Add(nums, distance1); - double distance2 = GeographyUtils.CalcDistance(CenterLat, CenterLng, 1, - lastInfo.TargetLat, lastInfo.TargetLng, 1); - nums = (SelectedTaskIndex - 1) << 16 ^ i; - distanceDic.Add(nums, distance2); - } - distanceDic = distanceDic.OrderByDescending(o => o.Value).ToDictionary(p => p.Key, o => o.Value); - - - Dictionary recordLatLng = new Dictionary(); - while (distanceDic.Count > 0) - { - KeyValuePair kv = distanceDic.First(); - int taskIndex = kv.Key >> 16; - int copterID = kv.Key & 0xffff; - var curInfo = Tasks[taskIndex].SingleCopterInfos[copterID]; - if (taskIndex == SelectedTaskIndex) - { - double mindistance = double.MaxValue; - int index = 0; - for (int i = 0; i < Tasks[taskIndex - 1].SingleCopterInfos.Count; i++) - { - if (distanceDic.ContainsKey((taskIndex - 1) << 16 ^ i)) - { - var destInfo = Tasks[taskIndex - 1].SingleCopterInfos[i]; - double distance = GeographyUtils.CalcDistance(curInfo.TargetLat, curInfo.TargetLng, 1, - destInfo.TargetLat, destInfo.TargetLng, 1); - if (distance < mindistance) - { - mindistance = distance; - index = i; - } - } - } - recordLatLng.Add(index, - new LatLng(SelectedTask.SingleCopterInfos[copterID].TargetLat, - SelectedTask.SingleCopterInfos[copterID].TargetLng)); - - Message.Show($"航点{taskIndex} ID{copterID + 1} --航点{taskIndex - 1} id{index + 1}"); - distanceDic.Remove(kv.Key); - distanceDic.Remove(( taskIndex - 1) << 16 ^ index ); - } - else - { - double mindistance = double.MaxValue; - int index = 0; - for (int i = 0; i < Tasks[taskIndex + 1].SingleCopterInfos.Count; i++) - { - if (distanceDic.ContainsKey((taskIndex + 1) << 16 ^ i)) - { - var destInfo = Tasks[taskIndex + 1].SingleCopterInfos[i]; - double distance = GeographyUtils.CalcDistance(curInfo.TargetLat, curInfo.TargetLng, 1, - destInfo.TargetLat, destInfo.TargetLng, 1); - if (distance < mindistance && distanceDic.ContainsKey((SelectedTaskIndex) << 16 ^ i)) - { - mindistance = distance; - index = i; - } - } - } - recordLatLng.Add(copterID, - new LatLng(SelectedTask.SingleCopterInfos[index].TargetLat, - SelectedTask.SingleCopterInfos[index].TargetLng)); - - Message.Show($"航点{taskIndex} ID{copterID + 1} --航点{taskIndex + 1} id{index + 1}"); - distanceDic.Remove(kv.Key); - distanceDic.Remove(( taskIndex + 1) << 16 ^ index ); - } - - } - - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - SelectedTask.SingleCopterInfos[i].TargetLat = recordLatLng[i].Lat; - SelectedTask.SingleCopterInfos[i].TargetLng = recordLatLng[i].Lng; - } - - } - public void OptimizeRoute() - { - Dictionary distanceDic = new Dictionary(); - Dictionary recordLatLng = new Dictionary(); - for (int i = 0; i < SelectedTask.SingleCopterInfos.Count; i++) - { - var curinfo = SelectedTask.SingleCopterInfos[i]; - recordLatLng.Add(i, new LatLng(curinfo.TargetLat, curinfo.TargetLng)); - for (int j = 0; j < Tasks[SelectedTaskIndex - 1].SingleCopterInfos.Count; j++) - { - var lastInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j]; - - double distance = GeographyUtils.CalcDistance(curinfo.TargetLat, curinfo.TargetLng, curinfo.TargetLng, - lastInfo.TargetLat, lastInfo.TargetLng, lastInfo.TargetLng); - int[] nums = new int[] {i,j}; - distanceDic.Add(nums, distance); - } - } - distanceDic = distanceDic.OrderBy(o=>o.Value).ToDictionary(p=>p.Key,o=>o.Value); - List movedCopters = new List(); - List usedPoints = new List(); - foreach (KeyValuePair kv in distanceDic) - { - int moveCopterNum = kv.Key[1]; - int destNum = kv.Key[0]; - if (movedCopters.Contains(moveCopterNum) || usedPoints.Contains(destNum)) - continue; - SelectedTask.SingleCopterInfos[moveCopterNum].TargetLat = recordLatLng[destNum].Lat; - SelectedTask.SingleCopterInfos[moveCopterNum].TargetLng = recordLatLng[destNum].Lng; - movedCopters.Add(moveCopterNum); - usedPoints.Add(destNum); - } - } - - public void ImportWaypoint(string tasksText) - { - dynamic jsonfile = JsonConvert.DeserializeObject(tasksText); - dynamic points = jsonfile.points; - for (int i = 0; i < SelectedTask.SingleCopterInfos.Count; i++) - { - MapManager _mapManager = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance(); - - var pointjson= points[i]; - System.Windows.Point point = new System.Windows.Point((int)pointjson.x, (int)pointjson.y); - var loc = _mapManager.MapView.gmap.FromLocalToLatLng((int)point.X , (int)point.Y); - SelectedTask.SingleCopterInfos[i].TargetLat = loc.Lat; - SelectedTask.SingleCopterInfos[i].TargetLng = loc.Lng; - } - } - - - - // 导入任务 - public void ImportTasks(dynamic tasks, bool isMeter) - { - var copters = _copterManager.Copters; - - if (Tasks.Count == 0) - AddTakeOffTask(copters); - - foreach (var task in tasks) - { - switch ((FlightTaskType)task.type) - { - case FlightTaskType.TakeOff: - // AddTakeOffTask(copters); // added by ZJF - // 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; - - case FlightTaskType.Land: - RestoreLandTask(task.singleCopterInfos); - break; - } - } - } - -// private void ImportCoptersLocate(dynamic coptersLocate) -// { -// -// } - - private void ImportGroupsInfo(dynamic coptersLocate) - { - - } - - public void SelectTask(int taskIndex) - { - if (taskIndex == -1) return; - this.SelectedTaskIndex = taskIndex; - this.SelectedTask = Tasks[taskIndex]; - - } - - /** - * 在悬停任务时,右键waypoint为取消选中 - */ - public void RightSelect(int taskIndex, ICopter copter) - { - this.SelectedTaskIndex = taskIndex; - this.SelectedTask = Tasks[taskIndex]; - - } - - private int Name2Index(string name) // 获取指定copter名字对应的序号 - { - int index = -1; - for (int i = 0; i < SelectedTask.SingleCopterInfos.Count; i++) - { - if (name.Equals(SelectedTask.SingleCopterInfos[i].Copter.Name)) - { - return i; - } - } - return index; - } - - private string DeleteSelectedName( string nameArray, string name ) // 删除字符串中的指定项 - { - string copterStr = nameArray; - if (copterStr.Equals("")) - return ""; - string[] copterNameArray = copterStr.Split(','); - copterNameArray = copterNameArray.Where(str => !str.Equals(name)).ToArray(); - - copterStr = ""; - for (int i = 0; i < copterNameArray.Length; i++) - { - copterStr = copterStr + copterNameArray[i]; - if (i < (copterNameArray.Length - 1)) - { - copterStr = copterStr + ","; - } - } - return copterStr; - } - - //左键选中任务 - public void Select(FlightTask flightTask) - { - this.SelectedTaskIndex = Tasks.IndexOf(flightTask); - this.SelectedTask = flightTask; - - - - - } - - // 右键选中任务 - public void RightSelect(FlightTask flightTask) - { - int RightSelectedTaskIndexTmp = Tasks.IndexOf(flightTask); - if (this.RightSelectedTaskIndex == RightSelectedTaskIndexTmp) - { - this.RightSelectedTaskIndex = -RightSelectedTaskIndexTmp; - } - else - { - this.RightSelectedTaskIndex = RightSelectedTaskIndexTmp; - } - } - - #region Run and pause. - - private bool? _IsPaused; - public bool? IsPaused - { - get { return _IsPaused; } - private set { - if (Set(nameof(IsPaused), ref _IsPaused, value)) - { - if (_IsPaused??false) - { - MessageText = "任务暂停!"; - - }else - { - MessageText = "任务运行中"; - } - } - - - } - } - - TimeSpan timeSpan; - DateTime taskStartTime; - public async Task RunTaskAsync() - { - if (Tasks.Count == 0) return; - - //检查有没有真实飞机--真实飞机不能模拟,因为位置来自物理飞机--只能全部是模拟飞机才行 - foreach (var copter in _copterManager.Copters) - { - if (!(copter is IFakeCopter)) - { - Alert.Show($"模拟任务需要全部是模拟飞机,编号:{copter.Id } 不是模拟飞机,请检查"); - return ; - }else - { - //设置模拟飞机的飞行速度加速度等参数,用于计算位置 - copter.maxspeed_down = FC_maxvel_down; - copter.maxspeed_up = FC_maxvel_up; - copter.maxspeed_xy = FC_maxvel_xy; - copter.acc_z =FC_acc_z; - copter.acc_xy = FC_acc_xy; - } - - } - - - - if (CurrentRunningTaskIndex == 0) - { - taskStartTime = DateTime.Now; - Message.Show($"{DateTime.Now.ToString("HH:mm:ss")}:任务开始"); - } - - /* - //设置模拟飞行更新间隔,都是I7配置下 - int update_int = 50; //300以内50流畅 - if ((_copterManager.Copters.Count() > 300) && ((_copterManager.Copters.Count() <= 500))) - update_int = 100; //300-500, 100才能模拟有些跳动 - if ((_copterManager.Copters.Count() > 500) ) - update_int = 150; //极限了 500-1000可以用 - foreach (var copter in _copterManager.Copters) - copter.sim_update_int = update_int; - */ - - - await RunAsync(); - if ((IsPaused ?? false) == false) - { - timeSpan = DateTime.Now - taskStartTime; - Message.Show($"{DateTime.Now.ToString("HH:mm:ss")}:任务结束"); - Message.Show($"总时长 = {timeSpan.Minutes}分{timeSpan.Seconds}秒"); - - } - } - - public async Task RunAsync() - { - IsPaused = false; - for (int i = CurrentRunningTaskIndex; i < Tasks.Count; i++) - { - var task = Tasks[i]; - //task.Status目前只用于任务条下面状态显示不同颜色 - task.Status = FlightTaskStatus.Stop; - } - AppEx.Current.AppMode = AppMode.RunningTasks; - StartAvoidingCrash(); //开始碰撞检测 - TaskState = TasksStatus.Running; - for (int i = CurrentRunningTaskIndex; i < Tasks.Count; i++) - { - var task = Tasks[i]; - //task.Status目前只用于任务条下面状态显示不同颜色 - task.Status = FlightTaskStatus.Running; - CurrentRunningTask = task; - CurrentRunningTaskIndex = i; - - //////////////////显示提示信息 - int starttime = 0; - for (int j = 0; j < task.TaskIndex; j++) - starttime += GetTaskTime(j); - TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(starttime)); - Message.Show($"{ts}:任务{i+1} {task.TaskCnName } 开始执行,需{ GetTaskTime(task.TaskIndex)}秒"); - ///////////////////////// - - - await task.RunAsync().ConfigureAwait(false); - // 1. 被暂停时,中断 RunAsync。继续运行时将把此时运行了一半的 CurrentRunningTask 重新运行一遍。 - if (IsPaused == true) - { - task.Status = FlightTaskStatus.Paused; - TaskState = TasksStatus.Paused; - Message.Show($"任务{i + 1} {task.TaskCnName } 暂停执行"); - return; - } - task.Status = FlightTaskStatus.Stop; - } - - // 2. 正常结束时,重置 CurrentRunningTask、CurrentRunningTaskIndex 和 IsPaused。 - TaskState = TasksStatus.Stop; - CurrentRunningTask = null; - CurrentRunningTaskIndex = 0; - IsPaused = null; - } - - public void Pause() - { - IsPaused = true; - } - - #endregion Run and pause. - - - Dictionary AvoidCrashLog = new Dictionary(); - - - - - - private async void StartAvoidingCrash() - { - await Task.Factory.StartNew(AvoidCrashtoshow); - await Task.Factory.StartNew(LoopToAvoidCrash); - } - private async void AvoidCrashtoshow() - { - while (IsPaused == false) - { - try - { - foreach (KeyValuePair kv in AvoidCrashLog) - { - string moveCopterNum = kv.Value; - int destNum = kv.Key; - Message.Show(moveCopterNum); - } - AvoidCrashLog.Clear(); //可能有丢失 - } - catch // 王海, 20151102, 通常是“集合已修改”异常。 - { - } - finally - { - await Task.Delay(100).ConfigureAwait(false); - } - } - } - private async void LoopToAvoidCrash() - { - while (IsPaused == false) - { - try - { - - double distance; - foreach (var copter in _copterManager.Copters) - { - foreach (var anotherCopter in _copterManager.Copters) - { - if (copter != anotherCopter && copter.IsTooCloseTo(anotherCopter, out distance)) - { - //防止卡顿,单加任务来显示 - AvoidCrashLog.Add(1, $"{copter.Name} 与 {anotherCopter.Name} 距离过近,间距{distance}米。"); - } - } - } - - - } - catch // 王海, 20151102, 通常是“集合已修改”异常。 - { - } - finally - { - await Task.Delay(50).ConfigureAwait(false); - } - } - } - - private void LoadIni() - { - Windows.IniHelper.IniFiles inifilse = new Windows.IniHelper.IniFiles(); - string readvalue = ""; - int intTemp; - float floatTemp; - readvalue = inifilse.IniReadvalue("Default", "ColumnCount"); - if (readvalue!= "" && int.TryParse(readvalue,out intTemp)) - ColumnCount = int.Parse(readvalue); - - readvalue = inifilse.IniReadvalue("Default", "ColumnDistance"); - if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) - ColumnDistance = float.Parse(readvalue); - - readvalue = inifilse.IniReadvalue("Default", "RowDistance"); - if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) - RowDistance = float.Parse(readvalue); - - readvalue = inifilse.IniReadvalue("Default", "Orientation"); - if (readvalue != "" && int.TryParse(readvalue, out intTemp)) - Orientation = int.Parse(readvalue); - - readvalue = inifilse.IniReadvalue("Default", "FC_acc_xy"); - if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) - FC_acc_xy = float.Parse(readvalue); - - readvalue = inifilse.IniReadvalue("Default", "FC_acc_z"); - if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) - FC_acc_z = float.Parse(readvalue); - - readvalue = inifilse.IniReadvalue("Default", "FC_maxvel_xy"); - if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) - FC_maxvel_xy = float.Parse(readvalue); - - readvalue = inifilse.IniReadvalue("Default", "FC_maxvel_up"); - if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) - FC_maxvel_up = float.Parse(readvalue); - - readvalue = inifilse.IniReadvalue("Default", "FC_maxvel_down"); - if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) - FC_maxvel_down = float.Parse(readvalue); - - - readvalue = inifilse.IniReadvalue("Default", "FC_defvel_xy"); - if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) - FC_defvel_xy = float.Parse(readvalue); - - readvalue = inifilse.IniReadvalue("Default", "FC_defvel_up"); - if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) - FC_defvel_up = float.Parse(readvalue); - - readvalue = inifilse.IniReadvalue("Default", "FC_defvel_down"); - if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) - FC_defvel_down = float.Parse(readvalue); - - - - } - - public void SaveIni() - { - Windows.IniHelper.IniFiles inifilse = new Windows.IniHelper.IniFiles(); - inifilse.IniWritevalue("Default", "ColumnCount", ColumnCount.ToString()); - inifilse.IniWritevalue("Default", "ColumnDistance", ColumnDistance.ToString()); - inifilse.IniWritevalue("Default", "RowDistance", RowDistance.ToString()); - inifilse.IniWritevalue("Default", "Orientation", Orientation.ToString()); - } - } - - public class FlightTaskAddedEventArgs : EventArgs - { - public FlightTask LastTask { get; set; } - public FlightTask AddedTask { get; set; } - } - - public class FlightTaskDeledEventArgs : EventArgs - { - public FlightTask DeledTask { get; set; } - public int TaskIndex { get; set; } - - } - - public class FlightTaskTypeChangedEventArgs : EventArgs - { - public FlightTaskTypeChangedEventArgs(FlightTask changedFlightTask) - { - this.ChangedFlightTask = changedFlightTask; - } - public FlightTask ChangedFlightTask { get; set; } - - } - - - public class FlightTaskcnNameChangedEventArgs : EventArgs - { - public FlightTaskcnNameChangedEventArgs(FlightTask changedFlightTask) - { - this.ChangedFlightTask = changedFlightTask; - } - public FlightTask ChangedFlightTask { get; set; } - - } - - - - - - - public class FlightTaskAddedOriginalEventArgs : EventArgs - { - public double Lat { get; set; } - public double Lng { get; set; } - } - - public class SingleCopterInfoChangedEventArgs : EventArgs - { - public SingleCopterInfoChangedEventArgs(FlightTaskSingleCopterInfo changedSingleCopterInfo) - { - this.ChangedSingleCopterInfo = changedSingleCopterInfo; - } - - public FlightTaskSingleCopterInfo ChangedSingleCopterInfo { get; set; } - } -} +using Plane.Collections; +using Plane.Copters; +using Plane.Geography; +using Plane.Windows.Messages; +using GalaSoft.MvvmLight; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Plane.CommunicationManagement; +using FlightRoute; +using System.IO; +using System.Windows.Media.Media3D; +using System.Diagnostics; +using Plane.FormationCreator.Util; +using System.Collections; +using System.Windows; + +namespace Plane.FormationCreator.Formation +{ + public class FlightTaskManager : ObservableObject + { + public FlightTaskManager(CopterManager copterManager) + { + LoadIni(); + _copterManager = copterManager; + + //AddTakeOffTask(_copterManager.Copters); + + _copterManager.Copters.CollectionChanged += (sender, e) => + { + // TODO: 王海, 20150724, 需要改为正确的做法(清除旧飞机的任务,补充新飞机的任务)。 + //AddTakeOffTask(e.NewItems?.Cast()); + }; + + _copterManager.SelectedCoptersChanged += (sender, e) => + { + if (_copterManager.AcceptingControlCopters != null && _copterManager.AcceptingControlCopters.Count() == 1) + CommModuleManager.Instance.LED_FlickerAsync(_copterManager.AcceptingControlCopters); + + /* + foreach (ICopter copter in _copterManager.AcceptingControlCopters) + { + copter.LEDAsync(); + } + */ + + // TODO: 王海, 20150803, 处理选中多个飞行器的情况。 + if (_copterManager.SelectedCopters.Count() > 1) + { + return; + } + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + + foreach (var task in Tasks) + { + foreach (var info in task.SingleCopterInfos) + { + if (info.Copter == selectedCopter) + { + task.ModifyingSingleCopterInfo = info; + break; + } + } + } + if (selectedCopter!=null) + selectedCopter.SetShowLEDFlashAsync(1, 100); + + //if (selectedCopter != null) + //selectedCopter.LEDAsync(); + }; + + TaskAdded += (sender, e) => + { + // TODO: 王海, 20150803, 处理选中多个飞行器的情况。 + if (_copterManager.SelectedCopters.Count() > 1) + { + return; + } + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + + var task = e.AddedTask; + foreach (var info in task.SingleCopterInfos) + { + if (info.Copter == selectedCopter) + { + task.ModifyingSingleCopterInfo = info; + break; + } + } + }; + } + + private CopterManager _copterManager; + + + + private string _MessageText="test"; + public string MessageText + { + get { return _MessageText; } + set + { + if (Set(nameof(MessageText), ref _MessageText, value)) + { + // _lastUpdateStatusTextTime = DateTime.Now; + } + } + } + + + private bool _TaskRun_2D = true; + public bool TaskRun_2D + { + get { return _TaskRun_2D; } + set + { + if (Set(nameof(TaskRun_2D), ref _TaskRun_2D, value)) + { + + } + } + } + + private void AddTakeOffTask(IEnumerable copters) + { + if (copters == null || !copters.Any()) return; + + bool takeOffTaskExisted = Tasks.Count >= 1; + FlightTask takeOffTask; + if (takeOffTaskExisted) + { + takeOffTask = Tasks[0]; + } + else + { + takeOffTask = new FlightTask(FlightTaskType.TakeOff); + Tasks.Add(takeOffTask); + RaiseTaskAdded(null, takeOffTask); + //TaskAdded?.Invoke(this, new FlightTaskAddedEventArgs { AddedTask = takeOffTask }); + } + foreach (var copter in copters) + { + takeOffTask.SingleCopterInfos.Add(FlightTaskSingleCopterInfo.CreateForTakeOffTask(copter, targetAlt: 15)); + } + } + + public ObservableCollection Tasks { get; } = new ObservableCollection(); + + + + public int GetTaskTime(int TaskIndex) + { + int tasktime = 0; + if ((Tasks==null)|| TaskIndex> Tasks.Count-1) return tasktime; + + FlightTask value = Tasks[TaskIndex]; + switch (value.TaskType) + { + case FlightTaskType.TakeOff: tasktime = value.TakeOffTime; ; break; + case FlightTaskType.FlyTo: tasktime = value.FlytoTime + value.LoiterTime; break; + //降落时间计算前一个任务目标高度最高的飞机的降落时间按1.5米/秒下降 + case FlightTaskType.Land: + float maxalt = 0.0f; + 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); + break; + } + return tasktime; + + } + + + + + private FlightTask _SelectedTask; + public FlightTask SelectedTask + { + get { return _SelectedTask; } + set + { + if (_SelectedTask != value) + { + int starttime=0; + + if (_SelectedTask != null) + { + + _SelectedTask.IsSelected = false; + if (TaskState == TasksStatus.Stop) + _SelectedTask.Status = FlightTaskStatus.Stop; + } + + if (value != null) + { + value.IsSelected = true; + value.IsRightSelected = true; + RightSelect(value); + if (TaskState== TasksStatus.Stop) + value.Status = FlightTaskStatus.Selected; + + for (int i = 0; i < value.TaskIndex; i++) + starttime += GetTaskTime(i); + + TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(starttime)); + string str = ""; + if (ts.Hours > 0) + { + str = ts.Hours.ToString() + "小时" + ts.Minutes.ToString() + "分" + ts.Seconds + "秒"; + } + if (ts.Hours == 0 && ts.Minutes > 0) + { + str = ts.Minutes.ToString() + "分" + ts.Seconds + "秒"; + } + if (ts.Hours == 0 && ts.Minutes == 0) + { + str = ts.Seconds + "秒"; + } + + if (value.ModifyingSingleCopterInfo == null) + { + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + + foreach (var info in value.SingleCopterInfos) + { + if (info.Copter == selectedCopter) + { + value.ModifyingSingleCopterInfo = info; + break; + } + } + + } + + + Message.ShowStatus($"选中 [{value.TaskIndex+1} {value.TaskCnName }] 从{str}开始执行,需{ GetTaskTime(value.TaskIndex)}秒,共{Tasks.Count}个任务"); + } + else Message.ShowStatus($"无任务选中"); + + } + Set(nameof(SelectedTask), ref _SelectedTask, value); + } + } + + private int _SelectedTaskIndex; + public int SelectedTaskIndex + { + get { return _SelectedTaskIndex; } + set { Set(nameof(SelectedTaskIndex), ref _SelectedTaskIndex, value); + // this.SelectedTask = Tasks[value]; + } + } + + // 右键单击任务,用于隐藏任务图标, 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 + { + get { return _CurrentRunningTask; } + private set { Set(nameof(CurrentRunningTask), ref _CurrentRunningTask, value); } + } + + private int _CurrentRunningTaskIndex; + public int CurrentRunningTaskIndex + { + get { return _CurrentRunningTaskIndex; } + private set { Set(nameof(CurrentRunningTaskIndex), ref _CurrentRunningTaskIndex, value); } + } + + private int _ColumnCount = 5; + public int ColumnCount + { + get { return _ColumnCount; } + set { Set(nameof(ColumnCount), ref _ColumnCount, value); } + } + + + private float _ColumnDistance = 4.0f; + public float ColumnDistance + { + get { return _ColumnDistance; } + set { Set(nameof(ColumnDistance), ref _ColumnDistance, value); } + } + + private float _RowDistance = 4.0f; + public float RowDistance + { + get { return _RowDistance; } + set { Set(nameof(RowDistance), ref _RowDistance, value); } + } + + private int _Orientation = 0; + public int Orientation + { + get { return _Orientation; } + set { Set(nameof(Orientation), ref _Orientation, value); } + } + + //水平加速度 + private float _FC_acc_xy = 0; + public float FC_acc_xy + { + get { return _FC_acc_xy; } + set { Set(nameof(FC_acc_xy), ref _FC_acc_xy, value); } + } + //垂直加速度 + private float _FC_acc_z = 0; + public float FC_acc_z + { + get { return _FC_acc_z; } + set { Set(nameof(FC_acc_z), ref _FC_acc_z, value); } + } + + //水平最大速度 + private float _FC_maxvel_xy = 0; + public float FC_maxvel_xy + { + get { return _FC_maxvel_xy; } + set { Set(nameof(FC_maxvel_xy), ref _FC_maxvel_xy, value); } + } + + //上升最大速度 + private float _FC_maxvel_up = 0; + public float FC_maxvel_up + { + get { return _FC_maxvel_up; } + set { Set(nameof(FC_maxvel_up), ref _FC_maxvel_up, value); } + } + //下降最大速度 + private float _FC_maxvel_down = 0; + public float FC_maxvel_down + { + get { return _FC_maxvel_down; } + set { Set(nameof(FC_maxvel_down), ref _FC_maxvel_down, value); } + } + + + //水平默认速度 + private float _FC_defvel_xy = 0; + public float FC_defvel_xy + { + get { return _FC_defvel_xy; } + set { Set(nameof(FC_defvel_xy), ref _FC_defvel_xy, value); } + } + + //上升默认速度 + private float _FC_defvel_up = 0; + public float FC_defvel_up + { + get { return _FC_defvel_up; } + set { Set(nameof(FC_defvel_up), ref _FC_defvel_up, value); } + } + //下降默认速度 + private float _FC_defvel_down = 0; + public float FC_defvel_down + { + get { return _FC_defvel_down; } + set { Set(nameof(FC_defvel_down), ref _FC_defvel_down, value); } + } + + + + + + private TasksStatus _TaskState = TasksStatus.Stop; + public TasksStatus TaskState + { + get { return _TaskState; } + private set { Set(nameof(TaskState), ref _TaskState, value); } + } + + public event EventHandler TaskAdded; + public event EventHandler TaskDeled; + + public void RaiseTaskDeled(FlightTask vDeledTask,int vTaskIndex) + { + try + { + TaskDeled?.Invoke(this, new FlightTaskDeledEventArgs { DeledTask = vDeledTask, TaskIndex= vTaskIndex }); + } + catch (Exception ex) + { + //RaiseExceptionThrown(ex); + } + + + } + public void RaiseTaskAdded(FlightTask lastTask ,FlightTask newTask) + { + try + { + TaskAdded?.Invoke(this, new FlightTaskAddedEventArgs { LastTask = lastTask, AddedTask = newTask }); + } + catch (Exception ex) + { + //RaiseExceptionThrown(ex); + } + newTask.PropertyChanged += (sender, e) => + { + switch (e.PropertyName) + { + case nameof(FlightTask.TaskTypeIndex): + case nameof(FlightTask.TaskCnName): + TaskTypeChanged?.Invoke(this, new FlightTaskTypeChangedEventArgs((FlightTask)sender)); + TaskcnNameChanged?.Invoke(this, new FlightTaskcnNameChangedEventArgs((FlightTask)sender)); + break; + default: + break; + } + }; + } + + + + + public event EventHandler OnOriginalSet; + + public event EventHandler SingleCopterInfoChanged; + + public void RaiseSingleCopterTaskChanged(FlightTaskSingleCopterInfo singleCopterInfo) + { + SingleCopterInfoChanged?.Invoke(this, new SingleCopterInfoChangedEventArgs(singleCopterInfo)); + } + + + public event EventHandler TaskTypeChanged; + public event EventHandler TaskcnNameChanged; + + public event EventHandler TasksCleared; + + public void AddTask() + { + //if (AppEx.Instance.CurrentMode == AppMode.PreparedForRunningTasks) + { + var copters = _copterManager.Copters; + if (!copters.Any()) return; + AppEx.Current.AppMode = AppMode.ModifyingTask; + if (Tasks.Count == 0) + AddTakeOffTask(copters); + var lastTask = Tasks.LastOrDefault(); + if (SelectedTask !=null) + lastTask = SelectedTask; + var nullableCenter = copters.GetCenter(); + if (nullableCenter == null) return; + var center = nullableCenter.Value; + var newTask = new FlightTask(FlightTaskType.FlyTo); + int coptindex = 0; + + int colnum = ColumnCount; //自动生成列数=4 + float coldis = ColumnDistance;//列相距5米 + float rowdis = RowDistance;//行相距5米 + float matrixdis = 20; //生成方阵距离30米 + int orientation = Orientation; + + int currcol = 0; //当前列号 + int currrow = 0; //当前行 + Tuple colLatLng = new Tuple(0, 0); + Tuple targetLatLng = new Tuple(0, 0); + FlightTaskSingleCopterInfo lastSingleCopterInfo = null; + FlightTaskSingleCopterInfo preSingleCopterInfo = null; + + foreach (var copter in copters) + { + preSingleCopterInfo = lastTask.SingleCopterInfos.Find(info => info.Copter == copter); + if (coptindex == 0) + { + lastSingleCopterInfo = lastTask.SingleCopterInfos.Find(info => info.Copter == copter); + targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(lastSingleCopterInfo.TargetLat, lastSingleCopterInfo.TargetLng, orientation, matrixdis); + colLatLng = targetLatLng; + } + else + { + if (currcol < colnum) + targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Item1, colLatLng.Item2, orientation + 90, currcol * coldis); + else + { + currrow++; + currcol = 0; + targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Item1, colLatLng.Item2, orientation + 180, rowdis); + colLatLng = targetLatLng; + } + } + currcol++; + coptindex++; + + + var newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask(copter, targetLatLng.Item1, targetLatLng.Item2, preSingleCopterInfo.TargetAlt); + newTask.SingleCopterInfos.Add(newSingleCopterInfo); + + } + int selindex = SelectedTaskIndex+1; + Tasks.Insert(SelectedTaskIndex+1, newTask); + RaiseTaskAdded(lastTask, newTask); + SelectTask(selindex); + + //第一个航点,回起飞点 + if (Tasks.Count == 2) + { + SelectedTask.FlytoTime = 2; + SelectedTask.LoiterTime = 2; + foreach (FlightTaskSingleCopterInfo info in SelectedTask.SingleCopterInfos) + { + info.TargetLat = info.Copter.Latitude; + info.TargetLng = info.Copter.Longitude; + } + } + + /* + Tasks.Add(newTask); + RaiseTaskAdded(lastTask, newTask); + SelectedTask = newTask; + SelectedTaskIndex = Tasks.Count - 1; + */ + + + + } + } + + //是否显示计划航线 + private bool _showroute = true; + public bool showroute + { + get { return _showroute; } + set { Set(nameof(showroute), ref _showroute, value); } + } + + private double _OriginLat = 0; + public double OriginLat + { + get { return _OriginLat; } + set { Set(nameof(OriginLat), ref _OriginLat, value); } + } + + private double _OriginLng = 0; + public double OriginLng + { + get { return _OriginLng; } + set { Set(nameof(OriginLng), ref _OriginLng, value); } + } + + private double _ObserverLat = 0; + public double ObserverLat + { + get { return _ObserverLat; } + set { Set(nameof(ObserverLat), ref _ObserverLat, value); } + } + + private double _ObserverLng = 0; + public double ObserverLng + { + get { return _ObserverLng; } + set { Set(nameof(ObserverLng), ref _ObserverLng, value); } + } + + + + + + /// + /// 起始点作为参考,设置起始点后飞行写入的数据将为相对坐标 + /// + public void SetOriginal() + { + OnOriginalSet?.Invoke(this, new FlightTaskAddedOriginalEventArgs { Lat = OriginLat, Lng = OriginLng }); + } + + + public void ClearTasks() + { + ResetTasks(); + this.Tasks.Clear(); + SelectedTask = null; + SelectedTaskIndex = 0; + //取消删除事件 + /* + if (TaskDeled != null) + { + Delegate[] dels = TaskDeled.GetInvocationList(); + if (dels != null) + { + foreach (Delegate d in dels) + { + TaskDeled -= d as EventHandler; + } + } + } + */ + + TasksCleared?.Invoke(this, EventArgs.Empty); + // AddTakeOffTask(_copterManager.Copters); + } + //删除选中的任务 + public void DelSelectedTask() + { + if (SelectedTask == null) return; + if (SelectedTask.TaskType == FlightTaskType.TakeOff) return; + int selindex = SelectedTaskIndex; + + // ResetTasks(); + SelectedTask.SingleCopterInfos.Clear(); + Tasks.RemoveAt(SelectedTaskIndex); + RaiseTaskDeled(SelectedTask,SelectedTaskIndex); + + SelectTask(selindex - 1); + + + // SelectedTaskIndex = 0; + } + + + + public async Task ForceNextTasks() + { + if (CurrentRunningTaskIndex == Tasks.Count - 1) + return; + + Pause(); + int i = 0; + //等待暂停或2s超时(80*25ms) + while ((TaskState != TasksStatus.Paused)||(i>80)) + { + await Task.Delay(25).ConfigureAwait(false); + i++; + } + + if (TaskState == TasksStatus.Paused) + { + CurrentRunningTask.Status = FlightTaskStatus.Stop; + CurrentRunningTask = null; + + //起飞任务需要跳过 +// if (CurrentRunningTaskIndex == 0) +// CurrentRunningTaskIndex++; + CurrentRunningTaskIndex++; + await RunTaskAsync(); + } + } + + //指定任务开始模拟 + public async Task FlyToTasks() + { + var copters = _copterManager.Copters; + if ((SelectedTaskIndex==-1) ||(TaskState == TasksStatus.Stop)) + return; + + int vSelectedTaskIndex= SelectedTaskIndex; + + Pause(); + int i = 0; + //等待暂停或2s超时(80*25ms) + while ((TaskState != TasksStatus.Paused) || (i > 80)) + { + await Task.Delay(25).ConfigureAwait(false); + i++; + } + if (SelectedTaskIndex == -1) + return; + + if (TaskState == TasksStatus.Paused) + { + CurrentRunningTask.Status = FlightTaskStatus.Stop; + CurrentRunningTask = null; + CurrentRunningTaskIndex = SelectedTaskIndex; + + + + //设置所有模拟飞机的位置 + for (int j = 0; j < copters.Count; j++) + { + var copter = copters[j]; + var fc = copter as FakeCopter; + float targalt = 0.0f; + double lat = 0.0f; + double lng = 0.0f; + + //飞机回到前一个任务位置, + + //起飞任务直接用当前起飞任务位置 + if (Tasks[SelectedTaskIndex].TaskType == FlightTaskType.TakeOff) + { + lat = Tasks[SelectedTaskIndex].SingleCopterInfos[j].TargetLat; + lng = Tasks[SelectedTaskIndex].SingleCopterInfos[j].TargetLng; + targalt = 0.0f; + } + else + { + //返航点直接设置起飞位置 + if (Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].IsLandWaypoint) + { + lat = Tasks[0].SingleCopterInfos[j].TargetLat; + lng = Tasks[0].SingleCopterInfos[j].TargetLng; + } + else + { + + //用前一个任务目标位置 + lat = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].TargetLat; + lng = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].TargetLng; + } + + //如果前一个是起飞任务,没有目标高度,用当前的 + if (Tasks[SelectedTaskIndex - 1].TaskType == FlightTaskType.TakeOff) + targalt = Tasks[SelectedTaskIndex].SingleCopterInfos[j].TargetAlt; + else + targalt = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].TargetAlt; + } + fc.SetProperties( + latitude: lat, + longitude: lng, + altitude: targalt + + ); + + } + + + + //起飞任务需要跳过 + // if (CurrentRunningTaskIndex == 0) + // CurrentRunningTaskIndex++; + + await RunTaskAsync(); + } + } + + + + + + public async Task ResetTasks() + { + var copters = _copterManager.Copters; + if (Tasks.Count == 0) return; + if (TaskState == TasksStatus.Running) + { + + Pause(); + //等待暂停或2s超时(80*25ms) + int k = 0; + while ((TaskState != TasksStatus.Paused) || (k > 80)) + { + await Task.Delay(25).ConfigureAwait(false); + k++; + } + } + TaskState = TasksStatus.Stop; + + CurrentRunningTaskIndex = 0; + if (CurrentRunningTask != null) + { + CurrentRunningTask.Status = FlightTaskStatus.Stop; + CurrentRunningTask = null; + } + + for (int i = 0; i < Tasks.Count; i++) + { + // 将起飞的阶段标志位都置位0 + if (Tasks[i].TaskType == FlightTaskType.TakeOff) + { + var infos = Tasks[i].SingleCopterInfos; + for (int j = 0; j < infos.Count; j++) + { + var info = infos[j]; + info.takeOffStage = 0; + } + } + + + } + + + //设置所有模拟飞机的位置 + for (int j = 0; j < copters.Count; j++) + { + var copter = copters[j]; + var fc = copter as FakeCopter; + if (fc != null) + { + fc.SetProperties( + latitude: Tasks[0].SingleCopterInfos[j].TargetLat, + longitude: Tasks[0].SingleCopterInfos[j].TargetLng, + altitude: 0 ); + //设置灯光为默认颜色 + fc.LEDColor = CopterManager.CopterDefaultColor;// "000000"; + fc.LEDMode = 0; + fc.LEDInterval = 0; + } + } + + } + + public string ExportC4DFlytoTask() + { + int count = SelectedTask.SingleCopterInfos.Count(); + //string[] lines = new string[count]; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < count; i++) + { + var singleCopterInfo = SelectedTask.SingleCopterInfos[i]; + double x = 100 * GeographyUtils.CalcDistance(OriginLat, OriginLng, 0, + OriginLat, singleCopterInfo.TargetLng, 0); + if (singleCopterInfo.TargetLng < OriginLng) x = -x; + double y = 100 * singleCopterInfo.TargetAlt; + + double z = 100 * GeographyUtils.CalcDistance(OriginLat, OriginLng, 0, + singleCopterInfo.TargetLat, OriginLng, 0); + if (singleCopterInfo.TargetLat < OriginLat) z = -z; + sb.AppendLine($"{i + 1} 0 {x} {y} {z}"); + //lines[i] = $"{i+1} {x} {y} {z}"; + } + + return sb.ToString().Trim(); + } + + + public void ImportC4DFlytoVCopter(string txt) + { + string[] lines = txt.Replace("\r\n", "\n").Split('\n'); + + if (lines.Length % (_copterManager.Copters.Count + 1) != 0) + { + Alert.Show("文件内容错误!"); + return; + } + + int taskCount = lines.Length / (_copterManager.Copters.Count + 1); + int startIndex; + string line; + Dictionary PointDic; + for (int i = 0; i < taskCount; i++) + { + startIndex = i * (_copterManager.Copters.Count + 1); + string taskName = lines[startIndex]; + PointDic = new Dictionary(); + for (int j = 0; j < _copterManager.Copters.Count; j++) + { + line = lines[startIndex + j + 1]; + string[] parameters = line.Split(' '); + int id = Convert.ToInt32(parameters[0]); + string frame = parameters[1]; + string[] point = new string[3]; + point[0] = parameters[1]; //左右 经度 + point[1] = parameters[2]; //上下 高度 + point[2] = parameters[3]; //前后 纬度 + PointDic.Add(id, point); + } + + var lastTask = Tasks.LastOrDefault(); + var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = true, FlytoTime = 10, LoiterTime = 1 }; + newTask.TaskCnName = taskName; + for (int k = 0; k < PointDic.Count; k++) + { + string[] point = PointDic[k + 1]; + + //string frame = parameters[1]; + string x = point[0]; //左右 经度 + string y = point[1]; //上下 高度 + string z = point[2]; //前后 纬度 + Tuple observationLatLng = null; + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + OriginLat, + OriginLng, + 90, + Convert.ToSingle(x) / 100); + + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + observationLatLng.Item1, + observationLatLng.Item2, + 0, + Convert.ToSingle(z) / 100); + + var fc = _copterManager.Copters[k] as FakeCopter; + double vlatitude = observationLatLng.Item1; + double vlongitude = observationLatLng.Item2; + + + fc.SetProperties( + latitude: vlatitude, + longitude: vlongitude, + altitude: Convert.ToSingle(y) / 100); + + + + + } + Tasks.Add(newTask); + RaiseTaskAdded(lastTask, newTask); + } + + + } + + public void ImportDlltoVCopter(string filename) + { + Vector3[] vc; + + + + + string extname = Path.GetExtension(filename); + if (extname == ".svg") + { + vc = FlyBase.svgToPos(filename); + } + else if (extname == ".obj") + { + vc = FlyBase.objToPos(filename); + } + else return; + + if (vc.Count() != _copterManager.Copters.Count) + { + Alert.Show($"飞机数量不匹配!导入{vc.Count()}架,实际{_copterManager.Copters.Count}"); + return; + } + int id = 0; + foreach (Vector3 item in vc) + { + Tuple observationLatLng = null; + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + OriginLat, + OriginLng, + 90, + (float)item.x / 100); + + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + observationLatLng.Item1, + observationLatLng.Item2, + 0, + (float)item.z / 100); + + + var fc = _copterManager.Copters[id] as FakeCopter; + double vlatitude = observationLatLng.Item1;// - OriginLat; + double vlongitude = observationLatLng.Item2;// - OriginLng; + + + fc.SetProperties( + latitude: vlatitude, + longitude: vlongitude, + altitude: (float)item.y / 100); + id++; + + } + } + + + //导入外部航点 + public void ImportDlltoTask(string filename) + { + Vector3[] vc; + + + string extname = Path.GetExtension(filename); + if (extname == ".svg") + { + vc = FlyBase.svgToPos(filename); + } + else if (extname == ".obj") + { + vc = FlyBase.objToPos(filename); + } + else return; + + 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); + newTask.TaskCnName = vname; + int id =0; + foreach (Vector3 item in vc) + { + Tuple observationLatLng = null; + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + OriginLat, + OriginLng, + 90, + (float)item.x / 100); + + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + observationLatLng.Item1, + observationLatLng.Item2, + 0, + (float)item.z / 100); + + var thisSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( + _copterManager.Copters[id++], new LatLng(observationLatLng.Item1 - OriginLat, observationLatLng.Item2 - OriginLng), + (float)item.y / 100, false); + newTask.SingleCopterInfos.Add(thisSingleCopterInfo); + } + Tasks.Add(newTask); + RaiseTaskAdded(lastTask, newTask); + } + + + public void ImportC4DFlytoTask(string txt) + { + string[] lines = txt.Replace("\r\n", "\n").Split('\n'); + + if (lines.Length % (_copterManager.Copters.Count + 1) != 0) + { + Alert.Show("文件内容错误!"); + return; + } + + int taskCount = lines.Length / (_copterManager.Copters.Count + 1); + int startIndex; + int flytime = 10; + string line; + Dictionary PointDic; + for (int i = 0; i < taskCount; i++) + { + startIndex = i * (_copterManager.Copters.Count + 1); + string taskName = lines[startIndex]; + if (taskName != "") + { + //去掉前后的"[]" + string taskName_temp = taskName.Substring(1); + taskName_temp= taskName_temp.Remove(taskName_temp.Length - 1); + //新版用":"分割时间 + string[] words = taskName_temp.Split(':'); + if (words.Count()==2) + { + taskName = words[0]; + flytime = int.Parse(words[1]); + if (flytime == -1) //第一个航点是-1 先设置成0 后面计算时间 + flytime = 0; + + } + } + + PointDic = new Dictionary(); + for (int j = 0; j < _copterManager.Copters.Count; j++) + { + line = lines[startIndex + j + 1]; + string[] parameters = line.Split(' '); + int id = Convert.ToInt32(parameters[0]); + string frame = parameters[1]; + string[] point = new string[3]; + point[0] = parameters[1]; //左右 经度 + point[1] = parameters[2]; //上下 高度 + point[2] = parameters[3]; //前后 纬度 + PointDic.Add(id, point); + } + + var lastTask = Tasks.LastOrDefault(); + var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = true, FlytoTime = flytime, LoiterTime = 0 }; + newTask.TaskCnName = taskName; + for (int k = 0; k < PointDic.Count; k++) + { + string[] point = PointDic[k + 1]; + + //string frame = parameters[1]; + string x = point[0]; //左右 经度 + string y = point[1]; //上下 高度 + string z = point[2]; //前后 纬度 + Tuple observationLatLng = null; + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + OriginLat, + OriginLng, + 90, + Convert.ToSingle(x) / 100); + + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + observationLatLng.Item1, + observationLatLng.Item2, + 0, + Convert.ToSingle(z) / 100); + + var thisSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( + _copterManager.Copters[k], new LatLng(observationLatLng.Item1 - OriginLat, observationLatLng.Item2 - OriginLng), + Convert.ToSingle(y) / 100, false); + newTask.SingleCopterInfos.Add(thisSingleCopterInfo); + + } + Tasks.Add(newTask); + RaiseTaskAdded(lastTask, newTask); + } + // Alert.Show("导入完成!"); + /* + Dictionary PointDic = new Dictionary(); + foreach (string line in lines) + { + string[] parameters = line.Split(' '); + int id = Convert.ToInt32(parameters[0]); + string frame = parameters[1]; + string[] point = new string[3]; + point[0] = parameters[1]; //左右 经度 + point[1] = parameters[2]; //上下 高度 + point[2] = parameters[3]; //前后 纬度 + PointDic.Add(id, point); + } + + + var lastTask = Tasks.LastOrDefault(); + var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = true, FlytoTime = 10, LoiterTime = 10 }; + for (int i = 0; i < PointDic.Count; i++) + { + string[] point = PointDic[i + 1]; + + //string frame = parameters[1]; + string x = point[0]; //左右 经度 + string y = point[1]; //上下 高度 + string z = point[2]; //前后 纬度 + Tuple observationLatLng = null; + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + OriginLat, + OriginLng, + 90, + Convert.ToSingle(x) / 100); + + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + observationLatLng.Item1, + observationLatLng.Item2, + 0, + Convert.ToSingle(z) / 100); + + var thisSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( + _copterManager.Copters[i], new LatLng(observationLatLng.Item1 - OriginLat, observationLatLng.Item2 - OriginLng), + Convert.ToSingle(y)/100, false); + newTask.SingleCopterInfos.Add(thisSingleCopterInfo); + + } + Tasks.Add(newTask); + TaskAdded?.Invoke(this, new FlightTaskAddedEventArgs { LastTask = lastTask, AddedTask = newTask }); + */ + + } + + public void ImportBlenderFlyToTask(string blenderVectors) + { + string[] lineVectors = blenderVectors.Replace("\r\n","\n").Split('\n'); + + var lastTask = Tasks.LastOrDefault(); + float alt = lastTask.SingleCopterInfos[0].TargetAlt; + double lat = lastTask.SingleCopterInfos[0].LatLngOffset.Lat; + double lng = lastTask.SingleCopterInfos[0].LatLngOffset.Lng; + + + foreach (var item in lineVectors) + { + string vector = item.Replace("Vector((", "").Replace("))", ""); + var newTask = new FlightTask(FlightTaskType.FlyTo) { StaggerRoutes = true, FlytoTime = 1, LoiterTime = 0 }; + + string[] vectors = vector.Split(','); + double x = double.Parse(vectors[1]); + double y = double.Parse(vectors[0]); + int x_directionDegrees = x > 0 ? 90 : -90; + int y_directionDegrees = y > 0 ? 0 : 180; + + Tuple observationLatLng = null; + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + lat, + lng, + 90, + (float)x); + + observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + observationLatLng.Item1, + observationLatLng.Item2, + 0, + (float)y); + + + var newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( + _copterManager.Copters[0], new LatLng((double)observationLatLng.Item1, + (double)observationLatLng.Item2), alt, false); + + newTask.SingleCopterInfos.Add(newSingleCopterInfo); + Tasks.Add(newTask); + RaiseTaskAdded(lastTask, newTask); + Message.Show(vector); + } + } + + public void RestoreFlyToTask(bool staggerRoutes, int flytoTime, int loiterTime, string taskName, dynamic singleCopterInfos, bool isMeter) + { + var copters = _copterManager.Copters; + float tagalt = 15; + if (!copters.Any()) return; + AppEx.Current.AppMode = AppMode.ModifyingTask; + var lastTask = Tasks.LastOrDefault(); + var nullableCenter = copters.GetCenter(); + 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; + // TODO: 王海, 20150801, 处理实际飞行器数目与记录中数目不一致的情况。 + for (int i = 0; i < copters.Count; i++) + { + var copter = copters[i]; + FlightTaskSingleCopterInfo newSingleCopterInfo; + if (i < singleCopterInfos.Count) + { + var singleCopterInfoObj = singleCopterInfos[i]; + tagalt = (float)singleCopterInfoObj.targetAlt; + if (isMeter) + newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( + copter, + (double)singleCopterInfoObj.x, + (double)singleCopterInfoObj.y, + (float)singleCopterInfoObj.targetAlt - copter.GroundAlt, + (bool)singleCopterInfoObj.isLandWaypoint); + else + newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask( + copter, + new LatLng((double)singleCopterInfoObj.latOffset, (double)singleCopterInfoObj.lngOffset), + (float)singleCopterInfoObj.targetAlt - copter.GroundAlt, (bool)singleCopterInfoObj.isLandWaypoint); + + var jsonArray = singleCopterInfoObj.ledInfos as Newtonsoft.Json.Linq.JArray; + ObservableCollection ledList = jsonArray.ToObject>(); + foreach(LEDInfo info in ledList) + { + newSingleCopterInfo.AddLEDInfo(info); + } + if (singleCopterInfoObj.isChangeSpeed != null) + { + bool isChangeSpeed = (bool)singleCopterInfoObj.isChangeSpeed; + if (isChangeSpeed) + { + newSingleCopterInfo.IsChangeSpeed = isChangeSpeed; + newSingleCopterInfo.LevelSpeed = (float)singleCopterInfoObj.levelSpeed; + newSingleCopterInfo.UpSpeed = (float)singleCopterInfoObj.upSpeed; + newSingleCopterInfo.DownSpeed = (float)singleCopterInfoObj.downSpeed; + } + } + } + else + { + //实际飞机比保存的任务计划的飞机多,多的飞机设置默认航点 + newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForFlyToTask + (copter, (double)copter.Latitude, (double)copter.Longitude, tagalt); + + } + newTask.SingleCopterInfos.Add(newSingleCopterInfo); + } + Tasks.Add(newTask); + RaiseTaskAdded(lastTask, newTask); + } + + + private void RestoreTakeOffTask(byte takeOffTime, dynamic singleCopterInfos) + { + var copters = _copterManager.Copters; + if (copters == null || !copters.Any()) return; + AppEx.Current.AppMode = AppMode.ModifyingTask; + var lastTask = Tasks.LastOrDefault(); + FlightTask takeOffTask = Tasks[0]; + takeOffTask.TakeOffTime = takeOffTime; + for (int i = 0; i < copters.Count; i++) + { + var singleCopterInfoObj = singleCopterInfos[i]; + takeOffTask.SingleCopterInfos[i].TakeOffWaitTime = (ushort)singleCopterInfoObj.waitTime; + if (singleCopterInfoObj.ledInfos!= null) + { + var jsonArray = singleCopterInfoObj.ledInfos as Newtonsoft.Json.Linq.JArray; + ObservableCollection ledList = jsonArray.ToObject>(); + foreach (LEDInfo info in ledList) + { + takeOffTask.SingleCopterInfos[i].AddLEDInfo(info); + } + } + + //Message.Show(((ushort)singleCopterInfoObj.waitTime).ToString()); + } + } + + private void RestoreLandTask(dynamic singleCopterInfos) + { + var copters = _copterManager.Copters; + if (copters == null || !copters.Any()) return; + AppEx.Current.AppMode = AppMode.ModifyingTask; + var lastTask = Tasks.LastOrDefault(); + + var LandTask = new FlightTask(FlightTaskType.Land); + for (int i = 0; i < copters.Count; i++) + { + var copter = copters[i]; + FlightTaskSingleCopterInfo newSingleCopterInfo; + var singleCopterInfoObj = singleCopterInfos[i]; + newSingleCopterInfo = FlightTaskSingleCopterInfo.CreateForLandTask(copter, (int)singleCopterInfoObj.waitTime); + LandTask.SingleCopterInfos.Add(newSingleCopterInfo); + } + Tasks.Add(LandTask); + RaiseTaskAdded(lastTask, LandTask); + + } + + + + //导出任务 (单位:米) + public IEnumerable ExportTasksToMeter() + { + var tasks = Tasks.Select(task => + { + var type = task.TaskType; + switch (type) + { + case FlightTaskType.TakeOff: + return new { + type = type, + takeoffnumber = 1,// TakeOffNumAttr, + takeoffTime = task.TakeOffTime, + singleCopterInfos = task.SingleCopterInfos.Select(info => + { + return new + { + waitTime = info.TakeOffWaitTime, + ledInfos = info.LEDInfos + }; + }) + }; + case FlightTaskType.FlyTo: + return new + { + type = type, + staggerRoutes = task.StaggerRoutes, + flytoTime = task.FlytoTime, + loiterTime = task.LoiterTime, + taskname = task.TaskCnName, + singleCopterInfos = task.SingleCopterInfos.Select(info => + { + var offset = info.LatLngOffset; + return new + { + x = info.X, + y = info.Y, + targetAlt = info.TargetAlt + info.Copter.GroundAlt, //导出时加上地面摆放高度,导入后若没有摆放高度,模拟就会清楚的看到高度错误 + //showLED = info.FlytoShowLED, + ledInfos = info.LEDInfos, + isLandWaypoint = info.IsLandWaypoint, + isChangeSpeed = info.IsChangeSpeed, + levelSpeed = info.LevelSpeed, + upSpeed = info.UpSpeed, + downSpeed = info.DownSpeed + }; + }) + }; + + + case FlightTaskType.Land: + { + return new + { + type = type, + singleCopterInfos = task.SingleCopterInfos.Select(info => + { + return new + { + waitTime = info.LandWaitTime + }; + }) + + }; + } + default: + throw new NotImplementedException(type + " task export not implemented."); + } + }); + return tasks; + } + + //导出任务 + public IEnumerable ExportTasks() + { + // For reference. + //var tasks = new object[] + //{ + // new + // { + // type = FlightTaskType.TakeOff, + // }, + // new + // { + // type = FlightTaskType.FlyTo, + // staggerRoutes = false, + // singleCopterInfos = new object[] { + // new { + // latOffset = 0.0001, + // lngOffset = 0.0001, + // targetAlt = 10 + // }, + // new { + // latOffset = 0.0003, + // lngOffset = 0.0003, + // targetAlt = 15 + // } + // } + // }, + // new + // { + // type = FlightTaskType.Turn, + // singleCopterInfos = new object[] { + // new { + // latOffset = 0.0001, + // lngOffset = 0.0001, + // targetAlt = 10, + // targetHeading = 90 + // }, + // new { + // latOffset = 0.0001, + // lngOffset = 0.0001, + // targetAlt = 10, + // targetHeading = 270 + // } + // } + // }, + // new + // { + // type = FlightTaskType.Circle, + // singleCopterInfos = new object[] { + // new { + // latOffset = 0.0001, + // lngOffset = 0.0001, + // targetAlt = 10, + // centerDirectionDeg = 90, + // radius = 1000, + // rate = 20, + // turns = 1, + // channel3 = 1500 + // }, + // new { + // latOffset = 0.0003, + // lngOffset = 0.0003, + // targetAlt = 15, + // centerDirectionDeg = 270, + // radius = 1000, + // rate = 20, + // turns = 1, + // channel3 = 1500 + // } + // } + // }, + // new + // { + // type = FlightTaskType.SimpleCircle, + // singleCopterInfos = new object[] { + // new { + // latOffset = 0.0001, + // lngOffset = 0.0001, + // targetAlt = 10, + // rate = 20, + // turns = 1, + // channel3 = 1500 + // }, + // new { + // latOffset = 0.0003, + // lngOffset = 0.0003, + // targetAlt = 15, + // rate = 20, + // turns = 1, + // channel3 = 1500 + // } + // } + // } + //}; + var tasks = Tasks.Select(task => + { + var type = task.TaskType; + switch (type) + { + case FlightTaskType.TakeOff: + return new { + type = type, + takeoffnumber = 1,//TakeOffNumAttr, + takeoffTime = task.TakeOffTime, + singleCopterInfos = task.SingleCopterInfos.Select(info => + { + return new + { + waitTime = info.TakeOffWaitTime, + ledInfos = info.LEDInfos + }; + }) + }; + case FlightTaskType.FlyTo: + return new + { + type = type, + staggerRoutes = task.StaggerRoutes, + flytoTime = task.FlytoTime, + loiterTime = task.LoiterTime, + taskname = task.TaskCnName, + singleCopterInfos = task.SingleCopterInfos.Select(info => + { + var offset = info.LatLngOffset; + return new + { + latOffset = offset.Lat, + lngOffset = offset.Lng, + targetAlt = info.TargetAlt + info.Copter.GroundAlt, //导出时加上地面摆放高度,导入后若没有摆放高度,模拟就会清楚的看到高度错误 + //showLED = info.FlytoShowLED, + ledInfos = info.LEDInfos, + isLandWaypoint = info.IsLandWaypoint, + isChangeSpeed = info.IsChangeSpeed, + levelSpeed = info.LevelSpeed, + upSpeed = info.UpSpeed, + downSpeed = info.DownSpeed + }; + }) + }; + + + case FlightTaskType.Land: + { + return new + { + type = type, + singleCopterInfos = task.SingleCopterInfos.Select(info => + { + return new + { + waitTime = info.LandWaitTime + }; + }) + + }; + } + default: + throw new NotImplementedException(type + " task export not implemented."); + } + }); + return tasks; + } + + + //导入任务,可设置导入哪些步骤 + public void ImportTasksindex(dynamic tasks, int startindex,int endindex, bool isMeter) + { + var copters = _copterManager.Copters; + + if (Tasks.Count == 0) + AddTakeOffTask(copters); + + + int i =1; + foreach (var task in tasks) + { + if ((i >= startindex)&& (i <= endindex)) + { + switch ((FlightTaskType)task.type) + { + case FlightTaskType.TakeOff: + // AddTakeOffTask(copters); // added by ZJF + // 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; + case FlightTaskType.Land: + RestoreLandTask(task.singleCopterInfos); + break; + } + } + i++; + } + } + + + //计算中心点 (三维的) + private Point3D CenterFormMeter(List point1, List point2) + { + Point3D centerPoint = new Point3D(0, 0, 0); + if (point1.Count != point2.Count) return centerPoint; + + double minX = point1[0].X; + double maxX = point1[0].X; + + double minY = point1[0].Y; + double maxY = point1[0].Y; + + + double minZ = point1[0].Z; + double maxZ = point1[0].Z; + + + + int count = point1.Count; + for (int i = 0; i < count; i++) + { + minX = Math.Min(minX, Math.Min(point1[i].X, point2[i].X)); + maxX = Math.Max(maxX, Math.Min(point1[i].X, point2[i].X)); + + minY = Math.Min(minY, Math.Min(point1[i].Y, point2[i].Y)); + maxY = Math.Max(maxY, Math.Max(point1[i].Y, point2[i].Y)); + + minZ = Math.Min(minZ, Math.Min(point1[i].Z, point2[i].Z)); + maxZ = Math.Max(maxZ, Math.Max(point1[i].Z, point2[i].Z)); + + + } + centerPoint.X = (minX + maxX) / 2; + centerPoint.Y = (minY + maxY) / 2; + centerPoint.Z = (minZ + maxZ) / 2; + return centerPoint; + } + + + public double SumFlyLines(List preinfos, List currinfos) + { + double sumdis = 0; + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + //当前任务 + Point3D preLoc = new Point3D(preinfos[i].X, preinfos[i].Y, preinfos[i].TargetAlt); + Point3D curLoc = new Point3D(currinfos[i].X, currinfos[i].Y, currinfos[i].TargetAlt); + //算距离 + sumdis += Point3D.Subtract(curLoc, preLoc).Length; + } + return sumdis; + } + public void SetAllTaskFlytime() + { + //起飞航点0需要单独计算 + //第一个航点1,是调整航点根据地面摆放情况调整,默认2+1秒 + //从2开始自动计算 + + + // Tasks[1].FlytoTime = 2; + // Tasks[1].LoiterTime = 1; + + for (int taskIndex = 0; taskIndex < Tasks.Count; taskIndex++) + SetTaskFlytime(taskIndex); + Message.Show($"任务时间计算执行完成----"); + } + public void CheckAllTaskFlytime() + { + if (_copterManager.FC_VER_NO < 3) + { + Alert.Show("不支持的功能", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); + return; + } + Alert.Show("检测2号航点后的所有飞行时间是否能飞到", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); + + //第一个航点1,是调整航点根据地面摆放情况调整,默认2+1秒 + //从2开始检查 + for (int taskIndex = 2; taskIndex < Tasks.Count; taskIndex++) + CheckTaskFlytime(taskIndex); + Message.Show($"任务检测执行完成----"); + } + + public void SetTaskFlytime_v1(int taskIndex, bool settime = true) + { + double speed = 5.0f; //默认速度 + + if ((taskIndex > 0) && (taskIndex < Tasks.Count) && (Tasks[taskIndex].TaskType == FlightTaskType.FlyTo)) + { + if (_copterManager.Copters.Count() > 0) + { + + //计算之前航点有没改变速度,有就取最后一次速度 + //if (currspeed == -1.0) + { + for (int _taskIndex = taskIndex - 1; _taskIndex > 1; _taskIndex--) + + { + var curWaypoint = Tasks[_taskIndex].SingleCopterInfos.FirstOrDefault(); + if ((curWaypoint.IsChangeSpeed)) + { + speed = curWaypoint.LevelSpeed; + break; + } + } + } + double maxDistance = 0.0f; + string copterName = ""; + foreach (var copter in _copterManager.Copters) + { + var prevWaypoint = Tasks[taskIndex - 1].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); + var curWaypoint = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); + if ((curWaypoint.IsChangeSpeed) && (curWaypoint.LevelSpeed == -1)) + { + Message.Show($"任务{taskIndex + 1}飞机编号:{copter.Id}是自动速度,无法计算时间!"); + return; + } + + //当前航点是否改变速度,有就取修改的速度 + if (curWaypoint.IsChangeSpeed) + { + + speed = curWaypoint.LevelSpeed; + + } + + double distance = GeographyUtils.CalcDistance( + prevWaypoint.TargetLat, prevWaypoint.TargetLng, prevWaypoint.TargetAlt, + curWaypoint.TargetLat, curWaypoint.TargetLng, curWaypoint.TargetAlt); + if (distance > maxDistance) + { + maxDistance = distance; + copterName = copter.Name; + // speed = curWaypoint.LevelSpeed; + } + } + + double time = CalculateFlyIime(maxDistance, speed); + Message.Show($"任务{taskIndex + 1}最大航点间距 = {Math.Round(maxDistance, 2)}米, 水平速度={Math.Round(speed, 2)}, 飞行时间 = {Math.Round(time, 2)}秒, 飞机编号:{copterName}"); + if (settime) + Tasks[taskIndex].FlytoTime = (int)Math.Round(time, 2); + } + } + + return; + } + + + public int getflytype(int taskIndex) + { + bool addspeedmk = false; //是否要加速 + 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; //加减速 + else if (addspeedmk) flytype = 2; //单加速 + else if (decspeedmk) flytype = 3; //单减速 + return flytype; + } + public void SetTaskFlytime_v2(int taskIndex, + float acc_xy, float acc_z, + float defvel_xy, float defvel_up, float defvel_down, + bool settime = true) + { + if (_copterManager.Copters.Count() == 0) return; + if ((taskIndex < Tasks.Count)) + { + string copterName = ""; + double maxDistance_xy = 0.0f; + double maxDistance_z = 0.0f; + double maxDistance_up = 0.0f; + double maxDistance_down = 0.0f; + string copterName_xy = ""; + string copterName_up = ""; + string copterName_down = ""; + int flytimetype = 1; //默认同时计算加减速 + + if (Tasks[taskIndex].TaskType == FlightTaskType.TakeOff) + { + double tasktime = 0; + double waittime = 0; + double upflytime = 0; + foreach (var copter in _copterManager.Copters) + { + var nextWaypoint = Tasks[taskIndex + 1].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); + 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 copter_tasktime = curWaypoint.TakeOffWaitTime + time_up; + + if (copter_tasktime > tasktime) + { + tasktime = copter_tasktime; + maxDistance_up = copter_maxDistance_up; + copterName= copter.Name; + waittime = curWaypoint.TakeOffWaitTime; + upflytime = time_up; + } + } + Message.Show($"起飞任务{taskIndex + 1}起飞高度:{Math.Round(maxDistance_up, 2)}米 " + + $"最长耗时:{Math.Round(tasktime, 2)}秒({Math.Round(upflytime, 2)},{Math.Round(waittime, 2)}),编号:{copterName}" + ); + if (settime) + { + if (tasktime > 255) + { + Alert.Show($"任务{taskIndex + 1}时间太长,目前{tasktime}秒不能超255秒,请调整高度或速度", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); + return; + } else + Tasks[taskIndex].TakeOffTime = (byte)(int)Math.Ceiling(tasktime); + } + } + else if (Tasks[taskIndex].TaskType == FlightTaskType.FlyTo) + { + flytimetype = getflytype(taskIndex); + foreach (var copter in _copterManager.Copters) + { + var prevWaypoint = Tasks[taskIndex - 1].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); + var curWaypoint = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); + + double distance_xy = GeographyUtils.CalcDistance( + prevWaypoint.TargetLat, prevWaypoint.TargetLng, 0, + curWaypoint.TargetLat, curWaypoint.TargetLng, 0); + double distance_z = curWaypoint.TargetAlt - prevWaypoint.TargetAlt; + + + if (distance_xy > maxDistance_xy) + { + maxDistance_xy = distance_xy; + copterName_xy = copter.Name; + } + + if (Math.Abs(distance_z) > maxDistance_z) + { + maxDistance_z = Math.Abs(distance_z); + } + + + if (distance_z > 0) + { + if (distance_z > maxDistance_up) + { + maxDistance_up = distance_z; + copterName_up = copter.Name; + } + } + else + { + if (-distance_z > maxDistance_down) + { + maxDistance_down = -distance_z; + copterName_down = copter.Name; + } + } + }//循环结束 + + double time_xy = getMinfligthtime((float)maxDistance_xy, acc_xy, defvel_xy, flytimetype); + double time_up = getMinfligthtime((float)maxDistance_up, acc_z, defvel_up, flytimetype); + double time_down = getMinfligthtime((float)maxDistance_down, acc_z, defvel_down, flytimetype); + double tasktime = time_xy; + copterName = copterName_xy; + string divstr = "水平"; + if (time_up > tasktime) + { + tasktime = time_up; + copterName = copterName_up; + divstr = "上升"; + } + + if (time_down > tasktime) + { + tasktime = time_down; + copterName = copterName_down; + divstr = "下降"; + } + tasktime = Math.Max(time_xy, time_up); + tasktime = Math.Max(tasktime, time_down); + Message.Show($"任务{taskIndex + 1}距离:水平{Math.Round(maxDistance_xy, 2)}米;垂直:{Math.Round(maxDistance_z, 2)}米, " + + $"最长耗时:{Math.Round(tasktime, 2)}秒,用于{divstr}飞行,编号:{copterName}" + ); + if (settime) + Tasks[taskIndex].FlytoTime = (int)(int)Math.Ceiling(tasktime); + } + } + + return; + + } + + public void SetTaskFlytime(int taskIndex, bool settime = true) + { + if (taskIndex== 1) + { + Message.Show($"2号任务是调整航点,根据现场飞机摆放离设计位置偏差来调整"); + return; + } + + if (_copterManager.FC_VER_NO >= 3) + { + float _acc_xy = FC_acc_xy; + float _acc_z = FC_acc_z; + float _defvel_xy = FC_defvel_xy; + float _defvel_up = FC_defvel_up; + float _defvel_down = FC_defvel_down; + if (Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().IsChangeSpeed) + { + _defvel_xy = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().LevelSpeed; + _defvel_up= Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().UpSpeed; + _defvel_down = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault().DownSpeed; + } + + SetTaskFlytime_v2(taskIndex, _acc_xy, _acc_z, _defvel_xy, _defvel_up, _defvel_down, settime); + } + else SetTaskFlytime_v1(taskIndex, settime); + } + //新版本才有的功能,老版本直接提示推出了 + public void CheckTaskFlytime(int taskIndex) + { + if ((taskIndex > 0) && (taskIndex < Tasks.Count) && (Tasks[taskIndex].TaskType == FlightTaskType.FlyTo)) + { + if (_copterManager.Copters.Count() > 0) + { + string copterName = ""; + double maxDistance_xy = 0.0f; + double maxDistance_z = 0.0f; + double maxDistance_up = 0.0f; + double maxDistance_down = 0.0f; + string copterName_xy = ""; + string copterName_up = ""; + string copterName_down = ""; + int flytimetype = getflytype(taskIndex); + foreach (var copter in _copterManager.Copters) + { + var prevWaypoint = Tasks[taskIndex - 1].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); + var curWaypoint = Tasks[taskIndex].SingleCopterInfos.FirstOrDefault(c => c.Copter == copter); + + double distance_xy = GeographyUtils.CalcDistance( + prevWaypoint.TargetLat, prevWaypoint.TargetLng, 0, + curWaypoint.TargetLat, curWaypoint.TargetLng, 0); + double distance_z = curWaypoint.TargetAlt - prevWaypoint.TargetAlt; + + + if (distance_xy > maxDistance_xy) + { + maxDistance_xy = distance_xy; + copterName_xy = copter.Name; + } + + if (Math.Abs(distance_z) > maxDistance_z) + { + maxDistance_z = Math.Abs(distance_z); + } + + + if (distance_z > 0) + { + if (distance_z > maxDistance_up) + { + maxDistance_up = distance_z; + copterName_up = copter.Name; + } + } + else + { + if (-distance_z > maxDistance_down) + { + maxDistance_down = -distance_z; + copterName_down = copter.Name; + } + } + }//循环结束 + + 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; + copterName = copterName_xy; + string divstr = "水平"; + if (time_up > tasktime) + { + tasktime = time_up; + copterName = copterName_up; + divstr = "上升"; + } + + if (time_down > tasktime) + { + tasktime = time_down; + copterName = copterName_down; + divstr = "下降"; + } + tasktime = Math.Max(time_xy, time_up); + tasktime = Math.Max(tasktime, time_down); + if (Tasks[taskIndex].FlytoTime < tasktime) + { + + Message.Show($"任务{taskIndex + 1}距离:水平{Math.Round(maxDistance_xy, 2)}米;垂直:{Math.Round(maxDistance_z, 2)}米, " + + $"目前飞行时间:{Tasks[taskIndex].FlytoTime}秒,最少需要:{Math.Round(tasktime, 2)}秒,用于{divstr}飞行,编号:{copterName}" + ); + if (Alert.Show($"任务{taskIndex + 1}时间过短,目前{Tasks[taskIndex].FlytoTime}秒至少{Math.Round(tasktime, 2)}秒才能全部飞到目标,需要更改吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning) + == MessageBoxResult.OK) + { + Message.Show($"任务{taskIndex + 1}飞行时间{Tasks[taskIndex].FlytoTime}秒更改为{Math.Ceiling(tasktime)}秒"); + Tasks[taskIndex].FlytoTime = (int)Math.Ceiling(tasktime); //上取整 + } + + + } + } + + + } + + return; + + } + + float fabsf(float vvalue) + { + return Math.Abs(vvalue); + + } + float sqrt(float vvalue) + { + return (float)Math.Sqrt(vvalue); + + } + + + //单算加速或减速和匀速部分的最小飞行时间 + float getMinfligthtime_acc(float Distance, float fc_acc, float fc_maxspeed) + { + float fDis = fabsf(Distance); // 总距离 + float facc = fabsf(fc_acc); // 减速度 + + // 物体开始时即以最大速度运动,不考虑加速过程 + float vel = fc_maxspeed; + + // 计算减速所需的时间和距离 + // 减速时间 (从最大速度减速到0) + float dectime = vel / facc; + // 减速阶段覆盖的距离 + float decdis = (vel * dectime) - (0.5f * facc * dectime * dectime); + + // 判断是否有足够的距离进行减速 + if (decdis >= fDis) + { + // 如果减速所需距离已经超过或等于总距离,调整最大速度 + // 使用公式 v^2 = u^2 + 2as 解出 v + vel = (float)Math.Sqrt(2 * facc * fDis); + // 重新计算减速时间 + dectime = vel / facc; + } + + // 计算匀速阶段时间 + float unftime = 0.0f; + if (decdis < fDis) + { + // 如果有剩余距离进行匀速运动 + unftime = (fDis - decdis) / vel; + } + + // 总飞行时间 = 匀速阶段时间 + 减速阶段时间 + return unftime + dectime; + } + float getMinfligthtime_acc_dec(float Distance, float fc_acc, float fc_maxspeed) + { + if ((Distance == 0) || (fc_acc == 0) || (fc_maxspeed == 0)) return 0; + float fDis = fabsf(Distance); + float facc = fabsf(fc_acc); + + float realflytime = 0.0f; + //计算一半的距离 + float hafdis = (fDis / 2); + //计算最大速度 + float vel = (float)sqrt(2 * facc * hafdis); + //如果速度超过最大速度 + if (vel > fc_maxspeed) + //使用最大速度 + vel = fc_maxspeed; + //加速时间 + float acctim = vel / facc; + //加速距离 + float accdis = vel * vel / (2 * facc); + //匀速段时间 + float vtime = (hafdis - accdis) / vel; + //到一半的时间 + float haftime = acctim + vtime; + realflytime = haftime * 2; + return realflytime; + } + + float getMinfligthtime(float Distance, float fc_acc, float fc_maxspeed,int timetype) + { + switch (timetype) + { + case 0://匀速 + return Distance / fc_maxspeed; + case 1: //同时计算加减速 + return getMinfligthtime_acc_dec(Distance, fc_acc, fc_maxspeed); + case 2: //计算加速 + case 3://计算减速 + return getMinfligthtime_acc(Distance, fc_acc, fc_maxspeed); + default: + return 0; + } + } + + public static double CalculateFlyIime(double s, double v) + { + double t; + double a = 1; //加速度1米每秒 + double at = v / a; + double a_s = 0.5f * a * at * at; + if (a_s > (s / 2)) //还没到特定速度就到了中点了 + { + t = (float)System.Math.Sqrt(s / a) * 2; + } + else + { + t = (s - a_s * 2) / v + at * 2; + } + + return t; + } //计算优化线路,采用米计算 + + /// + /// 自动生成航线2D和3D都用这个--------目前使用---------------- + /// + /// 3D计算 + /// 是否改变线路的结束点顺序--返回起飞点航线不能交换 + public void OptimizeRouteMeter(bool Is3d=false,bool Ischange=true) + { + Dictionary curTaskPoint = new Dictionary(); + Dictionary prevTaskPoint = new Dictionary(); + var stopWatch = new Stopwatch(); + stopWatch.Start(); + //获取当前航点与前一航点所有经纬高 + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + //当前任务 + var curinfo = SelectedTask.SingleCopterInfos[i]; + Point3D curLoc = new Point3D(curinfo.X, curinfo.Y, curinfo.TargetAlt); + curTaskPoint.Add(i, curLoc); + + //前一任务 + var prevInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i]; + Point3D prevLoc = new Point3D(prevInfo.X, prevInfo.Y, prevInfo.TargetAlt); + prevTaskPoint.Add(i, prevLoc); + } + //Dictionary RouteRes = Util.OptimizeRoute.GenRoute(curTaskPoint, prevTaskPoint); + if (Is3d) + { + ArrayList resarray = Util.OptimizeRoute.Gen3DRoute(curTaskPoint.Values.ToArray(), prevTaskPoint.Values.ToArray()); + Vector3[] RouteRes; + //最终 + RouteRes = (Vector3[])resarray[0]; + + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = RouteRes[i].x; + SelectedTask.SingleCopterInfos[i].Y = RouteRes[i].y; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)RouteRes[i].z; + } + + SetTaskFlytime(SelectedTaskIndex); + + + } + else + { + ArrayList resarray = Util.OptimizeRoute.Gen2DRoute(curTaskPoint.Values.ToArray(), prevTaskPoint.Values.ToArray(), Ischange); + Vector3[] RouteRes; + //有错层,需要插入2个错层任务 + if (resarray.Count == 3) + { + //选中前一个任务,插入错层 + SelectTask(SelectedTaskIndex - 1); + AddTask(); + + //第一个错层 + RouteRes = (Vector3[])resarray[0]; + + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = RouteRes[i].x; + SelectedTask.SingleCopterInfos[i].Y = RouteRes[i].y; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)RouteRes[i].z; + } + SetTaskFlytime(SelectedTaskIndex); + + + //第二个错层 + AddTask(); + + RouteRes = (Vector3[])resarray[1]; + + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = RouteRes[i].x; + SelectedTask.SingleCopterInfos[i].Y = RouteRes[i].y; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)RouteRes[i].z; + } + + SetTaskFlytime(SelectedTaskIndex); + + + SelectTask(SelectedTaskIndex + 1); + + //最终 + RouteRes = (Vector3[])resarray[2]; + + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = RouteRes[i].x; + SelectedTask.SingleCopterInfos[i].Y = RouteRes[i].y; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)RouteRes[i].z; + } + SetTaskFlytime(SelectedTaskIndex); + + + } + else + { + //最终 + RouteRes = (Vector3[])resarray[0]; + + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].X = RouteRes[i].x; + SelectedTask.SingleCopterInfos[i].Y = RouteRes[i].y; + SelectedTask.SingleCopterInfos[i].TargetAlt = (float)RouteRes[i].z; + } + SetTaskFlytime(SelectedTaskIndex); + + } + } + stopWatch.Stop(); + + double sumlength = SumFlyLines(Tasks[SelectedTaskIndex - 1].SingleCopterInfos, SelectedTask.SingleCopterInfos); + + Message.Show($"计算用时:{stopWatch.Elapsed.TotalMilliseconds}ms,总飞行距离{sumlength}米"); + + + return; + } + + + + + //计算优化线路,采用经纬度计算 + public void OptimizeRouteNew() + { + Dictionary curTaskPoint = new Dictionary(); + Dictionary prevTaskPoint = new Dictionary(); + + var stopWatch = new Stopwatch(); + stopWatch.Start(); + //获取当前航点与前一航点所有经纬高 + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + //当前任务 + var curinfo = SelectedTask.SingleCopterInfos[i]; + PLLocation curLoc = new PLLocation(curinfo.TargetLat, curinfo.TargetLng, curinfo.TargetAlt); + curTaskPoint.Add(i, curLoc); + + //前一任务 + var prevInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i]; + PLLocation prevLoc = new PLLocation(prevInfo.TargetLat, prevInfo.TargetLng, prevInfo.TargetAlt); + prevTaskPoint.Add(i, prevLoc); + } + + + // int sss = Plane.AutoLine.CalAutoLine(curTaskPoint, prevTaskPoint); + + // Message.Show($"中心点:{sss}"); + + double farDistance; + double nearDistance; + int index; + + Dictionary recordLatLng = new Dictionary(); + while (curTaskPoint.Count > 0) + { + farDistance = double.MinValue; + PLLocation centerLatLng = CenterLatLng(curTaskPoint.Values.ToList(), prevTaskPoint.Values.ToList()); + index = 0; + //计算两个列表距离中心最远距离 + // Message.Show($"有{curTaskPoint.Count}个点,当前中心点:{centerLatLng.Longitude},{centerLatLng.Latitude},{centerLatLng.Altitude}"); + double distance1; + bool farIsCurTaskPoint = true; + + foreach (var item in curTaskPoint) + { + distance1 =Math.Round(GeographyUtils.CalcDistance(centerLatLng,item.Value),4); + if (distance1 > farDistance) + { + index = item.Key; + farDistance = distance1; + farIsCurTaskPoint = true; + // Message.Show($"调整距离{farDistance}是{farIsCurTaskPoint}的{index}"); + + } + } + + foreach (var item in prevTaskPoint) + { + distance1 = Math.Round(GeographyUtils.CalcDistance(centerLatLng,item.Value),4); + if (distance1 > farDistance) + { + index = item.Key; + farDistance = distance1; + farIsCurTaskPoint = false; + // Message.Show($"调整距离{farDistance}是{farIsCurTaskPoint}的{index}"); + + } + } + // Message.Show($"最远{farDistance}是{farIsCurTaskPoint}的{index}"); + + + + double tempDistance1; + nearDistance = double.MaxValue; + int nearIndex = 0; + if (farIsCurTaskPoint) + { + //最远的航点在当前任务 + foreach (var item in prevTaskPoint) + { + tempDistance1 = Math.Round(GeographyUtils.CalcDistance(curTaskPoint[index],item.Value),4); + if (tempDistance1 < nearDistance) + { + nearDistance = tempDistance1; + nearIndex = item.Key; + } + } + //最远的航点在当前任务 + // Message.Show($"最远是当前任务{index}距离它最近的前一任务点:ind={nearIndex},记录前一任务序号和当前任务位置"); + + recordLatLng.Add(nearIndex, curTaskPoint[index]); + curTaskPoint.Remove(index); + prevTaskPoint.Remove(nearIndex); + + } + else + { + //最远的航点在前一任务 + double prevLat = prevTaskPoint[index].Latitude; + double prevLng = prevTaskPoint[index].Longitude; + float prevAlt = prevTaskPoint[index].Altitude; + //最远的航点在当前任务 + //Message.Show($"最远点在前一任务:ind={index},距离{farDistance}"); + foreach (var item in curTaskPoint) + { + tempDistance1 = Math.Round(GeographyUtils.CalcDistance(prevTaskPoint[index],item.Value),4); + if (tempDistance1 < nearDistance) + { + nearDistance = tempDistance1; + nearIndex = item.Key; + } + } + // Message.Show($"最远是前一任务{index}距离它最近的当前任务点:ind={nearIndex},记录前一任务序号和当前任务位置"); + recordLatLng.Add(index, curTaskPoint[nearIndex]); + curTaskPoint.Remove(nearIndex); + prevTaskPoint.Remove(index); + } + + + } + + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].TargetLat = recordLatLng[i].Latitude; + SelectedTask.SingleCopterInfos[i].TargetLng = recordLatLng[i].Longitude ; + SelectedTask.SingleCopterInfos[i].TargetAlt = recordLatLng[i].Altitude; + } + stopWatch.Stop(); + double sumlength = SumFlyLines(Tasks[SelectedTaskIndex - 1].SingleCopterInfos, SelectedTask.SingleCopterInfos); + + + + + double Dist; + int crosscount = 0; + for (int i = 0; i < _copterManager.Copters.Count; i++) + + { + for (int j = i + 1; j < _copterManager.Copters.Count; j++) + { + + + Dist = Util.OptimizeRoute.SqureDistanceSegmentToSegment( + new Point3D(Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i].X, + Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i].Y, + Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i].TargetAlt), + + new Point3D(Tasks[SelectedTaskIndex].SingleCopterInfos[i].X, + Tasks[SelectedTaskIndex].SingleCopterInfos[i].Y, + Tasks[SelectedTaskIndex].SingleCopterInfos[i].TargetAlt), + + new Point3D(Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].X, + Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].Y, + Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j].TargetAlt), + + new Point3D(Tasks[SelectedTaskIndex].SingleCopterInfos[j].X, + Tasks[SelectedTaskIndex].SingleCopterInfos[j].Y, + Tasks[SelectedTaskIndex].SingleCopterInfos[j].TargetAlt) + ); + //交叉 + if (Dist < 0.01) + { + crosscount++; + // Message.Show($"飞机{i}和飞机{j}有交叉,距离{Dist}"); + + + } + } + + + } + + + + + + + + + + + + + + + + + + + + Message.Show($"经纬方式计算用时:{stopWatch.Elapsed.TotalMilliseconds}ms,总飞行距离{sumlength}米,有{crosscount}个交叉"); + + } + + //计算中心点 (三维的) + private PLLocation CenterLatLng(List point1, List point2) + { + PLLocation centerLatLng = new PLLocation(0,0,0); + if (point1.Count != point2.Count) return centerLatLng; + + double minLat = point1[0].Latitude; + double maxLat = point1[0].Latitude; + + double minLng = point1[0].Longitude; + double maxLng = point1[0].Longitude; + + + double minAlt = point1[0].Altitude; + double maxAlt = point1[0].Altitude; + + + + int count = point1.Count; + for (int i = 0; i < count; i++) + { + minLat = Math.Min(minLat, Math.Min(point1[i].Latitude, point2[i].Latitude)); + maxLat = Math.Max(maxLat, Math.Min(point1[i].Latitude, point2[i].Latitude)); + + minLng = Math.Min(minLng, Math.Min(point1[i].Longitude, point2[i].Longitude)); + maxLng = Math.Max(maxLng, Math.Max(point1[i].Longitude, point2[i].Longitude)); + + minAlt = Math.Min(minAlt, Math.Min(point1[i].Altitude, point2[i].Altitude)); + maxAlt = Math.Max(maxAlt, Math.Max(point1[i].Altitude, point2[i].Altitude)); + + + } + centerLatLng.Latitude = (minLat + maxLat) / 2; + centerLatLng.Longitude = (minLng + maxLng) / 2; + centerLatLng.Altitude =(float)(minAlt + maxAlt) / 2; + return centerLatLng; + } + + public void OptimizeRoute2() + { + double minLat = SelectedTask.SingleCopterInfos[0].TargetLat; + double maxLat = SelectedTask.SingleCopterInfos[0].TargetLat; + double minLng = SelectedTask.SingleCopterInfos[0].TargetLng; + double maxLng = SelectedTask.SingleCopterInfos[0].TargetLng; + + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + var curinfo = SelectedTask.SingleCopterInfos[i]; + //recordLatLng.Add(i, new LatLng(curinfo.TargetLat, curinfo.TargetLng)); + var lastInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i]; + minLat = Math.Min(minLat, Math.Min(curinfo.TargetLat, lastInfo.TargetLat)); + maxLat = Math.Max(maxLat, Math.Max(curinfo.TargetLat, lastInfo.TargetLat)); + + minLng = Math.Min(minLng, Math.Min(curinfo.TargetLng, lastInfo.TargetLng)); + maxLng = Math.Max(maxLng, Math.Max(curinfo.TargetLng, lastInfo.TargetLng)); + } + double CenterLat = (maxLat + minLat) / 2; + double CenterLng = (maxLng + minLng) / 2; + + Message.Show($"中心点:{CenterLat} {CenterLng}"); + + Dictionary distanceDic = new Dictionary(); + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + var curinfo = SelectedTask.SingleCopterInfos[i]; + var lastInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[i]; + + + double distance1 = GeographyUtils.CalcDistance(CenterLat, CenterLng, 1, + curinfo.TargetLat, curinfo.TargetLng, 1); + //int[] nums = new int[] { SelectedTaskIndex, i}; + int nums = SelectedTaskIndex << 16 ^ i; + distanceDic.Add(nums, distance1); + double distance2 = GeographyUtils.CalcDistance(CenterLat, CenterLng, 1, + lastInfo.TargetLat, lastInfo.TargetLng, 1); + nums = (SelectedTaskIndex - 1) << 16 ^ i; + distanceDic.Add(nums, distance2); + } + distanceDic = distanceDic.OrderByDescending(o => o.Value).ToDictionary(p => p.Key, o => o.Value); + + + Dictionary recordLatLng = new Dictionary(); + while (distanceDic.Count > 0) + { + KeyValuePair kv = distanceDic.First(); + int taskIndex = kv.Key >> 16; + int copterID = kv.Key & 0xffff; + var curInfo = Tasks[taskIndex].SingleCopterInfos[copterID]; + if (taskIndex == SelectedTaskIndex) + { + double mindistance = double.MaxValue; + int index = 0; + for (int i = 0; i < Tasks[taskIndex - 1].SingleCopterInfos.Count; i++) + { + if (distanceDic.ContainsKey((taskIndex - 1) << 16 ^ i)) + { + var destInfo = Tasks[taskIndex - 1].SingleCopterInfos[i]; + double distance = GeographyUtils.CalcDistance(curInfo.TargetLat, curInfo.TargetLng, 1, + destInfo.TargetLat, destInfo.TargetLng, 1); + if (distance < mindistance) + { + mindistance = distance; + index = i; + } + } + } + recordLatLng.Add(index, + new LatLng(SelectedTask.SingleCopterInfos[copterID].TargetLat, + SelectedTask.SingleCopterInfos[copterID].TargetLng)); + + Message.Show($"航点{taskIndex} ID{copterID + 1} --航点{taskIndex - 1} id{index + 1}"); + distanceDic.Remove(kv.Key); + distanceDic.Remove(( taskIndex - 1) << 16 ^ index ); + } + else + { + double mindistance = double.MaxValue; + int index = 0; + for (int i = 0; i < Tasks[taskIndex + 1].SingleCopterInfos.Count; i++) + { + if (distanceDic.ContainsKey((taskIndex + 1) << 16 ^ i)) + { + var destInfo = Tasks[taskIndex + 1].SingleCopterInfos[i]; + double distance = GeographyUtils.CalcDistance(curInfo.TargetLat, curInfo.TargetLng, 1, + destInfo.TargetLat, destInfo.TargetLng, 1); + if (distance < mindistance && distanceDic.ContainsKey((SelectedTaskIndex) << 16 ^ i)) + { + mindistance = distance; + index = i; + } + } + } + recordLatLng.Add(copterID, + new LatLng(SelectedTask.SingleCopterInfos[index].TargetLat, + SelectedTask.SingleCopterInfos[index].TargetLng)); + + Message.Show($"航点{taskIndex} ID{copterID + 1} --航点{taskIndex + 1} id{index + 1}"); + distanceDic.Remove(kv.Key); + distanceDic.Remove(( taskIndex + 1) << 16 ^ index ); + } + + } + + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + SelectedTask.SingleCopterInfos[i].TargetLat = recordLatLng[i].Lat; + SelectedTask.SingleCopterInfos[i].TargetLng = recordLatLng[i].Lng; + } + + } + public void OptimizeRoute() + { + Dictionary distanceDic = new Dictionary(); + Dictionary recordLatLng = new Dictionary(); + for (int i = 0; i < SelectedTask.SingleCopterInfos.Count; i++) + { + var curinfo = SelectedTask.SingleCopterInfos[i]; + recordLatLng.Add(i, new LatLng(curinfo.TargetLat, curinfo.TargetLng)); + for (int j = 0; j < Tasks[SelectedTaskIndex - 1].SingleCopterInfos.Count; j++) + { + var lastInfo = Tasks[SelectedTaskIndex - 1].SingleCopterInfos[j]; + + double distance = GeographyUtils.CalcDistance(curinfo.TargetLat, curinfo.TargetLng, curinfo.TargetLng, + lastInfo.TargetLat, lastInfo.TargetLng, lastInfo.TargetLng); + int[] nums = new int[] {i,j}; + distanceDic.Add(nums, distance); + } + } + distanceDic = distanceDic.OrderBy(o=>o.Value).ToDictionary(p=>p.Key,o=>o.Value); + List movedCopters = new List(); + List usedPoints = new List(); + foreach (KeyValuePair kv in distanceDic) + { + int moveCopterNum = kv.Key[1]; + int destNum = kv.Key[0]; + if (movedCopters.Contains(moveCopterNum) || usedPoints.Contains(destNum)) + continue; + SelectedTask.SingleCopterInfos[moveCopterNum].TargetLat = recordLatLng[destNum].Lat; + SelectedTask.SingleCopterInfos[moveCopterNum].TargetLng = recordLatLng[destNum].Lng; + movedCopters.Add(moveCopterNum); + usedPoints.Add(destNum); + } + } + + public void ImportWaypoint(string tasksText) + { + dynamic jsonfile = JsonConvert.DeserializeObject(tasksText); + dynamic points = jsonfile.points; + for (int i = 0; i < SelectedTask.SingleCopterInfos.Count; i++) + { + MapManager _mapManager = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance(); + + var pointjson= points[i]; + System.Windows.Point point = new System.Windows.Point((int)pointjson.x, (int)pointjson.y); + var loc = _mapManager.MapView.gmap.FromLocalToLatLng((int)point.X , (int)point.Y); + SelectedTask.SingleCopterInfos[i].TargetLat = loc.Lat; + SelectedTask.SingleCopterInfos[i].TargetLng = loc.Lng; + } + } + + + + // 导入任务 + public void ImportTasks(dynamic tasks, bool isMeter) + { + var copters = _copterManager.Copters; + + if (Tasks.Count == 0) + AddTakeOffTask(copters); + + foreach (var task in tasks) + { + switch ((FlightTaskType)task.type) + { + case FlightTaskType.TakeOff: + // AddTakeOffTask(copters); // added by ZJF + // 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; + + case FlightTaskType.Land: + RestoreLandTask(task.singleCopterInfos); + break; + } + } + } + +// private void ImportCoptersLocate(dynamic coptersLocate) +// { +// +// } + + private void ImportGroupsInfo(dynamic coptersLocate) + { + + } + + public void SelectTask(int taskIndex) + { + if (taskIndex == -1) return; + this.SelectedTaskIndex = taskIndex; + this.SelectedTask = Tasks[taskIndex]; + + } + + /** + * 在悬停任务时,右键waypoint为取消选中 + */ + public void RightSelect(int taskIndex, ICopter copter) + { + this.SelectedTaskIndex = taskIndex; + this.SelectedTask = Tasks[taskIndex]; + + } + + private int Name2Index(string name) // 获取指定copter名字对应的序号 + { + int index = -1; + for (int i = 0; i < SelectedTask.SingleCopterInfos.Count; i++) + { + if (name.Equals(SelectedTask.SingleCopterInfos[i].Copter.Name)) + { + return i; + } + } + return index; + } + + private string DeleteSelectedName( string nameArray, string name ) // 删除字符串中的指定项 + { + string copterStr = nameArray; + if (copterStr.Equals("")) + return ""; + string[] copterNameArray = copterStr.Split(','); + copterNameArray = copterNameArray.Where(str => !str.Equals(name)).ToArray(); + + copterStr = ""; + for (int i = 0; i < copterNameArray.Length; i++) + { + copterStr = copterStr + copterNameArray[i]; + if (i < (copterNameArray.Length - 1)) + { + copterStr = copterStr + ","; + } + } + return copterStr; + } + + //左键选中任务 + public void Select(FlightTask flightTask) + { + this.SelectedTaskIndex = Tasks.IndexOf(flightTask); + this.SelectedTask = flightTask; + + + + + } + + // 右键选中任务 + public void RightSelect(FlightTask flightTask) + { + int RightSelectedTaskIndexTmp = Tasks.IndexOf(flightTask); + if (this.RightSelectedTaskIndex == RightSelectedTaskIndexTmp) + { + this.RightSelectedTaskIndex = -RightSelectedTaskIndexTmp; + } + else + { + this.RightSelectedTaskIndex = RightSelectedTaskIndexTmp; + } + } + + #region Run and pause. + + private bool? _IsPaused; + public bool? IsPaused + { + get { return _IsPaused; } + private set { + if (Set(nameof(IsPaused), ref _IsPaused, value)) + { + if (_IsPaused??false) + { + MessageText = "任务暂停!"; + + }else + { + MessageText = "任务运行中"; + } + } + + + } + } + + TimeSpan timeSpan; + DateTime taskStartTime; + public async Task RunTaskAsync() + { + if (Tasks.Count == 0) return; + + //检查有没有真实飞机--真实飞机不能模拟,因为位置来自物理飞机--只能全部是模拟飞机才行 + foreach (var copter in _copterManager.Copters) + { + if (!(copter is IFakeCopter)) + { + Alert.Show($"模拟任务需要全部是模拟飞机,编号:{copter.Id } 不是模拟飞机,请检查"); + return ; + }else + { + //设置模拟飞机的飞行速度加速度等参数,用于计算位置 + copter.maxspeed_down = FC_maxvel_down; + copter.maxspeed_up = FC_maxvel_up; + copter.maxspeed_xy = FC_maxvel_xy; + copter.acc_z =FC_acc_z; + copter.acc_xy = FC_acc_xy; + } + + } + + + + if (CurrentRunningTaskIndex == 0) + { + taskStartTime = DateTime.Now; + Message.Show($"{DateTime.Now.ToString("HH:mm:ss")}:任务开始"); + } + + /* + //设置模拟飞行更新间隔,都是I7配置下 + int update_int = 50; //300以内50流畅 + if ((_copterManager.Copters.Count() > 300) && ((_copterManager.Copters.Count() <= 500))) + update_int = 100; //300-500, 100才能模拟有些跳动 + if ((_copterManager.Copters.Count() > 500) ) + update_int = 150; //极限了 500-1000可以用 + foreach (var copter in _copterManager.Copters) + copter.sim_update_int = update_int; + */ + + + await RunAsync(); + if ((IsPaused ?? false) == false) + { + timeSpan = DateTime.Now - taskStartTime; + Message.Show($"{DateTime.Now.ToString("HH:mm:ss")}:任务结束"); + Message.Show($"总时长 = {timeSpan.Minutes}分{timeSpan.Seconds}秒"); + + } + } + + public async Task RunAsync() + { + IsPaused = false; + for (int i = CurrentRunningTaskIndex; i < Tasks.Count; i++) + { + var task = Tasks[i]; + //task.Status目前只用于任务条下面状态显示不同颜色 + task.Status = FlightTaskStatus.Stop; + } + AppEx.Current.AppMode = AppMode.RunningTasks; + StartAvoidingCrash(); //开始碰撞检测 + TaskState = TasksStatus.Running; + for (int i = CurrentRunningTaskIndex; i < Tasks.Count; i++) + { + var task = Tasks[i]; + //task.Status目前只用于任务条下面状态显示不同颜色 + task.Status = FlightTaskStatus.Running; + CurrentRunningTask = task; + CurrentRunningTaskIndex = i; + + //////////////////显示提示信息 + int starttime = 0; + for (int j = 0; j < task.TaskIndex; j++) + starttime += GetTaskTime(j); + TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(starttime)); + Message.Show($"{ts}:任务{i+1} {task.TaskCnName } 开始执行,需{ GetTaskTime(task.TaskIndex)}秒"); + ///////////////////////// + + + await task.RunAsync().ConfigureAwait(false); + // 1. 被暂停时,中断 RunAsync。继续运行时将把此时运行了一半的 CurrentRunningTask 重新运行一遍。 + if (IsPaused == true) + { + task.Status = FlightTaskStatus.Paused; + TaskState = TasksStatus.Paused; + Message.Show($"任务{i + 1} {task.TaskCnName } 暂停执行"); + return; + } + task.Status = FlightTaskStatus.Stop; + } + + // 2. 正常结束时,重置 CurrentRunningTask、CurrentRunningTaskIndex 和 IsPaused。 + TaskState = TasksStatus.Stop; + CurrentRunningTask = null; + CurrentRunningTaskIndex = 0; + IsPaused = null; + } + + public void Pause() + { + IsPaused = true; + } + + #endregion Run and pause. + + + Dictionary AvoidCrashLog = new Dictionary(); + + + + + + private async void StartAvoidingCrash() + { + await Task.Factory.StartNew(AvoidCrashtoshow); + await Task.Factory.StartNew(LoopToAvoidCrash); + } + private async void AvoidCrashtoshow() + { + while (IsPaused == false) + { + try + { + foreach (KeyValuePair kv in AvoidCrashLog) + { + string moveCopterNum = kv.Value; + int destNum = kv.Key; + Message.Show(moveCopterNum); + } + AvoidCrashLog.Clear(); //可能有丢失 + } + catch // 王海, 20151102, 通常是“集合已修改”异常。 + { + } + finally + { + await Task.Delay(100).ConfigureAwait(false); + } + } + } + private async void LoopToAvoidCrash() + { + while (IsPaused == false) + { + try + { + + double distance; + foreach (var copter in _copterManager.Copters) + { + foreach (var anotherCopter in _copterManager.Copters) + { + if (copter != anotherCopter && copter.IsTooCloseTo(anotherCopter, out distance)) + { + //防止卡顿,单加任务来显示 + AvoidCrashLog.Add(1, $"{copter.Name} 与 {anotherCopter.Name} 距离过近,间距{distance}米。"); + } + } + } + + + } + catch // 王海, 20151102, 通常是“集合已修改”异常。 + { + } + finally + { + await Task.Delay(50).ConfigureAwait(false); + } + } + } + + private void LoadIni() + { + Windows.IniHelper.IniFiles inifilse = new Windows.IniHelper.IniFiles(); + string readvalue = ""; + int intTemp; + float floatTemp; + readvalue = inifilse.IniReadvalue("Default", "ColumnCount"); + if (readvalue!= "" && int.TryParse(readvalue,out intTemp)) + ColumnCount = int.Parse(readvalue); + + readvalue = inifilse.IniReadvalue("Default", "ColumnDistance"); + if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) + ColumnDistance = float.Parse(readvalue); + + readvalue = inifilse.IniReadvalue("Default", "RowDistance"); + if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) + RowDistance = float.Parse(readvalue); + + readvalue = inifilse.IniReadvalue("Default", "Orientation"); + if (readvalue != "" && int.TryParse(readvalue, out intTemp)) + Orientation = int.Parse(readvalue); + + readvalue = inifilse.IniReadvalue("Default", "FC_acc_xy"); + if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) + FC_acc_xy = float.Parse(readvalue); + + readvalue = inifilse.IniReadvalue("Default", "FC_acc_z"); + if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) + FC_acc_z = float.Parse(readvalue); + + readvalue = inifilse.IniReadvalue("Default", "FC_maxvel_xy"); + if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) + FC_maxvel_xy = float.Parse(readvalue); + + readvalue = inifilse.IniReadvalue("Default", "FC_maxvel_up"); + if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) + FC_maxvel_up = float.Parse(readvalue); + + readvalue = inifilse.IniReadvalue("Default", "FC_maxvel_down"); + if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) + FC_maxvel_down = float.Parse(readvalue); + + + readvalue = inifilse.IniReadvalue("Default", "FC_defvel_xy"); + if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) + FC_defvel_xy = float.Parse(readvalue); + + readvalue = inifilse.IniReadvalue("Default", "FC_defvel_up"); + if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) + FC_defvel_up = float.Parse(readvalue); + + readvalue = inifilse.IniReadvalue("Default", "FC_defvel_down"); + if (readvalue != "" && float.TryParse(readvalue, out floatTemp)) + FC_defvel_down = float.Parse(readvalue); + + + + } + + public void SaveIni() + { + Windows.IniHelper.IniFiles inifilse = new Windows.IniHelper.IniFiles(); + inifilse.IniWritevalue("Default", "ColumnCount", ColumnCount.ToString()); + inifilse.IniWritevalue("Default", "ColumnDistance", ColumnDistance.ToString()); + inifilse.IniWritevalue("Default", "RowDistance", RowDistance.ToString()); + inifilse.IniWritevalue("Default", "Orientation", Orientation.ToString()); + } + } + + public class FlightTaskAddedEventArgs : EventArgs + { + public FlightTask LastTask { get; set; } + public FlightTask AddedTask { get; set; } + } + + public class FlightTaskDeledEventArgs : EventArgs + { + public FlightTask DeledTask { get; set; } + public int TaskIndex { get; set; } + + } + + public class FlightTaskTypeChangedEventArgs : EventArgs + { + public FlightTaskTypeChangedEventArgs(FlightTask changedFlightTask) + { + this.ChangedFlightTask = changedFlightTask; + } + public FlightTask ChangedFlightTask { get; set; } + + } + + + public class FlightTaskcnNameChangedEventArgs : EventArgs + { + public FlightTaskcnNameChangedEventArgs(FlightTask changedFlightTask) + { + this.ChangedFlightTask = changedFlightTask; + } + public FlightTask ChangedFlightTask { get; set; } + + } + + + + + + + public class FlightTaskAddedOriginalEventArgs : EventArgs + { + public double Lat { get; set; } + public double Lng { get; set; } + } + + public class SingleCopterInfoChangedEventArgs : EventArgs + { + public SingleCopterInfoChangedEventArgs(FlightTaskSingleCopterInfo changedSingleCopterInfo) + { + this.ChangedSingleCopterInfo = changedSingleCopterInfo; + } + + public FlightTaskSingleCopterInfo ChangedSingleCopterInfo { get; set; } + } +} diff --git a/Plane.FormationCreator/Plane.FormationCreator.csproj b/Plane.FormationCreator/Plane.FormationCreator.csproj index 05bdeae..27aa921 100644 --- a/Plane.FormationCreator/Plane.FormationCreator.csproj +++ b/Plane.FormationCreator/Plane.FormationCreator.csproj @@ -1,528 +1,532 @@ - - - - - Debug - AnyCPU - {61E2F31E-220A-4E3F-A64D-F7CDC2135008} - WinExe - Properties - Plane.FormationCreator - FGCS - v4.6 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - - - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - true - false - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - gcs.ico - - - - ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll - True - - - ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll - True - - - ..\packages\MvvmLightLibs.5.2.0.0\lib\net45\GalaSoft.MvvmLight.dll - True - - - ..\packages\MvvmLightLibs.5.2.0.0\lib\net45\GalaSoft.MvvmLight.Extras.dll - True - - - ..\packages\MvvmLightLibs.5.2.0.0\lib\net45\GalaSoft.MvvmLight.Platform.dll - True - - - ..\packages\GMap.NET.Windows.1.8.5\lib\net40\GMap.NET.Core.dll - True - - - ..\packages\GMap.NET.Windows.1.8.5\lib\net40\GMap.NET.WindowsPresentation.dll - True - - - ..\packages\HelixToolkit.2.4.0\lib\netstandard1.1\HelixToolkit.dll - True - - - ..\packages\HelixToolkit.Wpf.2.4.0\lib\net45\HelixToolkit.Wpf.dll - True - - - ..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll - True - - - ..\packages\MaterialDesignColors.1.1.2\lib\net45\MaterialDesignColors.dll - True - - - ..\packages\MaterialDesignThemes.1.4.0.473\lib\net45\MaterialDesignThemes.Wpf.dll - True - - - ..\packages\Unnoficial.Microsoft.Expression.Drawing.1.0.0\lib\Microsoft.Expression.Drawing.dll - - - ..\packages\Microsoft.Maps.MapControl.WPF.1.0.0.3\lib\net40-Client\Microsoft.Maps.MapControl.WPF.dll - True - - - ..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll - - - ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll - True - - - - - - - ..\packages\System.Data.SQLite.Core.1.0.109.1\lib\net46\System.Data.SQLite.dll - True - - - ..\packages\System.Data.SQLite.EF6.1.0.109.0\lib\net46\System.Data.SQLite.EF6.dll - True - - - ..\packages\System.Data.SQLite.Linq.1.0.109.0\lib\net46\System.Data.SQLite.Linq.dll - True - - - - - ..\packages\MahApps.Metro.1.5.0\lib\net45\System.Windows.Interactivity.dll - True - - - - - - - - 4.0 - - - - - - - - MSBuild:Compile - Designer - - - App.xaml - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ModifyParam.xaml - - - PlaneMessageBox.xaml - - - - - - - - Component - - - - - - - - - - - - - - - - - - - - - - - - - - - CalibrationWindow.xaml - - - ConfigVirtualIdView.xaml - - - ControlPanelView.xaml - - - CopterAttributeView.xaml - - - CopterGroupsView.xaml - - - CopterInfoView.xaml - - - CopterListView.xaml - - - ConnectWindow.xaml - - - ChangePasswordView.xaml - - - InputDialog.xaml - - - LoginView.xaml - - - LogWindow.xaml - - - MapView.xaml - - - - ModifyTaskView.xaml - - - RtcmInfoView.xaml - - - SetCoptersPutView.xaml - - - TaskBarView.xaml - - - View3D.xaml - - - - - MainWindow.xaml - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - Designer - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - - - - Designer - MSBuild:Compile - - - MSBuild:Compile - Designer - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - true - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - Form - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - - - {705aab55-ed7a-4856-8f7b-e7a78ed9e39a} - FlightRoute - - - {9c2cafda-cf1d-4565-b797-398376fcd346} - Plane.Logging - - - {98755514-c2e9-4abe-8a25-007804577558} - Plane.Reflection - - - {413C18E2-235F-4E15-B5C1-633657DE5D7A} - Plane.Windows.Messages - - - {06848293-9b17-4068-9b35-44d0ed713cd4} - Plane.Windows - - - {6cce2aeb-3b38-4c00-b32d-433a990ae2ad} - Plane - - - {47141894-ece3-48ca-8dcf-ca751bda231e} - PlaneGcsSdk.Contract_Private - - - {0111eb6e-72e3-499c-a3ba-022f5bbc4caf} - PlaneGcsSdk_Private_NET46 - - - - - - - - - - - - - - - - - - - - - - - False - Microsoft .NET Framework 4.6 %28x86 和 x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - - + + + + + Debug + AnyCPU + {61E2F31E-220A-4E3F-A64D-F7CDC2135008} + WinExe + Properties + Plane.FormationCreator + FGCS + v4.6 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + true + false + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + gcs.ico + + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + True + + + ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + True + + + ..\packages\MvvmLightLibs.5.2.0.0\lib\net45\GalaSoft.MvvmLight.dll + True + + + ..\packages\MvvmLightLibs.5.2.0.0\lib\net45\GalaSoft.MvvmLight.Extras.dll + True + + + ..\packages\MvvmLightLibs.5.2.0.0\lib\net45\GalaSoft.MvvmLight.Platform.dll + True + + + ..\packages\GMap.NET.Windows.1.8.5\lib\net40\GMap.NET.Core.dll + True + + + ..\packages\GMap.NET.Windows.1.8.5\lib\net40\GMap.NET.WindowsPresentation.dll + True + + + ..\packages\HelixToolkit.2.4.0\lib\netstandard1.1\HelixToolkit.dll + True + + + ..\packages\HelixToolkit.Wpf.2.4.0\lib\net45\HelixToolkit.Wpf.dll + True + + + ..\packages\MahApps.Metro.1.5.0\lib\net45\MahApps.Metro.dll + True + + + ..\packages\MaterialDesignColors.1.1.2\lib\net45\MaterialDesignColors.dll + True + + + ..\packages\MaterialDesignThemes.1.4.0.473\lib\net45\MaterialDesignThemes.Wpf.dll + True + + + ..\packages\Unnoficial.Microsoft.Expression.Drawing.1.0.0\lib\Microsoft.Expression.Drawing.dll + + + ..\packages\Microsoft.Maps.MapControl.WPF.1.0.0.3\lib\net40-Client\Microsoft.Maps.MapControl.WPF.dll + True + + + ..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll + + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + True + + + + + + + ..\packages\System.Data.SQLite.Core.1.0.109.1\lib\net46\System.Data.SQLite.dll + True + + + ..\packages\System.Data.SQLite.EF6.1.0.109.0\lib\net46\System.Data.SQLite.EF6.dll + True + + + ..\packages\System.Data.SQLite.Linq.1.0.109.0\lib\net46\System.Data.SQLite.Linq.dll + True + + + + + ..\packages\MahApps.Metro.1.5.0\lib\net45\System.Windows.Interactivity.dll + True + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ModifyParam.xaml + + + PlaneMessageBox.xaml + + + + + + + + Component + + + + + + + + + + + + + + + + + + + + + + + + + + + CalibrationWindow.xaml + + + ConfigVirtualIdView.xaml + + + ControlPanelView.xaml + + + CopterAttributeView.xaml + + + CopterGroupsView.xaml + + + CopterInfoView.xaml + + + CopterListView.xaml + + + ConnectWindow.xaml + + + ChangePasswordView.xaml + + + InputDialog.xaml + + + LoginView.xaml + + + LogWindow.xaml + + + MapView.xaml + + + + ModifyTaskView.xaml + + + RtcmInfoView.xaml + + + SetCoptersPutView.xaml + + + TaskBarView.xaml + + + View3D.xaml + + + + + MainWindow.xaml + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + Designer + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + true + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + Form + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + + + {626a9bfa-07de-4063-a178-360eb7057ed6} + FlyBase + + + {705aab55-ed7a-4856-8f7b-e7a78ed9e39a} + FlightRoute + + + {9c2cafda-cf1d-4565-b797-398376fcd346} + Plane.Logging + + + {98755514-c2e9-4abe-8a25-007804577558} + Plane.Reflection + + + {413C18E2-235F-4E15-B5C1-633657DE5D7A} + Plane.Windows.Messages + + + {06848293-9b17-4068-9b35-44d0ed713cd4} + Plane.Windows + + + {6cce2aeb-3b38-4c00-b32d-433a990ae2ad} + Plane + + + {47141894-ece3-48ca-8dcf-ca751bda231e} + PlaneGcsSdk.Contract_Private + + + {0111eb6e-72e3-499c-a3ba-022f5bbc4caf} + PlaneGcsSdk_Private_NET46 + + + + + + + + + + + + + + + + + + + + + + + False + Microsoft .NET Framework 4.6 %28x86 和 x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + \ No newline at end of file diff --git a/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs b/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs index 368f989..151d291 100644 --- a/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs +++ b/Plane.FormationCreator/ViewModels/ModifyTaskViewModel.cs @@ -1,2553 +1,2553 @@ -using Plane.Collections; -using Plane.Copters; -using Plane.FormationCreator.Formation; -using GalaSoft.MvvmLight; -using GalaSoft.MvvmLight.CommandWpf; -using Microsoft.Win32; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Input; -using Plane.Geography; -using Plane.Windows.Messages; -using System.Windows; -using System.Windows.Media; - -namespace Plane.FormationCreator.ViewModels -{ - public class ModifyTaskViewModel : ViewModelBase - { - public ModifyTaskViewModel(FlightTaskManager flightTaskManager, CopterManager copterManager) - { - _flightTaskManager = flightTaskManager; - _copterManager = copterManager; - //_flightTaskManager.SingleCopterInfoChanged += (sender, e) => - //{ - // var changedSingleInfo = e.ChangedSingleCopterInfo; - // if (changedSingleInfo.Copter == _copterManager.SelectedCopters.FirstOrDefault()) - // { - // if (changedSingleInfo is FlyToFlightTaskSingleCopterInfo) - // { - // FlyToLat = changedSingleInfo.TargetLat; - // FlyToLng = changedSingleInfo.TargetLng; - // FlyToAlt = changedSingleInfo.TargetAlt; - // } - // } - //}; - // TODO: 王海, 20150803, 没什么问题就把这段以及 FlyToLat 等属性删了。 - //_flightTaskManager.PropertyChanged += (sender, e) => - //{ - // switch (e.PropertyName) - // { - // case nameof(FlightTaskManager.SelectedTask): - // var currentCopter = _copterManager.SelectedCopters.FirstOrDefault(); - // if (currentCopter != null) - // { - // var selectedTask = _flightTaskManager.SelectedTask; - // if (selectedTask != null) - // { - // var singleCopterInfo = selectedTask.SingleCopterInfos.Find(i => i.Copter == currentCopter); - // if (singleCopterInfo is FlyToFlightTaskSingleCopterInfo) - // { - // var info = singleCopterInfo as FlyToFlightTaskSingleCopterInfo; - // this.FlyToLat = info.TargetLat; - // this.FlyToLng = info.TargetLng; - // this.FlyToAlt = info.TargetAlt; - // } - // } - // } - // break; - // default: - // break; - // } - //}; - //_copterManager.SelectedCoptersChanged += (sender, e) => - //{ - // // TODO: 王海, 20150731, 处理多选飞行器时的情况。 - // var selectedCopters = _copterManager.SelectedCopters; - // if (selectedCopters.Count() > 1) - // { - // CanModifySingleCopterInfo = false; - // return; - // } - - // CanModifySingleCopterInfo = true; - - // var currentCopter = e.AddedCopters.FirstOrDefault(); - // if (currentCopter != null) - // { - // var selectedTask = _flightTaskManager.SelectedTask; - // if (selectedTask != null) - // { - // var singleCopterInfo = selectedTask.SingleCopterInfos.Find(i => i.Copter == currentCopter); - // if (singleCopterInfo is FlyToFlightTaskSingleCopterInfo) - // { - // var info = singleCopterInfo as FlyToFlightTaskSingleCopterInfo; - // this.FlyToLat = info.TargetLat; - // this.FlyToLng = info.TargetLng; - // this.FlyToAlt = info.TargetAlt; - // } - // } - // } - //}; - //this.PropertyChanged += (sender, e) => - //{ - // switch (e.PropertyName) - // { - // case nameof(FlyToLat): - // InvokeForSelectedSingleCopterInfos(info => info.TargetLat = FlyToLat); - // break; - // case nameof(FlyToLng): - // InvokeForSelectedSingleCopterInfos(info => info.TargetLng = FlyToLng); - // break; - // case nameof(FlyToAlt): - // InvokeForSelectedSingleCopterInfos(info => info.TargetAlt = FlyToAlt); - // break; - // case nameof(StaggerRoutes): - // { - // var modifyingTask = _flightTaskManager.SelectedTask as FlyToFlightTask; - // if (modifyingTask != null) - // { - // modifyingTask.StaggerAlt = this.StaggerRoutes; - // } - // } - // break; - // default: - // break; - // } - //}; - } - - private FlightTaskManager _flightTaskManager; - private CopterManager _copterManager; - public FlightTaskManager FlightTaskManager { get { return _flightTaskManager; } } - public CopterManager CopterManager { get { return _copterManager; } } - - //private void InvokeForSelectedSingleCopterInfos(Action action) - //{ - // var modifyingTask = _flightTaskManager.SelectedTask as FlyToFlightTask; - // if (modifyingTask != null && _copterManager.SelectedCopters.Count() == 1) // 王海, 20150731, 目前不处理多选的情况。 - // { - // modifyingTask.FlyToFlightTaskSingleCopterInfos - // .Where(i => _copterManager.SelectedCopters.FirstOrDefault() == i.Copter) - // .ForEach(action); - - // // TODO: 王海, 20150731, 添加同时改多个 SingleCopterInfo 的程序。 - // //.Where(i => _copterManager.SelectedCopters.Contains(i.Copter)) - // } - //} - - private bool _CanModifySingleCopterInfo = true; - public bool CanModifySingleCopterInfo - { - get { return _CanModifySingleCopterInfo; } - set { Set(nameof(CanModifySingleCopterInfo), ref _CanModifySingleCopterInfo, value); } - } - -// private double _Distancevalue; -// public double Distancevalue -// { -// get { return _Distancevalue; } -// set { Set(nameof(Distancevalue), ref _Distancevalue, value); } -// } - - - private float _Modialtvalue; - public float Modialtvalue - { - get { return _Modialtvalue; } - set { Set(nameof(Modialtvalue), ref _Modialtvalue, value); } - } - - - private int _txtStarindex=0; - public int txtStarindex - { - get { return _txtStarindex; } - set { Set(nameof(txtStarindex), ref _txtStarindex, value); } - } - - private int _txtendindex=0; - public int txtendindex - { - get { return _txtendindex; } - set { Set(nameof(txtendindex), ref _txtendindex, value); } - } - - private float _directionvalue = 0; - public float directionvalue - { - get { return _directionvalue; } - set { Set(nameof(directionvalue), ref _directionvalue, value); } - } - - private float _directionvalueall = 0; - public float directionvalueall - { - get { return _directionvalueall; } - set { Set(nameof(directionvalueall), ref _directionvalueall, value); } - } - - - private int _taskstartno = 0; - public int taskstartno - { - get { return _taskstartno; } - set { Set(nameof(taskstartno), ref _taskstartno, value); } - } - - private int _taskendno = 0; - public int taskendno - { - get { return _taskendno; } - set { Set(nameof(taskendno), ref _taskendno, value); } - } - - - private float _taskdirection = 0; - public float taskdirection - { - get { return _taskdirection; } - set { Set(nameof(taskdirection), ref _taskdirection, value); } - } - - - - - - - private double _FlyToLat; - public double FlyToLat - { - get { return _FlyToLat; } - set { Set(nameof(FlyToLat), ref _FlyToLat, value); } - } - - private double _FlyToLng; - public double FlyToLng - { - get { return _FlyToLng; } - set { Set(nameof(FlyToLng), ref _FlyToLng, value); } - } - - private float _FlyToAlt; - public float FlyToAlt - { - get { return _FlyToAlt; } - set { Set(nameof(FlyToAlt), ref _FlyToAlt, value); } - } - - private bool _StaggerRoutes; - public bool StaggerRoutes - { - get { return _StaggerRoutes; } - set { Set(nameof(StaggerRoutes), ref _StaggerRoutes, value); } - } - - private bool _OnlySelected = false; - public bool OnlySelected - { - get { return _OnlySelected; } - set { Set(nameof(OnlySelected), ref _OnlySelected, value); } - } - - - - /// - /// 垂直旋转多个任务 - /// - private ICommand _MitTaskVrotationCommand; - public ICommand MitTaskVrotationCommand - - { - get - { - return _MitTaskVrotationCommand ?? (_MitTaskVrotationCommand = new RelayCommand(async => - { - - - double lngsum = 0; - double latsum = 0; - double altsum = 0; - int selectcount = 0; - // double centlng = 0; - double centlat = 0; - double centalt = 0; - - - - int _taskstartno = 0; - int _taskendno = 0; - - if (taskstartno == 0) - _taskstartno = 0; - else _taskstartno = taskstartno - 1; - - if (taskendno == 0) - _taskendno = _flightTaskManager.Tasks.Count()-1; - else _taskendno = taskendno - 1; - - - - - - - //计算旋转中心轴 - for (int i = _taskstartno ; i <= _taskendno; i++) - { - if ((_flightTaskManager.Tasks[i].TaskType == FlightTaskType.TakeOff) || (_flightTaskManager.Tasks[i].TaskType == FlightTaskType.Land)) - continue; - - for (int j = 0; j < _flightTaskManager.Tasks[i].SingleCopterInfos.Count; j++) - { - - lngsum += _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng; - latsum += _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat; - altsum += _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt; - selectcount++; - } - } - if (selectcount > 0) - { - // centlng = lngsum / selectcount; - centlat = latsum / selectcount; - centalt = altsum / selectcount; - } - - - - //////////计算旋转,经测试用下面的函数组合计算比较准确 - double k = (double)taskdirection / 180 * Math.PI; - double dx = 0; - double dy = 0; - double ax = 0; - double ay = 0; - double tlng = 0; - double tlat = 0; - - - for (int i = _taskstartno; i <= _taskendno; i++) - { - if ((_flightTaskManager.Tasks[i].TaskType == FlightTaskType.TakeOff) || (_flightTaskManager.Tasks[i].TaskType == FlightTaskType.Land)) - continue; - - for (int j = 0; j < _flightTaskManager.Tasks[i].SingleCopterInfos.Count; j++) - { - - - tlng = _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng; - tlat = _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat; - //纬度方向距离(单位m) - ax = CalculationLogLatDistance.GetDistanceOne(tlng, centlat, tlng, tlat) * 1000; - //方向角用于正负,0为正,180为负 - CalculationLogLatDistance.MyLatLng mypos1, mypos2; - mypos1 = new CalculationLogLatDistance.MyLatLng(tlng, centlat); - mypos2 = new CalculationLogLatDistance.MyLatLng(tlng, tlat); - double lpAzimuth = CalculationLogLatDistance.getAngle(mypos1, mypos2); - if (lpAzimuth > 90) - ax = -ax; - - - //高度方向距离(单位m) - ay = (_flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt - centalt); - - dx = ax * Math.Cos(k) + ay * Math.Sin(k); - dy = -ax * Math.Sin(k) + ay * Math.Cos(k); - - //新高度(米) - _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt = (float)(centalt + dy); - //计算新纬度 - double lng2 = 0; - double lat2 = 0; - if (dx < 0) - lpAzimuth = 180; - else - lpAzimuth = 0; - dx = Math.Abs(dx); - - CalculationLogLatDistance.ConvertDistanceToLogLat( - tlng, - centlat, //旋转中心纬度 - dx / 1000, //新距离 - lpAzimuth, //方向垂直 - out lng2, - out lat2); - _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat = lat2; - - } - - - } - // await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 - })); - } - } - - private ICommand _ShowallTaskpointCommand; - public ICommand ShowallTaskpointCommand - - { - get - { - return _ShowallTaskpointCommand ?? (_ShowallTaskpointCommand = new RelayCommand(async => - { - MapManager _mapManager = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance(); - _mapManager.MapView.ShowAllWaypoint(); - - //_flightTaskManager.SelectedTask = null; - })); - } - } - private void GetMaxMissions() - { - int missiontmp = 0; - - string maxCopterName = ""; - int maxmission = 0; - string minCopterName = ""; - int minmission = 65535; - - ICopter vcopter = _copterManager.SelectedCopters.FirstOrDefault(); - if (vcopter == null) - { - Alert.Show($"请先选中飞机!", "提示", MessageBoxButton.OK, MessageBoxImage.Information); - return; - } - - - int coptercount = _copterManager.Copters.Count; - - - for (int i = 0; i < coptercount; i++) - { - missiontmp = 0; - - var currcopter = _copterManager.Copters[i]; - - foreach (var capter in _copterManager.SelectedCopters) - { - if (currcopter == capter) - { - for (int j = 0; j < _flightTaskManager.Tasks.Count; j++) - { - missiontmp++; - missiontmp += _flightTaskManager.Tasks[j].SingleCopterInfos[i].LEDInfos.Count(); - } - - if (missiontmp > maxmission) - { - maxCopterName = _copterManager.Copters[i].Name; - maxmission = missiontmp; - } - - if (missiontmp < minmission) - { - minCopterName = _copterManager.Copters[i].Name; - minmission = missiontmp; - } - - } - - } - - - - - - } - if (maxmission>256) - Alert.Show($"飞机:[ {maxCopterName} ] 有最多任务数量:{maxmission} 已超出256的最大航点限制,请减少灯光; \n飞机:[ {minCopterName} ] 有最少任务数量:{minmission}", "提示", MessageBoxButton.OK, MessageBoxImage.Information); - else - Alert.Show($"飞机:[ {maxCopterName} ] 有最多任务数量:{maxmission} \n飞机:[ {minCopterName} ] 有最少任务数量:{minmission} \n (航点加灯光不能超过256个任务)", "提示", MessageBoxButton.OK, MessageBoxImage.Information); - return ; - } - - private ICommand _CheckMissionCountCommand; - public ICommand CheckMissionCountCommand - - { - get - { - return _CheckMissionCountCommand ?? (_CheckMissionCountCommand = new RelayCommand(async => - { - GetMaxMissions(); - - })); - } - } - - - - //调整所有任务经度 - private ICommand _ModiAllPosCommand; - public ICommand ModiAllPosCommand - { - get - { - return _ModiAllPosCommand ?? (_ModiAllPosCommand = new RelayCommand( cModialtvalue => - { - if (_flightTaskManager.Tasks.Count < 2) return; - - float lowalt = 200; - - int itaskendno = taskendno; - if (taskendno == 0) itaskendno = _flightTaskManager.Tasks.Count - 1; - else itaskendno = taskendno - 1; - if (itaskendno > _flightTaskManager.Tasks.Count-1) itaskendno = _flightTaskManager.Tasks.Count-1; - // for (int i = taskstartno; i < itaskendno; i++) - - int _startindex = taskstartno; - if (taskstartno == 0) - _startindex = 0; - else - _startindex = taskstartno - 1; - - int _endindex = itaskendno; - - - - int lowtask = 0; - int lowCopter = 0; - - if ((txtStarindex != 0) && (txtendindex != 0)) - { - _startindex = txtStarindex; - _endindex = txtendindex; - } - - for (int i = _startindex; i <= _endindex; i++) - { - - if ((_flightTaskManager.Tasks[i].TaskType == FlightTaskType.TakeOff)|| (_flightTaskManager.Tasks[i].TaskType == FlightTaskType.Land)) - continue; - - - for (int j = 0; j < _flightTaskManager.Tasks[i].SingleCopterInfos.Count; j++) - { - Tuple targetLatLng = new Tuple(0, 0); - - targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat, - _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng, - directionvalueall, - cModialtvalue - ); - _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat = targetLatLng.Item1; - _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng = targetLatLng.Item2; - } - } - Alert.Show("指定步骤任务位置已向" + directionvalueall + "度改变" + cModialtvalue + "米,注意是否有障碍物!"); - - })); - } - } - - - private ICommand _LevelAverageCommand; - public ICommand LevelAverageCommand - { - get - { - return _LevelAverageCommand ?? (_LevelAverageCommand = new RelayCommand(async => - { - double maxlng = 0; - double minlng = 0; - double tlng = 0; - double avgl = 0; - - if (_copterManager.SelectedCopters.Count() > 2) - { - List selectTaskInfos = new List(); - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - - if (_copterManager.SelectedCopters.Contains(_flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter)) - selectTaskInfos.Add(_flightTaskManager.SelectedTask.SingleCopterInfos[i]); - } - selectTaskInfos.Sort((x, y) => x.TargetLng.CompareTo(y.TargetLng)); - minlng = selectTaskInfos[0].TargetLng; - maxlng = selectTaskInfos[selectTaskInfos.Count - 1].TargetLng; - tlng = (maxlng - minlng) / (selectTaskInfos.Count - 1); - - for (int i = 0; i < selectTaskInfos.Count; i++) - { - selectTaskInfos[i].TargetLng = minlng + i * tlng; - } - } - - - /* - if (Alert.Show("本操作将导致飞机位置重新排列,编号最小的飞机在最左边,您确定要继续吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning) - == MessageBoxResult.OK) - { - - - - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - bool copterisselect; - int selectednumber = _copterManager.SelectedCopters.Count() - 1; - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - copterisselect = false; - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - copterisselect = true; - - } - if (copterisselect) - { - - tlng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; - if (minlng == 0) - minlng = tlng; - if (tlng > maxlng) - maxlng = tlng; - else if (tlng < minlng) - minlng = tlng; - - } - } - avgl = (maxlng - minlng) / selectednumber; - int coptnum = 0; - - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - copterisselect = false; - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - copterisselect = true; - - } - if (copterisselect) - { - - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = minlng + avgl * coptnum; - coptnum++; - - } - } - - } - - */ - /////////////////////// - - // await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 - - })); - } - } - - - - - private ICommand _VerticlAverageCommand; - public ICommand VerticlAverageCommand - { - get - { - return _VerticlAverageCommand ?? (_VerticlAverageCommand = new RelayCommand(async => - { - double maxlat = 0; - double tlat = 0; - double minlat = 0; - - double avgl = 0; - - if (_copterManager.SelectedCopters.Count() > 2) - { - List selectTaskInfos = new List(); - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - - if (_copterManager.SelectedCopters.Contains(_flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter)) - selectTaskInfos.Add(_flightTaskManager.SelectedTask.SingleCopterInfos[i]); - } - selectTaskInfos.Sort((x, y) => x.TargetLat.CompareTo(y.TargetLat)); - minlat = selectTaskInfos[0].TargetLat; - maxlat = selectTaskInfos[selectTaskInfos.Count - 1].TargetLat; - tlat = (maxlat - minlat) / (selectTaskInfos.Count - 1); - - for (int i = 0; i < selectTaskInfos.Count; i++) - { - selectTaskInfos[i].TargetLat = minlat + i * tlat; - } - } - - /* - if (Alert.Show("本操作将导致飞机位置重新排列,编号最小的飞机在最上边,您确定要继续吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning) - == MessageBoxResult.OK) - { - - ////////////////////// - - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - if (_flightTaskManager.SelectedTask != null) - { - bool copterisselect; - int selectednumber = _copterManager.SelectedCopters.Count() - 1; - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - copterisselect = false; - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - copterisselect = true; - - } - if (copterisselect) - { - - tlat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; - if (minlat == 0) - minlat = tlat; - if (tlat > maxlat) - maxlat = tlat; - else if (tlat < minlat) - minlat = tlat; - - } - } - avgl = (maxlat - minlat) / selectednumber; - int coptnum = 0; - - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - copterisselect = false; - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - copterisselect = true; - - } - if (copterisselect) - { - - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = maxlat - avgl * coptnum; - coptnum++; - - } - } - - /////////////////////// - - // await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 - } - } - */ - })); - } - } - - private ICommand _BackTakeOffPointCommand; - public ICommand BackTakeOffPointCommand - { - get - { - return _BackTakeOffPointCommand ?? (_BackTakeOffPointCommand = new RelayCommand(async => - { - foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos) - { - info.TargetLat = info.Copter.Latitude; - info.TargetLng = info.Copter.Longitude; - } - })); - } - } - private ICommand _ImportWayPointCommand; - public ICommand ImportWayPointCommand - { - get - { - return _ImportWayPointCommand ?? (_ImportWayPointCommand = new RelayCommand(async => - { - var dialog = new OpenFileDialog - { - DefaultExt = "json", - Filter = "json文件|*.json" - }; - if (dialog.ShowDialog() == true) - { - var tasksText = File.ReadAllText(dialog.FileName); - _flightTaskManager.ImportWaypoint(tasksText); - - } - })); - } - } - - private ICommand _ImportBlenderWayPointCommand; - public ICommand ImportBlenderWayPointCommand - { - get - { - return _ImportBlenderWayPointCommand ?? (_ImportBlenderWayPointCommand = new RelayCommand(async => - { - var dialog = new OpenFileDialog - { - DefaultExt = "txt", - Filter = "航点文件(*.txt,*.svg,*.obj) |*.txt;*.svg;*.obj" // "图片文件(*.jpg, *.gif, *.bmp, *.png) | *.jpg; *.gif; *.bmp; *.png" - }; - - if (dialog.ShowDialog() == true) - { - string extname=Path.GetExtension(dialog.FileName); - if (extname == ".txt") - { - var tasksText = File.ReadAllText(dialog.FileName); - _flightTaskManager.ImportC4DFlytoTask(tasksText); - if (_copterManager.FC_VER_NO >= 3) - Alert.Show($"导入的第一个航点默认为0,需要重新计算时间", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); - else - _flightTaskManager.SetAllTaskFlytime(); - - } - else - if ((extname == ".svg")|| (extname == ".obj")) - { - _flightTaskManager.ImportDlltoTask(dialog.FileName); - }; - - - //_flightTaskManager.ImportBlenderFlyToTask(tasksText); - } - })); - } - } - - - - - - private ICommand _ImportBlenderrCopterPosCommand; - public ICommand ImportBlenderCopterPosCommand - { - get - { - return _ImportBlenderrCopterPosCommand ?? (_ImportBlenderrCopterPosCommand = new RelayCommand(async => - { - - //有不是虚拟飞机的直接退出 - foreach (var copter in _copterManager.Copters) - { - if (!(copter is FakeCopter)) - { - Alert.Show($"导入起飞位置只能用于虚拟飞机,{copter.Id}不是虚拟飞机", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); - return; - } - } - - - var dialog = new OpenFileDialog - { - DefaultExt = "txt", - Filter = "航点文件(*.txt,*.svg,*.obj) |*.txt;*.svg;*.obj" // "图片文件(*.jpg, *.gif, *.bmp, *.png) | *.jpg; *.gif; *.bmp; *.png" - }; - - if (dialog.ShowDialog() == true) - { - string extname = Path.GetExtension(dialog.FileName); - if (extname == ".txt") - { - var tasksText = File.ReadAllText(dialog.FileName); - _flightTaskManager.ImportC4DFlytoVCopter(tasksText); - } - else - if ((extname == ".svg") || (extname == ".obj")) - { - _flightTaskManager.ImportDlltoVCopter(dialog.FileName); - }; - } - })); - } - } - - - - - - - private ICommand _ExportWayPointCommand; - public ICommand ExportWayPointCommand - { - get - { - return _ExportWayPointCommand ?? (_ExportWayPointCommand = new RelayCommand(async => - { - - // _flightTaskManager.OptimizeRouteNew(); - // return; - var dialog = new SaveFileDialog - { - DefaultExt = "txt", - Filter = "文本文件|*.txt" - }; - if (dialog.ShowDialog() == true) - { - - string exportedText = _flightTaskManager.ExportC4DFlytoTask(); - - File.WriteAllText(dialog.FileName, exportedText); - } - })); - } - } - - - private ICommand _AutoWayPointTmCommand; - public ICommand AutoWayPointTmCommand - { - get - { - return _AutoWayPointTmCommand ?? (_AutoWayPointTmCommand = new RelayCommand(async => - { - _flightTaskManager.SetTaskFlytime(_flightTaskManager.SelectedTaskIndex); - })); - } - } - - - - private ICommand _AutoWayPointAllTmCommand; - public ICommand AutoWayPointAllTmCommand - { - get - { - return _AutoWayPointAllTmCommand ?? (_AutoWayPointAllTmCommand = new RelayCommand(async => - { - - if (Alert.Show("本操作将导致2号任务以后所有任务飞行时间重新计算(不修改悬停时间),您确定要继续吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning) - == MessageBoxResult.OK) - { - _flightTaskManager.SetAllTaskFlytime(); - } - })); - } - } - - private ICommand _CheckTmCommand; - public ICommand CheckTmCommand - { - get - { - return _CheckTmCommand ?? (_CheckTmCommand = new RelayCommand(async => - { - - if (Alert.Show("本操作将检测2号任务以后所有任务飞行时间是否合理,您确定要继续吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning) - == MessageBoxResult.OK) - { - _flightTaskManager.CheckAllTaskFlytime(); - } - })); - } - } - - private ICommand _OptimizeRouteCommandRet; - public ICommand OptimizeRouteCommandRet - { - get - { - return _OptimizeRouteCommandRet ?? (_OptimizeRouteCommandRet = new RelayCommand(async => - { - _flightTaskManager.OptimizeRouteMeter(false,false); //采用米计算逻辑和OptimizeRouteNew一样 - })); - } - } - - - private ICommand _OptimizeRouteCommand3D; - public ICommand OptimizeRouteCommand3D - { - get - { - return _OptimizeRouteCommand3D ?? (_OptimizeRouteCommand3D = new RelayCommand(async => - { - //_flightTaskManager.OptimizeRoute2(); - // _flightTaskManager.OptimizeRouteNew (); //最后可用的,但是经纬度计算, - _flightTaskManager.OptimizeRouteMeter(true); //采用米计算逻辑和OptimizeRouteNew一样 - })); - } - } - private ICommand _OptimizeRouteCommand; - public ICommand OptimizeRouteCommand - { - get - { - return _OptimizeRouteCommand ?? (_OptimizeRouteCommand = new RelayCommand(async => - { - //_flightTaskManager.OptimizeRoute2(); - // _flightTaskManager.OptimizeRouteNew (); //最后可用的,但是经纬度计算, - _flightTaskManager.OptimizeRouteMeter(); //采用米计算逻辑和OptimizeRouteNew一样 - })); - } - } - - private ICommand _LevelAlignmentCommand; - public ICommand LevelAlignmentCommand - { - get - { - return _LevelAlignmentCommand ?? (_LevelAlignmentCommand = new RelayCommand(async => - { - double maxlat = 0; - double tlat = 0; - - - - - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - if (_flightTaskManager.SelectedTask != null) - { - bool copterisselect; - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - copterisselect = false; - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - copterisselect = true; - - } - if (copterisselect) - { - - tlat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; - if (tlat > maxlat) - maxlat = tlat; - - } - } - - - - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - copterisselect = false; - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - copterisselect = true; - - } - if (copterisselect) - { - - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = maxlat; - - } - } - } - else - //调整飞机 - { - //模拟飞机才能调整 - if (selectedCopter is FakeCopter) - { - foreach (var capter in _copterManager.SelectedCopters) - { - tlat = capter.Latitude; - if (tlat > maxlat) - maxlat = tlat; - } - - foreach (var capter in _copterManager.SelectedCopters) - { - var copterfk = (FakeCopter)capter; - copterfk.SetProperties( - latitude: maxlat, - longitude: copterfk.Longitude); - } - } - } - - - - - //await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 - - })); - } - } - - - - - - - - private ICommand _VerticlAlignmentCommand; -public ICommand VerticlAlignmentCommand - { - get - { - return _VerticlAlignmentCommand ?? (_VerticlAlignmentCommand = new RelayCommand(async => - { - - double maxlng = 0; - double tlng = 0; - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - bool copterisselect; - if (_flightTaskManager.SelectedTask != null) - { - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - copterisselect = false; - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - copterisselect = true; - - } - if (copterisselect) - { - - tlng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; - if (tlng > maxlng) - maxlng = tlng; - - } - } - - - - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - copterisselect = false; - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - copterisselect = true; - - } - if (copterisselect) - { - - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = maxlng; - - } - } - - //await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 - - //await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 - } - else - //调整飞机 - { - //模拟飞机才能调整 - if (selectedCopter is FakeCopter) - { - foreach (var capter in _copterManager.SelectedCopters) - { - tlng = capter.Longitude; - if (tlng > maxlng) - maxlng = tlng; - } - - foreach (var capter in _copterManager.SelectedCopters) - { - var copterfk = (FakeCopter)capter; - copterfk.SetProperties( - latitude: copterfk.Latitude, - longitude: maxlng); - } - } - } - - })); - } - - } - - - - - - - - - - public static double DistanceOfTwoPoints(double lng1, double lat1, double lng2, double lat2, GaussSphere gs) - { - double radLat1 = Rad(lat1); - double radLat2 = Rad(lat2); - double a = radLat1 - radLat2; - double b = Rad(lng1) - Rad(lng2); - double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + - Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2))); - s = s * (gs == GaussSphere.WGS84 ? 6378137.0 : (gs == GaussSphere.Xian80 ? 6378140.0 : 6378245.0)); - s = Math.Round(s * 10000) / 10000; - return s; - } - - private static double Rad(double d) - { - return d * Math.PI / 180.0; - } - - - /// - /// 高斯投影中所选用的参考椭球 - /// - public enum GaussSphere - { - Beijing54, - Xian80, - WGS84, - } - - - - - //水平旋转 - private ICommand _LevelRotateCommand; - public ICommand LevelRotateCommand - { - get - { - return _LevelRotateCommand ?? (_LevelRotateCommand = new RelayCommand(async RotateLine => - { - - - - double lngsum = 0; - double latsum = 0; - int selectcount = 0; - double centlng = 0; - double centlat = 0; - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - if (_flightTaskManager.SelectedTask != null) - { - bool copterisselect; - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - copterisselect = false; - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - copterisselect = true; - - } - if (copterisselect) - { - - lngsum+= _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; - latsum+= _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; - selectcount++; - - } - } - //计算旋转中心 - if (selectcount > 0) - { - centlng = lngsum / selectcount; - centlat = latsum / selectcount; - } - else return; - - - //////////计算旋转,经测试用下面的函数组合计算比较准确 - - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - { - double lpDistance = CalculationLogLatDistance.GetDistanceOne(centlng, centlat, - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng, - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat); - - CalculationLogLatDistance.MyLatLng mypos1, mypos2; - mypos1 = new CalculationLogLatDistance.MyLatLng(centlng, centlat); - mypos2 = new CalculationLogLatDistance.MyLatLng(_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng - , _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat); - double lpAzimuth = CalculationLogLatDistance.getAngle(mypos1, mypos2); - double lng2 = 0; - double lat2=0; - CalculationLogLatDistance.ConvertDistanceToLogLat(centlng, centlat, lpDistance, - lpAzimuth + (double)RotateLine,out lng2, out lat2); - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = lng2; - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = lat2; - - } - - - } - } - //// - await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 - - - } - else - //调整飞机 - { - //模拟飞机才能调整 - if (selectedCopter is FakeCopter) - { - foreach (var capter in _copterManager.SelectedCopters) - { - lngsum += capter.Longitude; - latsum += capter.Latitude; - selectcount++; - } - - //计算旋转中心 - if (selectcount > 0) - { - centlng = lngsum / selectcount; - centlat = latsum / selectcount; - } - else return; - - foreach (var capter in _copterManager.SelectedCopters) - { - - - double lpDistance = CalculationLogLatDistance.GetDistanceOne(centlng, centlat, - capter.Longitude, - capter.Latitude); - - CalculationLogLatDistance.MyLatLng mypos1, mypos2; - mypos1 = new CalculationLogLatDistance.MyLatLng(centlng, centlat); - mypos2 = new CalculationLogLatDistance.MyLatLng( - capter.Longitude - , capter.Latitude); - double lpAzimuth = CalculationLogLatDistance.getAngle(mypos1, mypos2); - double lng2 = 0; - double lat2 = 0; - CalculationLogLatDistance.ConvertDistanceToLogLat(centlng, centlat, lpDistance, - lpAzimuth + (double)RotateLine, out lng2, out lat2); - - var copterfk = (FakeCopter)capter; - copterfk.SetProperties( - latitude: lat2, - longitude: lng2); - } - } - } - - })); - } - } - - //任务整体旋转 - private ICommand _TaskRotateCommand; - public ICommand TaskRotateCommand - { - get - { - return _TaskRotateCommand ?? (_TaskRotateCommand = new RelayCommand(async RotateLine => - { - double centlng = 0; - double centlat = 0; - - if (_copterManager.Copters.Count > 0) - { - //centlng = _copterManager.Copters[0].Longitude; - //centlat = _copterManager.Copters[0].Latitude; - centlng = _flightTaskManager.OriginLng; - centlat = _flightTaskManager.OriginLat; - //虚拟飞机一起旋转 - if ("FakeCopter" == _copterManager.Copters[0].GetType().Name) - { - for (int i = 0; i < _copterManager.Copters.Count; i++) - { - FakeCopter tempcopter = (FakeCopter)_copterManager.Copters[i]; - double lng_out = 0; - double lat_out = 0; - CalculationLogLatDistance.GetRotatePos(centlng, centlat, (double)RotateLine, - tempcopter.Longitude, - tempcopter.Latitude, - out lng_out, out lat_out - ); - tempcopter.SetProperties( - latitude: lat_out, - longitude: lng_out - ); - - } - - _flightTaskManager.Orientation += RotateLine; - } - - - - - - double copterlng = 0; - double copterlat = 0; - double lng_out1 = 0; - double lat_out1 = 0; - - int itaskendno = taskendno; - if (itaskendno == 0) itaskendno = _flightTaskManager.Tasks.Count - 1; - else itaskendno = taskendno - 1; - if (itaskendno > _flightTaskManager.Tasks.Count-1) itaskendno = _flightTaskManager.Tasks.Count-1; - int _taskstartno = 0; - if (taskstartno == 0) _taskstartno = 0; - else _taskstartno = taskstartno - 1; - - for (int i = _taskstartno; i <= itaskendno; i++) - { - - - for (int j = 0; j < _flightTaskManager.Tasks[i].SingleCopterInfos.Count; j++) - { - copterlng=_flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng; - copterlat = _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat; - - CalculationLogLatDistance.GetRotatePos(centlng, centlat, (double)RotateLine, - copterlng, - copterlat, - out lng_out1, out lat_out1 - ); - - _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng = lng_out1; - _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat = lat_out1; - } - - } - - - } - - await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 - - })); - } - } - - - - //垂直旋转 - private ICommand _VerticlRotateCommand; - public ICommand VerticlRotateCommand - { - get - { - return _VerticlRotateCommand ?? (_VerticlRotateCommand = new RelayCommand(async RotateLine => - { - - - - double lngsum = 0; - double latsum = 0; - double altsum = 0; - int selectcount = 0; - double centlng = 0; - double centlat = 0; - double centalt = 0; - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - if (_flightTaskManager.SelectedTask != null) - { - bool copterisselect; - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - copterisselect = false; - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - copterisselect = true; - - } - if (copterisselect) - { - - lngsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; - latsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; - altsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt; - selectcount++; - - } - } - //计算旋转中心 - if (selectcount > 0) - { - centlng = lngsum / selectcount; - centlat = latsum / selectcount; - centalt = altsum / selectcount; - } - else return; - - - //////////计算旋转,经测试用下面的函数组合计算比较准确 - double k = (double)RotateLine / 180 * Math.PI; - double dx = 0; - double dy = 0; - double ax = 0; - double ay = 0; - double tlng = 0; - double tlat = 0; - - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - { - tlng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; - tlat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; - //纬度方向距离(单位m) - ax = CalculationLogLatDistance.GetDistanceOne(tlng, centlat,tlng,tlat) *1000; - //方向角用于正负,0为正,180为负 - CalculationLogLatDistance.MyLatLng mypos1, mypos2; - mypos1 = new CalculationLogLatDistance.MyLatLng(tlng,centlat); - mypos2 = new CalculationLogLatDistance.MyLatLng(tlng,tlat); - double lpAzimuth = CalculationLogLatDistance.getAngle(mypos1, mypos2); - if (lpAzimuth > 90) - ax = -ax; - - - //高度方向距离(单位m) - ay = (_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt - centalt); - - dx = ax * Math.Cos(k) + ay * Math.Sin(k); - dy = -ax * Math.Sin(k) + ay * Math.Cos(k); - - //新高度(米) - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt= (float)(centalt + dy); - //计算新纬度 - double lng2 = 0; - double lat2 = 0; - if (dx < 0) - lpAzimuth = 180; - else - lpAzimuth = 0; - dx=Math.Abs(dx); - - CalculationLogLatDistance.ConvertDistanceToLogLat( - tlng, - centlat, //旋转中心纬度 - dx/1000, //新距离 - lpAzimuth, //方向垂直 - out lng2, - out lat2); - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = lat2; - - } - - - } - } - //// - - - - - await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 - } - })); - } - } - - - private ICommand _AutoaltCommand; - public ICommand AutoaltCommand - { - get - { - return _AutoaltCommand ?? (_AutoaltCommand = new RelayCommand(async => - { - - - - - - - - - - - - - - - - - })); - } - } - - - private ICommand _PrealtCommand; - public ICommand PrealtCommand - { - get - { - return _PrealtCommand ?? (_PrealtCommand = new RelayCommand(async => - { - - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - { - if (_flightTaskManager.SelectedTaskIndex > 1) - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt = - _flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex - 1].SingleCopterInfos[i].TargetAlt; - } - - } - - - } - - - - - - - - - })); - } - } - - //当前任务选中的飞机修改高度 - private ICommand _ModiSelectedAltCommand; - public ICommand ModiSelectedAltCommand - { - get - { - return _ModiSelectedAltCommand ?? (_ModiSelectedAltCommand = new RelayCommand(async => - { - if (_flightTaskManager.Tasks.Count < 2) return; - if (_flightTaskManager.SelectedTask.TaskType != FlightTaskType.FlyTo) return; - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - var info = _flightTaskManager.SelectedTask.SingleCopterInfos[i]; - if (_copterManager.SelectedCopters.Contains(info.Copter)) - { - info.TargetAlt += Modialtvalue; - } - } - - })); - } - } - //当前任务选中的飞机水平移动 - private ICommand _ModiSelectedPosCommand; - public ICommand ModiSelectedPosCommand - { - get - { - return _ModiSelectedPosCommand ?? (_ModiSelectedPosCommand = new RelayCommand(async => - { - if (_flightTaskManager.Tasks.Count < 2) return; - if (_flightTaskManager.SelectedTask.TaskType != FlightTaskType.FlyTo) return; - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - var info = _flightTaskManager.SelectedTask.SingleCopterInfos[i]; - if (_copterManager.SelectedCopters.Contains(info.Copter)) - { - Tuple targetLatLng = new Tuple(0, 0); - - targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( - info.TargetLat, - info.TargetLng, - directionvalue, - Modialtvalue - ); - info.TargetLat = targetLatLng.Item1; - info.TargetLng = targetLatLng.Item2; - } - } - - })); - } - } - - - //调整所有任务高度 - private ICommand _ModiAltCommand; - public ICommand ModiAltCommand - { - get - { - return _ModiAltCommand ?? (_ModiAltCommand = new RelayCommand( cModialtvalue => - { - if (_flightTaskManager.Tasks.Count < 2) return; - - float lowalt = 200; - - - - int itaskendno = taskendno; - if (itaskendno == 0) itaskendno = _flightTaskManager.Tasks.Count - 1; - else itaskendno = taskendno - 1; - if (itaskendno > _flightTaskManager.Tasks.Count-1) itaskendno = _flightTaskManager.Tasks.Count-1; - // for (int i = taskstartno; i < itaskendno; i++) - int _startindex = taskstartno; - if (_startindex != 0) _startindex = taskstartno - 1; - int _endindex = itaskendno ; - int lowtask = 0; - int lowCopter = 0; - - if ((txtStarindex != 0) && (txtendindex != 0)) - { - _startindex = txtStarindex; - _endindex = txtendindex; - } - - for (int i = _startindex; i <= _endindex; i++) - { - - if ((_flightTaskManager.Tasks[i].TaskType == FlightTaskType.TakeOff)|| (_flightTaskManager.Tasks[i].TaskType == FlightTaskType.Land)) - continue; - for (int j = 0; j < _flightTaskManager.Tasks[i].SingleCopterInfos.Count; j++) - { - _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt +=(float) cModialtvalue; - if (lowalt > _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt) - { - lowalt = _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt; - lowtask = i; - lowCopter = j; - } - } - } - Alert.Show("指定步骤任务高度已改变"+ cModialtvalue + "米,步骤["+ lowtask + "],ID["+ - _flightTaskManager.Tasks[lowtask].SingleCopterInfos[lowCopter].Copter.Id - + "]最低飞行高度"+ lowalt + "米,注意是否太低!"); - - })); - } - } - - - - - - - //计算距离 - private ICommand _calDistinceCommand; - public ICommand calDistinceCommand - { - get - { - return _calDistinceCommand ?? (_calDistinceCommand = new RelayCommand(async => - { - if (_copterManager.AcceptingControlCopters.Count() < 2) - return; - - - - - - string currselectstr = ""; - - for (int tsi = 1; tsi < _flightTaskManager.Tasks.Count ; tsi++) - { - - if ((_flightTaskManager.Tasks[tsi].TaskType == FlightTaskType.TakeOff) || (_flightTaskManager.Tasks[tsi].TaskType == FlightTaskType.Land)) - continue; - - - - - double minDistance = double.MaxValue; - double maxDistance = 0.0; - var flightTask = _flightTaskManager.Tasks[tsi]; - List selectedCopter = new List(); - selectedCopter.AddRange(_copterManager.AcceptingControlCopters); - string minCopterId1 = "0"; - string minCopterId2 = "0"; - string maxCopterId1 = "0"; - string maxCopterId2 = "0"; - for (int i = 0; i < selectedCopter.Count; i++) - { - var copter1 = selectedCopter[i]; - var copterInfo1 = flightTask.SingleCopterInfos.FirstOrDefault(c => c.Copter == copter1); - - for (int j = i + 1; j < selectedCopter.Count; j++) - { - var copter2 = selectedCopter[j]; - var copterInfo2 = flightTask.SingleCopterInfos.FirstOrDefault(c => c.Copter == copter2); - - double distance = GeographyUtils.CalcDistance( - copterInfo1.TargetLat, copterInfo1.TargetLng, copterInfo1.TargetAlt, - copterInfo2.TargetLat, copterInfo2.TargetLng, copterInfo2.TargetAlt); - //minDistance = Math.Min(minDistance, distance); - if (distance < minDistance) - { - minDistance = distance; - minCopterId1 = copter1.Id; - minCopterId2 = copter2.Id; - } - - if (distance > maxDistance) - { - maxDistance = distance; - maxCopterId1 = copter1.Id; - maxCopterId2 = copter2.Id; - } - - } - } - minDistance = Math.Round(minDistance, 2); - maxDistance = Math.Round(maxDistance, 2); - - string showstr = string.Format("[{0}{1}] 最小距离 = {2:F2} 飞机: {3} 和 {4}; 最大距离 = {5:F2} 飞机: {6} 和 {7}", - flightTask.TaskIndex + 1, flightTask.TaskCnName, minDistance, minCopterId1, minCopterId2, maxDistance, - maxCopterId1, maxCopterId2); - - Message.Show(showstr); - - - // Message.Show($"[{0:flightTask.TaskIndex + 1}{flightTask.TaskCnName}]最小距离 = {minDistance} 飞机:{minCopterId1}和{minCopterId2} ; 最大距离 = {maxDistance} 飞机:{maxCopterId1}和{maxCopterId2}"); - if (flightTask == _flightTaskManager.SelectedTask) - currselectstr = showstr; - } - Message.Show("选中任务:"); - Message.Show(currselectstr); - - - - - - })); - } - } - - - private ICommand _MaxDistinceAndTimeCommand; - public ICommand MaxDistinceAndTimeCommand - { - get - { - return _MaxDistinceAndTimeCommand ?? (_MaxDistinceAndTimeCommand = new RelayCommand(async => - { - //不设置时间,只是计算 - _flightTaskManager.SetTaskFlytime(_flightTaskManager.SelectedTaskIndex, false); - })); - } - } - - - - - - //缩放 - private ICommand _ScaleCommand; - public ICommand ScaleCommand - { - get - { - return _ScaleCommand ?? (_ScaleCommand = new RelayCommand(async ScaleVale => - { - - - double lngsum = 0; - double latsum = 0; - int selectcount = 0; - double centlng = 0; - double centlat = 0; - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - bool copterisselect; - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - copterisselect = false; - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - copterisselect = true; - - } - if (copterisselect) - { - - lngsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; - latsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; - selectcount++; - - } - } - //计算缩放中心 - if (selectcount > 0) - { - centlng = lngsum / selectcount; - centlat = latsum / selectcount; - } - else return; - - - //////////计算旋转,经测试用下面的函数组合计算比较准确 - - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter) - { - double lpDistance = CalculationLogLatDistance.GetDistanceOne(centlng, centlat, - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng, - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat); - - CalculationLogLatDistance.MyLatLng mypos1, mypos2; - mypos1 = new CalculationLogLatDistance.MyLatLng(centlng, centlat); - mypos2 = new CalculationLogLatDistance.MyLatLng(_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng - , _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat); - double lpAzimuth = CalculationLogLatDistance.getAngle(mypos1, mypos2); - double lng2 = 0; - double lat2 = 0; - CalculationLogLatDistance.ConvertDistanceToLogLat(centlng, centlat, lpDistance * (double)ScaleVale/100, - lpAzimuth , out lng2, out lat2); - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = lng2; - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = lat2; - - } - - - } - } - - await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 - - })); - } - } - - - private ICommand _BackToPreviousTaskPoint; - public ICommand BackToPreviousTaskPoint - { - get - { - return _BackToPreviousTaskPoint ?? (_BackToPreviousTaskPoint = new RelayCommand(async => - { - _flightTaskManager.SelectedTask.VerticalLift = true; - })); - } - } - - #region 跑马灯参数 - - private double _BeginTime = 1; - public double BeginTime - { - get { return _BeginTime; } - set { Set(nameof(BeginTime), ref _BeginTime, value); } - } - - - //灯带扫光方向,默认从左到右 - private double _BeltDirection = 90; - public double BeltDirection - { - get { return _BeltDirection; } - set { Set(nameof(BeltDirection), ref _BeltDirection, value); } - } - - - - - - - - private double _EndTime = 3; - public double EndTime - { - get { return _EndTime; } - set { Set(nameof(EndTime), ref _EndTime, value); } - } - - private double _AverageSum = 10; - public double AverageSum - { - get { return _AverageSum; } - set { Set(nameof(AverageSum), ref _AverageSum, value); } - } - - private string _ChangeRGB = "FF0000"; - public string ChangeRGB - { - get { return _ChangeRGB; } - set { Set(nameof(ChangeRGB), ref _ChangeRGB, value); - DrawChangeRGB.Color = (Color)ColorConverter.ConvertFromString("#" + value); - } - } - - private string _EndRGB = "0000FF"; - public string EndRGB - { - get { return _EndRGB; } - set { Set(nameof(EndRGB), ref _EndRGB, value); - DrawEndRGB.Color = (Color)ColorConverter.ConvertFromString("#" + value); - } - } - - private SolidColorBrush _DrawChangeRGB = new SolidColorBrush(Color.FromRgb(0xFF, 0x00, 0x00)); - public SolidColorBrush DrawChangeRGB - { - get - { - return _DrawChangeRGB; - } - set - { - Set(nameof(DrawChangeRGB), ref _DrawChangeRGB, value); - - } - } - - private SolidColorBrush _DrawEndRGB = new SolidColorBrush(Color.FromRgb(0x00, 0x00, 0xFF)); - public SolidColorBrush DrawEndRGB - { - get - { - return _DrawEndRGB; - } - set - { - Set(nameof(DrawEndRGB), ref _DrawEndRGB, value); - - } - } - - #endregion - - //灯带--按照经纬度变换灯光 - private ICommand _SetHorseRaceLampCommand; - public ICommand SetHorseRaceLampCommand - { - get - { - return _SetHorseRaceLampCommand ?? (_SetHorseRaceLampCommand = new RelayCommand(async () => - { - float CopterDirection =90- (float)BeltDirection ; - - //必须大于1架 - if (_copterManager.SelectedCopters.Count() <= 1) - { - Alert.Show("必须选中多于一架飞机"); - return; - } - if (EndTime<= BeginTime) - { - Alert.Show("结束时间必须大于开始时间(非持续时间!)"); - return; - } - - - //旋转飞机矩阵 - if (CopterDirection != 0) - { - LevelRotateCommand.Execute(CopterDirection); - await Task.Delay(100); - } - - double minLat, maxLat; - double minLng, maxLng; - - - - //所以选中飞行当前任务信息 - var selectCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos.FindAll(delegate (FlightTaskSingleCopterInfo p) - { - return _copterManager.SelectedCopters.Contains(p.Copter); - }); - - minLat = selectCopterInfos.Min(c => c.TargetLat); - maxLat = selectCopterInfos.Max(c => c.TargetLat); - minLng = selectCopterInfos.Min(c => c.TargetLng); - maxLng = selectCopterInfos.Max(c => c.TargetLng); - - double averagelngCount = maxLng - minLng; - - foreach (var copterInfo in selectCopterInfos) - { - double interval = copterInfo.TargetLng - minLng; - double leddelay = 0; - int time = (int)(interval / (averagelngCount / AverageSum)); - LEDInfo led = new LEDInfo(); - led.LEDMode = 0; - led.Delay = BeginTime + time * (EndTime - BeginTime) / AverageSum; - leddelay += led.Delay; - led.LEDRGB = ChangeRGB; - copterInfo.AddLEDInfo(led); - - //跑马灯变化后改变颜色 效果类似灯带 - if (EndRGB != "") - { - LEDInfo endLed = new LEDInfo(); - endLed.LEDMode = 0; - endLed.Delay = (EndTime - BeginTime) / AverageSum; - if (EndRGB == "0") - endLed.LEDRGB = copterInfo.LEDInfos[copterInfo.LEDInfos.Count - 2].LEDRGB; - else - endLed.LEDRGB = EndRGB; - copterInfo.AddLEDInfo(endLed); - - //为了每架飞机结束灯光时间一致,以便下次再做跑马灯之类的效果有个一致的起始时间,再增加一个 - //改为专门的按钮功能=AlignmentTimeCommand - /* - leddelay += endLed.Delay; - LEDInfo endLed1 = new LEDInfo(); - endLed1.LEDMode = 0; - endLed1.Delay = (EndTime - BeginTime)-leddelay; - if (EndRGB == "0") - endLed1.LEDRGB = copterInfo.LEDInfos[copterInfo.LEDInfos.Count - 2].LEDRGB; - else - endLed1.LEDRGB = EndRGB; - copterInfo.AddLEDInfo(endLed1); - */ - } - } - - await Task.Delay(100); - - - //旋转飞机矩阵 - if (CopterDirection != 0) - LevelRotateCommand.Execute(0-CopterDirection); - - - - - })); - } - } - - - private double _StrokesTime = 1; - public double StrokesTime - { - get { return _StrokesTime; } - set { Set(nameof(StrokesTime), ref _StrokesTime, value); } - } - - private double _IntervalTime = 0.1; - public double IntervalTime - { - get { return _IntervalTime; } - set { Set(nameof(IntervalTime), ref _IntervalTime, value); } - } - - private double _SingleNum = 1; - public double SingleNum - { - get { return _SingleNum; } - set { Set(nameof(SingleNum), ref _SingleNum, value); } - } - - private string _StrokesRGB = "FFFFFF"; - public string StrokesRGB - { - get { return _StrokesRGB; } - set { Set(nameof(StrokesRGB), ref _StrokesRGB, value); } - } - - //跑马灯(笔画顺序用)--按照选择航点顺序变换灯光 - private ICommand _SetStrokesLampCommamd; - public ICommand SetStrokesLampCommamd - { - get - { - return _SetStrokesLampCommamd ?? (_SetStrokesLampCommamd = new RelayCommand(async () => - { - //必须大于1架 - if (_copterManager.SelectedCopters.Count() <= 1) - return; - - - double curTime = StrokesTime; - int curcount = 1; - foreach (var copter in _copterManager.SelectedCopters) - { - if (curcount > SingleNum) - { - curTime += IntervalTime; - curcount = 1; - } - - - var copterInfo = _flightTaskManager.SelectedTask.SingleCopterInfos.FirstOrDefault(c=>c.Copter == copter); - - LEDInfo led = new LEDInfo(); - led.LEDMode = 0; - led.Delay = curTime; - led.LEDRGB = ChangeRGB; - copterInfo.AddLEDInfo(led); - - if (EndRGB != "") - { - LEDInfo endLed = new LEDInfo(); - endLed.LEDMode = 0; - endLed.Delay = IntervalTime; - if (EndRGB == "0") - endLed.LEDRGB = copterInfo.LEDInfos[copterInfo.LEDInfos.Count - 2].LEDRGB; - else - endLed.LEDRGB = EndRGB; - copterInfo.AddLEDInfo(endLed); - } - - curcount++; - } - - await Task.Delay(100); - })); - } - } - - - - private double _AlignmentTime = 10; - public double AlignmentTime - { - get { return _AlignmentTime; } - set { Set(nameof(AlignmentTime), ref _AlignmentTime, value); } - } - - - - - #region 渐变灯参数 - private double _GradientRampTime = 1; - public double GradientRampTime - { - get { return _GradientRampTime; } - set { Set(nameof(GradientRampTime), ref _GradientRampTime, value); } - } - - private string _RightRGB = "FFFFFF"; - public string RightRGB - { - get { return _RightRGB; } - set { Set(nameof(RightRGB), ref _RightRGB, value); - DrawRightRGB.Color = (Color)ColorConverter.ConvertFromString("#" + value); - } - } - - private string _LeftRGB = "FFFFFF"; - public string LeftRGB - { - get { return _LeftRGB; } - set { Set(nameof(LeftRGB), ref _LeftRGB, value); - DrawLeftRGB.Color = (Color)ColorConverter.ConvertFromString("#" + value); - } - } - - - - //渐变方向,默认从左到右 - private double _GradualDirection = 90; - public double GradualDirection - { - get { return _GradualDirection; } - set { Set(nameof(GradualDirection), ref _GradualDirection, value); } - } - - - - - - private SolidColorBrush _DrawLeftRGB = new SolidColorBrush(Color.FromRgb(0xFF, 0xFF, 0xFF)); - public SolidColorBrush DrawLeftRGB - { - get - { - return _DrawLeftRGB; - } - set - { - Set(nameof(DrawLeftRGB), ref _DrawLeftRGB, value); - - } - } - - private SolidColorBrush _DrawRightRGB = new SolidColorBrush(Color.FromRgb(0xFF, 0xFF, 0xFF)); - public SolidColorBrush DrawRightRGB - { - get - { - return _DrawRightRGB; - } - set - { - Set(nameof(DrawRightRGB), ref _DrawRightRGB, value); - - } - } - - - private ICommand _QueryMAXTimeCommand; - public ICommand QueryMAXTimeCommand - { - get - { - return _QueryMAXTimeCommand ?? (_QueryMAXTimeCommand = new RelayCommand(async => - { - //所以选中飞行当前任务信息 - var selectCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos.FindAll(delegate (FlightTaskSingleCopterInfo p) - { - return _copterManager.SelectedCopters.Contains(p.Copter); - }); - double maxtime = 0.0f; - string maxid="" ; - foreach (var copterInfo in selectCopterInfos) - { - // AlignmentTime - double leddelay = 0; - foreach (LEDInfo led in copterInfo.LEDInfos) - { - leddelay += led.Delay; - } - if (leddelay > maxtime) - { - maxtime = leddelay; - maxid = copterInfo.Copter.Id; - } - } - - - Alert.Show($"ID={maxid}飞机的航点灯光时长为{maxtime}秒", "提示", MessageBoxButton.OK, MessageBoxImage.Information); - - - })); - } - } - - - - - - - - private ICommand _AlignmentTimeCommand; - public ICommand AlignmentTimeCommand - { - get - { - return _AlignmentTimeCommand ?? (_AlignmentTimeCommand = new RelayCommand(async => - { - //所以选中飞行当前任务信息 - var selectCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos.FindAll(delegate (FlightTaskSingleCopterInfo p) - { - return _copterManager.SelectedCopters.Contains(p.Copter); - }); - - foreach (var copterInfo in selectCopterInfos) - { - // AlignmentTime - double leddelay = 0; - foreach (LEDInfo led in copterInfo.LEDInfos) - { - leddelay += led.Delay; - } - if (leddelay > AlignmentTime) - { - Alert.Show($"{AlignmentTime}秒对齐时间不够,ID={copterInfo.Copter.Id}飞机的航点灯光时长为{leddelay}秒", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); - return; - } - - } - - - - - - foreach (var copterInfo in selectCopterInfos) - { - - double leddelay = 0; - foreach (LEDInfo led in copterInfo.LEDInfos) - { - leddelay += led.Delay; - } - if (leddelay<= AlignmentTime) - { - LEDInfo endLed = new LEDInfo(); - endLed.LEDMode = 0; - endLed.Delay = AlignmentTime - leddelay; - if (copterInfo.LEDInfos.Count > 0) - endLed.LEDRGB = copterInfo.LEDInfos[copterInfo.LEDInfos.Count - 1].LEDRGB; - else - endLed.LEDRGB = "FFFFFF"; - - copterInfo.AddLEDInfo(endLed); - } - } - })); - } - } - - - - - - - #endregion - - //渐变色 - private ICommand _SetGradientRampCommand; - public ICommand SetGradientRampCommand - { - get - { - return _SetGradientRampCommand ?? (_SetGradientRampCommand = new RelayCommand(async () => - { - - float CopterDirection = 90 - (float)GradualDirection; - //渐变需要2架以上 - if (_copterManager.SelectedCopters.Count() <= 1) - return; - - List TempSingleCopterInfos = new List(); - - //旋转飞机矩阵 - if (CopterDirection != 0) - { - - var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); - if (_flightTaskManager.SelectedTask != null) - { - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - //得到每个选择的飞机 - selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - //根据飞机查找任务中的位置信息 - foreach (var capter in _copterManager.SelectedCopters) - { - //如果是选择的那架飞机 - if (capter == selectedCopter) - { - FlightTaskSingleCopterInfo vFlightTaskSingleCopterInfo = new FlightTaskSingleCopterInfo(capter); - vFlightTaskSingleCopterInfo.TargetLng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; - vFlightTaskSingleCopterInfo.TargetAlt = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt; - vFlightTaskSingleCopterInfo.TargetLat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; - TempSingleCopterInfos.Add(vFlightTaskSingleCopterInfo); - } - - - } - } - } - - - - - LevelRotateCommand.Execute(CopterDirection); - await Task.Delay(100); - } - - - - - - - double minLat, maxLat; - double minLng, maxLng; - - - //所以选中飞行当前任务信息 - var selectCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos.FindAll(delegate (FlightTaskSingleCopterInfo p) - { - return _copterManager.SelectedCopters.Contains(p.Copter); - }); - - minLat = selectCopterInfos.Min(c => c.TargetLat); - maxLat = selectCopterInfos.Max(c => c.TargetLat); - minLng = selectCopterInfos.Min(c => c.TargetLng); - maxLng = selectCopterInfos.Max(c => c.TargetLng); - - double averagelngCount = maxLng - minLng; - - Color rightColor = (Color)ColorConverter.ConvertFromString("#" + RightRGB); - Color leftColor = (Color)ColorConverter.ConvertFromString("#" + LeftRGB); - - int diffR = rightColor.R - leftColor.R; - int diffG = rightColor.G - leftColor.G; - int diffB = rightColor.B - leftColor.B; - - foreach (var copterInfo in selectCopterInfos) - { - double interval = copterInfo.TargetLng - minLng; - double percent = (interval / averagelngCount ); - - int R = (int)(diffR * percent) + leftColor.R; - int G = (int)(diffG * percent) + leftColor.G; - int B = (int)(diffB * percent) + leftColor.B; - Color c = Color.FromRgb((byte)R, (byte)G, (byte)B); - - LEDInfo led = new LEDInfo(); - led.LEDMode = 0; - led.Delay = GradientRampTime; - led.LEDRGB = "000000"; - - //led.LEDRGB = Convert.ToString(R, 16) + Convert.ToString(G, 16) + Convert.ToString(B, 16); - - try - { - led.LEDRGB = R.ToString("X2") + G.ToString("X2") + B.ToString("X2"); - - } - catch (Exception) - { - - //throw; - } - - - copterInfo.AddLEDInfo(led); - } - - await Task.Delay(100); - - //使用之前保存的位置回到飞机原来的位置,不使用旋转因为转回去和原来的位置有一点点偏差 - if (CopterDirection != 0) - { - - int j = 0; - var selectedCopter1 = _copterManager.SelectedCopters.FirstOrDefault(); - if (_flightTaskManager.SelectedTask != null) - { - for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) - { - selectedCopter1 = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; - foreach (var capter in _copterManager.SelectedCopters) - { - if (capter == selectedCopter1) - { - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = TempSingleCopterInfos[j].TargetLat; - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = TempSingleCopterInfos[j].TargetLng; - _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt = TempSingleCopterInfos[j].TargetAlt; - j++; - - } - - - } - } - } - // LevelRotateCommand.Execute(0 - CopterDirection); - } - - })); - } - } - } -} +using Plane.Collections; +using Plane.Copters; +using Plane.FormationCreator.Formation; +using GalaSoft.MvvmLight; +using GalaSoft.MvvmLight.CommandWpf; +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using Plane.Geography; +using Plane.Windows.Messages; +using System.Windows; +using System.Windows.Media; + +namespace Plane.FormationCreator.ViewModels +{ + public class ModifyTaskViewModel : ViewModelBase + { + public ModifyTaskViewModel(FlightTaskManager flightTaskManager, CopterManager copterManager) + { + _flightTaskManager = flightTaskManager; + _copterManager = copterManager; + //_flightTaskManager.SingleCopterInfoChanged += (sender, e) => + //{ + // var changedSingleInfo = e.ChangedSingleCopterInfo; + // if (changedSingleInfo.Copter == _copterManager.SelectedCopters.FirstOrDefault()) + // { + // if (changedSingleInfo is FlyToFlightTaskSingleCopterInfo) + // { + // FlyToLat = changedSingleInfo.TargetLat; + // FlyToLng = changedSingleInfo.TargetLng; + // FlyToAlt = changedSingleInfo.TargetAlt; + // } + // } + //}; + // TODO: 王海, 20150803, 没什么问题就把这段以及 FlyToLat 等属性删了。 + //_flightTaskManager.PropertyChanged += (sender, e) => + //{ + // switch (e.PropertyName) + // { + // case nameof(FlightTaskManager.SelectedTask): + // var currentCopter = _copterManager.SelectedCopters.FirstOrDefault(); + // if (currentCopter != null) + // { + // var selectedTask = _flightTaskManager.SelectedTask; + // if (selectedTask != null) + // { + // var singleCopterInfo = selectedTask.SingleCopterInfos.Find(i => i.Copter == currentCopter); + // if (singleCopterInfo is FlyToFlightTaskSingleCopterInfo) + // { + // var info = singleCopterInfo as FlyToFlightTaskSingleCopterInfo; + // this.FlyToLat = info.TargetLat; + // this.FlyToLng = info.TargetLng; + // this.FlyToAlt = info.TargetAlt; + // } + // } + // } + // break; + // default: + // break; + // } + //}; + //_copterManager.SelectedCoptersChanged += (sender, e) => + //{ + // // TODO: 王海, 20150731, 处理多选飞行器时的情况。 + // var selectedCopters = _copterManager.SelectedCopters; + // if (selectedCopters.Count() > 1) + // { + // CanModifySingleCopterInfo = false; + // return; + // } + + // CanModifySingleCopterInfo = true; + + // var currentCopter = e.AddedCopters.FirstOrDefault(); + // if (currentCopter != null) + // { + // var selectedTask = _flightTaskManager.SelectedTask; + // if (selectedTask != null) + // { + // var singleCopterInfo = selectedTask.SingleCopterInfos.Find(i => i.Copter == currentCopter); + // if (singleCopterInfo is FlyToFlightTaskSingleCopterInfo) + // { + // var info = singleCopterInfo as FlyToFlightTaskSingleCopterInfo; + // this.FlyToLat = info.TargetLat; + // this.FlyToLng = info.TargetLng; + // this.FlyToAlt = info.TargetAlt; + // } + // } + // } + //}; + //this.PropertyChanged += (sender, e) => + //{ + // switch (e.PropertyName) + // { + // case nameof(FlyToLat): + // InvokeForSelectedSingleCopterInfos(info => info.TargetLat = FlyToLat); + // break; + // case nameof(FlyToLng): + // InvokeForSelectedSingleCopterInfos(info => info.TargetLng = FlyToLng); + // break; + // case nameof(FlyToAlt): + // InvokeForSelectedSingleCopterInfos(info => info.TargetAlt = FlyToAlt); + // break; + // case nameof(StaggerRoutes): + // { + // var modifyingTask = _flightTaskManager.SelectedTask as FlyToFlightTask; + // if (modifyingTask != null) + // { + // modifyingTask.StaggerAlt = this.StaggerRoutes; + // } + // } + // break; + // default: + // break; + // } + //}; + } + + private FlightTaskManager _flightTaskManager; + private CopterManager _copterManager; + public FlightTaskManager FlightTaskManager { get { return _flightTaskManager; } } + public CopterManager CopterManager { get { return _copterManager; } } + + //private void InvokeForSelectedSingleCopterInfos(Action action) + //{ + // var modifyingTask = _flightTaskManager.SelectedTask as FlyToFlightTask; + // if (modifyingTask != null && _copterManager.SelectedCopters.Count() == 1) // 王海, 20150731, 目前不处理多选的情况。 + // { + // modifyingTask.FlyToFlightTaskSingleCopterInfos + // .Where(i => _copterManager.SelectedCopters.FirstOrDefault() == i.Copter) + // .ForEach(action); + + // // TODO: 王海, 20150731, 添加同时改多个 SingleCopterInfo 的程序。 + // //.Where(i => _copterManager.SelectedCopters.Contains(i.Copter)) + // } + //} + + private bool _CanModifySingleCopterInfo = true; + public bool CanModifySingleCopterInfo + { + get { return _CanModifySingleCopterInfo; } + set { Set(nameof(CanModifySingleCopterInfo), ref _CanModifySingleCopterInfo, value); } + } + +// private double _Distancevalue; +// public double Distancevalue +// { +// get { return _Distancevalue; } +// set { Set(nameof(Distancevalue), ref _Distancevalue, value); } +// } + + + private float _Modialtvalue; + public float Modialtvalue + { + get { return _Modialtvalue; } + set { Set(nameof(Modialtvalue), ref _Modialtvalue, value); } + } + + + private int _txtStarindex=0; + public int txtStarindex + { + get { return _txtStarindex; } + set { Set(nameof(txtStarindex), ref _txtStarindex, value); } + } + + private int _txtendindex=0; + public int txtendindex + { + get { return _txtendindex; } + set { Set(nameof(txtendindex), ref _txtendindex, value); } + } + + private float _directionvalue = 0; + public float directionvalue + { + get { return _directionvalue; } + set { Set(nameof(directionvalue), ref _directionvalue, value); } + } + + private float _directionvalueall = 0; + public float directionvalueall + { + get { return _directionvalueall; } + set { Set(nameof(directionvalueall), ref _directionvalueall, value); } + } + + + private int _taskstartno = 0; + public int taskstartno + { + get { return _taskstartno; } + set { Set(nameof(taskstartno), ref _taskstartno, value); } + } + + private int _taskendno = 0; + public int taskendno + { + get { return _taskendno; } + set { Set(nameof(taskendno), ref _taskendno, value); } + } + + + private float _taskdirection = 0; + public float taskdirection + { + get { return _taskdirection; } + set { Set(nameof(taskdirection), ref _taskdirection, value); } + } + + + + + + + private double _FlyToLat; + public double FlyToLat + { + get { return _FlyToLat; } + set { Set(nameof(FlyToLat), ref _FlyToLat, value); } + } + + private double _FlyToLng; + public double FlyToLng + { + get { return _FlyToLng; } + set { Set(nameof(FlyToLng), ref _FlyToLng, value); } + } + + private float _FlyToAlt; + public float FlyToAlt + { + get { return _FlyToAlt; } + set { Set(nameof(FlyToAlt), ref _FlyToAlt, value); } + } + + private bool _StaggerRoutes; + public bool StaggerRoutes + { + get { return _StaggerRoutes; } + set { Set(nameof(StaggerRoutes), ref _StaggerRoutes, value); } + } + + private bool _OnlySelected = false; + public bool OnlySelected + { + get { return _OnlySelected; } + set { Set(nameof(OnlySelected), ref _OnlySelected, value); } + } + + + + /// + /// 垂直旋转多个任务 + /// + private ICommand _MitTaskVrotationCommand; + public ICommand MitTaskVrotationCommand + + { + get + { + return _MitTaskVrotationCommand ?? (_MitTaskVrotationCommand = new RelayCommand(async => + { + + + double lngsum = 0; + double latsum = 0; + double altsum = 0; + int selectcount = 0; + // double centlng = 0; + double centlat = 0; + double centalt = 0; + + + + int _taskstartno = 0; + int _taskendno = 0; + + if (taskstartno == 0) + _taskstartno = 0; + else _taskstartno = taskstartno - 1; + + if (taskendno == 0) + _taskendno = _flightTaskManager.Tasks.Count()-1; + else _taskendno = taskendno - 1; + + + + + + + //计算旋转中心轴 + for (int i = _taskstartno ; i <= _taskendno; i++) + { + if ((_flightTaskManager.Tasks[i].TaskType == FlightTaskType.TakeOff) || (_flightTaskManager.Tasks[i].TaskType == FlightTaskType.Land)) + continue; + + for (int j = 0; j < _flightTaskManager.Tasks[i].SingleCopterInfos.Count; j++) + { + + lngsum += _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng; + latsum += _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat; + altsum += _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt; + selectcount++; + } + } + if (selectcount > 0) + { + // centlng = lngsum / selectcount; + centlat = latsum / selectcount; + centalt = altsum / selectcount; + } + + + + //////////计算旋转,经测试用下面的函数组合计算比较准确 + double k = (double)taskdirection / 180 * Math.PI; + double dx = 0; + double dy = 0; + double ax = 0; + double ay = 0; + double tlng = 0; + double tlat = 0; + + + for (int i = _taskstartno; i <= _taskendno; i++) + { + if ((_flightTaskManager.Tasks[i].TaskType == FlightTaskType.TakeOff) || (_flightTaskManager.Tasks[i].TaskType == FlightTaskType.Land)) + continue; + + for (int j = 0; j < _flightTaskManager.Tasks[i].SingleCopterInfos.Count; j++) + { + + + tlng = _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng; + tlat = _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat; + //纬度方向距离(单位m) + ax = CalculationLogLatDistance.GetDistanceOne(tlng, centlat, tlng, tlat) * 1000; + //方向角用于正负,0为正,180为负 + CalculationLogLatDistance.MyLatLng mypos1, mypos2; + mypos1 = new CalculationLogLatDistance.MyLatLng(tlng, centlat); + mypos2 = new CalculationLogLatDistance.MyLatLng(tlng, tlat); + double lpAzimuth = CalculationLogLatDistance.getAngle(mypos1, mypos2); + if (lpAzimuth > 90) + ax = -ax; + + + //高度方向距离(单位m) + ay = (_flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt - centalt); + + dx = ax * Math.Cos(k) + ay * Math.Sin(k); + dy = -ax * Math.Sin(k) + ay * Math.Cos(k); + + //新高度(米) + _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt = (float)(centalt + dy); + //计算新纬度 + double lng2 = 0; + double lat2 = 0; + if (dx < 0) + lpAzimuth = 180; + else + lpAzimuth = 0; + dx = Math.Abs(dx); + + CalculationLogLatDistance.ConvertDistanceToLogLat( + tlng, + centlat, //旋转中心纬度 + dx / 1000, //新距离 + lpAzimuth, //方向垂直 + out lng2, + out lat2); + _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat = lat2; + + } + + + } + // await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 + })); + } + } + + private ICommand _ShowallTaskpointCommand; + public ICommand ShowallTaskpointCommand + + { + get + { + return _ShowallTaskpointCommand ?? (_ShowallTaskpointCommand = new RelayCommand(async => + { + MapManager _mapManager = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance(); + _mapManager.MapView.ShowAllWaypoint(); + + //_flightTaskManager.SelectedTask = null; + })); + } + } + private void GetMaxMissions() + { + int missiontmp = 0; + + string maxCopterName = ""; + int maxmission = 0; + string minCopterName = ""; + int minmission = 65535; + + ICopter vcopter = _copterManager.SelectedCopters.FirstOrDefault(); + if (vcopter == null) + { + Alert.Show($"请先选中飞机!", "提示", MessageBoxButton.OK, MessageBoxImage.Information); + return; + } + + + int coptercount = _copterManager.Copters.Count; + + + for (int i = 0; i < coptercount; i++) + { + missiontmp = 0; + + var currcopter = _copterManager.Copters[i]; + + foreach (var capter in _copterManager.SelectedCopters) + { + if (currcopter == capter) + { + for (int j = 0; j < _flightTaskManager.Tasks.Count; j++) + { + missiontmp++; + missiontmp += _flightTaskManager.Tasks[j].SingleCopterInfos[i].LEDInfos.Count(); + } + + if (missiontmp > maxmission) + { + maxCopterName = _copterManager.Copters[i].Name; + maxmission = missiontmp; + } + + if (missiontmp < minmission) + { + minCopterName = _copterManager.Copters[i].Name; + minmission = missiontmp; + } + + } + + } + + + + + + } + if (maxmission>256) + Alert.Show($"飞机:[ {maxCopterName} ] 有最多任务数量:{maxmission} 已超出256的最大航点限制,请减少灯光; \n飞机:[ {minCopterName} ] 有最少任务数量:{minmission}", "提示", MessageBoxButton.OK, MessageBoxImage.Information); + else + Alert.Show($"飞机:[ {maxCopterName} ] 有最多任务数量:{maxmission} \n飞机:[ {minCopterName} ] 有最少任务数量:{minmission} \n (航点加灯光不能超过256个任务)", "提示", MessageBoxButton.OK, MessageBoxImage.Information); + return ; + } + + private ICommand _CheckMissionCountCommand; + public ICommand CheckMissionCountCommand + + { + get + { + return _CheckMissionCountCommand ?? (_CheckMissionCountCommand = new RelayCommand(async => + { + GetMaxMissions(); + + })); + } + } + + + + //调整所有任务经度 + private ICommand _ModiAllPosCommand; + public ICommand ModiAllPosCommand + { + get + { + return _ModiAllPosCommand ?? (_ModiAllPosCommand = new RelayCommand( cModialtvalue => + { + if (_flightTaskManager.Tasks.Count < 2) return; + + float lowalt = 200; + + int itaskendno = taskendno; + if (taskendno == 0) itaskendno = _flightTaskManager.Tasks.Count - 1; + else itaskendno = taskendno - 1; + if (itaskendno > _flightTaskManager.Tasks.Count-1) itaskendno = _flightTaskManager.Tasks.Count-1; + // for (int i = taskstartno; i < itaskendno; i++) + + int _startindex = taskstartno; + if (taskstartno == 0) + _startindex = 0; + else + _startindex = taskstartno - 1; + + int _endindex = itaskendno; + + + + int lowtask = 0; + int lowCopter = 0; + + if ((txtStarindex != 0) && (txtendindex != 0)) + { + _startindex = txtStarindex; + _endindex = txtendindex; + } + + for (int i = _startindex; i <= _endindex; i++) + { + + if ((_flightTaskManager.Tasks[i].TaskType == FlightTaskType.TakeOff)|| (_flightTaskManager.Tasks[i].TaskType == FlightTaskType.Land)) + continue; + + + for (int j = 0; j < _flightTaskManager.Tasks[i].SingleCopterInfos.Count; j++) + { + Tuple targetLatLng = new Tuple(0, 0); + + targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat, + _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng, + directionvalueall, + cModialtvalue + ); + _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat = targetLatLng.Item1; + _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng = targetLatLng.Item2; + } + } + Alert.Show("指定步骤任务位置已向" + directionvalueall + "度改变" + cModialtvalue + "米,注意是否有障碍物!"); + + })); + } + } + + + private ICommand _LevelAverageCommand; + public ICommand LevelAverageCommand + { + get + { + return _LevelAverageCommand ?? (_LevelAverageCommand = new RelayCommand(async => + { + double maxlng = 0; + double minlng = 0; + double tlng = 0; + double avgl = 0; + + if (_copterManager.SelectedCopters.Count() > 2) + { + List selectTaskInfos = new List(); + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + + if (_copterManager.SelectedCopters.Contains(_flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter)) + selectTaskInfos.Add(_flightTaskManager.SelectedTask.SingleCopterInfos[i]); + } + selectTaskInfos.Sort((x, y) => x.TargetLng.CompareTo(y.TargetLng)); + minlng = selectTaskInfos[0].TargetLng; + maxlng = selectTaskInfos[selectTaskInfos.Count - 1].TargetLng; + tlng = (maxlng - minlng) / (selectTaskInfos.Count - 1); + + for (int i = 0; i < selectTaskInfos.Count; i++) + { + selectTaskInfos[i].TargetLng = minlng + i * tlng; + } + } + + + /* + if (Alert.Show("本操作将导致飞机位置重新排列,编号最小的飞机在最左边,您确定要继续吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning) + == MessageBoxResult.OK) + { + + + + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + bool copterisselect; + int selectednumber = _copterManager.SelectedCopters.Count() - 1; + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + copterisselect = false; + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + copterisselect = true; + + } + if (copterisselect) + { + + tlng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; + if (minlng == 0) + minlng = tlng; + if (tlng > maxlng) + maxlng = tlng; + else if (tlng < minlng) + minlng = tlng; + + } + } + avgl = (maxlng - minlng) / selectednumber; + int coptnum = 0; + + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + copterisselect = false; + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + copterisselect = true; + + } + if (copterisselect) + { + + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = minlng + avgl * coptnum; + coptnum++; + + } + } + + } + + */ + /////////////////////// + + // await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 + + })); + } + } + + + + + private ICommand _VerticlAverageCommand; + public ICommand VerticlAverageCommand + { + get + { + return _VerticlAverageCommand ?? (_VerticlAverageCommand = new RelayCommand(async => + { + double maxlat = 0; + double tlat = 0; + double minlat = 0; + + double avgl = 0; + + if (_copterManager.SelectedCopters.Count() > 2) + { + List selectTaskInfos = new List(); + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + + if (_copterManager.SelectedCopters.Contains(_flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter)) + selectTaskInfos.Add(_flightTaskManager.SelectedTask.SingleCopterInfos[i]); + } + selectTaskInfos.Sort((x, y) => x.TargetLat.CompareTo(y.TargetLat)); + minlat = selectTaskInfos[0].TargetLat; + maxlat = selectTaskInfos[selectTaskInfos.Count - 1].TargetLat; + tlat = (maxlat - minlat) / (selectTaskInfos.Count - 1); + + for (int i = 0; i < selectTaskInfos.Count; i++) + { + selectTaskInfos[i].TargetLat = minlat + i * tlat; + } + } + + /* + if (Alert.Show("本操作将导致飞机位置重新排列,编号最小的飞机在最上边,您确定要继续吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning) + == MessageBoxResult.OK) + { + + ////////////////////// + + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + if (_flightTaskManager.SelectedTask != null) + { + bool copterisselect; + int selectednumber = _copterManager.SelectedCopters.Count() - 1; + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + copterisselect = false; + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + copterisselect = true; + + } + if (copterisselect) + { + + tlat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; + if (minlat == 0) + minlat = tlat; + if (tlat > maxlat) + maxlat = tlat; + else if (tlat < minlat) + minlat = tlat; + + } + } + avgl = (maxlat - minlat) / selectednumber; + int coptnum = 0; + + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + copterisselect = false; + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + copterisselect = true; + + } + if (copterisselect) + { + + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = maxlat - avgl * coptnum; + coptnum++; + + } + } + + /////////////////////// + + // await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 + } + } + */ + })); + } + } + + private ICommand _BackTakeOffPointCommand; + public ICommand BackTakeOffPointCommand + { + get + { + return _BackTakeOffPointCommand ?? (_BackTakeOffPointCommand = new RelayCommand(async => + { + foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos) + { + info.TargetLat = info.Copter.Latitude; + info.TargetLng = info.Copter.Longitude; + } + })); + } + } + private ICommand _ImportWayPointCommand; + public ICommand ImportWayPointCommand + { + get + { + return _ImportWayPointCommand ?? (_ImportWayPointCommand = new RelayCommand(async => + { + var dialog = new OpenFileDialog + { + DefaultExt = "json", + Filter = "json文件|*.json" + }; + if (dialog.ShowDialog() == true) + { + var tasksText = File.ReadAllText(dialog.FileName); + _flightTaskManager.ImportWaypoint(tasksText); + + } + })); + } + } + + private ICommand _ImportBlenderWayPointCommand; + public ICommand ImportBlenderWayPointCommand + { + get + { + return _ImportBlenderWayPointCommand ?? (_ImportBlenderWayPointCommand = new RelayCommand(async => + { + var dialog = new OpenFileDialog + { + DefaultExt = "txt", + Filter = "航点文件(*.txt,*.svg,*.obj) |*.txt;*.svg;*.obj" // "图片文件(*.jpg, *.gif, *.bmp, *.png) | *.jpg; *.gif; *.bmp; *.png" + }; + + if (dialog.ShowDialog() == true) + { + string extname=Path.GetExtension(dialog.FileName); + if (extname == ".txt") + { + var tasksText = File.ReadAllText(dialog.FileName); + _flightTaskManager.ImportC4DFlytoTask(tasksText); + if (_copterManager.FC_VER_NO >= 3) + Alert.Show($"导入的第一个航点默认为0,需要重新计算时间", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); + else + _flightTaskManager.SetAllTaskFlytime(); + + } + else + if ((extname == ".svg")|| (extname == ".obj")) + { + _flightTaskManager.ImportDlltoTask(dialog.FileName); + }; + + + //_flightTaskManager.ImportBlenderFlyToTask(tasksText); + } + })); + } + } + + + + + + private ICommand _ImportBlenderrCopterPosCommand; + public ICommand ImportBlenderCopterPosCommand + { + get + { + return _ImportBlenderrCopterPosCommand ?? (_ImportBlenderrCopterPosCommand = new RelayCommand(async => + { + + //有不是虚拟飞机的直接退出 + foreach (var copter in _copterManager.Copters) + { + if (!(copter is FakeCopter)) + { + Alert.Show($"导入起飞位置只能用于虚拟飞机,{copter.Id}不是虚拟飞机", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); + return; + } + } + + + var dialog = new OpenFileDialog + { + DefaultExt = "txt", + Filter = "航点文件(*.txt,*.svg,*.obj) |*.txt;*.svg;*.obj" // "图片文件(*.jpg, *.gif, *.bmp, *.png) | *.jpg; *.gif; *.bmp; *.png" + }; + + if (dialog.ShowDialog() == true) + { + string extname = Path.GetExtension(dialog.FileName); + if (extname == ".txt") + { + var tasksText = File.ReadAllText(dialog.FileName); + _flightTaskManager.ImportC4DFlytoVCopter(tasksText); + } + else + if ((extname == ".svg") || (extname == ".obj")) + { + _flightTaskManager.ImportDlltoVCopter(dialog.FileName); + }; + } + })); + } + } + + + + + + + private ICommand _ExportWayPointCommand; + public ICommand ExportWayPointCommand + { + get + { + return _ExportWayPointCommand ?? (_ExportWayPointCommand = new RelayCommand(async => + { + + // _flightTaskManager.OptimizeRouteNew(); + // return; + var dialog = new SaveFileDialog + { + DefaultExt = "txt", + Filter = "文本文件|*.txt" + }; + if (dialog.ShowDialog() == true) + { + + string exportedText = _flightTaskManager.ExportC4DFlytoTask(); + + File.WriteAllText(dialog.FileName, exportedText); + } + })); + } + } + + + private ICommand _AutoWayPointTmCommand; + public ICommand AutoWayPointTmCommand + { + get + { + return _AutoWayPointTmCommand ?? (_AutoWayPointTmCommand = new RelayCommand(async => + { + _flightTaskManager.SetTaskFlytime(_flightTaskManager.SelectedTaskIndex); + })); + } + } + + + + private ICommand _AutoWayPointAllTmCommand; + public ICommand AutoWayPointAllTmCommand + { + get + { + return _AutoWayPointAllTmCommand ?? (_AutoWayPointAllTmCommand = new RelayCommand(async => + { + + if (Alert.Show("本操作将导致除2号任务以外所有任务飞行时间重新计算(不修改悬停时间),您确定要继续吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning) + == MessageBoxResult.OK) + { + _flightTaskManager.SetAllTaskFlytime(); + } + })); + } + } + + private ICommand _CheckTmCommand; + public ICommand CheckTmCommand + { + get + { + return _CheckTmCommand ?? (_CheckTmCommand = new RelayCommand(async => + { + + if (Alert.Show("本操作将检测2号任务以后所有任务飞行时间是否合理,您确定要继续吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning) + == MessageBoxResult.OK) + { + _flightTaskManager.CheckAllTaskFlytime(); + } + })); + } + } + + private ICommand _OptimizeRouteCommandRet; + public ICommand OptimizeRouteCommandRet + { + get + { + return _OptimizeRouteCommandRet ?? (_OptimizeRouteCommandRet = new RelayCommand(async => + { + _flightTaskManager.OptimizeRouteMeter(false,false); //采用米计算逻辑和OptimizeRouteNew一样 + })); + } + } + + + private ICommand _OptimizeRouteCommand3D; + public ICommand OptimizeRouteCommand3D + { + get + { + return _OptimizeRouteCommand3D ?? (_OptimizeRouteCommand3D = new RelayCommand(async => + { + //_flightTaskManager.OptimizeRoute2(); + // _flightTaskManager.OptimizeRouteNew (); //最后可用的,但是经纬度计算, + _flightTaskManager.OptimizeRouteMeter(true); //采用米计算逻辑和OptimizeRouteNew一样 + })); + } + } + private ICommand _OptimizeRouteCommand; + public ICommand OptimizeRouteCommand + { + get + { + return _OptimizeRouteCommand ?? (_OptimizeRouteCommand = new RelayCommand(async => + { + //_flightTaskManager.OptimizeRoute2(); + // _flightTaskManager.OptimizeRouteNew (); //最后可用的,但是经纬度计算, + _flightTaskManager.OptimizeRouteMeter(); //采用米计算逻辑和OptimizeRouteNew一样 + })); + } + } + + private ICommand _LevelAlignmentCommand; + public ICommand LevelAlignmentCommand + { + get + { + return _LevelAlignmentCommand ?? (_LevelAlignmentCommand = new RelayCommand(async => + { + double maxlat = 0; + double tlat = 0; + + + + + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + if (_flightTaskManager.SelectedTask != null) + { + bool copterisselect; + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + copterisselect = false; + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + copterisselect = true; + + } + if (copterisselect) + { + + tlat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; + if (tlat > maxlat) + maxlat = tlat; + + } + } + + + + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + copterisselect = false; + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + copterisselect = true; + + } + if (copterisselect) + { + + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = maxlat; + + } + } + } + else + //调整飞机 + { + //模拟飞机才能调整 + if (selectedCopter is FakeCopter) + { + foreach (var capter in _copterManager.SelectedCopters) + { + tlat = capter.Latitude; + if (tlat > maxlat) + maxlat = tlat; + } + + foreach (var capter in _copterManager.SelectedCopters) + { + var copterfk = (FakeCopter)capter; + copterfk.SetProperties( + latitude: maxlat, + longitude: copterfk.Longitude); + } + } + } + + + + + //await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 + + })); + } + } + + + + + + + + private ICommand _VerticlAlignmentCommand; +public ICommand VerticlAlignmentCommand + { + get + { + return _VerticlAlignmentCommand ?? (_VerticlAlignmentCommand = new RelayCommand(async => + { + + double maxlng = 0; + double tlng = 0; + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + bool copterisselect; + if (_flightTaskManager.SelectedTask != null) + { + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + copterisselect = false; + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + copterisselect = true; + + } + if (copterisselect) + { + + tlng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; + if (tlng > maxlng) + maxlng = tlng; + + } + } + + + + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + copterisselect = false; + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + copterisselect = true; + + } + if (copterisselect) + { + + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = maxlng; + + } + } + + //await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 + + //await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 + } + else + //调整飞机 + { + //模拟飞机才能调整 + if (selectedCopter is FakeCopter) + { + foreach (var capter in _copterManager.SelectedCopters) + { + tlng = capter.Longitude; + if (tlng > maxlng) + maxlng = tlng; + } + + foreach (var capter in _copterManager.SelectedCopters) + { + var copterfk = (FakeCopter)capter; + copterfk.SetProperties( + latitude: copterfk.Latitude, + longitude: maxlng); + } + } + } + + })); + } + + } + + + + + + + + + + public static double DistanceOfTwoPoints(double lng1, double lat1, double lng2, double lat2, GaussSphere gs) + { + double radLat1 = Rad(lat1); + double radLat2 = Rad(lat2); + double a = radLat1 - radLat2; + double b = Rad(lng1) - Rad(lng2); + double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2))); + s = s * (gs == GaussSphere.WGS84 ? 6378137.0 : (gs == GaussSphere.Xian80 ? 6378140.0 : 6378245.0)); + s = Math.Round(s * 10000) / 10000; + return s; + } + + private static double Rad(double d) + { + return d * Math.PI / 180.0; + } + + + /// + /// 高斯投影中所选用的参考椭球 + /// + public enum GaussSphere + { + Beijing54, + Xian80, + WGS84, + } + + + + + //水平旋转 + private ICommand _LevelRotateCommand; + public ICommand LevelRotateCommand + { + get + { + return _LevelRotateCommand ?? (_LevelRotateCommand = new RelayCommand(async RotateLine => + { + + + + double lngsum = 0; + double latsum = 0; + int selectcount = 0; + double centlng = 0; + double centlat = 0; + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + if (_flightTaskManager.SelectedTask != null) + { + bool copterisselect; + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + copterisselect = false; + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + copterisselect = true; + + } + if (copterisselect) + { + + lngsum+= _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; + latsum+= _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; + selectcount++; + + } + } + //计算旋转中心 + if (selectcount > 0) + { + centlng = lngsum / selectcount; + centlat = latsum / selectcount; + } + else return; + + + //////////计算旋转,经测试用下面的函数组合计算比较准确 + + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + { + double lpDistance = CalculationLogLatDistance.GetDistanceOne(centlng, centlat, + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng, + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat); + + CalculationLogLatDistance.MyLatLng mypos1, mypos2; + mypos1 = new CalculationLogLatDistance.MyLatLng(centlng, centlat); + mypos2 = new CalculationLogLatDistance.MyLatLng(_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng + , _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat); + double lpAzimuth = CalculationLogLatDistance.getAngle(mypos1, mypos2); + double lng2 = 0; + double lat2=0; + CalculationLogLatDistance.ConvertDistanceToLogLat(centlng, centlat, lpDistance, + lpAzimuth + (double)RotateLine,out lng2, out lat2); + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = lng2; + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = lat2; + + } + + + } + } + //// + await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 + + + } + else + //调整飞机 + { + //模拟飞机才能调整 + if (selectedCopter is FakeCopter) + { + foreach (var capter in _copterManager.SelectedCopters) + { + lngsum += capter.Longitude; + latsum += capter.Latitude; + selectcount++; + } + + //计算旋转中心 + if (selectcount > 0) + { + centlng = lngsum / selectcount; + centlat = latsum / selectcount; + } + else return; + + foreach (var capter in _copterManager.SelectedCopters) + { + + + double lpDistance = CalculationLogLatDistance.GetDistanceOne(centlng, centlat, + capter.Longitude, + capter.Latitude); + + CalculationLogLatDistance.MyLatLng mypos1, mypos2; + mypos1 = new CalculationLogLatDistance.MyLatLng(centlng, centlat); + mypos2 = new CalculationLogLatDistance.MyLatLng( + capter.Longitude + , capter.Latitude); + double lpAzimuth = CalculationLogLatDistance.getAngle(mypos1, mypos2); + double lng2 = 0; + double lat2 = 0; + CalculationLogLatDistance.ConvertDistanceToLogLat(centlng, centlat, lpDistance, + lpAzimuth + (double)RotateLine, out lng2, out lat2); + + var copterfk = (FakeCopter)capter; + copterfk.SetProperties( + latitude: lat2, + longitude: lng2); + } + } + } + + })); + } + } + + //任务整体旋转 + private ICommand _TaskRotateCommand; + public ICommand TaskRotateCommand + { + get + { + return _TaskRotateCommand ?? (_TaskRotateCommand = new RelayCommand(async RotateLine => + { + double centlng = 0; + double centlat = 0; + + if (_copterManager.Copters.Count > 0) + { + //centlng = _copterManager.Copters[0].Longitude; + //centlat = _copterManager.Copters[0].Latitude; + centlng = _flightTaskManager.OriginLng; + centlat = _flightTaskManager.OriginLat; + //虚拟飞机一起旋转 + if ("FakeCopter" == _copterManager.Copters[0].GetType().Name) + { + for (int i = 0; i < _copterManager.Copters.Count; i++) + { + FakeCopter tempcopter = (FakeCopter)_copterManager.Copters[i]; + double lng_out = 0; + double lat_out = 0; + CalculationLogLatDistance.GetRotatePos(centlng, centlat, (double)RotateLine, + tempcopter.Longitude, + tempcopter.Latitude, + out lng_out, out lat_out + ); + tempcopter.SetProperties( + latitude: lat_out, + longitude: lng_out + ); + + } + + _flightTaskManager.Orientation += RotateLine; + } + + + + + + double copterlng = 0; + double copterlat = 0; + double lng_out1 = 0; + double lat_out1 = 0; + + int itaskendno = taskendno; + if (itaskendno == 0) itaskendno = _flightTaskManager.Tasks.Count - 1; + else itaskendno = taskendno - 1; + if (itaskendno > _flightTaskManager.Tasks.Count-1) itaskendno = _flightTaskManager.Tasks.Count-1; + int _taskstartno = 0; + if (taskstartno == 0) _taskstartno = 0; + else _taskstartno = taskstartno - 1; + + for (int i = _taskstartno; i <= itaskendno; i++) + { + + + for (int j = 0; j < _flightTaskManager.Tasks[i].SingleCopterInfos.Count; j++) + { + copterlng=_flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng; + copterlat = _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat; + + CalculationLogLatDistance.GetRotatePos(centlng, centlat, (double)RotateLine, + copterlng, + copterlat, + out lng_out1, out lat_out1 + ); + + _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLng = lng_out1; + _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetLat = lat_out1; + } + + } + + + } + + await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 + + })); + } + } + + + + //垂直旋转 + private ICommand _VerticlRotateCommand; + public ICommand VerticlRotateCommand + { + get + { + return _VerticlRotateCommand ?? (_VerticlRotateCommand = new RelayCommand(async RotateLine => + { + + + + double lngsum = 0; + double latsum = 0; + double altsum = 0; + int selectcount = 0; + double centlng = 0; + double centlat = 0; + double centalt = 0; + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + if (_flightTaskManager.SelectedTask != null) + { + bool copterisselect; + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + copterisselect = false; + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + copterisselect = true; + + } + if (copterisselect) + { + + lngsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; + latsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; + altsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt; + selectcount++; + + } + } + //计算旋转中心 + if (selectcount > 0) + { + centlng = lngsum / selectcount; + centlat = latsum / selectcount; + centalt = altsum / selectcount; + } + else return; + + + //////////计算旋转,经测试用下面的函数组合计算比较准确 + double k = (double)RotateLine / 180 * Math.PI; + double dx = 0; + double dy = 0; + double ax = 0; + double ay = 0; + double tlng = 0; + double tlat = 0; + + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + { + tlng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; + tlat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; + //纬度方向距离(单位m) + ax = CalculationLogLatDistance.GetDistanceOne(tlng, centlat,tlng,tlat) *1000; + //方向角用于正负,0为正,180为负 + CalculationLogLatDistance.MyLatLng mypos1, mypos2; + mypos1 = new CalculationLogLatDistance.MyLatLng(tlng,centlat); + mypos2 = new CalculationLogLatDistance.MyLatLng(tlng,tlat); + double lpAzimuth = CalculationLogLatDistance.getAngle(mypos1, mypos2); + if (lpAzimuth > 90) + ax = -ax; + + + //高度方向距离(单位m) + ay = (_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt - centalt); + + dx = ax * Math.Cos(k) + ay * Math.Sin(k); + dy = -ax * Math.Sin(k) + ay * Math.Cos(k); + + //新高度(米) + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt= (float)(centalt + dy); + //计算新纬度 + double lng2 = 0; + double lat2 = 0; + if (dx < 0) + lpAzimuth = 180; + else + lpAzimuth = 0; + dx=Math.Abs(dx); + + CalculationLogLatDistance.ConvertDistanceToLogLat( + tlng, + centlat, //旋转中心纬度 + dx/1000, //新距离 + lpAzimuth, //方向垂直 + out lng2, + out lat2); + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = lat2; + + } + + + } + } + //// + + + + + await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 + } + })); + } + } + + + private ICommand _AutoaltCommand; + public ICommand AutoaltCommand + { + get + { + return _AutoaltCommand ?? (_AutoaltCommand = new RelayCommand(async => + { + + + + + + + + + + + + + + + + + })); + } + } + + + private ICommand _PrealtCommand; + public ICommand PrealtCommand + { + get + { + return _PrealtCommand ?? (_PrealtCommand = new RelayCommand(async => + { + + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + { + if (_flightTaskManager.SelectedTaskIndex > 1) + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt = + _flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex - 1].SingleCopterInfos[i].TargetAlt; + } + + } + + + } + + + + + + + + + })); + } + } + + //当前任务选中的飞机修改高度 + private ICommand _ModiSelectedAltCommand; + public ICommand ModiSelectedAltCommand + { + get + { + return _ModiSelectedAltCommand ?? (_ModiSelectedAltCommand = new RelayCommand(async => + { + if (_flightTaskManager.Tasks.Count < 2) return; + if (_flightTaskManager.SelectedTask.TaskType != FlightTaskType.FlyTo) return; + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + var info = _flightTaskManager.SelectedTask.SingleCopterInfos[i]; + if (_copterManager.SelectedCopters.Contains(info.Copter)) + { + info.TargetAlt += Modialtvalue; + } + } + + })); + } + } + //当前任务选中的飞机水平移动 + private ICommand _ModiSelectedPosCommand; + public ICommand ModiSelectedPosCommand + { + get + { + return _ModiSelectedPosCommand ?? (_ModiSelectedPosCommand = new RelayCommand(async => + { + if (_flightTaskManager.Tasks.Count < 2) return; + if (_flightTaskManager.SelectedTask.TaskType != FlightTaskType.FlyTo) return; + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + var info = _flightTaskManager.SelectedTask.SingleCopterInfos[i]; + if (_copterManager.SelectedCopters.Contains(info.Copter)) + { + Tuple targetLatLng = new Tuple(0, 0); + + targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D( + info.TargetLat, + info.TargetLng, + directionvalue, + Modialtvalue + ); + info.TargetLat = targetLatLng.Item1; + info.TargetLng = targetLatLng.Item2; + } + } + + })); + } + } + + + //调整所有任务高度 + private ICommand _ModiAltCommand; + public ICommand ModiAltCommand + { + get + { + return _ModiAltCommand ?? (_ModiAltCommand = new RelayCommand( cModialtvalue => + { + if (_flightTaskManager.Tasks.Count < 2) return; + + float lowalt = 200; + + + + int itaskendno = taskendno; + if (itaskendno == 0) itaskendno = _flightTaskManager.Tasks.Count - 1; + else itaskendno = taskendno - 1; + if (itaskendno > _flightTaskManager.Tasks.Count-1) itaskendno = _flightTaskManager.Tasks.Count-1; + // for (int i = taskstartno; i < itaskendno; i++) + int _startindex = taskstartno; + if (_startindex != 0) _startindex = taskstartno - 1; + int _endindex = itaskendno ; + int lowtask = 0; + int lowCopter = 0; + + if ((txtStarindex != 0) && (txtendindex != 0)) + { + _startindex = txtStarindex; + _endindex = txtendindex; + } + + for (int i = _startindex; i <= _endindex; i++) + { + + if ((_flightTaskManager.Tasks[i].TaskType == FlightTaskType.TakeOff)|| (_flightTaskManager.Tasks[i].TaskType == FlightTaskType.Land)) + continue; + for (int j = 0; j < _flightTaskManager.Tasks[i].SingleCopterInfos.Count; j++) + { + _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt +=(float) cModialtvalue; + if (lowalt > _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt) + { + lowalt = _flightTaskManager.Tasks[i].SingleCopterInfos[j].TargetAlt; + lowtask = i; + lowCopter = j; + } + } + } + Alert.Show("指定步骤任务高度已改变"+ cModialtvalue + "米,步骤["+ lowtask + "],ID["+ + _flightTaskManager.Tasks[lowtask].SingleCopterInfos[lowCopter].Copter.Id + + "]最低飞行高度"+ lowalt + "米,注意是否太低!"); + + })); + } + } + + + + + + + //计算距离 + private ICommand _calDistinceCommand; + public ICommand calDistinceCommand + { + get + { + return _calDistinceCommand ?? (_calDistinceCommand = new RelayCommand(async => + { + if (_copterManager.AcceptingControlCopters.Count() < 2) + return; + + + + + + string currselectstr = ""; + + for (int tsi = 1; tsi < _flightTaskManager.Tasks.Count ; tsi++) + { + + if ((_flightTaskManager.Tasks[tsi].TaskType == FlightTaskType.TakeOff) || (_flightTaskManager.Tasks[tsi].TaskType == FlightTaskType.Land)) + continue; + + + + + double minDistance = double.MaxValue; + double maxDistance = 0.0; + var flightTask = _flightTaskManager.Tasks[tsi]; + List selectedCopter = new List(); + selectedCopter.AddRange(_copterManager.AcceptingControlCopters); + string minCopterId1 = "0"; + string minCopterId2 = "0"; + string maxCopterId1 = "0"; + string maxCopterId2 = "0"; + for (int i = 0; i < selectedCopter.Count; i++) + { + var copter1 = selectedCopter[i]; + var copterInfo1 = flightTask.SingleCopterInfos.FirstOrDefault(c => c.Copter == copter1); + + for (int j = i + 1; j < selectedCopter.Count; j++) + { + var copter2 = selectedCopter[j]; + var copterInfo2 = flightTask.SingleCopterInfos.FirstOrDefault(c => c.Copter == copter2); + + double distance = GeographyUtils.CalcDistance( + copterInfo1.TargetLat, copterInfo1.TargetLng, copterInfo1.TargetAlt, + copterInfo2.TargetLat, copterInfo2.TargetLng, copterInfo2.TargetAlt); + //minDistance = Math.Min(minDistance, distance); + if (distance < minDistance) + { + minDistance = distance; + minCopterId1 = copter1.Id; + minCopterId2 = copter2.Id; + } + + if (distance > maxDistance) + { + maxDistance = distance; + maxCopterId1 = copter1.Id; + maxCopterId2 = copter2.Id; + } + + } + } + minDistance = Math.Round(minDistance, 2); + maxDistance = Math.Round(maxDistance, 2); + + string showstr = string.Format("[{0}{1}] 最小距离 = {2:F2} 飞机: {3} 和 {4}; 最大距离 = {5:F2} 飞机: {6} 和 {7}", + flightTask.TaskIndex + 1, flightTask.TaskCnName, minDistance, minCopterId1, minCopterId2, maxDistance, + maxCopterId1, maxCopterId2); + + Message.Show(showstr); + + + // Message.Show($"[{0:flightTask.TaskIndex + 1}{flightTask.TaskCnName}]最小距离 = {minDistance} 飞机:{minCopterId1}和{minCopterId2} ; 最大距离 = {maxDistance} 飞机:{maxCopterId1}和{maxCopterId2}"); + if (flightTask == _flightTaskManager.SelectedTask) + currselectstr = showstr; + } + Message.Show("选中任务:"); + Message.Show(currselectstr); + + + + + + })); + } + } + + + private ICommand _MaxDistinceAndTimeCommand; + public ICommand MaxDistinceAndTimeCommand + { + get + { + return _MaxDistinceAndTimeCommand ?? (_MaxDistinceAndTimeCommand = new RelayCommand(async => + { + //不设置时间,只是计算 + _flightTaskManager.SetTaskFlytime(_flightTaskManager.SelectedTaskIndex, false); + })); + } + } + + + + + + //缩放 + private ICommand _ScaleCommand; + public ICommand ScaleCommand + { + get + { + return _ScaleCommand ?? (_ScaleCommand = new RelayCommand(async ScaleVale => + { + + + double lngsum = 0; + double latsum = 0; + int selectcount = 0; + double centlng = 0; + double centlat = 0; + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + bool copterisselect; + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + copterisselect = false; + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + copterisselect = true; + + } + if (copterisselect) + { + + lngsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; + latsum += _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; + selectcount++; + + } + } + //计算缩放中心 + if (selectcount > 0) + { + centlng = lngsum / selectcount; + centlat = latsum / selectcount; + } + else return; + + + //////////计算旋转,经测试用下面的函数组合计算比较准确 + + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter) + { + double lpDistance = CalculationLogLatDistance.GetDistanceOne(centlng, centlat, + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng, + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat); + + CalculationLogLatDistance.MyLatLng mypos1, mypos2; + mypos1 = new CalculationLogLatDistance.MyLatLng(centlng, centlat); + mypos2 = new CalculationLogLatDistance.MyLatLng(_flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng + , _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat); + double lpAzimuth = CalculationLogLatDistance.getAngle(mypos1, mypos2); + double lng2 = 0; + double lat2 = 0; + CalculationLogLatDistance.ConvertDistanceToLogLat(centlng, centlat, lpDistance * (double)ScaleVale/100, + lpAzimuth , out lng2, out lat2); + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = lng2; + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = lat2; + + } + + + } + } + + await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。 + + })); + } + } + + + private ICommand _BackToPreviousTaskPoint; + public ICommand BackToPreviousTaskPoint + { + get + { + return _BackToPreviousTaskPoint ?? (_BackToPreviousTaskPoint = new RelayCommand(async => + { + _flightTaskManager.SelectedTask.VerticalLift = true; + })); + } + } + + #region 跑马灯参数 + + private double _BeginTime = 1; + public double BeginTime + { + get { return _BeginTime; } + set { Set(nameof(BeginTime), ref _BeginTime, value); } + } + + + //灯带扫光方向,默认从左到右 + private double _BeltDirection = 90; + public double BeltDirection + { + get { return _BeltDirection; } + set { Set(nameof(BeltDirection), ref _BeltDirection, value); } + } + + + + + + + + private double _EndTime = 3; + public double EndTime + { + get { return _EndTime; } + set { Set(nameof(EndTime), ref _EndTime, value); } + } + + private double _AverageSum = 10; + public double AverageSum + { + get { return _AverageSum; } + set { Set(nameof(AverageSum), ref _AverageSum, value); } + } + + private string _ChangeRGB = "FF0000"; + public string ChangeRGB + { + get { return _ChangeRGB; } + set { Set(nameof(ChangeRGB), ref _ChangeRGB, value); + DrawChangeRGB.Color = (Color)ColorConverter.ConvertFromString("#" + value); + } + } + + private string _EndRGB = "0000FF"; + public string EndRGB + { + get { return _EndRGB; } + set { Set(nameof(EndRGB), ref _EndRGB, value); + DrawEndRGB.Color = (Color)ColorConverter.ConvertFromString("#" + value); + } + } + + private SolidColorBrush _DrawChangeRGB = new SolidColorBrush(Color.FromRgb(0xFF, 0x00, 0x00)); + public SolidColorBrush DrawChangeRGB + { + get + { + return _DrawChangeRGB; + } + set + { + Set(nameof(DrawChangeRGB), ref _DrawChangeRGB, value); + + } + } + + private SolidColorBrush _DrawEndRGB = new SolidColorBrush(Color.FromRgb(0x00, 0x00, 0xFF)); + public SolidColorBrush DrawEndRGB + { + get + { + return _DrawEndRGB; + } + set + { + Set(nameof(DrawEndRGB), ref _DrawEndRGB, value); + + } + } + + #endregion + + //灯带--按照经纬度变换灯光 + private ICommand _SetHorseRaceLampCommand; + public ICommand SetHorseRaceLampCommand + { + get + { + return _SetHorseRaceLampCommand ?? (_SetHorseRaceLampCommand = new RelayCommand(async () => + { + float CopterDirection =90- (float)BeltDirection ; + + //必须大于1架 + if (_copterManager.SelectedCopters.Count() <= 1) + { + Alert.Show("必须选中多于一架飞机"); + return; + } + if (EndTime<= BeginTime) + { + Alert.Show("结束时间必须大于开始时间(非持续时间!)"); + return; + } + + + //旋转飞机矩阵 + if (CopterDirection != 0) + { + LevelRotateCommand.Execute(CopterDirection); + await Task.Delay(100); + } + + double minLat, maxLat; + double minLng, maxLng; + + + + //所以选中飞行当前任务信息 + var selectCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos.FindAll(delegate (FlightTaskSingleCopterInfo p) + { + return _copterManager.SelectedCopters.Contains(p.Copter); + }); + + minLat = selectCopterInfos.Min(c => c.TargetLat); + maxLat = selectCopterInfos.Max(c => c.TargetLat); + minLng = selectCopterInfos.Min(c => c.TargetLng); + maxLng = selectCopterInfos.Max(c => c.TargetLng); + + double averagelngCount = maxLng - minLng; + + foreach (var copterInfo in selectCopterInfos) + { + double interval = copterInfo.TargetLng - minLng; + double leddelay = 0; + int time = (int)(interval / (averagelngCount / AverageSum)); + LEDInfo led = new LEDInfo(); + led.LEDMode = 0; + led.Delay = BeginTime + time * (EndTime - BeginTime) / AverageSum; + leddelay += led.Delay; + led.LEDRGB = ChangeRGB; + copterInfo.AddLEDInfo(led); + + //跑马灯变化后改变颜色 效果类似灯带 + if (EndRGB != "") + { + LEDInfo endLed = new LEDInfo(); + endLed.LEDMode = 0; + endLed.Delay = (EndTime - BeginTime) / AverageSum; + if (EndRGB == "0") + endLed.LEDRGB = copterInfo.LEDInfos[copterInfo.LEDInfos.Count - 2].LEDRGB; + else + endLed.LEDRGB = EndRGB; + copterInfo.AddLEDInfo(endLed); + + //为了每架飞机结束灯光时间一致,以便下次再做跑马灯之类的效果有个一致的起始时间,再增加一个 + //改为专门的按钮功能=AlignmentTimeCommand + /* + leddelay += endLed.Delay; + LEDInfo endLed1 = new LEDInfo(); + endLed1.LEDMode = 0; + endLed1.Delay = (EndTime - BeginTime)-leddelay; + if (EndRGB == "0") + endLed1.LEDRGB = copterInfo.LEDInfos[copterInfo.LEDInfos.Count - 2].LEDRGB; + else + endLed1.LEDRGB = EndRGB; + copterInfo.AddLEDInfo(endLed1); + */ + } + } + + await Task.Delay(100); + + + //旋转飞机矩阵 + if (CopterDirection != 0) + LevelRotateCommand.Execute(0-CopterDirection); + + + + + })); + } + } + + + private double _StrokesTime = 1; + public double StrokesTime + { + get { return _StrokesTime; } + set { Set(nameof(StrokesTime), ref _StrokesTime, value); } + } + + private double _IntervalTime = 0.1; + public double IntervalTime + { + get { return _IntervalTime; } + set { Set(nameof(IntervalTime), ref _IntervalTime, value); } + } + + private double _SingleNum = 1; + public double SingleNum + { + get { return _SingleNum; } + set { Set(nameof(SingleNum), ref _SingleNum, value); } + } + + private string _StrokesRGB = "FFFFFF"; + public string StrokesRGB + { + get { return _StrokesRGB; } + set { Set(nameof(StrokesRGB), ref _StrokesRGB, value); } + } + + //跑马灯(笔画顺序用)--按照选择航点顺序变换灯光 + private ICommand _SetStrokesLampCommamd; + public ICommand SetStrokesLampCommamd + { + get + { + return _SetStrokesLampCommamd ?? (_SetStrokesLampCommamd = new RelayCommand(async () => + { + //必须大于1架 + if (_copterManager.SelectedCopters.Count() <= 1) + return; + + + double curTime = StrokesTime; + int curcount = 1; + foreach (var copter in _copterManager.SelectedCopters) + { + if (curcount > SingleNum) + { + curTime += IntervalTime; + curcount = 1; + } + + + var copterInfo = _flightTaskManager.SelectedTask.SingleCopterInfos.FirstOrDefault(c=>c.Copter == copter); + + LEDInfo led = new LEDInfo(); + led.LEDMode = 0; + led.Delay = curTime; + led.LEDRGB = ChangeRGB; + copterInfo.AddLEDInfo(led); + + if (EndRGB != "") + { + LEDInfo endLed = new LEDInfo(); + endLed.LEDMode = 0; + endLed.Delay = IntervalTime; + if (EndRGB == "0") + endLed.LEDRGB = copterInfo.LEDInfos[copterInfo.LEDInfos.Count - 2].LEDRGB; + else + endLed.LEDRGB = EndRGB; + copterInfo.AddLEDInfo(endLed); + } + + curcount++; + } + + await Task.Delay(100); + })); + } + } + + + + private double _AlignmentTime = 10; + public double AlignmentTime + { + get { return _AlignmentTime; } + set { Set(nameof(AlignmentTime), ref _AlignmentTime, value); } + } + + + + + #region 渐变灯参数 + private double _GradientRampTime = 1; + public double GradientRampTime + { + get { return _GradientRampTime; } + set { Set(nameof(GradientRampTime), ref _GradientRampTime, value); } + } + + private string _RightRGB = "FFFFFF"; + public string RightRGB + { + get { return _RightRGB; } + set { Set(nameof(RightRGB), ref _RightRGB, value); + DrawRightRGB.Color = (Color)ColorConverter.ConvertFromString("#" + value); + } + } + + private string _LeftRGB = "FFFFFF"; + public string LeftRGB + { + get { return _LeftRGB; } + set { Set(nameof(LeftRGB), ref _LeftRGB, value); + DrawLeftRGB.Color = (Color)ColorConverter.ConvertFromString("#" + value); + } + } + + + + //渐变方向,默认从左到右 + private double _GradualDirection = 90; + public double GradualDirection + { + get { return _GradualDirection; } + set { Set(nameof(GradualDirection), ref _GradualDirection, value); } + } + + + + + + private SolidColorBrush _DrawLeftRGB = new SolidColorBrush(Color.FromRgb(0xFF, 0xFF, 0xFF)); + public SolidColorBrush DrawLeftRGB + { + get + { + return _DrawLeftRGB; + } + set + { + Set(nameof(DrawLeftRGB), ref _DrawLeftRGB, value); + + } + } + + private SolidColorBrush _DrawRightRGB = new SolidColorBrush(Color.FromRgb(0xFF, 0xFF, 0xFF)); + public SolidColorBrush DrawRightRGB + { + get + { + return _DrawRightRGB; + } + set + { + Set(nameof(DrawRightRGB), ref _DrawRightRGB, value); + + } + } + + + private ICommand _QueryMAXTimeCommand; + public ICommand QueryMAXTimeCommand + { + get + { + return _QueryMAXTimeCommand ?? (_QueryMAXTimeCommand = new RelayCommand(async => + { + //所以选中飞行当前任务信息 + var selectCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos.FindAll(delegate (FlightTaskSingleCopterInfo p) + { + return _copterManager.SelectedCopters.Contains(p.Copter); + }); + double maxtime = 0.0f; + string maxid="" ; + foreach (var copterInfo in selectCopterInfos) + { + // AlignmentTime + double leddelay = 0; + foreach (LEDInfo led in copterInfo.LEDInfos) + { + leddelay += led.Delay; + } + if (leddelay > maxtime) + { + maxtime = leddelay; + maxid = copterInfo.Copter.Id; + } + } + + + Alert.Show($"ID={maxid}飞机的航点灯光时长为{maxtime}秒", "提示", MessageBoxButton.OK, MessageBoxImage.Information); + + + })); + } + } + + + + + + + + private ICommand _AlignmentTimeCommand; + public ICommand AlignmentTimeCommand + { + get + { + return _AlignmentTimeCommand ?? (_AlignmentTimeCommand = new RelayCommand(async => + { + //所以选中飞行当前任务信息 + var selectCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos.FindAll(delegate (FlightTaskSingleCopterInfo p) + { + return _copterManager.SelectedCopters.Contains(p.Copter); + }); + + foreach (var copterInfo in selectCopterInfos) + { + // AlignmentTime + double leddelay = 0; + foreach (LEDInfo led in copterInfo.LEDInfos) + { + leddelay += led.Delay; + } + if (leddelay > AlignmentTime) + { + Alert.Show($"{AlignmentTime}秒对齐时间不够,ID={copterInfo.Copter.Id}飞机的航点灯光时长为{leddelay}秒", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); + return; + } + + } + + + + + + foreach (var copterInfo in selectCopterInfos) + { + + double leddelay = 0; + foreach (LEDInfo led in copterInfo.LEDInfos) + { + leddelay += led.Delay; + } + if (leddelay<= AlignmentTime) + { + LEDInfo endLed = new LEDInfo(); + endLed.LEDMode = 0; + endLed.Delay = AlignmentTime - leddelay; + if (copterInfo.LEDInfos.Count > 0) + endLed.LEDRGB = copterInfo.LEDInfos[copterInfo.LEDInfos.Count - 1].LEDRGB; + else + endLed.LEDRGB = "FFFFFF"; + + copterInfo.AddLEDInfo(endLed); + } + } + })); + } + } + + + + + + + #endregion + + //渐变色 + private ICommand _SetGradientRampCommand; + public ICommand SetGradientRampCommand + { + get + { + return _SetGradientRampCommand ?? (_SetGradientRampCommand = new RelayCommand(async () => + { + + float CopterDirection = 90 - (float)GradualDirection; + //渐变需要2架以上 + if (_copterManager.SelectedCopters.Count() <= 1) + return; + + List TempSingleCopterInfos = new List(); + + //旋转飞机矩阵 + if (CopterDirection != 0) + { + + var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault(); + if (_flightTaskManager.SelectedTask != null) + { + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + //得到每个选择的飞机 + selectedCopter = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + //根据飞机查找任务中的位置信息 + foreach (var capter in _copterManager.SelectedCopters) + { + //如果是选择的那架飞机 + if (capter == selectedCopter) + { + FlightTaskSingleCopterInfo vFlightTaskSingleCopterInfo = new FlightTaskSingleCopterInfo(capter); + vFlightTaskSingleCopterInfo.TargetLng = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng; + vFlightTaskSingleCopterInfo.TargetAlt = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt; + vFlightTaskSingleCopterInfo.TargetLat = _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat; + TempSingleCopterInfos.Add(vFlightTaskSingleCopterInfo); + } + + + } + } + } + + + + + LevelRotateCommand.Execute(CopterDirection); + await Task.Delay(100); + } + + + + + + + double minLat, maxLat; + double minLng, maxLng; + + + //所以选中飞行当前任务信息 + var selectCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos.FindAll(delegate (FlightTaskSingleCopterInfo p) + { + return _copterManager.SelectedCopters.Contains(p.Copter); + }); + + minLat = selectCopterInfos.Min(c => c.TargetLat); + maxLat = selectCopterInfos.Max(c => c.TargetLat); + minLng = selectCopterInfos.Min(c => c.TargetLng); + maxLng = selectCopterInfos.Max(c => c.TargetLng); + + double averagelngCount = maxLng - minLng; + + Color rightColor = (Color)ColorConverter.ConvertFromString("#" + RightRGB); + Color leftColor = (Color)ColorConverter.ConvertFromString("#" + LeftRGB); + + int diffR = rightColor.R - leftColor.R; + int diffG = rightColor.G - leftColor.G; + int diffB = rightColor.B - leftColor.B; + + foreach (var copterInfo in selectCopterInfos) + { + double interval = copterInfo.TargetLng - minLng; + double percent = (interval / averagelngCount ); + + int R = (int)(diffR * percent) + leftColor.R; + int G = (int)(diffG * percent) + leftColor.G; + int B = (int)(diffB * percent) + leftColor.B; + Color c = Color.FromRgb((byte)R, (byte)G, (byte)B); + + LEDInfo led = new LEDInfo(); + led.LEDMode = 0; + led.Delay = GradientRampTime; + led.LEDRGB = "000000"; + + //led.LEDRGB = Convert.ToString(R, 16) + Convert.ToString(G, 16) + Convert.ToString(B, 16); + + try + { + led.LEDRGB = R.ToString("X2") + G.ToString("X2") + B.ToString("X2"); + + } + catch (Exception) + { + + //throw; + } + + + copterInfo.AddLEDInfo(led); + } + + await Task.Delay(100); + + //使用之前保存的位置回到飞机原来的位置,不使用旋转因为转回去和原来的位置有一点点偏差 + if (CopterDirection != 0) + { + + int j = 0; + var selectedCopter1 = _copterManager.SelectedCopters.FirstOrDefault(); + if (_flightTaskManager.SelectedTask != null) + { + for (int i = 0; i < _flightTaskManager.SelectedTask.SingleCopterInfos.Count; i++) + { + selectedCopter1 = _flightTaskManager.SelectedTask.SingleCopterInfos[i].Copter; + foreach (var capter in _copterManager.SelectedCopters) + { + if (capter == selectedCopter1) + { + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLat = TempSingleCopterInfos[j].TargetLat; + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetLng = TempSingleCopterInfos[j].TargetLng; + _flightTaskManager.SelectedTask.SingleCopterInfos[i].TargetAlt = TempSingleCopterInfos[j].TargetAlt; + j++; + + } + + + } + } + } + // LevelRotateCommand.Execute(0 - CopterDirection); + } + + })); + } + } + } +}