Compare commits
92 Commits
Author | SHA1 | Date | |
---|---|---|---|
7b024ed726 | |||
92a56a247f | |||
a9cf0fdc8a | |||
32110aab07 | |||
12262ff53d | |||
3491f87832 | |||
7402ace3f8 | |||
77afef5ee1 | |||
9bc7a66831 | |||
af9a86dffd | |||
36875bcdc2 | |||
2614dc2f59 | |||
17e4c8bd97 | |||
9cfd7db051 | |||
ff37f4fa04 | |||
f8f3f36304 | |||
b289618a87 | |||
c2d26dd62c | |||
b729f6b78e | |||
79669581f1 | |||
1403000ef9 | |||
c3a3877323 | |||
aea10b8382 | |||
ca07ddd155 | |||
09da3f24ba | |||
512d9e5386 | |||
3a8662548f | |||
4b54e56ebc | |||
63c9372550 | |||
cb2a672c44 | |||
7dfe36a7f8 | |||
ba8eb6b2e2 | |||
4dba5da8fd | |||
3719c74753 | |||
417f761e40 | |||
bbb7804831 | |||
7c71016e0c | |||
3efb9b719d | |||
62cde39a91 | |||
d547c7ab5c | |||
8fbb41928d | |||
c1db1e3525 | |||
f0ef8134d5 | |||
c27138d0e3 | |||
8938e3aaaa | |||
59b4669a7d | |||
62a7b8b028 | |||
e1c81f28ff | |||
9b5b3bb22c | |||
441cbe953d | |||
23c1390758 | |||
d525f00222 | |||
f787069624 | |||
84c12a1eb7 | |||
8facb729f7 | |||
3aa4879511 | |||
da086831bf | |||
911024c0ad | |||
3d2a3b10fb | |||
776b9cfe62 | |||
57fc99c434 | |||
9a1fd805b9 | |||
d4a9dc5bf3 | |||
3362a1b47c | |||
2f26de2196 | |||
b728584628 | |||
92044ae56b | |||
6cb44d5401 | |||
7fb0bcf60e | |||
e3f4e557dd | |||
d7df82f667 | |||
e8d17e29d1 | |||
ffe6b466fe | |||
f9428fbad2 | |||
d334442d62 | |||
08ff8c7772 | |||
5c6cf9ecdb | |||
1e38390fc6 | |||
00d03a0025 | |||
8990d57212 | |||
6f33c3867c | |||
b80026ff8c | |||
f7a638159e | |||
694472c9b7 | |||
fc3b2cae02 | |||
beb927a08c | |||
7ea00c6855 | |||
c0fa7d8ddb | |||
7ac2f48500 | |||
f49cd3c722 | |||
![]() |
59672e4f5e | ||
![]() |
9133800b62 |
@ -1,108 +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}"
|
||||
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
|
||||
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
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.7.34202.233
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.FormationCreator", "Plane.FormationCreator\Plane.FormationCreator.csproj", "{61E2F31E-220A-4E3F-A64D-F7CDC2135008}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{9BFB2123-2239-4A85-B5BC-0328CE7640D7} = {9BFB2123-2239-4A85-B5BC-0328CE7640D7}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plane.Windows", "..\Plane.Libraries\Plane.Windows\Plane.Windows.csproj", "{06848293-9B17-4068-9B35-44D0ED713CD4}"
|
||||
EndProject
|
||||
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", "{9BFB2123-2239-4A85-B5BC-0328CE7640D7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlightRouteV2", "..\FlyCube\FlightRouteV2\FlightRouteV2.csproj", "{626A9BFA-07DE-4063-A178-360EB7057ED6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(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
|
||||
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9BFB2123-2239-4A85-B5BC-0328CE7640D7}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{626A9BFA-07DE-4063-A178-360EB7057ED6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{626A9BFA-07DE-4063-A178-360EB7057ED6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{626A9BFA-07DE-4063-A178-360EB7057ED6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{626A9BFA-07DE-4063-A178-360EB7057ED6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{626A9BFA-07DE-4063-A178-360EB7057ED6}.v4.0-Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{0111eb6e-72e3-499c-a3ba-022f5bbc4caf}*SharedItemsImports = 4
|
||||
..\Plane.Sdk3\PlaneGcsSdk_Shared\PlaneGcsSdk_Shared.projitems*{2be393dc-21a4-48b3-83fd-f21cbe8b038b}*SharedItemsImports = 13
|
||||
..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{47141894-ece3-48ca-8dcf-ca751bda231e}*SharedItemsImports = 4
|
||||
..\Plane.Sdk3\PlaneGcsSdk.Contract_Shared\PlaneGcsSdk.Contract_Shared.projitems*{695733d7-99ff-4707-8c89-474e949cadcb}*SharedItemsImports = 13
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
@ -1,53 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="Plane.FormationCreator.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
|
||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Windows.Interactivity" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.0.109.0" newVersion="1.0.109.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<userSettings>
|
||||
<Plane.FormationCreator.Properties.Settings>
|
||||
<setting name="IPs" serializeAs="String">
|
||||
<value>192.168.1.50</value>
|
||||
</setting>
|
||||
</Plane.FormationCreator.Properties.Settings>
|
||||
</userSettings>
|
||||
<entityFramework>
|
||||
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
|
||||
<parameters>
|
||||
<parameter value="mssqllocaldb" />
|
||||
</parameters>
|
||||
</defaultConnectionFactory>
|
||||
<providers>
|
||||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
|
||||
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
|
||||
</providers>
|
||||
</entityFramework>
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
<remove invariant="System.Data.SQLite.EF6" />
|
||||
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6" />
|
||||
<remove invariant="System.Data.SQLite" /><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" /></DbProviderFactories>
|
||||
</system.data>
|
||||
</configuration>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="Plane.FormationCreator.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
|
||||
</sectionGroup>
|
||||
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
|
||||
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Windows.Interactivity" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Data.SQLite" publicKeyToken="db937bc2d44ff139" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.0.109.0" newVersion="1.0.109.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<userSettings>
|
||||
<Plane.FormationCreator.Properties.Settings>
|
||||
<setting name="IPs" serializeAs="String">
|
||||
<value>192.168.1.50</value>
|
||||
</setting>
|
||||
</Plane.FormationCreator.Properties.Settings>
|
||||
</userSettings>
|
||||
<entityFramework>
|
||||
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
|
||||
<parameters>
|
||||
<parameter value="mssqllocaldb"/>
|
||||
</parameters>
|
||||
</defaultConnectionFactory>
|
||||
<providers>
|
||||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
|
||||
<provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6"/>
|
||||
</providers>
|
||||
</entityFramework>
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
<remove invariant="System.Data.SQLite.EF6"/>
|
||||
<add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6" description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6"/>
|
||||
<remove invariant="System.Data.SQLite"/><add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite"/></DbProviderFactories>
|
||||
</system.data>
|
||||
</configuration>
|
||||
|
@ -1,55 +1,99 @@
|
||||
<Application x:Class="Plane.FormationCreator.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
d1p1:Ignorable="d"
|
||||
xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:cnv="clr-namespace:Plane.Windows.Converters;assembly=Plane.Windows"
|
||||
xmlns:lcnv="clr-namespace:Plane.FormationCreator.Converters"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
ShutdownMode="OnMainWindowClose">
|
||||
|
||||
<Application.Resources>
|
||||
<materialDesign:PackIcon x:Key="CheckIcon"
|
||||
x:Shared="False"
|
||||
Kind="Check"
|
||||
Foreground="#2196F3" />
|
||||
<materialDesign:PackIcon x:Key="CloseIcon"
|
||||
x:Shared="False"
|
||||
Kind="Close"
|
||||
Foreground="White" />
|
||||
<cnv:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
|
||||
<cnv:BooleanToVisibilityConverter x:Key="InversiveBooleanToVisibilityConverter"
|
||||
False="Visible"
|
||||
True="Collapsed" />
|
||||
<cnv:NullableBooleanToVisibilityConverter x:Key="IsPausedToRunButtonVisibilityConverter"
|
||||
False="Collapsed"
|
||||
Null="Visible"
|
||||
True="Visible" />
|
||||
<cnv:NullableBooleanToVisibilityConverter x:Key="IsPausedToPauseButtonVisibilityConverter"
|
||||
False="Visible"
|
||||
Null="Collapsed"
|
||||
True="Collapsed" />
|
||||
<cnv:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||
<cnv:BooleanToStringConverter x:Key="ShowModifyTaskViewButtonContentConverter"
|
||||
False="【飞行模式】"
|
||||
True="【编辑模式】" />
|
||||
<cnv:BooleanToResourceConverter x:Key="CheckSignConverter"
|
||||
FalseKey="CloseIcon"
|
||||
TrueKey="CheckIcon" />
|
||||
<cnv:BooleanToResourceConverter x:Key="CheckSignConverter2"
|
||||
FalseKey="CloseIcon"
|
||||
TrueKey="CheckIcon" />
|
||||
<cnv:BooleanToStringConverter x:Key="ColorConverter"
|
||||
False="Red"
|
||||
True="Green" />
|
||||
<cnv:BooleanToStringConverter x:Key="SendConverter"
|
||||
False="发送"
|
||||
True="关闭" />
|
||||
<lcnv:HeartbeatCountToBrushConverter x:Key="HeartbeatCountToBrushConverter" />
|
||||
<lcnv:AppModeToVisibilityConverter x:Key="AppModeToVisibilityConverter" />
|
||||
<lcnv:FlightTaskStatusToFillConverter x:Key="FlightTaskStatusToFillConverter" />
|
||||
<lcnv:FlightTaskIsSelectedToEffectConverter x:Key="FlightTaskIsSelectedToEffectConverter" />
|
||||
</Application.Resources>
|
||||
<Application x:Class="Plane.FormationCreator.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
d1p1:Ignorable="d"
|
||||
xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:cnv="clr-namespace:Plane.Windows.Converters;assembly=Plane.Windows"
|
||||
xmlns:lcnv="clr-namespace:Plane.FormationCreator.Converters"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
ShutdownMode="OnMainWindowClose">
|
||||
|
||||
<Application.Resources>
|
||||
<materialDesign:PackIcon x:Key="ConnectIcon"
|
||||
x:Shared="False"
|
||||
Kind="LanConnect"
|
||||
Foreground="#2196F3" />
|
||||
<materialDesign:PackIcon x:Key="DisconnectIcon"
|
||||
x:Shared="False"
|
||||
Kind="LanDisconnect"
|
||||
Foreground="White" />
|
||||
<materialDesign:PackIcon x:Key="CheckIcon"
|
||||
x:Shared="False"
|
||||
Kind="Check"
|
||||
Foreground="#2196F3" />
|
||||
<materialDesign:PackIcon x:Key="CloseIcon"
|
||||
x:Shared="False"
|
||||
Kind="Close"
|
||||
Foreground="White" />
|
||||
|
||||
<cnv:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
|
||||
<cnv:BooleanToVisibilityConverter x:Key="InversiveBooleanToVisibilityConverter"
|
||||
False="Visible"
|
||||
True="Collapsed" />
|
||||
<cnv:NullableBooleanToVisibilityConverter x:Key="IsPausedToRunButtonVisibilityConverter"
|
||||
False="Collapsed"
|
||||
Null="Visible"
|
||||
True="Visible" />
|
||||
<cnv:NullableBooleanToVisibilityConverter x:Key="IsPausedToPauseButtonVisibilityConverter"
|
||||
False="Visible"
|
||||
Null="Collapsed"
|
||||
True="Collapsed" />
|
||||
<cnv:InverseBooleanConverter x:Key="InverseBooleanConverter" />
|
||||
<cnv:BooleanToStringConverter x:Key="ShowModifyTaskViewButtonContentConverter"
|
||||
False="【飞行模式】"
|
||||
True="【设计模式】" />
|
||||
|
||||
|
||||
<cnv:BooleanToStringConverter x:Key="MainColorConverterDes"
|
||||
False="White"
|
||||
True="DeepSkyBlue" />
|
||||
<cnv:BooleanToStringConverter x:Key="MainFontSizeConverterDes"
|
||||
False="12"
|
||||
True="14" />
|
||||
|
||||
|
||||
|
||||
<cnv:BooleanToStringConverter x:Key="MainColorConverterFly"
|
||||
False="DeepSkyBlue"
|
||||
True="White" />
|
||||
<cnv:BooleanToStringConverter x:Key="MainFontSizeConverterFly"
|
||||
False="14"
|
||||
True="12" />
|
||||
|
||||
|
||||
|
||||
<cnv:BooleanToStringConverter x:Key="Show2d3dButtonContentConverter"
|
||||
False="平面视图"
|
||||
True="立体视图" />
|
||||
|
||||
|
||||
<cnv:BooleanToResourceConverter x:Key="CheckSignConverter"
|
||||
FalseKey="CloseIcon"
|
||||
TrueKey="CheckIcon" />
|
||||
<cnv:BooleanToResourceConverter x:Key="CheckSignConverter2"
|
||||
FalseKey="DisconnectIcon"
|
||||
TrueKey="ConnectIcon" />
|
||||
<cnv:BooleanToStringConverter x:Key="ColorConverter"
|
||||
False="Red"
|
||||
True="Green" />
|
||||
<cnv:BooleanToStringConverter x:Key="SendConverter"
|
||||
False="发送"
|
||||
True="关闭" />
|
||||
<lcnv:HeartbeatCountToBrushConverter x:Key="HeartbeatCountToBrushConverter" />
|
||||
<lcnv:AppModeToVisibilityConverter x:Key="AppModeToVisibilityConverter" />
|
||||
<lcnv:FlightTaskStatusToFillConverter x:Key="FlightTaskStatusToFillConverter" />
|
||||
<lcnv:ErrorCodeToColorConverter x:Key="ErrorCodeToColorConverter" />
|
||||
|
||||
<lcnv:PrecheckToColorConverter x:Key="PrecheckToColorConverter" />
|
||||
|
||||
<lcnv:FlightTaskStatusAndTransitionToFillConverter x:Key="FlightTaskStatusAndTransitionToFillConverter" />
|
||||
|
||||
<lcnv:FlightTaskIsSelectedToEffectConverter x:Key="FlightTaskIsSelectedToEffectConverter" />
|
||||
|
||||
|
||||
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
@ -1,280 +1,313 @@
|
||||
using Plane.Communication;
|
||||
using Plane.Copters;
|
||||
using Plane.FormationCreator.Formation;
|
||||
using Plane.Logging;
|
||||
using Plane.Windows;
|
||||
using Plane.Windows.Messages;
|
||||
using GalaSoft.MvvmLight.Ioc;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using Plane.CommunicationManagement;
|
||||
using Plane.FormationCreator.Util;
|
||||
|
||||
namespace Plane.FormationCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
public App()
|
||||
{
|
||||
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
|
||||
|
||||
ServiceLocatorConfigurer.Instance.Configure();
|
||||
_logger = ServiceLocator.Current.GetInstance<ILogger>();
|
||||
_copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
_formationController = ServiceLocator.Current.GetInstance<FormationController>();
|
||||
_mapManager = ServiceLocator.Current.GetInstance<MapManager>();
|
||||
|
||||
AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
|
||||
{
|
||||
var simpleName = new AssemblyName(e.Name).Name;
|
||||
if (simpleName.EndsWith(".resources"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return LoadAssembly(simpleName);
|
||||
};
|
||||
this.DispatcherUnhandledException += (s, e) =>
|
||||
{
|
||||
_logger.Log(e.Exception);
|
||||
// await _formationController.AllStop();
|
||||
TcpServerConnectionManager.Instance.StopListening();
|
||||
UdpServerConnectionManager.Instance.StopReceiving();
|
||||
};
|
||||
this.Exit += (s, e) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// TcpServerConnectionManager.Instance.StopListening();
|
||||
UdpServerConnectionManager.Instance.StopReceiving();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// RaiseExceptionThrown(ex);
|
||||
}
|
||||
|
||||
};
|
||||
//new Test().Prepare().Run();
|
||||
|
||||
VersionControl.GetVersionFromIni();
|
||||
}
|
||||
|
||||
private ILogger _logger;
|
||||
private CopterManager _copterManager;
|
||||
private FormationController _formationController;
|
||||
private MapManager _mapManager;
|
||||
|
||||
private Assembly LoadAssembly(string simpleName)
|
||||
{
|
||||
String resourceName = this.GetType().Namespace + ".AssemblyLoadingAndReflection." + simpleName + ".dll";
|
||||
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
|
||||
{
|
||||
Byte[] assemblyData = new Byte[stream.Length];
|
||||
stream.Read(assemblyData, 0, assemblyData.Length);
|
||||
return Assembly.Load(assemblyData);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
base.OnStartup(e);
|
||||
|
||||
var md = Resources.MergedDictionaries;
|
||||
// md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml") });
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml") });
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml") });
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Colors.xaml") });
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Styles.xaml") });
|
||||
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Plane.Windows.Messages;component/Styles.xaml") });
|
||||
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles/Colors.xaml") });
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles.xaml") });
|
||||
/*
|
||||
new UpdateChecker("http://dl.Plane.com/tools/ver.php?app=FormationCreator", _logger)
|
||||
.CheckAsync(ver =>
|
||||
{
|
||||
var currentVersion = this.GetType().Assembly.GetName().Version;
|
||||
if (currentVersion < ver
|
||||
&& Alert.Show("检测到新版本,请下载。", "更新提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
|
||||
{
|
||||
Process.Start("http://dl.Plane.com/tools/FormationCreatorSetup.exe");
|
||||
this.Shutdown();
|
||||
}
|
||||
});
|
||||
*/
|
||||
System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false;
|
||||
|
||||
MainWindow = new MainWindow();
|
||||
MainWindow.Show();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
/* by panxu tcp 不使用了 --使用TCP监听在自动获取IP的情况下,刚开始会导致界面无响应,过一会就好
|
||||
TcpServerConnectionManager.Instance.ConnectionEstablished += ConnectionManager_ConnectionEstablished;
|
||||
if (!TcpServerConnectionManager.Instance.StartListening())
|
||||
{
|
||||
Alert.Show("网络连接不正常,无法连接飞机。");
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
UdpServerConnectionManager.Instance.ExceptionThrown += (sender, e1) =>
|
||||
{
|
||||
_logger.Log(e1.Exception);
|
||||
};
|
||||
UdpServerConnectionManager.Instance.ConnectionEstablished += ConnectionManager_ConnectionEstablished;
|
||||
UdpServerConnectionManager.Instance.StartReceiving();
|
||||
*/
|
||||
|
||||
//初始化地面站连接
|
||||
CommModuleManager.Instance.CommunicationReceived += CommtionReceivedCopterInfo;
|
||||
CommModuleManager.Instance.CommunicationCopterDisconnect += CommCopterDisconnect;
|
||||
CommModuleManager.Instance.CommunicationConnected += CommCopterconnected;
|
||||
CommModuleManager.Instance.Connect();
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Alert.Show("网络连接不正常,无法连接飞机。");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExit(ExitEventArgs e)
|
||||
{
|
||||
CommModuleManager.Instance.CloseConnection();
|
||||
base.OnExit(e);
|
||||
}
|
||||
|
||||
|
||||
private void Copter_TextReceived(object sender, MessageCreatedEventArgs e)
|
||||
{
|
||||
_logger.Log(e.Message );
|
||||
}
|
||||
private async Task AddOrUpdateCopter(string ip, IConnection Connection)
|
||||
{
|
||||
var copters = _copterManager.Copters;
|
||||
var copterStatus = _copterManager.CopterStatus;
|
||||
|
||||
var copter = copters.FirstOrDefault(c => c.Id == ip);
|
||||
if (copter == null)
|
||||
{
|
||||
await Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
copter = new Copter(Connection, SynchronizationContext.Current, _mapManager.Center.Lat, _mapManager.Center.Lng)
|
||||
{
|
||||
Id = ip,
|
||||
Name = ip.Substring(ip.LastIndexOf('.') + 1)
|
||||
|
||||
};
|
||||
int _index;
|
||||
_index=copters.AddCopter(copter);
|
||||
copterStatus.Insert(_index,false);
|
||||
copter.TextReceived += Copter_TextReceived;
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
copter.Connection = Connection;
|
||||
}
|
||||
await copter.ConnectAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async void ConnectionManager_ConnectionEstablished(object sender, ConnectionEstablishedEventArgs e)
|
||||
{
|
||||
await AddOrUpdateCopter(e.RemoteAddress, e.Connection);
|
||||
}
|
||||
|
||||
private async void CommtionReceivedCopterInfo(object sender, CommunicationReceiveCopterInfoEventArgs e)
|
||||
{
|
||||
await UpdateCommCopterInfo(e.Id, e.Package, e.CommModuleVersion);
|
||||
//await TaskUtils.CompletedTask;
|
||||
}
|
||||
|
||||
private async void CommCopterDisconnect(object sender, CommunicationCopterDisconnectEventArgs e)
|
||||
{
|
||||
await DisconnectCopter(e.Id);
|
||||
}
|
||||
|
||||
private async void CommCopterconnected(object sender, CommunicationConnectEventArgs e)
|
||||
{
|
||||
await AddCommCopter(e.Id);
|
||||
}
|
||||
|
||||
private async Task DisconnectCopter(int id)
|
||||
{
|
||||
var copters = _copterManager.Copters;
|
||||
var copter = copters.FirstOrDefault(c => c.Id == id.ToString());
|
||||
if (copter != null)
|
||||
{
|
||||
if (copter is PLCopter)
|
||||
{
|
||||
PLCopter plcopter = (PLCopter)copter;
|
||||
plcopter.CommModuleConnected = false;
|
||||
}
|
||||
}
|
||||
await TaskUtils.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
private static readonly object locker = new object();
|
||||
private async Task AddCommCopter(int id)
|
||||
{
|
||||
await Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
lock(locker)
|
||||
{
|
||||
var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == id.ToString());
|
||||
if (copter == null)
|
||||
{
|
||||
var copterStatus = _copterManager.CopterStatus;
|
||||
var connection = new CommConnection();
|
||||
copter = new Copter(connection, SynchronizationContext.Current, _mapManager.Center.Lat, _mapManager.Center.Lng)
|
||||
{
|
||||
Id = id.ToString(),
|
||||
Name = id.ToString(),
|
||||
};
|
||||
int _index;
|
||||
_index = _copterManager.Copters.AddCopter(copter);
|
||||
copterStatus.Insert(_index, false);
|
||||
copter.TextReceived += Copter_TextReceived;
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private async Task UpdateCommCopterInfo(int id, byte[] package, byte CommModuleVersion)
|
||||
{
|
||||
await AddCommCopter(id);
|
||||
lock (locker)
|
||||
{
|
||||
var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == id.ToString());
|
||||
if (copter!= null && copter is PLCopter)
|
||||
{
|
||||
PLCopter plcopter = (PLCopter)copter;
|
||||
if (!plcopter.CommModuleConnected) plcopter.CommModuleConnected = true;
|
||||
plcopter.InternalCopter.AnalyzeCommMouldePositionIntPacket(package, CommModuleVersion);
|
||||
plcopter.CommModuleConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
using Plane.Communication;
|
||||
using Plane.Copters;
|
||||
using Plane.FormationCreator.Formation;
|
||||
using Plane.Logging;
|
||||
using Plane.Windows;
|
||||
using Plane.Windows.Messages;
|
||||
using GalaSoft.MvvmLight.Ioc;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
using Plane.FormationCreator.Util;
|
||||
using Plane.CommunicationManagement;
|
||||
|
||||
namespace Plane.FormationCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
public App()
|
||||
{
|
||||
VersionControl.GetSettingFromIni();
|
||||
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
|
||||
|
||||
ServiceLocatorConfigurer.Instance.Configure();
|
||||
_logger = ServiceLocator.Current.GetInstance<ILogger>();
|
||||
_copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
_formationController = ServiceLocator.Current.GetInstance<FormationController>();
|
||||
_mapManager = ServiceLocator.Current.GetInstance<MapManager>();
|
||||
|
||||
AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
|
||||
{
|
||||
var simpleName = new AssemblyName(e.Name).Name;
|
||||
if (simpleName.EndsWith(".resources"))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return LoadAssembly(simpleName);
|
||||
};
|
||||
this.DispatcherUnhandledException += (s, e) =>
|
||||
{
|
||||
_logger.Log(e.Exception);
|
||||
// await _formationController.AllStop();
|
||||
TcpServerConnectionManager.Instance.StopListening();
|
||||
UdpServerConnectionManager.Instance.StopReceiving();
|
||||
};
|
||||
this.Exit += (s, e) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// TcpServerConnectionManager.Instance.StopListening();
|
||||
UdpServerConnectionManager.Instance.StopReceiving();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// RaiseExceptionThrown(ex);
|
||||
}
|
||||
|
||||
};
|
||||
//new Test().Prepare().Run();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private ILogger _logger;
|
||||
private CopterManager _copterManager;
|
||||
private FormationController _formationController;
|
||||
private MapManager _mapManager;
|
||||
|
||||
private Assembly LoadAssembly(string simpleName)
|
||||
{
|
||||
String resourceName = this.GetType().Namespace + ".AssemblyLoadingAndReflection." + simpleName + ".dll";
|
||||
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
|
||||
{
|
||||
Byte[] assemblyData = new Byte[stream.Length];
|
||||
stream.Read(assemblyData, 0, assemblyData.Length);
|
||||
return Assembly.Load(assemblyData);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
base.OnStartup(e);
|
||||
|
||||
var md = Resources.MergedDictionaries;
|
||||
// md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml") });
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml") });
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml") });
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Colors.xaml") });
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/MahApps.Metro;component/Styles/VS/Styles.xaml") });
|
||||
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Plane.Windows.Messages;component/Styles.xaml") });
|
||||
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles/Colors.xaml") });
|
||||
md.Add(new ResourceDictionary { Source = new Uri("pack://application:,,,/Styles.xaml") });
|
||||
/*
|
||||
new UpdateChecker("http://dl.Plane.com/tools/ver.php?app=FormationCreator", _logger)
|
||||
.CheckAsync(ver =>
|
||||
{
|
||||
var currentVersion = this.GetType().Assembly.GetName().Version;
|
||||
if (currentVersion < ver
|
||||
&& Alert.Show("检测到新版本,请下载。", "更新提示", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
|
||||
{
|
||||
Process.Start("http://dl.Plane.com/tools/FormationCreatorSetup.exe");
|
||||
this.Shutdown();
|
||||
}
|
||||
});
|
||||
*/
|
||||
System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false;
|
||||
|
||||
MainWindow = new MainWindow();
|
||||
MainWindow.Show();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
/* by panxu tcp 不使用了 --使用TCP监听在自动获取IP的情况下,刚开始会导致界面无响应,过一会就好
|
||||
TcpServerConnectionManager.Instance.ConnectionEstablished += ConnectionManager_ConnectionEstablished;
|
||||
if (!TcpServerConnectionManager.Instance.StartListening())
|
||||
{
|
||||
Alert.Show("网络连接不正常,无法连接飞机。");
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
if (VersionControl.ConType == 1)
|
||||
{
|
||||
CommModuleManager.Instance.UseTransModule = false;
|
||||
UdpServerConnectionManager.Instance.ExceptionThrown += (sender, e1) =>
|
||||
{
|
||||
_logger.Log(e1.Exception);
|
||||
};
|
||||
UdpServerConnectionManager.Instance.ConnectionEstablished += ConnectionManager_ConnectionEstablished;
|
||||
UdpServerConnectionManager.Instance.StartReceiving();
|
||||
}
|
||||
else
|
||||
{
|
||||
CommModuleManager.Instance.UseTransModule = true;
|
||||
//初始化地面站连接
|
||||
CommModuleManager.Instance.CommunicationReceived += CommtionReceivedCopterInfo;
|
||||
CommModuleManager.Instance.CommunicationCopterDisconnect += CommCopterDisconnect;
|
||||
CommModuleManager.Instance.CommunicationConnected += CommCopterconnected;
|
||||
CommModuleManager.Instance.Connect();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Alert.Show("网络连接不正常,无法连接飞机。");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnExit(ExitEventArgs e)
|
||||
{
|
||||
CommModuleManager.Instance.CloseConnection();
|
||||
base.OnExit(e);
|
||||
}
|
||||
|
||||
|
||||
private void Copter_TextReceived(object sender, MessageCreatedEventArgs e)
|
||||
{
|
||||
_logger.Log(e.Message );
|
||||
}
|
||||
//wifi模式添加飞机
|
||||
private async Task AddOrUpdateCopter(string ip, IConnection Connection)
|
||||
{
|
||||
var copters = _copterManager.Copters;
|
||||
var copterStatus = _copterManager.CopterStatus;
|
||||
|
||||
string[] iparr = ip.Split('.');
|
||||
string vIPID = String.Format("{0:D3}", int.Parse(iparr[2])) + String.Format("{0:D3}", int.Parse(iparr[3]));
|
||||
|
||||
var copter = copters.FirstOrDefault(c => c.Id == vIPID);
|
||||
if (copter == null)
|
||||
{
|
||||
if (!_copterManager.EnAddCopter_Real())
|
||||
{
|
||||
UdpServerConnectionManager.Instance.DeleteConnections(ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
|
||||
|
||||
copter = new Copter(Connection, SynchronizationContext.Current, _mapManager.Center.Lat, _mapManager.Center.Lng)
|
||||
{
|
||||
Id = vIPID,
|
||||
Name = vIPID // ip.Substring(ip.LastIndexOf('.') + 1)
|
||||
};
|
||||
int _index;
|
||||
_index = copters.AddCopter(copter, _copterManager.SortType);
|
||||
copterStatus.Insert(_index, false);
|
||||
copter.TextReceived += Copter_TextReceived;
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copter.Connection = Connection;
|
||||
}
|
||||
if (copter!=null)
|
||||
await copter.ConnectAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async void ConnectionManager_ConnectionEstablished(object sender, ConnectionEstablishedEventArgs e)
|
||||
{
|
||||
await AddOrUpdateCopter(e.RemoteAddress, e.Connection);
|
||||
}
|
||||
|
||||
private async void CommtionReceivedCopterInfo(object sender, CommunicationReceiveCopterInfoEventArgs e)
|
||||
{
|
||||
await UpdateCommCopterInfo(e.Id, e.Package, e.CommModuleVersion);
|
||||
//await TaskUtils.CompletedTask;
|
||||
}
|
||||
|
||||
private async void CommCopterDisconnect(object sender, CommunicationCopterDisconnectEventArgs e)
|
||||
{
|
||||
await DisconnectCopter(e.Id);
|
||||
}
|
||||
|
||||
private async void CommCopterconnected(object sender, CommunicationConnectEventArgs e)
|
||||
{
|
||||
await AddCommCopter(e.Id);
|
||||
}
|
||||
|
||||
private async Task DisconnectCopter(int id)
|
||||
{
|
||||
var copters = _copterManager.Copters;
|
||||
var copter = copters.FirstOrDefault(c => c.Id == id.ToString());
|
||||
if (copter != null)
|
||||
{
|
||||
if (copter is PLCopter)
|
||||
{
|
||||
PLCopter plcopter = (PLCopter)copter;
|
||||
plcopter.CommModuleConnected = false;
|
||||
}
|
||||
}
|
||||
await TaskUtils.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
private static readonly object locker = new object();
|
||||
private async Task AddCommCopter(int id)
|
||||
{
|
||||
await Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
lock(locker)
|
||||
{
|
||||
var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == id.ToString());
|
||||
if ((copter != null)&&(copter is FakeCopter))
|
||||
{
|
||||
_copterManager.Copters.Remove(copter);
|
||||
copter = null;
|
||||
}
|
||||
|
||||
|
||||
if (copter == null)
|
||||
{
|
||||
if (_copterManager.EnAddCopter_Real())
|
||||
{
|
||||
|
||||
var copterStatus = _copterManager.CopterStatus;
|
||||
var connection = new CommConnection();
|
||||
copter = new Copter(connection, SynchronizationContext.Current, _mapManager.Center.Lat, _mapManager.Center.Lng)
|
||||
{
|
||||
Id = id.ToString(),
|
||||
Name = id.ToString(),
|
||||
};
|
||||
copter.VirtualId = 0;
|
||||
int _index;
|
||||
_index = _copterManager.Copters.AddCopter(copter, _copterManager.SortType);
|
||||
copterStatus.Insert(_index, false);
|
||||
copter.TextReceived += Copter_TextReceived;
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private async Task UpdateCommCopterInfo(int id, byte[] package, byte CommModuleVersion)
|
||||
{
|
||||
await AddCommCopter(id);
|
||||
lock (locker)
|
||||
{
|
||||
var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == id.ToString());
|
||||
if (copter!= null && copter is PLCopter)
|
||||
{
|
||||
PLCopter plcopter = (PLCopter)copter;
|
||||
if (!plcopter.CommModuleConnected) plcopter.CommModuleConnected = true;
|
||||
plcopter.InternalCopter.AnalyzeCommMouldePositionIntPacket(package, CommModuleVersion);
|
||||
plcopter.CommModuleConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace Plane.FormationCreator
|
||||
}
|
||||
}
|
||||
|
||||
private bool _ShowModifyTaskView = true;
|
||||
private bool _ShowModifyTaskView = false;
|
||||
public bool ShowModifyTaskView
|
||||
{
|
||||
get { return _ShowModifyTaskView; }
|
||||
|
@ -17,7 +17,8 @@ namespace Plane.FormationCreator.Converters
|
||||
{
|
||||
static DropShadowEffect _effect = new DropShadowEffect
|
||||
{
|
||||
Color = Colors.LightGray,
|
||||
//任务选中颜色
|
||||
Color = Colors.Firebrick, // Colors.LightGray,
|
||||
// Color = Colors.White,
|
||||
Direction = 90,
|
||||
BlurRadius = 10
|
||||
|
@ -26,6 +26,9 @@ namespace Plane.FormationCreator.Converters
|
||||
if (status == FlightTaskStatus.Paused)
|
||||
return _PausedFill;
|
||||
|
||||
if (status == FlightTaskStatus.Selected)
|
||||
return _PausedFill;
|
||||
|
||||
|
||||
return _normalFill;
|
||||
}
|
||||
|
@ -1,34 +1,87 @@
|
||||
using Plane.Copters;
|
||||
using Plane.FormationCreator.Formation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Plane.FormationCreator.Converters
|
||||
{
|
||||
public class HeartbeatCountToBrushConverter : IMultiValueConverter
|
||||
{
|
||||
private static SolidColorBrush _zeroBrush = new SolidColorBrush(Color.FromArgb(125, 125, 125, 125));
|
||||
private static SolidColorBrush _oneBrush = Copter.DefaultBrush;
|
||||
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values[0] == DependencyProperty.UnsetValue) return _zeroBrush;
|
||||
var heartbeatCount = (ulong)values[0];
|
||||
if (heartbeatCount % 2 == 0) return _zeroBrush;
|
||||
var copter = values[1] as Copter;
|
||||
return copter == null ? _oneBrush : copter.Brush;
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
using Plane.Copters;
|
||||
using Plane.FormationCreator.Formation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Plane.FormationCreator.Converters
|
||||
{
|
||||
public class HeartbeatCountToBrushConverter : IMultiValueConverter
|
||||
{
|
||||
private static SolidColorBrush _zeroBrush = new SolidColorBrush(Color.FromArgb(125, 125, 125, 125));
|
||||
|
||||
private static SolidColorBrush _zeroBrush_fault = new SolidColorBrush(Color.FromRgb(160, 140, 0));
|
||||
|
||||
private static SolidColorBrush _oneBrush = Copter.DefaultBrush;
|
||||
|
||||
private static SolidColorBrush _FakeCopterBrush = Copter.DefaultFakeBrush;
|
||||
private static SolidColorBrush _PreCheckNopassBrush = Copter.YellowBrush;
|
||||
private static SolidColorBrush _NoconnectedBrush = Copter.RedBrush;
|
||||
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values[0] == DependencyProperty.UnsetValue) return _zeroBrush;
|
||||
var heartbeatCount = (ulong)values[0];
|
||||
/* //绑定的是心跳,所以连接断开时不会调用这个转换器
|
||||
//如果是真飞机,并且断开了,直接显示红色
|
||||
if (values[1] is PLCopter)
|
||||
{
|
||||
var plcopter = values[1] as PLCopter;
|
||||
if (!plcopter.CommModuleConnected)
|
||||
return _NoconnectedBrush;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//用于显示收到心跳的闪烁
|
||||
if (heartbeatCount % 2 == 0)
|
||||
{
|
||||
//真飞机如果异常显示暗淡黄色
|
||||
if (values[1] is PLCopter)
|
||||
{
|
||||
var plcopter = values[1] as PLCopter;
|
||||
if (plcopter.CopterPreCheckPass)
|
||||
return _zeroBrush;
|
||||
else return _zeroBrush_fault;
|
||||
|
||||
}
|
||||
else
|
||||
return _zeroBrush;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (values[1] is FakeCopter)
|
||||
{
|
||||
var fkcopter = values[1] as FakeCopter;
|
||||
if (fkcopter.CopterPreCheckPass)
|
||||
return _FakeCopterBrush;
|
||||
else return _PreCheckNopassBrush;
|
||||
}
|
||||
|
||||
if (values[1] is PLCopter)
|
||||
{
|
||||
var plcopter = values[1] as PLCopter;
|
||||
if (plcopter.CopterPreCheckPass)
|
||||
return _oneBrush;
|
||||
else return _PreCheckNopassBrush;
|
||||
|
||||
}
|
||||
var copter = values[1] as Copter;
|
||||
return copter == null ? _oneBrush : copter.Brush;
|
||||
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,55 +1,75 @@
|
||||
using Plane.Copters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plane.Communication;
|
||||
using System.Threading;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
class Copter : PLCopter
|
||||
{
|
||||
public Copter(IConnection Connection, SynchronizationContext uiThreadContext) : base(Connection, uiThreadContext,false)
|
||||
{
|
||||
Brush = _brushes[NextBrushIndex()];
|
||||
|
||||
}
|
||||
|
||||
public Copter(IConnection Connection, SynchronizationContext uiThreadContext, double lat, double lng) : base(Connection, uiThreadContext, false)
|
||||
{
|
||||
Brush = _brushes[NextBrushIndex()];
|
||||
RecordLat = lat;
|
||||
RecordLng = lng;
|
||||
Latitude = lat;
|
||||
Longitude = lng;
|
||||
//RaiseLocationChangedIfNeeded();
|
||||
}
|
||||
|
||||
static SolidColorBrush[] _brushes = new[]
|
||||
{
|
||||
new SolidColorBrush(Color.FromArgb(180, 255, 0, 0)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 235, 97, 0)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 255, 255, 0)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 0, 255, 0)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 0, 198, 255)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 0, 122, 204)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 174, 0, 255))
|
||||
};
|
||||
static int _brushIndex = 0;
|
||||
static int NextBrushIndex()
|
||||
{
|
||||
return _brushIndex++ % _brushes.Length;
|
||||
}
|
||||
|
||||
internal static SolidColorBrush DefaultBrush { get; } = new SolidColorBrush(Color.FromRgb(28, 151, 234));
|
||||
private SolidColorBrush _Brush;
|
||||
public SolidColorBrush Brush
|
||||
{
|
||||
get { return _Brush ?? DefaultBrush; }
|
||||
set { Set(nameof(Brush), ref _Brush, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
using Plane.Copters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plane.Communication;
|
||||
using System.Threading;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
class Copter : PLCopter
|
||||
{
|
||||
public Copter(IConnection Connection, SynchronizationContext uiThreadContext) : base(Connection, uiThreadContext,false)
|
||||
{
|
||||
Brush = _brushes[NextBrushIndex()];
|
||||
|
||||
}
|
||||
|
||||
public Copter(IConnection Connection, SynchronizationContext uiThreadContext, double lat, double lng) : base(Connection, uiThreadContext, false)
|
||||
{
|
||||
Brush = _brushes[NextBrushIndex()];
|
||||
RecordLat = lat;
|
||||
RecordLng = lng;
|
||||
Latitude = lat;
|
||||
Longitude = lng;
|
||||
//RaiseLocationChangedIfNeeded();
|
||||
}
|
||||
|
||||
|
||||
internal static SolidColorBrush BlueBrush { get; } = new SolidColorBrush(Color.FromRgb(28, 151, 234));
|
||||
internal static SolidColorBrush RedBrush { get; } = new SolidColorBrush(Color.FromRgb(255, 100, 100));
|
||||
internal static SolidColorBrush GreenBrush { get; } = new SolidColorBrush(Color.FromRgb(100, 255, 100));
|
||||
internal static SolidColorBrush YellowBrush { get; } = new SolidColorBrush(Color.FromRgb(255, 215, 0));
|
||||
|
||||
|
||||
|
||||
static SolidColorBrush[] _brushes = new[]
|
||||
{
|
||||
new SolidColorBrush(Color.FromArgb(180, 255, 0, 0)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 235, 97, 0)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 255, 255, 0)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 0, 255, 0)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 0, 198, 255)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 0, 122, 204)),
|
||||
new SolidColorBrush(Color.FromArgb(180, 174, 0, 255))
|
||||
};
|
||||
static int _brushIndex = 0;
|
||||
static int NextBrushIndex()
|
||||
{
|
||||
return _brushIndex++ % _brushes.Length;
|
||||
}
|
||||
//真实飞机列表默认颜色
|
||||
internal static SolidColorBrush DefaultBrush { get; } = GreenBrush;// new SolidColorBrush(Color.FromRgb(50, 205, 50));
|
||||
//虚拟飞机列表默认颜色
|
||||
internal static SolidColorBrush DefaultFakeBrush { get; } = BlueBrush;
|
||||
|
||||
|
||||
|
||||
|
||||
private SolidColorBrush _Brush;
|
||||
public SolidColorBrush Brush
|
||||
{
|
||||
get {
|
||||
if (CopterPreCheckPass)
|
||||
return _Brush ?? DefaultBrush;
|
||||
else
|
||||
return _Brush ?? YellowBrush;
|
||||
|
||||
}
|
||||
set { Set(nameof(Brush), ref _Brush, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ namespace Plane.FormationCreator.Formation
|
||||
public static double DistanceTo(this ICopter copter, ICopter copter2)
|
||||
{
|
||||
return GeographyUtils.CalcDistance(copter.Latitude, copter.Longitude, copter.Altitude, copter2.Latitude, copter2.Longitude, copter2.Altitude);
|
||||
//return GeographyUtils.CalcDistance_simple(copter.Latitude, copter.Longitude, copter.Altitude, copter2.Latitude, copter2.Longitude, copter2.Altitude);
|
||||
}
|
||||
|
||||
public static double InPlaneDistanceTo(this ICopter copter, double targetLat, double targetLng)
|
||||
@ -81,8 +82,10 @@ namespace Plane.FormationCreator.Formation
|
||||
|
||||
public static bool IsTooCloseTo(this ICopter copter, ICopter copter2, out double distance)
|
||||
{
|
||||
// distance = 0;
|
||||
// return false; //效果图用 不检测碰撞
|
||||
distance = Math.Round(copter.DistanceTo(copter2), 2) ;
|
||||
//return false; //效果图用 不检测碰撞
|
||||
|
||||
if (copter.Altitude < 3 || copter2.Altitude < 3)
|
||||
return false;
|
||||
|
||||
|
@ -1,198 +1,196 @@
|
||||
using Plane.Copters;
|
||||
using Plane.Logging;
|
||||
using GalaSoft.MvvmLight;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTask : ObservableObject
|
||||
{
|
||||
public FlightTask(FlightTaskType type)
|
||||
{
|
||||
TaskType = type;
|
||||
}
|
||||
|
||||
private FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
|
||||
|
||||
private ILogger _logger = ServiceLocator.Current.GetInstance<ILogger>();
|
||||
|
||||
private FlightTaskStatus _Status = FlightTaskStatus.Stop;
|
||||
public FlightTaskStatus Status
|
||||
{
|
||||
get { return _Status; }
|
||||
set { Set(nameof(Status), ref _Status, value); }
|
||||
}
|
||||
|
||||
private FlightTaskType _TaskType;
|
||||
public FlightTaskType TaskType
|
||||
{
|
||||
get { return _TaskType; }
|
||||
set
|
||||
{
|
||||
|
||||
Set(nameof(TaskType), ref _TaskType, value);
|
||||
//if (_TaskType != value)
|
||||
{
|
||||
RaisePropertyChanged(nameof(TaskTypeIndex));
|
||||
RaisePropertyChanged(nameof(TaskCnName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public int TaskTypeIndex
|
||||
{
|
||||
get { return (int)TaskType; }
|
||||
set
|
||||
{
|
||||
TaskType = (FlightTaskType)value;
|
||||
VerticalLift = false;
|
||||
if ( (value == (int)FlightTaskType.Loiter) || (value == (int)FlightTaskType.Circle) )
|
||||
{
|
||||
VerticalLift = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
private string _TaskName = "";
|
||||
public string TaskCnName
|
||||
{
|
||||
get
|
||||
{
|
||||
string name = "";
|
||||
switch (TaskType)
|
||||
{
|
||||
case FlightTaskType.TakeOff: name = "起飞"; break;
|
||||
case FlightTaskType.FlyTo: name = _TaskName == "" ? "航点" : _TaskName; break;
|
||||
case FlightTaskType.Land: name = "降落"; break;
|
||||
}
|
||||
//name = (TaskIndex + 1).ToString() + "." + name;
|
||||
return name;
|
||||
}
|
||||
set { Set(nameof(TaskCnName), ref _TaskName, value); }
|
||||
}
|
||||
|
||||
public int TaskTypeIndex
|
||||
{
|
||||
get {
|
||||
int index = 1;
|
||||
switch (TaskType)
|
||||
{
|
||||
case FlightTaskType.TakeOff:index = 0; break;
|
||||
case FlightTaskType.FlyTo: index = 1; break;
|
||||
case FlightTaskType.Land: index = 2; break;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
set
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0: TaskType = FlightTaskType.TakeOff; break;
|
||||
case 1: TaskType = FlightTaskType.FlyTo; break;
|
||||
case 2: TaskType = FlightTaskType.Land; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//task在所以任务中的index
|
||||
public int TaskIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return _flightTaskManager.Tasks.IndexOf(this);
|
||||
}
|
||||
}
|
||||
|
||||
public int TaskNum
|
||||
{
|
||||
get
|
||||
{
|
||||
return TaskIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _IsSelected;
|
||||
public bool IsSelected
|
||||
{
|
||||
get { return _IsSelected; }
|
||||
set { Set(nameof(IsSelected), ref _IsSelected, value); }
|
||||
}
|
||||
|
||||
// 右键单击任务,用于隐藏任务图标, added by ZJF
|
||||
private bool _IsRightSelected;
|
||||
public bool IsRightSelected
|
||||
{
|
||||
get { return _IsRightSelected; }
|
||||
set { Set(nameof(IsRightSelected), ref _IsRightSelected, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public List<FlightTaskSingleCopterInfo> SingleCopterInfos { get; set; } = new List<FlightTaskSingleCopterInfo>();
|
||||
|
||||
private FlightTaskSingleCopterInfo _ModifyingSingleCopterInfo;
|
||||
public FlightTaskSingleCopterInfo ModifyingSingleCopterInfo
|
||||
{
|
||||
get { return _ModifyingSingleCopterInfo; }
|
||||
set { Set(nameof(ModifyingSingleCopterInfo), ref _ModifyingSingleCopterInfo, value); }
|
||||
}
|
||||
|
||||
public async Task RunAsync()
|
||||
{
|
||||
switch (TaskType)
|
||||
{
|
||||
case FlightTaskType.FlyTo:
|
||||
await RunFlyToTaskAsync().ConfigureAwait(false);
|
||||
break;
|
||||
case FlightTaskType.Turn:
|
||||
await RunTurnTaskAsync().ConfigureAwait(false);
|
||||
break;
|
||||
case FlightTaskType.Circle:
|
||||
await RunCircleTaskAsync().ConfigureAwait(false);
|
||||
break;
|
||||
case FlightTaskType.SimpleCircle:
|
||||
await RunSimpleCircleTaskAsync().ConfigureAwait(false);
|
||||
break;
|
||||
case FlightTaskType.Loiter:
|
||||
await RunLoiterTimeTaskAsync().ConfigureAwait(false);
|
||||
break;
|
||||
case FlightTaskType.TakeOff:
|
||||
//多架同时起飞
|
||||
//await MutilRunTakeOffTaskAsync().ConfigureAwait(false);
|
||||
await NewMutilRunTakeOffTaskAsync().ConfigureAwait(false);
|
||||
break;
|
||||
case FlightTaskType.ReturnToLand: // Added by ZJF
|
||||
//多架同时返航
|
||||
await MutilRunReturnToLandTaskAsync().ConfigureAwait(false);
|
||||
break;
|
||||
case FlightTaskType.Land:
|
||||
await MutilLandTaskAsync().ConfigureAwait(false);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum FlightTaskType
|
||||
{
|
||||
FlyTo = 0,
|
||||
Turn = 1,
|
||||
Circle = 2,
|
||||
Loiter = 3, // 加入悬停时间选项
|
||||
// LEDAction = 4,
|
||||
ReturnToLand = 4, // added by ZJF. 20160315
|
||||
SimpleCircle = 5,
|
||||
Land = 6,
|
||||
TakeOff = 100
|
||||
}
|
||||
}
|
||||
using Plane.Copters;
|
||||
using Plane.Logging;
|
||||
using GalaSoft.MvvmLight;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTask : ObservableObject
|
||||
{
|
||||
public FlightTask(FlightTaskType type)
|
||||
{
|
||||
TaskType = type;
|
||||
}
|
||||
|
||||
private FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
|
||||
|
||||
private ILogger _logger = ServiceLocator.Current.GetInstance<ILogger>();
|
||||
|
||||
private FlightTaskStatus _Status = FlightTaskStatus.Stop;
|
||||
public FlightTaskStatus Status
|
||||
{
|
||||
get { return _Status; }
|
||||
set { Set(nameof(Status), ref _Status, value); }
|
||||
}
|
||||
|
||||
private FlightTaskType _TaskType;
|
||||
public FlightTaskType TaskType
|
||||
{
|
||||
get { return _TaskType; }
|
||||
set
|
||||
{
|
||||
Set(nameof(TaskType), ref _TaskType, value);
|
||||
RaisePropertyChanged(nameof(TaskTypeIndex));
|
||||
RaisePropertyChanged(nameof(TaskCnName));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public int TaskTypeIndex
|
||||
{
|
||||
get { return (int)TaskType; }
|
||||
set
|
||||
{
|
||||
TaskType = (FlightTaskType)value;
|
||||
VerticalLift = false;
|
||||
if ( (value == (int)FlightTaskType.Loiter) || (value == (int)FlightTaskType.Circle) )
|
||||
{
|
||||
VerticalLift = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
private string _TaskName = "";
|
||||
public string TaskCnName
|
||||
{
|
||||
get
|
||||
{
|
||||
string name = "";
|
||||
switch (TaskType)
|
||||
{
|
||||
case FlightTaskType.TakeOff: name = "起飞"; break;
|
||||
case FlightTaskType.FlyTo: name = _TaskName == "" ? "航点" : _TaskName; break;
|
||||
case FlightTaskType.Land: name = "降落"; break;
|
||||
}
|
||||
//name = (TaskIndex + 1).ToString() + "." + name;
|
||||
return name;
|
||||
}
|
||||
set {
|
||||
|
||||
Set(nameof(TaskCnName), ref _TaskName, value);
|
||||
RaisePropertyChanged(nameof(TaskCnName));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public int TaskTypeIndex
|
||||
{
|
||||
get {
|
||||
int index = 1;
|
||||
switch (TaskType)
|
||||
{
|
||||
case FlightTaskType.TakeOff:index = 0; break;
|
||||
case FlightTaskType.FlyTo: index = 1; break;
|
||||
case FlightTaskType.Land: index = 2; break;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
set
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0: TaskType = FlightTaskType.TakeOff; break;
|
||||
case 1: TaskType = FlightTaskType.FlyTo; break;
|
||||
case 2: TaskType = FlightTaskType.Land; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//task在所以任务中的index
|
||||
public int TaskIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return _flightTaskManager.Tasks.IndexOf(this);
|
||||
}
|
||||
}
|
||||
|
||||
public int TaskNum
|
||||
{
|
||||
get
|
||||
{
|
||||
return TaskIndex + 1;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _IsTransition=false;
|
||||
public bool IsTransition
|
||||
{
|
||||
get { return _IsTransition; }
|
||||
set {
|
||||
|
||||
Set(nameof(IsTransition), ref _IsTransition, value);
|
||||
if ((value)&& (TaskCnName == "航点"))
|
||||
TaskCnName = "过度";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private bool _IsSelected;
|
||||
public bool IsSelected
|
||||
{
|
||||
get { return _IsSelected; }
|
||||
set { Set(nameof(IsSelected), ref _IsSelected, value); }
|
||||
}
|
||||
|
||||
// 右键单击任务,用于隐藏任务图标, added by ZJF
|
||||
private bool _IsRightSelected;
|
||||
public bool IsRightSelected
|
||||
{
|
||||
get { return _IsRightSelected; }
|
||||
set { Set(nameof(IsRightSelected), ref _IsRightSelected, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public List<FlightTaskSingleCopterInfo> SingleCopterInfos { get; set; } = new List<FlightTaskSingleCopterInfo>();
|
||||
|
||||
private FlightTaskSingleCopterInfo _ModifyingSingleCopterInfo;
|
||||
public FlightTaskSingleCopterInfo ModifyingSingleCopterInfo
|
||||
{
|
||||
get { return _ModifyingSingleCopterInfo; }
|
||||
set { Set(nameof(ModifyingSingleCopterInfo), ref _ModifyingSingleCopterInfo, value); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 实际执行某一个任务--包含等待
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public async Task RunAsync()
|
||||
{
|
||||
switch (TaskType)
|
||||
{
|
||||
case FlightTaskType.FlyTo:
|
||||
await RunFlyToTaskAsync().ConfigureAwait(false);
|
||||
break;
|
||||
case FlightTaskType.TakeOff:
|
||||
await NewMutilRunTakeOffTaskAsync().ConfigureAwait(false);
|
||||
break;
|
||||
case FlightTaskType.Land:
|
||||
await MutilLandTaskAsync().ConfigureAwait(false);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum FlightTaskType
|
||||
{
|
||||
FlyTo = 0,
|
||||
Land = 6,
|
||||
TakeOff = 100
|
||||
}
|
||||
}
|
||||
|
@ -1,68 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plane.Copters;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTaskSingleCopterInfo
|
||||
{
|
||||
public static FlightTaskSingleCopterInfo CreateForCircleTask(ICopter copter, LatLng latLngOffset, float targetAlt, short centerDirectionDeg, int radius, int rate, int turns, ushort channel3)
|
||||
{
|
||||
var info = new FlightTaskSingleCopterInfo(copter)
|
||||
{
|
||||
LatLngOffset = latLngOffset,
|
||||
TargetAlt = targetAlt,
|
||||
CenterDirectionDeg = centerDirectionDeg,
|
||||
Radius = radius,
|
||||
Rate = rate,
|
||||
Turns = turns,
|
||||
Channel3 = channel3
|
||||
};
|
||||
return info;
|
||||
}
|
||||
|
||||
private short _CenterDirectionDeg;
|
||||
public short CenterDirectionDeg
|
||||
{
|
||||
get { return _CenterDirectionDeg; }
|
||||
set { Set(nameof(CenterDirectionDeg), ref _CenterDirectionDeg, value); }
|
||||
}
|
||||
|
||||
private int _Radius = 1000;
|
||||
/// <summary>
|
||||
/// 圆的半径,单位为厘米。
|
||||
/// </summary>
|
||||
public int Radius
|
||||
{
|
||||
get { return _Radius; }
|
||||
set { Set(nameof(Radius), ref _Radius, value); }
|
||||
}
|
||||
|
||||
private int _Rate = 20;
|
||||
/// <summary>
|
||||
/// 转圈的角速度,单位为 deg/s,范围为 -90 到 90。
|
||||
/// </summary>
|
||||
public int Rate
|
||||
{
|
||||
get { return _Rate; }
|
||||
set { Set(nameof(Rate), ref _Rate, value); }
|
||||
}
|
||||
|
||||
private int _Turns = 1;
|
||||
public int Turns
|
||||
{
|
||||
get { return _Turns; }
|
||||
set { Set(nameof(Turns), ref _Turns, value); }
|
||||
}
|
||||
|
||||
private ushort _Channel3 = 1500;
|
||||
public ushort Channel3
|
||||
{
|
||||
get { return _Channel3; }
|
||||
set { Set(nameof(Channel3), ref _Channel3, value); }
|
||||
}
|
||||
}
|
||||
}
|
@ -61,7 +61,16 @@ namespace Plane.FormationCreator.Formation
|
||||
public bool IsLandWaypoint
|
||||
{
|
||||
get { return _IsLandWaypoint; }
|
||||
set { Set(nameof(IsLandWaypoint), ref _IsLandWaypoint, value); }
|
||||
set {
|
||||
|
||||
Set(nameof(IsLandWaypoint), ref _IsLandWaypoint, value);
|
||||
if (_flightTaskManager.SelectedTask == null) return;
|
||||
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos)
|
||||
{
|
||||
info._IsLandWaypoint = _IsLandWaypoint;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private bool _IsChangeSpeed = false;
|
||||
@ -72,7 +81,15 @@ namespace Plane.FormationCreator.Formation
|
||||
public bool IsChangeSpeed
|
||||
{
|
||||
get {return _IsChangeSpeed; }
|
||||
set { Set(nameof(IsChangeSpeed), ref _IsChangeSpeed, value); }
|
||||
set {
|
||||
Set(nameof(IsChangeSpeed), ref _IsChangeSpeed, value);
|
||||
if (_flightTaskManager.SelectedTask == null) return;
|
||||
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos)
|
||||
{
|
||||
info._IsChangeSpeed = _IsChangeSpeed;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +100,14 @@ namespace Plane.FormationCreator.Formation
|
||||
public float LevelSpeed
|
||||
{
|
||||
get { return _LevelSpeed; }
|
||||
set { Set(nameof(LevelSpeed), ref _LevelSpeed, value); }
|
||||
set {
|
||||
Set(nameof(LevelSpeed), ref _LevelSpeed, value);
|
||||
if (_flightTaskManager.SelectedTask == null) return;
|
||||
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos)
|
||||
{
|
||||
info._LevelSpeed = _LevelSpeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +118,14 @@ namespace Plane.FormationCreator.Formation
|
||||
public float UpSpeed
|
||||
{
|
||||
get { return _UpSpeed; }
|
||||
set { Set(nameof(UpSpeed), ref _UpSpeed, value); }
|
||||
set {
|
||||
Set(nameof(UpSpeed), ref _UpSpeed, value);
|
||||
if (_flightTaskManager.SelectedTask == null) return;
|
||||
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos)
|
||||
{
|
||||
info._UpSpeed = _UpSpeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float _DownSpeed = 1.5f;
|
||||
@ -104,7 +135,14 @@ namespace Plane.FormationCreator.Formation
|
||||
public float DownSpeed
|
||||
{
|
||||
get { return _DownSpeed; }
|
||||
set { Set(nameof(DownSpeed), ref _DownSpeed, value); }
|
||||
set {
|
||||
Set(nameof(DownSpeed), ref _DownSpeed, value);
|
||||
if (_flightTaskManager.SelectedTask == null) return;
|
||||
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.SelectedTask.SingleCopterInfos)
|
||||
{
|
||||
info._DownSpeed = _DownSpeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,18 +1,24 @@
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Plane.CommunicationManagement;
|
||||
using Plane.Copters;
|
||||
using Plane.Windows.Messages;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTaskSingleCopterInfo
|
||||
{
|
||||
|
||||
public static FlightTaskSingleCopterInfo CreateForFlyToTask(ICopter copter)
|
||||
{
|
||||
var info = new FlightTaskSingleCopterInfo(copter)
|
||||
@ -26,19 +32,24 @@ namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
LEDInfo LedInfo = new LEDInfo();
|
||||
LEDInfos.Add(LedInfo);
|
||||
LedInfo.RemoveEvent += new LEDInfo.RemoveEventHandler(LEDRemove);
|
||||
LedInfo.RemoveEvent += new LEDInfo.RemoveEventHandler(LEDRemove);
|
||||
LedInfo.PropertyChanged += (sender, e) =>{RefLEDSumTime();};
|
||||
RefLEDSumTime();
|
||||
}
|
||||
|
||||
public void AddLEDInfo(LEDInfo LedInfo)
|
||||
{
|
||||
LEDInfos.Add(LedInfo);
|
||||
LedInfo.RemoveEvent += new LEDInfo.RemoveEventHandler(LEDRemove);
|
||||
LedInfo.PropertyChanged += (sender, e) => { RefLEDSumTime(); };
|
||||
RefLEDSumTime();
|
||||
}
|
||||
|
||||
public void LEDRemove(object sender)
|
||||
{
|
||||
LEDInfo LedInfo = sender as LEDInfo;
|
||||
LEDInfos.Remove(LedInfo);
|
||||
RefLEDSumTime();
|
||||
}
|
||||
|
||||
|
||||
@ -54,9 +65,11 @@ namespace Plane.FormationCreator.Formation
|
||||
return _AddLEDCommand ?? (_AddLEDCommand = new RelayCommand<double>(async =>
|
||||
{
|
||||
AddLEDInfo();
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
private CommModuleManager _commModuleManager = CommModuleManager.Instance;
|
||||
|
||||
private ICommand _SetAllCopterLEDCommand;
|
||||
public ICommand SetAllCopterLEDCommand
|
||||
@ -82,8 +95,84 @@ namespace Plane.FormationCreator.Formation
|
||||
}
|
||||
}
|
||||
|
||||
public void RefLEDSumTime()
|
||||
{
|
||||
float _ledSumTime = 0;
|
||||
foreach (LEDInfo led in LEDInfos)
|
||||
{
|
||||
_ledSumTime += (float)led.Delay;
|
||||
}
|
||||
LEDSumTime =(float) Math.Round(_ledSumTime, 1);
|
||||
}
|
||||
|
||||
|
||||
//灯光总时长
|
||||
private float _LEDSumTime = 0;
|
||||
public float LEDSumTime
|
||||
{
|
||||
get { return _LEDSumTime; }
|
||||
set { Set(nameof(LEDSumTime), ref _LEDSumTime, value); }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool LEDTestRun = false;
|
||||
/*
|
||||
private string _TestLEDtxt = "测试";
|
||||
public string TestLEDtxt
|
||||
{
|
||||
get { return _TestLEDtxt; }
|
||||
set { Set(nameof(TestLEDtxt), ref _TestLEDtxt, value); }
|
||||
}
|
||||
*/
|
||||
/*
|
||||
|
||||
LEDMode 0 = "常亮"
|
||||
1="同步闪烁(单色)" />
|
||||
2 = "异步闪烁(随机)" />
|
||||
3="渐亮" />
|
||||
4 = "渐暗" />
|
||||
5="呼吸灯" />
|
||||
6 = "同步闪烁(随机)" />
|
||||
7="异步闪烁(单色)" />
|
||||
8 = "拉烟" />(飞控是50 ? )
|
||||
*/
|
||||
//测试灯光
|
||||
private ICommand _TestCopterLEDCommand;
|
||||
public ICommand TestCopterLEDCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _TestCopterLEDCommand ?? (_TestCopterLEDCommand = new RelayCommand<double>(async =>
|
||||
{
|
||||
if (!LEDTestRun)
|
||||
{
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
LEDTestRun = true;
|
||||
foreach (LEDInfo vLEDInfo in LEDInfos)
|
||||
{
|
||||
Thread.Sleep((int)(vLEDInfo.Delay * 1000));
|
||||
if (!LEDTestRun) break;
|
||||
_commModuleManager.LED_TaskAsync(vLEDInfo.LEDMode, vLEDInfo.LEDInterval, vLEDInfo.LEDTimes, vLEDInfo.LEDRGB, this.Copter);
|
||||
}
|
||||
//LEDTestRun = false;
|
||||
});
|
||||
}else
|
||||
{
|
||||
LEDTestRun = false;
|
||||
_commModuleManager.LED_TaskAsync(255, 0, 0, "000000", this.Copter);
|
||||
_commModuleManager.LED_TaskAsync(255, 0, 0, "000000", this.Copter);
|
||||
_commModuleManager.LED_TaskAsync(255, 0, 0, "000000", this.Copter);
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ICommand _SetSelectedCopterLEDCommand;
|
||||
public ICommand SetSelectedCopterLEDCommand
|
||||
{
|
||||
@ -112,13 +201,23 @@ namespace Plane.FormationCreator.Formation
|
||||
}
|
||||
}
|
||||
|
||||
public class LEDInfo
|
||||
public class LEDInfo :INotifyPropertyChanged
|
||||
{
|
||||
private double delay = 1; //灯光延时 单位:100ms (从当前任务开为0,延时几秒后设置LED)
|
||||
private int ledmode = 0; //灯光模式 0常亮 1闪烁 2随机闪烁(RGB无意义)
|
||||
private int ledrate = 0; //闪烁延时 单位:100ms
|
||||
private float ledInterval = 0; //闪烁延时 单位:秒
|
||||
private int ledrate = 0; //为了和以前文件兼容,自动转为ledInterval
|
||||
private int ledtimes = 0; //次数 (预留、暂取消其意义)
|
||||
private string ledRGB = "FFFFFF"; //灯光颜色
|
||||
private SolidColorBrush _DrawRGB = new SolidColorBrush(Color.FromRgb(0xFF, 0xFF, 0xFF));
|
||||
|
||||
protected internal virtual void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
if (PropertyChanged != null)
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
|
||||
public LEDInfo()
|
||||
{
|
||||
@ -129,13 +228,16 @@ namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
delay = led.delay;
|
||||
ledmode = led.ledmode;
|
||||
ledrate = led.ledrate;
|
||||
ledRGB = led.ledRGB;
|
||||
ledInterval = led.ledInterval;
|
||||
LEDRGB = led.ledRGB;
|
||||
}
|
||||
public double Delay
|
||||
{
|
||||
get { return delay; }
|
||||
set { delay = value; }
|
||||
set {
|
||||
delay = Math.Round(value, 1);
|
||||
OnPropertyChanged("delay");
|
||||
}
|
||||
}
|
||||
|
||||
public int LEDMode
|
||||
@ -143,11 +245,25 @@ namespace Plane.FormationCreator.Formation
|
||||
get { return ledmode; }
|
||||
set { ledmode = value; }
|
||||
}
|
||||
public float LEDInterval
|
||||
{
|
||||
get { return ledInterval; }
|
||||
set { ledInterval = value;
|
||||
if (ledInterval != 0)
|
||||
ledrate = (int)Math.Round(1 / ledInterval); //用于兼容老版本
|
||||
}
|
||||
}
|
||||
|
||||
public int LEDRate
|
||||
{
|
||||
get { return ledrate; }
|
||||
set { ledrate = value; }
|
||||
set { ledrate = value;
|
||||
if ((ledrate!=0)&&(ledInterval==0))
|
||||
ledInterval = 1 / ledrate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int LEDTimes
|
||||
{
|
||||
get { return ledtimes; }
|
||||
@ -157,9 +273,29 @@ namespace Plane.FormationCreator.Formation
|
||||
public string LEDRGB
|
||||
{
|
||||
get { return ledRGB; }
|
||||
set { ledRGB = value; }
|
||||
set {
|
||||
|
||||
ledRGB = value;
|
||||
DrawRGB.Color= (Color)ColorConverter.ConvertFromString("#" + ledRGB);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
public SolidColorBrush DrawRGB
|
||||
{
|
||||
get
|
||||
{
|
||||
return _DrawRGB;
|
||||
}
|
||||
set
|
||||
{
|
||||
_DrawRGB = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public delegate void RemoveEventHandler(object sender);
|
||||
public event RemoveEventHandler RemoveEvent;
|
||||
private ICommand _RemoveLEDCommand;
|
||||
|
@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plane.Copters;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTaskSingleCopterInfo
|
||||
{
|
||||
public static FlightTaskSingleCopterInfo CreateForLoiterTimeTask(ICopter copter, LatLng latLngOffset, float targetAlt)
|
||||
{
|
||||
var info = new FlightTaskSingleCopterInfo(copter)
|
||||
{
|
||||
LatLngOffset = latLngOffset,
|
||||
TargetAlt = targetAlt
|
||||
};
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plane.Copters;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTaskSingleCopterInfo
|
||||
{
|
||||
// This file is added by ZJF
|
||||
public static FlightTaskSingleCopterInfo CreateForReturnToLandTask(ICopter copter, float targetAlt)
|
||||
{
|
||||
var info = new FlightTaskSingleCopterInfo(copter)
|
||||
{
|
||||
TargetAlt = targetAlt
|
||||
};
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plane.Copters;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTaskSingleCopterInfo
|
||||
{
|
||||
public static FlightTaskSingleCopterInfo CreateForSimpleCircleTask(ICopter copter, LatLng latLngOffset, float targetAlt, int rate, int turns, ushort channel3)
|
||||
{
|
||||
var info = new FlightTaskSingleCopterInfo(copter)
|
||||
{
|
||||
LatLngOffset = latLngOffset,
|
||||
TargetAlt = targetAlt,
|
||||
Rate = rate,
|
||||
Turns = turns,
|
||||
Channel3 = channel3
|
||||
};
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,9 @@ namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
var info = new FlightTaskSingleCopterInfo(copter)
|
||||
{
|
||||
TargetAlt = targetAlt
|
||||
TargetAlt = targetAlt,
|
||||
TargetLat = copter.Latitude,
|
||||
TargetLng=copter.Longitude
|
||||
};
|
||||
return info;
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plane.Copters;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTaskSingleCopterInfo
|
||||
{
|
||||
public static FlightTaskSingleCopterInfo CreateForTurnTask(ICopter copter, LatLng latLngOffset, float targetAlt, short targetHeading)
|
||||
{
|
||||
var info = new FlightTaskSingleCopterInfo(copter)
|
||||
{
|
||||
LatLngOffset = latLngOffset,
|
||||
TargetAlt = targetAlt,
|
||||
TargetHeading = targetHeading
|
||||
};
|
||||
return info;
|
||||
}
|
||||
|
||||
private short _TargetHeading;
|
||||
public short TargetHeading
|
||||
{
|
||||
get { return _TargetHeading; }
|
||||
set { Set(nameof(TargetHeading), ref _TargetHeading, value); }
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
public enum FlightTaskStatus
|
||||
{
|
||||
Stop,
|
||||
Running,
|
||||
Paused
|
||||
}
|
||||
public enum TasksStatus
|
||||
{
|
||||
Stop,
|
||||
Running,
|
||||
Paused
|
||||
public enum FlightTaskStatus
|
||||
{
|
||||
Stop,
|
||||
Running,
|
||||
Paused,
|
||||
Selected
|
||||
}
|
||||
public enum TasksStatus
|
||||
{
|
||||
Stop,
|
||||
Running,
|
||||
Paused
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
using Plane.Copters;
|
||||
using Plane.Geography;
|
||||
using Plane.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTask
|
||||
{
|
||||
public async Task RunCircleTaskAsync()
|
||||
{
|
||||
// 林俊清, 20150922, 首先一起调好方向。
|
||||
await Task.WhenAll(
|
||||
SingleCopterInfos.Select(info =>
|
||||
{
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
// 当该飞机被标记时,跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
return Task.Run(()=> { });
|
||||
info.TargetHeading = info.CenterDirectionDeg;
|
||||
return TurnTaskFlySingleCopterAsync(info);
|
||||
})
|
||||
).ConfigureAwait(false);
|
||||
|
||||
await Task.WhenAll(
|
||||
SingleCopterInfos.Select(info => CircleTaskFlySingleCopterAsync(info))
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task CircleTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
// 林俊清, 20150907, 目前不对 Circle 进行仿真。
|
||||
if (info.Copter is FakeCopter)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
return;
|
||||
}
|
||||
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
// 当该飞机被标记时,跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
return;
|
||||
|
||||
await info.Copter.SetParamAsync("CIRCLE_RADIUS", info.Radius);
|
||||
|
||||
await info.Copter.SetParamAsync("CIRCLE_RATE", info.Rate);
|
||||
|
||||
var center = GeographyUtils.CalcLatLngSomeMetersAway2D(info.Copter.Latitude, info.Copter.Longitude, info.CenterDirectionDeg, 10);
|
||||
|
||||
await info.Copter.CircleAsync();
|
||||
|
||||
while (info.Copter.State != Copters.CopterState.Circling)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await info.Copter.SetChannelsAsync(ch3: info.Channel3);
|
||||
|
||||
for (int i = info.Turns; i > 0; i--)
|
||||
{
|
||||
//// 等待一段时间,让飞行器飞出一段距离。
|
||||
//for (int i = 0; i < 3000 / 25; i++)
|
||||
//{
|
||||
// if (_flightTaskManager.IsPaused == true)
|
||||
// {
|
||||
// info.Copter.Hover();
|
||||
// return;
|
||||
// }
|
||||
// await Task.Delay(25).ConfigureAwait(false);
|
||||
//}
|
||||
|
||||
//var log = new StringBuilder(1024);
|
||||
//var lastLogTime = DateTime.Now;
|
||||
bool step1 = false;
|
||||
while (true)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
var angle = info.Radius == 0 ? NormalizeAngleDeg(info.Copter.Heading - info.CenterDirectionDeg) : GetNormalizedAngleDeg(info, center);
|
||||
//log.AppendLine($"{angle} {step1}");
|
||||
if (!step1)
|
||||
{
|
||||
if (angle > 100 && angle < 330)
|
||||
{
|
||||
step1 = true;
|
||||
//log.AppendLine($"step1 is true now.");
|
||||
}
|
||||
}
|
||||
else if (angle > 340 || angle < 5)
|
||||
{
|
||||
//log.AppendLine("break");
|
||||
break;
|
||||
}
|
||||
//if (lastLogTime.AddSeconds(10) < DateTime.Now)
|
||||
//{
|
||||
// Logger.Instance.Log(log.ToString());
|
||||
// log.Clear();
|
||||
// lastLogTime = DateTime.Now;
|
||||
//}
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
}
|
||||
//Logger.Instance.Log(log.ToString());
|
||||
}
|
||||
|
||||
await info.Copter.HoverAsync();
|
||||
}
|
||||
|
||||
private static double GetNormalizedAngleDeg(FlightTaskSingleCopterInfo info, Tuple<double, double> center)
|
||||
{
|
||||
var angle = info.Copter.InPlaneDirectionToDeg(center.Item1, center.Item2) - info.CenterDirectionDeg;
|
||||
return NormalizeAngleDeg(angle);
|
||||
}
|
||||
|
||||
private static double NormalizeAngleDeg(double angle)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (angle < 0) angle += 360;
|
||||
else if (angle >= 360) angle -= 360;
|
||||
else break;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,280 +1,216 @@
|
||||
using Plane.Copters;
|
||||
using Plane.Geography;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plane.Windows.Messages;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTask
|
||||
{
|
||||
private bool _StaggerRoutes = true;
|
||||
|
||||
//是否有交错
|
||||
public bool StaggerRoutes
|
||||
{
|
||||
get { return _StaggerRoutes; }
|
||||
set { Set(nameof(StaggerRoutes), ref _StaggerRoutes, value); }
|
||||
}
|
||||
|
||||
//同一个任务每一架飞机的FlytoTime和LoiterTime保持统一
|
||||
private int _FlytoTime = 10;
|
||||
public int FlytoTime
|
||||
{
|
||||
get { return _FlytoTime; }
|
||||
set
|
||||
{
|
||||
if (value > 4095) value = 4095;
|
||||
if (value < 0) value = 0;
|
||||
Set(nameof(FlytoTime), ref _FlytoTime, value);
|
||||
}
|
||||
}
|
||||
private int _LoiterTime = 10;
|
||||
public int LoiterTime
|
||||
{
|
||||
get { return _LoiterTime; }
|
||||
set
|
||||
{
|
||||
if (value > 4095) value = 4095;
|
||||
if (value < 0) value = 0;
|
||||
Set(nameof(LoiterTime), ref _LoiterTime, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private bool _VerticalLift = false;
|
||||
public bool VerticalLift // 垂直升降标志位,后面需要加入即使拖动地图上的飞机,也不会变化经纬度. added by ZJF
|
||||
{
|
||||
get { return _VerticalLift; }
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
int currentIndex = _flightTaskManager.SelectedTaskIndex;
|
||||
var currentCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos;
|
||||
var previousCopterInfos = _flightTaskManager.Tasks[currentIndex - 1].SingleCopterInfos;
|
||||
for (int i = 0; i < currentCopterInfos.Count; i++)
|
||||
{
|
||||
currentCopterInfos[i].TargetLat = previousCopterInfos[i].TargetLat;
|
||||
currentCopterInfos[i].TargetLng = previousCopterInfos[i].TargetLng;
|
||||
currentCopterInfos[i].TargetAlt = previousCopterInfos[i].TargetAlt;
|
||||
}
|
||||
}
|
||||
|
||||
Set(nameof(VerticalLift), ref _VerticalLift, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public async Task RunFlyToTaskAsync() // 全部飞到指定航点
|
||||
{
|
||||
//是否有交错
|
||||
if (StaggerRoutes)
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
var tasks = new Task[infos.Count];
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
var info = infos[i];
|
||||
|
||||
tasks[i] = await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
var internalInfo = info;
|
||||
//if (i1 > 0)
|
||||
//{
|
||||
// var prevCopter = infos[i1 - 1].Copter;
|
||||
// while (CheckCrossing(infos, i1) &&
|
||||
// prevCopter.Altitude - copter.Altitude < 2)
|
||||
// {
|
||||
// await Task.Delay(25).ConfigureAwait(false);
|
||||
// }
|
||||
//}
|
||||
|
||||
await FlyToTaskFlySingleCopterAsync(internalInfo);
|
||||
});
|
||||
}
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.WhenAll(
|
||||
SingleCopterInfos.Select(info => FlyToTaskFlySingleCopterAsync(info))
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int RuningTaskRemaining = 0;
|
||||
|
||||
private async Task FlyToTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
DateTime dtNow = DateTime.Now;
|
||||
DateTime dtLastTime = DateTime.Now;
|
||||
TimeSpan ts = dtNow - dtLastTime;
|
||||
|
||||
|
||||
FlightTask task = _flightTaskManager.CurrentRunningTask;
|
||||
int flyToTime = task.FlytoTime * 1000;
|
||||
int loiterTime = task.LoiterTime * 1000;
|
||||
int taskIndex = _flightTaskManager.CurrentRunningTaskIndex;
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
|
||||
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
await info.Copter.SetShowLEDAsync(info.FlytoShowLED);
|
||||
|
||||
if (info.Copter.State != Plane.Copters.CopterState.CommandMode)
|
||||
await info.Copter.GuidAsync();
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, info.TargetAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
}
|
||||
*/
|
||||
double targetLat = info.TargetLat;
|
||||
double targetLng = info.TargetLng;
|
||||
if (info.IsLandWaypoint)
|
||||
{
|
||||
targetLat = info.Copter.TakeOffPoint.Latitude;
|
||||
targetLng = info.Copter.TakeOffPoint.Longitude;
|
||||
}
|
||||
//发送目标航点1次
|
||||
|
||||
await info.Copter.FlyToAsync(targetLat, targetLng, info.TargetAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
|
||||
int sendFlyToTimes = 0;
|
||||
|
||||
//第0个任务为takeoff
|
||||
if (taskIndex > 0)
|
||||
{
|
||||
FlightTask prevTask = _flightTaskManager.Tasks[taskIndex - 1];
|
||||
if (prevTask.TaskType == FlightTaskType.FlyTo && prevTask.LoiterTime == 0)
|
||||
flyToTime += prevTask.RuningTaskRemaining;
|
||||
}
|
||||
|
||||
//while (!info.Copter.ArrivedTarget(info.TargetLat, info.TargetLng, info.TargetAlt)) //按航点飞 :所有Copter到达目标点开始飞下个航点
|
||||
while (ts.TotalMilliseconds < (flyToTime + loiterTime)) //按时间轴飞:当前任务时间到达后自动飞往下个航点
|
||||
{
|
||||
//悬停时间等于0为快速航点 到达之后立即出发下个航点 切时间累积
|
||||
if (loiterTime == 0 &&
|
||||
info.Copter.ArrivedTarget(info.TargetLat, info.TargetLng, info.TargetAlt))
|
||||
{
|
||||
task.RuningTaskRemaining = flyToTime - (int)ts.TotalMilliseconds;
|
||||
break;
|
||||
}
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(10).ConfigureAwait(false); //判断是否到达位置10hz
|
||||
|
||||
|
||||
|
||||
// if (info.LEDInfos.Count > 0)
|
||||
// {
|
||||
// string LEDRGB = "";
|
||||
// List<LEDInfo> LedControl = info.LEDInfos.OrderBy(i=>i.Delay).ToList();
|
||||
// for (int i = 0; i < LedControl.Count; i++)
|
||||
// {
|
||||
// var led = LedControl[i];
|
||||
// if (ts.TotalMilliseconds >= led.Delay * 1000)
|
||||
// LEDRGB = info.LEDInfos[i].LEDRGB;
|
||||
// else
|
||||
// break;
|
||||
// }
|
||||
// info.Copter.LEDColor = LEDRGB;
|
||||
//
|
||||
// }
|
||||
|
||||
if (info.LEDInfos.Count > 0)
|
||||
{
|
||||
string LEDRGB = "";
|
||||
List<LEDInfo> LedControl = info.LEDInfos.ToList();
|
||||
double time = 0;
|
||||
for (int i = 0; i < LedControl.Count; i++)
|
||||
{
|
||||
|
||||
var led = LedControl[i];
|
||||
time += led.Delay * 1000;
|
||||
if (ts.TotalMilliseconds >= time)
|
||||
LEDRGB = info.LEDInfos[i].LEDRGB;
|
||||
else
|
||||
break;
|
||||
}
|
||||
info.Copter.LEDColor = LEDRGB;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (ts.TotalMilliseconds / 10 > sendFlyToTimes) // 每500ms发送一遍指点坐标
|
||||
{
|
||||
sendFlyToTimes++;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(targetLat, targetLng, info.TargetAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
//dtLastTime = dtNow;
|
||||
}
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
}
|
||||
// await info.Copter.HoverAsync();
|
||||
if (taskIndex == _flightTaskManager.Tasks.Count() - 1)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static bool CheckCrossing(List<FlightTaskSingleCopterInfo> infos, int currentIndex)
|
||||
{
|
||||
var info = infos[currentIndex];
|
||||
for (int i = 0; i < currentIndex; i++)
|
||||
{
|
||||
var nextInfo = infos[i];
|
||||
if (GeographyUtils.CheckCrossing2D(info.Copter.Latitude, info.Copter.Longitude, info.TargetLat, info.TargetLng,
|
||||
nextInfo.Copter.Latitude, nextInfo.Copter.Longitude, nextInfo.TargetLat, nextInfo.TargetLng))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
using Plane.Copters;
|
||||
using Plane.Geography;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plane.Windows.Messages;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTask
|
||||
{
|
||||
private bool _StaggerRoutes = true;
|
||||
|
||||
//是否有交错
|
||||
public bool StaggerRoutes
|
||||
{
|
||||
get { return _StaggerRoutes; }
|
||||
set { Set(nameof(StaggerRoutes), ref _StaggerRoutes, value); }
|
||||
}
|
||||
|
||||
//同一个任务每一架飞机的FlytoTime和LoiterTime保持统一
|
||||
private int _FlytoTime = 10;
|
||||
public int FlytoTime
|
||||
{
|
||||
get { return _FlytoTime; }
|
||||
set
|
||||
{
|
||||
if (value > 4095) value = 4095;
|
||||
if (value < 0) value = 0;
|
||||
Set(nameof(FlytoTime), ref _FlytoTime, value);
|
||||
}
|
||||
}
|
||||
private int _LoiterTime = 1;
|
||||
public int LoiterTime
|
||||
{
|
||||
get { return _LoiterTime; }
|
||||
set
|
||||
{
|
||||
if (value > 4095) value = 4095;
|
||||
if (value < 0) value = 0;
|
||||
Set(nameof(LoiterTime), ref _LoiterTime, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private bool _VerticalLift = false;
|
||||
public bool VerticalLift // 垂直升降标志位,后面需要加入即使拖动地图上的飞机,也不会变化经纬度. added by ZJF
|
||||
{
|
||||
get { return _VerticalLift; }
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
int currentIndex = _flightTaskManager.SelectedTaskIndex;
|
||||
var currentCopterInfos = _flightTaskManager.SelectedTask.SingleCopterInfos;
|
||||
var previousCopterInfos = _flightTaskManager.Tasks[currentIndex - 1].SingleCopterInfos;
|
||||
for (int i = 0; i < currentCopterInfos.Count; i++)
|
||||
{
|
||||
currentCopterInfos[i].TargetLat = previousCopterInfos[i].TargetLat;
|
||||
currentCopterInfos[i].TargetLng = previousCopterInfos[i].TargetLng;
|
||||
currentCopterInfos[i].TargetAlt = previousCopterInfos[i].TargetAlt;
|
||||
}
|
||||
}
|
||||
|
||||
Set(nameof(VerticalLift), ref _VerticalLift, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public async Task RunFlyToTaskAsync() // 全部飞到指定航点
|
||||
{
|
||||
//是否有交错
|
||||
if (StaggerRoutes)
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
var tasks = new Task[infos.Count];
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
var info = infos[i];
|
||||
//为每架飞机创建一个航点任务
|
||||
tasks[i] = await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
var internalInfo = info;
|
||||
await FlyToTaskFlySingleCopterAsync(internalInfo);
|
||||
});
|
||||
}
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.WhenAll(
|
||||
SingleCopterInfos.Select(info => FlyToTaskFlySingleCopterAsync(info))
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// private int RuningTaskRemaining = 0;
|
||||
/// <summary>
|
||||
/// 单独飞机执行飞行任务
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
/// <returns></returns>
|
||||
private async Task FlyToTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
DateTime dtNow = DateTime.Now;
|
||||
DateTime dtLastTime = DateTime.Now;
|
||||
TimeSpan ts = dtNow - dtLastTime;
|
||||
|
||||
|
||||
FlightTask task = _flightTaskManager.CurrentRunningTask;
|
||||
int flyToTime = task.FlytoTime * 1000;
|
||||
int loiterTime = task.LoiterTime * 1000;
|
||||
int taskIndex = _flightTaskManager.CurrentRunningTaskIndex;
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
|
||||
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
await info.Copter.SetShowLEDAsync(info.FlytoShowLED);
|
||||
|
||||
if (info.Copter.State != Plane.Copters.CopterState.CommandMode)
|
||||
await info.Copter.GuidAsync();
|
||||
|
||||
|
||||
double targetLat = info.TargetLat;
|
||||
double targetLng = info.TargetLng;
|
||||
if (info.IsLandWaypoint)
|
||||
{
|
||||
targetLat = info.Copter.TakeOffPoint.Latitude;
|
||||
targetLng = info.Copter.TakeOffPoint.Longitude;
|
||||
}
|
||||
int flytype = _flightTaskManager.getflytype(taskIndex);
|
||||
//指定目标位置
|
||||
await info.Copter.FlyToAsync(targetLat, targetLng, info.TargetAlt, task.FlytoTime, flytype);
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
//等待时间到达,并执行灯光模拟--不移动飞机,移动飞机是飞机自己计算的
|
||||
while (ts.TotalMilliseconds < (flyToTime + loiterTime)) //按时间轴飞:当前任务时间到达后自动飞往下个航点
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(100).ConfigureAwait(false); //判断是否到达位置10hz
|
||||
//执行灯光模拟
|
||||
if (info.LEDInfos.Count > 0)
|
||||
{
|
||||
string LEDRGB = "";
|
||||
List<LEDInfo> LedControl = info.LEDInfos.ToList();
|
||||
double time = 0;
|
||||
for (int i = 0; i < LedControl.Count; i++)
|
||||
{
|
||||
|
||||
var led = LedControl[i];
|
||||
time += led.Delay * 1000;
|
||||
if (ts.TotalMilliseconds >= time)
|
||||
LEDRGB = info.LEDInfos[i].LEDRGB;
|
||||
else
|
||||
break;
|
||||
}
|
||||
info.Copter.LEDColor = LEDRGB;
|
||||
}
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
if (_flightTaskManager.IsEmergencyRet == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
}
|
||||
// await info.Copter.HoverAsync();
|
||||
if (taskIndex == _flightTaskManager.Tasks.Count() - 1)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static bool CheckCrossing(List<FlightTaskSingleCopterInfo> infos, int currentIndex)
|
||||
{
|
||||
var info = infos[currentIndex];
|
||||
for (int i = 0; i < currentIndex; i++)
|
||||
{
|
||||
var nextInfo = infos[i];
|
||||
if (GeographyUtils.CheckCrossing2D(info.Copter.Latitude, info.Copter.Longitude, info.TargetLat, info.TargetLng,
|
||||
nextInfo.Copter.Latitude, nextInfo.Copter.Longitude, nextInfo.TargetLat, nextInfo.TargetLng))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,8 +36,34 @@ namespace Plane.FormationCreator.Formation
|
||||
DateTime dtLastTime = DateTime.Now;
|
||||
TimeSpan ts = dtNow - dtLastTime;
|
||||
int waittime = (int)info.LandWaitTime * 1000;
|
||||
await Task.Delay(waittime).ConfigureAwait(false);
|
||||
|
||||
while (ts.TotalMilliseconds < waittime)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
|
||||
}
|
||||
await Task.Delay(100).ConfigureAwait(true);
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
}
|
||||
await info.Copter.LandAsync();
|
||||
while ((info.Copter.Altitude>0.0f))
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
|
||||
}
|
||||
await Task.Delay(100).ConfigureAwait(true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,723 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTask
|
||||
{
|
||||
private float _LoiterTimeAttr = 0.0f;
|
||||
public float LoiterTimeAttr
|
||||
{
|
||||
get { return _LoiterTimeAttr; }
|
||||
set
|
||||
{
|
||||
Set(nameof(LoiterTimeAttr), ref _LoiterTimeAttr, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 改变机头
|
||||
private bool _ChangeYaw = false;
|
||||
public bool ChangeYaw
|
||||
{
|
||||
get { return _ChangeYaw; }
|
||||
set
|
||||
{
|
||||
Set(nameof(ChangeYaw), ref _ChangeYaw, value);
|
||||
}
|
||||
}
|
||||
|
||||
// 机头方向0为北,顺时针360
|
||||
private float _HeadYaw = 1.0f;
|
||||
public float HeadYaw
|
||||
{
|
||||
get { return _HeadYaw; }
|
||||
set
|
||||
{
|
||||
Set(nameof(HeadYaw), ref _HeadYaw, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// LED灯闪烁
|
||||
private bool _flashAttr = false;
|
||||
public bool flashAttr
|
||||
{
|
||||
get { return _flashAttr; }
|
||||
set
|
||||
{
|
||||
Set(nameof(flashAttr), ref _flashAttr, value);
|
||||
}
|
||||
}
|
||||
|
||||
// LED闪烁次数
|
||||
private float _flashPeriodAttr = 1.0f;
|
||||
public float flashPeriodAttr
|
||||
{
|
||||
get { return _flashPeriodAttr; }
|
||||
set
|
||||
{
|
||||
Set(nameof(flashPeriodAttr), ref _flashPeriodAttr, value);
|
||||
}
|
||||
}
|
||||
private string Name2Index(string name) // 获取指定copter名字对应的序号
|
||||
{
|
||||
int index = -1;
|
||||
for (int i = 0; i < SingleCopterInfos.Count; i++)
|
||||
{
|
||||
if (name.Equals(SingleCopterInfos[i].Copter.Name))
|
||||
{
|
||||
return i.ToString();
|
||||
}
|
||||
}
|
||||
return index.ToString();
|
||||
}
|
||||
|
||||
// 闪烁的飞机名字编号
|
||||
private string _flashCopterNameArray = "";
|
||||
public string flashCopterNameArray
|
||||
{
|
||||
get { return _flashCopterNameArray; }
|
||||
set
|
||||
{
|
||||
Set(nameof(flashCopterNameArray), ref _flashCopterNameArray, value);
|
||||
|
||||
flashCopterIndexArray = "";
|
||||
|
||||
string[] copterArray = flashCopterNameArray.Split(',');
|
||||
|
||||
for (int i = 0; i < copterArray.Length; i++)
|
||||
{
|
||||
flashCopterIndexArray += Name2Index(copterArray[i])+',';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 闪烁的飞机序号编号
|
||||
private string _flashCopterIndexArray = "";
|
||||
public string flashCopterIndexArray
|
||||
{
|
||||
get { return _flashCopterIndexArray; }
|
||||
set
|
||||
{
|
||||
Set(nameof(flashCopterIndexArray), ref _flashCopterIndexArray, value);
|
||||
}
|
||||
}
|
||||
|
||||
// LED走马灯
|
||||
private bool _oneByOneAttr = false;
|
||||
public bool oneByOneAttr
|
||||
{
|
||||
get { return _oneByOneAttr; }
|
||||
set
|
||||
{
|
||||
Set(nameof(oneByOneAttr), ref _oneByOneAttr, value);
|
||||
}
|
||||
}
|
||||
|
||||
// LED走马灯次数
|
||||
private float _oneByOnePeriodAttr = 1.0f;
|
||||
public float oneByOnePeriodAttr
|
||||
{
|
||||
get { return _oneByOnePeriodAttr; }
|
||||
set
|
||||
{
|
||||
Set(nameof(oneByOnePeriodAttr), ref _oneByOnePeriodAttr, value);
|
||||
}
|
||||
}
|
||||
|
||||
private int[] columnFirst = {0, 1, 2, 3, 4 };
|
||||
private int[] columnSecond = { 5, 6, 7, 8, 9 };
|
||||
private int[] columnThird = { 10, 11, 12, 13, 14 };
|
||||
private int[] columnFourth = { 15, 16, 17, 18, 19 };
|
||||
private int[] columnFive = { 20, 21, 22, 23, 24 };
|
||||
private int[] columnSix = { 25, 26, 27, 28, 29 };
|
||||
|
||||
private int[] rowFirst = { 0, 5, 10, 15, 20, 25 };
|
||||
private int[] rowSecond = { 1, 6, 11, 16, 21, 26 };
|
||||
private int[] rowThird = { 2, 7, 12, 17, 22, 27 };
|
||||
private int[] rowFourth = { 3, 8, 13, 18, 23, 28 };
|
||||
private int[] rowFive = { 4, 9, 14, 19, 24, 29 };
|
||||
|
||||
private int[] rowFirstForEight = { 0, 1, 2, 3 };
|
||||
private int[] rowSecondForEight = { 4, 5, 6, 7 };
|
||||
|
||||
private int[] doubleColumnFirst = { 0, 1, 2, 3, 4, 25, 26, 27, 28, 29 };
|
||||
private int[] doubleColumnSecond = { 5, 6, 7, 8, 9, 20, 21, 22, 23, 24 };
|
||||
private int[] doubleColumnThird = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
|
||||
|
||||
private int[] circleFirst = { 0, 1, 2, 3, 4, 9, 14, 19, 24, 29, 28, 27, 26, 25, 20, 15, 10, 5 };
|
||||
private int[] circleSecond = { 6, 7, 8, 13, 18, 23, 22, 21, 16, 11 };
|
||||
private int[] circleThird = { 12, 17 };
|
||||
|
||||
private int[] lineFirst = { 4 };
|
||||
private int[] lineSecond = { 3, 9 };
|
||||
private int[] lineThird = { 2, 8, 14 };
|
||||
private int[] lineFourth = { 1, 7, 13, 19 };
|
||||
private int[] lineFive = { 0, 6, 12, 18, 24 };
|
||||
private int[] lineSix = { 5, 11, 17, 23, 29 };
|
||||
private int[] lineSeven = { 10, 16, 22, 28 };
|
||||
private int[] lineEight = { 15, 21, 27 };
|
||||
private int[] lineNine = { 20, 26 };
|
||||
private int[] lineTen = { 25 };
|
||||
|
||||
public async Task RunLoiterTimeTaskAsync()
|
||||
{
|
||||
|
||||
if (ChangeYaw)
|
||||
{
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => SetCopterYawAsync(info,HeadYaw)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 判断flashPeriodAttr, oneByOnePeriodAttr的值,执行不同的闪烁模式
|
||||
// 当flashPeriodAttr小于10,正常闪烁,即没有预制闪烁模式
|
||||
// 当flashPeriodAttr大于等于10,小于20,执行预制闪烁模式
|
||||
// 当flashPeriodAttr大于等于20, 改变飞控闪烁模式,以oneByOnePeriodAttr作为周期值
|
||||
|
||||
//LEDFlashPlanAsync需要30架飞机
|
||||
if ((flashPeriodAttr >= 10.0f) && (flashPeriodAttr < 20.0f))
|
||||
{
|
||||
await LEDFlashPlanAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
//需要固件支持
|
||||
if (flashPeriodAttr >= 20.0f)
|
||||
{
|
||||
await LEDFlashParaModifyPlanAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var infos = SingleCopterInfos;
|
||||
if (flashAttr) // LED闪烁显示效果
|
||||
{
|
||||
if (flashCopterIndexArray.Equals(""))
|
||||
return;
|
||||
string[] copterArray = flashCopterIndexArray.Split(',');
|
||||
|
||||
var tasks_selected = new Task[copterArray.Length];
|
||||
|
||||
// LED灯全灭
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
|
||||
// 选中的飞机LED灯全亮
|
||||
for (int i = 0; i < copterArray.Length; i++)
|
||||
{
|
||||
int index = int.Parse(copterArray[i]);
|
||||
var info = infos[index];
|
||||
|
||||
tasks_selected[i] = await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
var internalInfo = info;
|
||||
await LEDFlashTaskFlySingleCopterAsync(internalInfo, true);
|
||||
});
|
||||
}
|
||||
await Task.WhenAll(tasks_selected).ConfigureAwait(false);
|
||||
await Task.Delay(3000).ConfigureAwait(false);
|
||||
// LED灯全亮
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
|
||||
//延时等待
|
||||
//判断是否下一步
|
||||
DateTime start = DateTime.Now;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => (info.Copter.HoverAsync())));
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime end = DateTime.Now;
|
||||
TimeSpan ts = end - start;
|
||||
//等待指定时间
|
||||
if (ts.TotalMilliseconds > LoiterTimeAttr * 1000)
|
||||
break;
|
||||
await Task.Delay(20).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else if (oneByOneAttr) // LED走马灯显示效果
|
||||
{
|
||||
if (flashCopterNameArray.Equals(""))
|
||||
return;
|
||||
string[] copterArray = flashCopterIndexArray.Split(',');
|
||||
//LED全灭
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
|
||||
// LED灯一个接一个全亮
|
||||
for (int i = 0; i < copterArray.Length; i++)
|
||||
{
|
||||
if (copterArray[i] == "") break;
|
||||
int index = int.Parse(copterArray[i]);
|
||||
var info = infos[index];
|
||||
await LEDFlashTaskFlySingleCopterAsync(info, true);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await Task.Delay(1000).ConfigureAwait(false);
|
||||
|
||||
//////////////////全部闪烁一次
|
||||
// LED灯全亮
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
// LED灯全灭
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
/////////////////////////////////////
|
||||
//////////////////全部闪烁一次
|
||||
// LED灯全亮
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
// LED灯全灭
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
/////////////////////////////////////
|
||||
//////////////////全部闪烁一次
|
||||
// LED灯全亮
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
// LED灯全灭
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
/////////////////////////////////////
|
||||
|
||||
|
||||
// LED灯全亮
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
|
||||
//延时等待
|
||||
|
||||
//判断是否下一步
|
||||
DateTime start = DateTime.Now;
|
||||
while (true)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => (info.Copter.HoverAsync())));
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime end = DateTime.Now;
|
||||
TimeSpan ts = end - start;
|
||||
//等待指定时间
|
||||
if (ts.TotalMilliseconds > LoiterTimeAttr * 1000)
|
||||
break;
|
||||
await Task.Delay(20).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else // 没有LED显示效果只等待
|
||||
{
|
||||
|
||||
//判断是否下一步
|
||||
DateTime start = DateTime.Now;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => (info.Copter.HoverAsync())));
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime end = DateTime.Now;
|
||||
TimeSpan ts = end - start;
|
||||
//等待指定时间
|
||||
if (ts.TotalMilliseconds > LoiterTimeAttr * 1000)
|
||||
break;
|
||||
await Task.Delay(20).ConfigureAwait(false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async Task LEDFlashParaModifyPlanAsync()
|
||||
{
|
||||
/*
|
||||
await LEDFlashParaModifyAsync(rowFirstForEight);
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await LEDFlashParaModifyAsync(rowSecondForEight);
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
*/
|
||||
|
||||
int copterCount = SingleCopterInfos.Count();
|
||||
int[] intArray = new int[copterCount];
|
||||
for (int ii=0; ii<copterCount; ii++)
|
||||
{
|
||||
intArray[ii] = ii;
|
||||
}
|
||||
await LEDFlashParaModifyAsync(intArray);
|
||||
|
||||
/*
|
||||
await LEDFlashParaModifyAsync(rowFirst);
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await LEDFlashParaModifyAsync(rowSecond);
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await LEDFlashParaModifyAsync(rowThird);
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await LEDFlashParaModifyAsync(rowFourth);
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await LEDFlashParaModifyAsync(rowFive);
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
*/
|
||||
}
|
||||
|
||||
private async Task LEDFlashParaModifyAsync(int[] LEDArray)
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
|
||||
var tasks_selected = new Task[LEDArray.Length];
|
||||
for (int i = 0; i < LEDArray.Length; i++)
|
||||
{
|
||||
var info = infos[LEDArray[i]];
|
||||
|
||||
tasks_selected[i] = await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
var internalInfo = info;
|
||||
await LEDParaModifySingleCopterAsync(internalInfo, oneByOnePeriodAttr);
|
||||
});
|
||||
}
|
||||
await Task.WhenAll(tasks_selected).ConfigureAwait(false);
|
||||
}
|
||||
private async Task SetCopterYawAsync(FlightTaskSingleCopterInfo info, float headyaw)
|
||||
{
|
||||
var copter = info.Copter;
|
||||
|
||||
// await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var tasks = new Task[1];
|
||||
tasks[0] = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await copter.SetMobileControlAsync(yaw: headyaw);
|
||||
|
||||
while (!copter.ArrivedHeading((short)headyaw))
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (TimeoutException ex)
|
||||
{
|
||||
_logger.Log($"SetYAWtimeout, {ex.Message}, CopterId: {copter.Id}。");
|
||||
}
|
||||
});
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
}
|
||||
private async Task LEDParaModifySingleCopterAsync(FlightTaskSingleCopterInfo info, float count)
|
||||
{
|
||||
var copter = info.Copter;
|
||||
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
var tasks = new Task[1];
|
||||
tasks[0] = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (count == 1.0)
|
||||
await copter.SetShowLEDAsync(true);
|
||||
else
|
||||
await copter.SetShowLEDAsync(false);
|
||||
//await copter.SetParamAsync("NTF_SHOWLED", count, 5000);
|
||||
}
|
||||
catch (TimeoutException ex)
|
||||
{
|
||||
_logger.Log($"SetShowLEDAsync 超时, {ex.Message}, CopterId: {copter.Id}。");
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
var tasks = new Task[2];
|
||||
tasks[0] = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await copter.SetParamAsync("NOTI_GPSLED", count, 5000);
|
||||
}
|
||||
catch (TimeoutException ex)
|
||||
{
|
||||
_logger.Log($"NOTI_GPSLED 超时, {ex.Message}, CopterId: {copter.Id}。");
|
||||
}
|
||||
});
|
||||
tasks[1] = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await copter.SetParamAsync("NOTI_ARMLED", count, 5000);
|
||||
}
|
||||
catch (TimeoutException ex)
|
||||
{
|
||||
_logger.Log($"NOTI_ARMLED 超时, {ex.Message}, CopterId: {copter.Id}。");
|
||||
}
|
||||
});
|
||||
*/
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* isOn为true,打开灯;isOn为false,关闭灯
|
||||
*/
|
||||
private async Task LEDFlashTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info, bool isOn)
|
||||
{
|
||||
var copter = info.Copter;
|
||||
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
// float gpsLed = await c.GetParamAsync("NOTI_GPSLED");
|
||||
|
||||
/*
|
||||
float ledControl = 0.0f; //关灯
|
||||
if (isOn)
|
||||
{
|
||||
ledControl = 1.0f; //长亮
|
||||
}
|
||||
*/
|
||||
var tasks = new Task[1];
|
||||
tasks[0] = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await copter.SetShowLEDAsync(isOn);
|
||||
// await copter.SetParamAsync("NTF_SHOWLED", ledControl, 5000);
|
||||
}
|
||||
catch (TimeoutException ex)
|
||||
{
|
||||
_logger.Log($"SetShowLED 超时, {ex.Message}, CopterId: {copter.Id}。");
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
var tasks = new Task[2];
|
||||
tasks[0] = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await copter.SetParamAsync("NOTI_GPSLED", ledControl, 5000);
|
||||
}
|
||||
catch (TimeoutException ex)
|
||||
{
|
||||
_logger.Log($"NOTI_GPSLED 超时, {ex.Message}, CopterId: {copter.Id}。");
|
||||
}
|
||||
});
|
||||
tasks[1] = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await copter.SetParamAsync("NOTI_ARMLED", ledControl, 5000);
|
||||
}
|
||||
catch (TimeoutException ex)
|
||||
{
|
||||
_logger.Log($"NOTI_ARMLED 超时, {ex.Message}, CopterId: {copter.Id}。");
|
||||
}
|
||||
});
|
||||
*/
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task LEDFlashPlanAsync()
|
||||
{
|
||||
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await LEDColumnFlashAsync();
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await LEDDoubleColumnFlashAsync();
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await LEDLineFlashAsync();
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await LEDCircleFlashAsync();
|
||||
await Task.Delay(500).ConfigureAwait(false);
|
||||
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, false)));
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await Task.WhenAll(SingleCopterInfos.Select(info => LEDFlashTaskFlySingleCopterAsync(info, true)));
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// 一排一排闪烁 需要30架飞机,6排,一排5架,一排排闪灯
|
||||
private async Task LEDColumnFlashAsync()
|
||||
{
|
||||
await LEDArrayFlashAsync(columnFirst);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(columnSecond);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(columnThird);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(columnFourth);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(columnFive);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(columnSix);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// 以圆圈收缩形式显示
|
||||
private async Task LEDCircleFlashAsync()
|
||||
{
|
||||
|
||||
await LEDArrayFlashAsync(circleFirst);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(circleSecond);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(circleThird);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// 两列同时闪烁
|
||||
private async Task LEDDoubleColumnFlashAsync()
|
||||
{
|
||||
|
||||
await LEDArrayFlashAsync(doubleColumnFirst);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(doubleColumnSecond);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(doubleColumnThird);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// 斜线方式闪烁
|
||||
private async Task LEDLineFlashAsync()
|
||||
{
|
||||
|
||||
await LEDArrayFlashAsync(lineFirst);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(lineSecond);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(lineThird);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(lineFourth);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(lineFive);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(lineSix);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(lineSeven);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(lineEight);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(lineNine);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
|
||||
await LEDArrayFlashAsync(lineTen);
|
||||
await Task.Delay(200).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task LEDArrayFlashAsync(int[] LEDArray)
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
|
||||
var tasks_selected = new Task[LEDArray.Length];
|
||||
for (int i = 0; i < LEDArray.Length; i++)
|
||||
{
|
||||
var info = infos[LEDArray[i]];
|
||||
|
||||
tasks_selected[i] = await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
var internalInfo = info;
|
||||
await LEDFlashTaskFlySingleCopterAsync(internalInfo, true);
|
||||
});
|
||||
}
|
||||
await Task.WhenAll(tasks_selected).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,489 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTask
|
||||
{
|
||||
private float _RTLAlt = 20.0f;
|
||||
public float RTLAlt
|
||||
{
|
||||
get { return _RTLAlt; }
|
||||
set { Set(nameof(RTLAlt), ref _RTLAlt, value); }
|
||||
}
|
||||
private int _RetNumAttr = 1;
|
||||
public int RetNumAttr
|
||||
{
|
||||
get { return _RetNumAttr; }
|
||||
set
|
||||
{
|
||||
Set(nameof(RetNumAttr), ref _RetNumAttr, value);
|
||||
}
|
||||
}
|
||||
public async Task RunReturnToLandTaskAsync()
|
||||
{
|
||||
int TaskCount = _flightTaskManager.Tasks.Count();
|
||||
if (TaskCount > 1)
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
// var infos = SingleCopterInfos.OrderByDescending(i => i.TargetAlt).ToList();
|
||||
var tasks = new Task[infos.Count];
|
||||
var tasksTmp = new Task[infos.Count];
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
var info = infos[i];
|
||||
|
||||
// var copter = info.Copter;
|
||||
if (info.RTLStage <= 1) // 当前阶段小于等于1时进入
|
||||
{
|
||||
await ReturnToLandTaskFlySingleCopterAsync(info);
|
||||
}
|
||||
|
||||
tasksTmp[i] = ReturnToLandSecondTaskAsync(info);
|
||||
|
||||
}
|
||||
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
var info = infos[i];
|
||||
info.RTLStage = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public async Task MutilRunReturnToLandTaskAsync()
|
||||
{
|
||||
int TaskCount = _flightTaskManager.Tasks.Count();
|
||||
if (TaskCount > 1)
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
|
||||
int copterCount = infos.Count;
|
||||
int integerPart = copterCount / RetNumAttr;
|
||||
int residualPart = copterCount % RetNumAttr;
|
||||
var tasksTmp = new Task[infos.Count];
|
||||
//整数部分执行返航降落
|
||||
for (int i = 0; i < integerPart; i++)
|
||||
{
|
||||
var tasksRetutn = new Task[RetNumAttr*2];
|
||||
//设置返航任务
|
||||
for (int j = RetNumAttr * i; j < RetNumAttr * (i + 1); j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
|
||||
int indexTmp = j - RetNumAttr * i;
|
||||
|
||||
// var copter = info.Copter;
|
||||
if (info.RTLStage <= 1) // 当前阶段小于等于1时进入
|
||||
{
|
||||
tasksRetutn[indexTmp] = ReturnToLandTaskFlySingleCopterAsync(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
tasksRetutn[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//设置降落任务
|
||||
if (i > 0)
|
||||
{
|
||||
|
||||
for (int j = RetNumAttr * (i - 1); j < RetNumAttr * (i); j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
|
||||
int indexTmp = RetNumAttr+ j - RetNumAttr * (i-1);
|
||||
|
||||
// var copter = info.Copter;
|
||||
if (info.RTLStage == 2) // 当前阶段小于等于1时进入
|
||||
{
|
||||
tasksRetutn[indexTmp] = ReturnToLandSecondTaskAsync(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
tasksRetutn[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
//第一波返航,降落任务为空
|
||||
for (int j = RetNumAttr * (i +1); j < RetNumAttr * (i+2); j++)
|
||||
{
|
||||
int indexTmp = j - RetNumAttr * i;
|
||||
tasksRetutn[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//开始执行这波返航和上波降落
|
||||
await Task.WhenAll(tasksRetutn).ConfigureAwait(false);
|
||||
//上波降落后设置为0
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
for (int j = RetNumAttr * (i - 1); j < RetNumAttr * (i); j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
info.RTLStage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (residualPart > 0)
|
||||
{
|
||||
var tasksreturn = new Task[residualPart+ RetNumAttr];
|
||||
//余数部分开始返航
|
||||
for (int j = integerPart * RetNumAttr; j < RetNumAttr * integerPart + residualPart; j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
int indexTmp = j - RetNumAttr * integerPart;
|
||||
// var copter = info.Copter;
|
||||
if (info.RTLStage <= 1) // 当前阶段小于等于1时进入
|
||||
{
|
||||
tasksreturn[indexTmp] = ReturnToLandTaskFlySingleCopterAsync(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
tasksreturn[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//无余数的整数部分最后一波开始降落
|
||||
// var tasksLastland = new Task[RetNumAttr];
|
||||
for (int j = RetNumAttr * (integerPart - 1); j < RetNumAttr * (integerPart); j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
|
||||
int indexTmp = RetNumAttr + j - RetNumAttr * integerPart;
|
||||
|
||||
// var copter = info.Copter;
|
||||
if (info.RTLStage == 2) // 当前阶段小于等于1时进入
|
||||
{
|
||||
tasksreturn[residualPart + indexTmp] = ReturnToLandSecondTaskAsync(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
tasksreturn[residualPart+indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||
}
|
||||
}
|
||||
|
||||
//开始执行降落和返航
|
||||
await Task.WhenAll(tasksreturn).ConfigureAwait(false);
|
||||
|
||||
//降落后设置为0
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
|
||||
for (int j = RetNumAttr * (integerPart - 1); j < RetNumAttr * (integerPart); j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
info.RTLStage = 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//最后余数部分降落
|
||||
|
||||
var tasksRetutn1 = new Task[residualPart];
|
||||
for (int j = integerPart * RetNumAttr; j < RetNumAttr * integerPart + residualPart; j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
int indexTmp = j - RetNumAttr * integerPart;
|
||||
// var copter = info.Copter;
|
||||
if (info.RTLStage == 2) // 当前阶段小于等于1时进入
|
||||
{
|
||||
tasksRetutn1[indexTmp] = ReturnToLandSecondTaskAsync(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
tasksRetutn1[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||
}
|
||||
}
|
||||
await Task.WhenAll(tasksRetutn1).ConfigureAwait(false);
|
||||
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
|
||||
for (int j = integerPart * RetNumAttr; j < RetNumAttr * integerPart + residualPart; j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
info.RTLStage = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
//无余数的整数部分最后一波开始降落
|
||||
var tasksLastland = new Task[RetNumAttr];
|
||||
for (int j = RetNumAttr * (integerPart - 1); j < RetNumAttr * (integerPart); j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
|
||||
int indexTmp = RetNumAttr + j - RetNumAttr * integerPart;
|
||||
|
||||
// var copter = info.Copter;
|
||||
if (info.RTLStage == 2) // 当前阶段小于等于1时进入
|
||||
{
|
||||
tasksLastland[indexTmp] = ReturnToLandSecondTaskAsync(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
tasksLastland[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||
}
|
||||
}
|
||||
await Task.WhenAll(tasksLastland).ConfigureAwait(false);
|
||||
|
||||
//降落后设置为0
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
|
||||
for (int j = RetNumAttr * (integerPart - 1); j < RetNumAttr * (integerPart); j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
info.RTLStage = 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//原地下降高度到15米,然后返回起飞点
|
||||
private async Task ReturnToLandTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
float takeOffAlt = RTLAlt;
|
||||
int TaskCount = _flightTaskManager.Tasks.Count();
|
||||
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
var copter = info.Copter;
|
||||
var copterPreviousTask = _flightTaskManager.Tasks[TaskCount-2].SingleCopterInfos[copterIndex]; // 倒数第二步的目标位置
|
||||
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
DateTime dtNow = DateTime.Now;
|
||||
DateTime dtLastTime = DateTime.Now;
|
||||
TimeSpan ts = dtNow - dtLastTime;
|
||||
// 第一阶段:垂直飞行
|
||||
if (info.RTLStage == 0)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(copterPreviousTask.TargetLat, copterPreviousTask.TargetLng, takeOffAlt);
|
||||
}
|
||||
|
||||
while (!info.Copter.ArrivedTarget(copterPreviousTask.TargetLat, copterPreviousTask.TargetLng, takeOffAlt))
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
if (ts.TotalMilliseconds > 1000)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(copterPreviousTask.TargetLat, copterPreviousTask.TargetLng, takeOffAlt);
|
||||
}
|
||||
dtLastTime = dtNow;
|
||||
}
|
||||
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
info.RTLStage++;
|
||||
}
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
dtLastTime = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
|
||||
var copterFirstTask = _flightTaskManager.Tasks[0].SingleCopterInfos[copterIndex]; // 第一步记录的家位置
|
||||
// 第二阶段:水平飞行
|
||||
if (info.RTLStage == 1)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(copterFirstTask.TargetLat, copterFirstTask.TargetLng, takeOffAlt);
|
||||
}
|
||||
|
||||
while (!info.Copter.ArrivedTarget(copterFirstTask.TargetLat, copterFirstTask.TargetLng, takeOffAlt))
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
if (ts.TotalMilliseconds > 1000)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(copterFirstTask.TargetLat, copterFirstTask.TargetLng, takeOffAlt);
|
||||
}
|
||||
dtLastTime = dtNow;
|
||||
}
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info.RTLStage++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//在起飞点上空从15米降落到4米,然后切land模式
|
||||
private async Task ReturnToLandSecondTaskAsync(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
// await Task.Run(async () =>
|
||||
// {
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
DateTime dtNow = DateTime.Now;
|
||||
DateTime dtLastTime = DateTime.Now;
|
||||
TimeSpan ts = dtNow - dtLastTime;
|
||||
|
||||
float landAlt = 4.0f; // 飞机降落到4m再切land模式
|
||||
|
||||
var copterFirstTask = _flightTaskManager.Tasks[0].SingleCopterInfos[copterIndex]; // 第一步记录的家位置
|
||||
// 第三阶段
|
||||
if (info.RTLStage == 2)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(copterFirstTask.TargetLat, copterFirstTask.TargetLng, landAlt);
|
||||
}
|
||||
|
||||
while (!info.Copter.ArrivedTarget(copterFirstTask.TargetLat, copterFirstTask.TargetLng, landAlt))
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
if (ts.TotalMilliseconds > 1000)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(copterFirstTask.TargetLat, copterFirstTask.TargetLng, landAlt);
|
||||
}
|
||||
dtLastTime = dtNow;
|
||||
}
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info.RTLStage++;
|
||||
}
|
||||
|
||||
// 切到land模式
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
var copter = info.Copter;
|
||||
if (info.RTLStage == 3) // 下降过程
|
||||
{
|
||||
for (int j = 0; j < 5; j++) // added by ZJF
|
||||
{
|
||||
// await copter.ReturnToLaunchAsync();
|
||||
await copter.LandAsync(); // 修改为降落模式
|
||||
await Task.Delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTask
|
||||
{
|
||||
public async Task RunSimpleCircleTaskAsync()
|
||||
{
|
||||
var center = SingleCopterInfos.Select(info => info.Copter).GetCenter().Value;
|
||||
|
||||
// 林俊清, 20150921, 自动计算圆心方向和半径,然后直接调用普通画圈的方法。
|
||||
foreach (var info in SingleCopterInfos)
|
||||
{
|
||||
info.CenterDirectionDeg = (short)info.Copter.InPlaneDirectionToDeg(center.Lat, center.Lng);
|
||||
info.Radius = (int)(info.Copter.InPlaneDistanceTo(center.Lat, center.Lng) * 100);
|
||||
}
|
||||
await RunCircleTaskAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,481 +1,488 @@
|
||||
using Plane.Copters;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plane.Geography;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTask
|
||||
{
|
||||
|
||||
|
||||
private int _TakeOffNumAttr = 1;
|
||||
public int TakeOffNumAttr
|
||||
{
|
||||
get { return _TakeOffNumAttr; }
|
||||
set
|
||||
{
|
||||
Set(nameof(TakeOffNumAttr), ref _TakeOffNumAttr, value);
|
||||
}
|
||||
}
|
||||
|
||||
//起飞到第一个航点高度的飞行时间
|
||||
private byte _TakeOffTime = 10;
|
||||
public byte TakeOffTime
|
||||
{
|
||||
get { return _TakeOffTime; }
|
||||
set { Set(nameof(TakeOffTime), ref _TakeOffTime, value); }
|
||||
}
|
||||
|
||||
//一架架起飞--未使用
|
||||
public async Task RunTakeOffTaskAsync()
|
||||
{
|
||||
// float takeOffAlt = 15;
|
||||
int TaskCount = _flightTaskManager.Tasks.Count();
|
||||
if (TaskCount > 1)
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
// var tasks = new Task[infos.Count];
|
||||
var tasksTmp = new Task[infos.Count];
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
var info = infos[i];
|
||||
|
||||
if (info.takeOffStage == 0) // 第一阶段:起飞到10m
|
||||
{
|
||||
await TakeOffTaskFlySingleCopterAsync(info);
|
||||
//if (_flightTaskManager.IsPaused == false)
|
||||
//{
|
||||
// info.takeOffStage++;
|
||||
//}
|
||||
}
|
||||
|
||||
tasksTmp[i] = TakeOffSecondTaskAsync(info); // 第二和第三阶段
|
||||
}
|
||||
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
var info = infos[i];
|
||||
info.takeOffStage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//新版的起飞方案
|
||||
public async Task NewMutilRunTakeOffTaskAsync()
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
var tasksTakeOff = new Task[infos.Count];
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
//tasksTakeOff[i] = NewSingleRunTaskOffTaskAsunc(infos[i]);
|
||||
|
||||
|
||||
tasksTakeOff[i] = await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
var internalInfo = infos[i];
|
||||
|
||||
await NewSingleRunTaskOffTaskAsunc(internalInfo);
|
||||
});
|
||||
}
|
||||
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
||||
//await Task.Delay(100);
|
||||
}
|
||||
|
||||
private async Task NewSingleRunTaskOffTaskAsunc(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
DateTime dtNow = DateTime.Now;
|
||||
DateTime dtLastTime = DateTime.Now;
|
||||
TimeSpan ts = dtNow - dtLastTime;
|
||||
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
var copter = info.Copter;
|
||||
await copter.UnlockAsync();
|
||||
//等待起飞时间
|
||||
while ((int)ts.TotalMilliseconds < (int)info.TakeOffWaitTime * 1000)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await copter.UnlockAsync();
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(100);
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
}
|
||||
|
||||
//虚拟飞机5秒后不起飞会自动上锁
|
||||
await copter.UnlockAsync();
|
||||
|
||||
for (int i = 0; i < 5; i++) // added by ZJF
|
||||
{
|
||||
await copter.TakeOffAsync();
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var copterNextTask = _flightTaskManager.Tasks[TaskIndex + 1].SingleCopterInfos[copterIndex];
|
||||
float takeOffAlt = copterNextTask.TargetAlt;
|
||||
|
||||
info.TargetLat = info.Copter.Latitude;
|
||||
info.TargetLng = info.Copter.Longitude;
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
FlightTask task = _flightTaskManager.CurrentRunningTask;
|
||||
|
||||
while (ts.TotalMilliseconds < task.TakeOffTime * 1000)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//老方案 ----- 按起飞数量起飞
|
||||
// 几架飞机同时起飞,参数为takeOffCount-----------------使用中
|
||||
//起飞分三个阶段:
|
||||
//1阶段:分批起飞到15米(目前15米高度是飞控起飞航点决定),上一批起飞超过5米下一批开始起飞,
|
||||
// 等待全部起飞完成后执行第二阶段,
|
||||
//2阶段:等待高度超过9米(可能已到达15米)然后平飞到第一个航点位置,高度为15米的位置,
|
||||
//3阶段:垂直上升到第一个航点指定高度
|
||||
//
|
||||
//修改方案:针对高度
|
||||
//1.上升到起飞高度(目前没有地面站设置高度,高度在飞控中)
|
||||
//2.直接飞往第一个航点的高度
|
||||
public async Task MutilRunTakeOffTaskAsync()
|
||||
{
|
||||
|
||||
int TaskCount = _flightTaskManager.Tasks.Count();
|
||||
if (TaskCount > 1)
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
|
||||
//不再使用起飞数量 强制设置起飞总数等于所有飞机
|
||||
int takeOffCount = _copterManager.Copters.Count();
|
||||
int copterCount = infos.Count;
|
||||
int integerPart = copterCount / takeOffCount;
|
||||
int residualPart = copterCount % takeOffCount;
|
||||
|
||||
// var tasks = new Task[infos.Count];
|
||||
var tasksTmp = new Task[infos.Count];
|
||||
for (int i = 0; i < integerPart; i++)
|
||||
{
|
||||
var tasksTakeOff = new Task[takeOffCount];
|
||||
//执行n架同时起飞
|
||||
for (int j = takeOffCount * i; j < takeOffCount * (i + 1); j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
|
||||
int indexTmp = j - takeOffCount * i;
|
||||
if (info.takeOffStage == 0) // 第一阶段:起飞到15m
|
||||
{
|
||||
tasksTakeOff[indexTmp] = TakeOffTaskFlySingleCopterAsync(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
tasksTakeOff[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||
}
|
||||
}
|
||||
//等待多架起飞任务-起飞高度超过5米完成
|
||||
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
||||
//加入已起飞飞机的第二第三阶段起飞任务--并不执行
|
||||
for (int j = takeOffCount * i; j < takeOffCount * (i + 1); j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
tasksTmp[j] = TakeOffSecondTaskAsync(info); // 第二和第三阶段
|
||||
}
|
||||
}
|
||||
|
||||
// 余数架飞机同时起飞
|
||||
if (residualPart > 0)
|
||||
{
|
||||
var tasksTakeOff = new Task[residualPart];
|
||||
for (int j = integerPart * takeOffCount; j < takeOffCount * integerPart + residualPart; j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
|
||||
int indexTmp = j - takeOffCount * integerPart;
|
||||
if (info.takeOffStage == 0) // 第一阶段:起飞到15m
|
||||
{
|
||||
tasksTakeOff[indexTmp] = TakeOffTaskFlySingleCopterAsync(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
tasksTakeOff[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||
}
|
||||
}
|
||||
//等待起飞超过5米
|
||||
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
||||
|
||||
for (int j = integerPart * takeOffCount; j < takeOffCount * integerPart + residualPart; j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
tasksTmp[j] = TakeOffSecondTaskAsync(info); // 加入第二和第三阶段
|
||||
}
|
||||
}
|
||||
//执行并等待所有的第二第三阶段起飞任务完成
|
||||
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
var info = infos[i];
|
||||
info.takeOffStage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
|
||||
//执行第一阶段解锁起飞任务---使用中
|
||||
private async Task TakeOffTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
DateTime dtNow = DateTime.Now;
|
||||
DateTime dtLastTime = DateTime.Now;
|
||||
TimeSpan ts = dtNow - dtLastTime;
|
||||
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
var copter = info.Copter;
|
||||
var copterNextTask = _flightTaskManager.Tasks[1].SingleCopterInfos[copterIndex];
|
||||
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
return;
|
||||
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//设置灯光
|
||||
await copter.SetShowLEDAsync(true);
|
||||
|
||||
//开始解锁
|
||||
await copter.UnlockAsync();
|
||||
for (int i = 0; !copter.IsUnlocked; i++)
|
||||
{
|
||||
//if (_flightTaskManager.IsPaused == true)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
//8秒内每1000毫秒尝试解锁一次
|
||||
//解锁间隔一定要超过1s否则导致飞控以后无法解锁
|
||||
|
||||
if (i > 320)
|
||||
return; //无法解锁后面不用执行了
|
||||
if (i % (1000 / 25) == 1000 / 25 - 1)
|
||||
{
|
||||
await copter.UnlockAsync(); // 每 1000 毫秒重试一次。
|
||||
}
|
||||
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
}
|
||||
//////解锁完成
|
||||
|
||||
// 为了返航,记录家的位置, 应该放在起飞命令
|
||||
info.TargetLat = info.Copter.Latitude;
|
||||
info.TargetLng = info.Copter.Longitude;
|
||||
|
||||
//等待起飞时间
|
||||
while (ts.TotalMilliseconds < info.TakeOffWaitTime * 1000 )
|
||||
{
|
||||
await Task.Delay(100);
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
}
|
||||
|
||||
//开始起飞
|
||||
for (int i = 0; i < 5; i++) // added by ZJF
|
||||
{
|
||||
await copter.TakeOffAsync();
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// while (copter.Altitude < 4 || copter.State == Copters.CopterState.TakingOff)
|
||||
//低于5米任务一直等待
|
||||
while (copter.Altitude < 5) // 修改起飞逻辑,当高度达到5米时,下一架开始起飞
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/* //先不要这个控制看能否正常工作
|
||||
if (copter.Altitude > 8)
|
||||
{
|
||||
await info.Copter.GuidAsync();
|
||||
return;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//执行第二第三阶段起飞任务-------------使用中
|
||||
private async Task TakeOffSecondTaskAsync(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
var copterNextTask = _flightTaskManager.Tasks[1].SingleCopterInfos[copterIndex];
|
||||
float takeOffAlt = copterNextTask.TargetAlt;// 15; 起飞高度到下个任务的高度
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
} // await Task.Run(async () =>
|
||||
// {
|
||||
// 小于9米时等待----按起飞高度算此时可能已到达15米起飞高度
|
||||
if (info.takeOffStage == 0)
|
||||
{
|
||||
while (info.Copter.Altitude < 9)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
info.takeOffStage++;
|
||||
}
|
||||
}
|
||||
|
||||
DateTime dtNow = DateTime.Now;
|
||||
DateTime dtLastTime = DateTime.Now;
|
||||
TimeSpan ts = dtNow - dtLastTime;
|
||||
|
||||
#region 屏蔽掉第二个阶段直接进入第三个阶 到达起飞高度直接飞往第一个航点
|
||||
|
||||
// 第二阶段:超过9米开始水平飞行
|
||||
if (info.takeOffStage == 1)
|
||||
{
|
||||
//切换到guided模式
|
||||
await info.Copter.GuidAsync();
|
||||
//设置灯光为航点要求的灯光
|
||||
await info.Copter.SetShowLEDAsync(copterNextTask.FlytoShowLED );
|
||||
//异步执行飞到第一个航点高度固定为15米的任务
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
}
|
||||
//直到到达第一个航点并高度15米
|
||||
while (!info.Copter.ArrivedTarget(info.TargetLat, info.TargetLng, takeOffAlt))
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
//每2秒再异步执行一次到航点高度15米的任务
|
||||
if (ts.TotalMilliseconds > 2000)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
}
|
||||
dtLastTime = dtNow;
|
||||
}
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
info.takeOffStage++; //当前变为2
|
||||
}
|
||||
}
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
dtLastTime = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
|
||||
#endregion
|
||||
|
||||
info.takeOffStage++;
|
||||
|
||||
// 第三阶段:从第一个航点位置15米垂直飞行
|
||||
if (info.takeOffStage == 2)
|
||||
{
|
||||
//执行飞到第一个航点高度为设定目标高度
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
}
|
||||
//直到到达第一个航点
|
||||
while (!info.Copter.ArrivedTarget(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt))
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
//每2秒发一次第一个航点飞行任务
|
||||
if (ts.TotalMilliseconds > 2000)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
}
|
||||
dtLastTime = dtNow;
|
||||
}
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
using Plane.Copters;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Plane.Geography;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTask
|
||||
{
|
||||
|
||||
|
||||
//起飞到第一个航点高度的飞行时间
|
||||
private byte _TakeOffTime = 10;
|
||||
public byte TakeOffTime
|
||||
{
|
||||
get { return _TakeOffTime; }
|
||||
set { Set(nameof(TakeOffTime), ref _TakeOffTime, value); }
|
||||
}
|
||||
|
||||
//一架架起飞--未使用
|
||||
public async Task RunTakeOffTaskAsync()
|
||||
{
|
||||
// float takeOffAlt = 15;
|
||||
int TaskCount = _flightTaskManager.Tasks.Count();
|
||||
if (TaskCount > 1)
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
// var tasks = new Task[infos.Count];
|
||||
var tasksTmp = new Task[infos.Count];
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
var info = infos[i];
|
||||
|
||||
if (info.takeOffStage == 0) // 第一阶段:起飞到10m
|
||||
{
|
||||
await TakeOffTaskFlySingleCopterAsync(info);
|
||||
//if (_flightTaskManager.IsPaused == false)
|
||||
//{
|
||||
// info.takeOffStage++;
|
||||
//}
|
||||
}
|
||||
|
||||
tasksTmp[i] = TakeOffSecondTaskAsync(info); // 第二和第三阶段
|
||||
}
|
||||
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
var info = infos[i];
|
||||
info.takeOffStage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//新版的起飞方案
|
||||
public async Task NewMutilRunTakeOffTaskAsync()
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
var tasksTakeOff = new Task[infos.Count];
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
tasksTakeOff[i] = await Task.Factory.StartNew(async () =>
|
||||
{
|
||||
var internalInfo = infos[i];
|
||||
await NewSingleRunTaskOffTaskAsunc(internalInfo);
|
||||
});
|
||||
}
|
||||
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单独飞机 执行起飞任务
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
/// <returns></returns>
|
||||
private async Task NewSingleRunTaskOffTaskAsunc(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
DateTime dtNow = DateTime.Now;
|
||||
DateTime dtLastTime = DateTime.Now;
|
||||
TimeSpan ts = dtNow - dtLastTime;
|
||||
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
var copter = info.Copter;
|
||||
await copter.UnlockAsync();
|
||||
//等待起飞时间
|
||||
while ((int)ts.TotalMilliseconds < (int)info.TakeOffWaitTime * 1000)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await copter.UnlockAsync();
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(100);
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
}
|
||||
|
||||
//虚拟飞机5秒后不起飞会自动上锁
|
||||
await copter.UnlockAsync();
|
||||
await copter.TakeOffAsync();
|
||||
var copterNextTask = _flightTaskManager.Tasks[TaskIndex + 1].SingleCopterInfos[copterIndex];
|
||||
float takeOffAlt = copterNextTask.TargetAlt;
|
||||
info.TargetLat = info.Copter.Latitude;
|
||||
info.TargetLng = info.Copter.Longitude;
|
||||
//info.Copter.takeOffTargetAltitude = takeOffAlt;
|
||||
FlightTask task = _flightTaskManager.CurrentRunningTask;
|
||||
if (task==null)
|
||||
return;
|
||||
float takeflytime = task.TakeOffTime - info.TakeOffWaitTime;
|
||||
//飞行目标,开始往上飞
|
||||
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt, takeflytime, 1); //秒
|
||||
//解锁起飞用暗紫色
|
||||
info.Copter.LEDColor = CopterManager.CopterTakeoffColor;
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
|
||||
//等待起飞时间完成,并模拟灯光--不移动飞机-飞机自己计算并移动位置
|
||||
while (ts.TotalMilliseconds < task.TakeOffTime * 1000)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
//灯光控制
|
||||
if (info.LEDInfos.Count > 0)
|
||||
{
|
||||
string LEDRGB = "";
|
||||
List<LEDInfo> LedControl = info.LEDInfos.ToList();
|
||||
double time = 0;
|
||||
for (int i = 0; i < LedControl.Count; i++)
|
||||
{
|
||||
|
||||
var led = LedControl[i];
|
||||
time += led.Delay * 1000;
|
||||
if (ts.TotalMilliseconds >= time)
|
||||
LEDRGB = info.LEDInfos[i].LEDRGB;
|
||||
else
|
||||
break;
|
||||
}
|
||||
info.Copter.LEDColor = LEDRGB;
|
||||
///灯光控制结束
|
||||
}
|
||||
}
|
||||
//起飞完成用默认颜色
|
||||
info.Copter.LEDColor = CopterManager.CopterFlyingColor;
|
||||
}
|
||||
|
||||
|
||||
//老方案 ----- 按起飞数量起飞
|
||||
// 几架飞机同时起飞,参数为takeOffCount-----------------使用中
|
||||
//起飞分三个阶段:
|
||||
//1阶段:分批起飞到15米(目前15米高度是飞控起飞航点决定),上一批起飞超过5米下一批开始起飞,
|
||||
// 等待全部起飞完成后执行第二阶段,
|
||||
//2阶段:等待高度超过9米(可能已到达15米)然后平飞到第一个航点位置,高度为15米的位置,
|
||||
//3阶段:垂直上升到第一个航点指定高度
|
||||
//
|
||||
//修改方案:针对高度
|
||||
//1.上升到起飞高度(目前没有地面站设置高度,高度在飞控中)
|
||||
//2.直接飞往第一个航点的高度
|
||||
public async Task MutilRunTakeOffTaskAsync()
|
||||
{
|
||||
|
||||
int TaskCount = _flightTaskManager.Tasks.Count();
|
||||
if (TaskCount > 1)
|
||||
{
|
||||
var infos = SingleCopterInfos;
|
||||
|
||||
//不再使用起飞数量 强制设置起飞总数等于所有飞机
|
||||
int takeOffCount = _copterManager.Copters.Count();
|
||||
int copterCount = infos.Count;
|
||||
int integerPart = copterCount / takeOffCount;
|
||||
int residualPart = copterCount % takeOffCount;
|
||||
|
||||
// var tasks = new Task[infos.Count];
|
||||
var tasksTmp = new Task[infos.Count];
|
||||
for (int i = 0; i < integerPart; i++)
|
||||
{
|
||||
var tasksTakeOff = new Task[takeOffCount];
|
||||
//执行n架同时起飞
|
||||
for (int j = takeOffCount * i; j < takeOffCount * (i + 1); j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
|
||||
int indexTmp = j - takeOffCount * i;
|
||||
if (info.takeOffStage == 0) // 第一阶段:起飞到15m
|
||||
{
|
||||
tasksTakeOff[indexTmp] = TakeOffTaskFlySingleCopterAsync(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
tasksTakeOff[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||
}
|
||||
}
|
||||
//等待多架起飞任务-起飞高度超过5米完成
|
||||
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
||||
//加入已起飞飞机的第二第三阶段起飞任务--并不执行
|
||||
for (int j = takeOffCount * i; j < takeOffCount * (i + 1); j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
tasksTmp[j] = TakeOffSecondTaskAsync(info); // 第二和第三阶段
|
||||
}
|
||||
}
|
||||
|
||||
// 余数架飞机同时起飞
|
||||
if (residualPart > 0)
|
||||
{
|
||||
var tasksTakeOff = new Task[residualPart];
|
||||
for (int j = integerPart * takeOffCount; j < takeOffCount * integerPart + residualPart; j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
|
||||
int indexTmp = j - takeOffCount * integerPart;
|
||||
if (info.takeOffStage == 0) // 第一阶段:起飞到15m
|
||||
{
|
||||
tasksTakeOff[indexTmp] = TakeOffTaskFlySingleCopterAsync(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
tasksTakeOff[indexTmp] = Task.Run(async () => { await Task.Delay(1).ConfigureAwait(false); });
|
||||
}
|
||||
}
|
||||
//等待起飞超过5米
|
||||
await Task.WhenAll(tasksTakeOff).ConfigureAwait(false);
|
||||
|
||||
for (int j = integerPart * takeOffCount; j < takeOffCount * integerPart + residualPart; j++)
|
||||
{
|
||||
var info = infos[j];
|
||||
tasksTmp[j] = TakeOffSecondTaskAsync(info); // 加入第二和第三阶段
|
||||
}
|
||||
}
|
||||
//执行并等待所有的第二第三阶段起飞任务完成
|
||||
await Task.WhenAll(tasksTmp).ConfigureAwait(false);
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
for (int i = 0; i < infos.Count; i++)
|
||||
{
|
||||
var info = infos[i];
|
||||
info.takeOffStage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
|
||||
//执行第一阶段解锁起飞任务---使用中
|
||||
private async Task TakeOffTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
DateTime dtNow = DateTime.Now;
|
||||
DateTime dtLastTime = DateTime.Now;
|
||||
TimeSpan ts = dtNow - dtLastTime;
|
||||
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
var copter = info.Copter;
|
||||
var copterNextTask = _flightTaskManager.Tasks[1].SingleCopterInfos[copterIndex];
|
||||
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
return;
|
||||
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//设置灯光
|
||||
await copter.SetShowLEDAsync(true);
|
||||
|
||||
//开始解锁
|
||||
await copter.UnlockAsync();
|
||||
for (int i = 0; !copter.IsUnlocked; i++)
|
||||
{
|
||||
//if (_flightTaskManager.IsPaused == true)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
//8秒内每1000毫秒尝试解锁一次
|
||||
//解锁间隔一定要超过1s否则导致飞控以后无法解锁
|
||||
|
||||
if (i > 320)
|
||||
return; //无法解锁后面不用执行了
|
||||
if (i % (1000 / 25) == 1000 / 25 - 1)
|
||||
{
|
||||
await copter.UnlockAsync(); // 每 1000 毫秒重试一次。
|
||||
}
|
||||
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
}
|
||||
//////解锁完成
|
||||
|
||||
// 为了返航,记录家的位置, 应该放在起飞命令
|
||||
info.TargetLat = info.Copter.Latitude;
|
||||
info.TargetLng = info.Copter.Longitude;
|
||||
|
||||
//等待起飞时间
|
||||
while (ts.TotalMilliseconds < info.TakeOffWaitTime * 1000 )
|
||||
{
|
||||
await Task.Delay(100);
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
}
|
||||
|
||||
//开始起飞
|
||||
for (int i = 0; i < 5; i++) // added by ZJF
|
||||
{
|
||||
await copter.TakeOffAsync();
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// while (copter.Altitude < 4 || copter.State == Copters.CopterState.TakingOff)
|
||||
//低于5米任务一直等待
|
||||
while (copter.Altitude < 5) // 修改起飞逻辑,当高度达到5米时,下一架开始起飞
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/* //先不要这个控制看能否正常工作
|
||||
if (copter.Altitude > 8)
|
||||
{
|
||||
await info.Copter.GuidAsync();
|
||||
return;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//执行第二第三阶段起飞任务-------------使用中
|
||||
private async Task TakeOffSecondTaskAsync(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
var copterNextTask = _flightTaskManager.Tasks[1].SingleCopterInfos[copterIndex];
|
||||
float takeOffAlt = copterNextTask.TargetAlt;// 15; 起飞高度到下个任务的高度
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
} // await Task.Run(async () =>
|
||||
// {
|
||||
// 小于9米时等待----按起飞高度算此时可能已到达15米起飞高度
|
||||
if (info.takeOffStage == 0)
|
||||
{
|
||||
while (info.Copter.Altitude < 9)
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
info.takeOffStage++;
|
||||
}
|
||||
}
|
||||
|
||||
DateTime dtNow = DateTime.Now;
|
||||
DateTime dtLastTime = DateTime.Now;
|
||||
TimeSpan ts = dtNow - dtLastTime;
|
||||
|
||||
#region 屏蔽掉第二个阶段直接进入第三个阶 到达起飞高度直接飞往第一个航点
|
||||
|
||||
// 第二阶段:超过9米开始水平飞行
|
||||
if (info.takeOffStage == 1)
|
||||
{
|
||||
//切换到guided模式
|
||||
await info.Copter.GuidAsync();
|
||||
//设置灯光为航点要求的灯光
|
||||
await info.Copter.SetShowLEDAsync(copterNextTask.FlytoShowLED );
|
||||
//异步执行飞到第一个航点高度固定为15米的任务
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
}
|
||||
//直到到达第一个航点并高度15米
|
||||
while (!info.Copter.ArrivedTarget(info.TargetLat, info.TargetLng, takeOffAlt))
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
//每2秒再异步执行一次到航点高度15米的任务
|
||||
if (ts.TotalMilliseconds > 2000)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(info.TargetLat, info.TargetLng, takeOffAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
}
|
||||
dtLastTime = dtNow;
|
||||
}
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_flightTaskManager.IsPaused == false)
|
||||
{
|
||||
info.takeOffStage++; //当前变为2
|
||||
}
|
||||
}
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
dtLastTime = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
|
||||
#endregion
|
||||
|
||||
info.takeOffStage++;
|
||||
|
||||
// 第三阶段:从第一个航点位置15米垂直飞行
|
||||
if (info.takeOffStage == 2)
|
||||
{
|
||||
//执行飞到第一个航点高度为设定目标高度
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
}
|
||||
//直到到达第一个航点
|
||||
while (!info.Copter.ArrivedTarget(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt))
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
|
||||
dtNow = DateTime.Now;
|
||||
ts = dtNow - dtLastTime;
|
||||
//每2秒发一次第一个航点飞行任务
|
||||
if (ts.TotalMilliseconds > 2000)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
await info.Copter.FlyToAsync(copterNextTask.TargetLat, copterNextTask.TargetLng, copterNextTask.TargetAlt);
|
||||
await Task.Delay(10).ConfigureAwait(false);
|
||||
}
|
||||
dtLastTime = dtNow;
|
||||
}
|
||||
// 当该飞机被标记时,悬停并跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
using Plane.Copters;
|
||||
using Plane.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Plane.FormationCreator.Formation
|
||||
{
|
||||
public partial class FlightTask
|
||||
{
|
||||
public async Task RunTurnTaskAsync()
|
||||
{
|
||||
await Task.WhenAll(
|
||||
SingleCopterInfos.Select(info => TurnTaskFlySingleCopterAsync(info))
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task TurnTaskFlySingleCopterAsync(FlightTaskSingleCopterInfo info)
|
||||
{
|
||||
int copterIndex = SingleCopterInfos.IndexOf(info);
|
||||
// 当该飞机被标记时,跳过飞行任务
|
||||
if ((bool)_copterManager.CopterStatus[copterIndex])
|
||||
return;
|
||||
|
||||
await info.Copter.SetMobileControlAsync(yaw: info.TargetHeading);
|
||||
while (!info.Copter.ArrivedHeading(info.TargetHeading))
|
||||
{
|
||||
if (_flightTaskManager.IsPaused == true)
|
||||
{
|
||||
await info.Copter.HoverAsync();
|
||||
return;
|
||||
}
|
||||
await Task.Delay(25).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await info.Copter.HoverAsync();
|
||||
}
|
||||
}
|
||||
}
|
@ -133,15 +133,16 @@ namespace Plane.FormationCreator.Formation
|
||||
// {
|
||||
//_copterManager.Select(_copterManager.Copters[copterIndex]);
|
||||
ICopter copter = null;
|
||||
// try
|
||||
// {
|
||||
// copter = _copterManager.Copters.First(o => o.Name == (copterIndex + 1).ToString());
|
||||
// }
|
||||
// catch (Exception)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
copter = _copterManager.Copters.FirstOrDefault(o => o.Name == (copterIndex + 1).ToString());
|
||||
// try
|
||||
// {
|
||||
// copter = _copterManager.Copters.First(o => o.Name == (copterIndex + 1).ToString());
|
||||
// }
|
||||
// catch (Exception)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
string strcoptername = _copterManager.Copters[copterIndex].Name;
|
||||
copter = _copterManager.Copters.FirstOrDefault(o => o.Name == strcoptername);
|
||||
if (copter != null)
|
||||
{
|
||||
_copterManager.Select(copter);
|
||||
|
@ -13,12 +13,15 @@
|
||||
WindowTransitionsEnabled="False"
|
||||
FontFamily="Microsoft YaHei"
|
||||
WindowState="Maximized"
|
||||
Title="无人机编队控制中心"
|
||||
Title="飞行魔方无人机编队控制系统 V2.0"
|
||||
PreviewKeyDown="MetroWindow_PreviewKeyDown"
|
||||
PreviewKeyUp="MetroWindow_PreviewKeyUp"
|
||||
Style="{StaticResource VSWindowStyleKey}"
|
||||
Width="800"
|
||||
Height="600">
|
||||
Width="1920"
|
||||
Height="1080"
|
||||
Closing="Window_Closing"
|
||||
Loaded="Window_Loaded"
|
||||
>
|
||||
|
||||
<c:MetroWindow.Resources>
|
||||
<Style TargetType="Separator"
|
||||
@ -42,18 +45,49 @@
|
||||
|
||||
<c:MetroWindow.RightWindowCommands>
|
||||
<c:WindowCommands>
|
||||
|
||||
<Button Content="{Binding LoginDisp}"
|
||||
Command="{Binding LoginCommand}" />
|
||||
<Button Content="飞行面板"
|
||||
Foreground="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource MainColorConverterFly}}"
|
||||
FontSize="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource MainFontSizeConverterFly}}"
|
||||
Command="{Binding HideModifyTaskViewCommand}" />
|
||||
|
||||
|
||||
<Button Content="设计面板"
|
||||
Foreground="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource MainColorConverterDes}}"
|
||||
FontSize="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource MainFontSizeConverterDes}}"
|
||||
Command="{Binding ShowModifyTaskViewCommand}" />
|
||||
|
||||
|
||||
<Button Content="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource ShowModifyTaskViewButtonContentConverter}}"
|
||||
Command="{Binding ShowOrHideModifyTaskViewCommand}" />
|
||||
<Button Content="切换地图"
|
||||
Command="{Binding ChangeMapModeCommand}"/>
|
||||
Command="{Binding ShowOrHideModifyTaskViewCommand}" Visibility="Collapsed" />
|
||||
|
||||
<Button Content="平面编辑"
|
||||
|
||||
Foreground="{Binding b2DMapMode, Converter={StaticResource MainColorConverterDes}}"
|
||||
FontSize="{Binding b2DMapMode, Converter={StaticResource MainFontSizeConverterDes}}"
|
||||
|
||||
|
||||
Command="{Binding Map2DCommand}"/>
|
||||
<Button Content="实景效果"
|
||||
Foreground="{Binding b2DMapMode, Converter={StaticResource MainColorConverterFly}}"
|
||||
FontSize="{Binding b2DMapMode, Converter={StaticResource MainFontSizeConverterFly}}"
|
||||
Command="{Binding Map3DCommand}"/>
|
||||
|
||||
|
||||
<Button Content="{Binding b2DMapMode, Converter={StaticResource Show2d3dButtonContentConverter}}"
|
||||
Command="{Binding ChangeMapModeCommand}" Visibility="Collapsed"/>
|
||||
|
||||
|
||||
|
||||
<Button Content="重启监听"
|
||||
Visibility="Collapsed"
|
||||
Command="{Binding RestartListeningCommand}" />
|
||||
<Button Content="{Binding SwitchVelocityModeButtonContent}"
|
||||
Command="{Binding SwitchVelocityModeCommand}"
|
||||
Visibility="Collapsed"/>
|
||||
<!--// 林俊清, 20150930, 不分这些模式了。
|
||||
<!--// 王海, 20150930, 不分这些模式了。
|
||||
<Button Content="进入任务模式"
|
||||
Command="{Binding SwitchAppModeCommand}"
|
||||
CommandParameter="{x:Static m:AppMode.PreparedForRunningTasks}"
|
||||
@ -71,7 +105,7 @@
|
||||
Visibility="Collapsed"
|
||||
Click="btnRefreshMap_Click" />
|
||||
<Button Name="btnConnect"
|
||||
Content="连接"
|
||||
Content="设置"
|
||||
Click="btnConnect_Click" />
|
||||
<Menu Name="menuTask" Background="Transparent" VerticalAlignment="Center" >
|
||||
|
||||
@ -98,11 +132,17 @@
|
||||
Command="{Binding ImportTasksCommand}"/>
|
||||
<StackPanel VerticalAlignment="Center" Margin="0,8,0,8" Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
|
||||
<TextBlock Foreground="#969696" VerticalAlignment="Center" Text="起始步骤:"/>
|
||||
<TextBox VerticalAlignment="Bottom" Width="40"
|
||||
<TextBox VerticalAlignment="Center" Width="40" Margin="0,0,5,0"
|
||||
Text="{Binding txtStarindex, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
<TextBlock Foreground="#969696" VerticalAlignment="Center" Text="截止:"/>
|
||||
<TextBox VerticalAlignment="Bottom" Width="40"
|
||||
<TextBox VerticalAlignment="Center" Width="40" Margin="0,0,5,0"
|
||||
Text="{Binding txtendindex, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
<CheckBox Content="飞机位置" Grid.Column="1" Margin="0,8,0,8" Foreground="#969696"
|
||||
IsChecked="{Binding isimpCopterLoc}" />
|
||||
|
||||
|
||||
|
||||
</StackPanel>
|
||||
<Button BorderThickness="1" BorderBrush="#FFFFFF" Content="导入分组信息" Margin="25,8,0,8" Grid.Row="2"
|
||||
Command="{Binding ImportGroupCommand}"/>
|
||||
@ -122,7 +162,7 @@
|
||||
</c:WindowCommands>
|
||||
</c:MetroWindow.RightWindowCommands>
|
||||
|
||||
<Grid>
|
||||
<Grid>
|
||||
<Grid.Background>
|
||||
<ImageBrush ImageSource=".\bg.jpg" />
|
||||
</Grid.Background>
|
||||
@ -131,7 +171,7 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Margin="1">
|
||||
<Grid Margin="1" d:IsHidden="True">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="73*" />
|
||||
<ColumnDefinition Width="27*" MinWidth="360" />
|
||||
@ -139,20 +179,19 @@
|
||||
|
||||
<Grid Margin="0,0,10,0"
|
||||
Width="Auto" >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1371*"/>
|
||||
<ColumnDefinition Width="13*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TabControl SelectedIndex="{Binding MapMode,UpdateSourceTrigger=PropertyChanged}" Grid.RowSpan="3">
|
||||
<TabItem Visibility="Collapsed">
|
||||
<v:MapView x:Name="map"/>
|
||||
</TabItem >
|
||||
<TabItem Visibility="Collapsed">
|
||||
<v:View3D/>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
<v:MapView x:Name="map" Grid.RowSpan="3" Margin="0,0,0,0" />
|
||||
<v:View3D x:Name="map3D" Visibility="Collapsed" Grid.RowSpan="3" Margin="0,0,0,0"/>
|
||||
|
||||
|
||||
<Grid Grid.Row="1" HorizontalAlignment="Right">
|
||||
<WrapPanel Orientation="Vertical">
|
||||
@ -183,12 +222,12 @@
|
||||
x:Name="TaskbarControl"
|
||||
VerticalAlignment="Bottom"
|
||||
Visibility="{Binding Source={x:Static local:AppEx.Current}, Path=AppMode, Converter={StaticResource AppModeToVisibilityConverter}, ConverterParameter=TaskBarView}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
|
||||
<Grid Margin="0,0,0,0"
|
||||
|
||||
Grid.Column="1">
|
||||
<Viewbox Stretch="Fill" Grid.Column="1" Margin="0,0,0,0">
|
||||
<DockPanel>
|
||||
<Grid Margin="0,0,0,0"
|
||||
>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
@ -200,7 +239,7 @@
|
||||
<StackPanel Grid.Row="1">
|
||||
<StackPanel Grid.Row="2"
|
||||
Visibility="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource InversiveBooleanToVisibilityConverter}}">
|
||||
<Separator Grid.ColumnSpan="2" />
|
||||
<Separator Grid.ColumnSpan="2" Margin="0,5,5,5"/>
|
||||
<v:ControlPanelView />
|
||||
</StackPanel>
|
||||
|
||||
@ -212,41 +251,74 @@
|
||||
|
||||
<StackPanel Grid.Row="2"
|
||||
Visibility="{Binding AppEx.ShowModifyTaskView, Converter={StaticResource InversiveBooleanToVisibilityConverter}}">
|
||||
|
||||
<Separator Grid.ColumnSpan="2" />
|
||||
|
||||
<Separator Grid.ColumnSpan="2" Margin="0,0,5,5" />
|
||||
<v:CopterInfoView DataContext="{Binding Path=CopterListViewModel.SelectedCopter}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</DockPanel>
|
||||
</Viewbox>
|
||||
</Grid>
|
||||
|
||||
<Border Grid.Row="1"
|
||||
Background="{StaticResource WhiteBrush}">
|
||||
<Grid>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<TextBlock Margin="4"
|
||||
Text="{Binding Message}" MouseUp="LogShowHide"/>
|
||||
<TextBlock Margin="4"
|
||||
Text="{Binding CopterListViewModel.SelectedCopter.StatusText}" />
|
||||
<TextBlock Margin="10,4"
|
||||
Text="{Binding Message}" Width="480" MouseUp="LogShowHide"/>
|
||||
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" Margin="0,8" BorderBrush="LightGray" BorderThickness="1"/>
|
||||
<TextBlock Margin="10,4" Width="280" Text="{Binding SysStatusText}" />
|
||||
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" Margin="0,8" BorderBrush="LightGray" BorderThickness="1"/>
|
||||
<TextBlock Margin="10,4" Width="210"
|
||||
Text="{Binding ControlPanelViewModelData.RTKState}" />
|
||||
<Separator Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}" Margin="0,8" BorderBrush="LightGray" BorderThickness="1"/>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<TextBlock Text="{Binding Loginstate}" Margin="0,4,14,0"/>
|
||||
<TextBlock Text="广播端口:" Margin="4"/>
|
||||
<ContentPresenter Margin="0,4,4,0" Content="{Binding BoardcastPortOpened, Converter={StaticResource CheckSignConverter2}, Mode=OneWay}" />
|
||||
<TextBlock Text="通信连接:" Margin="4"/>
|
||||
<ContentPresenter Content="{Binding CommunicationModuleConnected, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
|
||||
<ContentPresenter Margin="0,4,14,0" Content="{Binding CommunicationModuleConnected, Converter={StaticResource CheckSignConverter2}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</Border>
|
||||
<TextBox Name="logTextBox" Height="700" Width="600" Background="#FF2D2D2D"
|
||||
|
||||
<Grid x:Name="logGrid" Height="900" VerticalAlignment="Top" HorizontalAlignment="Left" Visibility="Hidden" >
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition MinWidth="20" MaxWidth="800" Width="500"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<DockPanel Grid.Row="0" Grid.Column="0">
|
||||
<TextBox x:Name="logTextBox" Height="900" Width="800" Background="#FF2D2D2D"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Visibility="Hidden"
|
||||
VerticalAlignment="Top"
|
||||
Text="{Binding Logs}"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
TextChanged="LogTextChange"
|
||||
IsReadOnly="True"
|
||||
TextWrapping="Wrap"
|
||||
FontSize="14"
|
||||
ContextMenu="{StaticResource LogMenu}"/>
|
||||
</DockPanel>
|
||||
<GridSplitter Grid.Row="0" Grid.Column="1" Width="3" Margin="0,0,0,0" Background="MidnightBlue"
|
||||
VerticalAlignment="Stretch" HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
|
||||
</c:MetroWindow>
|
||||
|
@ -21,6 +21,7 @@ using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Plane.CommunicationManagement;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Plane.FormationCreator
|
||||
{
|
||||
@ -34,7 +35,11 @@ namespace Plane.FormationCreator
|
||||
InitializeComponent();
|
||||
|
||||
this.DataContext = ServiceLocator.Current.GetInstance<MainViewModel>();
|
||||
|
||||
// this.OnClosing += Window_Closing;
|
||||
//改到设置窗口显示版本信息
|
||||
// var version = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
// Title = "飞行魔方无人机编队控制系统 V" + version.ToString() + "编译时间[" + System.IO.File.GetLastWriteTime(this.GetType().Assembly.Location).ToString() + "]";
|
||||
|
||||
|
||||
//ShowConnectDialog();
|
||||
//if (_copterManager.CoptersForControlling.Count <= 0)
|
||||
@ -53,8 +58,32 @@ namespace Plane.FormationCreator
|
||||
{
|
||||
loginWindow = new ConnectWindow();
|
||||
}
|
||||
loginWindow.Show();
|
||||
loginWindow.ShowDialog ();
|
||||
}
|
||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
bool waitnet = _copterManager.Logined;
|
||||
_copterManager.NetLogout();
|
||||
//等待网络退出
|
||||
if (waitnet)
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
|
||||
/*
|
||||
MessageBoxResult result = MessageBox.Show("Do you really want to exit?", "", MessageBoxButton.YesNo);
|
||||
if (result == MessageBoxResult.No)
|
||||
{
|
||||
e.Cancel = true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ServiceLocator.Current.GetInstance<MainViewModel>().LoginCommand.Execute(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void btnLogin_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
@ -81,7 +110,7 @@ namespace Plane.FormationCreator
|
||||
};
|
||||
var point = PointToScreen(Mouse.GetPosition(this));
|
||||
point.X = Math.Min(point.X, SystemParameters.WorkArea.Width - connectWindow.Width - 30);
|
||||
point.Y = Math.Min(point.Y, SystemParameters.WorkArea.Height - connectWindow.Height - 30);
|
||||
point.Y = Math.Min(point.Y+10, SystemParameters.WorkArea.Height - connectWindow.Height - 30);
|
||||
connectWindow.Left = point.X;
|
||||
connectWindow.Top = point.Y;
|
||||
|
||||
@ -109,7 +138,9 @@ namespace Plane.FormationCreator
|
||||
{
|
||||
|
||||
case Key.LeftCtrl:
|
||||
{
|
||||
case Key.RightCtrl:
|
||||
case Key.LeftAlt:
|
||||
{
|
||||
var copters = _copterManager.AcceptingControlCopters;
|
||||
Shiftkeydown = true;
|
||||
_copterManager.shiftkeydown = true;
|
||||
@ -393,6 +424,8 @@ namespace Plane.FormationCreator
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.LeftCtrl:
|
||||
case Key.RightCtrl:
|
||||
case Key.LeftAlt:
|
||||
{
|
||||
Shiftkeydown = false;
|
||||
_copterManager.shiftkeydown = false;
|
||||
@ -481,15 +514,20 @@ namespace Plane.FormationCreator
|
||||
{
|
||||
MainViewModel vm = DataContext as MainViewModel;
|
||||
LogWindow logWindows = new LogWindow(vm.Messages);
|
||||
logWindows.Show();
|
||||
logWindows.ShowDialog();
|
||||
}
|
||||
|
||||
private void LogShowHide(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (logTextBox.Visibility == Visibility.Visible)
|
||||
logTextBox.Visibility = Visibility.Hidden;
|
||||
|
||||
if (logGrid.Visibility == Visibility.Visible)
|
||||
logGrid.Visibility = Visibility.Hidden;
|
||||
else
|
||||
logTextBox.Visibility = Visibility.Visible;
|
||||
{
|
||||
logGrid.Height = Math.Max(map.ActualHeight, map3D.ActualHeight) - ((TaskBarView)TaskbarControl).TasksControl.ActualHeight;
|
||||
logTextBox.Height = logGrid.Height;
|
||||
logGrid.Visibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
||||
private void LogTextChange(object sender, TextChangedEventArgs e)
|
||||
|
@ -1,56 +1,65 @@
|
||||
using Plane.FormationCreator.Util;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Plane.FormationCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// ModifyParam.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ModifyParam : Window
|
||||
{
|
||||
public bool LoadParam = false;
|
||||
public ModifyParam()
|
||||
{
|
||||
InitializeComponent();
|
||||
// if (!VersionControl.IsFullVersion)
|
||||
// {
|
||||
// hide_panel.Visibility = Visibility.Collapsed;
|
||||
// textParamName.IsReadOnly = true;
|
||||
// btnLoad.Visibility = Visibility.Collapsed;
|
||||
//
|
||||
// label.Visibility = Visibility.Collapsed;
|
||||
// textParamName.Visibility = Visibility.Collapsed;
|
||||
// }
|
||||
}
|
||||
|
||||
private void btnModify_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
LoadParam = false;
|
||||
this.DialogResult = true;
|
||||
}
|
||||
|
||||
private void Modify_Select(object sender, RoutedEventArgs e)
|
||||
{
|
||||
textParamName.Text = ((Button)sender).Tag.ToString();
|
||||
textParamName_cn.Text = ((Button)sender).Content.ToString();
|
||||
}
|
||||
|
||||
private void btnLoad_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
LoadParam = true;
|
||||
this.DialogResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using Plane.FormationCreator.Util;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Plane.FormationCreator
|
||||
{
|
||||
/// <summary>
|
||||
/// ModifyParam.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ModifyParam : Window
|
||||
{
|
||||
public bool LoadParam = false;
|
||||
public ModifyParam()
|
||||
{
|
||||
InitializeComponent();
|
||||
// if (!VersionControl.IsFullVersion)
|
||||
// {
|
||||
// hide_panel.Visibility = Visibility.Collapsed;
|
||||
// textParamName.IsReadOnly = true;
|
||||
// btnLoad.Visibility = Visibility.Collapsed;
|
||||
//
|
||||
// label.Visibility = Visibility.Collapsed;
|
||||
// textParamName.Visibility = Visibility.Collapsed;
|
||||
// }
|
||||
}
|
||||
|
||||
private void btnModify_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
LoadParam = false;
|
||||
this.DialogResult = true;
|
||||
}
|
||||
|
||||
private void Modify_Select(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Formation.CopterManager _copterManager = ServiceLocator.Current.GetInstance<Formation.CopterManager>();
|
||||
|
||||
String strParamName = ((Button)sender).Tag.ToString();
|
||||
if (strParamName == "FS_BATT_VOLTAGE")
|
||||
{
|
||||
if (_copterManager.FC_VER_NO >= 3)
|
||||
strParamName = "BATT_LOW_VOLT";
|
||||
}
|
||||
textParamName.Text = strParamName;
|
||||
textParamName_cn.Text = ((Button)sender).Content.ToString();
|
||||
}
|
||||
|
||||
private void btnLoad_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
LoadParam = true;
|
||||
this.DialogResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,9 @@ using System.Windows;
|
||||
[assembly: AssemblyTitle("GroupGCSMain")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("GroupGCS")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyCompany("北京飞行魔方科技有限公司")]
|
||||
[assembly: AssemblyProduct("无人机编队地面控制系统")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2024")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@ -51,5 +51,5 @@ using System.Windows;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("2.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("2.0.0.0")]
|
||||
[assembly: AssemblyVersion("2.2.0.*")]
|
||||
[assembly: AssemblyFileVersion("2.2.0.0")]
|
||||
|
@ -1,5 +1,8 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Properties">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="/FGCS;component/Styles/Window.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
</ResourceDictionary>
|
136
Plane.FormationCreator/Properties/Resources.Designer.cs
generated
@ -1,63 +1,73 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Plane.FormationCreator.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Plane.FormationCreator.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用此强类型资源类,为所有资源查找
|
||||
/// 重写当前线程的 CurrentUICulture 属性。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Plane.FormationCreator.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Plane.FormationCreator.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重写当前线程的 CurrentUICulture 属性,对
|
||||
/// 使用此强类型资源类的所有资源查找执行重写。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap Logo_small {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Logo_small", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
@ -60,6 +60,7 @@
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
@ -68,9 +69,10 @@
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
@ -85,9 +87,10 @@
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
@ -109,9 +112,13 @@
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="Logo_small" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Logo_small.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
@ -1,38 +1,38 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Plane.FormationCreator.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("192.168.1.50")]
|
||||
public string IPs {
|
||||
get {
|
||||
return ((string)(this["IPs"]));
|
||||
}
|
||||
set {
|
||||
this["IPs"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Plane.FormationCreator.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("192.168.1.50")]
|
||||
public string IPs {
|
||||
get {
|
||||
return ((string)(this["IPs"]));
|
||||
}
|
||||
set {
|
||||
this["IPs"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
Plane.FormationCreator/Resources/Logo_small.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
Plane.FormationCreator/Resources/logo_big.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
@ -34,6 +34,8 @@ namespace Plane.FormationCreator
|
||||
_container.Register<View3DViewModel>();
|
||||
_container.Register<ModifyTaskViewModel>();
|
||||
_container.Register<CalibrationViewModel>();
|
||||
_container.Register<LoginViewModel>();
|
||||
_container.Register<ChangePasswordViewModel>();
|
||||
_container.Register<GroupsViewModel>();
|
||||
_container.Register<RtcmInfoViewModel>();
|
||||
_container.Register<ConfigVirtualIdViewModel>();
|
||||
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 238 KiB |
72
Plane.FormationCreator/Util/AsynDataUtils.cs
Normal file
@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace Plane.Util
|
||||
{
|
||||
public class AsynDataUtils
|
||||
{
|
||||
public delegate void DataResultCallBack(string data,bool haveerror);
|
||||
DataResultCallBack _callback;
|
||||
bool haveerror;
|
||||
string errorstr;
|
||||
public bool AsynGetData(string tagUrl, DataResultCallBack callback, out string verrorstr)
|
||||
{
|
||||
haveerror = false;
|
||||
errorstr = "";
|
||||
try
|
||||
{
|
||||
_callback = callback;
|
||||
AsyncGetWithWebRequest(tagUrl, new AsyncCallback(ReadCallback));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorstr += ex.Message;
|
||||
haveerror = true;
|
||||
Console.WriteLine(ex.Message);
|
||||
|
||||
}
|
||||
verrorstr = errorstr;
|
||||
return !haveerror;
|
||||
}
|
||||
|
||||
private void ReadCallback(IAsyncResult asynchronousResult)
|
||||
{
|
||||
try
|
||||
{
|
||||
string DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
|
||||
var request = (HttpWebRequest)asynchronousResult.AsyncState;
|
||||
request.Timeout = 5000;
|
||||
request.Method = "GET";
|
||||
request.UserAgent = DefaultUserAgent;
|
||||
|
||||
var response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
|
||||
using (var streamReader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default ))
|
||||
{
|
||||
var resultString = streamReader.ReadToEnd();
|
||||
Console.WriteLine(resultString);
|
||||
if (_callback != null)
|
||||
{
|
||||
_callback(resultString,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (_callback != null)
|
||||
{
|
||||
_callback(ex.Message, true);
|
||||
}
|
||||
Console.WriteLine(ex.Message);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
private void AsyncGetWithWebRequest(string url, AsyncCallback callback)
|
||||
{
|
||||
var request = (HttpWebRequest)System.Net.WebRequest.Create(new Uri(url));
|
||||
request.BeginGetResponse(callback, request);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,431 +1,430 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
using System.Net; // dns, ip address
|
||||
using System.Net.Sockets; // tcplistner
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Plane.Util
|
||||
{
|
||||
public class CommsNTRIP : ICommsSerial, IDisposable
|
||||
{
|
||||
public TcpClient client = new TcpClient();
|
||||
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
|
||||
private Uri remoteUri;
|
||||
|
||||
public double lat = 0;
|
||||
public double lng = 0;
|
||||
public double alt = 0;
|
||||
|
||||
int retrys = 3;
|
||||
|
||||
private string host;
|
||||
|
||||
public int WriteBufferSize { get; set; }
|
||||
public int WriteTimeout { get; set; }
|
||||
public bool RtsEnable { get; set; }
|
||||
private string url;
|
||||
|
||||
public Stream BaseStream
|
||||
{
|
||||
get { return client.GetStream(); }
|
||||
}
|
||||
|
||||
public CommsNTRIP(string url, double lat, double lng)
|
||||
{
|
||||
this.url = url;
|
||||
this.lat = lat;
|
||||
this.lng = lng;
|
||||
ReadTimeout = 500;
|
||||
}
|
||||
|
||||
public void toggleDTR()
|
||||
{
|
||||
}
|
||||
|
||||
public string Port { get; set; }
|
||||
|
||||
public int ReadTimeout
|
||||
{
|
||||
get; // { return client.ReceiveTimeout; }
|
||||
set; // { client.ReceiveTimeout = value; }
|
||||
}
|
||||
|
||||
public int ReadBufferSize { get; set; }
|
||||
|
||||
public int BaudRate { get; set; }
|
||||
public StopBits StopBits { get; set; }
|
||||
public Parity Parity { get; set; }
|
||||
public int DataBits { get; set; }
|
||||
|
||||
public string PortName { get; set; }
|
||||
|
||||
public int BytesToRead
|
||||
{
|
||||
get
|
||||
{
|
||||
/*Console.WriteLine(DateTime.Now.Millisecond + " tcp btr " + (client.Available + rbuffer.Length - rbufferread));*/
|
||||
SendNMEA();
|
||||
return (int)client.Available;
|
||||
}
|
||||
}
|
||||
|
||||
public int BytesToWrite
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
public bool IsOpen
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return client.Client.Connected;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool DtrEnable { get; set; }
|
||||
|
||||
public void Open()
|
||||
{
|
||||
if (client.Client.Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*string url = "";*/
|
||||
|
||||
|
||||
int count = url.Split('@').Length - 1;
|
||||
|
||||
if (count > 1)
|
||||
{
|
||||
var regex = new Regex("@");
|
||||
url = regex.Replace(url, "%40", 1);
|
||||
}
|
||||
|
||||
url = url.Replace("ntrip://", "http://");
|
||||
|
||||
remoteUri = new Uri(url);
|
||||
|
||||
doConnect();
|
||||
}
|
||||
|
||||
private byte[] TcpKeepAlive(bool On_Off, uint KeepaLiveTime, uint KeepaLiveInterval)
|
||||
{
|
||||
byte[] InValue = new byte[12];
|
||||
|
||||
Array.ConstrainedCopy(BitConverter.GetBytes(Convert.ToUInt32(On_Off)), 0, InValue, 0, 4);
|
||||
Array.ConstrainedCopy(BitConverter.GetBytes(KeepaLiveTime), 0, InValue, 4, 4);
|
||||
Array.ConstrainedCopy(BitConverter.GetBytes(KeepaLiveInterval), 0, InValue, 8, 4);
|
||||
|
||||
return InValue;
|
||||
}
|
||||
|
||||
private void doConnect()
|
||||
{
|
||||
string usernamePassword = remoteUri.UserInfo;
|
||||
string userpass2 = Uri.UnescapeDataString(usernamePassword);
|
||||
string auth = "Authorization: Basic " +
|
||||
Convert.ToBase64String(new ASCIIEncoding().GetBytes(userpass2)) + "\r\n";
|
||||
|
||||
if (usernamePassword == "")
|
||||
auth = "";
|
||||
|
||||
host = remoteUri.Host;
|
||||
Port = remoteUri.Port.ToString();
|
||||
|
||||
client = new TcpClient(host, int.Parse(Port));
|
||||
client.Client.IOControl(IOControlCode.KeepAliveValues, TcpKeepAlive(true, 36000000, 3000), null);
|
||||
|
||||
NetworkStream ns = client.GetStream();
|
||||
|
||||
StreamWriter sw = new StreamWriter(ns);
|
||||
StreamReader sr = new StreamReader(ns);
|
||||
|
||||
string line = "GET " + remoteUri.PathAndQuery + " HTTP/1.0\r\n"
|
||||
+ "User-Agent: NTRIP MissionPlanner/1.0\r\n"
|
||||
+ auth
|
||||
+ "Connection: close\r\n\r\n";
|
||||
|
||||
sw.Write(line);
|
||||
|
||||
sw.Flush();
|
||||
|
||||
line = sr.ReadLine();
|
||||
|
||||
if (!line.Contains("200"))
|
||||
{
|
||||
client.Dispose();
|
||||
|
||||
client = new TcpClient();
|
||||
|
||||
throw new Exception("Bad ntrip Responce\n\n" + line);
|
||||
}
|
||||
|
||||
// vrs may take up to 60+ seconds to respond
|
||||
SendNMEA();
|
||||
|
||||
VerifyConnected();
|
||||
}
|
||||
|
||||
DateTime _lastnmea = DateTime.MinValue;
|
||||
|
||||
private void SendNMEA()
|
||||
{
|
||||
if (lat != 0 || lng != 0)
|
||||
{
|
||||
if (_lastnmea.AddSeconds(30) < DateTime.Now)
|
||||
{
|
||||
double latdms = (int)lat + ((lat - (int)lat) * .6f);
|
||||
double lngdms = (int)lng + ((lng - (int)lng) * .6f);
|
||||
|
||||
var line = string.Format(System.Globalization.CultureInfo.InvariantCulture,
|
||||
"$GP{0},{1:HHmmss.ff},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14}", "GGA",
|
||||
DateTime.Now.ToUniversalTime(), Math.Abs(latdms * 100).ToString("0000.00"), lat < 0 ? "S" : "N",
|
||||
Math.Abs(lngdms * 100).ToString("00000.00"), lng < 0 ? "W" : "E", 1, 10,
|
||||
1, alt.ToString("0.00"), "M", 0, "M", "0.0", "0");
|
||||
|
||||
string checksum = GetChecksum(line);
|
||||
WriteLine(line + "*" + checksum);
|
||||
|
||||
|
||||
_lastnmea = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Calculates the checksum for a sentence
|
||||
string GetChecksum(string sentence)
|
||||
{
|
||||
// Loop through all chars to get a checksum
|
||||
int Checksum = 0;
|
||||
foreach (char Character in sentence.ToCharArray())
|
||||
{
|
||||
switch (Character)
|
||||
{
|
||||
case '$':
|
||||
// Ignore the dollar sign
|
||||
break;
|
||||
case '*':
|
||||
// Stop processing before the asterisk
|
||||
continue;
|
||||
default:
|
||||
// Is this the first value for the checksum?
|
||||
if (Checksum == 0)
|
||||
{
|
||||
// Yes. Set the checksum to the value
|
||||
Checksum = Convert.ToByte(Character);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No. XOR the checksum with this character's value
|
||||
Checksum = Checksum ^ Convert.ToByte(Character);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Return the checksum formatted as a two-character hexadecimal
|
||||
return Checksum.ToString("X2");
|
||||
}
|
||||
|
||||
void VerifyConnected()
|
||||
{
|
||||
if (!IsOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
client.Dispose();
|
||||
client = new TcpClient();
|
||||
}
|
||||
catch { }
|
||||
|
||||
// this should only happen if we have established a connection in the first place
|
||||
if (client != null && retrys > 0)
|
||||
{
|
||||
doConnect();
|
||||
retrys--;
|
||||
}
|
||||
|
||||
throw new Exception("The ntrip is closed");
|
||||
}
|
||||
}
|
||||
|
||||
public int Read(byte[] readto, int offset, int length)
|
||||
{
|
||||
VerifyConnected();
|
||||
|
||||
SendNMEA();
|
||||
|
||||
try
|
||||
{
|
||||
if (length < 1) { return 0; }
|
||||
|
||||
return client.Client.Receive(readto, offset, length, SocketFlags.Partial);
|
||||
/*
|
||||
byte[] temp = new byte[length];
|
||||
clientbuf.Read(temp, 0, length);
|
||||
|
||||
temp.CopyTo(readto, offset);
|
||||
|
||||
return length;*/
|
||||
}
|
||||
catch { throw new Exception("ntrip Socket Closed"); }
|
||||
}
|
||||
|
||||
public int ReadByte()
|
||||
{
|
||||
VerifyConnected();
|
||||
int count = 0;
|
||||
while (this.BytesToRead == 0)
|
||||
{
|
||||
System.Threading.Thread.Sleep(1);
|
||||
if (count > ReadTimeout)
|
||||
throw new Exception("ntrip Timeout on read");
|
||||
count++;
|
||||
}
|
||||
byte[] buffer = new byte[1];
|
||||
Read(buffer, 0, 1);
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
public int ReadChar()
|
||||
{
|
||||
return ReadByte();
|
||||
}
|
||||
|
||||
public string ReadExisting()
|
||||
{
|
||||
VerifyConnected();
|
||||
byte[] data = new byte[client.Available];
|
||||
if (data.Length > 0)
|
||||
Read(data, 0, data.Length);
|
||||
|
||||
string line = Encoding.ASCII.GetString(data, 0, data.Length);
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
public void WriteLine(string line)
|
||||
{
|
||||
VerifyConnected();
|
||||
line = line + "\r\n";
|
||||
Write(line);
|
||||
}
|
||||
|
||||
public void Write(string line)
|
||||
{
|
||||
VerifyConnected();
|
||||
byte[] data = new System.Text.ASCIIEncoding().GetBytes(line);
|
||||
Write(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public void Write(byte[] write, int offset, int length)
|
||||
{
|
||||
VerifyConnected();
|
||||
try
|
||||
{
|
||||
client.Client.Send(write, length, SocketFlags.None);
|
||||
}
|
||||
catch { }//throw new Exception("Comport / Socket Closed"); }
|
||||
}
|
||||
|
||||
public void DiscardInBuffer()
|
||||
{
|
||||
VerifyConnected();
|
||||
int size = (int)client.Available;
|
||||
byte[] crap = new byte[size];
|
||||
Read(crap, 0, size);
|
||||
}
|
||||
|
||||
public string ReadLine()
|
||||
{
|
||||
byte[] temp = new byte[4000];
|
||||
int count = 0;
|
||||
int timeout = 0;
|
||||
|
||||
while (timeout <= 100)
|
||||
{
|
||||
if (!this.IsOpen) { break; }
|
||||
if (this.BytesToRead > 0)
|
||||
{
|
||||
byte letter = (byte)this.ReadByte();
|
||||
|
||||
temp[count] = letter;
|
||||
|
||||
if (letter == '\n') // normal line
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
count++;
|
||||
if (count == temp.Length)
|
||||
break;
|
||||
timeout = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout++;
|
||||
System.Threading.Thread.Sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
Array.Resize<byte>(ref temp, count + 1);
|
||||
|
||||
return Encoding.ASCII.GetString(temp, 0, temp.Length);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (client.Client != null && client.Client.Connected)
|
||||
{
|
||||
client.Client.Dispose();
|
||||
client.Dispose();
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
client.Dispose();
|
||||
}
|
||||
catch { }
|
||||
|
||||
client = new TcpClient();
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// dispose managed resources
|
||||
this.Close();
|
||||
client = null;
|
||||
}
|
||||
// free native resources
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
using System.Net; // dns, ip address
|
||||
using System.Net.Sockets; // tcplistner
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Plane.Util
|
||||
{
|
||||
public class CommsNTRIP : ICommsSerial, IDisposable
|
||||
{
|
||||
public TcpClient client = new TcpClient();
|
||||
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
|
||||
private Uri remoteUri;
|
||||
|
||||
public double lat = 0;
|
||||
public double lng = 0;
|
||||
public double alt = 0;
|
||||
|
||||
int retrys = 3;
|
||||
|
||||
private string host;
|
||||
|
||||
public int WriteBufferSize { get; set; }
|
||||
public int WriteTimeout { get; set; }
|
||||
public bool RtsEnable { get; set; }
|
||||
private string url;
|
||||
|
||||
public Stream BaseStream
|
||||
{
|
||||
get { return client.GetStream(); }
|
||||
}
|
||||
|
||||
public CommsNTRIP(string url, double lat, double lng)
|
||||
{
|
||||
this.url = url;
|
||||
this.lat = lat;
|
||||
this.lng = lng;
|
||||
ReadTimeout = 500;
|
||||
}
|
||||
|
||||
public void toggleDTR()
|
||||
{
|
||||
}
|
||||
|
||||
public string Port { get; set; }
|
||||
|
||||
public int ReadTimeout
|
||||
{
|
||||
get; // { return client.ReceiveTimeout; }
|
||||
set; // { client.ReceiveTimeout = value; }
|
||||
}
|
||||
|
||||
public int ReadBufferSize { get; set; }
|
||||
|
||||
public int BaudRate { get; set; }
|
||||
public StopBits StopBits { get; set; }
|
||||
public Parity Parity { get; set; }
|
||||
public int DataBits { get; set; }
|
||||
|
||||
public string PortName { get; set; }
|
||||
|
||||
public int BytesToRead
|
||||
{
|
||||
get
|
||||
{
|
||||
/*Console.WriteLine(DateTime.Now.Millisecond + " tcp btr " + (client.Available + rbuffer.Length - rbufferread));*/
|
||||
SendNMEA();
|
||||
return (int)client.Available;
|
||||
}
|
||||
}
|
||||
|
||||
public int BytesToWrite
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
public bool IsOpen
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return client.Client.Connected;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool DtrEnable { get; set; }
|
||||
|
||||
public void Open()
|
||||
{
|
||||
if (client.Client.Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*string url = "";*/
|
||||
|
||||
|
||||
int count = url.Split('@').Length - 1;
|
||||
|
||||
if (count > 1)
|
||||
{
|
||||
var regex = new Regex("@");
|
||||
url = regex.Replace(url, "%40", 1);
|
||||
}
|
||||
|
||||
url = url.Replace("ntrip://", "http://");
|
||||
|
||||
remoteUri = new Uri(url);
|
||||
|
||||
doConnect();
|
||||
}
|
||||
|
||||
private byte[] TcpKeepAlive(bool On_Off, uint KeepaLiveTime, uint KeepaLiveInterval)
|
||||
{
|
||||
byte[] InValue = new byte[12];
|
||||
|
||||
Array.ConstrainedCopy(BitConverter.GetBytes(Convert.ToUInt32(On_Off)), 0, InValue, 0, 4);
|
||||
Array.ConstrainedCopy(BitConverter.GetBytes(KeepaLiveTime), 0, InValue, 4, 4);
|
||||
Array.ConstrainedCopy(BitConverter.GetBytes(KeepaLiveInterval), 0, InValue, 8, 4);
|
||||
|
||||
return InValue;
|
||||
}
|
||||
|
||||
private void doConnect()
|
||||
{
|
||||
string usernamePassword = remoteUri.UserInfo;
|
||||
string userpass2 = Uri.UnescapeDataString(usernamePassword);
|
||||
string auth = "Authorization: Basic " +
|
||||
Convert.ToBase64String(new ASCIIEncoding().GetBytes(userpass2)) + "\r\n";
|
||||
|
||||
if (usernamePassword == "")
|
||||
auth = "";
|
||||
|
||||
host = remoteUri.Host;
|
||||
Port = remoteUri.Port.ToString();
|
||||
|
||||
client = new TcpClient(host, int.Parse(Port));
|
||||
client.Client.IOControl(IOControlCode.KeepAliveValues, TcpKeepAlive(true, 36000000, 3000), null);
|
||||
|
||||
NetworkStream ns = client.GetStream();
|
||||
|
||||
StreamWriter sw = new StreamWriter(ns);
|
||||
StreamReader sr = new StreamReader(ns);
|
||||
|
||||
string line = "GET " + remoteUri.PathAndQuery + " HTTP/1.0\r\n"
|
||||
+ "User-Agent: NTRIP MissionPlanner/1.0\r\n"
|
||||
+ auth
|
||||
+ "Connection: close\r\n\r\n";
|
||||
|
||||
sw.Write(line);
|
||||
|
||||
sw.Flush();
|
||||
|
||||
line = sr.ReadLine();
|
||||
|
||||
if (!line.Contains("200"))
|
||||
{
|
||||
client.Dispose();
|
||||
|
||||
client = new TcpClient();
|
||||
|
||||
throw new Exception("Bad ntrip Responce\n\n" + line);
|
||||
}
|
||||
|
||||
// vrs may take up to 60+ seconds to respond
|
||||
SendNMEA();
|
||||
|
||||
VerifyConnected();
|
||||
}
|
||||
|
||||
DateTime _lastnmea = DateTime.MinValue;
|
||||
|
||||
private void SendNMEA()
|
||||
{
|
||||
if (lat != 0 || lng != 0)
|
||||
{
|
||||
DateTime currentUtcTime = DateTime.UtcNow;
|
||||
if (_lastnmea.AddSeconds(30) < currentUtcTime)
|
||||
{
|
||||
double latdms = (int)lat + ((lat - (int)lat) * .6f);
|
||||
double lngdms = (int)lng + ((lng - (int)lng) * .6f);
|
||||
|
||||
var line = string.Format(System.Globalization.CultureInfo.InvariantCulture,
|
||||
"$GP{0},{1:HHmmss.ff},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14}", "GGA",
|
||||
currentUtcTime, Math.Abs(latdms * 100).ToString("0000.00"), lat < 0 ? "S" : "N",
|
||||
Math.Abs(lngdms * 100).ToString("00000.00"), lng < 0 ? "W" : "E", 1, 10,
|
||||
1, alt.ToString("0.00"), "M", 0, "M", "0.0", "0");
|
||||
|
||||
string checksum = GetChecksum(line);
|
||||
WriteLine(line + "*" + checksum);
|
||||
_lastnmea = currentUtcTime;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Calculates the checksum for a sentence
|
||||
string GetChecksum(string sentence)
|
||||
{
|
||||
// Loop through all chars to get a checksum
|
||||
int Checksum = 0;
|
||||
foreach (char Character in sentence.ToCharArray())
|
||||
{
|
||||
switch (Character)
|
||||
{
|
||||
case '$':
|
||||
// Ignore the dollar sign
|
||||
break;
|
||||
case '*':
|
||||
// Stop processing before the asterisk
|
||||
continue;
|
||||
default:
|
||||
// Is this the first value for the checksum?
|
||||
if (Checksum == 0)
|
||||
{
|
||||
// Yes. Set the checksum to the value
|
||||
Checksum = Convert.ToByte(Character);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No. XOR the checksum with this character's value
|
||||
Checksum = Checksum ^ Convert.ToByte(Character);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Return the checksum formatted as a two-character hexadecimal
|
||||
return Checksum.ToString("X2");
|
||||
}
|
||||
|
||||
void VerifyConnected()
|
||||
{
|
||||
if (!IsOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
client.Dispose();
|
||||
client = new TcpClient();
|
||||
}
|
||||
catch { }
|
||||
|
||||
// this should only happen if we have established a connection in the first place
|
||||
if (client != null && retrys > 0)
|
||||
{
|
||||
doConnect();
|
||||
retrys--;
|
||||
}
|
||||
|
||||
throw new Exception("网络RTK基站通讯已关闭!");
|
||||
}
|
||||
}
|
||||
|
||||
public int Read(byte[] readto, int offset, int length)
|
||||
{
|
||||
VerifyConnected();
|
||||
|
||||
SendNMEA();
|
||||
|
||||
try
|
||||
{
|
||||
if (length < 1) { return 0; }
|
||||
|
||||
return client.Client.Receive(readto, offset, length, SocketFlags.Partial);
|
||||
/*
|
||||
byte[] temp = new byte[length];
|
||||
clientbuf.Read(temp, 0, length);
|
||||
|
||||
temp.CopyTo(readto, offset);
|
||||
|
||||
return length;*/
|
||||
}
|
||||
catch { throw new Exception("ntrip Socket Closed"); }
|
||||
}
|
||||
|
||||
public int ReadByte()
|
||||
{
|
||||
VerifyConnected();
|
||||
int count = 0;
|
||||
while (this.BytesToRead == 0)
|
||||
{
|
||||
System.Threading.Thread.Sleep(1);
|
||||
if (count > ReadTimeout)
|
||||
throw new Exception("ntrip Timeout on read");
|
||||
count++;
|
||||
}
|
||||
byte[] buffer = new byte[1];
|
||||
Read(buffer, 0, 1);
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
public int ReadChar()
|
||||
{
|
||||
return ReadByte();
|
||||
}
|
||||
|
||||
public string ReadExisting()
|
||||
{
|
||||
VerifyConnected();
|
||||
byte[] data = new byte[client.Available];
|
||||
if (data.Length > 0)
|
||||
Read(data, 0, data.Length);
|
||||
|
||||
string line = Encoding.ASCII.GetString(data, 0, data.Length);
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
public void WriteLine(string line)
|
||||
{
|
||||
VerifyConnected();
|
||||
line = line + "\r\n";
|
||||
Write(line);
|
||||
}
|
||||
|
||||
public void Write(string line)
|
||||
{
|
||||
VerifyConnected();
|
||||
byte[] data = new System.Text.ASCIIEncoding().GetBytes(line);
|
||||
Write(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public void Write(byte[] write, int offset, int length)
|
||||
{
|
||||
VerifyConnected();
|
||||
try
|
||||
{
|
||||
client.Client.Send(write, length, SocketFlags.None);
|
||||
}
|
||||
catch { }//throw new Exception("Comport / Socket Closed"); }
|
||||
}
|
||||
|
||||
public void DiscardInBuffer()
|
||||
{
|
||||
VerifyConnected();
|
||||
int size = (int)client.Available;
|
||||
byte[] crap = new byte[size];
|
||||
Read(crap, 0, size);
|
||||
}
|
||||
|
||||
public string ReadLine()
|
||||
{
|
||||
byte[] temp = new byte[4000];
|
||||
int count = 0;
|
||||
int timeout = 0;
|
||||
|
||||
while (timeout <= 100)
|
||||
{
|
||||
if (!this.IsOpen) { break; }
|
||||
if (this.BytesToRead > 0)
|
||||
{
|
||||
byte letter = (byte)this.ReadByte();
|
||||
|
||||
temp[count] = letter;
|
||||
|
||||
if (letter == '\n') // normal line
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
count++;
|
||||
if (count == temp.Length)
|
||||
break;
|
||||
timeout = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout++;
|
||||
System.Threading.Thread.Sleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
Array.Resize<byte>(ref temp, count + 1);
|
||||
|
||||
return Encoding.ASCII.GetString(temp, 0, temp.Length);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (client.Client != null && client.Client.Connected)
|
||||
{
|
||||
client.Client.Dispose();
|
||||
client.Dispose();
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
try
|
||||
{
|
||||
client.Dispose();
|
||||
}
|
||||
catch { }
|
||||
|
||||
client = new TcpClient();
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// dispose managed resources
|
||||
this.Close();
|
||||
client = null;
|
||||
}
|
||||
// free native resources
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
512
Plane.FormationCreator/Util/CommsSerialPort.cs
Normal file
@ -0,0 +1,512 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO.Ports;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System.Threading;
|
||||
|
||||
namespace Plane.Util
|
||||
{
|
||||
|
||||
public class SerialPort : System.IO.Ports.SerialPort, ICommsSerial
|
||||
{
|
||||
static object locker = new object();
|
||||
|
||||
public new bool DtrEnable { get { return base.DtrEnable; } set { if (base.DtrEnable == value) return; if (ispx4(base.PortName)) return; base.DtrEnable = value; } }
|
||||
public new bool RtsEnable { get { return base.RtsEnable; } set { if (base.RtsEnable == value) return; if (ispx4(base.PortName)) return; base.RtsEnable = value; } }
|
||||
/*
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
Type mytype = typeof(System.IO.Ports.SerialPort);
|
||||
FieldInfo field = mytype.GetField("internalSerialStream", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
if (field != null)
|
||||
{
|
||||
Stream stream = (Stream)field.GetValue(this);
|
||||
|
||||
if (stream != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
stream.Dispose();
|
||||
}
|
||||
catch (Exception ex) { Console.WriteLine("1 " + ex.ToString()); }
|
||||
stream = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { Console.WriteLine("2 " + ex.ToString()); }
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
catch (Exception ex) { Console.WriteLine("3 " + ex.ToString()); }
|
||||
}
|
||||
*/
|
||||
public new void Open()
|
||||
{
|
||||
// 500ms write timeout - win32 api default
|
||||
this.WriteTimeout = 500;
|
||||
|
||||
if (base.IsOpen)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
// this causes element not found with bluetooth devices.
|
||||
if (BaudRate > 115200)
|
||||
{
|
||||
Console.WriteLine("Doing SerialPortFixer");
|
||||
SerialPortFixer.Execute(this.PortName);
|
||||
Console.WriteLine("Done SerialPortFixer");
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
|
||||
|
||||
if (PortName.StartsWith("/"))
|
||||
if (!File.Exists(PortName))
|
||||
throw new Exception("No such device");
|
||||
|
||||
try
|
||||
{
|
||||
base.Open();
|
||||
}
|
||||
catch {
|
||||
try { Close(); }
|
||||
catch { }
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public new void Close()
|
||||
{
|
||||
base.Close();
|
||||
}
|
||||
|
||||
public void toggleDTR()
|
||||
{
|
||||
if (ispx4(this.PortName))
|
||||
{
|
||||
Console.WriteLine("PX4 - no DTR");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool open = this.IsOpen;
|
||||
Console.WriteLine("toggleDTR " + this.IsOpen);
|
||||
try
|
||||
{
|
||||
if (!open)
|
||||
this.Open();
|
||||
}
|
||||
catch { }
|
||||
|
||||
|
||||
base.DtrEnable = false;
|
||||
base.RtsEnable = false;
|
||||
|
||||
System.Threading.Thread.Sleep(50);
|
||||
|
||||
base.DtrEnable = true;
|
||||
base.RtsEnable = true;
|
||||
|
||||
System.Threading.Thread.Sleep(50);
|
||||
|
||||
try
|
||||
{
|
||||
if (!open)
|
||||
this.Close();
|
||||
}
|
||||
catch { }
|
||||
Console.WriteLine("toggleDTR done " + this.IsOpen);
|
||||
}
|
||||
|
||||
public new static string[] GetPortNames()
|
||||
{
|
||||
// prevent hammering
|
||||
lock (locker)
|
||||
{
|
||||
List<string> allPorts = new List<string>();
|
||||
|
||||
if (Directory.Exists("/dev/"))
|
||||
{
|
||||
// cleanup now
|
||||
GC.Collect();
|
||||
// mono is failing in here on linux "too many open files"
|
||||
try
|
||||
{
|
||||
if (Directory.Exists("/dev/serial/by-id/"))
|
||||
allPorts.AddRange(Directory.GetFiles("/dev/serial/by-id/", "*"));
|
||||
}
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
allPorts.AddRange(Directory.GetFiles("/dev/", "ttyACM*"));
|
||||
}
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
allPorts.AddRange(Directory.GetFiles("/dev/", "ttyUSB*"));
|
||||
}
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
allPorts.AddRange(Directory.GetFiles("/dev/", "rfcomm*"));
|
||||
}
|
||||
catch { }
|
||||
try
|
||||
{
|
||||
allPorts.AddRange(Directory.GetFiles("/dev/", "*usb*"));
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
string[] ports = null;
|
||||
|
||||
try
|
||||
{
|
||||
ports = System.IO.Ports.SerialPort.GetPortNames()
|
||||
.Select(p => p.TrimEnd())
|
||||
.Select(FixBlueToothPortNameBug)
|
||||
.ToArray();
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (ports != null)
|
||||
allPorts.AddRange(ports);
|
||||
|
||||
return allPorts.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
static Dictionary<string, string> comportnamecache = new Dictionary<string, string>();
|
||||
|
||||
public static string GetNiceName(string port)
|
||||
{
|
||||
// make sure we are exclusive
|
||||
lock (locker)
|
||||
{
|
||||
|
||||
portnamenice = "";
|
||||
|
||||
if (comportnamecache.ContainsKey(port))
|
||||
{
|
||||
return comportnamecache[port];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
CallWithTimeout(new Action<string>(GetName), 1000, port);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
comportnamecache[port] = portnamenice;
|
||||
|
||||
return (string)portnamenice.Clone();
|
||||
}
|
||||
}
|
||||
|
||||
static string portnamenice = "";
|
||||
|
||||
static void GetName(string port)
|
||||
{
|
||||
try
|
||||
{
|
||||
/*
|
||||
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_SerialPort"); // Win32_USBControllerDevice
|
||||
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
|
||||
{
|
||||
foreach (ManagementObject obj2 in searcher.Get())
|
||||
{
|
||||
//DeviceID
|
||||
if (obj2.Properties["DeviceID"].Value.ToString().ToUpper() == port.ToUpper())
|
||||
{
|
||||
portnamenice = obj2.Properties["Name"].Value.ToString();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
catch { }
|
||||
|
||||
portnamenice = "";
|
||||
}
|
||||
|
||||
static void CallWithTimeout(Action<string> action, int timeoutMilliseconds, string data)
|
||||
{
|
||||
Thread threadToKill = null;
|
||||
Action wrappedAction = () =>
|
||||
{
|
||||
threadToKill = Thread.CurrentThread;
|
||||
action(data);
|
||||
};
|
||||
|
||||
IAsyncResult result = wrappedAction.BeginInvoke(null, null);
|
||||
if (result.AsyncWaitHandle.WaitOne(timeoutMilliseconds))
|
||||
{
|
||||
wrappedAction.EndInvoke(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
threadToKill.Abort();
|
||||
throw new TimeoutException();
|
||||
}
|
||||
}
|
||||
|
||||
internal bool ispx4(string port)
|
||||
{
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// .NET bug: sometimes bluetooth ports are enumerated with bogus characters
|
||||
// eg 'COM10' becomes 'COM10c' - one workaround is to remove the non numeric
|
||||
// char. Annoyingly, sometimes a numeric char is added, which means this
|
||||
// does not work in all cases.
|
||||
// See http://connect.microsoft.com/VisualStudio/feedback/details/236183/system-io-ports-serialport-getportnames-error-with-bluetooth
|
||||
private static string FixBlueToothPortNameBug(string portName)
|
||||
{
|
||||
if (!portName.StartsWith("COM"))
|
||||
return portName;
|
||||
var newPortName = "COM"; // Start over with "COM"
|
||||
foreach (var portChar in portName.Substring(3).ToCharArray()) // Remove "COM", put the rest in a character array
|
||||
{
|
||||
if (char.IsDigit(portChar))
|
||||
newPortName += portChar.ToString(); // Good character, append to portName
|
||||
// else
|
||||
//log.WarnFormat("Bad (Non Numeric) character in port name '{0}' - removing", portName);
|
||||
}
|
||||
|
||||
return newPortName;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SerialPortFixer : IDisposable
|
||||
{
|
||||
|
||||
|
||||
public static void Execute(string portName)
|
||||
{
|
||||
using (new SerialPortFixer(portName))
|
||||
{
|
||||
}
|
||||
}
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (m_Handle != null)
|
||||
{
|
||||
m_Handle.Dispose();
|
||||
m_Handle = null;
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation
|
||||
|
||||
private const int DcbFlagAbortOnError = 14;
|
||||
private const int CommStateRetries = 10;
|
||||
private SafeFileHandle m_Handle;
|
||||
|
||||
private SerialPortFixer(string portName)
|
||||
{
|
||||
const int dwFlagsAndAttributes = 0x40000000;
|
||||
const int dwAccess = unchecked((int)0xC0000000); if ((portName == null) || !portName.StartsWith("COM", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new ArgumentException("Invalid Serial Port", "portName");
|
||||
}
|
||||
SafeFileHandle hFile = NativeMethods.CreateFile(@"\\.\" + portName, dwAccess, 0, IntPtr.Zero, 3, dwFlagsAndAttributes,
|
||||
IntPtr.Zero);
|
||||
if (hFile.IsInvalid)
|
||||
{
|
||||
WinIoError();
|
||||
}
|
||||
try
|
||||
{
|
||||
int fileType = NativeMethods.GetFileType(hFile);
|
||||
if ((fileType != 2) && (fileType != 0))
|
||||
{
|
||||
throw new ArgumentException("Invalid Serial Port", "portName");
|
||||
}
|
||||
m_Handle = hFile;
|
||||
InitializeDcb();
|
||||
}
|
||||
catch
|
||||
{
|
||||
hFile.Dispose();
|
||||
m_Handle = null;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static class NativeMethods
|
||||
{
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId,
|
||||
StringBuilder lpBuffer, int nSize, IntPtr arguments);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern bool GetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern bool SetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern bool ClearCommError(SafeFileHandle hFile, ref int lpErrors, ref Comstat lpStat);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode,
|
||||
IntPtr securityAttrs, int dwCreationDisposition,
|
||||
int dwFlagsAndAttributes, IntPtr hTemplateFile);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
internal static extern int GetFileType(SafeFileHandle hFile);
|
||||
|
||||
}
|
||||
|
||||
private void InitializeDcb()
|
||||
{
|
||||
Dcb dcb = new Dcb();
|
||||
GetCommStateNative(ref dcb);
|
||||
|
||||
dcb.Flags &= ~(1u << DcbFlagAbortOnError);
|
||||
|
||||
SetCommStateNative(ref dcb);
|
||||
}
|
||||
|
||||
private static string GetMessage(int errorCode)
|
||||
{
|
||||
StringBuilder lpBuffer = new StringBuilder(0x200);
|
||||
if (
|
||||
NativeMethods.FormatMessage(0x3200, new HandleRef(null, IntPtr.Zero), errorCode, 0, lpBuffer, lpBuffer.Capacity,
|
||||
IntPtr.Zero) != 0)
|
||||
{
|
||||
return lpBuffer.ToString();
|
||||
}
|
||||
return "Unknown Error";
|
||||
}
|
||||
|
||||
private static int MakeHrFromErrorCode(int errorCode)
|
||||
{
|
||||
return (int)(0x80070000 | (uint)errorCode);
|
||||
}
|
||||
|
||||
private static void WinIoError()
|
||||
{
|
||||
int errorCode = Marshal.GetLastWin32Error();
|
||||
throw new IOException(GetMessage(errorCode), MakeHrFromErrorCode(errorCode));
|
||||
}
|
||||
|
||||
private void GetCommStateNative(ref Dcb lpDcb)
|
||||
{
|
||||
int commErrors = 0;
|
||||
Comstat comStat = new Comstat();
|
||||
|
||||
for (int i = 0; i < CommStateRetries; i++)
|
||||
{
|
||||
if (!NativeMethods.ClearCommError(m_Handle, ref commErrors, ref comStat))
|
||||
{
|
||||
WinIoError();
|
||||
}
|
||||
if (NativeMethods.GetCommState(m_Handle, ref lpDcb))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (i == CommStateRetries - 1)
|
||||
{
|
||||
WinIoError();
|
||||
}
|
||||
}
|
||||
}
|
||||
private void SetCommStateNative(ref Dcb lpDcb)
|
||||
{
|
||||
int commErrors = 0;
|
||||
Comstat comStat = new Comstat(); for (int i = 0; i < CommStateRetries; i++)
|
||||
{
|
||||
if (!NativeMethods.ClearCommError(m_Handle, ref commErrors, ref comStat))
|
||||
{
|
||||
WinIoError();
|
||||
}
|
||||
if (NativeMethods.SetCommState(m_Handle, ref lpDcb))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (i == CommStateRetries - 1)
|
||||
{
|
||||
WinIoError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Nested type: COMSTAT
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct Comstat
|
||||
{
|
||||
public readonly uint Flags;
|
||||
public readonly uint cbInQue;
|
||||
public readonly uint cbOutQue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Nested type: DCB
|
||||
|
||||
/*
|
||||
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa363214(v=vs.85).aspx
|
||||
DWORD fBinary :1;
|
||||
DWORD fParity :1;
|
||||
DWORD fOutxCtsFlow :1;
|
||||
DWORD fOutxDsrFlow :1;
|
||||
DWORD fDtrControl :2;
|
||||
DWORD fDsrSensitivity :1;
|
||||
DWORD fTXContinueOnXoff :1;
|
||||
DWORD fOutX :1;
|
||||
DWORD fInX :1;
|
||||
DWORD fErrorChar :1;
|
||||
DWORD fNull :1;
|
||||
DWORD fRtsControl :2;
|
||||
DWORD fAbortOnError :1;
|
||||
DWORD fDummy2 :17;
|
||||
*/
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Dcb
|
||||
{
|
||||
public readonly uint DCBlength;
|
||||
public readonly uint BaudRate;
|
||||
public uint Flags;
|
||||
public readonly ushort wReserved;
|
||||
public readonly ushort XonLim;
|
||||
public readonly ushort XoffLim;
|
||||
public readonly byte ByteSize;
|
||||
public readonly byte Parity;
|
||||
public readonly byte StopBits;
|
||||
public readonly byte XonChar;
|
||||
public readonly byte XoffChar;
|
||||
public readonly byte ErrorChar;
|
||||
public readonly byte EofChar;
|
||||
public readonly byte EvtChar;
|
||||
public readonly ushort wReserved1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
86
Plane.FormationCreator/Util/PasswordBoxHelper.cs
Normal file
@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
|
||||
namespace Plane.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// 为PasswordBox控件的Password增加绑定功能
|
||||
/// </summary>
|
||||
public static class PasswordBoxHelper
|
||||
{
|
||||
public static readonly DependencyProperty PasswordProperty =
|
||||
DependencyProperty.RegisterAttached("Password",
|
||||
typeof(string), typeof(PasswordBoxHelper),
|
||||
new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged));
|
||||
public static readonly DependencyProperty AttachProperty =
|
||||
DependencyProperty.RegisterAttached("Attach",
|
||||
typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false, Attach));
|
||||
private static readonly DependencyProperty IsUpdatingProperty =
|
||||
DependencyProperty.RegisterAttached("IsUpdating", typeof(bool),
|
||||
typeof(PasswordBoxHelper));
|
||||
|
||||
|
||||
public static void SetAttach(DependencyObject dp, bool value)
|
||||
{
|
||||
dp.SetValue(AttachProperty, value);
|
||||
}
|
||||
public static bool GetAttach(DependencyObject dp)
|
||||
{
|
||||
return (bool)dp.GetValue(AttachProperty);
|
||||
}
|
||||
public static string GetPassword(DependencyObject dp)
|
||||
{
|
||||
return (string)dp.GetValue(PasswordProperty);
|
||||
}
|
||||
public static void SetPassword(DependencyObject dp, string value)
|
||||
{
|
||||
dp.SetValue(PasswordProperty, value);
|
||||
}
|
||||
private static bool GetIsUpdating(DependencyObject dp)
|
||||
{
|
||||
return (bool)dp.GetValue(IsUpdatingProperty);
|
||||
}
|
||||
private static void SetIsUpdating(DependencyObject dp, bool value)
|
||||
{
|
||||
dp.SetValue(IsUpdatingProperty, value);
|
||||
}
|
||||
private static void OnPasswordPropertyChanged(DependencyObject sender,
|
||||
DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
PasswordBox passwordBox = sender as PasswordBox;
|
||||
passwordBox.PasswordChanged -= PasswordChanged;
|
||||
if (!(bool)GetIsUpdating(passwordBox))
|
||||
{
|
||||
passwordBox.Password = (string)e.NewValue;
|
||||
}
|
||||
passwordBox.PasswordChanged += PasswordChanged;
|
||||
}
|
||||
private static void Attach(DependencyObject sender,
|
||||
DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
PasswordBox passwordBox = sender as PasswordBox;
|
||||
if (passwordBox == null)
|
||||
return;
|
||||
if ((bool)e.OldValue)
|
||||
{
|
||||
passwordBox.PasswordChanged -= PasswordChanged;
|
||||
}
|
||||
if ((bool)e.NewValue)
|
||||
{
|
||||
passwordBox.PasswordChanged += PasswordChanged;
|
||||
}
|
||||
}
|
||||
private static void PasswordChanged(object sender, RoutedEventArgs e)
|
||||
{
|
||||
PasswordBox passwordBox = sender as PasswordBox;
|
||||
SetIsUpdating(passwordBox, true);
|
||||
SetPassword(passwordBox, passwordBox.Password);
|
||||
SetIsUpdating(passwordBox, false);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
using Plane.Windows.IniHelper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -9,6 +11,7 @@ namespace Plane.FormationCreator.Util
|
||||
{
|
||||
public static class VersionControl
|
||||
{
|
||||
private static string DefaultServrURL= "http://111.229.174.37:81/login/";
|
||||
public static int Version = 0;
|
||||
/// <summary>
|
||||
/// 是否是完整版本 仅在Version = 255时为完整版本
|
||||
@ -20,13 +23,34 @@ namespace Plane.FormationCreator.Util
|
||||
/// </summary>
|
||||
public static int CopterUpperLimit = 50;
|
||||
|
||||
public static void GetVersionFromIni()
|
||||
public static string Username = "";
|
||||
public static string Password = "";
|
||||
public static bool IssavePassword = false;
|
||||
|
||||
public static string ServerURL = "";
|
||||
|
||||
public static int ConType = 0; //通讯模块
|
||||
|
||||
public static void SetUserLever(int vuserlever)
|
||||
{
|
||||
if (vuserlever==0)
|
||||
//管理员
|
||||
IsFullVersion = true;
|
||||
else
|
||||
IsFullVersion = false;
|
||||
}
|
||||
|
||||
|
||||
public static void GetSettingFromIni()
|
||||
{
|
||||
IniFiles iniFiles = new IniFiles();
|
||||
|
||||
int intTemp;
|
||||
bool boolTemp;
|
||||
string readvalue;
|
||||
|
||||
//完整版本和更多飞机数量通过网络授权或者超级用户得到
|
||||
|
||||
/*
|
||||
readvalue = iniFiles.IniReadvalue("Version", "Version");
|
||||
if (readvalue != "" && int.TryParse(readvalue, out intTemp))
|
||||
Version = int.Parse(readvalue);
|
||||
@ -35,6 +59,108 @@ namespace Plane.FormationCreator.Util
|
||||
readvalue = iniFiles.IniReadvalue("Version", "CopterUpperLimit");
|
||||
if (readvalue != "" && int.TryParse(readvalue, out intTemp))
|
||||
CopterUpperLimit = int.Parse(readvalue);
|
||||
*/
|
||||
|
||||
readvalue = iniFiles.IniReadvalue("Login", "Username");
|
||||
if (readvalue != "")
|
||||
Username = readvalue;
|
||||
|
||||
readvalue = Decrypt(iniFiles.IniReadvalue("Login", "Password"));
|
||||
if (readvalue != "")
|
||||
Password = readvalue;
|
||||
|
||||
|
||||
readvalue = iniFiles.IniReadvalue("Login", "issavePassword");
|
||||
if (readvalue != "" && bool.TryParse(readvalue, out boolTemp))
|
||||
IssavePassword = bool.Parse(readvalue);
|
||||
|
||||
readvalue = iniFiles.IniReadvalue("Default", "Server");
|
||||
if (readvalue != "")
|
||||
ServerURL = readvalue;
|
||||
else
|
||||
ServerURL = DefaultServrURL;
|
||||
|
||||
readvalue = iniFiles.IniReadvalue("Default", "ConType");
|
||||
if (readvalue != "")
|
||||
ConType = int.Parse(readvalue);
|
||||
else
|
||||
ConType = 0;
|
||||
}
|
||||
|
||||
public static void SaveLogininfoToIni(string username,string password,bool issavepassword)
|
||||
{
|
||||
Username = username;
|
||||
Password = password;
|
||||
IssavePassword = issavepassword;
|
||||
IniFiles iniFiles = new IniFiles();
|
||||
iniFiles.IniWritevalue("Login", "Username", username);
|
||||
if (issavepassword)
|
||||
iniFiles.IniWritevalue("Login", "Password", Encrypt(password));
|
||||
else
|
||||
iniFiles.IniWritevalue("Login", "Password", "");
|
||||
|
||||
iniFiles.IniWritevalue("Login", "issavepassword", issavepassword.ToString());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
static string encryptKey = "fxmf";//字符串加密密钥(注意:密钥只能是4位)
|
||||
|
||||
private static string Encrypt(string str)
|
||||
{//加密字符串
|
||||
|
||||
try
|
||||
{
|
||||
byte[] key = Encoding.Unicode.GetBytes(encryptKey);//密钥
|
||||
byte[] data = Encoding.Unicode.GetBytes(str);//待加密字符串
|
||||
|
||||
DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();//加密、解密对象
|
||||
MemoryStream MStream = new MemoryStream();//内存流对象
|
||||
|
||||
//用内存流实例化加密流对象
|
||||
CryptoStream CStream = new CryptoStream(MStream, descsp.CreateEncryptor(key, key), CryptoStreamMode.Write);
|
||||
CStream.Write(data, 0, data.Length);//向加密流中写入数据
|
||||
CStream.FlushFinalBlock();//将数据压入基础流
|
||||
byte[] temp = MStream.ToArray();//从内存流中获取字节序列
|
||||
CStream.Close();//关闭加密流
|
||||
MStream.Close();//关闭内存流
|
||||
|
||||
return Convert.ToBase64String(temp);//返回加密后的字符串
|
||||
}
|
||||
catch
|
||||
{
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static string Decrypt(string str)
|
||||
{//解密字符串
|
||||
|
||||
try
|
||||
{
|
||||
byte[] key = Encoding.Unicode.GetBytes(encryptKey);//密钥
|
||||
byte[] data = Convert.FromBase64String(str);//待解密字符串
|
||||
|
||||
DESCryptoServiceProvider descsp = new DESCryptoServiceProvider();//加密、解密对象
|
||||
MemoryStream MStream = new MemoryStream();//内存流对象
|
||||
|
||||
//用内存流实例化解密流对象
|
||||
CryptoStream CStream = new CryptoStream(MStream, descsp.CreateDecryptor(key, key), CryptoStreamMode.Write);
|
||||
CStream.Write(data, 0, data.Length);//向加密流中写入数据
|
||||
CStream.FlushFinalBlock();//将数据压入基础流
|
||||
byte[] temp = MStream.ToArray();//从内存流中获取字节序列
|
||||
CStream.Close();//关闭加密流
|
||||
MStream.Close();//关闭内存流
|
||||
|
||||
return Encoding.Unicode.GetString(temp);//返回解密后的字符串
|
||||
}
|
||||
catch
|
||||
{
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
123
Plane.FormationCreator/Util/nmea.cs
Normal file
@ -0,0 +1,123 @@
|
||||
using System;
|
||||
|
||||
using uint8_t = System.Byte;
|
||||
using uint16_t = System.UInt16;
|
||||
using int32_t = System.Int32;
|
||||
using uint32_t = System.UInt32;
|
||||
using int8_t = System.SByte;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Plane.Util
|
||||
{
|
||||
public class nmea : ICorrections
|
||||
{
|
||||
int step = 0;
|
||||
|
||||
public byte[] buffer = new byte[1024 * 1];
|
||||
int payloadlen = 0;
|
||||
int msglencount = 0;
|
||||
|
||||
public int length
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2 + 2 + 2 + 2 + payloadlen; // header2, class,subclass,length2,data,crc2
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] packet
|
||||
{
|
||||
get
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
public bool resetParser()
|
||||
{
|
||||
step = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
public int Read(byte data)
|
||||
{
|
||||
switch (step)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
if (data == '$')
|
||||
{
|
||||
step = 1;
|
||||
msglencount = 0;
|
||||
buffer[0] = data;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (data == 'G')
|
||||
{
|
||||
buffer[1] = data;
|
||||
step++;
|
||||
}
|
||||
else
|
||||
step = 0;
|
||||
break;
|
||||
case 2:
|
||||
if (msglencount > 1000)
|
||||
{
|
||||
step = 0;
|
||||
|
||||
}
|
||||
|
||||
buffer[msglencount + 2] = data;
|
||||
msglencount++;
|
||||
if(data == '\n')
|
||||
{
|
||||
var line = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, msglencount + 2);
|
||||
string[] items = line.Trim().Split(',', '*');
|
||||
if (items[items.Length-1] == GetChecksum(line))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
step = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Calculates the checksum for a sentence
|
||||
string GetChecksum(string sentence)
|
||||
{
|
||||
// Loop through all chars to get a checksum
|
||||
int Checksum = 0;
|
||||
foreach (char Character in sentence.ToCharArray())
|
||||
{
|
||||
switch (Character)
|
||||
{
|
||||
case '$':
|
||||
// Ignore the dollar sign
|
||||
break;
|
||||
case '*':
|
||||
// Stop processing before the asterisk
|
||||
return Checksum.ToString("X2");
|
||||
default:
|
||||
// Is this the first value for the checksum?
|
||||
if (Checksum == 0)
|
||||
{
|
||||
// Yes. Set the checksum to the value
|
||||
Checksum = Convert.ToByte(Character);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No. XOR the checksum with this character's value
|
||||
Checksum = Checksum ^ Convert.ToByte(Character);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Return the checksum formatted as a two-character hexadecimal
|
||||
return Checksum.ToString("X2");
|
||||
}
|
||||
}
|
||||
}
|
573
Plane.FormationCreator/Util/ubx_m8p.cs
Normal file
@ -0,0 +1,573 @@
|
||||
using System;
|
||||
|
||||
using uint8_t = System.Byte;
|
||||
using uint16_t = System.UInt16;
|
||||
using int32_t = System.Int32;
|
||||
using uint32_t = System.UInt32;
|
||||
using int8_t = System.SByte;
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace Plane.Util
|
||||
{
|
||||
public class Ubx : ICorrections
|
||||
{
|
||||
int step = 0;
|
||||
|
||||
public byte[] buffer = new byte[1024 * 8];
|
||||
int payloadlen = 0;
|
||||
int msglencount = 0;
|
||||
|
||||
public byte @class
|
||||
{
|
||||
get { return buffer[2]; }
|
||||
}
|
||||
|
||||
public byte subclass
|
||||
{
|
||||
get { return buffer[3]; }
|
||||
}
|
||||
|
||||
public int length
|
||||
{
|
||||
get
|
||||
{
|
||||
return 2 + 2 + 2 + 2 + payloadlen; // header2, class,subclass,length2,data,crc2
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] packet
|
||||
{
|
||||
get { return buffer; }
|
||||
}
|
||||
|
||||
public bool resetParser()
|
||||
{
|
||||
step = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
public int Read(byte data)
|
||||
{
|
||||
switch (step)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
if (data == 0xb5)
|
||||
{
|
||||
step = 1;
|
||||
buffer[0] = data;
|
||||
}
|
||||
|
||||
break;
|
||||
case 1:
|
||||
if (data == 0x62)
|
||||
{
|
||||
buffer[1] = data;
|
||||
step++;
|
||||
}
|
||||
else
|
||||
step = 0;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
buffer[2] = data;
|
||||
step++;
|
||||
break;
|
||||
case 3:
|
||||
buffer[3] = data;
|
||||
step++;
|
||||
break;
|
||||
case 4:
|
||||
buffer[4] = data;
|
||||
payloadlen = data;
|
||||
step++;
|
||||
break;
|
||||
case 5:
|
||||
buffer[5] = data;
|
||||
step++;
|
||||
payloadlen += (data << 8);
|
||||
msglencount = 0;
|
||||
// reset on oversize packet
|
||||
if (payloadlen > buffer.Length)
|
||||
step = 0;
|
||||
break;
|
||||
case 6:
|
||||
if (msglencount < (payloadlen))
|
||||
{
|
||||
buffer[msglencount + 6] = data;
|
||||
msglencount++;
|
||||
|
||||
if (msglencount == payloadlen)
|
||||
step++;
|
||||
}
|
||||
|
||||
break;
|
||||
case 7:
|
||||
buffer[msglencount + 6] = data;
|
||||
step++;
|
||||
break;
|
||||
case 8:
|
||||
buffer[msglencount + 6 + 1] = data;
|
||||
|
||||
var crc = ubx_checksum(buffer, payloadlen + 6);
|
||||
|
||||
var crcpacket = new byte[] { buffer[msglencount + 6], data };
|
||||
|
||||
if (crc[0] == crcpacket[0] && crc[1] == crcpacket[1])
|
||||
{
|
||||
step = 0;
|
||||
return (@class << 8) + subclass;
|
||||
}
|
||||
|
||||
step = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static byte[] ubx_checksum(byte[] packet, int size, int offset = 2)
|
||||
{
|
||||
uint a = 0x00;
|
||||
uint b = 0x00;
|
||||
var i = offset;
|
||||
while (i < size)
|
||||
{
|
||||
a += packet[i++];
|
||||
b += a;
|
||||
}
|
||||
|
||||
var ans = new byte[2];
|
||||
|
||||
ans[0] = (byte)(a & 0xFF);
|
||||
ans[1] = (byte)(b & 0xFF);
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
public static byte[] generate(byte cl, byte subclass, byte[] payload)
|
||||
{
|
||||
var data = new byte[2 + 2 + 2 + 2 + payload.Length];
|
||||
data[0] = 0xb5;
|
||||
data[1] = 0x62;
|
||||
data[2] = cl;
|
||||
data[3] = subclass;
|
||||
data[4] = (byte)(payload.Length & 0xff);
|
||||
data[5] = (byte)((payload.Length >> 8) & 0xff);
|
||||
|
||||
Array.ConstrainedCopy(payload, 0, data, 6, payload.Length);
|
||||
|
||||
var checksum = ubx_checksum(data, data.Length - 2);
|
||||
|
||||
data[data.Length - 2] = checksum[0];
|
||||
data[data.Length - 1] = checksum[1];
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct ubx_mon_ver
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
|
||||
public byte[] swVersion;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
|
||||
public Byte[] hwVersion;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
|
||||
public byte[] extension;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct ubx_mon_hw
|
||||
{
|
||||
public int pinSel;
|
||||
public int pinBank;
|
||||
public int pinDir;
|
||||
public int pinVal;
|
||||
public ushort noisePerMS;
|
||||
public ushort agcCnt;
|
||||
public byte aStatus;
|
||||
public byte aPower;
|
||||
public byte flags;
|
||||
public byte reserved1;
|
||||
public int usedMask;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
|
||||
public byte[] VP;
|
||||
|
||||
public byte jamInd;
|
||||
public ushort reserved3;
|
||||
public int pinIrq;
|
||||
public int pullH;
|
||||
public int pullL;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct ubx_nav_pvt
|
||||
{
|
||||
public uint32_t itow;
|
||||
public uint16_t year;
|
||||
public uint8_t month, day, hour, min, sec;
|
||||
public uint8_t valid;
|
||||
public uint32_t t_acc;
|
||||
public int32_t nano;
|
||||
public uint8_t fix_type;
|
||||
public uint8_t flags;
|
||||
public uint8_t flags2;
|
||||
public uint8_t num_sv;
|
||||
public int32_t lon, lat;
|
||||
public int32_t height, h_msl;
|
||||
public uint32_t h_acc, v_acc;
|
||||
public int32_t velN, velE, velD, gspeed;
|
||||
public int32_t head_mot;
|
||||
public uint32_t s_acc;
|
||||
public uint32_t head_acc;
|
||||
public uint16_t p_dop;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
|
||||
public uint8_t[] reserved1;
|
||||
|
||||
public uint32_t headVeh;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public uint8_t[] reserved2;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct ubx_nav_svin
|
||||
{
|
||||
public uint8_t version;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public uint8_t[] reserved1;
|
||||
|
||||
public uint32_t iTOW;
|
||||
public uint32_t dur;
|
||||
public int32_t meanX;
|
||||
public int32_t meanY;
|
||||
public int32_t meanZ;
|
||||
public int8_t meanXHP;
|
||||
public int8_t meanYHP;
|
||||
public int8_t meanZHP;
|
||||
public uint8_t reserved2;
|
||||
public uint32_t meanAcc;
|
||||
public uint32_t obs;
|
||||
public uint8_t valid;
|
||||
public uint8_t active;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public uint8_t[] reserved3;
|
||||
|
||||
public double[] getECEF()
|
||||
{
|
||||
var X = meanX / 100.0 + meanXHP * 0.0001;
|
||||
var Y = meanY / 100.0 + meanYHP * 0.0001;
|
||||
var Z = meanZ / 100.0 + meanZHP * 0.0001;
|
||||
|
||||
return new double[] { X, Y, Z };
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct ubx_nav_velned
|
||||
{
|
||||
public uint iTOW;
|
||||
public int velN;
|
||||
public int velE;
|
||||
public int velD;
|
||||
public uint speed;
|
||||
public uint gSpeed;
|
||||
public int heading;
|
||||
public uint sAcc;
|
||||
public uint cAcc;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct ubx_cfg_nav5_getset_s
|
||||
{
|
||||
public uint16_t mask;
|
||||
public uint8_t dynModel;
|
||||
public uint8_t fixMode;
|
||||
public int32_t fixedAlt;
|
||||
public uint32_t fixedAltVar;
|
||||
public int8_t minElev;
|
||||
public uint8_t drLimit;
|
||||
public uint16_t pDop;
|
||||
public uint16_t tDop;
|
||||
public uint16_t pAcc;
|
||||
public uint16_t tAcc;
|
||||
public uint8_t staticHoldThresh;
|
||||
public uint8_t dgnssTimeout;
|
||||
public uint8_t cnoThreshNumSVs;
|
||||
public uint8_t cnoThresh;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public uint8_t[] reserved1;
|
||||
|
||||
public uint16_t staticHoldMaxDist;
|
||||
public uint8_t utcStandard;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||
public uint8_t[] reserved2;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 40)]
|
||||
public struct ubx_cfg_tmode3
|
||||
{
|
||||
public ubx_cfg_tmode3(double lat, double lng, double alt, double acc = 0.001)
|
||||
{
|
||||
version = 0;
|
||||
reserved1 = 0;
|
||||
if (Math.Abs(lat) > 90)
|
||||
{
|
||||
flags = 2; // fixed mode ecef
|
||||
ecefXorLat = (int)(lat * 100);
|
||||
ecefYorLon = (int)(lng * 100);
|
||||
ecefZorAlt = (int)(alt * 100);
|
||||
ecefXOrLatHP = (sbyte)((lat * 100 - ecefXorLat) * 100.0);
|
||||
ecefYOrLonHP = (sbyte)((lng * 100 - ecefYorLon) * 100.0);
|
||||
ecefZOrAltHP = (sbyte)((alt * 100 - ecefZorAlt) * 100.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = 256 + 2; // lla + fixed mode
|
||||
ecefXorLat = (int)(lat * 1e7);
|
||||
ecefYorLon = (int)(lng * 1e7);
|
||||
ecefZorAlt = (int)(alt * 100.0);
|
||||
ecefXOrLatHP = (sbyte)((lat * 1e7 - ecefXorLat) * 100.0);
|
||||
ecefYOrLonHP = (sbyte)((lng * 1e7 - ecefYorLon) * 100.0);
|
||||
ecefZOrAltHP = (sbyte)((alt * 100.0 - ecefZorAlt) * 100.0);
|
||||
}
|
||||
|
||||
reserved2 = 0;
|
||||
fixedPosAcc = (uint)(acc * 1000.0);
|
||||
svinMinDur = 60;
|
||||
svinAccLimit = 2000;
|
||||
reserved3 = new byte[8];
|
||||
}
|
||||
|
||||
public ubx_cfg_tmode3(uint DurationS, double AccLimit)
|
||||
{
|
||||
version = 0;
|
||||
reserved1 = 0;
|
||||
flags = 1; // surveyin mode
|
||||
ecefXorLat = 0;
|
||||
ecefYorLon = 0;
|
||||
ecefZorAlt = 0;
|
||||
ecefXOrLatHP = (sbyte)0;
|
||||
ecefYOrLonHP = (sbyte)0;
|
||||
ecefZOrAltHP = (sbyte)0;
|
||||
reserved2 = 0;
|
||||
fixedPosAcc = 0;
|
||||
svinMinDur = DurationS;
|
||||
svinAccLimit = (uint)(AccLimit * 10000);
|
||||
reserved3 = new byte[8];
|
||||
}
|
||||
|
||||
public static ubx_cfg_tmode3 Disable
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ubx_cfg_tmode3()
|
||||
{
|
||||
flags = 0, // disable
|
||||
reserved3 = new byte[8]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator byte[] (ubx_cfg_tmode3 input)
|
||||
{
|
||||
return null;// MavlinkUtil.StructureToByteArray(input);
|
||||
}
|
||||
|
||||
public enum modeflags
|
||||
{
|
||||
Disabled = 0,
|
||||
SurveyIn = 1,
|
||||
FixedECEF = 2,
|
||||
LLA = 256,
|
||||
FixedLLA = 258
|
||||
}
|
||||
|
||||
public byte version;
|
||||
public byte reserved1;
|
||||
public ushort flags;
|
||||
public int ecefXorLat; // 1e7
|
||||
public int ecefYorLon;
|
||||
public int ecefZorAlt;
|
||||
public sbyte ecefXOrLatHP;
|
||||
public sbyte ecefYOrLonHP;
|
||||
public sbyte ecefZOrAltHP;
|
||||
public byte reserved2;
|
||||
public uint fixedPosAcc;
|
||||
public uint svinMinDur;
|
||||
public uint svinAccLimit;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] reserved3;
|
||||
|
||||
|
||||
|
||||
public void SetupM8P(ICommsSerial port, bool m8p_130plus = false, bool movingbase = false)
|
||||
{
|
||||
port.BaseStream.Flush();
|
||||
|
||||
var bauds = new[] { port.BaudRate, 9600, 38400, 57600, 115200, 230400, 460800 };
|
||||
|
||||
// change the baudrate
|
||||
foreach (var baud in bauds)
|
||||
{
|
||||
port.BaudRate = baud;
|
||||
|
||||
System.Threading.Thread.Sleep(50);
|
||||
// U = bit 01010101 - often used for autobaud
|
||||
port.Write("UU");
|
||||
// port config - 460800 - uart1
|
||||
var packet = generate(0x6, 0x00, new byte[]
|
||||
{
|
||||
0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x00, 0x08,
|
||||
0x07, 0x00, 0x23, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
});
|
||||
port.Write(packet, 0, packet.Length);
|
||||
port.BaseStream.Flush();
|
||||
System.Threading.Thread.Sleep(100);
|
||||
}
|
||||
|
||||
{
|
||||
// port config - usb
|
||||
var packet = generate(0x6, 0x00, new byte[]
|
||||
{
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x23, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
});
|
||||
port.Write(packet, 0, packet.Length);
|
||||
System.Threading.Thread.Sleep(300);
|
||||
|
||||
port.BaseStream.Flush();
|
||||
|
||||
port.BaudRate = 460800;
|
||||
}
|
||||
|
||||
{
|
||||
// set rate to 1hz
|
||||
var packet = generate(0x6, 0x8, new byte[] { 0xE8, 0x03, 0x01, 0x00, 0x01, 0x00 });
|
||||
port.Write(packet, 0, packet.Length);
|
||||
System.Threading.Thread.Sleep(200);
|
||||
|
||||
// set navmode to stationary
|
||||
{
|
||||
packet = generate(0x6, 0x24,
|
||||
new byte[]
|
||||
{
|
||||
0xFF, 0xFF, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x0F, 0x00, 0xFA,
|
||||
0x00,
|
||||
0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x23, 0x10, 0x27, 0x00, 0x00, 0x00,
|
||||
0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
});
|
||||
port.Write(packet, 0, packet.Length);
|
||||
System.Threading.Thread.Sleep(200);
|
||||
}
|
||||
}
|
||||
|
||||
// turn off all nmea
|
||||
for (int a = 0; a <= 0xf; a++)
|
||||
{
|
||||
if (a == 0xb || a == 0xc || a == 0xe)
|
||||
continue;
|
||||
turnon_off(port, 0xf0, (byte)a, 0);
|
||||
}
|
||||
|
||||
// mon-ver
|
||||
poll_msg(port, 0xa, 0x4);
|
||||
|
||||
// surveyin msg - for feedback
|
||||
turnon_off(port, 0x01, 0x3b, 1);
|
||||
|
||||
// pvt msg - for feedback
|
||||
turnon_off(port, 0x01, 0x07, 1);
|
||||
|
||||
// 1005 - 5s
|
||||
turnon_off(port, 0xf5, 0x05, 5);
|
||||
|
||||
byte rate1 = 1;
|
||||
byte rate2 = 0;
|
||||
|
||||
if (m8p_130plus)
|
||||
{
|
||||
rate1 = 0;
|
||||
rate2 = 1;
|
||||
}
|
||||
|
||||
// 1074 - 1s
|
||||
turnon_off(port, 0xf5, 0x4a, rate2);
|
||||
// 1077 - 1s
|
||||
turnon_off(port, 0xf5, 0x4d, rate1);
|
||||
|
||||
// 1084 - 1s
|
||||
turnon_off(port, 0xf5, 0x54, rate2);
|
||||
// 1087 - 1s
|
||||
turnon_off(port, 0xf5, 0x57, rate1);
|
||||
|
||||
// 1094 - 1s
|
||||
turnon_off(port, 0xf5, 0x5e, rate2);
|
||||
// 1097 - 1s
|
||||
turnon_off(port, 0xf5, 0x61, rate1);
|
||||
|
||||
// 1124 - 1s
|
||||
turnon_off(port, 0xf5, 0x7c, rate2);
|
||||
// 1127 - 1s
|
||||
turnon_off(port, 0xf5, 0x7f, rate1);
|
||||
|
||||
// 4072
|
||||
turnon_off(port, 0xf5, 0xFE, 0);
|
||||
|
||||
// 1230 - 5s
|
||||
turnon_off(port, 0xf5, 0xE6, 5);
|
||||
|
||||
// NAV-VELNED - 1s
|
||||
turnon_off(port, 0x01, 0x12, 1);
|
||||
|
||||
// rxm-raw/rawx - 1s
|
||||
turnon_off(port, 0x02, 0x15, 1);
|
||||
turnon_off(port, 0x02, 0x10, 1);
|
||||
|
||||
// rxm-sfrb/sfrb - 2s
|
||||
turnon_off(port, 0x02, 0x13, 2);
|
||||
turnon_off(port, 0x02, 0x11, 2);
|
||||
|
||||
// mon-hw - 2s
|
||||
turnon_off(port, 0x0a, 0x09, 2);
|
||||
|
||||
System.Threading.Thread.Sleep(100);
|
||||
}
|
||||
|
||||
|
||||
public void turnon_off(ICommsSerial port, byte clas, byte subclass, byte every_xsamples)
|
||||
{
|
||||
byte[] datastruct1 = { clas, subclass, 0, every_xsamples, 0, every_xsamples, 0, 0 };
|
||||
|
||||
var packet = generate(0x6, 0x1, datastruct1);
|
||||
|
||||
port.Write(packet, 0, packet.Length);
|
||||
|
||||
System.Threading.Thread.Sleep(10);
|
||||
}
|
||||
|
||||
public void poll_msg(ICommsSerial port, byte clas, byte subclass)
|
||||
{
|
||||
byte[] datastruct1 = { };
|
||||
|
||||
var packet = generate(clas, subclass, datastruct1);
|
||||
|
||||
port.Write(packet, 0, packet.Length);
|
||||
|
||||
System.Threading.Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,222 +1,263 @@
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using Plane.CommunicationManagement;
|
||||
using Plane.CopterManagement;
|
||||
using Plane.Copters;
|
||||
using Plane.FormationCreator.Formation;
|
||||
using Plane.Windows.Messages;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
public class CalibrationViewModel : ViewModelBase
|
||||
{
|
||||
CommModuleManager commModule = CommModuleManager.Instance;
|
||||
|
||||
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
|
||||
private string _AccelerometerTips;
|
||||
public string AccelerometerTips
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (AccelerometerState)
|
||||
{
|
||||
case AccelerometerStates.Idle:
|
||||
_AccelerometerTips = "点击“开始校准”后,开始校准加速计";
|
||||
break;
|
||||
case AccelerometerStates.Front:
|
||||
_AccelerometerTips = "亮紫色: 飞机水平放置(Front)";
|
||||
break;
|
||||
case AccelerometerStates.Left:
|
||||
_AccelerometerTips = "亮黄色:飞机左侧接触地面竖立放置(Left)";
|
||||
break;
|
||||
case AccelerometerStates.Right:
|
||||
_AccelerometerTips = "亮青色:飞机右侧接触地面竖立放置(Right)";
|
||||
break;
|
||||
case AccelerometerStates.Down:
|
||||
_AccelerometerTips = "紫色:飞机机头向下接触地面竖立放置(Down)";
|
||||
break;
|
||||
case AccelerometerStates.Up:
|
||||
_AccelerometerTips = "黄色:飞机机尾向下接触地面竖立放置(Up)";
|
||||
break;
|
||||
case AccelerometerStates.Back:
|
||||
_AccelerometerTips = "青色:飞机翻过来水平放置(Back)";
|
||||
break;
|
||||
}
|
||||
return _AccelerometerTips;
|
||||
}
|
||||
}
|
||||
|
||||
private string _AccelerometerBtnText = "开始校准";
|
||||
public string AccelerometerBtnText
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (AccelerometerState)
|
||||
{
|
||||
case AccelerometerStates.Idle:
|
||||
_AccelerometerBtnText = "开始校准";
|
||||
break;
|
||||
default:
|
||||
_AccelerometerBtnText = "完成";
|
||||
break;
|
||||
}
|
||||
return _AccelerometerBtnText;
|
||||
}
|
||||
}
|
||||
|
||||
//校准加速计的状态
|
||||
public enum AccelerometerStates
|
||||
{
|
||||
Idle = 0,
|
||||
Front = 1,
|
||||
Left = 2,
|
||||
Right = 3,
|
||||
Down = 4,
|
||||
Up = 5,
|
||||
Back = 6
|
||||
}
|
||||
|
||||
private AccelerometerStates _AccelerometerState = AccelerometerStates.Idle;
|
||||
public AccelerometerStates AccelerometerState
|
||||
{
|
||||
get { return _AccelerometerState; }
|
||||
set
|
||||
{
|
||||
Set(nameof(AccelerometerState), ref _AccelerometerState, value);
|
||||
RaisePropertyChanged(nameof(AccelerometerBtnText));
|
||||
RaisePropertyChanged(nameof(AccelerometerTips));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始校准加速计
|
||||
/// </summary>
|
||||
private ICommand _CalibrationAccelerometerStartCommand;
|
||||
public ICommand CalibrationAccelerometerStartCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CalibrationAccelerometerStartCommand ?? (_CalibrationAccelerometerStartCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
await commModule.DoStartPreflightCompassAsync(_copterManager.SelectedCopters);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校准加速计下一步
|
||||
/// </summary>
|
||||
private ICommand _CalibrationAccelerometerNextCommand;
|
||||
public ICommand CalibrationAccelerometerNextCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CalibrationAccelerometerNextCommand ?? (_CalibrationAccelerometerNextCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
await commModule.DoNextPreflightCompassAsync(_copterManager.SelectedCopters);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private int _CompassPercent;
|
||||
public int CompassPercent
|
||||
{
|
||||
get { return _CompassPercent; }
|
||||
set
|
||||
{
|
||||
Set(nameof(CompassPercent), ref _CompassPercent, value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCalibration { get; set; }
|
||||
/// <summary>
|
||||
/// 校准指南针
|
||||
/// </summary>
|
||||
private ICommand _CalibrationCompassCommand;
|
||||
public ICommand CalibrationCompassCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CalibrationCompassCommand ?? (_CalibrationCompassCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
|
||||
// ICopter copter = _copterManager.SelectedCopters.FirstOrDefault();
|
||||
//
|
||||
// short copterId = short.Parse(copter.Name);
|
||||
Message.Show("开始校准指南针");
|
||||
|
||||
await commModule.DoCalibrationCompassAsync(_copterManager.SelectedCopters);
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
|
||||
/*支持多飞行机同时校准 不再判断单架的返回值
|
||||
|
||||
IsCalibration = true;
|
||||
CompassPercent = 0;
|
||||
int State = 0; //4:成功 5失败 todo 改为枚举
|
||||
|
||||
|
||||
while (IsCalibration && CompassPercent <= 100)
|
||||
{
|
||||
//两个255的时候表示 当前预留字节代表的意思是校准
|
||||
if (copter.Retain[2] == 255 && copter.Retain[3] == 255)
|
||||
{
|
||||
CompassPercent = copter.Retain[0];
|
||||
State = copter.Retain[1];
|
||||
if (State == 4 || State == 5)
|
||||
break;
|
||||
}
|
||||
|
||||
await Task.Delay(100);
|
||||
}
|
||||
|
||||
switch (State)
|
||||
{
|
||||
case 4:
|
||||
Alert.Show($"校准成功,请重新上电{copterId}号", "指南针");
|
||||
break;
|
||||
case 5:
|
||||
Alert.Show("校准失败", "指南针");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
IsCalibration = false;
|
||||
*/
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private ICommand _CancelCalibrationCompassCommand;
|
||||
public ICommand CancelCalibrationCompassCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CancelCalibrationCompassCommand ?? (_CancelCalibrationCompassCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 1) return;
|
||||
|
||||
ICopter copter = _copterManager.SelectedCopters.FirstOrDefault();
|
||||
|
||||
short copterId = short.Parse(copter.Name);
|
||||
await commModule.DoCancelCalibrationCompassAsync(copterId);
|
||||
IsCalibration = false;
|
||||
Alert.Show("放弃校准", "指南针");
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using Plane.CommunicationManagement;
|
||||
using Plane.CopterManagement;
|
||||
using Plane.Copters;
|
||||
using Plane.FormationCreator.Formation;
|
||||
using Plane.Windows.Messages;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
public class CalibrationViewModel : ViewModelBase
|
||||
{
|
||||
CommModuleManager commModule = CommModuleManager.Instance;
|
||||
|
||||
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
|
||||
private string _AccelerometerTips;
|
||||
public string AccelerometerTips
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (AccelerometerState)
|
||||
{
|
||||
case AccelerometerStates.Idle:
|
||||
_AccelerometerTips = "点击“开始校准”后,开始校准加速计";
|
||||
break;
|
||||
case AccelerometerStates.Front:
|
||||
_AccelerometerTips = "亮紫色: 飞机水平放置(Front)";
|
||||
break;
|
||||
case AccelerometerStates.Left:
|
||||
_AccelerometerTips = "亮黄色:飞机左侧接触地面竖立放置(Left)";
|
||||
break;
|
||||
case AccelerometerStates.Right:
|
||||
_AccelerometerTips = "亮青色:飞机右侧接触地面竖立放置(Right)";
|
||||
break;
|
||||
case AccelerometerStates.Down:
|
||||
_AccelerometerTips = "紫色:飞机机头向下接触地面竖立放置(Down)";
|
||||
break;
|
||||
case AccelerometerStates.Up:
|
||||
_AccelerometerTips = "黄色:飞机机尾向下接触地面竖立放置(Up)";
|
||||
break;
|
||||
case AccelerometerStates.Back:
|
||||
_AccelerometerTips = "青色:飞机翻过来水平放置(Back)";
|
||||
break;
|
||||
}
|
||||
return _AccelerometerTips;
|
||||
}
|
||||
}
|
||||
|
||||
private string _AccelerometerBtnText = "开始校准";
|
||||
public string AccelerometerBtnText
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (AccelerometerState)
|
||||
{
|
||||
case AccelerometerStates.Idle:
|
||||
_AccelerometerBtnText = "开始校准";
|
||||
break;
|
||||
default:
|
||||
_AccelerometerBtnText = "完成";
|
||||
break;
|
||||
}
|
||||
return _AccelerometerBtnText;
|
||||
}
|
||||
}
|
||||
|
||||
//校准加速计的状态
|
||||
public enum AccelerometerStates
|
||||
{
|
||||
Idle = 0,
|
||||
Front = 1,
|
||||
Left = 2,
|
||||
Right = 3,
|
||||
Down = 4,
|
||||
Up = 5,
|
||||
Back = 6
|
||||
}
|
||||
|
||||
private AccelerometerStates _AccelerometerState = AccelerometerStates.Idle;
|
||||
public AccelerometerStates AccelerometerState
|
||||
{
|
||||
get { return _AccelerometerState; }
|
||||
set
|
||||
{
|
||||
Set(nameof(AccelerometerState), ref _AccelerometerState, value);
|
||||
RaisePropertyChanged(nameof(AccelerometerBtnText));
|
||||
RaisePropertyChanged(nameof(AccelerometerTips));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始校准加速计
|
||||
/// </summary>
|
||||
private ICommand _CalibrationAccelerometerStartCommand;
|
||||
public ICommand CalibrationAccelerometerStartCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CalibrationAccelerometerStartCommand ?? (_CalibrationAccelerometerStartCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
await commModule.DoStartPreflightCompassAsync(_copterManager.SelectedCopters);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校准加速计下一步
|
||||
/// </summary>
|
||||
private ICommand _CalibrationAccelerometerNextCommand;
|
||||
public ICommand CalibrationAccelerometerNextCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CalibrationAccelerometerNextCommand ?? (_CalibrationAccelerometerNextCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
await commModule.DoNextPreflightCompassAsync(_copterManager.SelectedCopters);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private int _CompassPercent;
|
||||
public int CompassPercent
|
||||
{
|
||||
get { return _CompassPercent; }
|
||||
set
|
||||
{
|
||||
Set(nameof(CompassPercent), ref _CompassPercent, value);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCalibration { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 重启飞控
|
||||
/// </summary>
|
||||
private ICommand _RestartFCCommand;
|
||||
public ICommand RestartFCCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _RestartFCCommand ?? (_RestartFCCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
Message.Show("重启飞控");
|
||||
await commModule.DoRestartFCAsync(_copterManager.SelectedCopters);
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 陀螺仪校准
|
||||
/// </summary>
|
||||
private ICommand _CalibrationPreflightCommand;
|
||||
public ICommand CalibrationPreflightCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CalibrationPreflightCommand ?? (_CalibrationPreflightCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
Message.Show("开始校准陀螺仪");
|
||||
await commModule.DoCalibrationPreflightAsync(_copterManager.SelectedCopters);
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 校准指南针
|
||||
/// </summary>
|
||||
private ICommand _CalibrationCompassCommand;
|
||||
public ICommand CalibrationCompassCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CalibrationCompassCommand ?? (_CalibrationCompassCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 0) return;
|
||||
|
||||
// ICopter copter = _copterManager.SelectedCopters.FirstOrDefault();
|
||||
//
|
||||
// short copterId = short.Parse(copter.Name);
|
||||
Message.Show("开始校准指南针");
|
||||
|
||||
await commModule.DoCalibrationCompassAsync(_copterManager.SelectedCopters);
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
|
||||
/*支持多飞行机同时校准 不再判断单架的返回值
|
||||
|
||||
IsCalibration = true;
|
||||
CompassPercent = 0;
|
||||
int State = 0; //4:成功 5失败 todo 改为枚举
|
||||
|
||||
|
||||
while (IsCalibration && CompassPercent <= 100)
|
||||
{
|
||||
//两个255的时候表示 当前预留字节代表的意思是校准
|
||||
if (copter.Retain[2] == 255 && copter.Retain[3] == 255)
|
||||
{
|
||||
CompassPercent = copter.Retain[0];
|
||||
State = copter.Retain[1];
|
||||
if (State == 4 || State == 5)
|
||||
break;
|
||||
}
|
||||
|
||||
await Task.Delay(100);
|
||||
}
|
||||
|
||||
switch (State)
|
||||
{
|
||||
case 4:
|
||||
Alert.Show($"校准成功,请重新上电{copterId}号", "指南针");
|
||||
break;
|
||||
case 5:
|
||||
Alert.Show("校准失败", "指南针");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
IsCalibration = false;
|
||||
*/
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private ICommand _CancelCalibrationCompassCommand;
|
||||
public ICommand CancelCalibrationCompassCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _CancelCalibrationCompassCommand ?? (_CancelCalibrationCompassCommand = new RelayCommand(async () =>
|
||||
{
|
||||
if (_copterManager.SelectedCopters.Count() == 1) return;
|
||||
|
||||
ICopter copter = _copterManager.SelectedCopters.FirstOrDefault();
|
||||
|
||||
short copterId = short.Parse(copter.Name);
|
||||
await commModule.DoCancelCalibrationCompassAsync(copterId);
|
||||
IsCalibration = false;
|
||||
Alert.Show("放弃校准", "指南针");
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
150
Plane.FormationCreator/ViewModels/ChangePasswordView.cs
Normal file
@ -0,0 +1,150 @@
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using Plane.FormationCreator.Formation;
|
||||
using Plane.FormationCreator.Util;
|
||||
using Plane.FormationCreator.Views;
|
||||
using Plane.Util;
|
||||
using Plane.Windows.Messages;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interactivity;
|
||||
|
||||
namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains properties that a View can data bind to.
|
||||
/// <para>
|
||||
/// See http://www.galasoft.ch/mvvm
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public class ChangePasswordViewModel : ViewModelBase
|
||||
{
|
||||
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
private MainViewModel _MainViewModel=ServiceLocator.Current.GetInstance<MainViewModel>();
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LoginViewModel class.
|
||||
/// </summary>
|
||||
public ChangePasswordViewModel()
|
||||
{
|
||||
|
||||
NewPassword = "";
|
||||
OldPassword = "";
|
||||
NewPassword1 = "";
|
||||
Username = "";
|
||||
}
|
||||
|
||||
|
||||
private string _Username="";
|
||||
public string Username
|
||||
{
|
||||
get { return _Username; }
|
||||
set
|
||||
{
|
||||
Set(nameof(Username), ref _Username, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private string _OldPassword = "";
|
||||
public string OldPassword
|
||||
{
|
||||
get { return _OldPassword; }
|
||||
set
|
||||
{
|
||||
Set(nameof(OldPassword), ref _OldPassword, value);
|
||||
}
|
||||
}
|
||||
|
||||
private string _NewPassword = "";
|
||||
public string NewPassword
|
||||
{
|
||||
get { return _NewPassword; }
|
||||
set
|
||||
{
|
||||
Set(nameof(NewPassword), ref _NewPassword, value);
|
||||
}
|
||||
}
|
||||
private string _NewPassword1 = "";
|
||||
public string NewPassword1
|
||||
{
|
||||
get { return _NewPassword1; }
|
||||
set
|
||||
{
|
||||
Set(nameof(NewPassword1), ref _NewPassword1, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private ICommand _ExitCommand;
|
||||
public ICommand ExitCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ExitCommand ?? (_ExitCommand = new RelayCommand<ChangePasswordView>(wd =>
|
||||
{
|
||||
if (wd != null)
|
||||
{
|
||||
NewPassword = "";
|
||||
OldPassword = "";
|
||||
NewPassword1 = "";
|
||||
Username = "";
|
||||
wd.Close();
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
private ICommand _ChangePasswordCommand;
|
||||
public ICommand ChangePasswordCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ChangePasswordCommand ?? (_ChangePasswordCommand = new RelayCommand<ChangePasswordView>(wd =>
|
||||
{
|
||||
if (Username.Trim() == "")
|
||||
{
|
||||
Alert.Show("请输入账号!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (OldPassword=="")
|
||||
{
|
||||
Alert.Show("请输入原密码!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NewPassword.Length<6)
|
||||
{
|
||||
Alert.Show("新密码长度不能低于6位!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NewPassword != NewPassword1)
|
||||
{
|
||||
Alert.Show("两次新密码不相同!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
_copterManager.NetChangePassword(Username.Trim(), OldPassword, NewPassword);
|
||||
|
||||
//wd.Close();
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
336
Plane.FormationCreator/ViewModels/ConfigVirtualIdViewModel.cs
Normal file
@ -0,0 +1,336 @@
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Plane.Copters;
|
||||
using Plane.FormationCreator.Formation;
|
||||
using Plane.Geography;
|
||||
using Plane.Windows.Messages;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using System.IO;
|
||||
|
||||
namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
public class ConfigVirtualIdViewModel : ViewModelBase
|
||||
{
|
||||
CopterManager _copterManager;
|
||||
public ConfigVirtualIdViewModel(CopterManager copterManager)
|
||||
{
|
||||
_copterManager = copterManager;
|
||||
}
|
||||
|
||||
private int _SingleVirtualId = 0;
|
||||
public int SingleVirtualId
|
||||
{
|
||||
get { return _SingleVirtualId; }
|
||||
set { Set(nameof(SingleVirtualId), ref _SingleVirtualId, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有编号
|
||||
/// </summary>
|
||||
private ICommand _ClearVirtualIdCommand;
|
||||
public ICommand ClearVirtualIdCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ClearVirtualIdCommand ?? (_ClearVirtualIdCommand = new RelayCommand(() =>
|
||||
{
|
||||
foreach (var c in _copterManager.Copters)
|
||||
{
|
||||
c.VirtualId = 0;
|
||||
}
|
||||
Message.Show($"已清除所有飞机编号");
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有编号
|
||||
/// </summary>
|
||||
private ICommand _SaveVirtualIdCommand;
|
||||
public ICommand SaveVirtualIdCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SaveVirtualIdCommand ?? (_SaveVirtualIdCommand = new RelayCommand(() =>
|
||||
{
|
||||
string Savestr = "";
|
||||
foreach (var c in _copterManager.Copters)
|
||||
{
|
||||
Savestr += c.Id + "=" + c.VirtualId + ';';
|
||||
}
|
||||
StreamWriter writer = new StreamWriter("vid.dat");
|
||||
writer.Write(Savestr);
|
||||
writer.Close();
|
||||
Message.Show($"保存成功");
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 清除所有编号
|
||||
/// </summary>
|
||||
private ICommand _LoadVirtualIdCommand;
|
||||
public ICommand LoadVirtualIdCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _LoadVirtualIdCommand ?? (_LoadVirtualIdCommand = new RelayCommand(() =>
|
||||
{
|
||||
if (!File.Exists("vid.dat"))
|
||||
return;
|
||||
// string str = System.IO.File.ReadAllText(@"vid.dat");
|
||||
|
||||
string str = File.ReadAllText("vid.dat");
|
||||
|
||||
string[] arr = str.Split(';');
|
||||
foreach (string s in arr)
|
||||
{
|
||||
|
||||
string[] arrs = s.Split('=');
|
||||
|
||||
|
||||
var copter = _copterManager.Copters.FirstOrDefault(c => c.Id == arrs[0]);
|
||||
if (copter != null)
|
||||
{
|
||||
copter.VirtualId = int.Parse(arrs[1]);
|
||||
}
|
||||
}
|
||||
|
||||
_copterManager.SortType = CopterManager.CopterSortType.ByVID;// .sortbyvid();
|
||||
Message.Show($"读入成功");
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置单个虚拟ID
|
||||
/// </summary>
|
||||
private ICommand _SetSingleVirtualIdCommand;
|
||||
public ICommand SetSingleVirtualIdCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SetSingleVirtualIdCommand ?? (_SetSingleVirtualIdCommand = new RelayCommand(() =>
|
||||
{
|
||||
if (SingleVirtualId <= 0)
|
||||
{
|
||||
System.Windows.MessageBox.Show("编号必须大于0");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_copterManager.AcceptingControlCopters.Count() == 1)
|
||||
{
|
||||
var copter = _copterManager.AcceptingControlCopters.FirstOrDefault();
|
||||
copter.VirtualId = SingleVirtualId;
|
||||
Message.Show($"飞机{copter.Name} 设置编号={SingleVirtualId}");
|
||||
}
|
||||
_copterManager.ReSort();
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private ICommand _AutoLocationNumsCommand;
|
||||
public ICommand AutoLocationNumsCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
//目前方案是
|
||||
//1.保证所有没有正确定位的飞机都人工编号,
|
||||
//2.然后选中3架飞机,1号飞机,第一排任意飞机,第一列任意飞机(尽量远离1号机),
|
||||
//3.开始计算
|
||||
return _AutoLocationNumsCommand ?? (_AutoLocationNumsCommand = new RelayCommand( () =>
|
||||
{
|
||||
//飞机摆放最小间距
|
||||
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
|
||||
float StepDis_Row = _flightTaskManager.ColumnDistance; //行内间距-列间距
|
||||
float StepDis_Col = _flightTaskManager.RowDistance ; //列间距-行间距
|
||||
float FindDis =Math.Min(StepDis_Row, StepDis_Col)*0.8f; //查找半径
|
||||
//如果选中的飞机总数大于2--需要2-3架用来确认行列方向,只有一行飞机就选2架,多行需要3架
|
||||
if (_copterManager.AcceptingControlCopters.Count() >= 2)
|
||||
{
|
||||
var copters = _copterManager.AcceptingControlCopters.ToList();
|
||||
var firstCopter = copters[0];
|
||||
var secondCopter = copters[1];
|
||||
ICopter thirdCopter=null;
|
||||
if (_copterManager.AcceptingControlCopters.Count() > 2)
|
||||
{
|
||||
thirdCopter = copters[2];
|
||||
Message.Show($"选中了3架飞机,将自动查找所有行列的飞机");
|
||||
}
|
||||
else
|
||||
Message.Show($"选中了2架飞机,将查找一行飞机");
|
||||
|
||||
|
||||
//行角度(1,2) 用于查找每行的飞机位置
|
||||
float RowDirect = (float)GeographyUtils.RadToDeg(firstCopter.CalcDirection2D(secondCopter));
|
||||
//列角度(1,3) 用于查找每行第一架飞机
|
||||
float ColDirect = 0;
|
||||
if (thirdCopter!=null)
|
||||
ColDirect = (float)GeographyUtils.RadToDeg(firstCopter.CalcDirection2D(thirdCopter));
|
||||
ICopter FindedCopter = firstCopter;
|
||||
ICopter LastCopter = firstCopter;
|
||||
ILocation2D LastRowHewadCopter = firstCopter;
|
||||
|
||||
Message.Show($"开始查找飞机:行角度{RowDirect},列角度{ColDirect},列间距{StepDis_Row},行间距{StepDis_Col},查找半径{FindDis}米...");
|
||||
|
||||
firstCopter.VirtualId = 1;
|
||||
int rowindex = 1;
|
||||
while (FindedCopter!=null)
|
||||
{
|
||||
//按一行找飞机
|
||||
FindedCopter = FindNextCopter(LastCopter, RowDirect, StepDis_Row, FindDis);
|
||||
//一行找不到了 找下一行的前3架飞机
|
||||
if ((FindedCopter == null) && (thirdCopter != null))
|
||||
{
|
||||
rowindex++;
|
||||
FindedCopter = FindNextColHeadCopter(out LastRowHewadCopter, LastRowHewadCopter, ColDirect, StepDis_Col, RowDirect, StepDis_Row, 3, FindDis);
|
||||
if (FindedCopter != null)
|
||||
Message.Show($"开始第{rowindex}行--找到飞机");
|
||||
else
|
||||
Message.Show($"开始第{rowindex}行--无飞机");
|
||||
}
|
||||
//如果找到了分配ID
|
||||
if (FindedCopter != null)
|
||||
{
|
||||
FindedCopter.VirtualId = GetVID(LastCopter.VirtualId);
|
||||
// Message.Show($"分配ID={FindedCopter.Id}飞机VID:={FindedCopter.VirtualId}");
|
||||
LastCopter = FindedCopter;
|
||||
}else
|
||||
{
|
||||
|
||||
Message.Show($"未找到飞机,自动分配结束");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
_copterManager.ReSort();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
//根据位置和查找范围查找飞机
|
||||
private ICopter FindCopteratLoc(ILocation2D startLoc, float findDis)
|
||||
{
|
||||
ICopter retCopter = null;
|
||||
ICopter foundCopter = null;
|
||||
double mindis = 1000;
|
||||
//所有没有虚拟ID的飞机
|
||||
List<ICopter> NoVIDCopters = _copterManager.Copters.Where(o => o.VirtualId == 0).ToList();
|
||||
//找距离startLoc最近的飞机
|
||||
foreach (var copter in NoVIDCopters)
|
||||
{
|
||||
//计算这些飞机和startLoc的距离
|
||||
double temp = startLoc.CalcDistance2D(copter);
|
||||
//找最近的飞机
|
||||
if (temp < mindis)
|
||||
{
|
||||
mindis = temp;
|
||||
foundCopter = copter;
|
||||
}
|
||||
}
|
||||
|
||||
//如果找到的最近的飞机小于查找半径就认为找到了
|
||||
if (mindis < findDis)
|
||||
retCopter = foundCopter;
|
||||
return retCopter;
|
||||
}
|
||||
|
||||
//根据VID查找飞机
|
||||
private ICopter FindCopteratVID(int VID)
|
||||
{
|
||||
List<ICopter> HaveVIDCopters = _copterManager.Copters.Where(o => o.VirtualId == VID).ToList();
|
||||
if (HaveVIDCopters.Count==1)
|
||||
return HaveVIDCopters[0];
|
||||
return null;
|
||||
}
|
||||
|
||||
//计算VID,找下一个没有提前分配的VID
|
||||
private int GetVID(int VirtualId)
|
||||
{
|
||||
int retvid = VirtualId+1;
|
||||
ICopter Copter = FindCopteratVID(retvid);
|
||||
while (Copter!=null)
|
||||
Copter = FindCopteratVID(++retvid);
|
||||
return retvid;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 按方向步长等找下一架飞机
|
||||
/// </summary>
|
||||
/// <param name="Copter">起始飞机</param>
|
||||
/// <param name="Direct">方向</param>
|
||||
/// <param name="findstep">步长</param>
|
||||
/// <param name="finddis">查找半径</param>
|
||||
/// <returns>找到的飞机</returns>
|
||||
private ICopter FindNextCopter(ILocation2D Copter, float Direct,float findstep,float finddis,int findstepnum=5)
|
||||
{
|
||||
ICopter FindedCopter = null;
|
||||
ILocation2D FindLoc = null;
|
||||
int step = 1;
|
||||
while ((FindedCopter == null) && (step <= findstepnum))
|
||||
{
|
||||
//查找下一个飞机应在摆放的位置
|
||||
FindLoc = Copter.CalcLatLngSomeMetersAway2D(Direct, findstep * step++);
|
||||
//该位置是否有飞机
|
||||
FindedCopter = FindCopteratLoc(FindLoc, finddis);
|
||||
}
|
||||
return FindedCopter;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///按方向步长等找下一行的第一架飞机同时输出该行第一个应该摆放飞机的位置
|
||||
/// </summary>
|
||||
/// <param name="HeadLoc">输出第一架飞机应该在的位置</param>
|
||||
/// <param name="Copter">起始飞机</param>
|
||||
/// <param name="ColDirect">列角度</param>
|
||||
/// <param name="Colstep">列步长</param>
|
||||
/// <param name="RowDirect">行角度</param>
|
||||
/// <param name="Rowstep">行步长</param>
|
||||
/// <param name="Rowstepnum">行查找深度</param>
|
||||
/// <param name="finddis">位置查找范围</param>
|
||||
/// <returns>找到的飞机</returns>
|
||||
private ICopter FindNextColHeadCopter(out ILocation2D HeadLoc, ILocation2D Copter, float ColDirect, float Colstep,
|
||||
float RowDirect, float Rowstep, int Rowstepnum,float finddis, int Colfindstepnum = 5)
|
||||
{
|
||||
ICopter FindedCopter = null;
|
||||
HeadLoc = null;
|
||||
int step = 1;
|
||||
while ((FindedCopter == null) && (step <= Colfindstepnum))
|
||||
{
|
||||
//查找下一行第一架飞机应在摆放的位置
|
||||
HeadLoc = Copter.CalcLatLngSomeMetersAway2D(ColDirect, Colstep * step++);
|
||||
//该位置是否有飞机
|
||||
FindedCopter = FindCopteratLoc(HeadLoc, finddis);
|
||||
//如果没有飞机,横着找找行有没飞机
|
||||
if (FindedCopter==null)
|
||||
FindedCopter=FindNextCopter(HeadLoc, RowDirect, Rowstep, finddis, Rowstepnum);
|
||||
}
|
||||
return FindedCopter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -24,16 +24,32 @@ using Plane.CommunicationManagement;
|
||||
using Plane.Protocols;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using System.Windows.Media;
|
||||
using Plane.FormationCreator.Views;
|
||||
using System.Collections.ObjectModel;
|
||||
using Plane.Util;
|
||||
using System.IO.Ports;
|
||||
using SerialPort = Plane.Util.SerialPort;
|
||||
|
||||
namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
public class ConnectViewModel : ViewModelBase
|
||||
{
|
||||
|
||||
public ConnectViewModel(CopterManager copterManager)
|
||||
{
|
||||
_copterManager = copterManager;
|
||||
RefreshPorts();
|
||||
}
|
||||
|
||||
public void RefreshPorts()
|
||||
{
|
||||
serialRePorts.Clear();
|
||||
string[] commports = SerialPort.GetPortNames();
|
||||
foreach (var item in commports)
|
||||
{
|
||||
serialRePorts.Add(item);
|
||||
}
|
||||
}
|
||||
private CommModuleManager _commModuleManager = CommModuleManager.Instance;
|
||||
private CopterManager _copterManager;
|
||||
|
||||
private const int PORT = 5250;
|
||||
@ -66,6 +82,16 @@ namespace Plane.FormationCreator.ViewModels
|
||||
set { Set(nameof(IsProcessing), ref _IsProcessing, value); }
|
||||
}
|
||||
|
||||
public ObservableCollection<string> serialRePorts { get; } = new ObservableCollection<string>();
|
||||
private string _serialPortResend;
|
||||
public string SerialPortResend
|
||||
{
|
||||
|
||||
get { return _serialPortResend; }
|
||||
set { Set(nameof(SerialPortResend), ref _serialPortResend, value); }
|
||||
|
||||
}
|
||||
|
||||
private ICommand _ConnectCommand;
|
||||
public ICommand ConnectCommand
|
||||
{
|
||||
@ -78,7 +104,67 @@ namespace Plane.FormationCreator.ViewModels
|
||||
));
|
||||
}
|
||||
}
|
||||
RtcmInfoViewModel _rtcmInfoViewModel = ServiceLocator.Current.GetInstance<RtcmInfoViewModel>();
|
||||
private ICommand _Openboardport;
|
||||
public ICommand Openboardport
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Openboardport ?? (_Openboardport = new RelayCommand<string>(async connectionType =>
|
||||
{
|
||||
if (btnBoardPortStr== "关闭广播端口")
|
||||
{
|
||||
//关闭广播端口
|
||||
//正在发送rtcm数据并且使用了广播端口
|
||||
if (_rtcmInfoViewModel.RtcmManager.Rtcmthreadrun&& _rtcmInfoViewModel.ResendToComMK)
|
||||
{
|
||||
if (Alert.Show("正在使用广播端口发送RTCM数据,关闭后广播端口将停止发送,继续吗?", "警告", MessageBoxButton.OKCancel, MessageBoxImage.Warning)
|
||||
== MessageBoxResult.OK)
|
||||
{
|
||||
// _rtcmInfoViewModel.ResendToComMK = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
//关闭同时清除广播端口,这样就不会重试打开
|
||||
_commModuleManager.CloseResendRtcmserial(true);
|
||||
btnBoardPortStr = "打开广播端口";
|
||||
BoardPortStatusStr = _commModuleManager.BoardPortStatusStr;
|
||||
Message.BoardOpen(false);
|
||||
}
|
||||
else
|
||||
{ //打开广播端口
|
||||
|
||||
if ((SerialPortResend != null))
|
||||
{
|
||||
if (!_commModuleManager.OpenResendRtcmserial(SerialPortResend))
|
||||
{
|
||||
Alert.Show($"打开串口失败", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
else
|
||||
{
|
||||
btnBoardPortStr = "关闭广播端口";
|
||||
Message.BoardOpen(true);
|
||||
}
|
||||
BoardPortStatusStr = _commModuleManager.BoardPortStatusStr;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Alert.Show($"请选择需要广播的端口", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_rtcmInfoViewModel.SetRTKStatestr();
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private ICommand _SendCommand;
|
||||
public ICommand SendCommand
|
||||
{
|
||||
@ -86,7 +172,7 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
return _SendCommand ?? (_SendCommand = new RelayCommand(async () =>
|
||||
{
|
||||
await SendCommandAsync(CopterNum);
|
||||
await SendCommandAsync(CopterSum);
|
||||
}
|
||||
));
|
||||
}
|
||||
@ -125,13 +211,43 @@ namespace Plane.FormationCreator.ViewModels
|
||||
set { Set(nameof(CopterNum), ref _CopterNum, value); }
|
||||
}
|
||||
|
||||
private string _CopterColor = "";
|
||||
|
||||
|
||||
public float scale3d
|
||||
{
|
||||
get { return _copterManager.scale3d ; }
|
||||
set { _copterManager.scale3d = value;}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private int _CopterSum=100;
|
||||
public int CopterSum
|
||||
{
|
||||
get { return _CopterSum; }
|
||||
set { Set(nameof(CopterSum), ref _CopterSum, value); }
|
||||
}
|
||||
private string _CopterColor = "330033";
|
||||
public string CopterColor
|
||||
{
|
||||
get { return _CopterColor; }
|
||||
set { Set(nameof(CopterColor), ref _CopterColor, value); }
|
||||
}
|
||||
|
||||
private string _BoardPortStatusStr = "广播端口未打开";
|
||||
public string BoardPortStatusStr
|
||||
{
|
||||
get { return _BoardPortStatusStr; }
|
||||
set { Set(nameof(BoardPortStatusStr), ref _BoardPortStatusStr, value); }
|
||||
}
|
||||
|
||||
private string _btnBoardPortStr = "打开广播端口";
|
||||
public string btnBoardPortStr
|
||||
{
|
||||
get { return _btnBoardPortStr; }
|
||||
set { Set(nameof(btnBoardPortStr), ref _btnBoardPortStr, value); }
|
||||
}
|
||||
|
||||
private ICommand _WriteIdCommand;
|
||||
public ICommand WriteIdCommand
|
||||
{
|
||||
@ -213,6 +329,46 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}));
|
||||
}
|
||||
}
|
||||
private ICommand _ChangepasswordCommand;
|
||||
public ICommand ChangepasswordCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ChangepasswordCommand ?? (_ChangepasswordCommand = new RelayCommand( () =>
|
||||
{
|
||||
ChangePasswordView changePasswordView = new ChangePasswordView();
|
||||
changePasswordView.ShowDialog();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private ICommand _TestModuleCommand;
|
||||
public ICommand TestModuleCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _TestModuleCommand ?? (_TestModuleCommand = new RelayCommand(async () =>
|
||||
{
|
||||
await commModule.TestModule((short)scale3d);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ICommand _SetModulePowerCommand;
|
||||
public ICommand SetModulePowerCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SetModulePowerCommand ?? (_SetModulePowerCommand = new RelayCommand(async () =>
|
||||
{
|
||||
int mPower = int.Parse(CopterColor);
|
||||
await commModule.SetModulePower((short)CopterNum, (short)mPower);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private ICommand _CommDataAsync;
|
||||
public ICommand CommDataAsync
|
||||
@ -227,6 +383,27 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ICommand _TestPWMCommandAsync;
|
||||
public ICommand TestPWMCommandAsync
|
||||
{
|
||||
get
|
||||
{
|
||||
return _TestPWMCommandAsync ?? (_TestPWMCommandAsync = new RelayCommand(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
int channel = 10; //固定10是控制PWM舵机
|
||||
await commModule.TestFire((short)CopterNum, channel);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private ICommand _TestFireCommandAsync;
|
||||
public ICommand TestFireCommandAsync
|
||||
{
|
||||
@ -234,9 +411,15 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
return _TestFireCommandAsync ?? (_TestFireCommandAsync = new RelayCommand(async () =>
|
||||
{
|
||||
int channel = int.Parse(CopterColor);
|
||||
if (channel >= 0 && channel <= 4)
|
||||
await commModule.TestFire((short)CopterNum, channel);
|
||||
try
|
||||
{
|
||||
int channel = int.Parse(CopterColor);
|
||||
if (channel >= 0 && channel <= 4)
|
||||
await commModule.TestFire((short)CopterNum, channel);
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
}
|
||||
));
|
||||
}
|
||||
@ -251,7 +434,7 @@ namespace Plane.FormationCreator.ViewModels
|
||||
IMission LEDMission = Mission.CreateLEDControlMission(
|
||||
(int)(ledInfo.Delay * 10),
|
||||
ledInfo.LEDMode,
|
||||
ledInfo.LEDRate,
|
||||
ledInfo.LEDInterval,
|
||||
0, //ledInfo.LEDTimes,
|
||||
color.R,
|
||||
color.G,
|
||||
|
@ -21,6 +21,7 @@ using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Plane.Windows.Messages;
|
||||
using Plane.Collections;
|
||||
|
||||
namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
@ -92,6 +93,12 @@ namespace Plane.FormationCreator.ViewModels
|
||||
get { return _IntervalNum; }
|
||||
set { Set(nameof(IntervalNum), ref _IntervalNum, value); }
|
||||
}
|
||||
private int _RowNum;
|
||||
public int RowNum
|
||||
{
|
||||
get { return _RowNum; }
|
||||
set { Set(nameof(RowNum), ref _RowNum, value); }
|
||||
}
|
||||
|
||||
private int _ContinuousNum;
|
||||
public int ContinuousNum
|
||||
@ -110,6 +117,19 @@ namespace Plane.FormationCreator.ViewModels
|
||||
public ObservableCollection<string[]> CopterGroups { get; } = new ObservableCollection<string[]>();
|
||||
|
||||
|
||||
private int getNextcopterindex( int currindex)
|
||||
{
|
||||
//每行数量
|
||||
int colcount = _flightTaskManager.ColumnCount;
|
||||
int newind = currindex;
|
||||
for (int i = 0;i< IntervalNum;i++)
|
||||
{
|
||||
newind +=1;
|
||||
if ((newind % colcount) == 0)
|
||||
newind += RowNum * colcount;
|
||||
}
|
||||
return newind;
|
||||
}
|
||||
|
||||
private ICommand _IntervalSelectCoptersCommand;
|
||||
public ICommand IntervalSelectCoptersCommand
|
||||
@ -125,6 +145,21 @@ namespace Plane.FormationCreator.ViewModels
|
||||
_copterManager.Select(null);
|
||||
int index = _copterManager.Copters.IndexOf(copter);
|
||||
_copterManager.shiftkeydown = true;
|
||||
int colcount = _flightTaskManager.ColumnCount;
|
||||
|
||||
for (; index < _copterManager.Copters.Count; index= getNextcopterindex( index) )
|
||||
{
|
||||
for (int i = 0; i < ContinuousNum; i++)
|
||||
{
|
||||
if (index >= _copterManager.Copters.Count) break;
|
||||
_copterManager.Select(_copterManager.Copters[index]);
|
||||
index += 1;
|
||||
if ((index % colcount) == 0)
|
||||
index += RowNum * colcount;
|
||||
getNextcopterindex(index);
|
||||
}
|
||||
}
|
||||
/*
|
||||
for (; index < _copterManager.Copters.Count; index += IntervalNum)
|
||||
{
|
||||
for (int i = 0; i < ContinuousNum; i++)
|
||||
@ -134,6 +169,7 @@ namespace Plane.FormationCreator.ViewModels
|
||||
index++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
_copterManager.shiftkeydown = false;
|
||||
|
||||
}));
|
||||
@ -158,6 +194,44 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private ICommand _SortbyVIdCommand;
|
||||
public ICommand SortbyVIdCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SortbyVIdCommand ?? (_SortbyVIdCommand = new RelayCommand( () =>
|
||||
{
|
||||
_copterManager.SortType = CopterManager.CopterSortType.ByVID;
|
||||
//强制刷新飞机显示
|
||||
// _copterManager.Copters.ForEach(copter => copter.RefreashLoc());
|
||||
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ICommand _SortbyIdCommand;
|
||||
public ICommand SortbyIdCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SortbyIdCommand ?? (_SortbyVIdCommand = new RelayCommand(() =>
|
||||
{
|
||||
_copterManager.SortType = CopterManager.CopterSortType.ByID;
|
||||
|
||||
//强制刷新飞机显示
|
||||
// _copterManager.Copters.ForEach(copter => copter.RefreashLoc());
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private ICommand _ShowAllCoptersCommand;
|
||||
public ICommand ShowAllCoptersCommand
|
||||
@ -173,25 +247,31 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
bool showVirtualId = false;
|
||||
|
||||
private ICommand _SwitchIdVirtualIdCommand;
|
||||
public ICommand SwitchIdVirtualIdCommand
|
||||
|
||||
|
||||
private ICommand _ShowAllIDCommand;
|
||||
public ICommand ShowAllIDCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _SwitchIdVirtualIdCommand ?? (_SwitchIdVirtualIdCommand = new RelayCommand(async () =>
|
||||
return _ShowAllIDCommand ?? (_ShowAllIDCommand = new RelayCommand(() =>
|
||||
{
|
||||
showVirtualId = !showVirtualId;
|
||||
foreach (var copter in _copterManager.Copters)
|
||||
{
|
||||
copter.DisplayVirtualId = showVirtualId;
|
||||
}
|
||||
await Task.Delay(10);
|
||||
|
||||
_copterManager.SortType = CopterManager.CopterSortType.ByVIDShowAll;
|
||||
|
||||
//强制刷新飞机显示
|
||||
// _copterManager.Copters.ForEach(copter => copter.RefreashLoc());
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private ICommand _AddVirtualCopterCommand;
|
||||
public ICommand AddVirtualCopterCommand
|
||||
{
|
||||
@ -200,10 +280,10 @@ namespace Plane.FormationCreator.ViewModels
|
||||
return _AddVirtualCopterCommand ?? (_AddVirtualCopterCommand = new RelayCommand<int>(async addcount =>
|
||||
{
|
||||
//给第三方时候限制数量用
|
||||
if (_copterManager.Copters.Count() >= VersionControl.CopterUpperLimit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// if (_copterManager.Copters.Count() >= VersionControl.CopterUpperLimit)
|
||||
/// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
var center = _mapManager.Center;
|
||||
string id;
|
||||
@ -223,13 +303,14 @@ namespace Plane.FormationCreator.ViewModels
|
||||
|
||||
|
||||
//内蒙地区
|
||||
// if (center.Lat < 37.4307185218 || center.Lat > 45.6754821756
|
||||
// || center.Lng < 97.3493089056 || center.Lng > 115.8006783856)
|
||||
// return ;
|
||||
// if (center.Lat < 37.4307185218 || center.Lat > 45.6754821756
|
||||
// || center.Lng < 97.3493089056 || center.Lng > 115.8006783856)
|
||||
// return ;
|
||||
|
||||
|
||||
|
||||
LatLng? colLatLng = new LatLng(center.Lat, center.Lng); ;
|
||||
|
||||
|
||||
LatLng? colLatLng = new LatLng(center.Lat, center.Lng);
|
||||
|
||||
for (int i = 0; i < addcount; ++i, ++_virtualCopterId)
|
||||
{
|
||||
@ -247,7 +328,7 @@ namespace Plane.FormationCreator.ViewModels
|
||||
else
|
||||
{
|
||||
if (currcol < colnum)
|
||||
targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Value.Lat, colLatLng.Value.Lng , orientation + 90, currcol * coldis);
|
||||
targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(colLatLng.Value.Lat, colLatLng.Value.Lng , orientation + 90, (currcol * coldis));
|
||||
else
|
||||
{
|
||||
currrow++;
|
||||
@ -257,7 +338,17 @@ namespace Plane.FormationCreator.ViewModels
|
||||
|
||||
colheadLatLng = targetLatLng;
|
||||
}
|
||||
_lastVirtualCopterLocation= new LatLng(targetLatLng.Item1, targetLatLng.Item2);
|
||||
/*
|
||||
//随机位置,偏差40cm
|
||||
Random r1 = new Random();
|
||||
float rdrad= ((float)r1.Next(0, 360));
|
||||
float rddis = ((float)r1.Next(-40, 40) / 100.0f);
|
||||
|
||||
targetLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(targetLatLng.Item1, targetLatLng.Item2, rdrad, rddis);
|
||||
*/
|
||||
|
||||
|
||||
_lastVirtualCopterLocation = new LatLng(targetLatLng.Item1, targetLatLng.Item2);
|
||||
}
|
||||
currcol++;
|
||||
|
||||
@ -271,19 +362,28 @@ namespace Plane.FormationCreator.ViewModels
|
||||
*/
|
||||
|
||||
|
||||
|
||||
var copter = new FakeCopter(SynchronizationContext.Current);
|
||||
copter.SetProperties(
|
||||
latitude: _lastVirtualCopterLocation.Value.Lat,
|
||||
longitude: _lastVirtualCopterLocation.Value.Lng,
|
||||
id: id,
|
||||
name: id
|
||||
);
|
||||
await copter.ConnectAsync();
|
||||
await copter.GetCopterDataAsync();
|
||||
_copterManager.Copters.AddCopter(copter);
|
||||
_copterManager.CopterStatus.Add(false);
|
||||
if (_copterManager.EnAddCopter_Fake())
|
||||
{
|
||||
var copter = new FakeCopter(SynchronizationContext.Current);
|
||||
copter.SetProperties(
|
||||
latitude: _lastVirtualCopterLocation.Value.Lat,
|
||||
longitude: _lastVirtualCopterLocation.Value.Lng,
|
||||
id: id,
|
||||
name: id
|
||||
);
|
||||
if (_copterManager.FC_VER_NO >= 3)
|
||||
copter.FlightControlMode = 1;
|
||||
else copter.FlightControlMode = 0;
|
||||
//不再预先分配VID
|
||||
// copter.VirtualId = _virtualCopterId;
|
||||
await copter.ConnectAsync();
|
||||
await copter.GetCopterDataAsync();
|
||||
_copterManager.CopterStatus.Add(false);
|
||||
_copterManager.Copters.AddCopter(copter, _copterManager.SortType);
|
||||
}
|
||||
}
|
||||
if (_flightTaskManager.OriginLat == 0 && _flightTaskManager.OriginLng == 0)
|
||||
_flightTaskManager.SetOriginal();
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -356,6 +456,8 @@ namespace Plane.FormationCreator.ViewModels
|
||||
return _ClearCoptersCommand ?? (_ClearCoptersCommand = new RelayCommand(async () =>
|
||||
{
|
||||
_flightTaskManager.Pause();
|
||||
await _copterManager.ClearCopters();
|
||||
/*
|
||||
foreach (var copter in _copterManager.Copters)
|
||||
{
|
||||
await copter.DisconnectAsync();
|
||||
@ -363,12 +465,19 @@ namespace Plane.FormationCreator.ViewModels
|
||||
await Task.Delay(100); // 如果不等待一段时间,很可能会再触发 DataStreamReceived 事件导致飞行器重新出现在地图上。
|
||||
_copterManager.Copters.Clear();
|
||||
_copterManager.CopterStatus.Clear();
|
||||
*/
|
||||
|
||||
_mapManager.ClearCopters();
|
||||
_view3DManager.ClearCopters();
|
||||
_flightTaskManager.ClearTasks();
|
||||
//UdpServerConnectionManager.Instance.ClearConnections();
|
||||
// UdpServerConnectionManager.Instance.ClearConnections();
|
||||
|
||||
_virtualCopterId = 1;
|
||||
_lastVirtualCopterLocation = null;
|
||||
_flightTaskManager.OriginLat = 0;
|
||||
_flightTaskManager.OriginLng = 0;
|
||||
_flightTaskManager.ObserverLat = 0;
|
||||
_flightTaskManager.ObserverLng = 0;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
123
Plane.FormationCreator/ViewModels/LoginViewModel.cs
Normal file
@ -0,0 +1,123 @@
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using Plane.FormationCreator.Formation;
|
||||
using Plane.FormationCreator.Util;
|
||||
using Plane.FormationCreator.Views;
|
||||
using Plane.Util;
|
||||
using Plane.Windows.Messages;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interactivity;
|
||||
|
||||
namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains properties that a View can data bind to.
|
||||
/// <para>
|
||||
/// See http://www.galasoft.ch/mvvm
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public class LoginViewModel : ViewModelBase
|
||||
{
|
||||
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
private MainViewModel _MainViewModel=ServiceLocator.Current.GetInstance<MainViewModel>();
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LoginViewModel class.
|
||||
/// </summary>
|
||||
public LoginViewModel()
|
||||
{
|
||||
|
||||
Username = VersionControl.Username;
|
||||
SavePassword = VersionControl.IssavePassword;
|
||||
if (SavePassword)
|
||||
Password = VersionControl.Password;
|
||||
}
|
||||
|
||||
|
||||
private string _Username="";
|
||||
public string Username
|
||||
{
|
||||
get { return _Username; }
|
||||
set
|
||||
{
|
||||
Set(nameof(Username), ref _Username, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private string _Password = "";
|
||||
public string Password
|
||||
{
|
||||
get { return _Password; }
|
||||
set
|
||||
{
|
||||
Set(nameof(Password), ref _Password, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool _SavePassword = false;
|
||||
public bool SavePassword
|
||||
{
|
||||
get { return _SavePassword; }
|
||||
set
|
||||
{
|
||||
Set(nameof(SavePassword), ref _SavePassword, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private ICommand _ExitCommand;
|
||||
public ICommand ExitCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ExitCommand ?? (_ExitCommand = new RelayCommand<LoginView>(wd =>
|
||||
{
|
||||
if (wd != null)
|
||||
{
|
||||
wd.Close();
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
private ICommand _LoginCommand;
|
||||
public ICommand LoginCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _LoginCommand ?? (_LoginCommand = new RelayCommand<LoginView>(wd =>
|
||||
{
|
||||
if (Username.Trim() == "")
|
||||
{
|
||||
Alert.Show("请输入账号!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Password == "")
|
||||
{
|
||||
Alert.Show("请输入密码!", "登录提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
_copterManager.NetLogoin(Username.Trim(), Password, SavePassword);
|
||||
if (!SavePassword) Password = "";
|
||||
wd.Close();
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -14,6 +14,11 @@ using Microsoft.Practices.ServiceLocation;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using Plane.Geography;
|
||||
using Plane.FormationCreator.Views;
|
||||
using System.Windows;
|
||||
using Plane.Collections;
|
||||
using Plane.Copters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
@ -23,12 +28,22 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
_copterListViewModel = copterListViewModel;
|
||||
|
||||
//状态信息
|
||||
Plane.Windows.Messages.Message.ConfigureStatus(showAction: msg => this.SysStatusText = msg);
|
||||
//日志信息
|
||||
Plane.Windows.Messages.Message.Configure(showAction: msg => this.Message = msg);
|
||||
//连接信息
|
||||
Plane.Windows.Messages.Message.Configure(connectAction: connected => this.CommunicationModuleConnected = connected);
|
||||
|
||||
//广播是否打开
|
||||
Plane.Windows.Messages.Message.Configureboard(boardportAction: opened => this.BoardcastPortOpened = opened);
|
||||
|
||||
|
||||
this.SwitchVelocityModeButtonContent = GetSwitchVelocityModeButtonContent();
|
||||
|
||||
AppEx.Current.PropertyChanged += AppEx_PropertyChanged;
|
||||
_copterManager.netStatusChanged += CopterManagernetStatusChanged;
|
||||
ControlPanelViewModelData = ServiceLocator.Current.GetInstance<ControlPanelViewModel>();
|
||||
}
|
||||
|
||||
private CopterListViewModel _copterListViewModel;
|
||||
@ -39,6 +54,8 @@ namespace Plane.FormationCreator.ViewModels
|
||||
|
||||
public AppEx AppEx { get; } = AppEx.Current;
|
||||
|
||||
|
||||
|
||||
private void AppEx_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
@ -51,6 +68,14 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private void CopterManagernetStatusChanged(bool Logined, string status)
|
||||
{
|
||||
Loginstate = status;
|
||||
if (Logined)
|
||||
LoginDisp = "注销";
|
||||
else LoginDisp = "登录";
|
||||
}
|
||||
|
||||
private string _SwitchVelocityModeButtonContent;
|
||||
public string SwitchVelocityModeButtonContent
|
||||
{
|
||||
@ -68,6 +93,18 @@ namespace Plane.FormationCreator.ViewModels
|
||||
Logs += (Environment.NewLine + value);
|
||||
}
|
||||
}
|
||||
private ControlPanelViewModel _controlPanelViewModelData;
|
||||
|
||||
public ControlPanelViewModel ControlPanelViewModelData
|
||||
{
|
||||
get { return _controlPanelViewModelData; }
|
||||
set
|
||||
{
|
||||
Set(nameof(ControlPanelViewModelData), ref _controlPanelViewModelData, value);
|
||||
}
|
||||
}
|
||||
|
||||
// public ControlPanelViewModel ControlPanelViewModelData = ServiceLocator.Current.GetInstance<ControlPanelViewModel>();
|
||||
|
||||
private bool _CommunicationModuleConnected;
|
||||
public bool CommunicationModuleConnected
|
||||
@ -79,6 +116,29 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool _BoardcastPortOpened=false;
|
||||
public bool BoardcastPortOpened
|
||||
{
|
||||
get { return _BoardcastPortOpened; }
|
||||
set
|
||||
{
|
||||
Set(nameof(BoardcastPortOpened), ref _BoardcastPortOpened, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string _SysStatusText="系统信息";
|
||||
public string SysStatusText
|
||||
{
|
||||
get { return _SysStatusText; }
|
||||
set
|
||||
{
|
||||
Set(nameof(SysStatusText), ref _SysStatusText, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<string> _MessageList = new List<string>();
|
||||
|
||||
public string Messages
|
||||
@ -140,6 +200,75 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private string _Loginstate = "未登录";
|
||||
public string Loginstate
|
||||
{
|
||||
get { return _copterManager.Loginstate ; }
|
||||
set
|
||||
{
|
||||
Set(nameof(Loginstate), ref _Loginstate, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ICommand _LoginCommand;
|
||||
public ICommand LoginCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _LoginCommand ?? (_LoginCommand = new RelayCommand(() =>
|
||||
{
|
||||
|
||||
if (!_copterManager.Logined)
|
||||
{
|
||||
LoginView loginview = new LoginView();
|
||||
loginview.ShowDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_copterManager.Copters.Count() > 0)
|
||||
{
|
||||
if (Alert.Show("注销将导致飞机全部清除,您确定要继续吗?", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Warning)
|
||||
== MessageBoxResult.Cancel)
|
||||
return;
|
||||
}
|
||||
_copterListViewModel.ClearCoptersCommand.Execute(null);
|
||||
_copterManager.NetLogout();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
private ICommand _ShowModifyTaskViewCommand;
|
||||
public ICommand ShowModifyTaskViewCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ShowModifyTaskViewCommand ?? (_ShowModifyTaskViewCommand = new RelayCommand(() =>
|
||||
{
|
||||
AppEx.Current.ShowModifyTaskView = true;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private ICommand _HideModifyTaskViewCommand;
|
||||
public ICommand HideModifyTaskViewCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _HideModifyTaskViewCommand ?? (_HideModifyTaskViewCommand = new RelayCommand(() =>
|
||||
{
|
||||
AppEx.Current.ShowModifyTaskView =false;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ICommand _ShowOrHideModifyTaskViewCommand;
|
||||
public ICommand ShowOrHideModifyTaskViewCommand
|
||||
@ -160,6 +289,72 @@ namespace Plane.FormationCreator.ViewModels
|
||||
set { Set(nameof(MapMode), ref _MapMode, value); }
|
||||
}
|
||||
|
||||
private bool _b2DMapMode = true;
|
||||
public bool b2DMapMode
|
||||
{
|
||||
get { return _b2DMapMode; }
|
||||
set { Set(nameof(b2DMapMode), ref _b2DMapMode, value); }
|
||||
}
|
||||
|
||||
|
||||
private string _LoginDisp = "登录";
|
||||
public string LoginDisp
|
||||
{
|
||||
get { return _LoginDisp; }
|
||||
set { Set(nameof(LoginDisp), ref _LoginDisp, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
private ICommand _Map2DCommand;
|
||||
public ICommand Map2DCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Map2DCommand ?? (_Map2DCommand = new RelayCommand(() =>
|
||||
{
|
||||
MainWindow mainw = (MainWindow)App.Current.MainWindow;
|
||||
|
||||
mainw.map.Visibility = System.Windows.Visibility.Visible;
|
||||
mainw.map3D.Visibility = System.Windows.Visibility.Collapsed;
|
||||
MapMode = 0;
|
||||
b2DMapMode = true;
|
||||
_flightTaskManager.TaskRun_2D = b2DMapMode; //2D模式模拟显示
|
||||
//强制刷新飞机位置
|
||||
_copterManager.Copters.ForEach(copter => copter.RefreashLoc());
|
||||
|
||||
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private ICommand _Map3DCommand;
|
||||
public ICommand Map3DCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Map3DCommand ?? (_Map3DCommand = new RelayCommand(() =>
|
||||
{
|
||||
MainWindow mainw = (MainWindow)App.Current.MainWindow;
|
||||
mainw.map.Visibility = System.Windows.Visibility.Collapsed;
|
||||
mainw.map3D.Visibility = System.Windows.Visibility.Visible;
|
||||
MapMode = 1;
|
||||
b2DMapMode = false;
|
||||
_flightTaskManager.TaskRun_2D = b2DMapMode; //3D模式模拟显示
|
||||
mainw.map3D.ResetCamera();
|
||||
|
||||
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private ICommand _ChangeMapModeCommand;
|
||||
public ICommand ChangeMapModeCommand
|
||||
{
|
||||
@ -167,10 +362,29 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
return _ChangeMapModeCommand ?? (_ChangeMapModeCommand = new RelayCommand(() =>
|
||||
{
|
||||
MainWindow mainw =(MainWindow) App.Current.MainWindow;
|
||||
if (MapMode == 0)
|
||||
{
|
||||
mainw.map.Visibility = System.Windows.Visibility.Collapsed;
|
||||
mainw.map3D.Visibility = System.Windows.Visibility.Visible;
|
||||
MapMode = 1;
|
||||
b2DMapMode = false;
|
||||
_flightTaskManager.TaskRun_2D = b2DMapMode; //3D模式模拟显示
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
mainw.map.Visibility = System.Windows.Visibility.Visible;
|
||||
mainw.map3D.Visibility = System.Windows.Visibility.Collapsed;
|
||||
MapMode = 0;
|
||||
b2DMapMode = true;
|
||||
_flightTaskManager.TaskRun_2D = b2DMapMode; //2D模式模拟显示
|
||||
}
|
||||
//强制刷新飞机位置
|
||||
_copterManager.Copters.ForEach(copter => copter.RefreashLoc());
|
||||
|
||||
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -183,6 +397,22 @@ namespace Plane.FormationCreator.ViewModels
|
||||
set { Set(nameof(OnlyImpotWaypointS), ref _OnlyImpotWaypointS, value); }
|
||||
}
|
||||
|
||||
//导入飞机的位置
|
||||
private bool _isimpCopterLoc =true;
|
||||
public bool isimpCopterLoc
|
||||
{
|
||||
get { return _isimpCopterLoc; }
|
||||
set { Set(nameof(isimpCopterLoc), ref _isimpCopterLoc, value); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//导出飞机和航点等
|
||||
private ICommand _ExportTasksCommand;
|
||||
public ICommand ExportTasksCommand
|
||||
{
|
||||
@ -195,7 +425,7 @@ namespace Plane.FormationCreator.ViewModels
|
||||
Alert.Show("作为参照的原点未设置,无法导出相对位置!", "提示");
|
||||
return;
|
||||
}
|
||||
|
||||
bool isToMeter = false;
|
||||
var dialog = new SaveFileDialog
|
||||
{
|
||||
DefaultExt = "fcgm",
|
||||
@ -205,11 +435,16 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
IEnumerable<object> taskObject;
|
||||
string extension = Path.GetExtension(dialog.FileName);
|
||||
if (extension == ".fcgm")
|
||||
isToMeter = (extension == ".fcgm");
|
||||
|
||||
if (isToMeter)
|
||||
taskObject = _flightTaskManager.ExportTasksToMeter();
|
||||
else
|
||||
taskObject = _flightTaskManager.ExportTasks();
|
||||
|
||||
|
||||
|
||||
|
||||
string exportedText;
|
||||
|
||||
if (OnlyImpotWaypointS)
|
||||
@ -219,11 +454,15 @@ namespace Plane.FormationCreator.ViewModels
|
||||
else
|
||||
{
|
||||
var groupObject = _groupManager.ExportGroups();
|
||||
var locateObject = ExportLocate();
|
||||
|
||||
var locateObject = ExportLocate(isToMeter);
|
||||
|
||||
|
||||
object obj = new
|
||||
{
|
||||
ID="flycube.com",
|
||||
ver = "2.0",
|
||||
coptercount = _copterManager.Copters.Count,
|
||||
taskcount = _flightTaskManager.Tasks.Count,
|
||||
groups = groupObject,
|
||||
locate = locateObject,
|
||||
tasks = taskObject
|
||||
@ -240,21 +479,41 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private List<object> ExportLocate()
|
||||
private List<object> ExportLocate(bool isToMeter)
|
||||
{
|
||||
List<object> locateList = new List<object>();
|
||||
foreach (var copter in _copterManager.Copters)
|
||||
{
|
||||
double[] locate = new double[3];
|
||||
locate[0] = copter.Latitude - _flightTaskManager.OriginLat;
|
||||
locate[1] = copter.Longitude - _flightTaskManager.OriginLng;
|
||||
|
||||
if (isToMeter)
|
||||
{
|
||||
double x = GeographyUtils.CalcDistance(_flightTaskManager.OriginLat, _flightTaskManager.OriginLng, 0,
|
||||
_flightTaskManager.OriginLat, copter.Longitude, 0);
|
||||
if (copter.Longitude < _flightTaskManager.OriginLng) x = -x;
|
||||
|
||||
|
||||
double y = GeographyUtils.CalcDistance(_flightTaskManager.OriginLat, _flightTaskManager.OriginLng, 0,
|
||||
copter.Latitude, _flightTaskManager.OriginLng, 0);
|
||||
if (copter.Latitude < _flightTaskManager.OriginLat) y = -y;
|
||||
|
||||
locate[0] = x;
|
||||
locate[1] = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
//为了和老版本兼容
|
||||
locate[1] = copter.Longitude - _flightTaskManager.OriginLng;
|
||||
locate[0] = copter.Latitude - _flightTaskManager.OriginLat;
|
||||
}
|
||||
|
||||
|
||||
locate[2] = copter.GroundAlt;
|
||||
locateList.Add(locate);
|
||||
}
|
||||
return locateList;
|
||||
}
|
||||
|
||||
|
||||
private int _txtStarindex = 0;
|
||||
public int txtStarindex
|
||||
{
|
||||
@ -269,6 +528,7 @@ namespace Plane.FormationCreator.ViewModels
|
||||
set { Set(nameof(txtendindex), ref _txtendindex, value); }
|
||||
}
|
||||
|
||||
//导入航点
|
||||
private ICommand _ImportTasksCommand;
|
||||
public ICommand ImportTasksCommand
|
||||
{
|
||||
@ -290,7 +550,8 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
|
||||
|
||||
|
||||
string extension = Path.GetExtension(dialog.FileName);
|
||||
bool isMeter = extension == ".fcgm";
|
||||
int _startindex = txtStarindex;
|
||||
int _endindex = txtendindex;
|
||||
|
||||
@ -300,10 +561,31 @@ namespace Plane.FormationCreator.ViewModels
|
||||
dynamic taskinfo = null;
|
||||
if (importInfo is Newtonsoft.Json.Linq.JObject)
|
||||
{
|
||||
int ? filecoptercount = importInfo.coptercount;
|
||||
string ver = importInfo.ver;
|
||||
string ID = importInfo.ID;
|
||||
if ((ID!=null)&&(ID!="flycube.com"))
|
||||
{
|
||||
Alert.Show($"文件格式不正确", "提示");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ((filecoptercount != null)&&(filecoptercount != _copterManager.Copters.Count ))
|
||||
{
|
||||
Alert.Show($"导入的飞机数量不符!导入飞机{filecoptercount},实际飞机{ _copterManager.Copters.Count}", "提示");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
taskinfo = importInfo.tasks;
|
||||
if (importInfo.locate != null)
|
||||
{
|
||||
ImportCoptersLocate(importInfo.locate);
|
||||
//老版本无论是fcgm还是fcg格式这个地方都存的经纬差,新版fcgm才用米为单位保存
|
||||
if ((ver != null) && (ver == "2.0"))
|
||||
ImportCoptersLocate(importInfo.locate, isMeter);
|
||||
else
|
||||
ImportCoptersLocate(importInfo.locate, false);
|
||||
}
|
||||
if (importInfo.groups != null)
|
||||
{
|
||||
@ -317,9 +599,22 @@ namespace Plane.FormationCreator.ViewModels
|
||||
|
||||
//int task Newtonsoft.Json.Linq.JArray
|
||||
|
||||
string extension = Path.GetExtension(dialog.FileName);
|
||||
bool isMeter = extension == ".fcgm";
|
||||
|
||||
|
||||
if (taskinfo.Count == 0)
|
||||
{
|
||||
|
||||
Alert.Show($"导入的文件没有飞行任务!", "提示");
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
if ((taskinfo[0].singleCopterInfos.Count != _copterManager.Copters.Count))
|
||||
{
|
||||
Alert.Show($"导入的飞机数量不符!导入飞机{taskinfo[0].singleCopterInfos.Count},实际飞机{ _copterManager.Copters.Count}", "提示");
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ((txtStarindex == 0) && (txtendindex == 0))
|
||||
{
|
||||
@ -337,6 +632,7 @@ namespace Plane.FormationCreator.ViewModels
|
||||
|
||||
|
||||
}
|
||||
// Alert.Show("导入完成!", "提示");
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -410,16 +706,54 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private void ImportCoptersLocate(dynamic coptersLocate)
|
||||
|
||||
private void ImportCoptersLocate(dynamic coptersLocate,bool isMeter)
|
||||
{
|
||||
//if (Newtonsoft.Json.Linq.JArray)
|
||||
try
|
||||
{
|
||||
int index = 0;
|
||||
bool loadxyLocate = isimpCopterLoc;
|
||||
foreach (var locate in coptersLocate)
|
||||
{
|
||||
_copterManager.Copters[index].GroundAlt = Convert.ToSingle(locate[2]);
|
||||
//虚拟飞机将读入保存时的位置
|
||||
if (loadxyLocate&&(_copterManager.Copters[index] is FakeCopter))
|
||||
{
|
||||
var fc = _copterManager.Copters[index] as FakeCopter;
|
||||
if (isMeter)
|
||||
{
|
||||
Tuple<double, double> observationLatLng = null;
|
||||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||||
_flightTaskManager.OriginLat,
|
||||
_flightTaskManager.OriginLng,
|
||||
90,
|
||||
Convert.ToSingle(locate[0]));
|
||||
double TargetLng = observationLatLng.Item2;
|
||||
|
||||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||||
_flightTaskManager.OriginLat,
|
||||
_flightTaskManager.OriginLng,
|
||||
0,
|
||||
Convert.ToSingle(locate[1]));
|
||||
double TargetLat = observationLatLng.Item1;
|
||||
|
||||
|
||||
fc.SetProperties(
|
||||
latitude: TargetLat,
|
||||
longitude: TargetLng
|
||||
);
|
||||
}else
|
||||
{
|
||||
double TargetLng = _flightTaskManager.OriginLng + Convert.ToSingle(locate[1]);
|
||||
double TargetLat = _flightTaskManager.OriginLat + Convert.ToSingle(locate[0]);
|
||||
fc.SetProperties(
|
||||
latitude:TargetLat,
|
||||
longitude: TargetLng
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
index++;
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using Plane.CommunicationManagement;
|
||||
using Plane.FormationCreator.Formation;
|
||||
using Plane.Windows.Messages;
|
||||
using System;
|
||||
@ -8,6 +10,7 @@ using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Plane.FormationCreator.ViewModels
|
||||
@ -17,9 +20,41 @@ namespace Plane.FormationCreator.ViewModels
|
||||
private RtcmManager _rtcmManager;
|
||||
|
||||
public RtcmManager RtcmManager { get { return _rtcmManager; } }
|
||||
|
||||
//方式
|
||||
public ObservableCollection<string> serialPorts { get; } = new ObservableCollection<string>();
|
||||
|
||||
private CommModuleManager _commModuleManager = CommModuleManager.Instance;
|
||||
|
||||
public string BoardPortsStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
return _commModuleManager.BoardPortStatusStr;
|
||||
}
|
||||
}
|
||||
private ControlPanelViewModel ControlPanelVM = ServiceLocator.Current.GetInstance<ControlPanelViewModel>();
|
||||
public void SetRTKStatestr()
|
||||
{
|
||||
string rtksstr = "";
|
||||
// ResendToCom
|
||||
if (_rtcmManager.Rtcmthreadrun)
|
||||
{
|
||||
rtksstr = "RTK发送中 ";
|
||||
|
||||
if (_rtcmManager.SmallRtcmData)
|
||||
rtksstr += ",低带宽模式 ";
|
||||
if (_rtcmManager.ResendToCom && _commModuleManager.Recomisopen)
|
||||
rtksstr += ",双通道模式 ";
|
||||
rtksstr += "...";
|
||||
}
|
||||
else
|
||||
rtksstr = "RTK未发送";
|
||||
|
||||
ControlPanelVM.RTKState = rtksstr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private string _serialPortsSelectdValue;
|
||||
public string SerialPortsSelectdValue
|
||||
{
|
||||
@ -29,15 +64,57 @@ namespace Plane.FormationCreator.ViewModels
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private bool _smalldatamk;
|
||||
public bool SmalldataMK
|
||||
{
|
||||
get { return _smalldatamk; }
|
||||
set
|
||||
{
|
||||
Set(nameof(SmalldataMK), ref _smalldatamk, value);
|
||||
_rtcmManager.SmallRtcmData= value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _resendtocommk=true;
|
||||
public bool ResendToComMK
|
||||
{
|
||||
get { return _resendtocommk; }
|
||||
set
|
||||
{
|
||||
|
||||
if (value)
|
||||
{
|
||||
//发送
|
||||
if (_commModuleManager.last_reserialport == "")
|
||||
{
|
||||
Alert.Show($"先在设置里打开广播端口", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}else
|
||||
if (!_commModuleManager.Recomisopen)
|
||||
{
|
||||
Alert.Show($"广播端口未打开,无法发送", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
|
||||
}
|
||||
Set(nameof(ResendToComMK), ref _resendtocommk, value);
|
||||
_rtcmManager.ResendToCom = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public RtcmInfoViewModel(RtcmManager rtcmManager)
|
||||
{
|
||||
_rtcmManager = rtcmManager;
|
||||
serialPorts.Add("魔方基站");
|
||||
serialPorts.Add("千寻");
|
||||
|
||||
string[] commports = _rtcmManager.GetPortNames();
|
||||
foreach (var item in commports)
|
||||
{
|
||||
serialPorts.Add(item);
|
||||
}
|
||||
serialPorts.Add("千寻");
|
||||
SerialPortsSelectdValue = serialPorts[0];
|
||||
}
|
||||
|
||||
@ -47,12 +124,13 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
string lastSelectValue = SerialPortsSelectdValue;
|
||||
serialPorts.Clear();
|
||||
serialPorts.Add("魔方基站");
|
||||
serialPorts.Add("千寻");
|
||||
string[] commports = _rtcmManager.GetPortNames();
|
||||
foreach (var item in commports)
|
||||
{
|
||||
serialPorts.Add(item);
|
||||
}
|
||||
serialPorts.Add("千寻");
|
||||
if (serialPorts.Contains(lastSelectValue))
|
||||
SerialPortsSelectdValue = lastSelectValue;
|
||||
}
|
||||
@ -64,10 +142,13 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
return _ConnectRtcmCommand ?? (_ConnectRtcmCommand = new RelayCommand(async() =>
|
||||
{
|
||||
//是否转发到特定端口
|
||||
string resendserial = "";
|
||||
_rtcmManager.ResendToCom = ResendToComMK;
|
||||
if (!_rtcmManager.Rtcmthreadrun)
|
||||
await _rtcmManager.Open(SerialPortsSelectdValue);
|
||||
else
|
||||
await _rtcmManager.Close();
|
||||
await _rtcmManager.Close(SerialPortsSelectdValue);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@ -42,8 +42,9 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
get
|
||||
{
|
||||
return _ClearTasksCommand ?? (_ClearTasksCommand = new RelayCommand(() =>
|
||||
return _ClearTasksCommand ?? (_ClearTasksCommand = new RelayCommand(async () =>
|
||||
{
|
||||
await _flightTaskManager.ResetTasks();
|
||||
_flightTaskManager.ClearTasks();
|
||||
}));
|
||||
}
|
||||
@ -65,6 +66,54 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private ICommand _renametaskCommand;
|
||||
public ICommand renametaskCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _renametaskCommand ?? (_renametaskCommand = new RelayCommand( () =>
|
||||
{
|
||||
|
||||
FlightTask task = _flightTaskManager.SelectedTask;
|
||||
if ((task==null) ||(task.TaskType != FlightTaskType.FlyTo)) return;
|
||||
|
||||
string newName = task.TaskCnName;
|
||||
if (PlaneMessageBox.OnShow("请输入新的名称", "重命名", ref newName))
|
||||
{
|
||||
task.TaskCnName = newName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private ICommand _DelTaskCommand;
|
||||
public ICommand DelTaskCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _DelTaskCommand ?? (_DelTaskCommand = new RelayCommand(() =>
|
||||
{
|
||||
// _flightTaskManager
|
||||
// FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
|
||||
_flightTaskManager.DelSelectedTask();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private ICommand _SetOriginCommand;
|
||||
public ICommand SetOriginCommand
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ namespace Plane.FormationCreator.ViewModels
|
||||
{
|
||||
private FlightTaskManager _flightTaskManager;
|
||||
private CopterManager _copterManager;
|
||||
|
||||
|
||||
private View3DManager _view3DManager = ServiceLocator.Current.GetInstance<View3DManager>();
|
||||
|
||||
public View3DViewModel(FlightTaskManager flightTaskManager, CopterManager copterManager)
|
||||
@ -51,6 +51,16 @@ namespace Plane.FormationCreator.ViewModels
|
||||
case nameof(FlightTaskManager.SelectedTaskIndex):
|
||||
SelectTask();
|
||||
break;
|
||||
case nameof(FlightTaskManager.RightSelectedTaskIndex): // 单击右键触发清除航点
|
||||
|
||||
int taskIndexTmp = Math.Abs(_flightTaskManager.RightSelectedTaskIndex);
|
||||
if (_flightTaskManager.Tasks[taskIndexTmp].IsRightSelected)
|
||||
{
|
||||
if (waypointGroup == null) waypointGroup = new Model3DGroup();
|
||||
waypointGroup.Children.Clear();
|
||||
}
|
||||
else SelectTask();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -83,6 +93,7 @@ namespace Plane.FormationCreator.ViewModels
|
||||
planeModel3Ds.Clear();
|
||||
planeGroup.Children.Clear();
|
||||
observationLatLng = null;
|
||||
SelectTask();
|
||||
}
|
||||
|
||||
private void Copter_LocationChanged(object sender, EventArgs e)
|
||||
@ -99,64 +110,88 @@ namespace Plane.FormationCreator.ViewModels
|
||||
}
|
||||
|
||||
private Dictionary<ICopter, GeometryModel3D> planeModel3Ds = new Dictionary<ICopter, GeometryModel3D>();
|
||||
Tuple<double, double> observationLatLng = null;
|
||||
private Tuple<double, double> observationLatLng = null;
|
||||
|
||||
private void AddOrMove3DCopter(ICopter copter)
|
||||
//得到观测位置
|
||||
//observationLatLng 观察点坐标,第一列的中间再往前2个中间距离)
|
||||
//观测点的位置放到最后排飞机的中间位置
|
||||
private void getobservationpos()
|
||||
{
|
||||
//var copternum1 = _copterManager.Copters.FirstOrDefault();
|
||||
if (_flightTaskManager.OriginLat == 0 || _flightTaskManager.OriginLng == 0)
|
||||
return;
|
||||
observationLatLng = new Tuple<double, double>(_flightTaskManager.ObserverLat, _flightTaskManager.ObserverLng);
|
||||
/*
|
||||
|
||||
//第一列到中间的距离
|
||||
float midColDistance = (_flightTaskManager.ColumnCount - 1) * _flightTaskManager.ColumnDistance / 2;
|
||||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||||
_flightTaskManager.OriginLat,
|
||||
_flightTaskManager.OriginLng,
|
||||
_flightTaskManager.Orientation + 90,
|
||||
midColDistance);
|
||||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||||
observationLatLng.Item1,
|
||||
observationLatLng.Item2,
|
||||
_flightTaskManager.Orientation + 180,
|
||||
midColDistance * 4);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
private void AddOrMove3DCopter(ICopter copter)
|
||||
{
|
||||
if (_flightTaskManager.TaskRun_2D) return; //不在3D模式运行直接退出
|
||||
//var copternum1 = _copterManager.Copters.FirstOrDefault();
|
||||
if (_flightTaskManager.OriginLat == 0 || _flightTaskManager.OriginLng == 0)
|
||||
return;
|
||||
//得到观测位置
|
||||
if (observationLatLng == null)
|
||||
{
|
||||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||||
_flightTaskManager.OriginLat,
|
||||
_flightTaskManager.OriginLng,
|
||||
_flightTaskManager.Orientation + 90,
|
||||
midColDistance);
|
||||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||||
observationLatLng.Item1,
|
||||
observationLatLng.Item2,
|
||||
_flightTaskManager.Orientation + 180,
|
||||
midColDistance * 2);
|
||||
getobservationpos();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//没有这架飞机就加入
|
||||
if (!planeModel3Ds.ContainsKey(copter))
|
||||
{
|
||||
|
||||
//观测点的位置放到最后排飞机的中间位置
|
||||
|
||||
var meshBuilderwaypoint = new MeshBuilder(false, false);
|
||||
|
||||
//meshBuilderwaypoint.AddTriangle(new Point3D(-0.1, -0.1, 0), new Point3D(0.1, -0.1, 0), new Point3D(0, 0.2, 0));
|
||||
meshBuilderwaypoint.AddSphere(new Point3D(0, 0, 0), 0.2);
|
||||
//飞机点的大小形状
|
||||
meshBuilderwaypoint.AddSphere(new Point3D(0, 0, 0), 0.3* _copterManager.scale3d);
|
||||
var meshwaypoint = meshBuilderwaypoint.ToMesh(true);
|
||||
|
||||
//离观测点距离y
|
||||
double y = GeographyUtils.CalcDistance(0, observationLatLng.Item1, 0, 0, copter.Latitude, 0) / 2;
|
||||
if (observationLatLng.Item1 > copter.Latitude) y = -y;
|
||||
|
||||
//离观测点距离x
|
||||
double x = GeographyUtils.CalcDistance(observationLatLng.Item2, 0, 0, copter.Longitude, 0, 0) / 2;
|
||||
if (observationLatLng.Item2 > copter.Longitude) x = -x;
|
||||
//离观测点距离z
|
||||
double z = copter.Altitude + 0.1;
|
||||
|
||||
|
||||
|
||||
x *= _copterManager.scale3d;
|
||||
y *= _copterManager.scale3d;
|
||||
z *= _copterManager.scale3d;
|
||||
Color color ;
|
||||
if (copter.LEDColor != null && copter.LEDColor != "")
|
||||
color = (Color)ColorConverter.ConvertFromString("#" + copter.LEDColor);
|
||||
else
|
||||
color = (Color)ColorConverter.ConvertFromString("#" + CopterManager.CopterDefaultColor);
|
||||
var model3D = new GeometryModel3D
|
||||
{
|
||||
Geometry = meshwaypoint,
|
||||
Transform = new TranslateTransform3D(x, y, copter.Altitude + 0.1),
|
||||
Material = MaterialHelper.CreateMaterial(Color.FromRgb(238, 210, 238)),
|
||||
BackMaterial = MaterialHelper.CreateMaterial(Color.FromRgb(238, 210, 238))
|
||||
Transform = new TranslateTransform3D(x, y, z),
|
||||
Material = new DiffuseMaterial(new SolidColorBrush(color)),
|
||||
//Material = MaterialHelper.CreateMaterial(color),
|
||||
// BackMaterial = MaterialHelper.CreateMaterial(color)
|
||||
};
|
||||
|
||||
planeModel3Ds.Add(copter, model3D);
|
||||
planeGroup.Children.Add(model3D);
|
||||
}
|
||||
//有飞机在视图里就移动位置
|
||||
else
|
||||
{
|
||||
|
||||
//计算和观测点的相对位置
|
||||
double y = GeographyUtils.CalcDistance(0, observationLatLng.Item1, 0, 0, copter.Latitude, 0) / 2;
|
||||
if (observationLatLng.Item1 > copter.Latitude) y = -y;
|
||||
|
||||
@ -167,51 +202,69 @@ namespace Plane.FormationCreator.ViewModels
|
||||
x = Math.Round(x, 2);//按照四舍五入的国际标准
|
||||
y = Math.Round(y, 2);
|
||||
double z = Math.Round(copter.Altitude / 2, 2);
|
||||
x *= _copterManager.scale3d;
|
||||
y *= _copterManager.scale3d;
|
||||
z *= _copterManager.scale3d;
|
||||
|
||||
//移动飞机到新位置
|
||||
GeometryModel3D panle3D = planeModel3Ds[copter];
|
||||
|
||||
|
||||
if (x != panle3D.Transform.Value.OffsetX || y != panle3D.Transform.Value.OffsetY || z != panle3D.Transform.Value.OffsetZ)
|
||||
{
|
||||
panle3D.Transform = new TranslateTransform3D(x, y, z);
|
||||
var trans = panle3D.Transform as TranslateTransform3D;
|
||||
trans.OffsetX = x;
|
||||
trans.OffsetY = y;
|
||||
trans.OffsetZ = z;
|
||||
}
|
||||
|
||||
//设置灯光
|
||||
|
||||
Color color;
|
||||
if (copter.LEDColor != null && copter.LEDColor != "")
|
||||
{
|
||||
Color color = (Color)ColorConverter.ConvertFromString("#" + copter.LEDColor);
|
||||
color = (Color)ColorConverter.ConvertFromString("#" + copter.LEDColor);
|
||||
panle3D.Material = MaterialHelper.CreateMaterial(color);
|
||||
panle3D.BackMaterial = MaterialHelper.CreateMaterial(color);
|
||||
// panle3D.BackMaterial = MaterialHelper.CreateMaterial(color);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Color color;
|
||||
if (copter.LEDShowColor != null)
|
||||
{
|
||||
Color currcolor = System.Windows.Media.Color.FromArgb(
|
||||
copter.LEDShowColor.A, copter.LEDShowColor.R, copter.LEDShowColor.G, copter.LEDShowColor.B);
|
||||
|
||||
{
|
||||
((panle3D.Material as DiffuseMaterial).Brush as SolidColorBrush).Color = currcolor;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//Message.Show("添加3D飞机:" + copter.Name);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void SelectTask()
|
||||
{
|
||||
{
|
||||
if (waypointGroup == null) waypointGroup = new Model3DGroup();
|
||||
waypointGroup.Children.Clear();
|
||||
if (_flightTaskManager.SelectedTaskIndex > 0)
|
||||
{
|
||||
//观测点的位置放到最后排飞机的中间位置
|
||||
Tuple<double, double> observationLatLng;
|
||||
|
||||
//列的中间位置
|
||||
float midDistance = (_flightTaskManager.ColumnCount - 1) * _flightTaskManager.ColumnDistance / 2;
|
||||
|
||||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||||
_flightTaskManager.OriginLat, _flightTaskManager.OriginLng, _flightTaskManager.Orientation + 90, midDistance);
|
||||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||||
observationLatLng.Item1, observationLatLng.Item2, _flightTaskManager.Orientation + 180, midDistance * 2);
|
||||
//得到观测位置
|
||||
if (observationLatLng == null)
|
||||
{
|
||||
getobservationpos();
|
||||
}
|
||||
|
||||
//modelGroup.Children.Clear();
|
||||
|
||||
var meshBuilderwaypoint = new MeshBuilder(false, false);
|
||||
meshBuilderwaypoint.AddSphere(new Point3D(0, 0, 0), 0.2);
|
||||
//航点的大小形状
|
||||
meshBuilderwaypoint.AddSphere(new Point3D(0, 0, 0), 0.2* _copterManager.scale3d);
|
||||
var meshwaypoint = meshBuilderwaypoint.ToMesh(true);
|
||||
var greenMaterial = MaterialHelper.CreateMaterial(Color.FromRgb(0,255,0));
|
||||
var greenMaterial = MaterialHelper.CreateMaterial(Color.FromRgb(50,50,255));
|
||||
|
||||
foreach (FlightTaskSingleCopterInfo info in _flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].SingleCopterInfos)
|
||||
{
|
||||
@ -221,12 +274,16 @@ namespace Plane.FormationCreator.ViewModels
|
||||
|
||||
double x = GeographyUtils.CalcDistance(observationLatLng.Item2, 0, 0, info.TargetLng, 0, 0)/2;
|
||||
if (observationLatLng.Item2 > info.TargetLng) x = -x;
|
||||
double z = info.TargetAlt / 2;
|
||||
|
||||
x *= _copterManager.scale3d;
|
||||
y *= _copterManager.scale3d;
|
||||
z *= _copterManager.scale3d;
|
||||
|
||||
waypointGroup.Children.Add(new GeometryModel3D
|
||||
{
|
||||
Geometry = meshwaypoint,
|
||||
Transform = new TranslateTransform3D(x, y, info.TargetAlt/2),
|
||||
Transform = new TranslateTransform3D(x, y, z),
|
||||
Material = greenMaterial,
|
||||
BackMaterial = greenMaterial
|
||||
});
|
||||
|
@ -1,40 +1,44 @@
|
||||
<Window x:Class="Plane.FormationCreator.Views.CalibrationWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
mc:Ignorable="d"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="校准" Height="320" Width="450">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="70*"/>
|
||||
<RowDefinition Height="30*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Margin="10" >
|
||||
<Label Content="加速计" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
<WrapPanel HorizontalAlignment="Center">
|
||||
<Button Content="开始校准" Width="100" Margin="10, 0"
|
||||
Command="{Binding CalibrationAccelerometerStartCommand}"/>
|
||||
<Button Content="下一步" Width="100" Margin="10, 0"
|
||||
Command="{Binding CalibrationAccelerometerNextCommand}"/>
|
||||
</WrapPanel>
|
||||
<Label Margin="0,10" Content="亮紫色:飞机水平放置(Front) 亮黄色:飞机左侧接触地面竖立放置(Left) 亮青色:飞机右侧接触地面竖立放置(Right) 紫色:飞机机头向下接触地面竖立放置(Down) 黄色:飞机机尾向下接触地面竖立放置(Up) 青色:飞机翻过来水平放置(Back)" HorizontalContentAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1" Margin="10,0,10,10">
|
||||
<Label Content="指南针" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
<WrapPanel HorizontalAlignment="Center">
|
||||
<Button Content="开始校准" Width="100" Margin="10, 0"
|
||||
Command="{Binding CalibrationCompassCommand}"/>
|
||||
<Button Content="放弃校准" Width="100" Margin="10, 0"
|
||||
Command="{Binding CancelCalibrationCompassCommand}"/>
|
||||
</WrapPanel>
|
||||
<ProgressBar Margin="0,20" Height="18" Width="220" Value="{Binding CompassPercent, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
<Window x:Class="Plane.FormationCreator.Views.CalibrationWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
mc:Ignorable="d"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Title="校准" Height="329" Width="455">
|
||||
<Grid Margin="0,0,0,7">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="70*"/>
|
||||
<RowDefinition Height="30*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Margin="10" >
|
||||
<Label Content="加速计" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
<WrapPanel HorizontalAlignment="Center">
|
||||
<Button Content="开始校准" Width="100" Margin="10, 0"
|
||||
Command="{Binding CalibrationAccelerometerStartCommand}"/>
|
||||
<Button Content="下一步" Width="100" Margin="10, 0"
|
||||
Command="{Binding CalibrationAccelerometerNextCommand}"/>
|
||||
</WrapPanel>
|
||||
<Label Margin="0,10" Content="亮紫色:飞机水平放置(Front) 亮黄色:飞机左侧接触地面竖立放置(Left) 亮青色:飞机右侧接触地面竖立放置(Right) 紫色:飞机机头向下接触地面竖立放置(Down) 黄色:飞机机尾向下接触地面竖立放置(Up) 青色:飞机翻过来水平放置(Back)" HorizontalContentAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1" Margin="10,0,10,10">
|
||||
<Label Content="其他" Margin="0,0,0,10" FontWeight="Bold" FontSize="14"/>
|
||||
<WrapPanel HorizontalAlignment="Center">
|
||||
<Button Content="放弃校准" Width="100" Margin="10, 0"
|
||||
Command="{Binding CancelCalibrationCompassCommand}" Visibility="Collapsed"/>
|
||||
<Button Content="校准指南针" Width="120"
|
||||
Command="{Binding CalibrationCompassCommand}"/>
|
||||
<Button Content="校准陀螺仪" Width="120" Margin="20, 0"
|
||||
Command="{Binding CalibrationPreflightCommand}"/>
|
||||
<Button Content="重启飞控" Width="100" Margin="10, 0"
|
||||
Command="{Binding RestartFCCommand}"/>
|
||||
</WrapPanel>
|
||||
<ProgressBar Margin="0,20" Height="18" Width="220" Value="{Binding CompassPercent, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
77
Plane.FormationCreator/Views/ChangePasswordView.xaml
Normal file
@ -0,0 +1,77 @@
|
||||
<Window x:Class="Plane.FormationCreator.Views.ChangePasswordView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ignore="http://www.galasoft.ch/ignore"
|
||||
xmlns:Helper="clr-namespace:Plane.Util"
|
||||
mc:Ignorable="d ignore" Height="316.504" Width="490.433" Title="更改登录密码" ResizeMode="NoResize" WindowStartupLocation="CenterScreen"
|
||||
>
|
||||
|
||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto" />
|
||||
<RowDefinition Height="auto" />
|
||||
<RowDefinition Height="auto" />
|
||||
<RowDefinition Height="auto" />
|
||||
<RowDefinition Height="auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition></ColumnDefinition>
|
||||
<ColumnDefinition></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Content="账号:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" />
|
||||
|
||||
<TextBox
|
||||
Margin="10"
|
||||
Width="120" VerticalContentAlignment="Center"
|
||||
Text="{Binding Username, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left"
|
||||
Grid.Row="0" Grid.Column="1"/>
|
||||
|
||||
<Label Content="原密码:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right" />
|
||||
|
||||
<PasswordBox
|
||||
x:Name="passwordBox"
|
||||
Margin="10"
|
||||
Width="120"
|
||||
HorizontalAlignment="Left" VerticalContentAlignment="Center" Grid.Row="1" Grid.Column="1"
|
||||
PasswordChar="*"
|
||||
MaxLength="20"
|
||||
Helper:PasswordBoxHelper.Attach="True"
|
||||
Helper:PasswordBoxHelper.Password="{Binding Path=OldPassword ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
|
||||
<Label Content="新密码:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Right" />
|
||||
|
||||
<PasswordBox
|
||||
x:Name="newpasswordBox"
|
||||
Margin="10"
|
||||
Width="120"
|
||||
HorizontalAlignment="Left" VerticalContentAlignment="Center" Grid.Row="2" Grid.Column="1"
|
||||
PasswordChar="*"
|
||||
MaxLength="20"
|
||||
Helper:PasswordBoxHelper.Attach="True"
|
||||
Helper:PasswordBoxHelper.Password="{Binding Path=NewPassword ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
|
||||
|
||||
<Label Content="再次输入新密码:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="3" Grid.Column="0" HorizontalAlignment="Right" />
|
||||
|
||||
<PasswordBox
|
||||
x:Name="newpasswordBox1"
|
||||
Margin="10"
|
||||
Width="120"
|
||||
HorizontalAlignment="Left" VerticalContentAlignment="Center" Grid.Row="3" Grid.Column="1"
|
||||
PasswordChar="*"
|
||||
MaxLength="20"
|
||||
Helper:PasswordBoxHelper.Attach="True"
|
||||
Helper:PasswordBoxHelper.Password="{Binding Path=NewPassword1 ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
|
||||
<Button Content="取消" Grid.Row="4" Grid.Column="0" Margin="10,5,10,5" Height="40" Width="80" IsCancel="True"
|
||||
Command="{Binding ExitCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" />
|
||||
<Button Content="更改" Grid.Row="4" Grid.Column="1" Margin="50,5,10,5" Height="40" Width="80" IsDefault="True"
|
||||
Command="{Binding ChangePasswordCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" />
|
||||
|
||||
|
||||
</Grid>
|
||||
</Window>
|
24
Plane.FormationCreator/Views/ChangePasswordView.xaml.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using Plane.FormationCreator.ViewModels;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Plane.FormationCreator.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Description for ChangePasswordView.
|
||||
/// </summary>
|
||||
public partial class ChangePasswordView : Window
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ChangePasswordView class.
|
||||
/// </summary>
|
||||
public ChangePasswordView()
|
||||
{
|
||||
InitializeComponent();
|
||||
ChangePasswordViewModel loginViewModel = ServiceLocator.Current.GetInstance<ChangePasswordViewModel>();
|
||||
this.DataContext = loginViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
42
Plane.FormationCreator/Views/ConfigVirtualIdView.xaml
Normal file
@ -0,0 +1,42 @@
|
||||
<UserControl x:Class="Plane.FormationCreator.Views.ConfigVirtualIdView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
mc:Ignorable="d"
|
||||
BorderThickness="1"
|
||||
Background="#FF2D2D2D" Width="340" Height="260" BorderBrush="#FF006595">
|
||||
<Grid>
|
||||
<StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Margin="10,5" Text="手动编号"/>
|
||||
<TextBlock Margin="10,5" Text="选中单架无人机输入虚拟ID后点击设置"/>
|
||||
<StackPanel Margin="10,0" Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<TextBox Margin="0,5" Width="80" VerticalAlignment="Center"
|
||||
Text="{Binding SingleVirtualId}"/>
|
||||
<Button Margin="10,5" Width="100" Content = "设置编号" VerticalAlignment="Center"
|
||||
Command="{Binding SetSingleVirtualIdCommand}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Margin="10,5" Text="自动编号"/>
|
||||
<StackPanel Margin="10,0" >
|
||||
<TextBlock Margin="0,5" TextWrapping = "Wrap" Height="auto" Text="请按顺序选择2-3架飞机,分别是1号机,第一行任意飞机,第一列任意飞机(如只有一行不用选),自动配置前必须:1.设置行间距和列间距2.把不在正确位置的飞机手动编号"/>
|
||||
<Button Margin="0,0,0,0" Width="100" Content = "自动编号" VerticalAlignment="Center"
|
||||
Command="{Binding AutoLocationNumsCommand}"/>
|
||||
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="5" Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
|
||||
<Button Margin="5" Width="95" Content = "清除编号" Command="{Binding ClearVirtualIdCommand}"/>
|
||||
<Button Margin="5" Width="95" Content = "保存编号" Command="{Binding SaveVirtualIdCommand}"/>
|
||||
<Button Margin="5" Width="95" Content = "读入编号" Command="{Binding LoadVirtualIdCommand}"/>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
31
Plane.FormationCreator/Views/ConfigVirtualIdView.xaml.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using Plane.FormationCreator.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace Plane.FormationCreator.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// ConfigVirtualIdView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ConfigVirtualIdView : UserControl
|
||||
{
|
||||
public ConfigVirtualIdView()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.DataContext = ServiceLocator.Current.GetInstance<ConfigVirtualIdViewModel>();
|
||||
}
|
||||
}
|
||||
}
|
@ -7,157 +7,102 @@
|
||||
xmlns:c="http://metro.mahapps.com/winfx/xaml/controls"
|
||||
xmlns:ec="clr-namespace:Plane.Windows.Controls;assembly=Plane.Windows"
|
||||
mc:Ignorable="d"
|
||||
Title="连接"
|
||||
Width="432.175"
|
||||
Height="300.371"
|
||||
|
||||
Title=""
|
||||
Width="565.58"
|
||||
Height="325.107"
|
||||
|
||||
WindowStartupLocation="CenterScreen"
|
||||
FontFamily="Microsoft YaHei"
|
||||
ResizeMode="NoResize">
|
||||
ResizeMode="NoResize" >
|
||||
|
||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Height="Auto" Width="Auto" >
|
||||
|
||||
<Grid HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center">
|
||||
|
||||
<Grid.Resources>
|
||||
<Style TargetType="Label"
|
||||
BasedOn="{StaticResource {x:Type Label}}">
|
||||
<Setter Property="HorizontalAlignment"
|
||||
Value="Right" />
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Center" />
|
||||
</Style>
|
||||
<Style TargetType="ComboBox"
|
||||
BasedOn="{StaticResource {x:Type ComboBox}}">
|
||||
<Setter Property="HorizontalAlignment"
|
||||
Value="Left" />
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Center" />
|
||||
<Setter Property="Width"
|
||||
Value="150" />
|
||||
</Style>
|
||||
<Style TargetType="TextBox"
|
||||
BasedOn="{StaticResource {x:Type TextBox}}">
|
||||
<Setter Property="HorizontalAlignment"
|
||||
Value="Left" />
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Center" />
|
||||
<Setter Property="Width"
|
||||
Value="150" />
|
||||
</Style>
|
||||
<Style TargetType="PasswordBox"
|
||||
BasedOn="{StaticResource {x:Type PasswordBox}}">
|
||||
<Setter Property="HorizontalAlignment"
|
||||
Value="Left" />
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Center" />
|
||||
<Setter Property="MinWidth"
|
||||
Value="150" />
|
||||
</Style>
|
||||
<Style TargetType="Button"
|
||||
BasedOn="{StaticResource {x:Type Button}}">
|
||||
<Setter Property="HorizontalAlignment"
|
||||
Value="Center" />
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Center" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="30" />
|
||||
<RowDefinition Height="30"/>
|
||||
<RowDefinition Height="30"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="10" />
|
||||
<ColumnDefinition />
|
||||
|
||||
<ColumnDefinition></ColumnDefinition>
|
||||
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Target="{Binding ElementName=txtIPs}" Visibility="Collapsed"
|
||||
Content="IP" />
|
||||
<TextBox Name="txtIPs"
|
||||
Grid.Column="2"
|
||||
AcceptsReturn="True"
|
||||
MinHeight="200"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
Visibility="Collapsed"
|
||||
Text="{Binding IPs, UpdateSourceTrigger=PropertyChanged}" />
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
Grid.Row="1"
|
||||
Grid.ColumnSpan="3"
|
||||
Name="panel1">
|
||||
|
||||
<ec:ProgressButton HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Margin="10"
|
||||
Content="连接 _TCP"
|
||||
IsDefault="True"
|
||||
IsProcessing="{Binding IsProcessing}"
|
||||
Command="{Binding Path=ConnectCommand}" />
|
||||
<ec:ProgressButton HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Margin="10"
|
||||
Content="连接 _UDP"
|
||||
IsDefault="True"
|
||||
IsProcessing="{Binding IsProcessing}"
|
||||
Command="{Binding Path=ConnectCommand}"
|
||||
CommandParameter="UDP"/>
|
||||
<ec:ProgressButton HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Margin="10"
|
||||
Content="连接串口"
|
||||
IsProcessing="{Binding IsProcessing}"
|
||||
Command="{Binding Path=ConnectCommand}"
|
||||
CommandParameter="SerialPort" />
|
||||
|
||||
<!--<ec:ProgressButton Name="btnConnectUdp"
|
||||
Grid.Row="1"
|
||||
Grid.ColumnSpan="3"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Margin="10"
|
||||
Content="连接 _UDP"
|
||||
IsDefault="True"
|
||||
IsProcessing="{Binding IsProcessing}"
|
||||
Command="{Binding Path=ConnectCommand}"
|
||||
CommandParameter="UDP" />-->
|
||||
<Button Content="关闭TCP" Margin="5" Command="{Binding CloseCommand}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
Grid.Row="2"
|
||||
Grid.ColumnSpan="3"
|
||||
Name="panel2">
|
||||
<Button Content="通信模块状态" Margin="5" Command="{Binding Path=StateInquireCommand}"/>
|
||||
<Button Content="设置总数" Margin="5" Command="{Binding Path=SendCommand}" />
|
||||
<Button Content="切换写航点" Margin="5" Command="{Binding Path=ChangeWriteMissionCommand}" />
|
||||
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
Grid.Row="3"
|
||||
Grid.ColumnSpan="3">
|
||||
<TextBox Margin="2,5,5,5" Width="30" Text="{Binding CopterNum}"></TextBox>
|
||||
<Button Content=" 对频 " Margin="5,5,0,5" Command="{Binding Path=WriteIdCommand}" />
|
||||
<Button Content="闪灯" Margin="5" Command="{Binding CommDataAsync}"/>
|
||||
<Button Content="拉烟" Margin="5" Command="{Binding TestFireCommandAsync}"/>
|
||||
<TextBox Width="80" Text="{Binding CopterColor}"/>
|
||||
HorizontalAlignment="Left"
|
||||
Grid.Row="0" >
|
||||
<TextBlock Margin="5" VerticalAlignment="Center" Text="ID:" />
|
||||
<TextBox Width="30" VerticalContentAlignment="Center" Text="{Binding CopterNum}" Margin="5,5,5,5" />
|
||||
<TextBlock Margin="5" VerticalAlignment="Center" Text="参数:" />
|
||||
<TextBox Width="56" VerticalContentAlignment="Center" Text="{Binding CopterColor}" Margin="5,5,5,5"/>
|
||||
<Button Content="对频" Width="67" Margin="5,5,5,5" Command="{Binding Path=WriteIdCommand}" ToolTip="ID框输入新编号" />
|
||||
<Button Content="闪灯 " Width="67" Margin="5,5,5,5" Command="{Binding CommDataAsync}" ToolTip="参数为十六进制颜色"/>
|
||||
<Button Content="拉烟" Width="67" Margin="5,5,5,5" Command="{Binding TestFireCommandAsync}" ToolTip="参数为通道号1-4"/>
|
||||
<Button Content="抛物" Width="67" Margin="5,5,5,5" Command="{Binding TestPWMCommandAsync}" ToolTip="接入舵机控制"/>
|
||||
<Button Content="功率" Width="67" Margin="5,5,5,5" Command="{Binding SetModulePowerCommand}" ToolTip="设置模块回传功率"/>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Center"
|
||||
Grid.Row="4"
|
||||
Grid.ColumnSpan="3"
|
||||
Name="panel3">
|
||||
<Button Content="空中升级" Margin="5" Command="{Binding UpdateAllCopterCommand}"></Button>
|
||||
<Button Content="搜索飞机" Margin="5" Command="{Binding QueryAllCopterCommand}"/>
|
||||
HorizontalAlignment="Left"
|
||||
Grid.Row="1"
|
||||
Name="panel4" >
|
||||
<Button Content="立体缩放" Width="90" Margin="5,5,5,5" Command="{Binding UpdateAllCopterCommand}"></Button>
|
||||
<TextBlock Margin="5" VerticalAlignment="Center" Text="比例/模块号:" />
|
||||
<TextBox Width="30" VerticalContentAlignment="Center" Text="{Binding scale3d}" Margin="5,5,5,5" />
|
||||
<Button Content="更改密码" Width="90" Margin="5,5,5,5" Command="{Binding ChangepasswordCommand}"></Button>
|
||||
<Button Content="测试模块" Width="90" Margin="5,5,5,5" Command="{Binding TestModuleCommand}" ToolTip="测试地面站通讯模块1-8"></Button>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Grid.Row="2" Name="panel7" >
|
||||
|
||||
<Button Content="{Binding btnBoardPortStr}" Width="115" Margin="5,5,5,5" Command="{Binding Openboardport}"/>
|
||||
<ComboBox Width="90" Height="25" Foreground="White" SelectedIndex="0"
|
||||
ItemsSource="{Binding serialRePorts, Mode=OneWay}"
|
||||
SelectedValue="{Binding SerialPortResend}"
|
||||
DropDownOpened="ComboBox_DropDownOpened"/>
|
||||
<TextBlock Margin="10,5,5,5" VerticalAlignment="Center" Text="{Binding BoardPortStatusStr}" />
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Left"
|
||||
Grid.Row="3"
|
||||
Name="panel2" >
|
||||
<TextBlock Margin="5" VerticalAlignment="Center" Text="总数:" />
|
||||
<TextBox Width="45" VerticalContentAlignment="Center" Text="{Binding CopterSum}" Margin="5,5,5,5" />
|
||||
<Button Content="设置总数" Width="90" Margin="5,5,5,5" Command="{Binding Path=SendCommand}" />
|
||||
<Button Content="切换写航点" Width="90" Margin="5,5,5,5" Command="{Binding Path=ChangeWriteMissionCommand}" />
|
||||
<Button Content="通信状态" Width="90" Margin="5,5,5,5" Command="{Binding StateInquireCommand}"/>
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="Left"
|
||||
Grid.Row="4"
|
||||
Name="panel3" >
|
||||
<Button Content="空中升级" Width="90" Margin="5,5,5,5" Command="{Binding UpdateAllCopterCommand}"></Button>
|
||||
<Button Content="搜索飞机" Width="90" Margin="5,5,5,5" Command="{Binding QueryAllCopterCommand}"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<Image Margin="0,0,0,0" x:Name="image1" Grid.RowSpan="2" Grid.Row="5" Source="/Resources/Logo_small.png" HorizontalAlignment="Left" />
|
||||
<TextBlock Margin="5" Grid.Row="6" x:Name="about_ver" HorizontalAlignment="Right" VerticalAlignment="Bottom" Text="版本:V2.0.1213" />
|
||||
<TextBlock Margin="5" Grid.Row="7" HorizontalAlignment="Right" x:Name="about_buildtm" VerticalAlignment="Bottom" Text="编译日期:2020.12.12" />
|
||||
|
||||
|
||||
|
||||
|
||||
</Grid>
|
||||
</c:MetroWindow>
|
||||
|
@ -16,6 +16,7 @@ using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Plane.FormationCreator.Util;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Plane.FormationCreator.Views
|
||||
{
|
||||
@ -41,12 +42,24 @@ namespace Plane.FormationCreator.Views
|
||||
|
||||
if (!VersionControl.IsFullVersion)
|
||||
{
|
||||
panel1.Visibility = Visibility.Collapsed;
|
||||
//panel1.Visibility = Visibility.Collapsed;
|
||||
panel2.Visibility = Visibility.Collapsed;
|
||||
panel3.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
var version = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
about_ver.Text = "版本:" + version.ToString() + "(飞控兼容:" + _copterManager.FC_VER_STRING + ")";
|
||||
about_buildtm .Text= "编译时间:" + System.IO.File.GetLastWriteTime(this.GetType().Assembly.Location).ToString();
|
||||
|
||||
|
||||
|
||||
//txtIPs.Focus();
|
||||
}
|
||||
ConnectViewModel _ConnectViewModel = ServiceLocator.Current.GetInstance<ConnectViewModel>();
|
||||
private void ComboBox_DropDownOpened(object sender, EventArgs e)
|
||||
{
|
||||
_ConnectViewModel.RefreshPorts();
|
||||
|
||||
txtIPs.Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,191 +1,235 @@
|
||||
<UserControl x:Class="Plane.FormationCreator.Views.ControlPanelView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
xmlns:fc="clr-namespace:Plane.FormationCreator"
|
||||
xmlns:ec="clr-namespace:Plane.Copters;assembly=PlaneGcsSdk_Private_NET46"
|
||||
xmlns:vm="clr-namespace:Plane.FormationCreator.ViewModels"
|
||||
xmlns:m="clr-namespace:Plane.FormationCreator.Formation"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="300">
|
||||
|
||||
<StackPanel>
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="Button"
|
||||
BasedOn="{StaticResource {x:Type Button}}">
|
||||
<Setter Property="Margin"
|
||||
Value="0,0,3,5" />
|
||||
</Style>
|
||||
</StackPanel.Resources>
|
||||
|
||||
<!--<TextBlock Text="连接" />
|
||||
<WrapPanel>
|
||||
<Button Content="连接"
|
||||
Command="{Binding ConnectCommand}" />
|
||||
<Button Content="断开"
|
||||
Command="{Binding DisconnectCommand}" />
|
||||
</WrapPanel>-->
|
||||
|
||||
<TextBlock Text="飞行控制"
|
||||
Margin="5,0,0,8"/>
|
||||
<WrapPanel>
|
||||
<Button Content="解锁"
|
||||
Command="{Binding UnlockCommand}" />
|
||||
<Button Content="起飞" Visibility="Collapsed"
|
||||
Command="{Binding TakeOffCommand}" />
|
||||
<Button Content="起飞"
|
||||
Command="{Binding GuidAsyncCommand}" />
|
||||
<Button Content="悬停"
|
||||
Command="{Binding HoverCommand}" />
|
||||
<Button Content="手动"
|
||||
Command="{Binding FloatCommand}" />
|
||||
<Button Content="参数"
|
||||
Command="{Binding ParamModify}" />
|
||||
<Button Content="参数文件" Visibility="Collapsed"
|
||||
Command="{Binding LoadParamfile}" />
|
||||
<Button Content="版本"
|
||||
Command="{Binding GetVersionsCommand}" />
|
||||
<Button Content="校准"
|
||||
Command="{Binding CalibrationSingleCommand}" />
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
<Button Content="返航"
|
||||
Command="{Binding ReturnToLaunchCommand}" />
|
||||
<Button Content="降落"
|
||||
Command="{Binding LandCommand}" />
|
||||
<Button Content="上锁"
|
||||
Command="{Binding LockCommand}" />
|
||||
<Button Content="跳过" Visibility="Collapsed"
|
||||
Command="{Binding FlagCommand}" />
|
||||
<Button Content="闪灯"
|
||||
Command="{Binding LEDFlickerCommand}" />
|
||||
<Button Content="测试" Visibility="Collapsed"
|
||||
Command="{Binding TestCommand}" />
|
||||
<Button Content="开灯"
|
||||
Command="{Binding LEDOnOffCommand}"
|
||||
CommandParameter="0"/>
|
||||
<Button Content="关灯"
|
||||
Command="{Binding LEDOnOffCommand}"
|
||||
CommandParameter="1"/>
|
||||
<Button Content="电机"
|
||||
|
||||
Command="{Binding MotorTestCommand}" />
|
||||
|
||||
<TextBox Width="50"
|
||||
Visibility="Collapsed"
|
||||
Text="{Binding AltP, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
|
||||
<Button Content="选写航点"
|
||||
Command="{Binding WriteMissionSingleCommand}" />
|
||||
<Button Content="定位统计"
|
||||
Command="{Binding ReportGPSTypeCommand}"/>
|
||||
<Button Content="统计模块"
|
||||
Command="{Binding DetectionCommModuleVersion}" />
|
||||
<Button Content="正式参数"
|
||||
Command="{Binding TurnOffTestLightsCommand}"
|
||||
/>
|
||||
<TextBlock Margin="5,0,3,0" Text="起飞高度" VerticalAlignment="Center"></TextBlock>
|
||||
<TextBox Width="30" Height="26" Text="{Binding TaskOffAlt}"
|
||||
/>
|
||||
<Label Visibility="Collapsed">Lat</Label>
|
||||
<TextBox Visibility="Collapsed" Text="{Binding LatOffset}" Width="50"/>
|
||||
<Label Visibility="Collapsed">Lng</Label>
|
||||
<TextBox Visibility="Collapsed" Text="{Binding LngOffset}" Width="50"/>
|
||||
<Button Visibility="Collapsed" Content="设置返航点"
|
||||
Command="{Binding RLTOffsetCommand}" />
|
||||
</WrapPanel>
|
||||
<Separator/>
|
||||
<WrapPanel>
|
||||
<Button Content="全部降落"
|
||||
Command="{Binding AllLandCommand}" />
|
||||
<Button Content="全部加锁"
|
||||
Command="{Binding LockAllCommand}" />
|
||||
<Button Content="检测电压"
|
||||
Command="{Binding DetectionVoltage}" />
|
||||
<Button Content="统计返回"
|
||||
Command="{Binding DetectionReturnData}" />
|
||||
<Button Content="统计航点"
|
||||
Command="{Binding DetectionMissionData}" />
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
<Button Content="写入航点"
|
||||
Command="{Binding WriteMissionCommand}" />
|
||||
<Button Content="全部解锁"
|
||||
Command="{Binding UnlockAllCommand}"
|
||||
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Button Content="开始任务"
|
||||
Command="{Binding MissionStartCommand}"
|
||||
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
<Button Content="暂停任务"
|
||||
Command="{Binding MissionPauseCommand}" />
|
||||
<Button Content="继续任务"
|
||||
Command="{Binding MissionResumeCommand}" />
|
||||
</WrapPanel>
|
||||
|
||||
<WrapPanel>
|
||||
<Button Content="航点续写"
|
||||
Command="{Binding WriteMissionFailedCommand}" />
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
Width="55"
|
||||
Margin="5, 5, 5, 5"
|
||||
HorizontalContentAlignment="Right"
|
||||
Text="{Binding RTKcomvalue, UpdateSourceTrigger=PropertyChanged}"
|
||||
/>
|
||||
|
||||
<Button Content="{Binding Path=RTKbtntxt}"
|
||||
Command="{Binding SendRTKCommand}" />
|
||||
|
||||
<Button Content="{Binding Path=NTRIPbtntxt}"
|
||||
Command="{Binding SendRTCMCommand}"/>
|
||||
|
||||
<Button Content="RTK" Command="{Binding OpenRtcmManageCommand}" />
|
||||
|
||||
<TextBlock
|
||||
Margin="5,5,5,5"
|
||||
Text="{Binding Path=RTKState}"
|
||||
/>
|
||||
</WrapPanel>
|
||||
|
||||
<!--// 林俊清, 20150920, 目前不再使用 FormationController,删除相关按钮。
|
||||
<StackPanel Visibility="{Binding Source={x:Static fc:AppEx.Current}, Path=AppMode, Converter={StaticResource AppModeToVisibilityConverter}, ConverterParameter=ControlPanelView_Formation}">
|
||||
<TextBlock Text="任务" />
|
||||
<WrapPanel>
|
||||
<Button Content="飞到50米高"
|
||||
Command="{Binding FlyToAltitudeCommand}"
|
||||
CommandParameter="50" />
|
||||
<Button Content="飞到15米高"
|
||||
Command="{Binding FlyToAltitudeCommand}"
|
||||
CommandParameter="15" />
|
||||
<Button Content="Test"
|
||||
Command="{Binding TestCommand}" />
|
||||
</WrapPanel>
|
||||
-->
|
||||
<!--<WrapPanel>
|
||||
<Button Content="画圈"
|
||||
Command="{Binding FlyInCircleCommand}" />
|
||||
<Button Content="绕队列中心画圈"
|
||||
Command="{Binding FlyAroundCenterOfCoptersCommand}" />
|
||||
<Button Content="Test"
|
||||
Command="{Binding TestCommand}" />
|
||||
<Button Content="画矩形"
|
||||
Command="{Binding FlyInRectangleCommand}"
|
||||
Visibility="Collapsed" />
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
<Button Content="飞到一条竖线画圈"
|
||||
Command="{Binding FlyToVerticalLineAndMakeCircleCommand}" />
|
||||
</WrapPanel>-->
|
||||
<!--
|
||||
<WrapPanel>
|
||||
<Button Content="停止"
|
||||
Command="{Binding StopTaskCommand}" />
|
||||
</WrapPanel>
|
||||
</StackPanel>-->
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
<UserControl x:Class="Plane.FormationCreator.Views.ControlPanelView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
xmlns:fc="clr-namespace:Plane.FormationCreator"
|
||||
xmlns:ec="clr-namespace:Plane.Copters;assembly=PlaneGcsSdk_Private_NET46"
|
||||
xmlns:vm="clr-namespace:Plane.FormationCreator.ViewModels"
|
||||
xmlns:m="clr-namespace:Plane.FormationCreator.Formation"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="300">
|
||||
|
||||
<StackPanel Margin="0,0,-8,0">
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="Button"
|
||||
BasedOn="{StaticResource {x:Type Button}}">
|
||||
<Setter Property="Margin"
|
||||
Value="0,0,3,5" />
|
||||
</Style>
|
||||
</StackPanel.Resources>
|
||||
|
||||
<!--<TextBlock Text="连接" />
|
||||
<WrapPanel>
|
||||
<Button Content="连接"
|
||||
Command="{Binding ConnectCommand}" />
|
||||
<Button Content="断开"
|
||||
Command="{Binding DisconnectCommand}" />
|
||||
</WrapPanel>-->
|
||||
|
||||
|
||||
<TabControl Margin="0,0,13,0">
|
||||
<TabItem Header="飞行前准备">
|
||||
|
||||
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
||||
<WrapPanel>
|
||||
|
||||
<Button Content="电压检测"
|
||||
Command="{Binding DetectionVoltage}" />
|
||||
<Button Content="版本检测"
|
||||
Command="{Binding GetVersionsCommand}" />
|
||||
<Button Content="通讯版本" Command="{Binding DetectionCommModuleVersion}" />
|
||||
<Button Content="统计返回"
|
||||
Command="{Binding DetectionReturnData}" />
|
||||
<Button Content="通讯统计"
|
||||
Command="{Binding GetCommsumCommand}" />
|
||||
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
<Button Content="参数设置"
|
||||
Command="{Binding ParamModify}" />
|
||||
<Button Content="读入参数"
|
||||
Command="{Binding LoadParamfile}" />
|
||||
<Button Content="状态统计" Command="{Binding ReportGPSTypeCommand}"/>
|
||||
<Button Content="飞机校准"
|
||||
Command="{Binding CalibrationSingleCommand}" />
|
||||
<Button Content="正式参数" Command="{Binding TurnOffTestLightsCommand}" Visibility="Collapsed" />
|
||||
|
||||
<Button Content="电机" Visibility="Collapsed"
|
||||
|
||||
Command="{Binding MotorTestCommand}" />
|
||||
|
||||
|
||||
<Button Content="删除飞机"
|
||||
|
||||
Command="{Binding DelCommand}" />
|
||||
|
||||
<Label Visibility="Collapsed" Content="Lat"/>
|
||||
<TextBox Visibility="Collapsed" Text="{Binding LatOffset}" Width="50"/>
|
||||
<Label Visibility="Collapsed" Content="Lng"/>
|
||||
<TextBox Visibility="Collapsed" Text="{Binding LngOffset}" Width="50"/>
|
||||
<Button Visibility="Collapsed" Content="设置返航点" Command="{Binding RLTOffsetCommand}" />
|
||||
</WrapPanel>
|
||||
|
||||
<WrapPanel>
|
||||
<Button Content="写入航点"
|
||||
Command="{Binding WriteMissionCommand}" />
|
||||
<Button Content="航点续写"
|
||||
Command="{Binding WriteMissionFailedCommand}" />
|
||||
<Button Content="选写航点" Command="{Binding WriteMissionSingleCommand}" />
|
||||
<Button Content="统计航点"
|
||||
Command="{Binding DetectionMissionData}" />
|
||||
<TextBox
|
||||
Grid.Column="1"
|
||||
Width="55"
|
||||
Margin="5, 5, 5, 5"
|
||||
HorizontalContentAlignment="Right"
|
||||
|
||||
Text="{Binding RTKcomvalue, UpdateSourceTrigger=PropertyChanged}" Visibility="Collapsed"
|
||||
/>
|
||||
|
||||
<Button Content="{Binding RTKbtntxt}"
|
||||
Command="{Binding SendRTKCommand}" Visibility="Collapsed" />
|
||||
|
||||
<Button Content="{Binding NTRIPbtntxt}"
|
||||
Command="{Binding SendRTCMCommand}" Visibility="Collapsed"/>
|
||||
|
||||
<Button Content="RTK 控制" Command="{Binding OpenRtcmManageCommand}" />
|
||||
|
||||
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
|
||||
</TabItem>
|
||||
|
||||
|
||||
<TabItem Header="飞行控制">
|
||||
|
||||
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
||||
<WrapPanel >
|
||||
<Button Content="解锁"
|
||||
Command="{Binding UnlockCommand}" />
|
||||
<Button Content="加锁"
|
||||
Command="{Binding LockCommand}" />
|
||||
<Button Content="单独任务"
|
||||
Command="{Binding TakeOffCommand}" />
|
||||
|
||||
<Button Content="抛物"
|
||||
Command="{Binding ThrowoutCommand}" />
|
||||
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
<Button Content="起飞"
|
||||
Command="{Binding GuidAsyncCommand}" />
|
||||
<Button Content="悬停"
|
||||
Command="{Binding HoverCommand}" />
|
||||
<Button Content="手动"
|
||||
Command="{Binding FloatCommand}" />
|
||||
<Button Content="返航"
|
||||
Command="{Binding ReturnToLaunchCommand}" />
|
||||
<Button Content="降落"
|
||||
Command="{Binding LandCommand}" />
|
||||
|
||||
<Button Content="跳过" Visibility="Collapsed"
|
||||
Command="{Binding FlagCommand}" />
|
||||
|
||||
|
||||
|
||||
<TextBox Width="50"
|
||||
Visibility="Collapsed"
|
||||
Text="{Binding AltP, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</WrapPanel>
|
||||
|
||||
|
||||
<WrapPanel>
|
||||
<Button Content="闪灯"
|
||||
Command="{Binding LEDFlickerCommand}" />
|
||||
<Button Content="测试" Visibility="Collapsed"
|
||||
Command="{Binding TestCommand}" />
|
||||
<Button Content="开灯"
|
||||
Command="{Binding LEDOnOffCommand}"
|
||||
CommandParameter="0"/>
|
||||
<Button Content="关灯"
|
||||
Command="{Binding LEDOnOffCommand}"
|
||||
CommandParameter="1"/>
|
||||
<TextBlock Margin="8,-3,5,0" Text="起飞高度" VerticalAlignment="Center"/>
|
||||
<TextBox VerticalContentAlignment="Center" Margin="0,0,0,5" Width="30" Height="25" Text="{Binding TaskOffAlt}" />
|
||||
<TextBlock Margin="5,-3,5,0" Text="米" VerticalAlignment="Center"/>
|
||||
</WrapPanel>
|
||||
|
||||
|
||||
|
||||
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
|
||||
<TabItem Header="任务控制">
|
||||
|
||||
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
||||
<WrapPanel>
|
||||
|
||||
<Button Content="全部解锁"
|
||||
Command="{Binding UnlockAllCommand}"
|
||||
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Button Content="全部加锁"
|
||||
Command="{Binding LockAllCommand}" />
|
||||
</WrapPanel>
|
||||
<WrapPanel>
|
||||
|
||||
<Button Content="开始任务"
|
||||
Command="{Binding MissionStartCommand}"
|
||||
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
<Button Content="暂停任务"
|
||||
Command="{Binding MissionPauseCommand}" />
|
||||
<Button Content="继续任务"
|
||||
Command="{Binding MissionResumeCommand}" />
|
||||
|
||||
|
||||
|
||||
</WrapPanel>
|
||||
|
||||
<WrapPanel>
|
||||
|
||||
<Button Content="全部降落"
|
||||
Command="{Binding AllLandCommand}" />
|
||||
<Button Content="紧急返航"
|
||||
Command="{Binding EmergencyRetCommand}" />
|
||||
|
||||
<Button Content="重设任务"
|
||||
Command="{Binding ResetRealMissionCommand}" />
|
||||
|
||||
</WrapPanel>
|
||||
</StackPanel>
|
||||
|
||||
</TabItem>
|
||||
|
||||
|
||||
|
||||
<TabItem Header="飞行报告" Visibility="Collapsed">
|
||||
|
||||
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
|
||||
|
||||
<WrapPanel>
|
||||
|
||||
<Button Content="添加报告"
|
||||
Command="{Binding UnlockAllCommand}"
|
||||
IsEnabled="{Binding AllowMissionStart, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<Button Content="查看报告"
|
||||
Command="{Binding LockAllCommand}" />
|
||||
</WrapPanel>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
|
||||
|
||||
|
||||
</TabControl>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
@ -7,7 +7,7 @@
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
BorderThickness="1"
|
||||
Background="#FF2D2D2D" Width="464">
|
||||
Background="#FF2D2D2D" Width="340">
|
||||
<UserControl.BorderBrush>
|
||||
<SolidColorBrush Color="{DynamicResource {x:Static SystemColors.ActiveBorderColorKey}}"/>
|
||||
</UserControl.BorderBrush>
|
||||
@ -17,7 +17,7 @@
|
||||
<Label Margin="5,0,0,0" Content="属性设置" VerticalAlignment="Center"/>
|
||||
<Separator></Separator>
|
||||
<StackPanel Margin="5,0,0,5" Orientation="Horizontal" HorizontalAlignment="Left">
|
||||
<Label Margin="0" Content="摆放高度" ></Label>
|
||||
<Label Margin="0" Content="摆放高度(米)" ></Label>
|
||||
<TextBox
|
||||
Margin="30,0"
|
||||
Width="80"
|
||||
|
@ -6,7 +6,7 @@
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
mc:Ignorable="d"
|
||||
BorderThickness="1"
|
||||
Background="#FF2D2D2D" Width="464" Height="300">
|
||||
Background="#FF2D2D2D" Width="340" Height="300">
|
||||
<UserControl.BorderBrush>
|
||||
<SolidColorBrush Color="{DynamicResource {x:Static SystemColors.ActiveBorderColorKey}}"/>
|
||||
</UserControl.BorderBrush>
|
||||
@ -14,14 +14,14 @@
|
||||
<StackPanel Orientation="Vertical">
|
||||
<Grid >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="70"/>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="80"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Margin="5,0" Content="分组设置" HorizontalAlignment="Left" />
|
||||
<Label Margin="15,0" Grid.Column="1" Content="最后选中:" HorizontalAlignment="Left"/>
|
||||
<Label Grid.Column="1" Content="{Binding GroupManager.LastSelectedGroup}" HorizontalAlignment="Right"/>
|
||||
<Button Margin="5,0" Grid.Column="2" Content="添加分组" HorizontalAlignment="Right"
|
||||
<Label Margin="0,0" Grid.Column="1" Content="最后选中:" HorizontalAlignment="Left"/>
|
||||
<Label Margin="0,0" Grid.Column="1" Content="{Binding GroupManager.LastSelectedGroup}" HorizontalAlignment="Right"/>
|
||||
<Button Margin="0,0" Grid.Column="2" Content="添加" HorizontalAlignment="Right"
|
||||
Command="{Binding Path=GroupManager.AddGroupsCommand}"/>
|
||||
</Grid>
|
||||
<Separator></Separator>
|
||||
@ -48,9 +48,9 @@
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBox Width="95" Text="{Binding groupName,UpdateSourceTrigger=PropertyChanged}"/>
|
||||
<Button Margin="20,0,0,0" Width="90" Content="删除" Command="{Binding RemoveGroupCommand}"/>
|
||||
<Button Margin="20,0,0,0" Width="90" Content="设置" Command="{Binding SetGroupCoptersCommand}"/>
|
||||
<Button Margin="20,0,0,0" Width="90" Content="选中" Command="{Binding SelectCoptersCommand}"/>
|
||||
<Button Margin="5,0,0,0" Width="65" Content="删除" Command="{Binding RemoveGroupCommand}"/>
|
||||
<Button Margin="5,0,0,0" Width="65" Content="设置" Command="{Binding SetGroupCoptersCommand}"/>
|
||||
<Button Margin="5,0,0,0" Width="65" Content="选中" Command="{Binding SelectCoptersCommand}"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
|
@ -1,187 +1,331 @@
|
||||
<UserControl x:Class="Plane.FormationCreator.Views.CopterInfoView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
xmlns:ec="clr-namespace:Plane.Copters;assembly=PlaneGcsSdk_Private_NET46"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="300"
|
||||
d:DataContext="{d:DesignInstance Type=ec:FakeCopter, IsDesignTimeCreatable=True}">
|
||||
<StackPanel>
|
||||
<TextBlock Text="飞行信息" />
|
||||
<Grid>
|
||||
<Grid.Resources>
|
||||
<Style x:Key="CopterInfo_ComboBox"
|
||||
TargetType="ComboBox"
|
||||
BasedOn="{StaticResource {x:Type ComboBox}}">
|
||||
<Setter Property="MinWidth"
|
||||
Value="120" />
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Center" />
|
||||
</Style>
|
||||
<Style x:Key="CopterInfo_StackPanel"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="Orientation"
|
||||
Value="Horizontal" />
|
||||
<Setter Property="Margin"
|
||||
Value="0,2" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="180" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Orientation="Vertical">
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="ComboBox"
|
||||
BasedOn="{StaticResource CopterInfo_ComboBox}" />
|
||||
<Style TargetType="StackPanel"
|
||||
BasedOn="{StaticResource CopterInfo_StackPanel}" />
|
||||
</StackPanel.Resources>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="ID:" />
|
||||
<TextBlock Text="{Binding Path=Id}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="已连接:" />
|
||||
<ContentPresenter Content="{Binding CommModuleConnected, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="已解锁:" />
|
||||
<ContentPresenter Content="{Binding IsUnlocked, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="心跳数:" />
|
||||
<TextBlock Text="{Binding Path=HeartbeatCount}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="卫星数:" />
|
||||
<TextBlock Text="{Binding Path=SatCount}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="方向:" />
|
||||
<TextBlock Text="{Binding Path=Heading}" />
|
||||
</StackPanel>
|
||||
<!--<StackPanel>
|
||||
<TextBlock Text="Yaw:" />
|
||||
<TextBlock Text="{Binding Path=Yaw, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="纬度:" />
|
||||
<TextBlock Text="{Binding Path=Latitude}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="经度:" />
|
||||
<TextBlock Text="{Binding Path=Longitude}" />
|
||||
</StackPanel>-->
|
||||
<StackPanel>
|
||||
<TextBlock Text="高度:" />
|
||||
<TextBlock Text="{Binding Altitude, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="距离:" />
|
||||
<TextBlock Text="{Binding FlightDistance, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="锁定类型:" />
|
||||
<TextBlock Text="{Binding GpsFixType}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="返回数据:" />
|
||||
<StackPanel ToolTip="{Binding RetainInt}">
|
||||
<TextBlock Text="{Binding Retain[3]}" />
|
||||
<TextBlock Text="." />
|
||||
<TextBlock Text="{Binding Retain[2]}" />
|
||||
<TextBlock Text="." />
|
||||
<TextBlock Text="{Binding Retain[1]}" />
|
||||
<TextBlock Text="." />
|
||||
<TextBlock Text="{Binding Retain[0]}" />
|
||||
</StackPanel>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<!--
|
||||
<StackPanel>
|
||||
<TextBlock Text="固件版本:" />
|
||||
<TextBlock Text="{Binding FirmwareVersionText}" />
|
||||
</StackPanel>-->
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Orientation="Vertical">
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="ComboBox"
|
||||
BasedOn="{StaticResource CopterInfo_ComboBox}" />
|
||||
<Style TargetType="StackPanel"
|
||||
BasedOn="{StaticResource CopterInfo_StackPanel}" />
|
||||
</StackPanel.Resources>
|
||||
|
||||
<StackPanel>
|
||||
<Slider x:Name="sldChannel3"
|
||||
Width="100"
|
||||
Minimum="1100"
|
||||
Maximum="1900"
|
||||
Value="{Binding Channel3, Mode=OneWay}"
|
||||
ValueChanged="sldChannel3_ValueChanged">
|
||||
<Slider.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Blue.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Slider.Resources>
|
||||
</Slider>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="电压:" />
|
||||
<TextBlock Text="{Binding Path=Voltage}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="剩余电量:" />
|
||||
<TextBlock Text="{Binding Path=BatteryPer}" />
|
||||
<TextBlock Text="%" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="状态:" />
|
||||
<TextBlock Text="{Binding Path=CommModuleMode}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="纬度:" />
|
||||
<TextBlock Text="{Binding Latitude}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="经度:" />
|
||||
<TextBlock Text="{Binding Longitude}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="通道3:" />
|
||||
<TextBlock Text="{Binding Channel3}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="通道4:" />
|
||||
<TextBlock Text="{Binding Channel4}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="定位精度:" />
|
||||
<TextBlock Text="{Binding GpsHdop, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="通信模块:" />
|
||||
<TextBlock Text="{Binding CommModuleVersion}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
<UserControl x:Class="Plane.FormationCreator.Views.CopterInfoView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
xmlns:ec="clr-namespace:Plane.Copters;assembly=PlaneGcsSdk_Private_NET46"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="300"
|
||||
d:DataContext="{d:DesignInstance Type=ec:FakeCopter, IsDesignTimeCreatable=True}">
|
||||
|
||||
|
||||
|
||||
<UserControl.Resources>
|
||||
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
</Style>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!--笔刷-->
|
||||
<LinearGradientBrush x:Key="SliderBackground" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Offset="0" Color="#59ccfc"/>
|
||||
<GradientStop Offset="0.5" Color="#00b3fe"/>
|
||||
<GradientStop Offset="1" Color="#59ccfc"/>
|
||||
</LinearGradientBrush>
|
||||
<LinearGradientBrush x:Key="SliderThumb" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Offset="0" Color="#FFD9D3E8"/>
|
||||
<!--<GradientStop Offset="1" Color="#dfdfdf"/>-->
|
||||
</LinearGradientBrush>
|
||||
<LinearGradientBrush x:Key="SliderText" StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Offset="0" Color="#7cce45"/>
|
||||
<GradientStop Offset="1" Color="#4ea017"/>
|
||||
</LinearGradientBrush>
|
||||
|
||||
<!--Slider模板-->
|
||||
<Style x:Key="Slider_RepeatButton" TargetType="RepeatButton">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RepeatButton">
|
||||
<Border Background="{StaticResource SliderBackground}" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Slider_RepeatButton1" TargetType="RepeatButton">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RepeatButton">
|
||||
<Border Background="Transparent" />
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Slider_Thumb" TargetType="Thumb">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Thumb">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Background="{StaticResource SliderBackground}"/>
|
||||
<Border Grid.ColumnSpan="2" CornerRadius="4" Background="{StaticResource SliderThumb}" Width="15">
|
||||
<!--<TextBlock Text="||" HorizontalAlignment="Center" VerticalAlignment="Center"/>-->
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="Slider_CustomStyle" TargetType="Slider">
|
||||
<Setter Property="Focusable" Value="false" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Slider">
|
||||
<Grid>
|
||||
<!--<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="40"/>
|
||||
</Grid.ColumnDefinitions>-->
|
||||
<Grid.Effect>
|
||||
<DropShadowEffect BlurRadius="10" ShadowDepth="1" />
|
||||
</Grid.Effect>
|
||||
<!--<Border HorizontalAlignment="Right" BorderBrush="Gray" BorderThickness="1,1,0,1" Background="{StaticResource SliderText}" Width="80" CornerRadius="8,0,0,8"/>-->
|
||||
<!--<Border Grid.Column="2" HorizontalAlignment="Right" BorderBrush="Gray" BorderThickness="0,1,1,1" Background="{StaticResource SliderText}" Width="40" CornerRadius="0,8,8,0"/>-->
|
||||
<!--<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Tag}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14"/>-->
|
||||
<!--<TextBlock Grid.Column="2" Text="{Binding ElementName=PART_Track,Path=Value,StringFormat=\{0:N0\}}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="14" DataContext="{Binding}" />-->
|
||||
<Border Grid.Column="1" BorderBrush="Gray" BorderThickness="1" CornerRadius="8,0,0,8">
|
||||
<Track Grid.Column="1" Name="PART_Track">
|
||||
<Track.DecreaseRepeatButton>
|
||||
<RepeatButton Style="{StaticResource Slider_RepeatButton}"
|
||||
Command="Slider.DecreaseLarge"/>
|
||||
</Track.DecreaseRepeatButton>
|
||||
<Track.IncreaseRepeatButton>
|
||||
<RepeatButton Style="{StaticResource Slider_RepeatButton1}"
|
||||
Command="Slider.IncreaseLarge"/>
|
||||
</Track.IncreaseRepeatButton>
|
||||
<Track.Thumb>
|
||||
<Thumb Style="{StaticResource Slider_Thumb}"/>
|
||||
</Track.Thumb>
|
||||
</Track>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="飞行信息" />
|
||||
<Grid>
|
||||
|
||||
<Grid.Resources>
|
||||
<Style x:Key="CopterInfo_ComboBox"
|
||||
TargetType="ComboBox"
|
||||
BasedOn="{StaticResource {x:Type ComboBox}}">
|
||||
<Setter Property="MinWidth"
|
||||
Value="120" />
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Center" />
|
||||
</Style>
|
||||
<Style x:Key="CopterInfo_StackPanel"
|
||||
TargetType="StackPanel">
|
||||
<Setter Property="Orientation"
|
||||
Value="Horizontal" />
|
||||
<Setter Property="Margin"
|
||||
Value="0,2" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="180" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Orientation="Vertical" >
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="ComboBox"
|
||||
BasedOn="{StaticResource CopterInfo_ComboBox}" />
|
||||
<Style TargetType="StackPanel"
|
||||
BasedOn="{StaticResource CopterInfo_StackPanel}" />
|
||||
</StackPanel.Resources>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="ID:" />
|
||||
<TextBlock Width="30" Text="{Binding Path=Id}" />
|
||||
<TextBlock Text="VID:" />
|
||||
<TextBlock Width="30" Text="{Binding Path=VirtualId}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="已连接:" />
|
||||
<ContentPresenter Content="{Binding CommModuleConnected, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="已解锁:" />
|
||||
<ContentPresenter Content="{Binding IsUnlocked, Converter={StaticResource CheckSignConverter}, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="心跳数:" />
|
||||
<TextBlock Text="{Binding Path=HeartbeatCount}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="卫星数:" />
|
||||
<TextBlock Text="{Binding Path=SatCount}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="方向:" />
|
||||
<TextBlock Text="{Binding Path=Heading}" />
|
||||
</StackPanel>
|
||||
<!--<StackPanel>
|
||||
<TextBlock Text="Yaw:" />
|
||||
<TextBlock Text="{Binding Path=Yaw, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="纬度:" />
|
||||
<TextBlock Text="{Binding Path=Latitude}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="经度:" />
|
||||
<TextBlock Text="{Binding Path=Longitude}" />
|
||||
</StackPanel>-->
|
||||
<StackPanel>
|
||||
<TextBlock Text="高度:" />
|
||||
<TextBlock Text="{Binding Altitude, StringFormat=0.##}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="锁定类型:" />
|
||||
<TextBlock Text="{Binding GpsFixType}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="预检查状态:" />
|
||||
<TextBlock Text="{Binding CopterPreCheckPassStr}"
|
||||
Foreground="{Binding CopterPreCheckPass, Converter={StaticResource PrecheckToColorConverter}}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
<StackPanel Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Orientation="Vertical">
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="ComboBox"
|
||||
BasedOn="{StaticResource CopterInfo_ComboBox}" />
|
||||
<Style TargetType="StackPanel"
|
||||
BasedOn="{StaticResource CopterInfo_StackPanel}" />
|
||||
</StackPanel.Resources>
|
||||
<StackPanel Visibility="Hidden">
|
||||
<TextBlock Text="电压值:" />
|
||||
<TextBlock Text="{Binding Path=Voltage}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel>
|
||||
<TextBlock Text="电压值:" />
|
||||
<TextBlock Text="{Binding Path=Voltage}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="剩余电量:" />
|
||||
<TextBlock Text="{Binding Path=BatteryPer}" />
|
||||
<TextBlock Text="%" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="状态:" />
|
||||
<TextBlock Text="{Binding Path=CommModuleMode}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="纬度:" />
|
||||
<TextBlock Text="{Binding Latitude}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="经度:" />
|
||||
<TextBlock Text="{Binding Longitude}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="通信模块版本:" />
|
||||
<TextBlock Text="{Binding CommModuleVersion}" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="返回数据:" />
|
||||
<StackPanel Margin="0,0,0,0" Height="14" ToolTip="{Binding RetainInt}">
|
||||
<TextBlock Margin="0,-1,0,0" Text="{Binding Retain[3]}" />
|
||||
<TextBlock Margin="0,-1,0,0" Text="." />
|
||||
<TextBlock Margin="0,-1,0,0" Text="{Binding Retain[2]}" />
|
||||
<TextBlock Margin="0,-1,0,0" Text="." />
|
||||
<TextBlock Margin="0,-1,0,0" Text="{Binding Retain[1]}" />
|
||||
<TextBlock Margin="0,-1,0,0" Text="." />
|
||||
<TextBlock Margin="0,-1,0,0" Text="{Binding Retain[0]}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel >
|
||||
<TextBlock Text="最后异常:" />
|
||||
<TextBlock Text="{Binding CopterErrorString}"/>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
@ -38,10 +38,10 @@ namespace Plane.FormationCreator.Views
|
||||
var copter = sldChannel3.DataContext as ICopter;
|
||||
var selectedCopter = _copterManager.SelectedCopters.FirstOrDefault();
|
||||
if (copter == null || copter != selectedCopter) return; // copter != selectedCopter 说明正在切换 copter。
|
||||
var newCh3 = (ushort)e.NewValue;
|
||||
if (Math.Abs(copter.Channel3 - newCh3) > 5)
|
||||
var vol = (ushort)e.NewValue;
|
||||
if (vol<15)
|
||||
{
|
||||
await copter.SetChannelsAsync(ch3: newCh3);
|
||||
// sldChannel3.co
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
@ -10,21 +10,30 @@
|
||||
d:DesignHeight="600"
|
||||
d:DesignWidth="300">
|
||||
<UserControl.Resources>
|
||||
|
||||
|
||||
<ContextMenu x:Key="CoptersMenu" >
|
||||
<MenuItem Header="只显示当前选中"
|
||||
<MenuItem Header="显示当前选中"
|
||||
Foreground="White"
|
||||
Command="{Binding OnlyShowSelectedCoptersCommand}"/>
|
||||
<MenuItem Header="显示所有飞机"
|
||||
Foreground="White"
|
||||
Command="{Binding ShowAllCoptersCommand}"/>
|
||||
<MenuItem Header="显示自动编号"
|
||||
<MenuItem Header="所有编号(虚拟排序)"
|
||||
Foreground="White"
|
||||
Command="{Binding SwitchIdVirtualIdCommand}"/>
|
||||
Command="{Binding ShowAllIDCommand}"/>
|
||||
<MenuItem Header="虚拟编号(虚拟排序)"
|
||||
Foreground="White"
|
||||
Command="{Binding SortbyVIdCommand}"/>
|
||||
<MenuItem Header="真实编号(真实排序)"
|
||||
Foreground="White"
|
||||
Command="{Binding SortbyIdCommand}"/>
|
||||
</ContextMenu>
|
||||
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid Width="550">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="540"/>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
@ -60,24 +69,31 @@
|
||||
</MultiBinding>
|
||||
</Rectangle.Fill>
|
||||
</Rectangle>
|
||||
<TextBlock MaxWidth="100"
|
||||
<TextBlock MaxWidth="50" Visibility="{Binding DisplayID, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Text="{Binding Name}" />
|
||||
<TextBlock MaxWidth="100"
|
||||
Margin="2,0,0,0"
|
||||
Foreground="Red"
|
||||
<TextBlock Margin="2,0,0,0" MaxWidth="5" Visibility="{Binding DisplayVirtualId, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Text="[" />
|
||||
<TextBlock MaxWidth="50" Visibility="{Binding DisplayVirtualId, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Margin="0,0,0,0"
|
||||
Foreground="Yellow"
|
||||
Text="{Binding VirtualId}" />
|
||||
<TextBlock Margin="0,0,0,0" MaxWidth="5" Visibility="{Binding DisplayVirtualId, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
Text="]" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<StackPanel Grid.Row="1" Margin="0,0,0,5"
|
||||
<StackPanel Grid.Row="1" Margin="0,5,0,5"
|
||||
Orientation="Horizontal">
|
||||
<Button Content="间隔选中" Command="{Binding IntervalSelectCoptersCommand}"/>
|
||||
<Button Content="间隔选择" Command="{Binding IntervalSelectCoptersCommand}"/>
|
||||
<TextBlock Text="连选数量" Margin="5,5,0,0"/>
|
||||
<TextBox Width="30" Margin="5,0,0,0" Text="{Binding ContinuousNum}"/>
|
||||
<TextBox Width="30" Margin="5,0" VerticalContentAlignment="Center" Text="{Binding ContinuousNum}"/>
|
||||
<TextBlock Text="间隔数量" Margin="5,5,0,0"/>
|
||||
<TextBox Width="30" Margin="5,0,0,0" Text="{Binding IntervalNum}"/>
|
||||
<TextBox Width="30" Margin="5,0" VerticalContentAlignment="Center" Text="{Binding IntervalNum}"/>
|
||||
<TextBlock Text="间隔排数" Margin="5,5,0,0"/>
|
||||
<TextBox Width="30" Margin="5,0" VerticalContentAlignment="Center" Text="{Binding RowNum}"/>
|
||||
|
||||
<TextBlock Text="选中个数" Margin="5,5,0,0"/>
|
||||
<TextBlock Width="30" Margin="5,5,0,0" Text="{Binding CopterManager.SeletedCopterCount, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
@ -104,7 +120,7 @@
|
||||
Margin="5,0,0,0"
|
||||
Command="{Binding ShowLackCopterNumsCommand}"/>
|
||||
<Button Content="自动编号"
|
||||
Margin="5,0,0,0"
|
||||
Margin="5,0,0,0" Visibility="Collapsed"
|
||||
Command="{Binding AutoLocationNumsCommand}"/>
|
||||
<Button Content="设置"
|
||||
Margin="5,0,5,0"
|
||||
|
@ -16,6 +16,8 @@ using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Threading;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace Plane.FormationCreator.Views
|
||||
{
|
||||
@ -44,22 +46,47 @@ namespace Plane.FormationCreator.Views
|
||||
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
private void SelectitemMessage(ICopter copter)
|
||||
{
|
||||
if (copter == null)
|
||||
|
||||
////需要访问UI线程,可能在其他线程里面
|
||||
Dispatcher dispatcher = Dispatcher.FromThread(Thread.CurrentThread);
|
||||
if (dispatcher != null)
|
||||
{
|
||||
lvwDrones.SelectedItems.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_copterManager.shiftkeydown)
|
||||
if (copter == null)
|
||||
{
|
||||
lvwDrones.SelectedItems.Clear();
|
||||
lvwDrones.SelectedItem = copter;
|
||||
}
|
||||
else
|
||||
lvwDrones.SelectedItems.Add(copter);
|
||||
}
|
||||
{
|
||||
if (!_copterManager.shiftkeydown)
|
||||
{
|
||||
lvwDrones.SelectedItems.Clear();
|
||||
lvwDrones.SelectedItem = copter;
|
||||
}
|
||||
else
|
||||
lvwDrones.SelectedItems.Add(copter);
|
||||
}
|
||||
}else
|
||||
|
||||
|
||||
lvwDrones.Dispatcher.BeginInvoke(new Action(() =>
|
||||
{
|
||||
|
||||
if (copter == null)
|
||||
{
|
||||
lvwDrones.SelectedItems.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_copterManager.shiftkeydown)
|
||||
{
|
||||
lvwDrones.SelectedItems.Clear();
|
||||
lvwDrones.SelectedItem = copter;
|
||||
}
|
||||
else
|
||||
lvwDrones.SelectedItems.Add(copter);
|
||||
}
|
||||
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
private void SelectitemClearMessage(ICopter copter)
|
||||
|
30
Plane.FormationCreator/Views/InputDialog.xaml
Normal file
@ -0,0 +1,30 @@
|
||||
<Window x:Class="Plane.FormationCreator.Views.InputDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ignore="http://www.galasoft.ch/ignore"
|
||||
Title="输入窗口" SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen"
|
||||
ContentRendered="Window_ContentRendered" ResizeMode="NoResize">
|
||||
<Grid Margin="15">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Image Source="/FGCS;component/Resources/logo_big.png" Width="40" Height="40" Grid.RowSpan="2" Margin="20,0" />
|
||||
|
||||
<Label Name="lblQuestion" Grid.Column="1">最低更换电压:</Label>
|
||||
<TextBox Name="txtAnswer" Grid.Column="1" Grid.Row="1" MinWidth="250">15.6</TextBox>
|
||||
|
||||
<WrapPanel Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Right" Margin="0,15,0,0">
|
||||
<Button IsDefault="True" Name="btnDialogOk" Click="btnDialogOk_Click" MinWidth="60" Margin="0,0,10,0">确定</Button>
|
||||
<Button IsCancel="True" MinWidth="60">取消</Button>
|
||||
</WrapPanel>
|
||||
</Grid>
|
||||
</Window>
|
31
Plane.FormationCreator/Views/InputDialog.xaml.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace Plane.FormationCreator.Views
|
||||
{
|
||||
public partial class InputDialog : Window
|
||||
{
|
||||
public InputDialog(string question, string defaultAnswer = "")
|
||||
{
|
||||
InitializeComponent();
|
||||
lblQuestion.Content = question;
|
||||
txtAnswer.Text = defaultAnswer;
|
||||
}
|
||||
|
||||
private void btnDialogOk_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
this.DialogResult = true;
|
||||
}
|
||||
|
||||
private void Window_ContentRendered(object sender, EventArgs e)
|
||||
{
|
||||
txtAnswer.SelectAll();
|
||||
txtAnswer.Focus();
|
||||
}
|
||||
|
||||
public string Answer
|
||||
{
|
||||
get { return txtAnswer.Text; }
|
||||
}
|
||||
}
|
||||
}
|
58
Plane.FormationCreator/Views/LoginView.xaml
Normal file
@ -0,0 +1,58 @@
|
||||
<Window x:Class="Plane.FormationCreator.Views.LoginView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ignore="http://www.galasoft.ch/ignore"
|
||||
xmlns:Helper="clr-namespace:Plane.Util"
|
||||
mc:Ignorable="d ignore" Height="253.421" Width="463.894" Title="飞行魔方地面控制中心" ResizeMode="NoResize" WindowStartupLocation="CenterScreen"
|
||||
>
|
||||
|
||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto" />
|
||||
<RowDefinition Height="auto" />
|
||||
<RowDefinition Height="auto" />
|
||||
<RowDefinition Height="auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition></ColumnDefinition>
|
||||
<ColumnDefinition></ColumnDefinition>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Content="账号:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="0" Grid.Column="0" />
|
||||
|
||||
<TextBox
|
||||
Margin="10"
|
||||
Width="120" VerticalContentAlignment="Center"
|
||||
Text="{Binding Username, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left"
|
||||
Grid.Row="0" Grid.Column="1"/>
|
||||
|
||||
<Label Content="密码:" Margin="10" FontWeight="Bold" FontSize="14" Grid.Row="1" Grid.Column="0" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<PasswordBox
|
||||
x:Name="passwordBox"
|
||||
Margin="10"
|
||||
Width="120"
|
||||
HorizontalAlignment="Left" VerticalContentAlignment="Center" Grid.Row="1" Grid.Column="1"
|
||||
PasswordChar="*"
|
||||
MaxLength="20"
|
||||
Helper:PasswordBoxHelper.Attach="True"
|
||||
Helper:PasswordBoxHelper.Password="{Binding Path=Password ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
|
||||
|
||||
|
||||
<Button Content="取消" Grid.Row="2" Grid.Column="0" Margin="10,5,10,5" Height="40" Width="80" IsCancel="True"
|
||||
Command="{Binding ExitCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" />
|
||||
<Button Content="登录" Grid.Row="2" Grid.Column="1" Margin="50,5,10,5" Height="40" Width="80" IsDefault="True"
|
||||
Command="{Binding LoginCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" />
|
||||
<CheckBox x:Name="checkBox" Content="保存密码" Grid.Column="1" HorizontalAlignment="Right" Margin="0,18.033,-85.353,12.168" Grid.Row="1" Width="75.353"
|
||||
IsChecked="{Binding SavePassword}"/>
|
||||
<Label x:Name="about_ver" Content="版本:" HorizontalContentAlignment="Right" Margin="0,10,-85,0" Grid.Row="3" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
|
||||
|
||||
</Grid>
|
||||
|
||||
</Window>
|
30
Plane.FormationCreator/Views/LoginView.xaml.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using Microsoft.Practices.ServiceLocation;
|
||||
using Plane.FormationCreator.Formation;
|
||||
using Plane.FormationCreator.ViewModels;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Plane.FormationCreator.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Description for LoginView.
|
||||
/// </summary>
|
||||
public partial class LoginView : Window
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LoginView class.
|
||||
/// </summary>
|
||||
public LoginView()
|
||||
{
|
||||
InitializeComponent();
|
||||
LoginViewModel loginViewModel = ServiceLocator.Current.GetInstance<LoginViewModel>();
|
||||
this.DataContext = loginViewModel;
|
||||
var version = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
about_ver.Content = "版本:" + version.ToString() + "(飞控兼容:"+ _copterManager.FC_VER_STRING + ")";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -41,16 +41,16 @@
|
||||
>
|
||||
<CheckBox Grid.Row="0" Content="所有航点" Margin="5,5,0,0"
|
||||
Click="showallpoint_Checked"
|
||||
Foreground="White" IsChecked="True"
|
||||
Foreground="White" IsChecked="True" Visibility="Collapsed"
|
||||
/>
|
||||
<CheckBox Grid.Row="0" Content="计划航线" Margin="5,5,0,0"
|
||||
<CheckBox Grid.Row="0" Content="飞行航线" Margin="5,5,0,0"
|
||||
Click="showpanline_Checked"
|
||||
Foreground="White"
|
||||
Foreground="White" IsChecked="True"
|
||||
/>
|
||||
|
||||
<CheckBox Grid.Row="0" Content="实时航线" Margin="5,5,0,0"
|
||||
Foreground="White"
|
||||
Click="showrealtimeline_Checked" />
|
||||
Click="showrealtimeline_Checked" Visibility="Collapsed" />
|
||||
|
||||
<ComboBox x:Name="MapSelectionComboBox"
|
||||
HorizontalAlignment="Right"
|
||||
|
@ -41,25 +41,33 @@ namespace Plane.FormationCreator.Views
|
||||
/// </summary>
|
||||
public partial class MapView : UserControl
|
||||
{
|
||||
public void initmap()
|
||||
{
|
||||
|
||||
gmap.MinZoom = 2; //最小缩放
|
||||
gmap.MaxZoom = 30; //最大缩放
|
||||
gmap.Zoom = 19; //当前缩放
|
||||
gmap.ShowCenter = true; //不显示中心十字点
|
||||
gmap.DragButton = MouseButton.Middle; //中键拖拽地图
|
||||
}
|
||||
|
||||
public MapView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.DataContext = ServiceLocator.Current.GetInstance<MapViewModel>();
|
||||
gmap.MapProvider = GMapProviders.BingHybridMap; //google china 地图
|
||||
gmap.MinZoom = 2; //最小缩放
|
||||
gmap.MaxZoom = 30; //最大缩放
|
||||
gmap.Zoom = 19; //当前缩放
|
||||
gmap.ShowCenter = false; //不显示中心十字点
|
||||
gmap.DragButton = MouseButton.Middle; //左键拖拽地图
|
||||
initmap();
|
||||
gmap.Position = new LatLng(40.07734857737275, 116.34323845862502).ToGCJ02();
|
||||
|
||||
_mapManager.MapView = this;
|
||||
_mapManager.SetCenterGetter(() => new LatLng { Lat = gmap.Position.ToWGS84().Lat, Lng = gmap.Position.ToWGS84().Lng });
|
||||
|
||||
_flightTaskManager.TaskAdded += FlightTaskManager_TaskAdded;
|
||||
_flightTaskManager.TaskDeled += FlightTaskManager_TaskDeled;
|
||||
_flightTaskManager.OnOriginalSet += FlightTaskManager_SetOriginal;
|
||||
|
||||
/*
|
||||
Task.Factory.StartNew(async () =>
|
||||
{
|
||||
int delay = 500;
|
||||
@ -73,7 +81,7 @@ namespace Plane.FormationCreator.Views
|
||||
await Task.Delay(delay);
|
||||
}
|
||||
});
|
||||
|
||||
*/
|
||||
_copterManager.SelectedCoptersChanged += (sender, e) =>
|
||||
{
|
||||
//if (AppEx.Instance.CurrentMode.IsForTasks())
|
||||
@ -87,11 +95,18 @@ namespace Plane.FormationCreator.Views
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
//选中任务时触发
|
||||
case nameof(FlightTaskManager.SelectedTaskIndex):
|
||||
//_copterDrawings有多少架飞机(航点)
|
||||
foreach (var item in _copterDrawings)
|
||||
{
|
||||
var copterDrawing = item.Value;
|
||||
//设置选中的航点白边和下面任务块的白影
|
||||
|
||||
copterDrawing.ShowWaypoint(_flightTaskManager.SelectedTaskIndex);
|
||||
|
||||
copterDrawing.SetTaskEffect(_flightTaskManager.SelectedTaskIndex);
|
||||
//画计划航线
|
||||
copterDrawing.ResetRoute(_flightTaskManager.SelectedTaskIndex);
|
||||
}
|
||||
break;
|
||||
@ -125,30 +140,7 @@ namespace Plane.FormationCreator.Views
|
||||
|
||||
gmap.MouseDoubleClick += async (sender, e) =>
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
//// Test
|
||||
//var pos = map.ViewportPointToLocation(e.GetPosition(map));
|
||||
//AddOrMoveCopter(new FakeCopter(pos.Latitude, pos.Longitude));
|
||||
|
||||
// 林俊清, 20150930, AppMode 存在意义已不大;只有正在运行任务的时候才不允许指点。
|
||||
//if (AppEx.Current.AppMode != AppMode.ControllingCopters) return;
|
||||
if (_flightTaskManager.IsPaused == false) return;
|
||||
|
||||
var copters = _copterManager.AcceptingControlCopters;
|
||||
|
||||
if (!copters.Any()) return;
|
||||
|
||||
Point clickPoint = e.GetPosition(gmap);
|
||||
var pos = gmap.FromLocalToLatLng((int)clickPoint.X, (int)clickPoint.Y);
|
||||
var centerLat = copters.Average(c => c.Latitude);
|
||||
var centerLng = copters.Average(c => c.Longitude);
|
||||
var latDelta = pos.Lat - centerLat;
|
||||
var lngDelta = pos.Lng - centerLng;
|
||||
|
||||
|
||||
await Task.WhenAll(copters.Select(copter => copter.FlyToAsync(copter.Latitude + latDelta, copter.Longitude + lngDelta, copter.Altitude)));
|
||||
};
|
||||
};
|
||||
|
||||
var center = _appConfig.Center;
|
||||
gmap.Position = new LatLng(center.Lat, center.Lng).ToGCJ02();
|
||||
@ -170,6 +162,19 @@ namespace Plane.FormationCreator.Views
|
||||
originalMarker.Position = gmap.FromLocalToLatLng((int)wpPos.X, (int)wpPos.Y);
|
||||
//MapLayer.SetPosition(original, gmap.ViewportPointToLocation(wpPos));
|
||||
}
|
||||
|
||||
|
||||
if (observerMarker != null && gmap.Markers.Contains(observerMarker))
|
||||
{
|
||||
PointLatLng location = new LatLng(_flightTaskManager.ObserverLat, _flightTaskManager.ObserverLng).ToGCJ02();
|
||||
GPoint wpPos = gmap.FromLatLngToLocal(location);
|
||||
//Point wpPos = gmap.LocationToViewportPoint(location);
|
||||
wpPos.X -= (long)ORIGIN_RADIUS;
|
||||
wpPos.Y -= (long)ORIGIN_RADIUS;
|
||||
observerMarker.Position = gmap.FromLocalToLatLng((int)wpPos.X, (int)wpPos.Y);
|
||||
//MapLayer.SetPosition(original, gmap.ViewportPointToLocation(wpPos));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
GMapMarker rectangleMarker = null;
|
||||
@ -263,6 +268,9 @@ namespace Plane.FormationCreator.Views
|
||||
|
||||
gmap.MouseMove += new MouseEventHandler(OriginalMove);
|
||||
gmap.MouseLeftButtonUp += new MouseButtonEventHandler(OriginalMouseUp);
|
||||
|
||||
gmap.MouseMove += new MouseEventHandler(observerMove);
|
||||
gmap.MouseLeftButtonUp += new MouseButtonEventHandler(observerMouseUp);
|
||||
}
|
||||
|
||||
private CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
@ -273,6 +281,7 @@ namespace Plane.FormationCreator.Views
|
||||
const string COPTER_TAG = "Copter";
|
||||
const string WAYPOINT_TAG = "Waypoint";
|
||||
const string ORIGINALPOINT_TAG = "Originalpoint";
|
||||
const string OBSERVER_TAG = "Observerpoint";
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
@ -322,6 +331,8 @@ namespace Plane.FormationCreator.Views
|
||||
|
||||
private void Copter_LocationChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!_flightTaskManager.TaskRun_2D) return; //不在3D模式运行直接退出
|
||||
|
||||
var copter = sender as ICopter;
|
||||
if (App.Current.CheckAccess())
|
||||
{
|
||||
@ -352,6 +363,19 @@ namespace Plane.FormationCreator.Views
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void ShowAllWaypoint()
|
||||
{
|
||||
|
||||
foreach (var item in _copterDrawings)
|
||||
{
|
||||
var copterDrawing = item.Value;
|
||||
copterDrawing.ShowAllWaypoint();
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearCopters()
|
||||
{
|
||||
/*
|
||||
@ -369,6 +393,11 @@ namespace Plane.FormationCreator.Views
|
||||
*/
|
||||
|
||||
gmap.Markers.Clear();
|
||||
|
||||
|
||||
|
||||
//_copterManager.Copters.ForEach(copter => _copterDrawings[copter]=null );
|
||||
|
||||
_copterDrawings.Clear();
|
||||
}
|
||||
|
||||
@ -390,14 +419,29 @@ namespace Plane.FormationCreator.Views
|
||||
|
||||
private void FlightTaskManager_TaskAdded(object sender, FlightTaskAddedEventArgs e)
|
||||
{
|
||||
//给每个任务在地图上添加航点
|
||||
foreach (var info in e.AddedTask.SingleCopterInfos)
|
||||
{
|
||||
var drawingInfo = _copterDrawings[info.Copter];
|
||||
//计算位置
|
||||
var location = new Microsoft.Maps.MapControl.WPF.Location(info.TargetLat, info.TargetLng, info.TargetAlt);
|
||||
drawingInfo.AddWaypoint(location, e.AddedTask.TaskType);
|
||||
//添加航点
|
||||
drawingInfo.AddWaypoint(location, e.AddedTask.TaskType,e.AddedTask);
|
||||
}
|
||||
}
|
||||
|
||||
private void FlightTaskManager_TaskDeled(object sender, FlightTaskDeledEventArgs e)
|
||||
{
|
||||
//清除每架飞机的这个任务的航点
|
||||
// foreach (var info in e.DeledTask.SingleCopterInfos)
|
||||
// {
|
||||
// _copterDrawings[info.Copter].Waypoints.RemoveAt(e.TaskIndex);
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
GMapMarker observerMarker = null;
|
||||
Microsoft.Expression.Shapes.RegularPolygon observer = null;
|
||||
GMapMarker originalMarker = null;
|
||||
Microsoft.Expression.Shapes.RegularPolygon original = null;
|
||||
const double ORIGIN_RADIUS = 12;
|
||||
@ -436,8 +480,131 @@ namespace Plane.FormationCreator.Views
|
||||
_flightTaskManager.OriginLng = location.Lng;
|
||||
original.MouseLeftButtonDown += new MouseButtonEventHandler(OriginalMouseDown);
|
||||
|
||||
///加入或者改变观测点用于3D模拟
|
||||
|
||||
if (gmap.Markers.Contains(observerMarker))
|
||||
gmap.Markers.Remove(observerMarker);
|
||||
observer = new Microsoft.Expression.Shapes.RegularPolygon
|
||||
{
|
||||
Tag = OBSERVER_TAG,
|
||||
Fill = new SolidColorBrush(Color.FromArgb(200, 3, 155, 3)),
|
||||
Stroke = new SolidColorBrush(Color.FromArgb(200, 3, 80, 238)),
|
||||
StrokeThickness = 1,
|
||||
Width = ORIGIN_RADIUS *2,
|
||||
Height = ORIGIN_RADIUS * 2,
|
||||
InnerRadius = 1,
|
||||
PointCount = 6,
|
||||
};
|
||||
|
||||
if (_flightTaskManager.ObserverLat == 0)
|
||||
{
|
||||
Tuple<double, double> observationLatLng = null;
|
||||
|
||||
|
||||
//第一列到中间的距离
|
||||
float midColDistance = (_flightTaskManager.ColumnCount - 1) * _flightTaskManager.ColumnDistance / 2;
|
||||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||||
_flightTaskManager.OriginLat,
|
||||
_flightTaskManager.OriginLng,
|
||||
_flightTaskManager.Orientation + 90,
|
||||
midColDistance);
|
||||
observationLatLng = GeographyUtils.CalcLatLngSomeMetersAway2D(
|
||||
observationLatLng.Item1,
|
||||
observationLatLng.Item2,
|
||||
_flightTaskManager.Orientation + 180,
|
||||
midColDistance * 4);
|
||||
|
||||
|
||||
_flightTaskManager.ObserverLat = observationLatLng.Item1;
|
||||
_flightTaskManager.ObserverLng = observationLatLng.Item2;
|
||||
}
|
||||
|
||||
//_flightTaskManager.ObserverLat = _flightTaskManager.OriginLat;
|
||||
//_flightTaskManager.ObserverLng = _flightTaskManager.OriginLng;
|
||||
|
||||
PointLatLng Observerlocation = new LatLng(_flightTaskManager.ObserverLat, _flightTaskManager.ObserverLng).ToGCJ02();
|
||||
GPoint opoint = gmap.FromLatLngToLocal(Observerlocation);
|
||||
|
||||
opoint.X -= (long)ORIGIN_RADIUS;
|
||||
opoint.Y -= (long)ORIGIN_RADIUS;
|
||||
|
||||
|
||||
mapLocation = gmap.FromLocalToLatLng((int)opoint.X, (int)opoint.Y);
|
||||
|
||||
observerMarker = new GMapMarker(mapLocation);
|
||||
observerMarker.ZIndex = 200;
|
||||
observerMarker.Shape = observer;
|
||||
observerDrag = false;
|
||||
observer.MouseLeftButtonDown += new MouseButtonEventHandler(observerMouseDown);
|
||||
|
||||
|
||||
gmap.Markers.Add(observerMarker);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private bool observerDrag = false;
|
||||
double observerX = 0;
|
||||
double observerY = 0;
|
||||
|
||||
|
||||
private void observerMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
observerDrag = true;
|
||||
|
||||
gmap.CanDragMap = false;
|
||||
var originPoint = e.GetPosition(gmap);
|
||||
observerX = originPoint.X;
|
||||
observerX = originPoint.Y;
|
||||
|
||||
var posInObject = e.GetPosition(observer);
|
||||
wpOffsetX = posInObject.X;
|
||||
wpOffsetY = posInObject.Y;
|
||||
}
|
||||
|
||||
private void observerMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (observerDrag)
|
||||
{
|
||||
Point eventPos = e.GetPosition(gmap);
|
||||
var leftTopPos = new Point(eventPos.X - wpOffsetX, eventPos.Y - wpOffsetY);
|
||||
observerMarker.Position = gmap.FromLocalToLatLng((int)leftTopPos.X, (int)leftTopPos.Y);
|
||||
//MapLayer.SetPosition(original, map.ViewportPointToLocation(leftTopPos));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void observerMouseUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (observerDrag)
|
||||
{
|
||||
Point eventPos = e.GetPosition(gmap);
|
||||
var centrePos = new Point(eventPos.X - wpOffsetX + ORIGIN_RADIUS, eventPos.Y - wpOffsetY + ORIGIN_RADIUS);
|
||||
PointLatLng location = gmap.FromLocalToLatLng((int)centrePos.X, (int)centrePos.Y);
|
||||
_flightTaskManager.ObserverLat = location.Lat;
|
||||
_flightTaskManager.ObserverLng = location.Lng;
|
||||
// original.ToolTip = location.ToString();
|
||||
//Clipboard.SetDataObject(string.Format("{0},{1}", location.Lat, location.Lng), true);
|
||||
observerDrag = false;
|
||||
gmap.CanDragMap = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private bool originaDrag = false;
|
||||
double originX = 0;
|
||||
double originY = 0;
|
||||
@ -501,11 +668,7 @@ namespace Plane.FormationCreator.Views
|
||||
break;
|
||||
}
|
||||
|
||||
gmap.MinZoom = 2; //最小缩放
|
||||
gmap.MaxZoom = 30; //最大缩放
|
||||
gmap.Zoom = 19; //当前缩放
|
||||
gmap.ShowCenter = false; //不显示中心十字点
|
||||
gmap.DragButton = MouseButton.Left; //左键拖拽地图
|
||||
initmap();
|
||||
|
||||
/*
|
||||
switch ((e.AddedItems[0] as FrameworkElement).Tag.ToString())
|
||||
@ -559,7 +722,8 @@ namespace Plane.FormationCreator.Views
|
||||
foreach (var item in _copterDrawings)
|
||||
{
|
||||
var copterDrawing = item.Value;
|
||||
copterDrawing.SetShowroute(chk.IsChecked);
|
||||
_flightTaskManager.showroute = chk.IsChecked??false;
|
||||
copterDrawing.UpdateShowroute();
|
||||
}
|
||||
|
||||
}
|
||||
@ -573,9 +737,6 @@ namespace Plane.FormationCreator.Views
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void RemoveTileLayers()
|
||||
{
|
||||
/*
|
||||
@ -617,9 +778,7 @@ namespace Plane.FormationCreator.Views
|
||||
grid_bg.Background = ib;
|
||||
gmap.Opacity = 0.5;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class LocationExtensions
|
||||
|
@ -17,20 +17,48 @@ using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using Plane.Geography;
|
||||
using Plane.FormationCreator.Util;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Plane.FormationCreator.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for ModifyTaskView.xaml
|
||||
/// </summary>
|
||||
|
||||
public partial class ModifyTaskView : UserControl
|
||||
{
|
||||
private int[] defcolor= { 255, 65280, 16711680, 65535 , 16711935, 16776960,0 };
|
||||
ModifyTaskViewModel _modifyTaskViewModel = ServiceLocator.Current.GetInstance<ModifyTaskViewModel>();
|
||||
CopterManager _copterManager = ServiceLocator.Current.GetInstance<CopterManager>();
|
||||
|
||||
private childItem FindVisualChild<childItem>(DependencyObject obj)
|
||||
where childItem : DependencyObject
|
||||
{
|
||||
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
|
||||
{
|
||||
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
|
||||
if (child != null && child is childItem)
|
||||
{
|
||||
return (childItem)child;
|
||||
}
|
||||
else
|
||||
{
|
||||
childItem childOfChild = FindVisualChild<childItem>(child);
|
||||
if (childOfChild != null)
|
||||
return childOfChild;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public ModifyTaskView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.DataContext = _modifyTaskViewModel;
|
||||
|
||||
|
||||
|
||||
|
||||
if (!VersionControl.IsFullVersion)
|
||||
{
|
||||
//lightDesign.Visibility = Visibility.Collapsed;
|
||||
@ -39,28 +67,113 @@ namespace Plane.FormationCreator.Views
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// distanceCopters.Text;
|
||||
/*
|
||||
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
|
||||
|
||||
int firstIndex = int.Parse( firstCopter.Text );
|
||||
int secondIndex = int.Parse( secondCopter.Text );
|
||||
|
||||
if (_flightTaskManager.SelectedTask != null)
|
||||
{
|
||||
var firstCopterInfo = _flightTaskManager.SelectedTask.SingleCopterInfos[firstIndex-1];
|
||||
var secondCopterInfo = _flightTaskManager.SelectedTask.SingleCopterInfos[secondIndex-1];
|
||||
double distance = GeographyUtils.CalcDistance(firstCopterInfo.TargetLat, firstCopterInfo.TargetLng, firstCopterInfo.TargetAlt,
|
||||
secondCopterInfo.TargetLat, secondCopterInfo.TargetLng, secondCopterInfo.TargetAlt);
|
||||
|
||||
distanceCopters.Text = ((double)Math.Round(distance*100)/100).ToString();
|
||||
|
||||
}
|
||||
/*
|
||||
DependencyObject myListItem = LEDItems.ItemContainerGenerator.ContainerFromItem(LEDItems.Items.CurrentItem);
|
||||
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListItem);
|
||||
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
|
||||
ComboBox ledcomb = (ComboBox)myDataTemplate.FindName("cmbTemplateLEDMode", myContentPresenter);
|
||||
// ledcomb.SelectedIndex = 2;
|
||||
*/
|
||||
|
||||
|
||||
// distanceCopters.Text;
|
||||
/*
|
||||
FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
|
||||
|
||||
int firstIndex = int.Parse( firstCopter.Text );
|
||||
int secondIndex = int.Parse( secondCopter.Text );
|
||||
|
||||
if (_flightTaskManager.SelectedTask != null)
|
||||
{
|
||||
var firstCopterInfo = _flightTaskManager.SelectedTask.SingleCopterInfos[firstIndex-1];
|
||||
var secondCopterInfo = _flightTaskManager.SelectedTask.SingleCopterInfos[secondIndex-1];
|
||||
double distance = GeographyUtils.CalcDistance(firstCopterInfo.TargetLat, firstCopterInfo.TargetLng, firstCopterInfo.TargetAlt,
|
||||
secondCopterInfo.TargetLat, secondCopterInfo.TargetLng, secondCopterInfo.TargetAlt);
|
||||
|
||||
distanceCopters.Text = ((double)Math.Round(distance*100)/100).ToString();
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OnCBLoaded(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void TextBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
System.Windows.Forms.ColorDialog colorDialog = new System.Windows.Forms.ColorDialog();
|
||||
colorDialog.CustomColors = defcolor;
|
||||
try
|
||||
{
|
||||
colorDialog.Color = ColorTranslator.FromHtml("#" + (sender as TextBox).Text);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
colorDialog.Color = System.Drawing.Color.White;
|
||||
}
|
||||
|
||||
|
||||
if (colorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||
{
|
||||
defcolor = colorDialog.CustomColors;
|
||||
(sender as TextBox).Text = String.Format("{0:X2}", colorDialog.Color.R) +
|
||||
String.Format("{0:X2}", colorDialog.Color.G) +
|
||||
String.Format("{0:X2}", colorDialog.Color.B);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void cmbTemplateLEDMode_Initialized(object sender, EventArgs e)
|
||||
{
|
||||
int selind = 0;
|
||||
ComboBox cb = (ComboBox)sender;
|
||||
selind = cb.SelectedIndex;
|
||||
cb.Items.Clear();
|
||||
if (_copterManager.FC_VER_NO == 1)
|
||||
{
|
||||
cb.Items.Add("常亮"); //0
|
||||
cb.Items.Add("同步闪烁(单色)"); //1
|
||||
cb.Items.Add("异步闪烁(随机)"); //2
|
||||
cb.Items.Add("渐亮"); //3
|
||||
cb.Items.Add("渐暗"); //4
|
||||
cb.Items.Add("呼吸灯(单色)"); //5
|
||||
cb.Items.Add("同步闪烁(随机)"); //6
|
||||
cb.Items.Add("异步闪烁(单色)"); //7
|
||||
cb.Items.Add("拉烟"); //8
|
||||
}
|
||||
else
|
||||
{
|
||||
cb.Items.Add("常亮"); //0
|
||||
cb.Items.Add("同步闪烁(单色)"); //1
|
||||
cb.Items.Add("异步闪烁(随机)"); //2
|
||||
cb.Items.Add("同步闪烁(随机)"); //3
|
||||
cb.Items.Add("异步闪烁(单色)"); //4
|
||||
cb.Items.Add("渐亮"); //5
|
||||
cb.Items.Add("渐暗"); //6
|
||||
cb.Items.Add("同步呼吸灯(单色)"); //7
|
||||
cb.Items.Add("同步呼吸灯(随机色)"); //8
|
||||
cb.Items.Add("异步呼吸(单色)"); //9
|
||||
cb.Items.Add("异步呼吸(随机色)"); //10
|
||||
cb.Items.Add("变色(单色)"); //11
|
||||
cb.Items.Add("变色(随机)"); //12
|
||||
cb.Items.Add("异步变色(单色)"); //13
|
||||
cb.Items.Add("异步变色(随机)"); //14
|
||||
cb.Items.Add("拉烟"); //15
|
||||
cb.Items.Add("抛物"); //16
|
||||
}
|
||||
cb.SelectedIndex = selind;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,78 +5,114 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
xmlns:c="http://metro.mahapps.com/winfx/xaml/controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="800"
|
||||
Height="350" Width="1500" WindowStartupLocation="CenterScreen" Background="#FF2D2D2D" BorderBrush="#FF039AF0">
|
||||
mc:Ignorable="d" d:DesignWidth="800"
|
||||
Height="426" Width="1500" WindowStartupLocation="CenterScreen" Background="#FF2D2D2D" BorderBrush="#FF039AF0" Title="RTK控制" ResizeMode="NoResize">
|
||||
<Grid Margin="0,0,0,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Margin="5" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<ComboBox Width="120" Height="25" Foreground="White" SelectedIndex="0"
|
||||
ItemsSource="{Binding serialPorts, Mode=OneWay}"
|
||||
<Border Margin="10,5" BorderBrush="#FFB9B8B8" BorderThickness="1">
|
||||
<StackPanel Margin="0" Orientation="Vertical">
|
||||
<StackPanel Margin="0" Orientation="Horizontal">
|
||||
<ComboBox Width="120" Height="25" Foreground="White" SelectedIndex="0"
|
||||
Margin="10" ItemsSource="{Binding serialPorts, Mode=OneWay}"
|
||||
SelectedValue="{Binding SerialPortsSelectdValue}"
|
||||
DropDownOpened="ComboBox_DropDownOpened"/>
|
||||
<Button Margin="6" Width="80" Height="28"
|
||||
<Button Margin="6" Width="90" Height="28"
|
||||
Content="{Binding RtcmManager.Rtcmthreadrun,Converter={StaticResource SendConverter}}"
|
||||
Command="{Binding ConnectRtcmCommand}"/>
|
||||
<Label Margin="6,6,0,6" Height="28" Content="总数:"/>
|
||||
<Label Margin="0,6,6,6" Height="28" Content="{Binding RtcmManager.rtcmInfoList.Count,UpdateSourceTrigger=PropertyChanged}"></Label>
|
||||
<Label Margin="6,6,0,6" Height="28" Content="卫星数:"/>
|
||||
<Label Margin="0,6,6,6" Height="28" Content="{Binding RtcmManager.rtcmInfoList.Count,UpdateSourceTrigger=PropertyChanged}"></Label>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="6,0,0,2" Orientation="Horizontal">
|
||||
<CheckBox x:Name="checkBox" Content="双通道模式 (同时发到广播端口)"
|
||||
Margin="4,5,5,0" Width="190"
|
||||
IsChecked="{Binding ResendToComMK}"/>
|
||||
|
||||
<CheckBox x:Name="cBsmalldata" Content="低带宽模式"
|
||||
Margin="20,5,5,0" Width="95"
|
||||
IsChecked="{Binding SmalldataMK}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="6,0,0,2" Orientation="Horizontal">
|
||||
<TextBlock Margin="23,1,0,0" Text="{Binding BoardPortsStatus}"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
|
||||
</StackPanel>
|
||||
|
||||
</Border>
|
||||
|
||||
<Border Margin="10,5" BorderBrush="#FFB9B8B8" BorderThickness="1">
|
||||
<StackPanel Margin="5" Orientation="Vertical">
|
||||
<StackPanel Margin="5" Orientation="Horizontal">
|
||||
<TextBlock Text="Input data rate "/>
|
||||
<TextBlock Text="接收速率: "/>
|
||||
<TextBlock TextAlignment="Right" Width="30"
|
||||
Text="{Binding RtcmManager.Bps}"/>
|
||||
<TextBlock Text=" bps: put data rate "/>
|
||||
<TextBlock Text=" 字节/秒;发送速率:"/>
|
||||
<TextBlock TextAlignment="Right" Width="30"
|
||||
Text="{Binding RtcmManager.Bpsusefull}"/>
|
||||
<TextBlock Text=" bps sent"/>
|
||||
<TextBlock Text=" 字节/秒"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="5" Orientation="Horizontal">
|
||||
<TextBlock Text="Messages seen "/>
|
||||
<TextBlock Text="{Binding RtcmManager.Messages_seen}"
|
||||
/>
|
||||
<TextBlock Text="消息: "/>
|
||||
<TextBlock Text="{Binding RtcmManager.Messages_seen}"/>
|
||||
|
||||
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0" Orientation="Horizontal">
|
||||
<TextBlock Margin="5" Text="L1信号强度"/>
|
||||
<Rectangle Margin="0,0,15,0" Width="20" Height="20" Fill="#3EBE55"/>
|
||||
<TextBlock Margin="5" Text="L2信号强度"/>
|
||||
<Rectangle Margin="0,0,15,0" Width="20" Height="20" Fill="#ACACEC"/>
|
||||
<TextBlock Margin="5" Text="L1/L2重合"/>
|
||||
<Rectangle Margin="0,0,15,0" Width="20" Height="20" Fill="#04845C"/>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
|
||||
|
||||
|
||||
|
||||
</Border>
|
||||
|
||||
<Border Margin="10,5" BorderBrush="#FFB9B8B8" BorderThickness="1">
|
||||
<StackPanel Margin="5" Width="488">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Margin="5" Text="Base"/>
|
||||
<TextBlock Margin="5" Text="基站位置"/>
|
||||
<Rectangle Margin="0,0,15,0" Width="20" Height="20"
|
||||
Fill="{Binding RtcmManager.BaseState,Converter={StaticResource ColorConverter}}"/>
|
||||
<TextBlock Margin="5" Text="Gps"/>
|
||||
<Rectangle Margin="0,0,15,0" Width="20" Height="20"
|
||||
Fill="{Binding RtcmManager.GlonassState,Converter={StaticResource ColorConverter}}"/>
|
||||
Fill="{Binding RtcmManager.GpsState ,Converter={StaticResource ColorConverter}}"/>
|
||||
<TextBlock Margin="5" Text="Glonass"/>
|
||||
<Rectangle Margin="0,0,15,0" Width="20" Height="20"
|
||||
Fill="{Binding RtcmManager.GpsState,Converter={StaticResource ColorConverter}}"/>
|
||||
<TextBlock Margin="5" Text="Beidou"/>
|
||||
Fill="{Binding RtcmManager.GlonassState,Converter={StaticResource ColorConverter}}"/>
|
||||
<TextBlock Margin="5" Text="北斗"/>
|
||||
<Rectangle Margin="0,0,15,0" Width="20" Height="20"
|
||||
Fill="{Binding RtcmManager.BeidouState,Converter={StaticResource ColorConverter}}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" >
|
||||
<TextBlock Margin="5" Text="RTCM Base"/>
|
||||
<TextBlock Margin="5" Text="RTCM 位置"/>
|
||||
<TextBlock Margin="2,5" Text="{Binding RtcmManager.StationLat}"/>
|
||||
<TextBlock Margin="2,5" Text="{Binding RtcmManager.StationLng}"/>
|
||||
<TextBlock Margin="2,5" Text="{Binding RtcmManager.StationAlt}"/>
|
||||
<TextBlock Margin="2,5" Text="-"/>
|
||||
<TextBlock Margin="2,5" Text="{Binding RtcmManager.StationTime}"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<ItemsControl Grid.Row="1"
|
||||
ItemsSource="{Binding Path = RtcmManager.rtcmInfoList}"
|
||||
ItemsSource="{Binding Path = RtcmManager.rtcmInfoList}" Margin="0,0.333,-0.333,-80" Height="303" VerticalAlignment="Top"
|
||||
>
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
@ -95,19 +131,34 @@
|
||||
Minimum="25"
|
||||
Maximum="55"
|
||||
Grid.RowSpan="2"
|
||||
Value="{Binding Snr, UpdateSourceTrigger=PropertyChanged}"/>
|
||||
<StackPanel Orientation ="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
|
||||
Value="{Binding Snr, UpdateSourceTrigger=PropertyChanged}"
|
||||
|
||||
/>
|
||||
|
||||
<ProgressBar x:Name="BarSnr2"
|
||||
Margin="0.5"
|
||||
Orientation="Vertical"
|
||||
Minimum="25"
|
||||
Maximum="55"
|
||||
Grid.RowSpan="2"
|
||||
Foreground="Blue"
|
||||
Value="{Binding Snr2, UpdateSourceTrigger=PropertyChanged}"
|
||||
Opacity="0.25"
|
||||
|
||||
/>
|
||||
<StackPanel Orientation ="Vertical" VerticalAlignment="Top" HorizontalAlignment="Center">
|
||||
<StackPanel Orientation ="Horizontal">
|
||||
<TextBlock Text="{Binding Sys,UpdateSourceTrigger=PropertyChanged}" Foreground="Black"></TextBlock>
|
||||
<TextBlock Text="{Binding Prn,UpdateSourceTrigger=PropertyChanged}" Foreground="Black"></TextBlock>
|
||||
</StackPanel>
|
||||
<TextBlock Margin="0,20,0,0" Text="{Binding Snr,UpdateSourceTrigger=PropertyChanged}" Foreground="Black"></TextBlock>
|
||||
<TextBlock Margin="0,5,0,0" Text="{Binding Snr,UpdateSourceTrigger=PropertyChanged}" Foreground="Black"></TextBlock>
|
||||
<TextBlock Margin="0,5,0,0" Text="{Binding Snr2,UpdateSourceTrigger=PropertyChanged}" Foreground="Blue" ></TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation ="Vertical" HorizontalAlignment="Center">
|
||||
<Line Stroke="Red" X2="1000" StrokeThickness="3" />
|
||||
<TextBlock Text="40" Foreground="Black"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
|
||||
</Grid>
|
||||
|
||||
|
@ -5,20 +5,20 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
mc:Ignorable="d"
|
||||
Title="设置摆放" Height="301.595" Width="364.628" WindowStartupLocation="CenterScreen" WindowStyle="ToolWindow" ResizeMode="NoResize">
|
||||
<Grid Margin="90,45">
|
||||
Title="设置摆放" Height="290.592" Width="364.628" WindowStartupLocation="CenterScreen" WindowStyle="ToolWindow" ResizeMode="NoResize">
|
||||
<Grid Margin="90,35,90,20">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="28"/>
|
||||
<RowDefinition Height="28"/>
|
||||
<RowDefinition Height="28"/>
|
||||
<RowDefinition Height="28"/>
|
||||
<RowDefinition Height="32"/>
|
||||
<RowDefinition Height="32"/>
|
||||
<RowDefinition Height="32"/>
|
||||
<RowDefinition Height="32"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Label Content="每列数量" Margin="5,2"></Label>
|
||||
<Label Content="每行数量" Margin="5,2"></Label>
|
||||
<TextBox Name="textboxColNum" Grid.Column="1" Margin="5" Width="80" ></TextBox>
|
||||
|
||||
<Label Content="列间距" Margin="5,2" Grid.Row="1"></Label>
|
||||
|
@ -1,209 +1,234 @@
|
||||
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
xmlns:m="clr-namespace:Plane.FormationCreator.Formation"
|
||||
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
|
||||
x:Class="Plane.FormationCreator.Views.TaskBarView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="156.968"
|
||||
d:DesignWidth="500">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button HorizontalAlignment="Left" Grid.Column="1"
|
||||
Visibility="{Binding FlightTaskManager.IsPaused, Converter={StaticResource IsPausedToRunButtonVisibilityConverter}}"
|
||||
Command="{Binding RunTasksCommand}">
|
||||
<Button.Template>
|
||||
<ControlTemplate>
|
||||
<Grid Width="30"
|
||||
Height="30"
|
||||
Background="#00FFFFFF"
|
||||
VerticalAlignment="Bottom">
|
||||
<ed:RegularPolygon Fill="Black"
|
||||
InnerRadius="1"
|
||||
PointCount="3"
|
||||
Width="30"
|
||||
Height="30"
|
||||
Stretch="Fill"
|
||||
Stroke="Gray">
|
||||
<ed:RegularPolygon.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform />
|
||||
<SkewTransform />
|
||||
<RotateTransform Angle="90" />
|
||||
<TranslateTransform X="30" />
|
||||
</TransformGroup>
|
||||
</ed:RegularPolygon.RenderTransform>
|
||||
</ed:RegularPolygon>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Button.Template>
|
||||
</Button>
|
||||
<Button HorizontalAlignment="Left" Grid.Column="1"
|
||||
Background="#00FFFFFF"
|
||||
Visibility="{Binding FlightTaskManager.IsPaused, Converter={StaticResource IsPausedToPauseButtonVisibilityConverter}}"
|
||||
Command="{Binding PauseTasksCommand}">
|
||||
<Button.Template>
|
||||
<ControlTemplate>
|
||||
<Grid Width="30"
|
||||
Height="30"
|
||||
VerticalAlignment="Bottom"
|
||||
Background="#00FFFFFF">
|
||||
<Rectangle Fill="Black"
|
||||
HorizontalAlignment="Left"
|
||||
Width="10"
|
||||
Height="30"
|
||||
Stroke="Gray" />
|
||||
<Rectangle Fill="Black"
|
||||
Margin="0,0,3,0"
|
||||
HorizontalAlignment="Right"
|
||||
Width="10"
|
||||
Height="30"
|
||||
Stroke="Gray" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Button.Template>
|
||||
</Button>
|
||||
|
||||
<ItemsControl Grid.Column="0"
|
||||
VerticalAlignment="Bottom"
|
||||
ItemsSource="{Binding Tasks}"
|
||||
Name="TasksControl">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid x:Name="itemgrid">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border Background="{Binding Status, Converter={StaticResource FlightTaskStatusToFillConverter}}"
|
||||
Width="85"
|
||||
Height="19"
|
||||
BorderThickness="1"
|
||||
BorderBrush="Black"
|
||||
Effect="{Binding IsSelected, Converter={StaticResource FlightTaskIsSelectedToEffectConverter}}"
|
||||
MouseLeftButtonDown="TaskLeftButtonDown"
|
||||
MouseLeftButtonUp="SelectTask"
|
||||
MouseRightButtonUp="HideTask">
|
||||
|
||||
<WrapPanel VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center" >
|
||||
<TextBlock Width="auto"
|
||||
FontSize="12"
|
||||
Margin="0,0,2,0"
|
||||
Foreground="White"
|
||||
Text="{Binding TaskNum}"/>
|
||||
<TextBlock Width="auto"
|
||||
FontSize="12"
|
||||
Foreground="White"
|
||||
Text="{Binding TaskCnName}"/>
|
||||
</WrapPanel>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<Grid Grid.Column="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="28"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Height="100" Background="#FF2D2D2D" VerticalAlignment="Bottom">
|
||||
|
||||
<TabControl
|
||||
DataContext="{Binding FlightTaskManager.SelectedTask}"
|
||||
SelectedIndex="{Binding TaskTypeIndex,UpdateSourceTrigger=PropertyChanged}">
|
||||
|
||||
|
||||
|
||||
<TabItem Header="起飞">
|
||||
<Grid Margin="10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="起飞时间"/>
|
||||
<TextBox Grid.Column="1" Margin="2"
|
||||
Text="{Binding TakeOffTime, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
|
||||
</TabItem>
|
||||
<TabItem Header="航点">
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Row="0" Text="飞行时间: " />
|
||||
<TextBox Grid.Column="1" Margin="2"
|
||||
MaxLength="4"
|
||||
Text="{Binding FlytoTime, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<TextBlock Grid.Row="1" Text="悬停时间: " />
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Margin="2"
|
||||
MaxLength="4"
|
||||
Text="{Binding LoiterTime, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="降落">
|
||||
<Grid Margin="10" >
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
</TabControl>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1"
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Bottom">
|
||||
<Button Content="添加任务"
|
||||
Background="#232323"
|
||||
Command="{Binding AddTaskCommand}" />
|
||||
<Button Content="清除任务"
|
||||
Background="#232323"
|
||||
Command="{Binding ClearTasksCommand}" />
|
||||
<Button Content="重置任务"
|
||||
Background="#232323"
|
||||
Command="{Binding ResetTasksCommand}" />
|
||||
<Button Content="强制下一步"
|
||||
Background="#232323"
|
||||
Command="{Binding NextTasksCommand}" />
|
||||
<Button Content="重设原点"
|
||||
Background="#232323"
|
||||
Command="{Binding SetOriginCommand}" />
|
||||
<!--<Button Content="保存" />
|
||||
<Button Content="取消" />-->
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Plane.FormationCreator.Views"
|
||||
xmlns:m="clr-namespace:Plane.FormationCreator.Formation"
|
||||
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
|
||||
x:Class="Plane.FormationCreator.Views.TaskBarView"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="156.968"
|
||||
d:DesignWidth="500">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button HorizontalAlignment="Left" Grid.Column="1"
|
||||
Visibility="{Binding FlightTaskManager.IsPaused, Converter={StaticResource IsPausedToRunButtonVisibilityConverter}}"
|
||||
Command="{Binding RunTasksCommand}">
|
||||
<Button.Template>
|
||||
<ControlTemplate>
|
||||
<Grid Width="40"
|
||||
Height="40"
|
||||
Background="#00FFFFFF"
|
||||
VerticalAlignment="Bottom">
|
||||
<ed:RegularPolygon Fill="MidnightBlue"
|
||||
InnerRadius="1"
|
||||
PointCount="3"
|
||||
Width="40"
|
||||
Height="40"
|
||||
Stretch="Fill"
|
||||
Stroke="Gray">
|
||||
<ed:RegularPolygon.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform />
|
||||
<SkewTransform />
|
||||
<RotateTransform Angle="90" />
|
||||
<TranslateTransform X="40" />
|
||||
</TransformGroup>
|
||||
</ed:RegularPolygon.RenderTransform>
|
||||
</ed:RegularPolygon>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Button.Template>
|
||||
</Button>
|
||||
<Button HorizontalAlignment="Left" Grid.Column="1"
|
||||
Background="#00FFFFFF"
|
||||
Visibility="{Binding FlightTaskManager.IsPaused, Converter={StaticResource IsPausedToPauseButtonVisibilityConverter}}"
|
||||
Command="{Binding PauseTasksCommand}">
|
||||
<Button.Template>
|
||||
<ControlTemplate>
|
||||
<Grid Width="40"
|
||||
Height="40"
|
||||
VerticalAlignment="Bottom"
|
||||
Background="#00FFFFFF">
|
||||
<Rectangle Fill="Red"
|
||||
HorizontalAlignment="Left"
|
||||
Width="15"
|
||||
Height="40"
|
||||
Stroke="Gray" />
|
||||
<Rectangle Fill="Red"
|
||||
Margin="0,0,3,0"
|
||||
HorizontalAlignment="Right"
|
||||
Width="15"
|
||||
Height="40"
|
||||
Stroke="Gray" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Button.Template>
|
||||
</Button>
|
||||
|
||||
<ItemsControl Grid.Column="0"
|
||||
VerticalAlignment="Bottom"
|
||||
ItemsSource="{Binding Tasks}"
|
||||
Name="TasksControl">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid x:Name="itemgrid">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border
|
||||
Width="88"
|
||||
Height="19"
|
||||
BorderThickness="1"
|
||||
BorderBrush="Black"
|
||||
Effect="{Binding IsSelected, Converter={StaticResource FlightTaskIsSelectedToEffectConverter}}"
|
||||
MouseLeftButtonDown="TaskLeftButtonDown"
|
||||
MouseLeftButtonUp="SelectTask"
|
||||
MouseRightButtonUp="HideTask">
|
||||
<Border.Background>
|
||||
<MultiBinding Converter="{StaticResource FlightTaskStatusAndTransitionToFillConverter}">
|
||||
<Binding Path="Status" />
|
||||
<Binding Path="IsTransition" />
|
||||
</MultiBinding>
|
||||
</Border.Background>
|
||||
|
||||
<WrapPanel VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center" >
|
||||
<TextBlock Width="auto"
|
||||
FontSize="12"
|
||||
Margin="0,0,2,0"
|
||||
Foreground="White"
|
||||
Text="{Binding TaskNum}"/>
|
||||
<TextBlock Width="auto"
|
||||
FontSize="12"
|
||||
Foreground="White"
|
||||
Text="{Binding TaskCnName}"/>
|
||||
</WrapPanel>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<Grid Grid.Column="2" >
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="28"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Height="120" Background="#FF2D2D2D" VerticalAlignment="Bottom">
|
||||
|
||||
<TextBlock x:Name="hintaddtask" Margin="0,25,0,0" Text="请添加或选择飞行任务" Visibility="Collapsed" FontSize="18" TextAlignment="Center"/>
|
||||
|
||||
<TabControl x:Name="tasktabcont"
|
||||
DataContext="{Binding FlightTaskManager.SelectedTask}"
|
||||
SelectedIndex="{Binding TaskTypeIndex,UpdateSourceTrigger=PropertyChanged}">
|
||||
|
||||
|
||||
|
||||
<TabItem Header="1 起飞" x:Name="takeoffpage">
|
||||
<Grid Margin="10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="起飞时间:" Margin="2" VerticalAlignment="Center"/>
|
||||
<TextBox Grid.Column="1" Margin="2" VerticalAlignment="Center"
|
||||
Text="{Binding TakeOffTime, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
|
||||
</TabItem>
|
||||
<TabItem x:Name="flytopage" >
|
||||
|
||||
<TabItem.Header>
|
||||
<Label x:Name="flytoLabel" Content="航点" HorizontalAlignment="Stretch" MouseLeftButtonDown="TaskLabelLeftButtonDown"
|
||||
ToolTip="双击修改名称" />
|
||||
</TabItem.Header>
|
||||
|
||||
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Row="0" Margin="2" Text="飞行时间: " VerticalAlignment="Center" />
|
||||
<TextBox Grid.Column="1" Margin="2" VerticalAlignment="Center"
|
||||
MaxLength="4"
|
||||
Text="{Binding FlytoTime, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<TextBlock Grid.Row="1" Margin="2" Text="悬停时间: " VerticalAlignment="Center" />
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Margin="2" VerticalAlignment="Center"
|
||||
MaxLength="4"
|
||||
Text="{Binding LoiterTime, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<CheckBox Grid.Row="2" Grid.Column="2" x:Name="tranBox" Content="过度航点" HorizontalAlignment="Left" Width="75.353"
|
||||
IsChecked="{Binding IsTransition}"/>
|
||||
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
<TabItem Header="降落" x:Name="landpage">
|
||||
<Grid Margin="10" >
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
</TabControl>
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1"
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Bottom">
|
||||
<Button Content="添加" x:Name="addtaskbtn"
|
||||
Background="#232323"
|
||||
Command="{Binding AddTaskCommand}" />
|
||||
<Button Content="删除"
|
||||
Background="#232323"
|
||||
Command="{Binding DelTaskCommand}" />
|
||||
<Button Content="清除"
|
||||
Background="#232323"
|
||||
Command="{Binding ClearTasksCommand}" />
|
||||
<Button Content="重置"
|
||||
Background="#232323"
|
||||
Command="{Binding ResetTasksCommand}" />
|
||||
|
||||
<Button Content="更名" Visibility="Collapsed"
|
||||
Background="#232323"
|
||||
Command="{Binding renametaskCommand}" />
|
||||
<Button Content="原点"
|
||||
Background="#232323"
|
||||
Command="{Binding SetOriginCommand}" />
|
||||
|
||||
|
||||
<!--<Button Content="保存" />
|
||||
<Button Content="取消" />-->
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
@ -28,103 +28,165 @@ namespace Plane.FormationCreator.Views
|
||||
InitializeComponent();
|
||||
|
||||
this.DataContext = ServiceLocator.Current.GetInstance<TaskBarViewModel>();
|
||||
|
||||
|
||||
|
||||
hintaddtask.Visibility = Visibility.Visible;
|
||||
tasktabcont.Visibility = Visibility.Collapsed;
|
||||
_flightTaskManager.TaskTypeChanged += (sender, e) =>
|
||||
{
|
||||
if (e.ChangedFlightTask.TaskType == FlightTaskType.Land)
|
||||
addtaskbtn.IsEnabled = false;
|
||||
else addtaskbtn.IsEnabled = true;
|
||||
};
|
||||
|
||||
|
||||
_flightTaskManager.TaskcnNameChanged += (sender, e) =>
|
||||
{
|
||||
if (e.ChangedFlightTask.TaskType == FlightTaskType.Land)
|
||||
flytoLabel.Content = (_flightTaskManager.SelectedTaskIndex + 1) + " 航点";
|
||||
else
|
||||
flytoLabel.Content = (_flightTaskManager.SelectedTaskIndex + 1) + " " + _flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].TaskCnName;
|
||||
};
|
||||
|
||||
|
||||
_flightTaskManager.PropertyChanged += (sender, e) =>
|
||||
{
|
||||
if (_flightTaskManager.SelectedTaskIndex == -1) return;
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
//选中任务时触发--控制任务类型选项卡的显示和是否允许加入新任务
|
||||
case nameof(FlightTaskManager.SelectedTaskIndex):
|
||||
if (_flightTaskManager.Tasks.Count == 0)
|
||||
{
|
||||
tasktabcont.Visibility = Visibility.Collapsed;
|
||||
hintaddtask.Visibility = Visibility.Visible;
|
||||
addtaskbtn.IsEnabled = true;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
hintaddtask.Visibility = Visibility.Collapsed;
|
||||
tasktabcont.Visibility = Visibility.Visible;
|
||||
//刷新任务编号--可能删除了任务
|
||||
TasksControl.Items.Refresh();
|
||||
|
||||
//起飞任务
|
||||
if (_flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].TaskType == FlightTaskType.TakeOff)
|
||||
{
|
||||
takeoffpage.Visibility = Visibility.Visible;
|
||||
landpage.Visibility = Visibility.Collapsed;
|
||||
flytopage.Visibility = Visibility.Collapsed;
|
||||
}else
|
||||
//选中中间的任务
|
||||
if (_flightTaskManager.SelectedTaskIndex < (_flightTaskManager.Tasks.Count - 1))
|
||||
{
|
||||
takeoffpage.Visibility = Visibility.Collapsed;
|
||||
landpage.Visibility = Visibility.Collapsed;
|
||||
flytopage.Visibility = Visibility.Visible;
|
||||
|
||||
flytoLabel.Content = (_flightTaskManager.SelectedTaskIndex+1)+" "+ _flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].TaskCnName;
|
||||
//允许添加中途任务
|
||||
addtaskbtn.IsEnabled = true;
|
||||
|
||||
}
|
||||
else
|
||||
//最后一个任务--只有最后一个任务能设置成降落-防止中途降落
|
||||
{
|
||||
|
||||
takeoffpage.Visibility = Visibility.Collapsed;
|
||||
landpage.Visibility = Visibility.Visible;
|
||||
flytopage.Visibility = Visibility.Visible;
|
||||
//如果不是降落任务
|
||||
if (_flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].TaskType != FlightTaskType.Land)
|
||||
{
|
||||
addtaskbtn.IsEnabled = true;
|
||||
flytoLabel.Content = (_flightTaskManager.SelectedTaskIndex + 1) + " " + _flightTaskManager.Tasks[_flightTaskManager.SelectedTaskIndex].TaskCnName;
|
||||
}
|
||||
else
|
||||
{
|
||||
flytoLabel.Content = (_flightTaskManager.SelectedTaskIndex + 1) + " 航点";
|
||||
addtaskbtn.IsEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// case nameof(FlightTaskManager.SelectedTask .TaskTypeIndex):
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private FlightTaskManager _flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
|
||||
|
||||
//用于直接飞到航点
|
||||
public void TaskLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ClickCount > 1)
|
||||
{
|
||||
var elem = sender as FrameworkElement;
|
||||
var task = elem.DataContext as FlightTask;
|
||||
if (task.TaskType != FlightTaskType.FlyTo) return;
|
||||
TasksControl.Focus();
|
||||
|
||||
_flightTaskManager.FlyToTasks();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//用于更名
|
||||
public void TaskLabelLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (e.ClickCount > 1)
|
||||
{
|
||||
FlightTask task = _flightTaskManager.SelectedTask;
|
||||
if ((task == null) || (task.TaskType != FlightTaskType.FlyTo)) return;
|
||||
|
||||
string newName = task.TaskCnName;
|
||||
if (PlaneMessageBox.OnShow("请输入新的名称", "重命名", ref newName))
|
||||
{
|
||||
task.TaskCnName = newName;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//选择任务
|
||||
private void SelectTask(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var elem = sender as FrameworkElement;
|
||||
var task = elem.DataContext as FlightTask;
|
||||
//if (task.TaskType != FlightTaskType.TakeOff) // 不让选起飞任务。 现在可以选择起飞任务
|
||||
{
|
||||
_flightTaskManager.Select(task);
|
||||
}
|
||||
}
|
||||
_flightTaskManager.Select(task);
|
||||
|
||||
}
|
||||
|
||||
//以前的右键隐藏航点,已不用
|
||||
public void setRightSelect(FlightTask task, bool vRightSelect)
|
||||
{
|
||||
|
||||
// var borderBrush = new SolidColorBrush(vRightSelect ? Colors.Gray : Colors.OrangeRed);
|
||||
var borderBrush = new SolidColorBrush( Colors.OrangeRed);
|
||||
|
||||
if (task.TaskType == FlightTaskType.TakeOff) return;
|
||||
|
||||
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(TasksControl); i++)
|
||||
{
|
||||
DependencyObject child = VisualTreeHelper.GetChild(TasksControl, i);
|
||||
if (child != null && child is FrameworkElement)
|
||||
{
|
||||
var taskdata = (child as FrameworkElement).DataContext as FlightTask;
|
||||
if (taskdata == task)
|
||||
{
|
||||
if (child is Rectangle)
|
||||
{
|
||||
(child as Rectangle).Stroke = borderBrush;
|
||||
}
|
||||
else if (child is Border)
|
||||
{
|
||||
(child as Border).BorderBrush = borderBrush;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
if (elem is Rectangle)
|
||||
{
|
||||
(elem as Rectangle).Stroke = borderBrush;
|
||||
}
|
||||
else if (elem is Border)
|
||||
{
|
||||
(elem as Border).BorderBrush = borderBrush;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//右键功能 ---隐藏航点
|
||||
private void HideTask(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var elem = sender as FrameworkElement;
|
||||
var task = elem.DataContext as FlightTask;
|
||||
// int a = _flightTaskManager.RightSelectedTaskIndex;
|
||||
if (task.TaskType != FlightTaskType.TakeOff) // 不让选起飞任务。
|
||||
{
|
||||
var borderBrush = new SolidColorBrush(task.IsRightSelected ? Colors.Gray : Colors.OrangeRed);
|
||||
if (elem is Rectangle)
|
||||
{
|
||||
(elem as Rectangle).Stroke = borderBrush;
|
||||
}
|
||||
else if (elem is Border)
|
||||
{
|
||||
(elem as Border).BorderBrush = borderBrush;
|
||||
}
|
||||
_flightTaskManager.RightSelect(task);
|
||||
setRightSelect(task, true);
|
||||
|
||||
|
||||
_flightTaskManager.RightSelect(task);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
|
@ -31,20 +31,15 @@ namespace Plane.FormationCreator.Views
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
var camera = view3d.Camera as PerspectiveCamera;
|
||||
camera.Position = new Point3D(0, 0, 0);
|
||||
camera.LookDirection = new Vector3D(0, 1, 0);
|
||||
camera.UpDirection = new Vector3D(0, 0, 1);
|
||||
camera.FieldOfView = 120;
|
||||
ResetCamera();
|
||||
|
||||
_flightTaskManager = ServiceLocator.Current.GetInstance<FlightTaskManager>();
|
||||
_view3DManager = ServiceLocator.Current.GetInstance<View3DViewModel>();
|
||||
this.DataContext = _view3DManager;
|
||||
//view3d.ShowCameraInfo = true;
|
||||
//view3d.ShowFieldOfView = true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void ResetCamera_Click(object sender, RoutedEventArgs e)
|
||||
public void ResetCamera()
|
||||
{
|
||||
// view3d.CameraController.CameraPosition = new Point3D(0, 40, 1);
|
||||
// view3d.CameraController.CameraUpDirection = new Vector3D(0, -1, 10);
|
||||
@ -53,12 +48,29 @@ namespace Plane.FormationCreator.Views
|
||||
// view3d.CameraController.CameraRotationMode = CameraRotationMode.Turntable;
|
||||
|
||||
var camera = view3d.Camera as PerspectiveCamera;
|
||||
camera.Position = new Point3D(0, 0, 0);
|
||||
camera.LookDirection = new Vector3D(0, 1, 0);
|
||||
camera.UpDirection = new Vector3D(0, 0, 1);
|
||||
camera.FieldOfView = 120;
|
||||
camera.Position = new Point3D(0, 0, 1);
|
||||
//用于朝向180度
|
||||
// camera.LookDirection = new Vector3D(-0.025, -0.911, 0.411);
|
||||
//用于朝向9度
|
||||
camera.LookDirection = new Vector3D(0, 1, 0.8);
|
||||
camera.UpDirection = new Vector3D(0.011, 0.411, 0.912);
|
||||
|
||||
//用于0度
|
||||
//camera.LookDirection = new Vector3D(0, 1, 0);
|
||||
//camera.UpDirection = new Vector3D(0,0, 1);
|
||||
|
||||
|
||||
camera.FieldOfView = 120;
|
||||
_view3DManager.Clear3DCopters();
|
||||
//for test 用来确定上面的参数
|
||||
//view3d.ShowCameraInfo = true;
|
||||
//view3d.ShowFieldOfView = true;
|
||||
|
||||
}
|
||||
|
||||
private void ResetCamera_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ResetCamera();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 49 KiB |
BIN
Plane.FormationCreator/bin/Debug/Models/Opera/cube_b.JPG
Normal file
After Width: | Height: | Size: 142 KiB |
BIN
Plane.FormationCreator/bin/Debug/Models/Opera/cube_d.JPG
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
Plane.FormationCreator/bin/Debug/Models/Opera/cube_f.JPG
Normal file
After Width: | Height: | Size: 82 KiB |
BIN
Plane.FormationCreator/bin/Debug/Models/Opera/cube_l.JPG
Normal file
After Width: | Height: | Size: 137 KiB |
BIN
Plane.FormationCreator/bin/Debug/Models/Opera/cube_r.JPG
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
Plane.FormationCreator/bin/Debug/Models/Opera/cube_u.JPG
Normal file
After Width: | Height: | Size: 34 KiB |