AircraftSJ.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. using KYFramework;
  2. using Model;
  3. using MongoDB.Bson;
  4. using MuShiApp;
  5. using SimulationCommon;
  6. using SimulationSingleServer.Utils;
  7. using Unity.Mathematics;
  8. using Point = SimulationCommon.Point;
  9. using Random = System.Random;
  10. namespace SimulationServer;
  11. public class AircraftSJ : AircraftEntity
  12. {
  13. public bool IsOver;
  14. private MissionEndPoint MissionEndPoint;
  15. private CurrentLocation currentLocation;
  16. private double temptime = 0;
  17. private double probability = 0;
  18. private double finalProbability = 1.0;
  19. private bool isseefire = false;
  20. private int fireIndex = -1; // 记录发现火点的位置
  21. public EquationHelper helper;
  22. public SeaSouJiuTask taskContent;
  23. public bool Success = true; //本目标搜救是否成功
  24. public override void Start()
  25. {
  26. //TODO 计算 AirRoute[]
  27. double[] initialPosition =
  28. {
  29. FlightPlanEditor.targetpoint[0].TargetPointLatitude, FlightPlanEditor.targetpoint[0].TargetPointLongitude
  30. };
  31. double dt = 1;
  32. double totalTime = 24.0;
  33. Text_readNC text_ReadNC = new Text_readNC();
  34. text_ReadNC.GetNCData();
  35. text_ReadNC.GetWaveHighData();
  36. var nCread = text_ReadNC.windNCread;
  37. //漂移轨迹
  38. List<double[]> trajectory = SeaSJ.CalculateDriftTrajectory(nCread, initialPosition, dt, totalTime);
  39. Log.Info(trajectory.ToJson());
  40. // 生成任务终点
  41. MissionEndPoint = new MissionEndPoint
  42. {
  43. MissionEndPointLongitude = trajectory[^1][1],
  44. MissionEndPointLatitude = trajectory[^1][0],
  45. MissionEndPointHeight = 0
  46. };
  47. var temp = SeaSJ.getminEnclosingRect(trajectory);
  48. // temp 转成 List<Point>
  49. List<Point> points = new List<Point>();
  50. foreach (var item in temp)
  51. {
  52. points.Add(new Point(item[0], item[1]));
  53. }
  54. Point basePoint = new Point(FlightPlanEditor.originbase.BaseLatitude,
  55. FlightPlanEditor.originbase.BaseLongitude);
  56. List<Point> waypoints = new List<Point>();
  57. //*******
  58. if (taskContent.SearchMode == "平行线搜索")
  59. {
  60. waypoints = ParallellineSearch.parallellineSearch(basePoint, points, taskContent.SearchWidth);
  61. }
  62. if (taskContent.SearchMode == "扇形搜索")
  63. {
  64. waypoints = SectorSearch.PerformSearch(taskContent.SearchWidth);
  65. }
  66. if (taskContent.SearchMode == "扩展矩形搜索")
  67. {
  68. waypoints = TZFX.GenerateWaypoints(points[0], points[1], points[2], points[3], 20, taskContent.SearchWidth);
  69. }
  70. Log.Info("===========================");
  71. Log.Info( FlightPlanEditor.targetpoint[0].ToJson());
  72. Log.Info("===========================");
  73. Log.Info(points.ToJson());
  74. Log.Info("===========================");
  75. Log.Info(waypoints.ToJson());
  76. // List<Point> 转成 List<AirRoute>
  77. List<AirRoute> airRoutes = new List<AirRoute>();
  78. foreach (var item in waypoints)
  79. {
  80. airRoutes.Add(new AirRoute
  81. {
  82. AirRouteLatitude = item.lat,
  83. AirRouteLongitude = item.lon
  84. });
  85. }
  86. // var distance = Utils.Util.GetDistance(waypoints[0].lon,FlightPlanEditor.targetpoint[0].TargetPointLongitude, waypoints[0].lat,
  87. // FlightPlanEditor.targetpoint[0].TargetPointLatitude);
  88. // var distance1 = Utils.Util.GetDistance(waypoints[0].lon,FlightPlanEditor.originbase.BaseLongitude, waypoints[0].lat,
  89. // FlightPlanEditor.originbase.BaseLatitude);
  90. FlightPlanEditor.airroute = airRoutes.ToArray();
  91. MissionPoint missionPoint = new MissionPoint();
  92. missionPoint.MissionPointLatitude = waypoints[0].lat;
  93. missionPoint.MissionPointLongitude = waypoints[0].lon;
  94. FlightPlanEditor.missionpoint = missionPoint;
  95. FXJHGenerate.FromStartToMission(FlightPlanEditor, ref TurningPoints); //生成从起点到任务段起点的航路点
  96. FXJHGenerate.SeaSouJiu(FlightPlanEditor, ref TurningPoints);
  97. FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions);
  98. Task.Run(() =>
  99. {
  100. bool isseefire = false;
  101. double temptime = 0; // 自增时间,每次增加1s
  102. CurrentLocation currentLocation = new CurrentLocation();
  103. double probability = 0;
  104. double finalProbability = 1.0;
  105. Random random = new Random();
  106. int fireIndex = -1; // 记录发现火点的位置
  107. do
  108. {
  109. (currentLocation, _) =
  110. FXJHGenerate.GetCurrentLocation(TurningPoints, FlightPlanEditor, temptime); // 获取飞机当前位置
  111. double3 aricraftPoint = new double3(currentLocation.CurrentLon, currentLocation.CurrentLat,
  112. currentLocation.CurrentHei);
  113. double3 targetPoint = new double3(FlightPlanEditor.targetpoint[0].TargetPointLongitude,
  114. FlightPlanEditor.targetpoint[0].TargetPointLatitude,
  115. FlightPlanEditor.targetpoint[0].TargetPointHeight);
  116. var wind = SeaSJ.GetWindVelocityFromAPI(nCread, currentLocation.CurrentLat, currentLocation.CurrentLon,
  117. temptime);
  118. var windSpeed = Math.Sqrt(wind[0] * wind[0] + wind[1] * wind[1]);
  119. var waveHigh = SeaSJ.GetWaveHeightFromAPI(nCread, currentLocation.CurrentLon,
  120. currentLocation.CurrentLat, temptime);
  121. var distance = Utils.Util.GetDistance(currentLocation.CurrentLon,targetPoint.x, currentLocation.CurrentLat,
  122. targetPoint.y);
  123. Log.Info("距离:====================" + distance);
  124. if (distance < 20)
  125. {
  126. probability = helper.getProbability(aricraftPoint, targetPoint, currentLocation.CurrentCourse,
  127. windSpeed, waveHigh, "落水人员", "海上"); // 计算发现概率,需要其他模型输入 // 计算发现概率,需要其他模型输入
  128. }
  129. // probability = helper.getProbability(aricraftPoint, targetPoint, currentLocation.CurrentCourse,
  130. // windSpeed, waveHigh, "落水人员", "海上"); // 计算发现概率,需要其他模型输入 // 计算发现概率,需要其他模型输入
  131. // if (taskContent.SearchMode == "雷达搜索")
  132. // {
  133. // probability = DectionModel.Radar(taskContent.DetectionWavelength, taskContent.MinDetectionSignal, taskContent.RadarTransmitterPower,taskContent.TransmitAntennaGain, taskContent.ReceiveAntennaGain, taskContent.)
  134. // }
  135. //
  136. // if (taskContent.SearchMode == "光电搜索")
  137. // {
  138. // //搜寻目标相对搜救力量的侧向距离
  139. // probability = DectionModel.GuangDian(taskContent.OpticalTowerHorizontalRange,
  140. // taskContent.InfraredDetectorFieldAngle, taskContent.FlightHeight,,
  141. // FlightPlanEditor.cityweather.Visibility);
  142. // }
  143. finalProbability *= (1 - probability);
  144. Console.WriteLine(
  145. $"海上任务:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},最终概率:{1 - finalProbability},是否看到落水人员:{isseefire}");
  146. double randomValue = random.NextDouble(); // 生成随机数比较概率
  147. if (randomValue < (1 - finalProbability))
  148. {
  149. isseefire = true;
  150. fireIndex = currentLocation.Currentsegnum; // 记录当前航路点位置
  151. IsOver = true;
  152. }
  153. else
  154. {
  155. isseefire = false;
  156. }
  157. // if (temptime >= 7200) IsOver = true;
  158. temptime += 1;
  159. } while (!isseefire && IsOver == false);
  160. finalProbability = 1 - finalProbability;
  161. if (fireIndex != -1)
  162. {
  163. // 删除目标点位置开始的所有后续航路点
  164. TurningPoints.RemoveRange(fireIndex + 1, TurningPoints.Count - fireIndex - 1);
  165. MissionPoint missionPoint = new MissionPoint
  166. {
  167. MissionPointLongitude = currentLocation.CurrentLon,
  168. MissionPointLatitude = currentLocation.CurrentLat,
  169. MissionPointHeight = currentLocation.CurrentHei
  170. };
  171. FXJHGenerate.SeaSouJiu2(FlightPlanEditor, missionPoint, ref TurningPoints);
  172. //发现的目标坐标,需要其他模型输入
  173. FXJHGenerate.FromMissionToEnd(FlightPlanEditor, MissionEndPoint, ref TurningPoints);
  174. }
  175. FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions);
  176. End();
  177. });
  178. }
  179. public override void End()
  180. {
  181. for (int i = 0; i < TurningPoints.Count - 2; i++)
  182. {
  183. EffMisTime += TurningPoints[i].SegmentFlightTime;
  184. }
  185. for (int i = 0; i < TurningPoints.Count - 3; i++)
  186. {
  187. SearchTime += TurningPoints[i].SegmentFlightTime; //搜索时间
  188. }
  189. for (int i = 0; i < TurningPoints.Count; i++)
  190. {
  191. TotalTime += TurningPoints[i].SegmentFlightTime; // 总时间
  192. }
  193. TotalFuelConsumption = TurningPoints[0].RemainingFuel -
  194. TurningPoints[TurningPoints.Count - 1].RemainingFuel;
  195. // GetNCData getNCData = new GetNCData();
  196. // getNCData.GetData();
  197. //
  198. // double time = TotalTime; //time——搜索时间,单位:秒;数据测试用
  199. //
  200. // double latitude = FlightPlanEditor.targetpoint[0].TargetPointLatitude; //落水人员纬度;数据测试用
  201. // double longitude = FlightPlanEditor.targetpoint[0].TargetPointLongitude; //落水人员经度,数据测试用
  202. //
  203. // double survivalTime = SurvivalTimeModel.SurvivalTime(getNCData.tempreadNC, latitude, longitude, time); //幸存时间
  204. //
  205. //
  206. //
  207. // if (survivalTime > time)
  208. // {
  209. // Success = true;
  210. // }
  211. // else
  212. // {
  213. // Success = false;
  214. // }
  215. }
  216. }
  217. [ObjectSystem]
  218. public class AircraftSJAwakeSystem : AwakeSystem<AircraftSJ, FlightPlanEditor>
  219. {
  220. public override void Awake(AircraftSJ self, FlightPlanEditor flightPlanEditor)
  221. {
  222. self.FlightPlanEditor = flightPlanEditor;
  223. self.helper = new EquationHelper(HttpInterface.baseUrl);
  224. self.Awake();
  225. }
  226. }