FXJHGenenrate.cs 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. using SimulationCommon;
  2. namespace Model
  3. {
  4. public class FXJHGenerate
  5. {
  6. public static void
  7. FromStartToMission(FlightPlanEditor editor, ref List<TurningPoint> turningPoints) //生成从基地到任务段起点的航路点
  8. {
  9. turningPoints.Add(new TurningPoint
  10. {
  11. TurningPointName = "爬升",
  12. TurningPointLongitude = editor.originbase.BaseLongitude, //基地位置
  13. TurningPointLatitude = editor.originbase.BaseLatitude,
  14. TurningPointHeight = editor.originbase.BaseHeight,
  15. TurningPointType = "普通",
  16. //TurningPointVelocity = editor.climbsegment.ClimbVelocity;
  17. SegmentFlightFuelConsumption = 1,
  18. SegmentFlightTime = 0,
  19. RemainingFuel = 0,
  20. });
  21. // double k;
  22. double lat1, lon1; //直升机起飞后爬升到的航路点的经纬度,记为经纬度1
  23. lat1 = (editor.originbase.BaseLatitude + editor.missionpoint.MissionPointLatitude) / 2;
  24. lon1 = (editor.originbase.BaseLongitude + editor.missionpoint.MissionPointLongitude) / 2;
  25. // k = (editor.missionpoint.MissionPointLatitude - editor.originbase.BaseLatitude) /
  26. // (editor.missionpoint.MissionPointLongitude - editor.originbase.BaseLongitude);
  27. // if (editor.missionpoint.MissionPointLongitude > editor.originbase.BaseLongitude)
  28. // {
  29. // lat1 = 0.08544 * k / (Math.Sqrt(k * k + 1)) + editor.originbase.BaseLatitude; //经验公式
  30. // lon1 = 0.08544 / (Math.Sqrt(k * k + 1)) + editor.originbase.BaseLongitude;
  31. // }
  32. // else
  33. // {
  34. // lat1 = editor.originbase.BaseLatitude - 0.08544 * k / (Math.Sqrt(k * k + 1));
  35. // lon1 = editor.originbase.BaseLongitude - 0.08544 / (Math.Sqrt(k * k + 1));
  36. // }
  37. turningPoints.Add(new TurningPoint
  38. {
  39. TurningPointName = "平飞",
  40. TurningPointLongitude = lon1,
  41. TurningPointLatitude = lat1,
  42. TurningPointHeight = 2000,
  43. TurningPointType = "普通",
  44. SegmentFlightFuelConsumption = 2,
  45. SegmentFlightTime = 0,
  46. RemainingFuel = 0,
  47. });
  48. }
  49. //获取油耗率
  50. public static double GetClimbFuelConsumptionRate(FlightPlanEditor editor, double height, double t)
  51. {
  52. Fuel fuel = Util.GetFuel(editor.aircraftparameter.AircraftID, editor.aircraftparameter.AircraftSubType,
  53. "爬升", t.ToString(), height.ToString(),
  54. editor.aircraftparameter.MaxTakeoffWeight.ToString());
  55. if (fuel == null)
  56. {
  57. return 1100;
  58. }
  59. return fuel.oilconsume;
  60. }
  61. public static double GetCruisingFuelConsumptionRate(FlightPlanEditor editor, double height, double t)
  62. {
  63. Fuel fuel = Util.GetFuel(editor.aircraftparameter.AircraftID, editor.aircraftparameter.AircraftSubType,
  64. "平飞远航", t.ToString(), height.ToString(),
  65. editor.aircraftparameter.MaxTakeoffWeight.ToString());
  66. if (fuel == null)
  67. {
  68. return 600;
  69. }
  70. return fuel.oilconsume;
  71. }
  72. public static double GetEnduranceFuelConsumptionRate(FlightPlanEditor editor, double height, double t)
  73. {
  74. Fuel fuel = Util.GetFuel(editor.aircraftparameter.AircraftID, editor.aircraftparameter.AircraftSubType,
  75. "平飞久航", t.ToString(), height.ToString(),
  76. editor.aircraftparameter.MaxTakeoffWeight.ToString());
  77. if (fuel == null)
  78. {
  79. return 600;
  80. }
  81. return fuel.oilconsume;
  82. }
  83. public static double GetDescentFuelConsumptionRate(FlightPlanEditor editor, double height, double t)
  84. {
  85. return 2 * GetCruisingFuelConsumptionRate(editor, height,t) - GetClimbFuelConsumptionRate(editor, height,t);
  86. }
  87. public static double GetHoverFuelConsumptionRate(FlightPlanEditor editor, double height, double t)
  88. {
  89. Fuel fuel = Util.GetFuel(editor.aircraftparameter.AircraftID, editor.aircraftparameter.AircraftSubType,
  90. "悬停", t.ToString(), height.ToString(),
  91. editor.aircraftparameter.MaxTakeoffWeight.ToString());
  92. if (fuel == null)
  93. {
  94. return 200;
  95. }
  96. return fuel.oilconsume;
  97. }
  98. //获取速度值
  99. public static double GetClimbVelocity(FlightPlanEditor editor, double height, double t)
  100. {
  101. Fuel fuel = Util.GetFuel(editor.aircraftparameter.AircraftID, editor.aircraftparameter.AircraftSubType,
  102. "爬升", t.ToString(), height.ToString(), editor.aircraftparameter.MaxTakeoffWeight.ToString());
  103. if (fuel == null)
  104. {
  105. return 60;
  106. }
  107. return fuel.speed;
  108. }
  109. public static double GetCruisingVelocity(FlightPlanEditor editor, double height, double t)
  110. {
  111. Fuel fuel = Util.GetFuel(editor.aircraftparameter.AircraftID, editor.aircraftparameter.AircraftSubType,
  112. "平飞远航", t.ToString(), height.ToString(), editor.aircraftparameter.MaxTakeoffWeight.ToString());
  113. if (fuel == null)
  114. {
  115. return 200;
  116. }
  117. return fuel.speed;
  118. }
  119. public static double GetEnduranceVelocity(FlightPlanEditor editor, double height, double t)
  120. {
  121. Fuel fuel = Util.GetFuel(editor.aircraftparameter.AircraftID, editor.aircraftparameter.AircraftSubType,
  122. "平飞久航", t.ToString(), height.ToString(), editor.aircraftparameter.MaxTakeoffWeight.ToString());
  123. if (fuel == null)
  124. {
  125. return 200;
  126. }
  127. return fuel.speed;
  128. }
  129. public static double GetDescentVelocity(FlightPlanEditor editor, double height, double t)
  130. {
  131. return GetCruisingVelocity(editor, height,t) / 2;
  132. }
  133. public static void ZhenCha(List<double[]> SC01, FlightPlanEditor editor,
  134. ref List<TurningPoint> turningPoints) //侦查模型航路点生成
  135. {
  136. int i;
  137. for (i = 0; i < SC01.Count - 1; i++)
  138. {
  139. turningPoints.Add(new TurningPoint
  140. {
  141. TurningPointName = "平飞",
  142. TurningPointLongitude = SC01[i][0],
  143. TurningPointLatitude = SC01[i][1],
  144. TurningPointHeight = SC01[i][2],
  145. TurningPointType = "侦查",
  146. SegmentFlightFuelConsumption = 3,
  147. SegmentFlightTime = 0,
  148. RemainingFuel = 0,
  149. });
  150. }
  151. }
  152. public static void SuoHuaJiang(double resulttime, FlightPlanEditor editor,
  153. ref List<TurningPoint> turningPoints) //索滑降模型航路点生成
  154. {
  155. turningPoints.Add(new TurningPoint
  156. {
  157. TurningPointName = "索滑降",
  158. TurningPointLongitude = editor.missionpoint.MissionPointLongitude,
  159. TurningPointLatitude = editor.missionpoint.MissionPointLatitude,
  160. TurningPointHeight = editor.missionpoint.MissionPointHeight,
  161. TurningPointType = "索滑降",
  162. SegmentFlightFuelConsumption = 5,
  163. SegmentFlightTime = resulttime,
  164. RemainingFuel = 0,
  165. });
  166. }
  167. public static void XunHu(FlightPlanEditor editor, ref List<TurningPoint> turningPoints)
  168. {
  169. int i;
  170. for (i = 0; i < editor.airroute.Length; i++)
  171. {
  172. turningPoints.Add(new TurningPoint
  173. {
  174. TurningPointName = "平飞",
  175. TurningPointLongitude = editor.airroute[i].AirRouteLongitude,
  176. TurningPointLatitude = editor.airroute[i].AirRouteLatitude,
  177. TurningPointHeight = 3000,
  178. TurningPointType = "普通",
  179. SegmentFlightFuelConsumption = 3,
  180. SegmentFlightTime = 0,
  181. RemainingFuel = 0,
  182. });
  183. }
  184. }
  185. public static void TongXin(FlightPlanEditor editor, ref List<TurningPoint> turningPoints)
  186. {
  187. int i;
  188. for (i = 0; i < editor.airroute.Length; i++)
  189. {
  190. turningPoints.Add(new TurningPoint
  191. {
  192. TurningPointName = "平飞",
  193. TurningPointLongitude = editor.airroute[i].AirRouteLongitude,
  194. TurningPointLatitude = editor.airroute[i].AirRouteLatitude,
  195. TurningPointHeight = editor.airroute[i].AirRouteHeight,
  196. TurningPointType = "普通",
  197. SegmentFlightFuelConsumption = 3,
  198. SegmentFlightTime = 0,
  199. RemainingFuel = 0,
  200. });
  201. }
  202. }
  203. public static void MieHuo1(FlightPlanEditor editor, ref List<TurningPoint> turningPoints) //灭火任务从取水点到火场部分的航路点生成
  204. {
  205. turningPoints.Add(new TurningPoint
  206. {
  207. TurningPointName = "取水",
  208. TurningPointLongitude = editor.missionpoint.MissionPointLongitude,
  209. TurningPointLatitude = editor.missionpoint.MissionPointLatitude,
  210. TurningPointHeight = editor.missionpoint.MissionPointHeight + 1000,
  211. TurningPointType = "取水",
  212. SegmentFlightFuelConsumption = 5,
  213. SegmentFlightTime = 60,
  214. RemainingFuel = 0,
  215. });
  216. turningPoints.Add(new TurningPoint
  217. {
  218. TurningPointName = "取水",
  219. TurningPointLongitude = editor.missionpoint.MissionPointLongitude,
  220. TurningPointLatitude = editor.missionpoint.MissionPointLatitude,
  221. TurningPointHeight = editor.missionpoint.MissionPointHeight,
  222. TurningPointType = "取水",
  223. SegmentFlightFuelConsumption = 3,
  224. SegmentFlightTime = 0,
  225. RemainingFuel = 0,
  226. });
  227. turningPoints.Add(new TurningPoint
  228. {
  229. TurningPointName = "洒水",
  230. TurningPointLongitude = editor.firepoint[0].FirePointLongitude,
  231. TurningPointLatitude = editor.firepoint[0].FirePointLatitude,
  232. TurningPointHeight = editor.firepoint[0].FirePointHeight + 1000,
  233. TurningPointType = "巡航",
  234. SegmentFlightFuelConsumption = 5,
  235. SegmentFlightTime = 120,
  236. RemainingFuel = 0,
  237. });
  238. turningPoints.Add(new TurningPoint
  239. {
  240. TurningPointName = "洒水",
  241. TurningPointLongitude = editor.firepoint[0].FirePointLongitude,
  242. TurningPointLatitude = editor.firepoint[0].FirePointLatitude,
  243. TurningPointHeight = editor.firepoint[0].FirePointHeight,
  244. TurningPointType = "巡航",
  245. SegmentFlightFuelConsumption = 3,
  246. SegmentFlightTime = 0,
  247. RemainingFuel = 0,
  248. });
  249. }
  250. public static MissionEndPoint ZhenChaMissionEndPoint(List<double[]> SC01) //侦查模型任务终点生成
  251. {
  252. MissionEndPoint missionEndPoint = new();
  253. int length = SC01.Count - 1;
  254. missionEndPoint.MissionEndPointLongitude = SC01[length][0];
  255. missionEndPoint.MissionEndPointLatitude = SC01[length][1];
  256. missionEndPoint.MissionEndPointHeight = SC01[length][2];
  257. return missionEndPoint;
  258. }
  259. public static MissionEndPoint SuoHuaJiangMissionEndPoint(FlightPlanEditor editor) //索滑降模型任务终点生成
  260. {
  261. MissionEndPoint missionEndPoint = new();
  262. missionEndPoint.MissionEndPointLongitude = editor.missionpoint.MissionPointLongitude;
  263. missionEndPoint.MissionEndPointLatitude = editor.missionpoint.MissionPointLatitude;
  264. missionEndPoint.MissionEndPointHeight = editor.missionpoint.MissionPointHeight;
  265. return missionEndPoint;
  266. }
  267. public static void JijiangMiehuo1(FlightPlanEditor editor, ref List<TurningPoint> turningPoint)
  268. {
  269. turningPoint.Add(new TurningPoint
  270. {
  271. TurningPointName = "转运",
  272. TurningPointLongitude = editor.missionpoint.MissionPointLongitude,
  273. TurningPointLatitude = editor.missionpoint.MissionPointLatitude,
  274. TurningPointHeight = editor.missionpoint.MissionPointHeight,
  275. TurningPointType = "转运",
  276. SegmentFlightFuelConsumption = 2,
  277. SegmentFlightTime = 0,
  278. RemainingFuel = 0,
  279. });
  280. }
  281. public static void JijiangMiehuo(FlightPlanEditor editor, ref List<TurningPoint> turningPoint)
  282. {
  283. turningPoint.Add(new TurningPoint
  284. {
  285. TurningPointName = "转运",
  286. TurningPointLongitude = editor.originbase.BaseLongitude,
  287. TurningPointLatitude = editor.originbase.BaseLatitude,
  288. TurningPointHeight = editor.originbase.BaseHeight,
  289. TurningPointType = "转运",
  290. SegmentFlightFuelConsumption = 2,
  291. SegmentFlightTime = 0,
  292. RemainingFuel = 0,
  293. });
  294. turningPoint.Add(new TurningPoint
  295. {
  296. TurningPointName = "转运",
  297. TurningPointLongitude = editor.missionpoint.MissionPointLongitude,
  298. TurningPointLatitude = editor.missionpoint.MissionPointLatitude,
  299. TurningPointHeight = editor.missionpoint.MissionPointHeight,
  300. TurningPointType = "转运",
  301. SegmentFlightFuelConsumption = 2,
  302. SegmentFlightTime = 0,
  303. RemainingFuel = 0,
  304. });
  305. }
  306. public static void SeaSouJiu(FlightPlanEditor editor, ref List<TurningPoint> turningPoints)
  307. {
  308. int i;
  309. for (i = 0; i < editor.airroute.Length; i++)
  310. {
  311. turningPoints.Add(new TurningPoint
  312. {
  313. TurningPointName = "巡航",
  314. TurningPointLongitude = editor.airroute[i].AirRouteLongitude,
  315. TurningPointLatitude = editor.airroute[i].AirRouteLatitude,
  316. TurningPointHeight = 2000,
  317. TurningPointType = "普通",
  318. SegmentFlightFuelConsumption = 3,
  319. SegmentFlightTime = 0,
  320. RemainingFuel = 0,
  321. });
  322. }
  323. }
  324. public static void SeaSouJiu2(FlightPlanEditor editor, MissionPoint missionPoint,
  325. ref List<TurningPoint> turningPoints)
  326. {
  327. turningPoints.Add(new TurningPoint
  328. {
  329. TurningPointName = "巡航",
  330. TurningPointLongitude = missionPoint.MissionPointLongitude,
  331. TurningPointLatitude = missionPoint.MissionPointLatitude,
  332. TurningPointHeight = 0,
  333. TurningPointType = "普通",
  334. SegmentFlightFuelConsumption = 3,
  335. SegmentFlightTime = 0,
  336. RemainingFuel = 0,
  337. });
  338. }
  339. public static void LandSouJiu(FlightPlanEditor editor, ref List<TurningPoint> turningPoints)
  340. {
  341. int i;
  342. for (i = 0; i < editor.airroute.Length; i++)
  343. {
  344. turningPoints.Add(new TurningPoint
  345. {
  346. TurningPointName = "巡航",
  347. TurningPointLongitude = editor.airroute[i].AirRouteLongitude,
  348. TurningPointLatitude = editor.airroute[i].AirRouteLatitude,
  349. TurningPointHeight = editor.airroute[i].AirRouteHeight,
  350. TurningPointType = "普通",
  351. SegmentFlightFuelConsumption = 3,
  352. SegmentFlightTime = 0,
  353. RemainingFuel = 0,
  354. });
  355. }
  356. }
  357. public static void FromMissionToEnd(FlightPlanEditor editor, MissionEndPoint missionEndPoint,
  358. ref List<TurningPoint> turningPoints) //生成从任务段终点到基地的航路点
  359. {
  360. turningPoints.Add(new TurningPoint
  361. {
  362. TurningPointName = "平飞",
  363. TurningPointLongitude = missionEndPoint.MissionEndPointLongitude,
  364. TurningPointLatitude = missionEndPoint.MissionEndPointLatitude,
  365. TurningPointHeight = missionEndPoint.MissionEndPointHeight,
  366. TurningPointType = "普通",
  367. SegmentFlightFuelConsumption = 3,
  368. SegmentFlightTime = 0,
  369. RemainingFuel = 0,
  370. });
  371. //double k;
  372. double lat2, lon2;
  373. lat2 = (turningPoints[^1].TurningPointLatitude + editor.endbase.BaseLatitude) / 2;
  374. lon2 = (turningPoints[^1].TurningPointLongitude + editor.endbase.BaseLongitude) / 2;
  375. // k = (turningPoints[^1].TurningPointLatitude - editor.originbase.BaseLatitude) /
  376. // (turningPoints[^1].TurningPointLongitude - editor.originbase.BaseLongitude);
  377. // if (turningPoints[^1].TurningPointLongitude > editor.originbase.BaseLongitude)
  378. // {
  379. // lat2 = 0.08544 * k / (Math.Sqrt(k * k + 1)) + editor.originbase.BaseLatitude;
  380. // lon2 = 0.08544 / (Math.Sqrt(k * k + 1)) + editor.originbase.BaseLongitude;
  381. // }
  382. // else
  383. // {
  384. // lat2 = editor.originbase.BaseLatitude - 0.08544 * k / (Math.Sqrt(k * k + 1));
  385. // lon2 = editor.originbase.BaseLongitude - 0.08544 / (Math.Sqrt(k * k + 1));
  386. // }
  387. turningPoints.Add(new TurningPoint
  388. {
  389. TurningPointName = "降高",
  390. TurningPointLongitude = lon2,
  391. TurningPointLatitude = lat2,
  392. TurningPointHeight = 2000,
  393. TurningPointType = "普通",
  394. SegmentFlightFuelConsumption = 4,
  395. SegmentFlightTime = 0,
  396. RemainingFuel = 0,
  397. });
  398. turningPoints.Add(new TurningPoint
  399. {
  400. TurningPointName = "返回基地",
  401. TurningPointLongitude = editor.endbase.BaseLongitude,
  402. TurningPointLatitude = editor.endbase.BaseLatitude,
  403. TurningPointHeight = editor.endbase.BaseHeight,
  404. TurningPointType = "普通",
  405. SegmentFlightFuelConsumption = 4,
  406. SegmentFlightTime = 0,
  407. RemainingFuel = 0,
  408. });
  409. }
  410. public static void InitializeVelocities(FlightPlanEditor editor, List<TurningPoint> turningPoints,
  411. ref double[] velocitys,double t)
  412. {
  413. velocitys[0] = GetClimbVelocity(editor, turningPoints[0].TurningPointHeight,t);
  414. velocitys[1] = GetCruisingVelocity(editor, turningPoints[1].TurningPointHeight,t);
  415. velocitys[2] = GetEnduranceVelocity(editor, turningPoints[2].TurningPointHeight,t);
  416. velocitys[3] = GetDescentVelocity(editor, turningPoints[0].TurningPointHeight,t);
  417. }
  418. public static void InitializeFuelConsumptions(FlightPlanEditor editor, List<TurningPoint> turningPoints,
  419. ref double[] fuelConsumptions,double t)
  420. {
  421. fuelConsumptions[0] = GetClimbFuelConsumptionRate(editor, turningPoints[0].TurningPointHeight,t);
  422. fuelConsumptions[1] = GetCruisingFuelConsumptionRate(editor, turningPoints[1].TurningPointHeight,t);
  423. fuelConsumptions[2] = GetEnduranceFuelConsumptionRate(editor, turningPoints[2].TurningPointHeight,t);
  424. fuelConsumptions[3] = GetDescentFuelConsumptionRate(editor, turningPoints[0].TurningPointHeight,t);
  425. fuelConsumptions[4] = GetHoverFuelConsumptionRate(editor, turningPoints[2].TurningPointHeight,t);
  426. }
  427. public static void CalculateTrueHeading(FlightPlanEditor editor,ref List<TurningPoint> turningPoints)
  428. {
  429. for (int i=0;i<turningPoints.Count-1;i++)
  430. {
  431. // 转换为弧度
  432. double lat1Rad = turningPoints[i].TurningPointLatitude * Math.PI / 180;
  433. double lon1Rad = turningPoints[i].TurningPointLongitude * Math.PI / 180;
  434. double lat2Rad = turningPoints[i + 1].TurningPointLatitude * Math.PI / 180;
  435. double lon2Rad = turningPoints[i + 1].TurningPointLongitude * Math.PI / 180;
  436. double deltaLon = lon2Rad - lon1Rad;
  437. double x = Math.Sin(deltaLon) * Math.Cos(lat2Rad);
  438. double y = Math.Cos(lat1Rad) * Math.Sin(lat2Rad) - Math.Sin(lat1Rad) * Math.Cos(lat2Rad) * Math.Cos(deltaLon);
  439. // 计算航向角
  440. double headingRad = Math.Atan2(x, y);
  441. // 转换为度并标准化
  442. double headingDeg = headingRad * 180 / Math.PI;
  443. headingDeg = (headingDeg + 360) % 360;
  444. turningPoints[i].HeadingAngle = headingDeg;
  445. }
  446. }
  447. public static void FXJHTPDiedai(FlightPlanEditor editor, ref List<TurningPoint> turningPoints,
  448. double[] velocitys, double[] fuelConsumptions)
  449. {
  450. int i;
  451. double DEG_TO_RAD_LOCAL = 3.1415926535897932 / 180;
  452. double[] x = new double[turningPoints.Count];
  453. double[] y = new double[turningPoints.Count];
  454. double[] z = new double[turningPoints.Count];
  455. // LLA坐标转换为ECEF坐标
  456. for (i = 0; i < turningPoints.Count; i++)
  457. {
  458. double lon = turningPoints[i].TurningPointLongitude * DEG_TO_RAD_LOCAL;
  459. double lat = turningPoints[i].TurningPointLatitude * DEG_TO_RAD_LOCAL;
  460. double hei = turningPoints[i].TurningPointHeight;
  461. double a = 6378137.0;
  462. double b = 6356752.31424518;
  463. double N = a / (Math.Sqrt(1 - ((a * a - b * b) / (a * a)) * Math.Sin(lat) * Math.Sin(lat)));
  464. x[i] = (N + hei) * Math.Cos(lat) * Math.Cos(lon);
  465. y[i] = (N + hei) * Math.Cos(lat) * Math.Sin(lon);
  466. z[i] = ((b * b * N) / (a * a) + hei) * Math.Sin(lat);
  467. }
  468. // 计算每个航段的飞行时间
  469. for (i = 0; i < turningPoints.Count; i++)
  470. {
  471. if (turningPoints[i].SegmentFlightTime == 0)
  472. {
  473. double distanceab = 0;
  474. if (i != turningPoints.Count - 1)
  475. {
  476. distanceab = Math.Sqrt(Math.Pow(x[i] - x[i + 1], 2) + Math.Pow(y[i] - y[i + 1], 2) +
  477. Math.Pow(z[i] - z[i + 1], 2));
  478. }
  479. double velocity;
  480. switch (turningPoints[i].SegmentFlightFuelConsumption)
  481. {
  482. case 1:
  483. velocity = velocitys[0];
  484. break;
  485. case 2:
  486. velocity = velocitys[1];
  487. break;
  488. case 3:
  489. velocity = velocitys[2];
  490. break;
  491. case 4:
  492. velocity = velocitys[3];
  493. break;
  494. case 5:
  495. velocity = 0;
  496. break;
  497. default:
  498. velocity = 0;
  499. break;
  500. }
  501. turningPoints[i].SegmentFlightTime = CalculateSegmentFlightTime(distanceab, velocity);
  502. double CalculateSegmentFlightTime(double distance, double velocit)
  503. {
  504. return distance * 3.6 / velocit;
  505. }
  506. // 打印调试信息
  507. //Console.WriteLine($"航段 {i}: 时间 = {turningPoints[i].SegmentFlightTime} s, 速度 = {velocity} km/h, 距离 = {distanceab} m");
  508. }
  509. //Console.WriteLine($"航段 {i}: 时间 = {turningPoints[i].SegmentFlightTime} s");
  510. // 计算燃油消耗,并在燃油不足时插入“返回基地”、“加油”和“返回原航路点”航路点
  511. if (turningPoints[i].RemainingFuel == 0)
  512. {
  513. double remainingFuel;
  514. if (i == 0)
  515. {
  516. remainingFuel = editor.aircraftparameter.MaxFuelCapacity * 0.8;
  517. }
  518. else
  519. {
  520. remainingFuel = turningPoints[i - 1].RemainingFuel;
  521. }
  522. double fuelConsumption = 0;
  523. switch (turningPoints[i].SegmentFlightFuelConsumption)
  524. {
  525. case 1:
  526. fuelConsumption = fuelConsumptions[0];
  527. break;
  528. case 2:
  529. fuelConsumption = fuelConsumptions[1];
  530. break;
  531. case 3:
  532. fuelConsumption = fuelConsumptions[2];
  533. break;
  534. case 4:
  535. fuelConsumption = fuelConsumptions[3];
  536. break;
  537. case 5:
  538. fuelConsumption = fuelConsumptions[4];
  539. break;
  540. default:
  541. fuelConsumption = 0;
  542. break;
  543. }
  544. remainingFuel -= fuelConsumption * turningPoints[i].SegmentFlightTime / 3600;
  545. turningPoints[i].RemainingFuel = remainingFuel;
  546. // 打印调试信息
  547. //Console.WriteLine($"航段 {i}: 油耗率 = {fuelConsumption} kg/h, 剩余燃油 = {turningPoints[i].RemainingFuel} kg");
  548. }
  549. //Console.WriteLine($"航段 {i}: 剩余燃油 = {turningPoints[i].RemainingFuel} kg");
  550. if (turningPoints[i].RemainingFuel < editor.aircraftparameter.MaxFuelCapacity * 0.2 &&
  551. !turningPoints[i].IsRefuelPointInserted && i < turningPoints.Count - 2)
  552. {
  553. // 标记当前航路点为已插入加油点
  554. turningPoints[i].IsRefuelPointInserted = true;
  555. turningPoints[i + 1].IsRefuelPointInserted = true;
  556. TurningPoint returnToBase = new TurningPoint
  557. {
  558. TurningPointName = "返回基地",
  559. TurningPointLongitude = editor.fuelbase.BaseLongitude,
  560. TurningPointLatitude = editor.fuelbase.BaseLatitude,
  561. TurningPointHeight = editor.fuelbase.BaseHeight,
  562. TurningPointType = "返航",
  563. SegmentFlightTime = 600,
  564. SegmentFlightFuelConsumption = 0,
  565. RemainingFuel = editor.aircraftparameter.MaxFuelCapacity,
  566. };
  567. TurningPoint refuelPoint = new TurningPoint
  568. {
  569. TurningPointName = "加油",
  570. TurningPointLongitude = editor.fuelbase.BaseLongitude,
  571. TurningPointLatitude = editor.fuelbase.BaseLatitude,
  572. TurningPointHeight = editor.fuelbase.BaseHeight,
  573. TurningPointType = "加油",
  574. SegmentFlightTime = 0,
  575. SegmentFlightFuelConsumption = 2,
  576. RemainingFuel = 0,
  577. };
  578. TurningPoint returnToPrevious = new TurningPoint
  579. {
  580. TurningPointName = "返回原航路点",
  581. TurningPointLongitude = turningPoints[i + 1].TurningPointLongitude,
  582. TurningPointLatitude = turningPoints[i + 1].TurningPointLatitude,
  583. TurningPointHeight = turningPoints[i + 1].TurningPointHeight,
  584. TurningPointType = "返航",
  585. SegmentFlightTime = 0,
  586. SegmentFlightFuelConsumption = 2,
  587. RemainingFuel = 0,
  588. };
  589. // 插入新航路点到当前位置
  590. turningPoints.Insert(i + 2, returnToBase);
  591. turningPoints.Insert(i + 3, refuelPoint);
  592. turningPoints.Insert(i + 4, returnToPrevious);
  593. // 重新计算插入的航路点的飞行时间和燃油消耗
  594. FXJHTPDiedai(editor, ref turningPoints, velocitys, fuelConsumptions);
  595. // 退出当前方法,避免重复计算
  596. return;
  597. }
  598. }
  599. }
  600. public static void BackToEnd(FlightPlanEditor editor, MissionEndPoint missionEndPoint,
  601. ref List<TurningPoint> turningPoints, int index)
  602. {
  603. turningPoints.Insert(index,new TurningPoint
  604. {
  605. TurningPointName = "平飞",
  606. TurningPointLongitude = missionEndPoint.MissionEndPointLongitude,
  607. TurningPointLatitude = missionEndPoint.MissionEndPointLatitude,
  608. TurningPointHeight = missionEndPoint.MissionEndPointHeight,
  609. TurningPointType = "普通",
  610. SegmentFlightFuelConsumption = 3,
  611. SegmentFlightTime = 0,
  612. RemainingFuel = 0,
  613. });
  614. //double k;
  615. double lat2, lon2;
  616. lat2 = (turningPoints[^1].TurningPointLatitude + editor.endbase.BaseLatitude) / 2;
  617. lon2 = (turningPoints[^1].TurningPointLongitude + editor.endbase.BaseLongitude) / 2;
  618. turningPoints.Insert(index + 1,new TurningPoint
  619. {
  620. TurningPointName = "降高",
  621. TurningPointLongitude = lon2,
  622. TurningPointLatitude = lat2,
  623. TurningPointHeight = 2000,
  624. TurningPointType = "普通",
  625. SegmentFlightFuelConsumption = 4,
  626. SegmentFlightTime = 0,
  627. RemainingFuel = 0,
  628. });
  629. turningPoints.Insert(index+2,new TurningPoint
  630. {
  631. TurningPointName = "返回基地",
  632. TurningPointLongitude = editor.endbase.BaseLongitude,
  633. TurningPointLatitude = editor.endbase.BaseLatitude,
  634. TurningPointHeight = editor.endbase.BaseHeight,
  635. TurningPointType = "普通",
  636. SegmentFlightFuelConsumption = 4,
  637. SegmentFlightTime = 0,
  638. RemainingFuel = 0,
  639. });
  640. }
  641. public static double CalculateTotalFuelConsumption(FlightPlanEditor editor, List<TurningPoint> turningPoints)
  642. {
  643. double initialFuel = editor.aircraftparameter.MaxFuelCapacity; // 起始燃油量
  644. double totalFuelConsumption = 0; // 总燃油消耗量
  645. double totalRefuelAmount = 0; // 总加油量
  646. for (int i = 0; i < turningPoints.Count; i++)
  647. {
  648. //// 更新飞行过程中的燃油消耗
  649. //if (i ==0)
  650. //{
  651. // double segmentFuelConsumed = initialFuel - turningPoints[i].RemainingFuel;
  652. //}
  653. //else
  654. //{
  655. // double segmentFuelConsumed = (turningPoints[i - 1].RemainingFuel - turningPoints[i].RemainingFuel);
  656. // totalFuelConsumption += segmentFuelConsumed;
  657. //}
  658. // 如果当前航路点是加油点,更新燃油并记录加油量
  659. if (turningPoints[i].TurningPointType == "加油")
  660. {
  661. double refuelAmount = editor.aircraftparameter.MaxFuelCapacity - turningPoints[i - 2].RemainingFuel;
  662. totalRefuelAmount += refuelAmount;
  663. }
  664. }
  665. // 最终燃油消耗 = 初始燃油 + 总加油量 - 最终剩余燃油
  666. double finalFuel = turningPoints.Last().RemainingFuel;
  667. totalFuelConsumption = (initialFuel + totalRefuelAmount) - finalFuel;
  668. return totalFuelConsumption;
  669. }
  670. /// <summary>
  671. /// 巡护用
  672. /// </summary>
  673. /// <param name="turningPoints"></param>
  674. /// <param name="editor"></param>
  675. /// <param name="nowtime"></param>
  676. /// <returns></returns>
  677. public static (CurrentLocation, bool) GetCurrentLocation(List<TurningPoint> turningPoints,
  678. FlightPlanEditor editor,
  679. double nowtime)
  680. {
  681. CurrentLocation currentLocation = new CurrentLocation();
  682. double[] timetable = new double[editor.airroute.Length + 2]; //airroute.Length表示巡护航线中有几个航路点
  683. timetable[0] = 0; //设起飞时刻为0
  684. int segmentnumber = -1;
  685. int i;
  686. for (i = 0; i < editor.airroute.Length + 1; i++)
  687. {
  688. timetable[i + 1] = timetable[i] + turningPoints[i].SegmentFlightTime;
  689. }
  690. for (i = 0; i < editor.airroute.Length + 2; i++)
  691. {
  692. if ((nowtime - timetable[i]) >= 0)
  693. {
  694. segmentnumber += 1;
  695. }
  696. else
  697. {
  698. break;
  699. }
  700. }
  701. bool isEnd = false || segmentnumber >= turningPoints.Count;
  702. currentLocation.CurrentLon = turningPoints[segmentnumber].TurningPointLongitude +
  703. (turningPoints[segmentnumber + 1].TurningPointLongitude -
  704. turningPoints[segmentnumber].TurningPointLongitude) *
  705. (nowtime - timetable[segmentnumber]) /
  706. turningPoints[segmentnumber].SegmentFlightTime;
  707. currentLocation.CurrentLat = turningPoints[segmentnumber].TurningPointLatitude +
  708. (turningPoints[segmentnumber + 1].TurningPointLatitude -
  709. turningPoints[segmentnumber].TurningPointLatitude) *
  710. (nowtime - timetable[segmentnumber]) /
  711. turningPoints[segmentnumber].SegmentFlightTime;
  712. currentLocation.CurrentHei = turningPoints[segmentnumber].TurningPointHeight +
  713. (turningPoints[segmentnumber + 1].TurningPointHeight -
  714. turningPoints[segmentnumber].TurningPointHeight) *
  715. (nowtime - timetable[segmentnumber]) /
  716. turningPoints[segmentnumber].SegmentFlightTime;
  717. currentLocation.CurrentFuel = 0;
  718. currentLocation.Currentvelo = 0;
  719. currentLocation.Currentsegnum = segmentnumber + 1;
  720. currentLocation.CurrentCourse = 75;
  721. return (currentLocation, isEnd);
  722. }
  723. //改
  724. /// <summary>
  725. /// 计算当前位置
  726. /// </summary>
  727. /// <param name="FXJHTP"></param>
  728. /// <param name="FXJHTPLength"></param>
  729. /// <param name="nowtime"></param>
  730. /// <returns></returns>
  731. public static (CurrentLocation, bool, int)
  732. GetAllCurrentLocation(List<TurningPoint> turningPoints, double nowtime) //飞机实时位置打印
  733. {
  734. CurrentLocation currentLocation = new CurrentLocation();
  735. double[] timetable = new double[turningPoints.Count + 1];
  736. timetable[0] = 0;
  737. int segmentnumber = -1;
  738. int i;
  739. for (i = 0; i < turningPoints.Count; i++)
  740. {
  741. timetable[i + 1] = timetable[i] + turningPoints[i].SegmentFlightTime;
  742. }
  743. for (i = 0; i < turningPoints.Count + 1; i++)
  744. {
  745. if ((nowtime - timetable[i]) >= 0)
  746. {
  747. segmentnumber += 1;
  748. }
  749. else
  750. {
  751. break;
  752. }
  753. }
  754. bool isEnd = false || segmentnumber >= turningPoints.Count;
  755. currentLocation.Currentsegnum = segmentnumber;
  756. if (segmentnumber < turningPoints.Count - 1)
  757. {
  758. currentLocation.CurrentLon = turningPoints[segmentnumber].TurningPointLongitude +
  759. ((turningPoints[segmentnumber + 1].TurningPointLongitude -
  760. turningPoints[segmentnumber].TurningPointLongitude) /
  761. turningPoints[segmentnumber].SegmentFlightTime) *
  762. (nowtime - timetable[segmentnumber]);
  763. currentLocation.CurrentLat = turningPoints[segmentnumber].TurningPointLatitude +
  764. ((turningPoints[segmentnumber + 1].TurningPointLatitude -
  765. turningPoints[segmentnumber].TurningPointLatitude) /
  766. turningPoints[segmentnumber].SegmentFlightTime) *
  767. (nowtime - timetable[segmentnumber]);
  768. currentLocation.CurrentHei = turningPoints[segmentnumber].TurningPointHeight +
  769. ((turningPoints[segmentnumber + 1].TurningPointHeight -
  770. turningPoints[segmentnumber].TurningPointHeight) /
  771. turningPoints[segmentnumber].SegmentFlightTime) *
  772. (nowtime - timetable[segmentnumber]);
  773. currentLocation.CurrentFuel = turningPoints[segmentnumber].RemainingFuel -
  774. turningPoints[segmentnumber].SegmentFlightFuelConsumption *
  775. (nowtime - timetable[segmentnumber]);
  776. currentLocation.PresentMission = turningPoints[segmentnumber].TurningPointName;
  777. }
  778. else if (segmentnumber == turningPoints.Count - 1)
  779. {
  780. currentLocation.CurrentLon = turningPoints[segmentnumber].TurningPointLongitude +
  781. ((turningPoints[0].TurningPointLongitude -
  782. turningPoints[segmentnumber].TurningPointLongitude) /
  783. turningPoints[segmentnumber].SegmentFlightTime) *
  784. (nowtime - timetable[segmentnumber]);
  785. currentLocation.CurrentLat = turningPoints[segmentnumber].TurningPointLatitude +
  786. ((turningPoints[0].TurningPointLatitude -
  787. turningPoints[segmentnumber].TurningPointLatitude) /
  788. turningPoints[segmentnumber].SegmentFlightTime) *
  789. (nowtime - timetable[segmentnumber]);
  790. currentLocation.CurrentHei = turningPoints[segmentnumber].TurningPointHeight +
  791. ((turningPoints[0].TurningPointHeight -
  792. turningPoints[segmentnumber].TurningPointHeight) /
  793. turningPoints[segmentnumber].SegmentFlightTime) *
  794. (nowtime - timetable[segmentnumber]);
  795. currentLocation.CurrentFuel = turningPoints[segmentnumber].RemainingFuel -
  796. turningPoints[segmentnumber].SegmentFlightFuelConsumption *
  797. (nowtime - timetable[segmentnumber]);
  798. currentLocation.PresentMission = turningPoints[segmentnumber].TurningPointName;
  799. }
  800. else
  801. {
  802. currentLocation.CurrentLon = turningPoints[^1].TurningPointLongitude;
  803. currentLocation.CurrentLat = turningPoints[^1].TurningPointLatitude;
  804. currentLocation.CurrentHei = turningPoints[^1].TurningPointHeight;
  805. currentLocation.Currentvelo = 0;
  806. currentLocation.CurrentFuel = turningPoints[segmentnumber - 1].RemainingFuel -
  807. turningPoints[segmentnumber - 1].SegmentFlightFuelConsumption *
  808. turningPoints[segmentnumber - 1].SegmentFlightTime;
  809. currentLocation.PresentMission = turningPoints[segmentnumber - 1].TurningPointName;
  810. isEnd = true;
  811. }
  812. return (currentLocation, isEnd,segmentnumber);
  813. }
  814. }
  815. }