毫米波制导在跟踪和锁定时,使用单脉冲测角,并进行波束宽度检查

This commit is contained in:
Tian jianyong 2025-03-13 14:15:10 +08:00
parent ea54c35d42
commit 8a27dd5077
6 changed files with 166 additions and 50 deletions

View File

@ -17,20 +17,8 @@
"explosionRadius": 5.0, "explosionRadius": 5.0,
"hitProbability": 0.9, "hitProbability": 0.9,
"selfDestructHeight": 0.0, "selfDestructHeight": 0.0,
"irSeekerConfig": { "trackerSensitivity": null,
"spectralBand": { "commandLatency": null,
"min": 3.0, "irSignature": null
"max": 5.0
},
"fieldOfView": 2.0,
"sensitivity": -60.0,
"trackingRate": 10.0
},
"commandLink": {
"frequency": 10.0,
"bandwidth": 1.0,
"modulationType": "FSK",
"updateRate": 100
}
} }
} }

View File

@ -18,7 +18,7 @@
"hitProbability": 0.9, "hitProbability": 0.9,
"selfDestructHeight": 0.0 "selfDestructHeight": 0.0
}, },
"MillimeterWaveGuidanceConfig": { "millimeterWaveGuidanceConfig": {
"maxDetectionRange": 5000.0, "maxDetectionRange": 5000.0,
"fieldOfViewAngle": 45.0, "fieldOfViewAngle": 45.0,
"targetRecognitionProbability": 0.95, "targetRecognitionProbability": 0.95,
@ -46,6 +46,10 @@
"antennaGainDB": 23.0, "antennaGainDB": 23.0,
"noiseFigureDB": 7.0, "noiseFigureDB": 7.0,
"systemLossDB": 6.0 "systemLossDB": 6.0,
"monopulseSensitivity": 1,
"yawControlEffectiveness": 120.0,
"pitchControlEffectiveness": 150.0
} }
} }

View File

@ -27,7 +27,6 @@ namespace ThreatSource.Data
{ {
PropertyNameCaseInsensitive = true, PropertyNameCaseInsensitive = true,
WriteIndented = true, WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = Converters =
{ {
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
@ -79,6 +78,10 @@ namespace ThreatSource.Data
{ {
var jsonContent = File.ReadAllText(file); var jsonContent = File.ReadAllText(file);
Console.WriteLine($"读取导弹文件内容:{jsonContent}"); Console.WriteLine($"读取导弹文件内容:{jsonContent}");
Console.WriteLine($"序列化选项:");
Console.WriteLine($"- PropertyNameCaseInsensitive: {_jsonOptions.PropertyNameCaseInsensitive}");
Console.WriteLine($"- WriteIndented: {_jsonOptions.WriteIndented}");
Console.WriteLine($"- PropertyNamingPolicy: {_jsonOptions.PropertyNamingPolicy}");
var data = JsonSerializer.Deserialize<MissileData>(jsonContent, _jsonOptions); var data = JsonSerializer.Deserialize<MissileData>(jsonContent, _jsonOptions);
if (data != null) if (data != null)
@ -86,7 +89,16 @@ namespace ThreatSource.Data
string model = Path.GetFileNameWithoutExtension(file); string model = Path.GetFileNameWithoutExtension(file);
_missiles[model] = data; _missiles[model] = data;
Console.WriteLine($"已加载导弹数据:{model}"); 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) catch (Exception ex)
@ -113,7 +125,7 @@ namespace ThreatSource.Data
try try
{ {
var jsonContent = File.ReadAllText(file); var jsonContent = File.ReadAllText(file);
Console.WriteLine($"读取指示器文件内容:{jsonContent}"); //Console.WriteLine($"读取指示器文件内容:{jsonContent}");
var data = JsonSerializer.Deserialize<IndicatorData>(jsonContent, _jsonOptions); var data = JsonSerializer.Deserialize<IndicatorData>(jsonContent, _jsonOptions);
if (data != null) if (data != null)
@ -121,7 +133,7 @@ namespace ThreatSource.Data
string model = Path.GetFileNameWithoutExtension(file); string model = Path.GetFileNameWithoutExtension(file);
_indicators[model] = data; _indicators[model] = data;
Console.WriteLine($"已加载指示器数据:{model}"); Console.WriteLine($"已加载指示器数据:{model}");
Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}"); //Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}");
} }
} }
catch (Exception ex) catch (Exception ex)
@ -148,7 +160,7 @@ namespace ThreatSource.Data
try try
{ {
var jsonContent = File.ReadAllText(file); var jsonContent = File.ReadAllText(file);
Console.WriteLine($"读取传感器文件内容:{jsonContent}"); //Console.WriteLine($"读取传感器文件内容:{jsonContent}");
var data = JsonSerializer.Deserialize<SensorData>(jsonContent, _jsonOptions); var data = JsonSerializer.Deserialize<SensorData>(jsonContent, _jsonOptions);
if (data != null) if (data != null)
@ -156,7 +168,7 @@ namespace ThreatSource.Data
string model = Path.GetFileNameWithoutExtension(file); string model = Path.GetFileNameWithoutExtension(file);
_sensors[model] = data; _sensors[model] = data;
Console.WriteLine($"已加载传感器数据:{model}"); Console.WriteLine($"已加载传感器数据:{model}");
Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}"); //Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}");
} }
} }
catch (Exception ex) catch (Exception ex)
@ -183,7 +195,7 @@ namespace ThreatSource.Data
try try
{ {
var jsonContent = File.ReadAllText(file); var jsonContent = File.ReadAllText(file);
Console.WriteLine($"读取目标文件内容:{jsonContent}"); //Console.WriteLine($"读取目标文件内容:{jsonContent}");
var data = JsonSerializer.Deserialize<TargetData>(jsonContent, _jsonOptions); var data = JsonSerializer.Deserialize<TargetData>(jsonContent, _jsonOptions);
if (data != null) if (data != null)
@ -191,7 +203,7 @@ namespace ThreatSource.Data
string model = Path.GetFileNameWithoutExtension(file); string model = Path.GetFileNameWithoutExtension(file);
_targets[model] = data; _targets[model] = data;
Console.WriteLine($"正在加载目标数据:{file}"); Console.WriteLine($"正在加载目标数据:{file}");
Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}"); //Console.WriteLine($"读取到的数据:{JsonSerializer.Serialize(data, _jsonOptions)}");
} }
} }
catch (Exception ex) catch (Exception ex)

