diff --git a/src/Models/MIssile/TerminalSensitiveSubmunition.cs b/src/Models/MIssile/TerminalSensitiveSubmunition.cs
index 8687e32..fb82b5d 100644
--- a/src/Models/MIssile/TerminalSensitiveSubmunition.cs
+++ b/src/Models/MIssile/TerminalSensitiveSubmunition.cs
@@ -78,8 +78,8 @@ namespace ActiveProtect.Models
detectionAngle = 0;
// 初始化传感器
- infraredDetector = new InfraredDetector(Position, Orientation, 100, 30);
- radiometer = new MillimeterWaveRadiometer(this, 3); // 毫米波辐射计,工作波段3mm
+ infraredDetector = new InfraredDetector(this, 500, 5); // 红外探测器,探测距离 500 米,视场角5度
+ radiometer = new MillimeterWaveRadiometer(this, 3, 5); // 毫米波辐射计,工作波段3mm,扫描视场角5度
altimeter = new MillimeterWaveAltimeter(this, 1000, 0.1); // 毫米波测高仪,测量精度0.1米
rangefinder = new LaserRangefinder(Position, Orientation, 1000, 1000);
}
@@ -177,6 +177,11 @@ namespace ActiveProtect.Models
// 激活毫米波辐射计
radiometer.Activate();
}
+ if(!infraredDetector.IsActive)
+ {
+ // 激活红外探测器
+ infraredDetector.Activate();
+ }
Velocity = new Vector3D(0, -VerticalDescentSpeed, 0);
GuidanceAcceleration = Vector3D.Zero;
@@ -202,7 +207,10 @@ namespace ActiveProtect.Models
Math.Sin(spiralAngle) * Math.Sin(ScanAngle)
);
- if (radiometer.GetSensorData() is RadiometerSensorData radiometerData && radiometerData.IsTargetDetected)
+ bool isRadiationDetected = radiometer.GetSensorData() is RadiometerSensorData radiometerData && radiometerData.IsTargetDetected;
+ bool isInfraredDetected = infraredDetector.GetSensorData() is InfraredSensorData infraredData && infraredData.IsTargetDetected;
+
+ if (isRadiationDetected || isInfraredDetected)
{
double currentTime = SimulationManager.CurrentTime;
if (lastDetectionTime == null)
@@ -265,14 +273,15 @@ namespace ActiveProtect.Models
///
/// 检测目标
///
- /// 是否检测到目标
- public bool DetectTarget()
+ /// 视场角
+ /// 在扫描方向上是否检测到目标
+ public bool DetectTarget(double fieldOfView)
{
Vector3D targetPosition = SimulationManager.GetEntityById(MissileProperties.TargetId).Position;
Vector3D toTarget = (targetPosition - Position).Normalize();
- // 检查目标是否在扫描线上
- return Vector3D.DotProduct(scanDirection, toTarget) > Math.Cos(5 * Math.PI / 180); // 允许5度的误差
+ // 检查目标是否在扫描视场内
+ return Vector3D.DotProduct(scanDirection, toTarget) > Math.Cos(fieldOfView * Math.PI / 180);
}
///
diff --git a/src/Models/Sensor/InfraredDetector.cs b/src/Models/Sensor/InfraredDetector.cs
index 686cbff..2b8e18b 100644
--- a/src/Models/Sensor/InfraredDetector.cs
+++ b/src/Models/Sensor/InfraredDetector.cs
@@ -7,6 +7,11 @@ namespace ActiveProtect.Models
///
public class InfraredDetector : Sensor
{
+ ///
+ /// 探测辐射强度阈值,单位:W/Sr
+ ///
+ private const double DetectionRadiationIntensityThreshold = 50;
+
///
/// 探测范围
///
@@ -17,18 +22,29 @@ namespace ActiveProtect.Models
///
public double FieldOfView { get; set; }
+ ///
+ /// 末敏弹
+ ///
+ private readonly TerminalSensitiveSubmunition submunition;
+
+ ///
+ /// 红外探测器数据
+ ///
+ private InfraredSensorData sensorData;
+
///
/// 构造函数
///
- /// 探测器的位置
- /// 探测器的朝向
+ /// 末敏弹
/// 探测范围
/// 视场角
- public InfraredDetector(Vector3D position, Orientation orientation, double detectionRange, double fieldOfView)
- : base(position, orientation)
+ public InfraredDetector(TerminalSensitiveSubmunition submunition, double detectionRange, double fieldOfView)
+ : base(submunition.Position, submunition.Orientation)
{
DetectionRange = detectionRange;
FieldOfView = fieldOfView;
+ this.submunition = submunition;
+ sensorData = new InfraredSensorData();
}
///
@@ -38,6 +54,30 @@ namespace ActiveProtect.Models
public override void Update(double deltaTime)
{
// 实现红外探测器的更新逻辑
+ if (IsActive)
+ {
+ // 获取当前方向上的红外辐射强度
+ double currentDirectionRadiationIntensity = GetCurrentDirectionRadiationIntensity();
+ // 如果辐射强度大于探测阈值,则认为检测到目标
+ if (currentDirectionRadiationIntensity >= DetectionRadiationIntensityThreshold)
+ {
+ sensorData.IsTargetDetected = true;
+ }
+ else
+ {
+ sensorData.IsTargetDetected = false;
+ }
+ }
+ }
+
+ ///
+ /// 获取当前方向上的红外辐射强度
+ ///
+ /// 当前方向上的红外辐射强度
+ private double GetCurrentDirectionRadiationIntensity()
+ {
+ // 获取当前方向上的辐射强度,如果检测到目标,则返回目标的辐射强度,否则返回0
+ return submunition.DetectTarget(FieldOfView) ? 100 : 0;
}
///
@@ -47,7 +87,7 @@ namespace ActiveProtect.Models
public override SensorData GetSensorData()
{
// 返回红外探测器的数据
- return new InfraredSensorData();
+ return sensorData;
}
}
diff --git a/src/Models/Sensor/MillimeterWaveRadiometer.cs b/src/Models/Sensor/MillimeterWaveRadiometer.cs
index a2b5468..c611f10 100644
--- a/src/Models/Sensor/MillimeterWaveRadiometer.cs
+++ b/src/Models/Sensor/MillimeterWaveRadiometer.cs
@@ -12,6 +12,9 @@ namespace ActiveProtect.Models
///
public double Wavelength { get; set; }
+ //扫描视场角,默认 5度
+ private double FieldOfView;
+
///
/// 辐射温度差检测阈值,辐射计高温物体与低温物体的检测温差,单位K,默认 100K;
/// 对于金属目标,与草地的典型温差为170~230K,砂石地 120~150K
@@ -20,7 +23,7 @@ namespace ActiveProtect.Models
///
public double DetectionTemperatureDifferenceThreshold { get; set; } = 100;
- private double lastDetectionTemperature = 0;
+ private double lastDetectionTemperature;
///
/// 毫米波辐射计传感器数据
@@ -36,10 +39,11 @@ namespace ActiveProtect.Models
/// 辐射计的朝向
/// 工作波段
/// 辐射温差检测阈值
- public MillimeterWaveRadiometer(TerminalSensitiveSubmunition submunition, double wavelength)
+ public MillimeterWaveRadiometer(TerminalSensitiveSubmunition submunition, double wavelength, double fieldOfView)
: base(submunition.Position, submunition.Orientation)
{
Wavelength = wavelength;
+ FieldOfView = fieldOfView;
lastDetectionTemperature = 0;
sensorData = new RadiometerSensorData();
this.submunition = submunition;
@@ -75,7 +79,7 @@ namespace ActiveProtect.Models
private double GetCurrentDirectionRadiationTemperature()
{
// 获取当前方向上的辐射温度,如果检测到目标,则返回天空背景辐射的反射温度,否则返回300K
- return submunition.DetectTarget() ? 90 : 300;
+ return submunition.DetectTarget(FieldOfView) ? 90 : 300;
}
///
diff --git a/src/Models/Sensor/SensorData.cs b/src/Models/Sensor/SensorData.cs
index e84b29c..f98a82a 100644
--- a/src/Models/Sensor/SensorData.cs
+++ b/src/Models/Sensor/SensorData.cs
@@ -25,9 +25,9 @@ namespace ActiveProtect.Models
public double Temperature { get; set; }
///
- /// 目标方向(如果检测到目标)
+ /// 是否检测到目标
///
- public Vector3D? TargetDirection { get; set; }
+ public bool IsTargetDetected { get; set; }
}
///