ActiveProtect/Models/InfraredImagingGuidanceSystem.cs

117 lines
4.5 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 System;
using ActiveProtect.SimulationEnvironment;
namespace ActiveProtect.Models
{
/// <summary>
/// 红外成像引导系统
/// </summary>
public class InfraredImagingGuidanceSystem : BasicGuidanceSystem
{
private const double MAX_DETECTION_RANGE = 5000; // 最大探测范围(米)
private const double FIELD_OF_VIEW = Math.PI / 6; // 视场角(弧度)标枪导弹为40°坦克破坏者为 24°
private const double TARGET_RECOGNITION_PROBABILITY = 0.9; // 目标识别概率
private const double RECOGNITION_SNR_THRESHOLD = 6; // 识别目标信噪比阈值, 单位dB
private const double BACKGROUND_RADIATION_INTENSITY = 10; // 背景辐射强度 (W/sr)
private readonly Random random = new();
public ISimulationManager SimulationManager { get; set; }
private Vector3D lastTargetPosition;
public InfraredImagingGuidanceSystem(double maxAcceleration, double proportionalNavigationCoefficient, ISimulationManager simulationManager) : base(maxAcceleration, proportionalNavigationCoefficient)
{
SimulationManager = simulationManager;
lastTargetPosition = Vector3D.Zero;
}
/// <summary>
/// 更新引导系统
/// </summary>
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
{
base.Update(deltaTime, missilePosition, missileVelocity);
if (TryDetectTank(missilePosition, missileVelocity, out Vector3D tankPosition))
{
//根据目标当前位置和上一次位置计算目标速度
Vector3D targetVelocity = (tankPosition - lastTargetPosition) / deltaTime;
lastTargetPosition = tankPosition;
// 使用基类的比例控制算法
GuidanceAcceleration = CalculateProportionalNavigation(ProportionalNavigationCoefficient, missilePosition, missileVelocity, tankPosition, targetVelocity);
// 限制最大加速度
if (GuidanceAcceleration.Magnitude() > MaxAcceleration)
{
GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration;
}
HasGuidance = true;
}
else
{
HasGuidance = false;
}
}
/// <summary>
/// 探测目标
/// </summary>
private bool TryDetectTank(Vector3D missilePosition, Vector3D missileVelocity, out Vector3D tankPosition)
{
tankPosition = Vector3D.Zero;
foreach (var element in SimulationManager.GetElements())
{
if (element is Tank tank)
{
Vector3D toTarget = tank.Position - missilePosition;
double distance = toTarget.Magnitude();
if (distance <= MAX_DETECTION_RANGE)
{
double angle = Math.Acos(Vector3D.DotProduct(toTarget.Normalize(), missileVelocity.Normalize()));
if (angle <= FIELD_OF_VIEW / 2)
{
double snr = CalculateSNR(tank, distance);
if (snr > RECOGNITION_SNR_THRESHOLD)
{
tankPosition = tank.Position;
return true;
}
}
}
}
}
return false;
}
/// <summary>
/// 获取制导系统状态
/// </summary>
public override string GetStatus()
{
return base.GetStatus() + $", GuidanceAcceleration: {GuidanceAcceleration}, " +
$"Tank Position: {lastTargetPosition}";
}
/// <summary>
/// 计算信噪比
/// </summary>
private static double CalculateSNR(Tank tank, double distance)
{
double targetRadiation = tank.InfraredRadiationIntensity;
double backgroundRadiation = BACKGROUND_RADIATION_INTENSITY;
// 考虑距离衰减
double attenuationFactor = 1 / (distance * distance);
double signal = (targetRadiation - backgroundRadiation) * attenuationFactor;
double noise = backgroundRadiation * attenuationFactor;
return 10 * Math.Log10(signal / noise); // 转换为dB
}
}
}