TaskService.cs 35 KB

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