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; } } ///