ThreatSourceLibaray/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs

590 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using ThreatSource.Simulation;
using ThreatSource.Utils;
using ThreatSource.Target;
using System.Diagnostics;
namespace ThreatSource.Guidance
{
/// <summary>
/// 毫米波导引头系统类,实现了基于毫米波雷达的目标探测和跟踪功能
/// </summary>
/// <remarks>
/// 该类提供了毫米波导引头系统的核心功能:
/// - 目标探测和识别
/// - 信噪比计算
/// - 抗干扰处理
/// - 比例导引控制
/// 用于实现全天候制导打击
/// </remarks>
public class MillimeterWaveGuidanceSystem : BasicGuidanceSystem
{
/// <summary>
/// 工作模式枚举
/// </summary>
private enum WorkMode
{
Search, // 搜索模式
Track, // 跟踪模式
Lock // 锁定模式
}
/// <summary>
/// 毫米波导引系统配置
/// </summary>
/// <remarks>
/// 存储系统的所有可配置参数
/// 包括探测范围、视场角等
/// </remarks>
private readonly MillimeterWaveGuidanceConfig config;
/// <summary>
/// 随机数生成器实例
/// </summary>
/// <remarks>
/// 用于生成随机扰动
/// 模拟系统噪声和识别概率
/// </remarks>
private readonly Random random = new();
/// <summary>
/// 上一次探测到的目标位置
/// </summary>
/// <remarks>
/// 记录目标的历史位置
/// 用于计算目标速度
/// </remarks>
private Vector3D lastTargetPosition;
/// <summary>
/// 上一次探测到的目标速度
/// </summary>
/// <remarks>
/// 记录目标的历史速度
/// 用于计算目标速度
/// </remarks>
private Vector3D lastTargetVelocity;
/// <summary>
/// 目标丢失计时器
/// </summary>
/// <remarks>
/// 记录目标丢失的时间
/// 用于切换到搜索模式
/// </remarks>
private double targetLostTimer = 0;
/// <summary>
/// 锁定确认计时器
/// </summary>
/// <remarks>
/// 记录锁定确认的时间
/// 用于切换到锁定模式
/// </remarks>
private double lockConfirmationTimer = 0;
/// <summary>
/// 当前工作模式
/// </summary>
private WorkMode currentMode = WorkMode.Search;
/// <summary>
/// 是否受到干扰
/// </summary>
/// <remarks>
/// 指示当前是否受到电子干扰
/// 影响系统的工作状态
/// </remarks>
private bool isJammed = false;
/// <summary>
/// 干扰功率,单位:瓦特
/// </summary>
/// <remarks>
/// 记录接收到的干扰信号功率
/// 用于评估干扰效果
/// </remarks>
private double jammingPower = 0;
/// <summary>
/// 是否有目标
/// </summary>
public bool HasTarget { get; private set; }
/// <summary>
/// 是否在锁定模式
/// </summary>
public bool IsInLockMode => currentMode == WorkMode.Lock;
/// <summary>
/// 当前扫描角度,单位:弧度
/// </summary>
private double currentScanAngle = 0;
/// <summary>
/// 当前扫描半径,单位:弧度
/// </summary>
private double currentScanRadius = 0;
/// <summary>
/// 最大扫描半径,单位:弧度
/// </summary>
private double maxScanRadius => config.FieldOfViewAngle * Math.PI / 180.0 / 2;
/// <summary>
/// 激活制导系统
/// </summary>
public override void Activate()
{
base.Activate();
SwitchToSearchMode();
}
/// <summary>
/// 停用制导系统
/// </summary>
public override void Deactivate()
{
base.Deactivate();
HasTarget = false;
HasGuidance = false;
GuidanceAcceleration = Vector3D.Zero;
}
/// <summary>
/// 初始化毫米波制导系统的新实例
/// </summary>
/// <param name="id">制导系统ID</param>
/// <param name="maxAcceleration">最大加速度,单位:米/平方秒</param>
/// <param name="guidanceCoefficient">制导系数</param>
/// <param name="simulationManager">仿真管理器实例</param>
/// <param name="config">毫米波导引系统配置</param>
/// <remarks>
/// 构造过程:
/// - 初始化基类参数
/// - 设置仿真管理器
/// - 初始化目标位置
/// - 注册干扰事件处理
/// </remarks>
public MillimeterWaveGuidanceSystem(
string id,
double maxAcceleration,
double guidanceCoefficient,
MillimeterWaveGuidanceConfig config,
ISimulationManager simulationManager)
: base(id, maxAcceleration, guidanceCoefficient, simulationManager)
{
this.config = config;
lastTargetPosition = Vector3D.Zero;
lastTargetVelocity = Vector3D.Zero;
// 订阅干扰事件
simulationManager.SubscribeToEvent<MillimeterWaveJammingEvent>(HandleJammingEvent);
SwitchToSearchMode(); // 初始化为搜索模式
}
/// <summary>
/// 切换到搜索模式
/// </summary>
public void SwitchToSearchMode()
{
currentMode = WorkMode.Search;
HasTarget = false;
HasGuidance = false;
targetLostTimer = 0;
lockConfirmationTimer = 0;
currentScanAngle = 0;
currentScanRadius = config.SearchBeamWidth * Math.PI / 720.0; // 从半个波束宽度的一半开始
Trace.WriteLine($"切换到搜索模式,波束宽度: {config.SearchBeamWidth}度");
}
/// <summary>
/// 切换到跟踪模式
/// </summary>
private void SwitchToTrackMode()
{
currentMode = WorkMode.Track;
lockConfirmationTimer = 0;
HasGuidance = true;
Trace.WriteLine($"切换到跟踪模式,波束宽度: {config.TrackBeamWidth}度");
}
/// <summary>
/// 切换到锁定模式
/// </summary>
private void SwitchToLockMode()
{
currentMode = WorkMode.Lock;
HasGuidance = true;
Trace.WriteLine("切换到锁定模式 - 目标锁定成功");
}
/// <summary>
/// 处理毫米波干扰事件
/// </summary>
/// <param name="evt">干扰事件参数</param>
/// <remarks>
/// 处理过程:
/// - 更新干扰状态
/// - 记录干扰功率
/// </remarks>
private void HandleJammingEvent(MillimeterWaveJammingEvent evt)
{
isJammed = true;
jammingPower = evt.JammingPower;
}
/// <summary>
/// 更新圆锥扫描参数
/// </summary>
private void UpdateConicalScan(double deltaTime)
{
if (currentMode == WorkMode.Search)
{
// 使用配置参数
currentScanAngle += config.ScanAngularSpeedDeg * Math.PI / 180.0 * deltaTime;
currentScanRadius += config.ScanRadiusGrowthRateDeg * Math.PI / 180.0 * deltaTime;
currentScanRadius = Math.Min(currentScanRadius, maxScanRadius);
if (currentScanAngle >= 2 * Math.PI)
{
currentScanAngle -= 2 * Math.PI;
}
Console.WriteLine($"扫描参数 - 半径: {currentScanRadius * 180/Math.PI:F2}度, 角度: {currentScanAngle * 180/Math.PI:F2}度");
}
else
{
currentScanAngle = 0;
// 非搜索模式时重置扫描参数
currentScanRadius = config.SearchBeamWidth * Math.PI / 720.0;
}
}
/// <summary>
/// 计算目标是否在当前扫描波束内
/// </summary>
private bool IsTargetInBeam(Vector3D missileVelocity, Vector3D toTarget)
{
// 使用导弹速度方向作为X轴前进方向
Vector3D baseDirection = missileVelocity.Normalize();
// 根据当前模式选择波束宽度
double currentBeamWidth = currentMode switch
{
WorkMode.Search => config.SearchBeamWidth * Math.PI / 180.0,
WorkMode.Track => config.TrackBeamWidth * Math.PI / 180.0,
WorkMode.Lock => config.LockBeamWidth * Math.PI / 180.0,
_ => config.SearchBeamWidth * Math.PI / 180.0
};
if (currentMode == WorkMode.Search)
{
// 建立以前进方向为X轴的右手坐标系
Vector3D xAxis = baseDirection;
Vector3D yAxis;
Vector3D referenceAxis = Vector3D.UnitY; // 优先使用垂直轴作为参考
// 处理近乎垂直飞行的情况
if (Math.Abs(xAxis.Y) > 0.9)
{
referenceAxis = Vector3D.UnitZ; // 改用Z轴作为参考
}
// 构建正交坐标系
yAxis = Vector3D.CrossProduct(Vector3D.CrossProduct(xAxis, referenceAxis), xAxis).Normalize();
Vector3D zAxis = Vector3D.CrossProduct(xAxis, yAxis).Normalize();
// 计算圆锥扫描方向
double offsetAngle = currentScanRadius;
// X轴为主轴的圆锥扫描参数
double x = Math.Cos(offsetAngle); // 主轴分量
double y = Math.Sin(offsetAngle) * Math.Sin(currentScanAngle); // 垂直分量
double z = Math.Sin(offsetAngle) * Math.Cos(currentScanAngle); // 水平分量
// 合成扫描方向向量
Vector3D scanDirection = (
xAxis * x +
yAxis * y +
zAxis * z
).Normalize();
// 调试输出
Console.WriteLine($"导弹前进方向: {baseDirection}");
Console.WriteLine($"目标方向: {toTarget.Normalize()}");
Console.WriteLine($"扫描方向: {scanDirection}");
// 计算目标夹角
double angle = Vector3D.AngleBetween(scanDirection, toTarget.Normalize());
Console.WriteLine($"目标夹角: {angle * 180/Math.PI:F2}度");
Console.WriteLine($"波束宽度: {currentBeamWidth * 180/Math.PI:F2}度SNR阈值: {config.RecognitionSNRThreshold}dB");
return angle <= currentBeamWidth;
}
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;
}
}
/// <summary>
/// 更新制导系统的状态
/// </summary>
/// <param name="deltaTime">自上次更新以来的时间间隔,单位:秒</param>
/// <param name="missilePosition">导弹当前位置,单位:米</param>
/// <param name="missileVelocity">导弹当前速度,单位:米/秒</param>
/// <remarks>
/// 更新过程:
/// - 探测目标位置
/// - 计算目标速度
/// - 生成制导指令
/// - 限制最大加速度
/// </remarks>
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
{
// 更新扫描参数
UpdateConicalScan(deltaTime);
base.Update(deltaTime, missilePosition, missileVelocity);
if (TryDetectAndTrackTarget(missilePosition, missileVelocity, deltaTime, out Vector3D targetPosition))
{
targetLostTimer = 0;
Vector3D targetVelocity = (targetPosition - lastTargetPosition) / deltaTime;
lastTargetPosition = targetPosition;
lastTargetVelocity = targetVelocity;
// 使用比例导引控制算法
GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation(
ProportionalNavigationCoefficient,
missilePosition,
missileVelocity,
targetPosition,
targetVelocity);
if (GuidanceAcceleration.Magnitude() > MaxAcceleration)
{
GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration;
}
HasGuidance = true;
}
else
{
if (currentMode != WorkMode.Search)
{
targetLostTimer += deltaTime;
// 如果目标丢失时间达到阈值,切换回搜索模式
if (targetLostTimer >= config.TargetLostTolerance)
{
HasGuidance = false;
Trace.WriteLine($"目标丢失 {targetLostTimer:F3}秒,切换回搜索模式");
SwitchToSearchMode();
}
}
else
{
HasGuidance = false;
}
}
}
/// <summary>
/// 尝试探测和跟踪目标
/// </summary>
/// <param name="missilePosition">导弹当前位置,单位:米</param>
/// <param name="missileVelocity">导弹当前速度,单位:米/秒</param>
/// <param name="deltaTime">自上次更新以来的时间间隔,单位:秒</param>
/// <param name="targetPosition">输出探测到的目标位置,单位:米</param>
/// <returns>是否成功探测到目标</returns>
/// <remarks>
/// 探测过程:
/// - 检查干扰状态
/// - 遍历场景中的目标
/// - 检查距离和角度
/// - 计算信噪比
/// - 判断目标有效性
/// </remarks>
private bool TryDetectAndTrackTarget(Vector3D missilePosition, Vector3D missileVelocity, double deltaTime, out Vector3D targetPosition)
{
targetPosition = Vector3D.Zero;
double minDistance = double.MaxValue;
bool foundTarget = false;
double currentSNR = double.MinValue;
// 如果被干扰直接返回false
if (isJammed)
{
Trace.WriteLine($"毫米波导引头受到干扰,干扰功率: {jammingPower:F2}W");
HasGuidance = false;
return false;
}
foreach (var element in SimulationManager.GetEntitiesByType<SimulationElement>())
{
if (element is ITarget target)
{
Vector3D toTarget = target.Position - missilePosition;
double distance = toTarget.Magnitude();
if (distance <= config.MaxDetectionRange)
{
// 计算信噪比
double snr = CalculateSNR(distance, target.RadarCrossSection);
Console.WriteLine($"信噪比: {snr:F2}dB");
if (currentMode == WorkMode.Search)
{
// 在搜索模式下进行波束判断
if (IsTargetInBeam(missileVelocity, toTarget) && snr >= config.RecognitionSNRThreshold)
{
targetPosition = target.Position;
minDistance = distance;
foundTarget = true;
currentSNR = snr;
}
}
else if (currentMode == WorkMode.Track || currentMode == WorkMode.Lock)
{
// 在跟踪和锁定模式下直接使用搜索阶段的目标位置
if (Vector3D.Distance(target.Position, lastTargetPosition) < 100.0) // 目标识别容差
{
targetPosition = target.Position;
foundTarget = true;
currentSNR = snr;
break;
}
}
}
}
}
// 根据当前模式和探测结果更新系统状态
UpdateSystemState(foundTarget, currentSNR, deltaTime);
HasTarget = foundTarget;
return foundTarget;
}
/// <summary>
/// 更新系统状态
/// </summary>
private void UpdateSystemState(bool hasTarget, double snr, double deltaTime)
{
if (!hasTarget)
{
targetLostTimer += deltaTime;
if (targetLostTimer >= config.TargetLostTolerance)
{
SwitchToSearchMode();
}
return;
}
targetLostTimer = 0;
switch (currentMode)
{
case WorkMode.Search:
if (snr >= config.RecognitionSNRThreshold)
{
SwitchToTrackMode();
}
break;
case WorkMode.Track:
if (snr >= config.LockSNRThreshold)
{
lockConfirmationTimer += deltaTime;
if (lockConfirmationTimer >= config.LockConfirmationTime)
{
SwitchToLockMode();
}
}
else
{
lockConfirmationTimer = 0;
}
break;
case WorkMode.Lock:
if (snr < config.LockSNRThreshold)
{
SwitchToTrackMode();
}
break;
}
}
/// <summary>
/// 获取制导系统的详细状态信息
/// </summary>
/// <returns>包含完整状态参数的字符串</returns>
/// <remarks>
/// 返回信息:
/// - 基本状态信息
/// - 目标位置
/// 用于系统监控和调试
/// </remarks>
public override string GetStatus()
{
return base.GetStatus() +
$"\n当前模式: {currentMode}" +
$"\n目标位置: {lastTargetPosition}" +
$"\n目标速度: {lastTargetVelocity}" +
$"\n是否有目标: {HasTarget}";
}
/// <summary>
/// 计算目标的信噪比
/// </summary>
/// <param name="distance">到目标的距离,单位:米</param>
/// <param name="radarCrossSection">目标雷达散射截面积,单位:平方米</param>
/// <returns>信噪比,单位:分贝</returns>
/// <remarks>
/// 计算过程:
/// - 设置雷达参数
/// - 计算信号功率
/// - 计算噪声功率
/// - 计算信噪比
/// - 转换为分贝值
/// </remarks>
private double CalculateSNR(double distance, double radarCrossSection)
{
// 雷达参数
double transmitPower = config.TransmitPower; // 发射功率(W)典型值0.3W
double antennaGain = Math.Pow(10, config.AntennaGainDB/10); // 天线增益(线性值)
double wavelength = 3e8 / config.WaveFrequency; // 波长(m)94GHz -> 3.19mm
double bandwidth = 1.0 / config.PulseDuration; // 带宽(Hz),由脉冲持续时间决定
double noiseFigure = Math.Pow(10, config.NoiseFigureDB/10); // 噪声系数(线性值)
// 系统损耗单位dB
double atmosphericLoss = 0.4 * distance / 1000.0; // 大气衰减0.4dB/km
double totalLoss = Math.Pow(10, (atmosphericLoss + config.SystemLossDB) / 10); // 转换为线性值
// 常量
double k = 1.38e-23; // 玻尔兹曼常数
double T0 = 290; // 标准噪声温度(K)
// 计算接收信号功率
double signalPower = (transmitPower * Math.Pow(antennaGain, 2) * Math.Pow(wavelength, 2) * radarCrossSection)
/ (Math.Pow(4 * Math.PI, 3) * Math.Pow(distance, 4) * totalLoss);
// 计算噪声功率
double noisePower = k * T0 * bandwidth * noiseFigure;
// 计算信噪比
double snr = signalPower / noisePower;
// 转换为dB
return 10 * Math.Log10(snr);
}
}
}