diff --git a/ThreatSource/data/missiles/ir_command/irc_001.json b/ThreatSource/data/missiles/ir_command/irc_001.json index 2e9614d..fdcf029 100644 --- a/ThreatSource/data/missiles/ir_command/irc_001.json +++ b/ThreatSource/data/missiles/ir_command/irc_001.json @@ -17,20 +17,8 @@ "explosionRadius": 5.0, "hitProbability": 0.9, "selfDestructHeight": 0.0, - "irSeekerConfig": { - "spectralBand": { - "min": 3.0, - "max": 5.0 - }, - "fieldOfView": 2.0, - "sensitivity": -60.0, - "trackingRate": 10.0 - }, - "commandLink": { - "frequency": 10.0, - "bandwidth": 1.0, - "modulationType": "FSK", - "updateRate": 100 - } + "trackerSensitivity": null, + "commandLatency": null, + "irSignature": null } } \ No newline at end of file diff --git a/ThreatSource/data/missiles/mmw/mmw_001.json b/ThreatSource/data/missiles/mmw/mmw_001.json index 3a0d8be..eb30a17 100644 --- a/ThreatSource/data/missiles/mmw/mmw_001.json +++ b/ThreatSource/data/missiles/mmw/mmw_001.json @@ -18,7 +18,7 @@ "hitProbability": 0.9, "selfDestructHeight": 0.0 }, - "MillimeterWaveGuidanceConfig": { + "millimeterWaveGuidanceConfig": { "maxDetectionRange": 5000.0, "fieldOfViewAngle": 45.0, "targetRecognitionProbability": 0.95, @@ -46,6 +46,10 @@ "antennaGainDB": 23.0, "noiseFigureDB": 7.0, - "systemLossDB": 6.0 + "systemLossDB": 6.0, + "monopulseSensitivity": 1, + + "yawControlEffectiveness": 120.0, + "pitchControlEffectiveness": 150.0 } } \ No newline at end of file diff --git a/ThreatSource/src/Data/ThreatSourceDataManager.cs b/ThreatSource/src/Data/ThreatSourceDataManager.cs index d77fdb4..c64a554 100644 --- a/ThreatSource/src/Data/ThreatSourceDataManager.cs +++ b/ThreatSource/src/Data/ThreatSourceDataManager.cs @@ -27,7 +27,6 @@ namespace ThreatSource.Data { PropertyNameCaseInsensitive = true, WriteIndented = true, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) @@ -79,6 +78,10 @@ namespace ThreatSource.Data { var jsonContent = File.ReadAllText(file); Console.WriteLine($"读取导弹文件内容:{jsonContent}"); + Console.WriteLine($"序列化选项:"); + Console.WriteLine($"- PropertyNameCaseInsensitive: {_jsonOptions.PropertyNameCaseInsensitive}"); + Console.WriteLine($"- WriteIndented: {_jsonOptions.WriteIndented}"); + Console.WriteLine($"- PropertyNamingPolicy: {_jsonOptions.PropertyNamingPolicy}"); var data = JsonSerializer.Deserialize(jsonContent, _jsonOptions); if (data != null) @@ -86,7 +89,16 @@ namespace ThreatSource.Data string model = Path.GetFileNameWithoutExtension(file); _missiles[model] = data; Console.WriteLine($"已加载导弹数据:{model}"); - Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}"); + Console.WriteLine($"导弹类型:{data.Type}"); + Console.WriteLine($"毫米波导引配置:{(data.MillimeterWaveGuidanceConfig != null ? "已加载" : "未加载")}"); + if (data.MillimeterWaveGuidanceConfig != null) + { + var config = data.MillimeterWaveGuidanceConfig; + Console.WriteLine($"- 最大探测范围:{config.MaxDetectionRange}"); + Console.WriteLine($"- 视场角:{config.FieldOfViewAngle}"); + Console.WriteLine($"- 目标识别概率:{config.TargetRecognitionProbability}"); + } + //Console.WriteLine($"读取到的完整数据:{JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true })}"); } } catch (Exception ex) @@ -113,7 +125,7 @@ namespace ThreatSource.Data try { var jsonContent = File.ReadAllText(file); - Console.WriteLine($"读取指示器文件内容:{jsonContent}"); + //Console.WriteLine($"读取指示器文件内容:{jsonContent}"); var data = JsonSerializer.Deserialize(jsonContent, _jsonOptions); if (data != null) @@ -121,7 +133,7 @@ namespace ThreatSource.Data string model = Path.GetFileNameWithoutExtension(file); _indicators[model] = data; Console.WriteLine($"已加载指示器数据:{model}"); - Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}"); + //Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}"); } } catch (Exception ex) @@ -148,7 +160,7 @@ namespace ThreatSource.Data try { var jsonContent = File.ReadAllText(file); - Console.WriteLine($"读取传感器文件内容:{jsonContent}"); + //Console.WriteLine($"读取传感器文件内容:{jsonContent}"); var data = JsonSerializer.Deserialize(jsonContent, _jsonOptions); if (data != null) @@ -156,7 +168,7 @@ namespace ThreatSource.Data string model = Path.GetFileNameWithoutExtension(file); _sensors[model] = data; Console.WriteLine($"已加载传感器数据:{model}"); - Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}"); + //Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}"); } } catch (Exception ex) @@ -183,7 +195,7 @@ namespace ThreatSource.Data try { var jsonContent = File.ReadAllText(file); - Console.WriteLine($"读取目标文件内容:{jsonContent}"); + //Console.WriteLine($"读取目标文件内容:{jsonContent}"); var data = JsonSerializer.Deserialize(jsonContent, _jsonOptions); if (data != null) @@ -191,7 +203,7 @@ namespace ThreatSource.Data string model = Path.GetFileNameWithoutExtension(file); _targets[model] = data; Console.WriteLine($"正在加载目标数据:{file}"); - Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}"); + //Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}"); } } catch (Exception ex) diff --git a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs index 9322b49..ba1dd15 100644 --- a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs @@ -260,14 +260,51 @@ namespace ThreatSource.Guidance } } + /// + /// 单脉冲和差测角处理(仅用于跟踪/锁定模式) + /// + /// 弹目视线方向向量 + /// 导弹速度向量 + /// (方位误差弧度, 俯仰误差弧度) + private (double azimuthError, double elevationError) ProcessMonopulse(Vector3D toTarget, Vector3D missileVelocity) + { + // 建立弹体坐标系(X轴为导弹速度方向) + Vector3D xAxis = missileVelocity.Normalize(); + // 使用地面垂直方向作为参考 + Vector3D up = Vector3D.UnitY; + // 计算水平方向 + Vector3D yAxis = Vector3D.CrossProduct(up, xAxis).Normalize(); + if (yAxis.Magnitude() < 1e-6) + { + // 如果导弹垂直飞行,使用北向作为参考 + yAxis = Vector3D.CrossProduct(Vector3D.UnitZ, xAxis).Normalize(); + } + // 计算垂直方向 + Vector3D zAxis = Vector3D.CrossProduct(xAxis, yAxis).Normalize(); + + // 将目标向量转换到弹体坐标系 + Vector3D targetBodyFrame = new( + Vector3D.DotProduct(toTarget, xAxis), + Vector3D.DotProduct(toTarget, yAxis), + Vector3D.DotProduct(toTarget, zAxis) + ); + + // 计算方位角和俯仰角 + double azimuthError = Math.Atan2(targetBodyFrame.Y, targetBodyFrame.X); + double elevationError = Math.Atan2(targetBodyFrame.Z, Math.Sqrt(targetBodyFrame.X * targetBodyFrame.X + targetBodyFrame.Y * targetBodyFrame.Y)); + + // 应用灵敏度系数 + return ( + azimuthError * config.MonopulseSensitivity, + elevationError * config.MonopulseSensitivity + ); + } + /// /// 计算目标是否在当前扫描波束内 /// private bool IsTargetInBeam(Vector3D missileVelocity, Vector3D toTarget) - { - // 使用导弹速度方向作为X轴(前进方向) - Vector3D baseDirection = missileVelocity.Normalize(); - + { // 根据当前模式选择波束宽度 double currentBeamWidth = currentMode switch { @@ -279,8 +316,9 @@ namespace ThreatSource.Guidance if (currentMode == WorkMode.Search) { + // 搜索模式使用圆锥扫描 // 建立以前进方向为X轴的右手坐标系 - Vector3D xAxis = baseDirection; + Vector3D xAxis = missileVelocity.Normalize(); Vector3D yAxis; Vector3D referenceAxis = Vector3D.UnitY; // 优先使用垂直轴作为参考 @@ -309,7 +347,7 @@ namespace ThreatSource.Guidance ).Normalize(); // 调试输出 - Console.WriteLine($"导弹前进方向: {baseDirection}"); + Console.WriteLine($"导弹前进方向: {xAxis}"); Console.WriteLine($"目标方向: {toTarget.Normalize()}"); Console.WriteLine($"扫描方向: {scanDirection}"); @@ -322,13 +360,11 @@ namespace ThreatSource.Guidance } else { - // 跟踪和锁定模式:直接使用基准方向 - double angle = Math.Acos(Vector3D.DotProduct(baseDirection, toTarget.Normalize())); - - string mode = currentMode == WorkMode.Track ? "跟踪" : "锁定"; - Console.WriteLine($"{mode}模式 - 目标夹角: {angle * 180.0 / Math.PI:F2}度, 波束宽度: {currentBeamWidth * 180.0 / Math.PI:F2}度"); - - return angle <= currentBeamWidth; + // 跟踪/锁定模式使用单脉冲测角 + var (azError, elError) = ProcessMonopulse(toTarget.Normalize(), missileVelocity); + Console.WriteLine($"[单脉冲测角] 方位误差: {azError * 180/Math.PI:F3}度, 俯仰误差: {elError * 180/Math.PI:F3}度"); + Console.WriteLine($"[波束宽度检查] 当前阈值: {currentBeamWidth * 180/Math.PI:F3}度,实际误差: {Math.Sqrt(azError*azError + elError*elError) * 180/Math.PI:F3}度"); + return Math.Sqrt(azError*azError + elError*elError) < currentBeamWidth; } } @@ -359,19 +395,22 @@ namespace ThreatSource.Guidance lastTargetPosition = targetPosition; lastTargetVelocity = targetVelocity; - // 使用比例导引控制算法 + // 使用比例导引计算制导加速度 GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation( - ProportionalNavigationCoefficient, - missilePosition, - missileVelocity, - targetPosition, - targetVelocity); + ProportionalNavigationCoefficient, + missilePosition, + missileVelocity, + targetPosition, + targetVelocity + ); + // 限制最大加速度 if (GuidanceAcceleration.Magnitude() > MaxAcceleration) { GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration; } + Console.WriteLine($"制导加速度: {GuidanceAcceleration}"); HasGuidance = true; } else @@ -451,13 +490,26 @@ namespace ThreatSource.Guidance } else if (currentMode == WorkMode.Track || currentMode == WorkMode.Lock) { - // 在跟踪和锁定模式下直接使用搜索阶段的目标位置 - if (Vector3D.Distance(target.Position, lastTargetPosition) < 100.0) // 目标识别容差 + // 波束内判断 + if (IsTargetInBeam(missileVelocity, toTarget) && + Vector3D.Distance(target.Position, lastTargetPosition) < 100.0) { - targetPosition = target.Position; - foundTarget = true; - currentSNR = snr; - break; + // 在跟踪模式下,SNR至少要达到识别阈值 + double requiredSNR = (currentMode == WorkMode.Track) ? + config.RecognitionSNRThreshold : config.LockSNRThreshold; + + if (snr >= requiredSNR) + { + targetPosition = target.Position; + foundTarget = true; + currentSNR = snr; + Console.WriteLine($"[目标跟踪] 距离: {distance:F1}米, SNR: {snr:F2}dB, 要求SNR: {requiredSNR:F2}dB"); + break; + } + else + { + Console.WriteLine($"[目标丢失] 距离: {distance:F1}米, SNR: {snr:F2}dB, 要求SNR: {requiredSNR:F2}dB"); + } } } } diff --git a/ThreatSource/src/Simulation/SimulationConfig.cs b/ThreatSource/src/Simulation/SimulationConfig.cs index eecbd84..aa47b36 100644 --- a/ThreatSource/src/Simulation/SimulationConfig.cs +++ b/ThreatSource/src/Simulation/SimulationConfig.cs @@ -1347,6 +1347,25 @@ namespace ThreatSource.Simulation /// public double SystemLossDB { get; set; } = 6.0; + /// + /// 单脉冲灵敏度(弧度/误差单位) + /// + public double MonopulseSensitivity { get; set; } = 0.005; + + /// + /// 偏航舵效 (m/s² per rad/s) + /// + public double YawControlEffectiveness { get; set; } = 120.0; + + /// + /// 俯仰舵效 (m/s² per rad/s) + /// + public double PitchControlEffectiveness { get; set; } = 150.0; + + /// + /// 单脉冲跟踪滤波器参数 + /// + public KalmanFilterParams TrackFilterParams { get; set; } = new(); /// /// 初始化毫米波末制导导引系统配置的新实例 @@ -1372,10 +1391,35 @@ namespace ThreatSource.Simulation /// - 天线增益:23dB /// - 噪声系数:7dB /// - 系统损耗:6dB + /// - 单脉冲灵敏度:0.002弧度/误差单位 + /// - 偏航通道控制增益:1.2 + /// - 俯仰通道控制增益:1.0 + /// - 单脉冲跟踪滤波器参数:ProcessNoise=0.1, MeasurementNoise=0.01, InitialEstimateError=1.0 /// public MillimeterWaveGuidanceConfig() { // 使用属性初始化器设置的默认值 } } + + /// + /// 卡尔曼滤波器参数类 + /// + public class KalmanFilterParams + { + /// + /// 过程噪声 + /// + public double ProcessNoise { get; set; } = 0.1; + + /// + /// 测量噪声 + /// + public double MeasurementNoise { get; set; } = 0.01; + + /// + /// 初始估计误差 + /// + public double InitialEstimateError { get; set; } = 1.0; + } } diff --git a/ThreatSource/src/Utils/MotionAlgorithm.cs b/ThreatSource/src/Utils/MotionAlgorithm.cs index 055ad80..4ed07bd 100644 --- a/ThreatSource/src/Utils/MotionAlgorithm.cs +++ b/ThreatSource/src/Utils/MotionAlgorithm.cs @@ -229,6 +229,22 @@ namespace ThreatSource.Utils return acceleration; } + /// + /// 将角速度转换为加速度 + /// + /// 角速度 + /// 偏航舵效 + /// 俯仰舵效 + /// 加速度 + public static Vector3D ConvertAngularRateToAcceleration(Vector3D angularRate, double yawEffectiveness, double pitchEffectiveness) + { + return new Vector3D( + 0, + angularRate.Y * yawEffectiveness, + angularRate.Z * pitchEffectiveness + ); + } + /// /// 为向量添加高斯噪声 ///