wyq 1 year ago
parent
commit
f7989c96aa

+ 3 - 0
Service/X2D1NoRefTaskServer54/App.config

@@ -35,6 +35,9 @@
 		<!--星历误差(单位:m)-->
 		<add key="EphErrm" value="10000"/>
 
+		<!--使用GPU执行参数估计=1 ,使用CPU执行参数估计=0-->
+		<add key="UseGpuCg" value="1"/>
+
 	</appSettings>
 	<startup>
 		<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />

+ 12 - 13
Service/X2D1NoRefTaskServer54/Controllers/X2D1NoRefTaskProcessingController.cs

@@ -12,7 +12,7 @@ using X2D1NoRefTaskServer54.Service;
 namespace X2D1NoRefTaskServer54.Controllers
 {
     /// <summary>
-    ///离线任务处理接口
+    ///两星一地任务处理接口
     /// </summary>
     public class X2D1NoRefTaskProcessingController : BaseController
     {
@@ -20,37 +20,37 @@ namespace X2D1NoRefTaskServer54.Controllers
          * !!!不要在Controller中放业务逻辑的全局变量(每次调用Http接口Controller都可能是一个新的对象)
          * Controller主要就是调用Service层的东西。Service层执行业务逻辑和调用Repository层操作数据库
          * ********************/
-        private readonly HistoryTaskService _service;
-        public X2D1NoRefTaskProcessingController(HistoryTaskService service)
+        private readonly TaskService _service;
+        public X2D1NoRefTaskProcessingController(TaskService service)
         {
             _service = service;
         }
 
 
         /// <summary>
-        /// 执行离线任务
+        /// 执行任务
         /// </summary>
-        /// <param name="dto">离线任务信息</param>
+        /// <param name="dto">任务信息</param>
         /// <returns></returns>
         [HttpPost]
         public AjaxResult Run(X2D1NoRefTaskHandleDto dto)
         {
             try
             {
-                LogHelper.Info($"接收到两星一地历史任务编号:{dto.ID}");
+                LogHelper.Info($"接收到任务编号:{dto.ID}");
                 _service.StartAsync(dto);
                 return Success();
             }
             catch (Exception ex)
             {
-                Serilog.Log.Error(ex, "两星一地历史任务处理出错!");
-                return Error("两星一地历史任务处理出错");
+                Serilog.Log.Error(ex, "任务处理出错!");
+                return Error("任务处理出错");
             }
         }
 
 
         /// <summary>
-        /// 历史任务停止
+        /// 任务停止
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
@@ -59,15 +59,14 @@ namespace X2D1NoRefTaskServer54.Controllers
         {
             try
             {
-
-                LogHelper.Warning($"接收停止两星一地历史任务编号:{dto.ID}");
+                LogHelper.Warning($"用户停止了任务,ID={dto.ID}");
                 _service.Stop();
                 return Success();
             }
             catch (Exception ex)
             {
-                Serilog.Log.Error(ex, "停止两星一地历史任务处理出错!");
-                return Error("停止两星一地历史任务处理出错");
+                Serilog.Log.Error(ex, $"【任务{dto.ID}】停止执行异常!");
+                return Error($"【任务{dto.ID}】停止执行异常!");
             }
         }
 

+ 0 - 426
Service/X2D1NoRefTaskServer54/Service/HistoryTaskService.cs

@@ -1,426 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using XdCxRhDW.Api;
-using XdCxRhDW.Dto;
-
-namespace X2D1NoRefTaskServer54.Service
-{
-    //业务逻辑处理类
-    public class HistoryTaskService
-    {
-        private readonly string baseUrl;
-        CancellationTokenSource cts;
-
-        string DetectDir;
-        string CapDir;
-        string DdcDir;
-        string PosResDir;
-        int MainSatCode, Adja1SatCode;
-        double[] MainSatXYZ, Adja1SatXYZ;
-        int PosDtoFactor;
-        double DtoErrus;
-        double EphErrm;
-
-        public HistoryTaskService()
-        {
-            var posPlatformAddr = ConfigurationManager.AppSettings["PosPlatformAddr"].Trim();//like http://127.0.0.1:8091 or http://127.0.0.1:8091/
-            if (posPlatformAddr.EndsWith("/"))
-                this.baseUrl = posPlatformAddr + "api/";
-            else
-                this.baseUrl = posPlatformAddr + "/api/";
-
-            DetectDir = ConfigurationManager.AppSettings["DetectDir"].Trim();
-            CapDir = ConfigurationManager.AppSettings["CapDir"].Trim();
-            DdcDir = ConfigurationManager.AppSettings["DdcDir"].Trim();
-            PosResDir = ConfigurationManager.AppSettings["PosResDir"].Trim();
-            var PosDtoFactorstr = ConfigurationManager.AppSettings["PosDtoFactor"].Trim();
-            int.TryParse(PosDtoFactorstr, out PosDtoFactor);
-            if (PosDtoFactor == 0) PosDtoFactor = 1;
-            var DtoErrusstr = ConfigurationManager.AppSettings["DtoErrus"].Trim();
-            double.TryParse(DtoErrusstr, out DtoErrus);
-            var EphErrmstr = ConfigurationManager.AppSettings["EphErrm"].Trim();
-            double.TryParse(EphErrmstr, out EphErrm);
-        }
-        public void StartAsync(X2D1NoRefTaskHandleDto dto)
-        {
-            cts = new CancellationTokenSource();
-            Task.Run(async () =>
-            {
-                LogHelper.Info($"【任务{dto.ID}】开始执行...");
-                //点击定位平台右上角查看接口可以在浏览器中查看平台提供的所有接口详细信息
-                while (!cts.IsCancellationRequested)
-                {
-                    try
-                    {
-                        #region 第1步,读取需要的配置信息
-                        if (!Directory.Exists(DetectDir))
-                        {
-                            StopTask(dto.ID, EnumTaskStopType.Error, $"检测结果目录[{DetectDir}]不存在");
-                            return;
-                        }
-                        if (!Directory.Exists(CapDir))
-                        {
-                            StopTask(dto.ID, EnumTaskStopType.Error, $"AD采集目录[{CapDir}]不存在");
-                            return;
-                        }
-                        Directory.CreateDirectory(DdcDir);
-                        Directory.CreateDirectory(PosResDir);
-                        LogHelper.Info($"【任务{dto.ID}】检测结果目录[{DetectDir}]");
-                        LogHelper.Info($"【任务{dto.ID}】AD采集目录[{CapDir}]");
-                        LogHelper.Info($"【任务{dto.ID}】DDC输出目录[{DdcDir}]");
-                        try
-                        {
-                            var mainInfo = ConfigurationManager.AppSettings["MainSatInfo"].Replace(",", ",").Trim();
-                            var adja1Info = ConfigurationManager.AppSettings["Adja1SatInfo"].Replace(",", ",").Trim();
-                            var arr1 = mainInfo.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
-                            var arr2 = adja1Info.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
-                            MainSatCode = Convert.ToInt32(arr1[0]);
-                            Adja1SatCode = Convert.ToInt32(arr2[0]);
-                            MainSatXYZ = new double[3] { Convert.ToDouble(arr1[1]), Convert.ToDouble(arr1[2]), Convert.ToDouble(arr1[3]) };
-                            Adja1SatXYZ = new double[3] { Convert.ToDouble(arr2[1]), Convert.ToDouble(arr2[2]), Convert.ToDouble(arr2[3]) };
-                        }
-                        catch
-                        {
-                            StopTask(dto.ID, EnumTaskStopType.Error, $"任务处理服务配置文件卫星信息解析出错");
-                            return;
-                        }
-                        #endregion
-
-                        #region 第2步,扫描检测结果目录
-                        var groupFiles = Directory.EnumerateFiles(DetectDir, "*.dat", SearchOption.TopDirectoryOnly).Select(p => StringToCheckResFile(p))
-                             .GroupBy(m => Convert.ToInt64(m.DayTime.ToString("yyyyMMdd") + m.FlagNo)).OrderBy(m => m.Key);
-                        if (!groupFiles.Any())
-                        {
-                            LogHelper.Info($"【任务{dto.ID}】等待扫描文件...");
-                            await Task.Delay(10000);
-                        }
-                        foreach (var groupFile in groupFiles)//每一组文件代表同一个时刻的
-                        {
-                            if (cts.IsCancellationRequested) break;
-                            List<SlotsInfo> listSlotsInfo = new List<SlotsInfo>();//多个频点的时隙结果
-                            foreach (var item in groupFile)
-                            {
-                                var slotsInfo = SlotHelper.GetFileSlots(item.File);//某个频点的所有时隙
-                                if (!Debugger.IsAttached)
-                                    File.Delete(item.File);//检测检测结果文件
-                                if (slotsInfo.Slots.Any())
-                                    listSlotsInfo.Add(slotsInfo);
-                                LogHelper.Warning($"【任务{dto.ID}】{slotsInfo.AdTime:yyyyMMddHHmmss}时刻频点{slotsInfo.FreqDownMHz}共{slotsInfo.Slots.Count}个突发");
-                            }
-                            if (!listSlotsInfo.Any()) continue;
-                            var adFiles = Directory.EnumerateFiles(CapDir, "*.dat", SearchOption.TopDirectoryOnly).Select(p => StringToAdFile(p))
-                                .Where(p => p.AdTime == listSlotsInfo.First().AdTime);
-                            if (!adFiles.Any())
-                            {
-                                LogHelper.Warning($"【任务{dto.ID}】{listSlotsInfo.First().AdTime:yyyyMMddHHmmss}时刻找不到原始AD文件,跳过此组文件");
-                                continue;
-                            }
-                            var first = listSlotsInfo.First();
-                            var sigs = listSlotsInfo.Select(p => new DDCSig() { FreqDownHz = (int)(p.FreqDownMHz * 1e6), Mult = (int)first.Multi, Slots = p });
-                            List<DDCFile> chDDCFiles = new List<DDCFile>();//同一个时刻多个频点多个通道的DDC数据
-                            LogHelper.Info($"【任务{dto.ID}】{listSlotsInfo.First().AdTime:yyyyMMddHHmmss}时刻DDC处理开始...");
-                            Parallel.ForEach(adFiles, adFile =>
-                            {
-
-                                //227=变频器频点255-(140-112))
-                                var ddcRes = DDCHelper.DDC(adFile.File, adFile.AdTime, adFile.ChNo, (long)(first.FsampleM * 1e6), (long)(227 * 1e6), DdcDir, sigs);
-                                chDDCFiles.AddRange(StringToDDCFile(ddcRes));
-                                if (!Debugger.IsAttached)
-                                    File.Delete(adFile.File);//删除AD文件
-                            });
-                            LogHelper.Info($"【任务{dto.ID}】{listSlotsInfo.First().AdTime:yyyyMMddHHmmss}时刻DDC处理完成");
-                            if (!chDDCFiles.Any())
-                            {
-                                LogHelper.Error($"【任务{dto.ID}】{listSlotsInfo.First().AdTime:yyyyMMddHHmmss}时刻DDC处理无结果");
-                                continue;
-                            }
-                            var groupDDCFiles = chDDCFiles.GroupBy(p => p.FreqDownMHz);
-                            foreach (var group in groupDDCFiles)
-                            {
-                                //group:同一个时刻同一个频点的多个通道数据
-                                var capTime = group.First().AdTime;
-                                var ch0File = group.Where(p => p.ChNo == 0).FirstOrDefault();
-                                var ch1File = group.Where(p => p.ChNo == 1).FirstOrDefault();
-                                var ch2File = group.Where(p => p.ChNo == 2).FirstOrDefault();
-                                if (ch0File == null)
-                                {
-                                    LogHelper.Warning($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻未找到主星信号ch0文件,跳过此组数据");
-                                    continue;
-                                }
-                                if (ch1File == null)
-                                {
-                                    LogHelper.Warning($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻未找到邻星信号ch1文件,跳过此组数据");
-                                    continue;
-                                }
-                                if (ch2File == null)
-                                {
-                                    LogHelper.Warning($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻未找到超短信号ch2文件,跳过此组数据");
-                                    continue;
-                                }
-                                if (cts.IsCancellationRequested) break;
-                                string mainFile = await HttpHelper.UploadFileAsync(ch0File.File, baseUrl, token: cts.Token);//主星文件
-                                string adja1File = await HttpHelper.UploadFileAsync(ch1File.File, baseUrl, token: cts.Token);//邻1星文件
-                                string cdbFile = await HttpHelper.UploadFileAsync(ch2File.File, baseUrl, token: cts.Token);//地面信号文件
-
-
-                                var sig = sigs.FirstOrDefault(p => p.FreqDownHz == (int)(group.Key * 1e6));
-                                var cgDto = new CpuCgMultiDto()
-                                {
-                                    dtCenter = 0,
-                                    dtRange = 40000,
-                                    file1 = mainFile,
-                                    file2 = adja1File,
-                                    samplingRate = ch0File.Fs,
-                                    smpPositions = sig.Slots.Slots.Select(p => new SmpPosition() { TimeSeconds = p.TimeSeconds, smpStart = p.StartPoint, smpCount = p.Len }).ToList(),
-                                    snrThreshold = 15,
-                                };
-                                LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻主星邻星CPU参估开始...");
-                                var result1 = await HttpHelper.PostRequestAsync<List<CpuCgResDto>>(baseUrl + "DetectCg/CpuCgMultiCalc", cgDto, token: cts.Token);
-                                if (result1.code != 200)
-                                {
-                                    LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻主星邻星CPU参估出错.{result1.msg}");
-                                    continue;
-                                }
-                                LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻主星邻星CPU参估完成");
-                                cgDto = new CpuCgMultiDto()
-                                {
-                                    dtCenter = 260000,
-                                    dtRange = 50000,
-                                    file1 = mainFile,
-                                    file2 = cdbFile,
-                                    samplingRate = ch0File.Fs,
-                                    smpPositions = sig.Slots.Slots.Select(p => new SmpPosition() { TimeSeconds = p.TimeSeconds, smpStart = p.StartPoint, smpCount = p.Len }).ToList(),
-                                    snrThreshold = 15,
-                                };
-                                LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻主星超短CPU参估开始...");
-                                var result2 = await HttpHelper.PostRequestAsync<List<CpuCgResDto>>(baseUrl + "DetectCg/CpuCgMultiCalc", cgDto, token: cts.Token);
-                                if (result2.code != 200)
-                                {
-                                    LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻主星超短CPU参估出错.{result2.msg}");
-                                    continue;
-                                }
-
-                                //删除DDC文件
-                                File.Delete(ch0File.File);
-                                File.Delete(ch1File.File);
-                                File.Delete(ch2File.File);
-                                LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻主星超短CPU参估完成");
-                                var data1 = result1.data;
-                                var data2 = result2.data;
-                                if (data1.Count != data2.Count || data1.Count != cgDto.smpPositions.Count)
-                                {
-                                    LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻参估结果个数和检测结果个数不匹配");
-                                    continue;
-                                }
-                                for (int i = 0; i < data1.Count; i++)
-                                {
-                                    try
-                                    {
-                                        if (cts.IsCancellationRequested) break;
-                                        X2D1NoParPosDto x21d = new X2D1NoParPosDto()
-                                        {
-                                            TaskID = dto.ID,
-                                            //SigTime = capTime.AddSeconds(data1[i].Smpstart / (double)ch0File.Fs),
-                                            SigTime = capTime.AddSeconds(data1[i].TimeSeconds),
-                                            MainCode = MainSatCode,
-                                            AdjaCode = Adja1SatCode,
-                                            MainX = MainSatXYZ[0],
-                                            MainY = MainSatXYZ[1],
-                                            MainZ = MainSatXYZ[2],
-                                            AdjaX = Adja1SatXYZ[0],
-                                            AdjaY = Adja1SatXYZ[1],
-                                            AdjaZ = Adja1SatXYZ[2],
-                                            SxDto = PosDtoFactor * data1[i].Dt,
-                                            SxDfo = data1[i].Df,
-                                            SxSnr = data1[i].Snr,
-                                            XdDto = PosDtoFactor * data2[i].Dt,
-                                            XdDfo = data2[i].Df,
-                                            XdSnr = data2[i].Snr,
-                                            SatTxLon = dto.CapLon,
-                                            SatTxLat = dto.CapLat,
-                                            CdbTxLon = dto.CdbLon,
-                                            CdbTxLat = dto.CdbLat,
-                                            FreqDown = ch0File.FreqDownMHz * 1e6,
-                                            FreqUp = ch0File.FreqDownMHz * 1e6,
-                                            CheckRes = new CheckResDto()
-                                            {
-                                                FileName = Path.GetFileName(ch0File.File),
-                                                SmpStart = sig.Slots.Slots[i].StartPoint,
-                                                SmpCount = sig.Slots.Slots[i].Len,
-                                                PosCheckType = EnumPosCheckTypeDto.DAMA,
-                                            }
-                                        };
-                                        var result = await HttpHelper.PostRequestAsync<PosResDto>(baseUrl + "Pos/PosX2D1NoParAsync", x21d);
-                                        if (result.code != 200)
-                                        {
-                                            LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻时隙位置{data1[i].Smpstart}定位异常.{result.msg}");
-                                        }
-                                        else
-                                        {
-                                            var posRes = result.data;
-                                            double posLon = posRes.PosLon;
-                                            double posLat = posRes.PosLat;
-                                            if (x21d.SxSnr == 0 || x21d.XdSnr == 0)
-                                            {
-                                                posLon = 0;
-                                                posLat = 0;
-                                            }
-                                            double longAxis = 0, shortAxis = 0, dipAngle = 0;
-                                            if (posLon != 0 &&posLat != 0 &&posLon != 999&& posLat != 999)
-                                            {
-                                                double[] cdbPos = new double[] { dto.CdbLon, dto.CdbLat, 0 };
-                                                double[] refGeod = new double[] { 0, 0, 0 };
-                                                double[] errorEllipse = GdopHelper.ErrorEllipse2X1D(posLon, posLat, MainSatXYZ, Adja1SatXYZ, cdbPos, refGeod, DtoErrus, EphErrm);
-                                                if (errorEllipse.Length == 3)
-                                                {
-                                                    longAxis = errorEllipse[0];
-                                                    shortAxis = errorEllipse[1];
-                                                    dipAngle = errorEllipse[2];
-                                                }
-                                            }
-                                            StringBuilder sb = new StringBuilder();
-                                            sb.Append($"{x21d.SigTime:yyyy}\t");
-                                            sb.Append($"{x21d.SigTime:MM}\t");
-                                            sb.Append($"{x21d.SigTime:dd}\t");
-                                            sb.Append($"{x21d.SigTime:HH}\t");
-                                            sb.Append($"{x21d.SigTime:mm}\t");
-                                            sb.Append($"{x21d.SigTime:ss}\t");
-                                            sb.Append($"{x21d.SigTime:fff}\t");
-                                            sb.Append($"{x21d.CheckRes.SmpCount * 1000 / ch0File.Fs:D4}\t");//信号持续时间ms
-                                            sb.Append($"{Convert.ToInt64(group.First().FreqDownMHz * 1e6):D12}\t");//下行频点
-                                            sb.Append($"{Convert.ToInt64((group.First().FreqDownMHz + 44) * 1e6):D12}\t");//上行频点
-                                            sb.Append($"{4}\t");//信号样式(暂定有这些1:CPM,2:BPSK,4:QPSK),
-                                            sb.Append($"{0:D4}\t");//目标序号
-                                            sb.Append($"res\t");
-                                            sb.Append($"{Convert.ToInt64(posLon * 1e6):D10}\t");
-                                            sb.Append($"{Convert.ToInt64(posLat * 1e6):D10}\t");
-                                            sb.Append($"{Convert.ToInt64(0 * 1e3):D8}\t");//定位误差km
-                                            sb.Append($"{Convert.ToInt64(x21d.SxDto * 1e2):D10}\t");
-                                            sb.Append($"{Convert.ToInt64(x21d.SxDfo * 1e2):D10}\t");
-                                            sb.Append($"{Convert.ToInt64(x21d.SxSnr * 1e2):D6}\t");
-                                            sb.Append($"{Convert.ToInt64(x21d.XdDto * 1e2):D10}\t");
-                                            sb.Append($"{Convert.ToInt64(x21d.XdDfo * 1e2):D10}\t");
-                                            sb.Append($"{Convert.ToInt64(x21d.XdSnr * 1e2):D6}\t");
-                                            sb.Append($"{Convert.ToInt64(0 * 1e2):D10}\t");
-                                            sb.Append($"{Convert.ToInt64(0 * 1e2):D10}\t");
-                                            sb.Append($"{Convert.ToInt64(0 * 1e2):D6}\t");
-                                            sb.Append($"{longAxis:D8}\t");//长轴
-                                            sb.Append($"{shortAxis:D8}\t");//短轴
-                                            sb.Append($"{dipAngle:D7}\t");//倾角
-                                            sb.Append($"{data1.Count:D2}\t");//时隙属性
-                                            sb.Append($"{1}\t");//所属卫星
-                                            sb.Append($"{950:D3}\t");//置信度
-                                            sb.Append($"{3}");//定位体制(星地=3)
-                                            sb.Append($"QPSK");//调制类型
-                                            sb.Append($"1.33\r\n");//符号速率kbps
-                                            string resFile = Path.Combine(PosResDir, $"定位结果_{posRes.SigTime:yyyyMMdd}.txt");
-                                            File.AppendAllText(resFile, sb.ToString());
-                                        }
-                                    }
-                                    catch (Exception ex)
-                                    {
-                                        LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻时隙位置{data1[i].Smpstart}定位异常", ex);
-                                    }
-                                }
-                                LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻定位完成");
-                            }
-
-                        }
-                        #endregion
-                    }
-                    catch (Exception ex)
-                    {
-                        if (!cts.IsCancellationRequested)
-                            LogHelper.Error("任务执行出错", ex);
-                    }
-                }
-            }, cts.Token);
-        }
-        public void Stop()
-        {
-            cts?.Cancel();
-        }
-        private void StopTask(int taskID, EnumTaskStopType type, string stopReason)
-        {
-            Thread.Sleep(2000);
-            if (type == EnumTaskStopType.Properly)
-            {
-                LogHelper.Info($"【任务{taskID}】{stopReason}");
-            }
-            else
-            {
-                LogHelper.Error($"【任务{taskID}】{stopReason}");
-            }
-            TaskStopHandleDto stopDto = new TaskStopHandleDto() { ID = taskID, StopType = type, StopReason = stopReason };
-            var stopResp = HttpHelper.PostRequestAsync(baseUrl + "Task/StopTask", stopDto).Result;
-            if (stopResp.code != 200)
-            {
-                LogHelper.Error($"【任务{taskID}】停止异常.{stopResp.msg}");
-            }
-        }
-
-        private CheckResFile StringToCheckResFile(string file)
-        {
-            //YUFO_252.050MHz_20240409_1398.dat
-            string fileName = Path.GetFileNameWithoutExtension(file).ToUpper();
-            var arr = fileName.Split(new string[] { "_", "MHZ" }, StringSplitOptions.RemoveEmptyEntries);
-            var dayTime = DateTime.ParseExact(arr[2], "yyyyMMdd", null);
-            CheckResFile res = new CheckResFile()
-            {
-                DayTime = dayTime,
-                File = file,
-                FreqDownMHz = Convert.ToDouble(arr[1]),
-                FlagNo = Convert.ToInt64(arr[3]),
-            };
-            return res;
-        }
-        private AdFile StringToAdFile(string file)
-        {
-            //20240409094240_ADC_ch02.dat
-            var name = Path.GetFileNameWithoutExtension(file).ToUpper();
-            var arr = name.Split(new string[] { "_", "CH" }, StringSplitOptions.RemoveEmptyEntries);
-            var time = DateTime.ParseExact(arr[0], "yyyyMMddHHmmss", null);
-            AdFile adFile = new AdFile()
-            {
-                File = file,
-                AdTime = time,
-                ChNo = Convert.ToInt32(arr[2]),
-            };
-            return adFile;
-        }
-        public DDCFile StringToDDCFile(string file)
-        {
-            //20240409094240_252.025_C109375_ch0.dat
-            var name = Path.GetFileNameWithoutExtension(file).ToUpper();
-            var arr = name.Split(new string[] { "_", "MHz", "C", "H" }, StringSplitOptions.RemoveEmptyEntries);
-            var time = DateTime.ParseExact(arr[0], "yyyyMMddHHmmss", null);
-            double freqDown = Convert.ToDouble(arr[1]);
-            int fs = Convert.ToInt32(arr[2]);
-            int chNo = Convert.ToInt32(arr[3]);
-            return new DDCFile()
-            {
-                AdTime = time,
-                ChNo = chNo,
-                File = file,
-                FreqDownMHz = freqDown,
-                Fs = fs
-            };
-        }
-        public List<DDCFile> StringToDDCFile(List<string> files)
-        {
-            List<DDCFile> list = new List<DDCFile>();
-            foreach (var item in files)
-            {
-                list.Add(StringToDDCFile(item));
-            }
-            return list;
-        }
-    }
-}

+ 698 - 0
Service/X2D1NoRefTaskServer54/Service/TaskService.cs

@@ -0,0 +1,698 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using XdCxRhDW.Api;
+using XdCxRhDW.Dto;
+
+namespace X2D1NoRefTaskServer54.Service
+{
+    //业务逻辑处理类
+    public class TaskService
+    {
+        private readonly string baseUrl;
+        CancellationTokenSource cts;
+
+        string DetectDir;
+        string CapDir;
+        string DdcDir;
+        string PosResDir;
+        int MainSatCode, Adja1SatCode;
+        double[] MainSatXYZ, Adja1SatXYZ;
+        int PosDtoFactor;
+        bool useGpuCg = false;
+        double DtoErrus;
+        double EphErrm;
+
+        public TaskService()
+        {
+            Directory.CreateDirectory("tmp");
+            var posPlatformAddr = ConfigurationManager.AppSettings["PosPlatformAddr"].Trim();//like http://127.0.0.1:8091 or http://127.0.0.1:8091/
+            if (posPlatformAddr.EndsWith("/"))
+                this.baseUrl = posPlatformAddr + "api/";
+            else
+                this.baseUrl = posPlatformAddr + "/api/";
+
+            DetectDir = ConfigurationManager.AppSettings["DetectDir"].Trim();
+            CapDir = ConfigurationManager.AppSettings["CapDir"].Trim();
+            DdcDir = ConfigurationManager.AppSettings["DdcDir"].Trim();
+            PosResDir = ConfigurationManager.AppSettings["PosResDir"].Trim();
+            var PosDtoFactorstr = ConfigurationManager.AppSettings["PosDtoFactor"].Trim();
+            int.TryParse(PosDtoFactorstr, out PosDtoFactor);
+            if (PosDtoFactor == 0) PosDtoFactor = 1;
+            var DtoErrusstr = ConfigurationManager.AppSettings["DtoErrus"].Trim();
+            double.TryParse(DtoErrusstr, out DtoErrus);
+            var EphErrmstr = ConfigurationManager.AppSettings["EphErrm"].Trim();
+            double.TryParse(EphErrmstr, out EphErrm);
+
+            string useGpuStr = ConfigurationManager.AppSettings["UseGpuCg"];
+            if (useGpuStr != null && useGpuStr.Trim() == "1")
+                useGpuCg = true;
+        }
+        public void StartAsync(X2D1NoRefTaskHandleDto dto)
+        {
+            cts = new CancellationTokenSource();
+            Task.Run(async () =>
+            {
+                LogHelper.Info($"【任务{dto.ID}】开始执行...");
+                LogHelper.Info($"【任务{dto.ID}】检测结果目录[{DetectDir}]");
+                LogHelper.Info($"【任务{dto.ID}】AD采集目录[{CapDir}]");
+                LogHelper.Info($"【任务{dto.ID}】DDC输出目录[{DdcDir}]");
+                //点击定位平台右上角查看接口可以在浏览器中查看平台提供的所有接口详细信息
+                while (!cts.IsCancellationRequested)
+                {
+                    try
+                    {
+                        #region 第1步,读取需要的配置信息
+                        if (!Directory.Exists(DetectDir))
+                        {
+                            await StopTask(dto.ID, EnumTaskStopType.Error, $"检测结果目录[{DetectDir}]不存在");
+                            return;
+                        }
+                        if (!Directory.Exists(CapDir))
+                        {
+                            await StopTask(dto.ID, EnumTaskStopType.Error, $"AD采集目录[{CapDir}]不存在");
+                            return;
+                        }
+                        Directory.CreateDirectory(DdcDir);
+                        Directory.CreateDirectory(PosResDir);
+
+                        try
+                        {
+                            var mainInfo = ConfigurationManager.AppSettings["MainSatInfo"].Replace(",", ",").Trim();
+                            var adja1Info = ConfigurationManager.AppSettings["Adja1SatInfo"].Replace(",", ",").Trim();
+                            var arr1 = mainInfo.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
+                            var arr2 = adja1Info.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
+                            MainSatCode = Convert.ToInt32(arr1[0]);
+                            Adja1SatCode = Convert.ToInt32(arr2[0]);
+                            MainSatXYZ = new double[3] { Convert.ToDouble(arr1[1]), Convert.ToDouble(arr1[2]), Convert.ToDouble(arr1[3]) };
+                            Adja1SatXYZ = new double[3] { Convert.ToDouble(arr2[1]), Convert.ToDouble(arr2[2]), Convert.ToDouble(arr2[3]) };
+                        }
+                        catch
+                        {
+                            await StopTask(dto.ID, EnumTaskStopType.Error, $"任务处理服务配置文件卫星信息解析出错");
+                            return;
+                        }
+                        #endregion
+
+                        #region 第2步,扫描检测结果目录
+                        var groupFiles = Directory.EnumerateFiles(DetectDir, "*.dat", SearchOption.TopDirectoryOnly).Select(p => StringToCheckResFile(p))
+                             .GroupBy(m => Convert.ToInt64(m.DayTime.ToString("yyyyMMdd") + m.FlagNo)).OrderBy(m => m.Key);
+                        if (!groupFiles.Any())
+                        {
+                            LogHelper.Info($"【任务{dto.ID}】等待扫描文件...");
+                            await Task.Delay(10000);
+                        }
+                        foreach (var groupFile in groupFiles)//每一组文件代表同一个时刻的
+                        {
+                            if (cts.IsCancellationRequested) break;
+                            List<SlotsInfo> listSlotsInfo = new List<SlotsInfo>();//多个频点的时隙结果
+                            foreach (var item in groupFile)
+                            {
+                                var slotsInfo = SlotHelper.GetFileSlots(item.File);//某个频点的所有时隙
+                                if (!Debugger.IsAttached)
+                                    File.Delete(item.File);//检测检测结果文件
+                                if (slotsInfo.Slots.Any())
+                                    listSlotsInfo.Add(slotsInfo);
+                            }
+                            if (!listSlotsInfo.Any()) continue;
+                            var adFiles = Directory.EnumerateFiles(CapDir, "*.dat", SearchOption.TopDirectoryOnly).Select(p => StringToAdFile(p))
+                                .Where(p => p.AdTime == listSlotsInfo.First().AdTime);
+                            if (!adFiles.Any())
+                            {
+                                LogHelper.Warning($"【任务{dto.ID}】{listSlotsInfo.First().AdTime:yyyyMMddHHmmss}时刻找不到原始AD文件,跳过此组文件");
+                                continue;
+                            }
+                            var first = listSlotsInfo.First();
+                            var sigs = listSlotsInfo.Select(p => new DDCSig() { FreqDownHz = (int)(p.FreqDownMHz * 1e6), Mult = (int)first.Multi, Slots = p });
+                            List<DDCFile> chDDCFiles = new List<DDCFile>();//同一个时刻多个频点多个通道的DDC数据
+                            LogHelper.Info($"【任务{dto.ID}】{listSlotsInfo.First().AdTime:yyyyMMddHHmmss}时刻DDC处理开始,共{sigs.Count()}个频点...");
+                            Stopwatch sw = new Stopwatch();
+                            sw.Start();
+                            var listTask = new List<Task>();
+                            foreach (var adFile in adFiles)
+                            {
+                                var task = Task.Run(() =>
+                                {
+                                    var ddcRes = DDCHelper.DDC(adFile.File, adFile.AdTime, adFile.ChNo, (long)(first.FsampleM * 1e6), (long)(227 * 1e6), DdcDir, sigs);
+                                    chDDCFiles.AddRange(StringToDDCFile(ddcRes));
+                                    if (!Debugger.IsAttached)
+                                        File.Delete(adFile.File);//删除AD文件
+                                }, cts.Token);
+                                listTask.Add(task);
+                            }
+                            await Task.WhenAll(listTask);
+                            sw.Stop();
+                            LogHelper.Info($"【任务{dto.ID}】{listSlotsInfo.First().AdTime:yyyyMMddHHmmss}时刻DDC处理完成,耗时{sw.ElapsedMilliseconds}ms");
+                            if (!chDDCFiles.Any())
+                            {
+                                LogHelper.Error($"【任务{dto.ID}】{listSlotsInfo.First().AdTime:yyyyMMddHHmmss}时刻DDC处理无结果");
+                                continue;
+                            }
+                            var groupDDCFiles = chDDCFiles.GroupBy(p => p.FreqDownMHz);
+                            listTask.Clear();
+                            foreach (var group in groupDDCFiles)
+                            {
+                                //group:同一个时刻同一个频点的多个通道数据
+                                var task = Task.Run(async () =>
+                                {
+                                    var capTime = group.First().AdTime;
+                                    var ch0File = group.Where(p => p.ChNo == 0).FirstOrDefault();
+                                    var ch1File = group.Where(p => p.ChNo == 1).FirstOrDefault();
+                                    var ch2File = group.Where(p => p.ChNo == 2).FirstOrDefault();
+                                    if (ch0File == null)
+                                    {
+                                        LogHelper.Warning($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-未找到主星信号ch0文件,跳过此组数据");
+                                        return;
+                                    }
+                                    if (ch1File == null)
+                                    {
+                                        LogHelper.Warning($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-未找到邻星信号ch1文件,跳过此组数据");
+                                        return;
+                                    }
+                                    if (ch2File == null)
+                                    {
+                                        LogHelper.Warning($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-未找到超短信号ch2文件,跳过此组数据");
+                                        return;
+                                    }
+                                    var sig = sigs.FirstOrDefault(p => p.FreqDownHz == (int)(group.Key * 1e6));
+
+                                    if (cts.IsCancellationRequested) return;
+                                    if (useGpuCg)
+                                    {
+                                        LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-GPU参估开始,共{sig.Slots.Slots.Count}个突发...");
+                                        sw.Start();
+                                        List<GpuCgResponseDto> data1 = new List<GpuCgResponseDto>();
+                                        List<GpuCgResponseDto> data2 = new List<GpuCgResponseDto>();
+                                        foreach (var item in sig.Slots.Slots)
+                                        {
+                                            string f1 = $"tmp\\{Path.GetFileNameWithoutExtension(ch0File.File)}_{item.StartPoint}_{item.Len}.dat";
+                                            string f2 = $"tmp\\{Path.GetFileNameWithoutExtension(ch1File.File)}_{item.StartPoint}_{item.Len}.dat";
+                                            string f3 = $"tmp\\{Path.GetFileNameWithoutExtension(ch2File.File)}_{item.StartPoint}_{item.Len}.dat";
+                                            using (FileStream fs = new FileStream(ch0File.File, FileMode.Open))
+                                            {
+                                                byte[] data = new byte[item.Len * 4];
+                                                fs.Position = item.StartPoint * 4;
+                                                fs.Read(data, 0, data.Length);
+                                                File.WriteAllBytes(f1, data);
+                                            }
+                                            using (FileStream fs = new FileStream(ch1File.File, FileMode.Open))
+                                            {
+                                                byte[] data = new byte[item.Len * 4];
+                                                fs.Position = item.StartPoint * 4;
+                                                fs.Read(data, 0, data.Length);
+                                                File.WriteAllBytes(f2, data);
+                                            }
+                                            using (FileStream fs = new FileStream(ch2File.File, FileMode.Open))
+                                            {
+                                                byte[] data = new byte[item.Len * 4];
+                                                fs.Position = item.StartPoint * 4;
+                                                fs.Read(data, 0, data.Length);
+                                                File.WriteAllBytes(f3, data);
+                                            }
+                                            string mainSlotFile = await HttpHelper.UploadFileAsync(f1, baseUrl, token: cts.Token);//主星文件
+                                            string adja1SlotFile = await HttpHelper.UploadFileAsync(f2, baseUrl, token: cts.Token);//邻1星文件
+                                            string adja2SlotFile = await HttpHelper.UploadFileAsync(f3, baseUrl, token: cts.Token);//邻2星文件
+                                            File.Delete(f1);
+                                            File.Delete(f2);
+                                            File.Delete(f3);
+                                            var gpudto = new GpuCgRequestDto()
+                                            {
+                                                dtCenter = 0,
+                                                dtRange = 40000,
+                                                file1 = mainSlotFile,
+                                                file2 = adja1SlotFile,
+                                                samplingRate = ch0File.Fs,
+                                                smpCount = 0,
+                                                snrThreshold = 15
+                                            };
+                                            var result1 = await HttpHelper.PostRequestAsync<List<GpuCgResponseDto>>(baseUrl + "DetectCg/GpuCgCalc", gpudto, token: cts.Token);
+                                            if (result1.code != 200)
+                                            {
+                                                LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-主星邻1星GPU参估出错.{result1.msg}.突发位置{item.StartPoint}-{item.Len}");
+                                                continue;
+                                            }
+                                            var data1First = result1.data.First();
+                                            data1First.TimeSeconds = item.TimeSeconds;
+                                            data1.Add(data1First);
+                                            gpudto = new GpuCgRequestDto()
+                                            {
+                                                dtCenter = 0,
+                                                dtRange = 40000,
+                                                file1 = mainSlotFile,
+                                                file2 = adja2SlotFile,
+                                                samplingRate = ch0File.Fs,
+                                                smpCount = 0,
+                                                snrThreshold = 15
+                                            };
+                                            var result2 = await HttpHelper.PostRequestAsync<List<GpuCgResponseDto>>(baseUrl + "DetectCg/GpuCgCalc", gpudto, token: cts.Token);
+                                            if (result2.code != 200)
+                                            {
+                                                LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-主星邻2星GPU参估出错.{result2.msg}.突发位置{item.StartPoint}-{item.Len}");
+                                                continue;
+                                            }
+                                            var data2First = result2.data.First();
+                                            data2First.TimeSeconds = item.TimeSeconds;
+                                            data2.Add(data2First);
+                                        }
+                                        sw.Stop();
+                                        LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-GPU参估完成,耗时{sw.ElapsedMilliseconds}ms");
+
+                                        string mainFile = await HttpHelper.UploadFileAsync(ch0File.File, baseUrl, token: cts.Token);//主星文件
+                                        var smpPositions = sig.Slots.Slots.Select(p => new SmpPosition() { TimeSeconds = p.TimeSeconds, smpStart = p.StartPoint, smpCount = p.Len }).ToList();
+                                        var signaldto = new SignalProcDto()
+                                        {
+                                            File = mainFile,
+                                            Fs = ch0File.Fs,
+                                            Smps = smpPositions,
+                                        };
+                                        var signalResult = await HttpHelper.PostRequestAsync<List<SignalProcResDto>>(baseUrl + "DetectCg/SignalProc", signaldto);
+                                        if (signalResult.code != 200)
+                                        {
+                                            LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-主星信号识别出错.{signalResult.msg}");
+                                            return;
+
+                                        }
+                                        LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-GPU参估完成,耗时{sw.ElapsedMilliseconds}ms");
+                                        if (data1.Count != data2.Count || data1.Count != sig.Slots.Slots.Count)
+                                        {
+                                            LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-参估结果个数和检测结果个数不匹配");
+                                            return;
+                                        }
+
+                                        if (data1.Count != data2.Count || data1.Count != signalResult.data.Count)
+                                        {
+                                            LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-信号识别结果个数和检测结果个数不匹配");
+                                            return;
+                                        }
+                                        for (int i = 0; i < data1.Count; i++)
+                                        {
+                                            try
+                                            {
+                                                if (cts.IsCancellationRequested) break;
+                                                X2D1NoParPosDto x21d = new X2D1NoParPosDto()
+                                                {
+                                                    TaskID = dto.ID,
+                                                    //SigTime = capTime.AddSeconds(data1[i].Smpstart / (double)ch0File.Fs),
+                                                    SigTime = capTime.AddSeconds(data1[i].TimeSeconds),
+                                                    MainCode = MainSatCode,
+                                                    AdjaCode = Adja1SatCode,
+                                                    MainX = MainSatXYZ[0],
+                                                    MainY = MainSatXYZ[1],
+                                                    MainZ = MainSatXYZ[2],
+                                                    AdjaX = Adja1SatXYZ[0],
+                                                    AdjaY = Adja1SatXYZ[1],
+                                                    AdjaZ = Adja1SatXYZ[2],
+                                                    SxDto = PosDtoFactor * data1[i].Dt,
+                                                    SxDfo = data1[i].Df,
+                                                    SxSnr = data1[i].Snr,
+                                                    XdDto = PosDtoFactor * data2[i].Dt,
+                                                    XdDfo = data2[i].Df,
+                                                    XdSnr = data2[i].Snr,
+                                                    SatTxLon = dto.CapLon,
+                                                    SatTxLat = dto.CapLat,
+                                                    CdbTxLon = dto.CdbLon,
+                                                    CdbTxLat = dto.CdbLat,
+                                                    FreqDown = ch0File.FreqDownMHz * 1e6,
+                                                    FreqUp = ch0File.FreqDownMHz * 1e6,
+                                                    CheckRes = new CheckResDto()
+                                                    {
+                                                        FileName = Path.GetFileName(ch0File.File),
+                                                        SmpStart = sig.Slots.Slots[i].StartPoint,
+                                                        SmpCount = sig.Slots.Slots[i].Len,
+                                                        PosCheckType = EnumPosCheckTypeDto.DAMA,
+                                                    }
+                                                };
+                                                var result = await HttpHelper.PostRequestAsync<PosResDto>(baseUrl + "Pos/PosX2D1NoParAsync", x21d);
+                                                if (result.code != 200)
+                                                {
+                                                    LogHelper.Error($"【任务{dto.ID}】-信号{group.Key}MHz-{capTime:yyyyMMddHHmmss}时刻第{i + 1}个突发定位异常.{result.msg}");
+                                                }
+                                                else
+                                                {
+                                                    var posRes = result.data;
+                                                    double posLon = posRes.PosLon;
+                                                    double posLat = posRes.PosLat;
+                                                    if (x21d.SxSnr == 0 || x21d.XdSnr == 0)
+                                                    {
+                                                        posLon = 0;
+                                                        posLat = 0;
+                                                    }
+                                                    double longAxis = 0, shortAxis = 0, dipAngle = 0;
+                                                    if (posLon != 0 && posLat != 0 && posLon != 999 && posLat != 999)
+                                                    {
+                                                        double[] cdbPos = new double[] { dto.CdbLon, dto.CdbLat, 0 };
+                                                        double[] refGeod = new double[] { 0, 0, 0 };
+#warning 误差椭圆没有提供无参算法 暂时使用有参
+                                                        double[] errorEllipse = GdopHelper.ErrorEllipse2X1D(posLon, posLat, MainSatXYZ, Adja1SatXYZ, cdbPos, refGeod, DtoErrus, EphErrm);
+                                                        if (errorEllipse.Length == 3)
+                                                        {
+                                                            longAxis = errorEllipse[0];
+                                                            shortAxis = errorEllipse[1];
+                                                            dipAngle = errorEllipse[2];
+                                                        }
+                                                    }
+                                                    StringBuilder sb = new StringBuilder();
+                                                    sb.Append($"{x21d.SigTime:yyyy}\t");
+                                                    sb.Append($"{x21d.SigTime:MM}\t");
+                                                    sb.Append($"{x21d.SigTime:dd}\t");
+                                                    sb.Append($"{x21d.SigTime:HH}\t");
+                                                    sb.Append($"{x21d.SigTime:mm}\t");
+                                                    sb.Append($"{x21d.SigTime:ss}\t");
+                                                    sb.Append($"{x21d.SigTime:fff}\t");
+                                                    sb.Append($"{x21d.CheckRes.SmpCount * 1000 / ch0File.Fs:D4}\t");//信号持续时间ms
+                                                    sb.Append($"{Convert.ToInt64(group.First().FreqDownMHz * 1e6):D12}\t");//下行频点
+                                                    sb.Append($"{Convert.ToInt64((group.First().FreqDownMHz + 44) * 1e6):D12}\t");//上行频点
+                                                    sb.Append($"{4}\t");//信号样式(暂定有这些1:CPM,2:BPSK,4:QPSK),
+                                                    sb.Append($"{0:D4}\t");//目标序号
+                                                    sb.Append($"res\t");
+                                                    sb.Append($"{Convert.ToInt64(posLon * 1e6):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(posLat * 1e6):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(0 * 1e3):D8}\t");//定位误差km
+                                                    sb.Append($"{Convert.ToInt64(x21d.SxDto * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(x21d.SxDfo * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(x21d.SxSnr * 1e2):D6}\t");
+                                                    sb.Append($"{Convert.ToInt64(x21d.XdDto * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(x21d.XdDfo * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(x21d.XdSnr * 1e2):D6}\t");
+                                                    sb.Append($"{Convert.ToInt64(0 * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(0 * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(0 * 1e2):D6}\t");
+                                                    sb.Append($"{longAxis:F8}\t");//长轴
+                                                    sb.Append($"{shortAxis:F8}\t");//短轴
+                                                    sb.Append($"{dipAngle:F7}\t");//倾角
+                                                    sb.Append($"{data1.Count:D2}\t");//时隙属性
+                                                    sb.Append($"{1}\t");//所属卫星
+                                                    sb.Append($"{950:D3}\t");//置信度
+                                                    sb.Append($"{3}");//定位体制(星地=3)
+                                                    sb.Append($"{signalResult.data[i].ModType.GetEnumDisplayName()}");//调制类型
+                                                    sb.Append($"{signalResult.data[i].Rate * 1e-3:F3}\r\n");//符号速率kbps
+                                                    string resFile = Path.Combine(PosResDir, $"定位结果_{posRes.SigTime:yyyyMMdd}.txt");
+                                                    File.AppendAllText(resFile, sb.ToString());
+                                                }
+                                            }
+                                            catch (Exception ex)
+                                            {
+                                                LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-第{i + 1}个突发定位异常", ex);
+                                            }
+                                        }
+
+                                    }
+                                    else
+                                    {
+
+                                        LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-CPU参估开始,共{sig.Slots.Slots.Count}个突发...");
+                                        sw.Start();
+                                        string mainFile = await HttpHelper.UploadFileAsync(ch0File.File, baseUrl, token: cts.Token);//主星文件
+                                        string adja1File = await HttpHelper.UploadFileAsync(ch1File.File, baseUrl, token: cts.Token);//邻1星文件
+                                        string cdbFile = await HttpHelper.UploadFileAsync(ch2File.File, baseUrl, token: cts.Token);//地面信号文件
+
+                                        var smpPositions = sig.Slots.Slots.Select(p => new SmpPosition() { TimeSeconds = p.TimeSeconds, smpStart = p.StartPoint, smpCount = p.Len }).ToList();
+                                        var cgDto = new CpuCgMultiDto()
+                                        {
+                                            dtCenter = 0,
+                                            dtRange = 40000,
+                                            file1 = mainFile,
+                                            file2 = adja1File,
+                                            samplingRate = ch0File.Fs,
+                                            smpPositions = smpPositions,
+                                            snrThreshold = 15,
+                                        };
+                                        var result1 = await HttpHelper.PostRequestAsync<List<CpuCgResDto>>(baseUrl + "DetectCg/CpuCgMultiCalc", cgDto, token: cts.Token);
+                                        if (result1.code != 200)
+                                        {
+                                            LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻主星邻星CPU参估出错.{result1.msg}");
+                                            return;
+                                        }
+                                        cgDto = new CpuCgMultiDto()
+                                        {
+                                            dtCenter = 260000,
+                                            dtRange = 50000,
+                                            file1 = mainFile,
+                                            file2 = cdbFile,
+                                            samplingRate = ch0File.Fs,
+                                            smpPositions = smpPositions,
+                                            snrThreshold = 15,
+                                        };
+                                        var result2 = await HttpHelper.PostRequestAsync<List<CpuCgResDto>>(baseUrl + "DetectCg/CpuCgMultiCalc", cgDto, token: cts.Token);
+                                        if (result2.code != 200)
+                                        {
+                                            LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-主星超短CPU参估出错.{result2.msg}");
+                                            return;
+                                        }
+                                        sw.Stop();
+                                        LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-CPU参估完成,耗时{sw.ElapsedMilliseconds}ms");
+                                        var signaldto = new SignalProcDto()
+                                        {
+                                            File = mainFile,
+                                            Fs = ch0File.Fs,
+                                            Smps = smpPositions,
+                                        };
+                                        var signalResult = await HttpHelper.PostRequestAsync<List<SignalProcResDto>>(baseUrl + "DetectCg/SignalProc", signaldto);
+                                        if (signalResult.code != 200)
+                                        {
+                                            LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-主星信号识别出错.{signalResult.msg}");
+                                            return;
+
+                                        }
+
+                                        LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-主星超短CPU参估完成");
+                                        var data1 = result1.data;
+                                        var data2 = result2.data;
+                                        if (data1.Count != data2.Count || data1.Count != cgDto.smpPositions.Count)
+                                        {
+                                            LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-参估结果个数和检测结果个数不匹配");
+                                            return;
+                                        }
+                                        if (data1.Count != signalResult.data.Count)
+                                        {
+                                            LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-信号识别结果个数和检测结果个数不匹配");
+                                            return;
+                                        }
+                                        for (int i = 0; i < data1.Count; i++)
+                                        {
+                                            try
+                                            {
+                                                if (cts.IsCancellationRequested) break;
+                                                X2D1NoParPosDto x21d = new X2D1NoParPosDto()
+                                                {
+                                                    TaskID = dto.ID,
+                                                    //SigTime = capTime.AddSeconds(data1[i].Smpstart / (double)ch0File.Fs),
+                                                    SigTime = capTime.AddSeconds(data1[i].TimeSeconds),
+                                                    MainCode = MainSatCode,
+                                                    AdjaCode = Adja1SatCode,
+                                                    MainX = MainSatXYZ[0],
+                                                    MainY = MainSatXYZ[1],
+                                                    MainZ = MainSatXYZ[2],
+                                                    AdjaX = Adja1SatXYZ[0],
+                                                    AdjaY = Adja1SatXYZ[1],
+                                                    AdjaZ = Adja1SatXYZ[2],
+                                                    SxDto = PosDtoFactor * data1[i].Dt,
+                                                    SxDfo = data1[i].Df,
+                                                    SxSnr = data1[i].Snr,
+                                                    XdDto = PosDtoFactor * data2[i].Dt,
+                                                    XdDfo = data2[i].Df,
+                                                    XdSnr = data2[i].Snr,
+                                                    SatTxLon = dto.CapLon,
+                                                    SatTxLat = dto.CapLat,
+                                                    CdbTxLon = dto.CdbLon,
+                                                    CdbTxLat = dto.CdbLat,
+                                                    FreqDown = ch0File.FreqDownMHz * 1e6,
+                                                    FreqUp = ch0File.FreqDownMHz * 1e6,
+                                                    CheckRes = new CheckResDto()
+                                                    {
+                                                        FileName = Path.GetFileName(ch0File.File),
+                                                        SmpStart = sig.Slots.Slots[i].StartPoint,
+                                                        SmpCount = sig.Slots.Slots[i].Len,
+                                                        PosCheckType = EnumPosCheckTypeDto.DAMA,
+                                                    }
+                                                };
+                                                var result = await HttpHelper.PostRequestAsync<PosResDto>(baseUrl + "Pos/PosX2D1NoParAsync", x21d);
+                                                if (result.code != 200)
+                                                {
+                                                    LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-时隙位置{data1[i].Smpstart}定位异常.{result.msg}");
+                                                }
+                                                else
+                                                {
+                                                    var posRes = result.data;
+                                                    double posLon = posRes.PosLon;
+                                                    double posLat = posRes.PosLat;
+                                                    if (x21d.SxSnr == 0 || x21d.XdSnr == 0)
+                                                    {
+                                                        posLon = 0;
+                                                        posLat = 0;
+                                                    }
+                                                    double longAxis = 0, shortAxis = 0, dipAngle = 0;
+                                                    if (posLon != 0 && posLat != 0 && posLon != 999 && posLat != 999)
+                                                    {
+                                                        double[] cdbPos = new double[] { dto.CdbLon, dto.CdbLat, 0 };
+                                                        double[] refGeod = new double[] { 0, 0, 0 };
+#warning 误差椭圆没有提供无参算法 暂时使用有参
+                                                        double[] errorEllipse = GdopHelper.ErrorEllipse2X1D(posLon, posLat, MainSatXYZ, Adja1SatXYZ, cdbPos, refGeod, DtoErrus, EphErrm);
+                                                        if (errorEllipse.Length == 3)
+                                                        {
+                                                            longAxis = errorEllipse[0];
+                                                            shortAxis = errorEllipse[1];
+                                                            dipAngle = errorEllipse[2];
+                                                        }
+                                                    }
+                                                    StringBuilder sb = new StringBuilder();
+                                                    sb.Append($"{x21d.SigTime:yyyy}\t");
+                                                    sb.Append($"{x21d.SigTime:MM}\t");
+                                                    sb.Append($"{x21d.SigTime:dd}\t");
+                                                    sb.Append($"{x21d.SigTime:HH}\t");
+                                                    sb.Append($"{x21d.SigTime:mm}\t");
+                                                    sb.Append($"{x21d.SigTime:ss}\t");
+                                                    sb.Append($"{x21d.SigTime:fff}\t");
+                                                    sb.Append($"{x21d.CheckRes.SmpCount * 1000 / ch0File.Fs:D4}\t");//信号持续时间ms
+                                                    sb.Append($"{Convert.ToInt64(group.First().FreqDownMHz * 1e6):D12}\t");//下行频点
+                                                    sb.Append($"{Convert.ToInt64((group.First().FreqDownMHz + 44) * 1e6):D12}\t");//上行频点
+                                                    sb.Append($"{4}\t");//信号样式(暂定有这些1:CPM,2:BPSK,4:QPSK),
+                                                    sb.Append($"{0:D4}\t");//目标序号
+                                                    sb.Append($"res\t");
+                                                    sb.Append($"{Convert.ToInt64(posLon * 1e6):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(posLat * 1e6):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(0 * 1e3):D8}\t");//定位误差km
+                                                    sb.Append($"{Convert.ToInt64(x21d.SxDto * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(x21d.SxDfo * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(x21d.SxSnr * 1e2):D6}\t");
+                                                    sb.Append($"{Convert.ToInt64(x21d.XdDto * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(x21d.XdDfo * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(x21d.XdSnr * 1e2):D6}\t");
+                                                    sb.Append($"{Convert.ToInt64(0 * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(0 * 1e2):D10}\t");
+                                                    sb.Append($"{Convert.ToInt64(0 * 1e2):D6}\t");
+                                                    sb.Append($"{longAxis:F8}\t");//长轴
+                                                    sb.Append($"{shortAxis:F8}\t");//短轴
+                                                    sb.Append($"{dipAngle:F7}\t");//倾角
+                                                    sb.Append($"{data1.Count:D2}\t");//时隙属性
+                                                    sb.Append($"{1}\t");//所属卫星
+                                                    sb.Append($"{950:D3}\t");//置信度
+                                                    sb.Append($"{3}");//定位体制(星地=3)
+                                                    sb.Append($"{signalResult.data[i].ModType.GetEnumDisplayName()}");//调制类型
+                                                    sb.Append($"{signalResult.data[i].Rate * 1e-3:F3}\r\n");//符号速率kbps
+                                                    string resFile = Path.Combine(PosResDir, $"定位结果_{posRes.SigTime:yyyyMMdd}.txt");
+                                                    File.AppendAllText(resFile, sb.ToString());
+                                                }
+                                            }
+                                            catch (Exception ex)
+                                            {
+                                                LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-时隙位置{data1[i].Smpstart}定位异常", ex);
+                                            }
+                                        }
+
+                                    }
+
+                                    //删除DDC文件
+                                    File.Delete(ch0File.File);
+                                    File.Delete(ch1File.File);
+                                    File.Delete(ch2File.File);
+                                    LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-定位完成");
+                                }, cts.Token);
+                                listTask.Add(task);
+                            }
+                            await Task.WhenAll(listTask);
+                        }
+                        #endregion
+                    }
+                    catch (TaskCanceledException ex)
+                    {
+                        LogHelper.Warning($"【任务{dto.ID}】处理结束,用户手动终止", ex.InnerException);
+                    }
+                    catch (Exception ex)
+                    {
+                        if (ex.InnerException != null && ex.InnerException.GetType() == typeof(TaskCanceledException))
+                            LogHelper.Warning($"【任务{dto.ID}】处理结束,用户手动终止", ex.InnerException);
+                        else
+                            LogHelper.Error($"【任务{dto.ID}】任务执行出错", ex);
+                        continue;
+                    }
+                }
+            }, cts.Token);
+        }
+        public void Stop()
+        {
+            cts?.Cancel();
+        }
+        private async Task StopTask(int taskID, EnumTaskStopType type, string stopReason)
+        {
+            await Task.Delay(2000);
+            if (type == EnumTaskStopType.Properly)
+            {
+                LogHelper.Info($"【任务{taskID}】{stopReason}");
+            }
+            else
+            {
+                LogHelper.Error($"【任务{taskID}】{stopReason}");
+            }
+            TaskStopHandleDto stopDto = new TaskStopHandleDto() { ID = taskID, StopType = type, StopReason = stopReason };
+            var stopResp = await HttpHelper.PostRequestAsync(baseUrl + "Task/StopTask", stopDto);
+            if (stopResp.code != 200)
+            {
+                LogHelper.Error($"【任务{taskID}】停止异常.{stopResp.msg}");
+            }
+        }
+
+        private CheckResFile StringToCheckResFile(string file)
+        {
+            //YUFO_252.050MHz_20240409_1398.dat
+            string fileName = Path.GetFileNameWithoutExtension(file).ToUpper();
+            var arr = fileName.Split(new string[] { "_", "MHZ" }, StringSplitOptions.RemoveEmptyEntries);
+            var dayTime = DateTime.ParseExact(arr[2], "yyyyMMdd", null);
+            CheckResFile res = new CheckResFile()
+            {
+                DayTime = dayTime,
+                File = file,
+                FreqDownMHz = Convert.ToDouble(arr[1]),
+                FlagNo = Convert.ToInt64(arr[3]),
+            };
+            return res;
+        }
+        private AdFile StringToAdFile(string file)
+        {
+            //20240409094240_ADC_ch02.dat
+            var name = Path.GetFileNameWithoutExtension(file).ToUpper();
+            var arr = name.Split(new string[] { "_", "CH" }, StringSplitOptions.RemoveEmptyEntries);
+            var time = DateTime.ParseExact(arr[0], "yyyyMMddHHmmss", null);
+            AdFile adFile = new AdFile()
+            {
+                File = file,
+                AdTime = time,
+                ChNo = Convert.ToInt32(arr[2]),
+            };
+            return adFile;
+        }
+        public DDCFile StringToDDCFile(string file)
+        {
+            //20240409094240_252.025_C109375_ch0.dat
+            var name = Path.GetFileNameWithoutExtension(file).ToUpper();
+            var arr = name.Split(new string[] { "_", "MHz", "C", "H" }, StringSplitOptions.RemoveEmptyEntries);
+            var time = DateTime.ParseExact(arr[0], "yyyyMMddHHmmss", null);
+            double freqDown = Convert.ToDouble(arr[1]);
+            int fs = Convert.ToInt32(arr[2]);
+            int chNo = Convert.ToInt32(arr[3]);
+            return new DDCFile()
+            {
+                AdTime = time,
+                ChNo = chNo,
+                File = file,
+                FreqDownMHz = freqDown,
+                Fs = fs
+            };
+        }
+        public List<DDCFile> StringToDDCFile(List<string> files)
+        {
+            List<DDCFile> list = new List<DDCFile>();
+            foreach (var item in files)
+            {
+                list.Add(StringToDDCFile(item));
+            }
+            return list;
+        }
+    }
+}

+ 1 - 1
Service/X2D1NoRefTaskServer54/X2D1NoRefTaskServer54.csproj

@@ -131,7 +131,7 @@
     <Compile Include="MainForm.Designer.cs">
       <DependentUpon>MainForm.cs</DependentUpon>
     </Compile>
-    <Compile Include="Service\HistoryTaskService.cs" />
+    <Compile Include="Service\TaskService.cs" />
     <Compile Include="AddIns\时隙获取\SlotHelper.cs" />
     <None Include="packages.config" />
     <EmbeddedResource Include="Properties\Resources.resx">

+ 6 - 6
Service/X2D1TaskServer54/Controllers/X3NoRefTaskProcessingController.cs

@@ -28,29 +28,29 @@ namespace X3TaskServer54.Controllers
 
 
         /// <summary>
-        /// 执行离线任务
+        /// 执行任务
         /// </summary>
-        /// <param name="dto">离线任务信息</param>
+        /// <param name="dto">任务信息</param>
         /// <returns></returns>
         [HttpPost]
         public AjaxResult Run(X3NoRefTaskHandleDto dto)
         {
             try
             {
-                LogHelper.Info($"接收到历史任务编号:{dto.ID}");
+                LogHelper.Info($"接收到任务编号:{dto.ID}");
                 _service.StartAsync(dto);
                 return Success();
             }
             catch (Exception ex)
             {
-                Serilog.Log.Error(ex, "历史任务处理出错!");
-                return Error("历史任务处理出错");
+                Serilog.Log.Error(ex, "任务处理出错!");
+                return Error("任务处理出错");
             }
         }
 
 
         /// <summary>
-        /// 历史任务停止
+        /// 任务停止
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>

+ 2 - 1
Service/X2D1TaskServer54/Service/TaskService.cs

@@ -179,6 +179,7 @@ namespace X3TaskServer54.Service
                                         return;
                                     }
                                     var sig = sigs.FirstOrDefault(p => p.FreqDownHz == (int)(group.Key * 1e6));
+                                    if (cts.IsCancellationRequested) return;
                                     if (useGpuCg)
                                     {
                                         LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-GPU参估开始,共{sig.Slots.Slots.Count}个突发...");
@@ -260,7 +261,7 @@ namespace X3TaskServer54.Service
                                         LogHelper.Info($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-GPU参估完成,耗时{sw.ElapsedMilliseconds}ms");
                                         if (data1.Count != data2.Count || data1.Count != sig.Slots.Slots.Count)
                                         {
-                                            LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻参估结果个数和检测结果个数不匹配");
+                                            LogHelper.Error($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻-信号{group.Key}MHz-参估结果个数和检测结果个数不匹配");
                                             return;
                                         }
                                         for (int i = 0; i < data1.Count; i++)

+ 7 - 1
XdCxRhDW.App/UserControl/CtrlHome.cs

@@ -722,6 +722,7 @@ namespace XdCxRhDW.App.UserControl
                         await db.SaveChangesAsync();
                     }
                     tsk.TaskState = EnumTaskState.Stopped;
+                    string url = "";
                     if (tsk.TaskType != EnumTaskType.Group)
                     {
                         ModelSvr svtItem = null;
@@ -730,9 +731,14 @@ namespace XdCxRhDW.App.UserControl
                             bool isUserFor54 = UseFor54();
                             EnumSvrType svrType = isUserFor54 ? EnumSvrType.X2D1NoRefTask54 : EnumSvrType.X2D1NoRefTask;
                             svtItem = ServerContext.Instance.GetRandomOne(svrType);
+                            url = "X2D1NoRefTaskProcessing";
                         }
                         else if (tsk.PosType == EnumPosType.X3TwoDto)
+                        {
+
                             svtItem = ServerContext.Instance.GetRandomOne(EnumSvrType.X3NoRefTask54);
+                            url = "X3NoRefTaskProcessing";
+                        }
                         if (svtItem == null)
                         {
                             //DxHelper.MsgBoxHelper.ShowWarning($"未找到注册的处理服务");
@@ -740,7 +746,7 @@ namespace XdCxRhDW.App.UserControl
                         }
                         TaskStopHandleDto dto = new TaskStopHandleDto();
                         dto.ID = tsk.ID;
-                        var res = await HttpHelper.PostRequestAsync<AjaxResult>(svtItem.BaseHttpAddr + "X3NoRefTaskProcessing/Stop", dto);
+                        var res = await HttpHelper.PostRequestAsync<AjaxResult>(svtItem.BaseHttpAddr + $"{url}/Stop", dto);
                         if (res.code != 200)
                         {
                             Serilog.Log.Error(res.msg);