View File

@ -260,14 +260,51 @@ namespace ThreatSource.Guidance
} }
} }
/// <summary>
/// 单脉冲和差测角处理(仅用于跟踪/锁定模式)
/// </summary>
/// <param name="toTarget">弹目视线方向向量</param>
/// <param name="missileVelocity">导弹速度向量</param>
/// <returns>(方位误差弧度, 俯仰误差弧度)</returns>
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
);
}
/// <summary> /// <summary>
/// 计算目标是否在当前扫描波束内 /// 计算目标是否在当前扫描波束内
/// </summary> /// </summary>
private bool IsTargetInBeam(Vector3D missileVelocity, Vector3D toTarget) private bool IsTargetInBeam(Vector3D missileVelocity, Vector3D toTarget)
{ {
// 使用导弹速度方向作为X轴前进方向
Vector3D baseDirection = missileVelocity.Normalize();
// 根据当前模式选择波束宽度 // 根据当前模式选择波束宽度
double currentBeamWidth = currentMode switch double currentBeamWidth = currentMode switch
{ {
@ -279,8 +316,9 @@ namespace ThreatSource.Guidance
if (currentMode == WorkMode.Search) if (currentMode == WorkMode.Search)
{ {
// 搜索模式使用圆锥扫描
// 建立以前进方向为X轴的右手坐标系 // 建立以前进方向为X轴的右手坐标系
Vector3D xAxis = baseDirection; Vector3D xAxis = missileVelocity.Normalize();
Vector3D yAxis; Vector3D yAxis;
Vector3D referenceAxis = Vector3D.UnitY; // 优先使用垂直轴作为参考 Vector3D referenceAxis = Vector3D.UnitY; // 优先使用垂直轴作为参考
@ -309,7 +347,7 @@ namespace ThreatSource.Guidance
).Normalize(); ).Normalize();
// 调试输出 // 调试输出
Console.WriteLine($"导弹前进方向: {baseDirection}"); Console.WriteLine($"导弹前进方向: {xAxis}");
Console.WriteLine($"目标方向: {toTarget.Normalize()}"); Console.WriteLine($"目标方向: {toTarget.Normalize()}");
Console.WriteLine($"扫描方向: {scanDirection}"); Console.WriteLine($"扫描方向: {scanDirection}");
@ -322,13 +360,11 @@ namespace ThreatSource.Guidance
} }
else else
{ {
// 跟踪和锁定模式:直接使用基准方向 // 跟踪/锁定模式使用单脉冲测角
double angle = Math.Acos(Vector3D.DotProduct(baseDirection, toTarget.Normalize())); var (azError, elError) = ProcessMonopulse(toTarget.Normalize(), missileVelocity);
Console.WriteLine($"[单脉冲测角] 方位误差: {azError * 180/Math.PI:F3}度, 俯仰误差: {elError * 180/Math.PI:F3}度");
string mode = currentMode == WorkMode.Track ? "跟踪" : "锁定"; Console.WriteLine($"[波束宽度检查] 当前阈值: {currentBeamWidth * 180/Math.PI:F3}度,实际误差: {Math.Sqrt(azError*azError + elError*elError) * 180/Math.PI:F3}度");
Console.WriteLine($"{mode}模式 - 目标夹角: {angle * 180.0 / Math.PI:F2}度, 波束宽度: {currentBeamWidth * 180.0 / Math.PI:F2}度"); return Math.Sqrt(azError*azError + elError*elError) < currentBeamWidth;
return angle <= currentBeamWidth;
} }
} }
@ -359,19 +395,22 @@ namespace ThreatSource.Guidance
lastTargetPosition = targetPosition; lastTargetPosition = targetPosition;
lastTargetVelocity = targetVelocity; lastTargetVelocity = targetVelocity;
// 使用比例导引控制算法 // 使用比例导引计算制导加速度
GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation( GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation(
ProportionalNavigationCoefficient, ProportionalNavigationCoefficient,
missilePosition, missilePosition,
missileVelocity, missileVelocity,
targetPosition, targetPosition,
targetVelocity); targetVelocity
);
// 限制最大加速度
if (GuidanceAcceleration.Magnitude() > MaxAcceleration) if (GuidanceAcceleration.Magnitude() > MaxAcceleration)
{ {
GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration; GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration;
} }
Console.WriteLine($"制导加速度: {GuidanceAcceleration}");
HasGuidance = true; HasGuidance = true;
} }
else else
@ -451,13 +490,26 @@ namespace ThreatSource.Guidance
} }
else if (currentMode == WorkMode.Track || currentMode == WorkMode.Lock) 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; // 在跟踪模式下SNR至少要达到识别阈值
foundTarget = true; double requiredSNR = (currentMode == WorkMode.Track) ?
currentSNR = snr; config.RecognitionSNRThreshold : config.LockSNRThreshold;
break;
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");
}
} }
} }
} }

