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

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,
"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
}
}

View File

@ -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
}
}

View File

@ -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<MissileData>(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<IndicatorData>(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<SensorData>(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<TargetData>(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)

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>
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");
}
}
}
}

View File

@ -1347,6 +1347,25 @@ namespace ThreatSource.Simulation
/// </remarks>
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>
/// 初始化毫米波末制导导引系统配置的新实例
@ -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
/// </remarks>
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;
}
/// <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>