毫米波制导在跟踪和锁定时,使用单脉冲测角,并进行波束宽度检查
This commit is contained in:
parent
ea54c35d42
commit
8a27dd5077
@ -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
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user