using KYFramework; using Model; using MongoDB.Bson; using MuShiApp; using Org.BouncyCastle.Asn1.Pkcs; using SimulationCommon; using SimulationSingleServer.Utils; using System.Threading; using Unity.Mathematics; using Point = SimulationCommon.Point; using Random = System.Random; namespace SimulationServer; public class AircraftSJ : AircraftEntity { public bool IsOver; private MissionEndPoint MissionEndPoint; private CurrentLocation currentLocation; private double temptime = 0; private double probability = 0; private double finalProbability = 1.0; public bool isseePerson = false; private int fireIndex = -1; // 记录发现火点的位置 public EquationHelper helper; public SeaSouJiuTask taskContent; public bool Success = false; //本目标搜救是否成功 public GetNCData getNCData; public double resulttime; public SearchMissionPayload searchMissionPayload; //private bool isbool; //private bool isbool2; //Text_readNC text_ReadNC; public SearchMissionMode SearchMode; int Days; int Hour; public int targetCount; public bool isEndWhile; public int sbCount; public double seaArea; public bool isReadNC; Text_readNC text_ReadNC; public override void Reset() { base.Reset(); IsOver = false; isseePerson = false; Success = false; SearchTime = 0; TotalTime = 0; resulttime = 0; isEndWhile = false; targetCount = 0; sbCount = 0; seaArea = 0; } public override void Start() { if (FlightPlanEditor.targetpoint[0].TargetType.Type == "落水人员") { targetCount = FlightPlanEditor.targetpoint[0].TargetType.Count; sbCount = targetCount; } else sbCount = 1; int Year = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[0]); int Month = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[0]); int Day = Convert.ToInt32(taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[1].Split("日")[0]); Hour = Convert.ToInt32(taskContent.missionInformation.StartTime.Split("时")[0]); Days = GetDaysInYear(Year, Month, Day); //Console.WriteLine("Day:" + Days); Velocitys = new double[5] { 220, 220, 60, 110, 0 }; // 速度 //TODO 计算 AirRoute[] double[] initialPosition = { FlightPlanEditor.targetpoint[0].TargetPointLatitude, FlightPlanEditor.targetpoint[0].TargetPointLongitude }; double dt = 1; double totalTime = 24.0; if (!isReadNC) { //if (!isbool2) //{ text_ReadNC = new Text_readNC(); text_ReadNC.initlatitudes = FlightPlanEditor.targetpoint[0].TargetPointLatitude; text_ReadNC.initlongitudes = FlightPlanEditor.targetpoint[0].TargetPointLongitude; //text_ReadNC = new Text_readNC(); bool isSuccess = false; while(!isSuccess) { isSuccess = text_ReadNC.GetNCData(); } bool isSuccess2 = false; while (!isSuccess2) { isSuccess2 = text_ReadNC.GetWaveHighData(); } //isbool2 = true; //} getNCData = new GetNCData(); getNCData.initlatitudes = FlightPlanEditor.targetpoint[0].TargetPointLatitude; getNCData.initlongitudes = FlightPlanEditor.targetpoint[0].TargetPointLongitude; bool isSuccess3 = false; while(!isSuccess3) { isSuccess3 = getNCData.GetData(); } isReadNC = true; } var nCread = text_ReadNC.windNCread; //漂移轨迹 List trajectory = SeaSJ.CalculateDriftTrajectory(nCread, initialPosition, dt, totalTime, text_ReadNC.times, text_ReadNC.latitudes, text_ReadNC.longitudes, text_ReadNC.times1, text_ReadNC.latitudes1, text_ReadNC.longitudes1, text_ReadNC.times2, text_ReadNC.latitudes2, text_ReadNC.longitudes2, text_ReadNC.times3, text_ReadNC.latitudes3, text_ReadNC.longitudes3, Days, Hour, text_ReadNC.initlatitudes, text_ReadNC.initlongitudes); //foreach ( var trajectoryItem in trajectory) //{ // Console.WriteLine("trajectory:" + trajectoryItem[0] + "_" + trajectoryItem[1]); //} // 生成任务终点 MissionEndPoint = new MissionEndPoint { MissionEndPointLongitude = trajectory[^1][1], MissionEndPointLatitude = trajectory[^1][0], MissionEndPointHeight = 0 }; var temp = SeaSJ.getminEnclosingRect(trajectory); // seaArea = Rectangular_Area_Search_Function.min_area; // temp 转成 List List points = new List(); foreach (var item in temp) { points.Add(new Point(item[0], item[1])); } //foreach (var item in points) //{ // Console.WriteLine("item:" + item.lat + "-" + item.lon); //} Point basePoint = new Point(FlightPlanEditor.originbase.BaseLatitude, FlightPlanEditor.originbase.BaseLongitude); List waypoints = new List(); //******* if (SearchMode.SearchMode == "平行线搜索") { waypoints = ParallellineSearch.parallellineSearch(basePoint, points, SearchMode.SearchWidth); } if (SearchMode.SearchMode == "扇形搜索") { // 求 points 的中心点 var startPoint1 = new Point { lat = points[0].lat / 2 + points[1].lat / 2, lon = points[0].lon / 2 + points[1].lon / 2 }; var startPoint2 = new Point { lat = points[2].lat / 2 + points[3].lat / 2, lon = points[2].lon / 2 + points[3].lon / 2 }; var centerPoint = new Point { lat = startPoint1.lat / 2 + startPoint2.lat / 2, lon = startPoint1.lon / 2 + startPoint2.lon / 2 }; waypoints = SectorSearch.sectorSearch(centerPoint, 30, SearchMode.SearchWidth); } if (SearchMode.SearchMode == "扩展矩形搜索") { // 求 points 的中心点 var startPoint1 = new Point { lat = points[0].lat / 2 + points[1].lat / 2, lon = points[0].lon / 2 + points[1].lon / 2 }; //Console.WriteLine("startPoint1:" + startPoint1.lat + "-" + startPoint1.lon); var startPoint2 = new Point { lat = points[2].lat / 2 + points[3].lat / 2, lon = points[2].lon / 2 + points[3].lon / 2 }; //Console.WriteLine("startPoint2:" + startPoint2.lat + "-" + startPoint2.lon); var centerPoint = new Point { lat = startPoint1.lat / 2 + startPoint2.lat / 2, lon = startPoint1.lon / 2 + startPoint2.lon / 2 }; //Console.WriteLine("centerPoint:" + centerPoint.lat + "-" + centerPoint.lon); // 以 centerPoint 为中心,生成正方形区域 var lonD = Math.Abs(points[0].lon - points[1].lon); var latD1 = Math.Abs(points[1].lat - points[2].lat); var max = Math.Max(lonD, latD1); //Console.WriteLine("max:" + max); // 以 distance 为边长 以 centerPoint 为中心点的正方形 var temp0 = new Point(centerPoint.lat + max / 2, centerPoint.lon - max / 2); var temp1 = new Point(centerPoint.lat + max / 2, centerPoint.lon + max / 2); var temp2 = new Point(centerPoint.lat - max / 2, centerPoint.lon + max / 2); var temp3 = new Point(centerPoint.lat - max / 2, centerPoint.lon - max / 2); //Console.WriteLine("temp0:" + temp0.lat + "-" + temp0.lon); //Console.WriteLine("temp1:" + temp1.lat + "-" + temp1.lon); //Console.WriteLine("temp2:" + temp2.lat + "-" + temp2.lon); //Console.WriteLine("temp3:" + temp3.lat + "-" + temp3.lon); //Console.WriteLine("SearchWidth:" + SearchMode.SearchWidth); waypoints = TZFX.GenerateWaypoints(temp0, temp1, temp2, temp3, max, SearchMode.SearchWidth); } //foreach (var item in waypoints) //{ // Console.WriteLine("item.lat :" + item.lat + "-" + "item.lon:" + item.lon); //} // List 转成 List List airRoutes = new List(); foreach (var item in waypoints) { airRoutes.Add(new AirRoute { AirRouteLatitude = item.lat, AirRouteLongitude = item.lon }); } FlightPlanEditor.airroute = airRoutes.ToArray(); MissionPoint missionPoint = new MissionPoint(); missionPoint.MissionPointLatitude = waypoints[0].lat; missionPoint.MissionPointLongitude = waypoints[0].lon; FlightPlanEditor.missionpoint = missionPoint; FXJHGenerate.FromStartToMission(FlightPlanEditor, ref TurningPoints); //生成从起点到任务段起点的航路点 FXJHGenerate.SeaSouJiu(FlightPlanEditor, ref TurningPoints); FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions); //foreach (var item in TurningPoints) //{ // Console.WriteLine("TurningPointLatitude:" + item.TurningPointLatitude + "_" + "TurningPointLongitude:" + item.TurningPointLongitude); //} double time = 0; // 第一次 搜寻结束 for (int i = 0; i < TurningPoints.Count - 2; i++) { time += TurningPoints[i].SegmentFlightTime; } double3 targetPoint = new double3(FlightPlanEditor.targetpoint[0].TargetPointLongitude, FlightPlanEditor.targetpoint[0].TargetPointLatitude, FlightPlanEditor.targetpoint[0].TargetPointHeight); string cityName = helper.getCityName(targetPoint.x, targetPoint.y); //var vis = helper.getVisibility(cityName, DateTime.Now.ToString("yyyy-MM-dd HH")); string year = taskContent.missionInformation.StartDate.Split("年")[0]; string month = taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[0]; if (Convert.ToInt32(month) < 10) month = "0" + month; string day = taskContent.missionInformation.StartDate.Split("年")[1].Split("月")[1].Split("日")[0]; if (Convert.ToInt32(day) < 10) day = "0" + day; //string hour = taskContent.missionInformation.StartTime.Split("时")[0]; string date = year + "-" + month + "-" + day;// + " " + hour; //Console.Write(date); //Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH")); var vis = helper.getVisibilityByDb(targetPoint.x, targetPoint.y, date); //DateTime.Now.ToString("yyyy-MM-dd HH") //if (!isbool) //{ //getNCData = new GetNCData(); //getNCData.initlatitudes = FlightPlanEditor.targetpoint[0].TargetPointLatitude; //getNCData.initlongitudes = FlightPlanEditor.targetpoint[0].TargetPointLongitude; //getNCData.GetData(); //isbool = true; //} Task.Run(() => { bool isseePerson = false; // 输出表格平均救助时间没看到人是0看到人调用下面get_result_time_rope方法 //人员存活率需要重新算读取Editor搜救目标点初始坐标人数 //任务准备时间取值所有任务最小 double temptime = 0; // 自增时间,每次增加1s CurrentLocation currentLocation = new CurrentLocation(); double probability = 0; double finalProbability = 1.0; Random random = new Random(); int fireIndex = -1; // 记录发现火点的位置 double windSpeed = 0; do { if (!isseePerson && temptime >= time) { FXJHGenerate.SeaSouJiu(FlightPlanEditor, ref TurningPoints); FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions); time = 0; for (int i = 0; i < TurningPoints.Count - 2; i++) { time += TurningPoints[i].SegmentFlightTime; } Log.Info($"+++++++++++搜寻结束 TurningPoints Count: {TurningPoints.Count} 下次结束的时间 {time}++++++++++++++++"); } (currentLocation, _) = FXJHGenerate.GetAllCurrentLocation(TurningPoints, temptime); // 获取飞机当前位置 double3 aricraftPoint = new double3(currentLocation.CurrentLon, currentLocation.CurrentLat, currentLocation.CurrentHei); double3 targetPoint = new double3(FlightPlanEditor.targetpoint[0].TargetPointLongitude, FlightPlanEditor.targetpoint[0].TargetPointLatitude, FlightPlanEditor.targetpoint[0].TargetPointHeight); var wind = SeaSJ.GetWindVelocityFromAPI(nCread, currentLocation.CurrentLat, currentLocation.CurrentLon, temptime, text_ReadNC.times, text_ReadNC.latitudes, text_ReadNC.longitudes, text_ReadNC.times1, text_ReadNC.latitudes1, text_ReadNC.longitudes1, Days, Hour); windSpeed = Math.Sqrt(wind[0] * wind[0] + wind[1] * wind[1]); var waveHigh = SeaSJ.GetWaveHeightFromAPI(nCread, currentLocation.CurrentLon, currentLocation.CurrentLat, temptime, text_ReadNC.times4, text_ReadNC.latitudes4, text_ReadNC.longitudes4, Days, Hour); var distance = Utils.Util.GetDistance(currentLocation.CurrentLon, targetPoint.x, currentLocation.CurrentLat, targetPoint.y); //Console.WriteLine("targetPoint:" + targetPoint.x + "-" + targetPoint.y + "-" + targetPoint.z); Log.Info("距离:====================" + distance); //Console.WriteLine("searchMissionPayload.SearchPayload:" + searchMissionPayload.SearchPayload); if (searchMissionPayload.SearchPayload == "雷达搜索") { // Pd0 = 0.5 / Pf0 = Math.Pow(10,-6) / Pf = Math.Pow(10,-6) / R0 = 23645 / sigma0 = 5000 / sigma = Editor雷达截面面积 // R 单位m probability = helper.GetRadarPossibility(0.5, Math.Pow(10, -6), Math.Pow(10, -6), 23645, aricraftPoint, FlightPlanEditor.targetpoint[0], FlightPlanEditor.targetpoint[0].TargetType.RadarArea, 5000, vis); } else if (searchMissionPayload.SearchPayload == "目视搜索") { probability = helper.GetMushiSeaProbability(aricraftPoint, vis, waveHigh, FlightPlanEditor.targetpoint[0]); } else if (searchMissionPayload.SearchPayload == "光电(红外)搜索") { // Lt = 探测目标亮度 Editor / At = 探测目标面积 Editor / τa = 1 / Lb = 3 / A0 = 1 / D0 = 0.075 / Dstar = 3 / τo = 0.8 / Ad = 0.0073728 / Δf = 0.125 / δ = 0.5 / Pf0 = Math.Pow(10, -6); probability = helper.GetInfraredDetectionProbability(FlightPlanEditor.targetpoint[0].TargetType.TargetBrightness, FlightPlanEditor.targetpoint[0].TargetType.TargetArea, 1, 3, 1, aricraftPoint, FlightPlanEditor.targetpoint[0], 0.075, 3, 0.8, 0073728, 0.125, 0.5, Math.Pow(10, -6)); } // probability = helper.getProbability(aricraftPoint, targetPoint,pb, currentLocation.CurrentCourse, // windSpeed, waveHigh, "落水人员", "海上"); // 计算发现概率,需要其他模型输入 // 计算发现概率,需要其他模型输入 //finalProbability *= (1 - probability); // 到搜寻航路点的最后一个点 (?) Log.Info( $"海上任务:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},是否看到目标:{isseePerson}"); double randomValue = random.NextInt64(9006, 10000); // 生成随机数比较概率 //0.05 第一个参数越高概率越低 / 8985 0.212 100 / 9000 0.16 100 / 8995 0.14 100 / 8997 0.12 100 / 8999 0.18 100 / 9006 0.11 100 / 9010 0.12 100 / 9030 0.03 100 / 9026 0.07 0.04 100 / 9028 0.03 100 / 9027 0.04 100 / 9025 0.05 100 / //9025 0.02 100 / 9015 0.02 100 / 9020 0.04 100 / 9022 0.05 100 / 9022 0.04 100 / 9022 0 100 /9018 0.01 100 / 9021 0.01 100 / 9023 0.03 100 / 9000 0.08 100 / 9006 randomValue /= 10000; //randomValue = 0.8; if (randomValue < probability) // 1 - finalProbability { isseePerson = true; this.isseePerson = true; fireIndex = currentLocation.Currentsegnum; // 记录当前航路点位置 //IsOver = true; isEndWhile = true; } else { isseePerson = false; } if (temptime >= taskContent.missionInformation.TaskEndConditions.TaskTime) { //IsOver = true; isEndWhile = true; isseePerson = false; fireIndex = currentLocation.Currentsegnum; } temptime += 10; } while (!isseePerson && !isEndWhile); //IsOver == false //finalProbability = 1 - finalProbability; if (fireIndex != -1) { // 删除目标点位置开始的所有后续航路点 TurningPoints.RemoveRange(fireIndex + 1, TurningPoints.Count - fireIndex - 1); MissionPoint missionPoint = new MissionPoint { MissionPointLongitude = currentLocation.CurrentLon, MissionPointLatitude = currentLocation.CurrentLat, MissionPointHeight = currentLocation.CurrentHei }; FXJHGenerate.SeaSouJiu2(FlightPlanEditor, missionPoint, ref TurningPoints); //发现的目标坐标,需要其他模型输入 FXJHGenerate.FromMissionToEnd(FlightPlanEditor, MissionEndPoint, ref TurningPoints); } if (isseePerson) { double seeTime = 0; if (FlightPlanEditor.targetpoint[0].TargetType.Type == "落水人员") { for (int i = 0; i < TurningPoints.Count - 1; i++) { seeTime += TurningPoints[i].SegmentFlightTime; } //time = TotalTime; //time——搜索时间,单位:秒;数据测试用 double latitude = FlightPlanEditor.targetpoint[0].TargetPointLatitude; //落水人员纬度;数据测试用 double longitude = FlightPlanEditor.targetpoint[0].TargetPointLongitude; //落水人员经度,数据测试用 double survivalTime = SurvivalTimeModel.SurvivalTime(getNCData.tempreadNC, latitude, longitude, time, text_ReadNC.times, text_ReadNC.latitudes, text_ReadNC.longitudes, Days, Hour); //幸存时间 // SHJParameter.person_number = Eidtor里读取 SHJParameter.windspeed Nc/Editor目标气象信息读取时间先取任务初始时间 resulttime = get_result_time_rope(30, FlightPlanEditor.targetpoint[0].TargetType.Count, windSpeed, vis, 0.75, 1.38).time; //调运时间 Console.WriteLine("resulttime:" + resulttime); if (survivalTime * 3600 > seeTime) { Success = true; } //Log.Info("TotalTime:" + TotalTime); //Log.Info("幸存时间:" + survivalTime); } } //Console.WriteLine( // $"海上任务1:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},最终概率:{1 - finalProbability},是否看到落水人员:{isseePerson}"); Log.Info( $"海上任务:{taskContent.missionInformation.MissionName} 机型: {AircraftId} 当前时间:{temptime},当前位置:{currentLocation.CurrentLon},{currentLocation.CurrentLat},{currentLocation.CurrentHei},概率:{probability},是否看到目标:{isseePerson},人员是否幸存:{Success}"); FXJHGenerate.FXJHTPDiedai(FlightPlanEditor, ref TurningPoints, Velocitys, FuelConsumptions); End(); }); } public static handling_result get_result_time_rope(double H, int person_number, double windspeed, double vis, double upspeed, double downspeed) { handling_result result = new handling_result(); if (windspeed < 8 && vis > 3) { result.time = (person_number * H) / downspeed + (person_number * H) / upspeed; result.success = true; } else { result.success = false; } return result; } public static int GetDaysInYear(int year, int month, int day) { int[] daysInMonths = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (IsLeapYear(year)) { daysInMonths[1] = 29; } int days = day; for (int i = 0; i < month - 1; i++) { days += daysInMonths[i]; } return days; } public static bool IsLeapYear(int year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } public override void End() { for (int i = 0; i < TurningPoints.Count - 2; i++) { EffMisTime += TurningPoints[i].SegmentFlightTime; } for (int i = 0; i < TurningPoints.Count - 3; i++) { SearchTime += TurningPoints[i].SegmentFlightTime; //搜索时间 } for (int i = 0; i < TurningPoints.Count; i++) { TotalTime += TurningPoints[i].SegmentFlightTime; // 总时间 } TotalFuelConsumption = TurningPoints[0].RemainingFuel - TurningPoints[TurningPoints.Count - 1].RemainingFuel; //GetNCData getNCData = new GetNCData(); ////getNCData.GetData(); IsOver = true; } } [ObjectSystem] public class AircraftSJAwakeSystem : AwakeSystem { public override void Awake(AircraftSJ self, FlightPlanEditor flightPlanEditor) { self.FlightPlanEditor = flightPlanEditor; self.helper = new EquationHelper(HttpInterface.baseUrl); self.Awake(); } }