TaskService.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. using Microsoft.Win32.SafeHandles;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Configuration;
  5. using System.Diagnostics;
  6. using System.Globalization;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using XdCxRhDW.Dto;
  12. using XdCxRhDW.Framework;
  13. namespace X3Leo1TaskServer54.Service
  14. {
  15. public class TaskService
  16. {
  17. public TaskSvrConfig _config;
  18. public TaskService()
  19. {
  20. try
  21. {
  22. Directory.CreateDirectory("tmp");
  23. _config = new TaskSvrConfig();
  24. _config.baseUrl = AppConfigHelper.Get("PosPlatformAddr").AppendUrlSuffix("api/");
  25. _config.capSeconds = AppConfigHelper.Get("CapSeconds", 60);
  26. _config.mainSatDelay = AppConfigHelper.Get<double?>("MainSatDelay");
  27. _config.adja1SatDelay = AppConfigHelper.Get<double?>("Adja1SatDelay");
  28. _config.adja2SatDelay = AppConfigHelper.Get<double?>("Adja2SatDelay");
  29. _config.checkFileType = AppConfigHelper.Get("CheckFileType", 0);
  30. _config.threadCount = AppConfigHelper.Get("ThreadCount", 0).NotLessThanZero();
  31. _config.posDtoFactor = AppConfigHelper.Get("PosDtoFactor", 1);
  32. _config.DtoErrus = AppConfigHelper.Get<double>("DtoErrus", 1);
  33. _config.EphErrm = AppConfigHelper.Get<double>("EphErrm", 10000);
  34. }
  35. catch (Exception ex)
  36. {
  37. XdCxRhDW.UI.Lib.LogHelper.Error("读取配置文件异常", ex).Wait(5000);
  38. }
  39. }
  40. //等待采集完成(根据文件字节大小判断是否完成,最多等待采集时长+5秒)
  41. internal async Task WaitFileEnd(int taskID, HistoryFile file, int capSeconds, CancellationTokenSource cts)
  42. {
  43. int idx = 0;
  44. Stopwatch sw = new Stopwatch();
  45. sw.Start();
  46. while (true)
  47. {
  48. FileInfo s = new FileInfo(file.FilePath);
  49. long fs = (long)file.FsHz;
  50. var fileSize = fs * capSeconds * 4;
  51. if (s.Length == fileSize)
  52. {
  53. break;
  54. }
  55. if (idx == 0)
  56. await XdCxRhDW.UI.Lib.LogHelper.Info($"【任务{taskID}】等待[{file.CapTime:yyyyMMddHHmmss}]时刻文件采集完成...");
  57. await Task.Delay(2000, cts.Token);
  58. if (sw.ElapsedMilliseconds / 1000 > capSeconds + 5)
  59. break;
  60. idx++;
  61. }
  62. sw.Stop();
  63. }
  64. /// <summary>
  65. /// 是否能打开文件
  66. /// </summary>
  67. /// <param name="taskID"></param>
  68. /// <param name="file"></param>
  69. /// <returns></returns>
  70. internal bool CanOpenFile(int taskID, HistoryFile file)
  71. {
  72. try
  73. {
  74. using (var fs = new FileStream(file.FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
  75. {
  76. }
  77. return true;
  78. }
  79. catch (Exception ex)
  80. {
  81. XdCxRhDW.UI.Lib.LogHelper.Error($"【任务{taskID}】文件[{file.FilePath}]尝试打开失败", ex).Wait(5000);
  82. return false;
  83. }
  84. }
  85. /// <summary>
  86. /// 重置时间
  87. /// </summary>
  88. /// <param name="formatFlag"></param>
  89. /// <param name="time"></param>
  90. internal void ResetTime(int formatFlag, ref DateTime time)
  91. {
  92. if (formatFlag == 0)
  93. {
  94. time = DateTime.MaxValue;
  95. }
  96. else if (formatFlag == 1)
  97. {
  98. var newTime = new DateTime(time.Year, time.Month, time.Day, 0, 0, 0);
  99. time = newTime.AddHours(24);
  100. }
  101. else
  102. {
  103. var newTime = new DateTime(time.Year, time.Month, time.Day, time.Hour, 0, 0);
  104. time = newTime.AddHours(1);
  105. }
  106. }
  107. /// <summary>
  108. /// 获取采集文件信息
  109. /// </summary>
  110. /// <param name="dto"></param>
  111. /// <param name="filePath"></param>
  112. /// <param name="preTime"></param>
  113. /// <param name="ct"></param>
  114. /// <returns></returns>
  115. internal HistoryFile FileToHistoryFile(LeoSat3TaskHandleDto dto, string filePath, DateTime preTime, CancellationToken ct)
  116. {
  117. try
  118. {
  119. if (ct.IsCancellationRequested) return null;
  120. //读取采集文件
  121. //20240131100151_39206_310.850MHz_265.350MHz_C96000_CH2.dat
  122. HistoryFile historyFile = new HistoryFile();
  123. historyFile.FilePath = filePath;
  124. var fileName = Path.GetFileNameWithoutExtension(filePath);
  125. var strs = fileName.Split(new string[] { "_", "MHz", "CH", "ch", "C" }, StringSplitOptions.RemoveEmptyEntries);
  126. if (strs.Length == 6)
  127. { //采集时间
  128. var datestr = strs[0];
  129. DateTime dateTime;
  130. bool istime = DateTime.TryParseExact(datestr, "yyyyMMddHHmmss", null, DateTimeStyles.None, out dateTime);
  131. //卫星编号
  132. var satCodestr = strs[1];
  133. int.TryParse(satCodestr, out int satCode);
  134. //上行采集频点
  135. var upfreqstr = strs[2];
  136. double.TryParse(upfreqstr, out double upfreqMHz);
  137. //下行采集频点
  138. var downfreqstr = strs[3];
  139. double.TryParse(downfreqstr, out double downfreqMHz);
  140. //采样率
  141. var fsstr = strs[4];
  142. double.TryParse(fsstr, out double fsHz);
  143. var chstr = strs[5];
  144. int.TryParse(chstr, out int ch);
  145. historyFile.UpFreqHz = (long)((decimal)upfreqMHz * 1000000);
  146. historyFile.DownFreqHz = (long)((decimal)downfreqMHz * 1000000);
  147. historyFile.Ch = ch;
  148. historyFile.FsHz = fsHz;
  149. historyFile.XdIndex = 1;
  150. historyFile.SatId = satCode;
  151. historyFile.CapTime = dateTime;
  152. }
  153. else if (strs.Length == 13)
  154. {//采集时间
  155. var datestr = $"{strs[0]}{strs[1]}{strs[2]}{strs[3]}{strs[4]}{strs[5]}";
  156. DateTime dateTime;
  157. bool istime = DateTime.TryParseExact(datestr, "yyyyMMddHHmmss", null, DateTimeStyles.None, out dateTime);
  158. //采样率
  159. var fsstr = strs[8];
  160. Int64.TryParse(fsstr, out long fsHz);
  161. //卫星编号
  162. var satCodestr = strs[9];
  163. int.TryParse(satCodestr, out int satCode);
  164. //上行采集频点
  165. var upfreqstr = strs[10];
  166. double.TryParse(upfreqstr, out double upfreqMHz);
  167. //下行采集频点
  168. var downfreqstr = strs[11];
  169. double.TryParse(downfreqstr, out double downfreqMHz);
  170. var chstr = strs[12];
  171. int.TryParse(chstr, out int ch);
  172. historyFile.UpFreqHz = (long)((decimal)upfreqMHz * 1000000);
  173. historyFile.DownFreqHz = (long)((decimal)downfreqMHz * 1000000);
  174. historyFile.Ch = ch;
  175. historyFile.FsHz = fsHz;
  176. historyFile.XdIndex = 1;
  177. historyFile.SatId = satCode;
  178. historyFile.CapTime = dateTime;
  179. }
  180. else
  181. {
  182. return null;
  183. }
  184. return historyFile;
  185. }
  186. catch (Exception ex)
  187. {
  188. _=XdCxRhDW.UI.Lib.LogHelper.Error($"文件[{Path.GetFileName(filePath)}]名称格式异常,解析出错", ex);
  189. return null;
  190. }
  191. }
  192. internal bool IsLocal(string file)
  193. {
  194. if (file.StartsWith("\\")) return false;
  195. DirectoryInfo dir = new DirectoryInfo(file);
  196. foreach (DriveInfo d in DriveInfo.GetDrives())
  197. {
  198. if (string.Compare(dir.Root.FullName, d.Name, StringComparison.OrdinalIgnoreCase) == 0) //[drweb86] Fix for different case.
  199. {
  200. return (d.DriveType != DriveType.Network);
  201. }
  202. }
  203. return false;
  204. }
  205. internal List<List<IGrouping<long, HistoryFile>>> SplitFreqFiles(IEnumerable<IGrouping<long, HistoryFile>> multFreqFiles)
  206. {
  207. var thread = _config.threadCount;
  208. if (thread <= 0)
  209. thread = 1000;
  210. var list = new List<List<IGrouping<long, HistoryFile>>>();
  211. var count = multFreqFiles.Count();//10
  212. var countPackage = count / thread;//2
  213. if (countPackage == 0)
  214. countPackage = 1;
  215. for (int i = 0; i < thread; i++)//0-3
  216. {
  217. if (i * countPackage >= count) break;
  218. list.Add(multFreqFiles.Skip(i * countPackage).Take(countPackage).ToList());
  219. }
  220. for (int i = 0; i < list.Count; i++)
  221. {
  222. if (thread * countPackage + i >= count) break;
  223. list[i].AddRange(multFreqFiles.Skip(thread * countPackage + i).Take(1));
  224. }
  225. return list;
  226. }
  227. private bool GetLocalFile(ref long size, string localFile, string sourceFile, CancellationTokenSource cts)
  228. {
  229. using (FileStream fs = new FileStream(localFile, FileMode.Create))
  230. {
  231. using (FileStream fs2 = new FileStream(sourceFile, FileMode.Open))
  232. {
  233. size += fs2.Length;
  234. while (fs2.Position < fs2.Length)
  235. {
  236. if (cts.IsCancellationRequested) return false;
  237. byte[] data = new byte[1024];
  238. var len = fs2.Read(data, 0, 1024);
  239. data = data.Take(len).ToArray();
  240. fs.Write(data, 0, len);
  241. }
  242. }
  243. }
  244. return true;
  245. }
  246. private async Task<(bool, List<DetectResDto>)> DetectCalc(string cdbFile, string mainFile, BaseParamInfo paramInfo, CancellationTokenSource cts)
  247. {
  248. List<DetectResDto> deteRes = new List<DetectResDto>();
  249. DetectDto detectDto = new DetectDto()
  250. {
  251. file1 = cdbFile,//使用上行泄露信号进行检测
  252. dmcType = paramInfo.TaskSig.SigType,//上行信号检测目前的算法只能使用基于能量的KY或IBS检测
  253. fsHz = paramInfo.Minfo.FsHz,
  254. mergeRes = true,
  255. SigProc = true,
  256. // band = paramInfo.TaskSig.BandHz / 1e3,
  257. };
  258. if (_config.checkFileType == 0)//检测上行信号=0,检测主星下行信号=1
  259. {
  260. detectDto.dmcType = detectDto.dmcType & ~EnumSigCheckTypeDto.DAMA;//DAMA不支持上行信号检测,在这里移除掉
  261. if ((int)detectDto.dmcType == 0)
  262. {
  263. await XdCxRhDW.UI.Lib.LogHelper.Warning($"【任务{paramInfo.TaskSig.TaskInfoID}】信号[{paramInfo.TaskSig.FreqUp / 1e6:f3}MHz],上行信号不支持仅DAMA检测");
  264. return (false, deteRes);
  265. }
  266. }
  267. else
  268. {
  269. detectDto.file1 = mainFile;//使用主星下行信号进行检测
  270. }
  271. if (detectDto.dmcType == EnumSigCheckTypeDto.Normal)
  272. {
  273. await XdCxRhDW.UI.Lib.LogHelper.Warning($"【任务{paramInfo.TaskSig.TaskInfoID}】信号[{paramInfo.TaskSig.FreqUp / 1e6:f3}MHz],该服务不支持Normal类型信号");
  274. return (false, deteRes);
  275. }
  276. Stopwatch sw3 = new Stopwatch();
  277. sw3.Start();
  278. var deteResp = await HttpHelper.PostRequestAsync<List<DetectResDto>>(_config.baseUrl + "DetectCg/DetectCalc", detectDto, token: cts.Token);
  279. if (deteResp.code != 200)
  280. {
  281. if (deteResp.msg.Contains("超时"))
  282. await XdCxRhDW.UI.Lib.LogHelper.Error($"【任务{paramInfo.TaskSig.TaskInfoID}】信号[{paramInfo.TaskSig.FreqUp / 1e6:f3}MHz],{paramInfo.Minfo.CapTime:yyyyMMddHHmmss}时刻{deteResp.msg}");
  283. else
  284. await XdCxRhDW.UI.Lib.LogHelper.Error($"【任务{paramInfo.TaskSig.TaskInfoID}】信号[{paramInfo.TaskSig.FreqUp / 1e6:f3}MHz],{paramInfo.Minfo.CapTime:yyyyMMddHHmmss}时刻信号检测出错.{deteResp.msg}");
  285. return (false, deteRes);
  286. }
  287. sw3.Stop();
  288. await XdCxRhDW.UI.Lib.LogHelper.Info($"【任务{paramInfo.TaskSig.TaskInfoID}】信号[{paramInfo.TaskSig.FreqUp / 1e6:f3}MHz],{paramInfo.Minfo.CapTime:yyyyMMddHHmmss}时刻{_config.checkFileTypeStr}检测完成,共{deteResp.data.Count}个时隙,耗时{sw3.ElapsedMilliseconds}ms");
  289. deteRes.AddRange(deteResp.data);
  290. return (true, deteRes);
  291. }
  292. internal Task GetPosTask(LeoSat3TaskHandleDto dto, List<IGrouping<long, HistoryFile>> item, bool isLocal, CancellationTokenSource cts)
  293. {
  294. var task = Task.Run(async () =>
  295. {
  296. foreach (var xdInfos in item)//item中的数据串行处理
  297. {
  298. var finfos = xdInfos.ToList();
  299. var capTime = finfos.First().CapTime;
  300. if (dto.TaskType == EnumTaskTypeDto.History)
  301. {
  302. if (capTime < dto.StartTime) continue;
  303. if (capTime > dto.EndTime) continue;
  304. }
  305. if (finfos.Count < 3)
  306. {
  307. await XdCxRhDW.UI.Lib.LogHelper.Warning($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻文件数量只有{finfos.Count}个,跳过此组数据");
  308. continue;
  309. }
  310. //主星
  311. var minfo = finfos.FirstOrDefault(m => m.SatId == dto.MainSatCode);
  312. if (minfo == null)
  313. {
  314. await XdCxRhDW.UI.Lib.LogHelper.Warning($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻未找到主星信号文件,跳过此组数据");
  315. continue;
  316. }
  317. var taskSig = dto.Sigs.FirstOrDefault(p => p.FreqUp == minfo.UpFreqHz);
  318. if (taskSig == null)
  319. {
  320. continue;//跳过不是任务处理的频点
  321. }
  322. //邻1
  323. var n1info = finfos.FirstOrDefault(m => m.SatId == dto.Adja1SatCode);
  324. if (n1info == null)
  325. {
  326. await XdCxRhDW.UI.Lib.LogHelper.Info($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6}],{capTime:yyyyMMddHHmmss}时刻未找到邻星1信号文件,跳过此组数据");
  327. continue;
  328. }
  329. //主星
  330. var n2info = finfos.FirstOrDefault(m => m.SatId == dto.Adja2SatCode);
  331. if (n2info == null)
  332. {
  333. await XdCxRhDW.UI.Lib.LogHelper.Warning($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6}],{capTime:yyyyMMddHHmmss}时刻未找到邻星2信号文件,跳过此组数据");
  334. continue;
  335. }
  336. var paramInfo = new BaseParamInfo(taskSig, minfo, n1info, n2info);
  337. try
  338. {
  339. paramInfo.SetDelay(_config.mainSatDelay, _config.adja1SatDelay, _config.adja2SatDelay);
  340. string localFile1 = minfo.FilePath;
  341. string localFile2 = n1info.FilePath;
  342. string localFile3 = n2info.FilePath;
  343. if (!isLocal)
  344. {
  345. long size = 0;
  346. await XdCxRhDW.UI.Lib.LogHelper.Info($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻三路采集文件正在拉取到本地...");
  347. Stopwatch sw22 = new Stopwatch();
  348. sw22.Start();
  349. localFile1 = $"wwwroot\\{Path.GetFileName(minfo.FilePath)}";
  350. bool ret = GetLocalFile(ref size, localFile1, minfo.FilePath, cts);
  351. if (!ret) return;
  352. localFile2 = $"wwwroot\\{Path.GetFileName(n1info.FilePath)}";
  353. ret = GetLocalFile(ref size, localFile2, n1info.FilePath, cts);
  354. if (!ret) return;
  355. localFile3 = $"wwwroot\\{Path.GetFileName(n2info.FilePath)}";
  356. ret = GetLocalFile(ref size, localFile3, n2info.FilePath, cts);
  357. if (!ret) return;
  358. sw22.Stop();
  359. var spped = size / 1024d / 1024d / (sw22.ElapsedMilliseconds / 1000d);
  360. await XdCxRhDW.UI.Lib.LogHelper.Info($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻三路采集文件拉取到本地完成,共耗时{sw22.ElapsedMilliseconds}ms,平均速率{spped:f2}MB/s");
  361. }
  362. string mainFile = await HttpHelper.UploadFileAsync(localFile1, _config.baseUrl, token: cts.Token);//主星文件
  363. string adja1File = await HttpHelper.UploadFileAsync(localFile2, _config.baseUrl, token: cts.Token);//邻星文件
  364. string adja2File = await HttpHelper.UploadFileAsync(localFile3, _config.baseUrl, token: cts.Token);//超短文件
  365. if (!isLocal)
  366. {
  367. File.Delete(localFile1);
  368. File.Delete(localFile2);
  369. File.Delete(localFile3);
  370. }
  371. //检测
  372. (bool deret, List<DetectResDto> deteRes) = await DetectCalc(adja2File, mainFile, paramInfo, cts);
  373. if (!deret) continue;
  374. var smps = deteRes.Select(m => new SmpPosition(m.Start, m.Length)).ToList();//怎么补0?
  375. //double tarLon = 118.95, tarLat = 9.17;
  376. //var tarLoc = PhysicsHelper.GeoToEcef((tarLon, tarLat, 0));
  377. //var mxl = await GetSatEphAsync(paramInfo.Minfo.SatId, n2info.CapTime.AddSeconds(7));
  378. //var nx2 = await GetSatEphAsync(paramInfo.N2info.SatId, n2info.CapTime.AddSeconds(7));
  379. //var mx1Ecef = (mxl.X, mxl.Y, mxl.Z);
  380. //var nx21Ecef = (nx2.X, nx2.Y, nx2.Z);
  381. //var rec1 = PhysicsHelper.GeoToEcef((dto.MSatCapLon, dto.MSatCapLat, 0));
  382. //var rec2 = PhysicsHelper.GeoToEcef((dto.N2SatCapLon, dto.N2SatCapLat, 0));
  383. //var dt1 = PhysicsHelper.Dto(tarLoc, mx1Ecef, rec1);
  384. //var dt2 = PhysicsHelper.Dto(tarLoc, nx21Ecef, rec2);
  385. //var centerUs = (dt2 - dt1) * 1e6;
  386. //File.AppendAllText("1.txt", centerUs.ToString() + "\r\n");
  387. var cgDto = new CpuCgMultiDto()
  388. {
  389. dtCenter = -190000,
  390. dtRange = 80000,
  391. file1 = adja2File,
  392. file2 = mainFile,
  393. samplingRate = minfo.FsHz,
  394. smpPositions = smps,
  395. snrThreshold = taskSig.Snr,
  396. BandHz = 0,
  397. dfRange = 16384*4,
  398. };
  399. if (_config.checkFileType != 0)
  400. {
  401. cgDto.file1 = mainFile;
  402. cgDto.file2 = adja2File;
  403. }
  404. Stopwatch sw2 = new Stopwatch();
  405. sw2.Start();
  406. var result1 = await HttpHelper.PostRequestAsync<List<CpuCgResDto>>(_config.baseUrl + "DetectCg/CpuCgMultiCalc", cgDto, token: cts.Token);
  407. if (result1.code != 200)
  408. {
  409. if (result1.msg.Contains("超时"))
  410. await XdCxRhDW.UI.Lib.LogHelper.Error($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻主星邻2{result1.msg}");
  411. else
  412. await XdCxRhDW.UI.Lib.LogHelper.Error($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻主星邻2参估出错.{result1.msg}");
  413. continue;
  414. }
  415. sw2.Stop();
  416. await XdCxRhDW.UI.Lib.LogHelper.Info($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻主星邻2参估完成,耗时{sw2.ElapsedMilliseconds}ms");
  417. cgDto = new CpuCgMultiDto()
  418. {
  419. dtCenter = 0,
  420. dtRange = 40000,
  421. file1 = adja2File,
  422. file2 = adja1File,
  423. samplingRate = minfo.FsHz,
  424. smpPositions = smps,
  425. snrThreshold = taskSig.Snr,
  426. BandHz = 0,
  427. dfRange = 16384,
  428. };
  429. if (_config.checkFileType != 0)
  430. {
  431. cgDto.file1 = mainFile;
  432. cgDto.file2 = adja1File;
  433. cgDto.dtCenter = 0;
  434. cgDto.dtRange = 40000;
  435. }
  436. sw2.Restart();
  437. var result2 = await HttpHelper.PostRequestAsync<List<CpuCgResDto>>(_config.baseUrl + "DetectCg/CpuCgMultiCalc", cgDto, token: cts.Token);
  438. if (result2.code != 200)
  439. {
  440. if (_config.checkFileType == 0)
  441. {
  442. if (result2.msg.Contains("超时"))
  443. await XdCxRhDW.UI.Lib.LogHelper.Error($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻邻星超短{result2.msg}");
  444. else
  445. await XdCxRhDW.UI.Lib.LogHelper.Error($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻邻星超短CPU参估出错.{result2.msg}");
  446. }
  447. else
  448. {
  449. if (result2.msg.Contains("超时"))
  450. await XdCxRhDW.UI.Lib.LogHelper.Error($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻主星邻星1{result2.msg}");
  451. else
  452. await XdCxRhDW.UI.Lib.LogHelper.Error($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻主星邻星1CPU参估出错.{result2.msg}");
  453. }
  454. continue;
  455. }
  456. sw2.Stop();
  457. if (_config.checkFileType == 0)
  458. await XdCxRhDW.UI.Lib.LogHelper.Info($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻邻星超短CPU参估完成,耗时{sw2.ElapsedMilliseconds}ms");
  459. else
  460. await XdCxRhDW.UI.Lib.LogHelper.Info($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻主星邻星1CPU参估完成,耗时{sw2.ElapsedMilliseconds}ms");
  461. await HttpHelper.DeleteFileAsync(_config.baseUrl, mainFile, adja1File, adja2File);
  462. var data1 = result2.data;//主星邻星1
  463. var data2 = result1.data;//主星邻星2
  464. if (data1.Count != data2.Count || data1.Count != deteRes.Count)
  465. {
  466. await XdCxRhDW.UI.Lib.LogHelper.Error($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻参估结果个数和检测结果个数不匹配");
  467. continue;
  468. }
  469. string msg = $"【任务{dto.ID}】目标信号[{paramInfo.TaskSig.FreqUp / 1e6:f3}MHz]";
  470. //目标信号
  471. await DoX3NoRefPosAsync(dto, paramInfo, deteRes, data1, data2, cts, msg);
  472. }
  473. catch (TaskCanceledException)
  474. {
  475. }
  476. catch (Exception ex)
  477. {
  478. if (ex.InnerException != null && ex.InnerException.GetType() == typeof(TaskCanceledException))
  479. break;
  480. else
  481. await XdCxRhDW.UI.Lib.LogHelper.Error($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6:f3}MHz],{capTime:yyyyMMddHHmmss}时刻文件处理异常", ex);
  482. continue;
  483. }
  484. }
  485. });
  486. return task;
  487. }
  488. private async Task DoX3NoRefPosAsync(LeoSat3TaskHandleDto dto, BaseParamInfo paramInfo, List<DetectResDto> deteRes, List<CpuCgResDto> data1, List<CpuCgResDto> data2, CancellationTokenSource cts, string msg)
  489. {
  490. for (int i = 0; i < data1.Count; i++)
  491. {
  492. try
  493. {
  494. if (cts.IsCancellationRequested) break;
  495. var detect = deteRes.First(r => r.Start == data1[i].Smpstart && r.Length == data1[i].Smplen);
  496. DateTime SigTime = paramInfo.Minfo.CapTime.AddSeconds(data1[i].Smpstart / paramInfo.Minfo.FsHz);
  497. var mxl = await GetSatEphAsync(paramInfo.Minfo.SatId, SigTime);
  498. var nxl = await GetSatEphAsync(paramInfo.N1info.SatId, SigTime);
  499. var nx2 = await GetSatEphAsync(paramInfo.N2info.SatId, SigTime);
  500. if (mxl == null || nxl == null || nx2 == null)
  501. {
  502. await XdCxRhDW.UI.Lib.LogHelper.Error($"{paramInfo.Minfo.CapTime:yyyyMMddHHmmss}时刻[{paramInfo.Minfo.SatId},{paramInfo.N1info.SatId},{paramInfo.N2info.SatId}]星历不存在");
  503. continue;
  504. }
  505. X3TwoDtoNoParPosDto x3 = new X3TwoDtoNoParPosDto()
  506. {
  507. TaskID = dto.ID,
  508. SigTime = SigTime,
  509. MainCode = paramInfo.Minfo.SatId,
  510. Adja1Code = paramInfo.N1info.SatId,
  511. Adja2Code = paramInfo.N2info.SatId,
  512. MainX = mxl.X,
  513. MainY = mxl.Y,
  514. MainZ = mxl.Z,
  515. MainVX = mxl.VX,
  516. MainVY = mxl.VY,
  517. MainVZ = mxl.VZ,
  518. Adja1X = nxl.X,
  519. Adja1Y = nxl.Y,
  520. Adja1Z = nxl.Z,
  521. Adja1VX = nxl.VX,
  522. Adja1VY = nxl.VY,
  523. Adja1VZ = nxl.VZ,
  524. Adja2X = nx2.X,
  525. Adja2Y = nx2.Y,
  526. Adja2Z = nx2.Z,
  527. Adja2VX = nx2.VX,
  528. Adja2VY = nx2.VY,
  529. Adja2VZ = nx2.VZ,
  530. MSatTxLon = dto.MSatCapLon,
  531. MSatTxLat = dto.MSatCapLat,
  532. N1SatTxLon = dto.N1SatCapLon,
  533. N1SatTxLat = dto.N1SatCapLat,
  534. N2SatTxLon = dto.N2SatCapLon,
  535. N2SatTxLat = dto.N2SatCapLat,
  536. FreqDown = paramInfo.Minfo.DownFreqHz,
  537. FreqUp = paramInfo.Minfo.UpFreqHz,
  538. CheckRes = new CheckResDto()
  539. {
  540. FileName = Path.GetFileName(paramInfo.Minfo.FilePath),
  541. ModRate = detect.ModRate,
  542. ModType = detect.ModType,
  543. SmpCount = detect.Length,
  544. SmpStart = detect.Start,
  545. UserName = detect.UserName,
  546. FfcHz = detect.FfcHz,
  547. Snr = detect.Snr,
  548. PosCheckType = detect.DmcType.GetEnumByDisplayName<EnumPosCheckTypeDto>(),
  549. }
  550. };
  551. double conValue = (666 + 2 / 3) * 2;//ddc不同算法的误差us
  552. if (data1[i].Snr > 0 && data2[i].Snr > 0)
  553. {
  554. x3.Dto1 = data1[i].Dt * _config.posDtoFactor - paramInfo.Delay1.Value + paramInfo.Delay2.Value;
  555. x3.Dfo1 = data1[i].Df;
  556. x3.Snr1 = data1[i].Snr;
  557. x3.Dto2 = data2[i].Dt * _config.posDtoFactor - paramInfo.Delay1.Value - conValue;
  558. x3.Dfo2 = data2[i].Df;
  559. x3.Snr2 = data2[i].Snr;
  560. }
  561. var result = await HttpHelper.PostRequestAsync<PosResDto>(_config.baseUrl + "Pos/PosX3LeoDtoNoParAsync", x3);
  562. if (result.code != 200)
  563. {
  564. await XdCxRhDW.UI.Lib.LogHelper.Error($"{msg},{paramInfo.Minfo.CapTime:yyyyMMddHHmmss}时刻时隙位置{data1[i].Smpstart}定位异常.{result.msg}");
  565. }
  566. else
  567. {
  568. var posRes = result.data;
  569. double posLon = posRes.PosLon;
  570. double posLat = posRes.PosLat;
  571. if (x3.Snr1 == 0 || x3.Snr2 == 0)
  572. {
  573. posLon = 0;
  574. posLat = 0;
  575. }
  576. ErrEllipseResDto errRes = new ErrEllipseResDto();
  577. if (posLon != 0 && posLat != 0 && posLon != 999 && posLat != 999)
  578. {
  579. var errDto = new ErrEllipseX3NoRefDto()
  580. {
  581. MainX = mxl.X,
  582. MainY = mxl.Y,
  583. MainZ = mxl.Z,
  584. Adja1X = nxl.X,
  585. Adja1Y = nxl.Y,
  586. Adja1Z = nxl.Z,
  587. Adja2X = nx2.X,
  588. Adja2Y = nx2.Y,
  589. Adja2Z = nx2.Z,
  590. PosLon = posLon,
  591. PosLat = posLat,
  592. //RefLon = dto.RefLon,
  593. // RefLat = dto.RefLat,
  594. OutputErrPoint = false,
  595. DtoErrus = _config.DtoErrus,
  596. EphErr = _config.EphErrm,
  597. };
  598. var errResRsp = await HttpHelper.PostRequestAsync<ErrEllipseResDto>(_config.baseUrl + "Ellipse/X3TwoDtoNoRef", errDto);
  599. if (errResRsp.code != 200)
  600. {
  601. await XdCxRhDW.UI.Lib.LogHelper.Error(errResRsp.msg);
  602. }
  603. else
  604. {
  605. errRes = errResRsp.data;
  606. }
  607. }
  608. PosResWriteDto wDto = new PosResWriteDto()
  609. {
  610. PosTypeDto = EnumPosTypeDto.X3LeoDto,
  611. SigTime = x3.SigTime,
  612. SigTimeLenMs = x3.CheckRes.SmpCount / (long)paramInfo.Minfo.FsHz * 1000,
  613. FreqDownMHz = paramInfo.Minfo.DownFreqHz * 1e-6,
  614. FreqUpMHz = paramInfo.Minfo.UpFreqHz * 1e-6,
  615. SigModType = detect.ModType,
  616. PosLon = posLon,
  617. PosLat = posLat,
  618. Dto1 = x3.Dto1,
  619. Dfo1 = x3.Dfo1,
  620. Snr1 = x3.Snr1,
  621. Dto2 = x3.Dto2,
  622. Dfo2 = x3.Dfo2,
  623. Snr2 = x3.Snr2,
  624. LongRadius = errRes.LongRadius,
  625. ShortRadius = errRes.ShortRadius,
  626. DipAngle = errRes.DipAngle,
  627. TsCount = data1.Count,
  628. PosType = 4,
  629. ModRate = detect.ModRate.HasValue ? detect.ModRate.Value : 0,
  630. };
  631. await HttpHelper.PostRequestAsync(_config.baseUrl + "Result/WritePosResToFile", wDto);
  632. }
  633. }
  634. catch (Exception ex)
  635. {
  636. await XdCxRhDW.UI.Lib.LogHelper.Error($"{msg},{paramInfo.Minfo.CapTime:yyyyMMddHHmmss}时刻时隙位置{data1[i].Smpstart}定位异常", ex);
  637. }
  638. }
  639. await XdCxRhDW.UI.Lib.LogHelper.Info($"{msg},{paramInfo.Minfo.CapTime:yyyyMMddHHmmss}时刻定位完成");
  640. }
  641. private async Task<SatEphResDto> GetSatEphAsync(int satcode, DateTime sigtime)
  642. {
  643. var result = await HttpHelper.PostRequestAsync<SatEphResDto>(_config.baseUrl + "Xl/XLCalc", new SatDto() { SatCode = satcode, SigTime = sigtime });
  644. if (result.code != 200)
  645. {
  646. await XdCxRhDW.UI.Lib.LogHelper.Error($"卫星:{satcode},{sigtime:yyyyMMddHHmmss}时刻获取星历异常.{result.msg}");
  647. return null;
  648. }
  649. return result.data;
  650. }
  651. private async Task<RefCafResultDto> GeRefCgDtAsync(int satcode, DateTime sigtime)
  652. {
  653. var result = await HttpHelper.PostRequestAsync<RefCafResultDto>(_config.baseUrl + "Task/GetRefCalcAsync", new SatDto() { SatCode = satcode, SigTime = sigtime });
  654. if (result.code != 200)
  655. {
  656. await XdCxRhDW.UI.Lib.LogHelper.Error($"卫星:{satcode},{sigtime:yyyyMMddHHmmss}时刻获取参考参估结果异常.{result.msg}");
  657. return null;
  658. }
  659. return result.data;
  660. }
  661. }
  662. }