View File

@ -1347,6 +1347,25 @@ namespace ThreatSource.Simulation
/// </remarks> /// </remarks>
public double SystemLossDB { get; set; } = 6.0; public double SystemLossDB { get; set; } = 6.0;
/// <summary>
/// 单脉冲灵敏度(弧度/误差单位)
/// </summary>
public double MonopulseSensitivity { get; set; } = 0.005;
/// <summary>
/// 偏航舵效 (m/s² per rad/s)
/// </summary>
public double YawControlEffectiveness { get; set; } = 120.0;
/// <summary>
/// 俯仰舵效 (m/s² per rad/s)
/// </summary>
public double PitchControlEffectiveness { get; set; } = 150.0;
/// <summary>
/// 单脉冲跟踪滤波器参数
/// </summary>
public KalmanFilterParams TrackFilterParams { get; set; } = new();
/// <summary> /// <summary>
/// 初始化毫米波末制导导引系统配置的新实例 /// 初始化毫米波末制导导引系统配置的新实例
@ -1372,10 +1391,35 @@ namespace ThreatSource.Simulation
/// - 天线增益23dB /// - 天线增益23dB
/// - 噪声系数7dB /// - 噪声系数7dB
/// - 系统损耗6dB /// - 系统损耗6dB
/// - 单脉冲灵敏度0.002弧度/误差单位
/// - 偏航通道控制增益1.2
/// - 俯仰通道控制增益1.0
/// - 单脉冲跟踪滤波器参数ProcessNoise=0.1, MeasurementNoise=0.01, InitialEstimateError=1.0
/// </remarks> /// </remarks>
public MillimeterWaveGuidanceConfig() public MillimeterWaveGuidanceConfig()
{ {
// 使用属性初始化器设置的默认值 // 使用属性初始化器设置的默认值
} }
} }
/// <summary>
/// 卡尔曼滤波器参数类
/// </summary>
public class KalmanFilterParams
{
/// <summary>
/// 过程噪声
/// </summary>
public double ProcessNoise { get; set; } = 0.1;
/// <summary>
/// 测量噪声
/// </summary>
public double MeasurementNoise { get; set; } = 0.01;
/// <summary>
/// 初始估计误差
/// </summary>
public double InitialEstimateError { get; set; } = 1.0;
}
} }

View File

@ -229,6 +229,22 @@ namespace ThreatSource.Utils
return acceleration; return acceleration;
} }
/// <summary>
/// 将角速度转换为加速度
/// </summary>
/// <param name="angularRate">角速度</param>
/// <param name="yawEffectiveness">偏航舵效</param>
/// <param name="pitchEffectiveness">俯仰舵效</param>
/// <returns>加速度</returns>
public static Vector3D ConvertAngularRateToAcceleration(Vector3D angularRate, double yawEffectiveness, double pitchEffectiveness)
{
return new Vector3D(
0,
angularRate.Y * yawEffectiveness,
angularRate.Z * pitchEffectiveness
);
}
/// <summary> /// <summary>
/// 为向量添加高斯噪声 /// 为向量添加高斯噪声
/// </summary> /// </summary>