From a5c0bfc3d98c7871d3dcbfad980aae6ce4aa0d34 Mon Sep 17 00:00:00 2001 From: Tian jianyong <11429339@qq.com> Date: Sun, 27 Oct 2024 13:56:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=BA=A2=E5=A4=96=E6=88=90?= =?UTF-8?q?=E5=83=8F=E6=9C=AB=E5=88=B6=E5=AF=BC=E5=AF=BC=E5=BC=B9=E5=92=8C?= =?UTF-8?q?=E6=AF=AB=E7=B1=B3=E6=B3=A2=E6=9C=AB=E5=88=B6=E5=AF=BC=E5=AF=BC?= =?UTF-8?q?=E5=BC=B9=E7=9A=84=E5=85=B7=E4=BD=93=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Docs/{Seeker.md => DesignSeeker.md} | 0 Models/BasicGuidanceSystem.cs | 29 ++++++- Models/InfraredCommandGuidanceSystem.cs | 16 +--- Models/InfraredCommandGuidedMissile.cs | 10 +++ Models/InfraredImagingGuidanceSystem.cs | 64 ++++++++++---- .../InfraredImagingTerminalGuidedMissile.cs | 57 +++++++++---- Models/InfraredTracker.cs | 17 +++- Models/LaserBeamRider.cs | 2 + Models/LaserBeamRiderGuidanceSystem.cs | 8 +- Models/LaserBeamRiderMissile.cs | 2 +- Models/LaserSemiActiveGuidanceSystem.cs | 8 +- Models/LaserSemiActiveGuidedMissile.cs | 2 +- Models/MillimeterWaveGuidanceSystem.cs | 77 +++++++++++------ Models/MillimeterWaveTerminalGuidedMissile.cs | 54 ++++++++---- Models/Tank.cs | 12 +++ Program.cs | 42 +++++++++- README.md | 83 +++++++++++++------ SimulationEnvironment/SimulationConfig.cs | 13 ++- SimulationEnvironment/SimulationEvents.cs | 9 +- SimulationEnvironment/SimulationManager.cs | 31 ++++--- 20 files changed, 389 insertions(+), 147 deletions(-) rename Docs/{Seeker.md => DesignSeeker.md} (100%) diff --git a/Docs/Seeker.md b/Docs/DesignSeeker.md similarity index 100% rename from Docs/Seeker.md rename to Docs/DesignSeeker.md diff --git a/Models/BasicGuidanceSystem.cs b/Models/BasicGuidanceSystem.cs index 4762f1a..00f3a87 100644 --- a/Models/BasicGuidanceSystem.cs +++ b/Models/BasicGuidanceSystem.cs @@ -17,17 +17,44 @@ namespace ActiveProtect.Models /// public class BasicGuidanceSystem : IGuidanceSystem { + /// + /// 是否有制导 + /// public bool HasGuidance { get; protected set; } + + /// + /// 最大加速度 + /// + public double MaxAcceleration { get; set; } + + /// + /// 制导系数 + /// + public double ProportionalNavigationCoefficient { get; set; } + + /// + /// 导弹位置 + /// protected Vector3D Position { get; set; } + + /// + /// 导弹速度 + /// protected Vector3D Velocity { get; set; } + + /// + /// 制导加速度 + /// protected Vector3D GuidanceAcceleration { get; set; } - public BasicGuidanceSystem() + public BasicGuidanceSystem(double maxAcceleration, double proportionalNavigationCoefficient) { HasGuidance = false; GuidanceAcceleration = Vector3D.Zero; Position = Vector3D.Zero; Velocity = Vector3D.Zero; + MaxAcceleration = maxAcceleration; + ProportionalNavigationCoefficient = proportionalNavigationCoefficient; } /// diff --git a/Models/InfraredCommandGuidanceSystem.cs b/Models/InfraredCommandGuidanceSystem.cs index 6c0998d..ad3462c 100644 --- a/Models/InfraredCommandGuidanceSystem.cs +++ b/Models/InfraredCommandGuidanceSystem.cs @@ -15,27 +15,15 @@ namespace ActiveProtect.Models private const double TurnRateSmoothingFactor = 0.5; // 转向速率平滑因子,越大越平滑,0.1~0.5 private const double LeadTimeFactor = 0.3; // 提前量因子,单位:秒,越大提前量越大,一般取0.5秒 - /// - /// 制导系数 - /// - public double GuidanceCoefficient { get; set; } - - /// - /// 最大加速度 - /// - public double MaxAcceleration { get; set; } - /// /// 构造函数 /// public InfraredCommandGuidanceSystem(double maxAcceleration, double guidanceCoefficient) - : base() + : base(maxAcceleration, guidanceCoefficient) { lastTrackerToMissileVector = Vector3D.Zero; lastTrackerToTargetVector = Vector3D.Zero; lastDesiredDirection = Vector3D.Zero; - MaxAcceleration = maxAcceleration; - GuidanceCoefficient = guidanceCoefficient; turnRate = 0; } @@ -89,7 +77,7 @@ namespace ActiveProtect.Models double turnAngle = Math.Acos(Vector3D.DotProduct(currentDirection, desiredDirectionWithLead)); // 计算制导加速度 - double accelerationMagnitude = GuidanceCoefficient * turnAngle * Velocity.Magnitude(); + double accelerationMagnitude = ProportionalNavigationCoefficient * turnAngle * Velocity.Magnitude(); GuidanceAcceleration = Vector3D.CrossProduct(turnAxis, currentDirection) * accelerationMagnitude; // 限制最大加速度 diff --git a/Models/InfraredCommandGuidedMissile.cs b/Models/InfraredCommandGuidedMissile.cs index 12e0da5..f9dd932 100644 --- a/Models/InfraredCommandGuidedMissile.cs +++ b/Models/InfraredCommandGuidedMissile.cs @@ -164,6 +164,14 @@ namespace ActiveProtect.Models SimulationManager.PublishEvent(new InfraredGuidanceMissileLightEvent { RadiationPower = this.RadiationPower, SenderId = this.Id }); } + /// + /// 熄灭红外热源 + /// + public void LightOffInfraredSource() + { + SimulationManager.PublishEvent(new InfraredGuidanceMissileLightOffEvent { SenderId = this.Id }); + } + public override void Activate() { base.Activate(); @@ -174,6 +182,8 @@ namespace ActiveProtect.Models public override void Deactivate() { base.Deactivate(); + // 熄灭红外热源 + LightOffInfraredSource(); // 取消订阅红外指令制导事件 SimulationManager.UnsubscribeFromEvent(HandleGuidanceCommand); } diff --git a/Models/InfraredImagingGuidanceSystem.cs b/Models/InfraredImagingGuidanceSystem.cs index 4df3c54..8dc5864 100644 --- a/Models/InfraredImagingGuidanceSystem.cs +++ b/Models/InfraredImagingGuidanceSystem.cs @@ -9,15 +9,19 @@ namespace ActiveProtect.Models public class InfraredImagingGuidanceSystem : BasicGuidanceSystem { private const double MAX_DETECTION_RANGE = 5000; // 最大探测范围(米) - private const double FIELD_OF_VIEW = Math.PI / 6; // 视场角(弧度) + 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 Random(); + private readonly Random random = new(); public ISimulationManager SimulationManager { get; set; } + private Vector3D lastTargetPosition; - public InfraredImagingGuidanceSystem(ISimulationManager simulationManager) : base() + public InfraredImagingGuidanceSystem(double maxAcceleration, double proportionalNavigationCoefficient, ISimulationManager simulationManager) : base(maxAcceleration, proportionalNavigationCoefficient) { SimulationManager = simulationManager; + lastTargetPosition = Vector3D.Zero; } /// @@ -27,17 +31,18 @@ namespace ActiveProtect.Models { base.Update(deltaTime, missilePosition, missileVelocity); - if (TryDetectTarget(missilePosition, missileVelocity, out Vector3D targetPosition)) + if (TryDetectTank(missilePosition, missileVelocity, out Vector3D tankPosition)) { - Vector3D toTarget = targetPosition - missilePosition; - Vector3D desiredVelocity = toTarget.Normalize() * missileVelocity.Magnitude(); - GuidanceAcceleration = (desiredVelocity - missileVelocity) / deltaTime; + //根据目标当前位置和上一次位置计算目标速度 + Vector3D targetVelocity = (tankPosition - lastTargetPosition) / deltaTime; + lastTargetPosition = tankPosition; + // 使用基类的比例控制算法 + GuidanceAcceleration = CalculateProportionalNavigation(ProportionalNavigationCoefficient, missilePosition, missileVelocity, tankPosition, targetVelocity); // 限制最大加速度 - double maxAcceleration = 25; // 25 m/s² - if (GuidanceAcceleration.Magnitude() > maxAcceleration) + if (GuidanceAcceleration.Magnitude() > MaxAcceleration) { - GuidanceAcceleration = GuidanceAcceleration.Normalize() * maxAcceleration; + GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration; } HasGuidance = true; @@ -49,11 +54,11 @@ namespace ActiveProtect.Models } /// - /// 尝试探测目标 + /// 探测目标 /// - private bool TryDetectTarget(Vector3D missilePosition, Vector3D missileVelocity, out Vector3D targetPosition) + private bool TryDetectTank(Vector3D missilePosition, Vector3D missileVelocity, out Vector3D tankPosition) { - targetPosition = Vector3D.Zero; + tankPosition = Vector3D.Zero; foreach (var element in SimulationManager.GetElements()) { @@ -65,12 +70,12 @@ namespace ActiveProtect.Models if (distance <= MAX_DETECTION_RANGE) { double angle = Math.Acos(Vector3D.DotProduct(toTarget.Normalize(), missileVelocity.Normalize())); - if (angle <= FIELD_OF_VIEW / 2) { - if (random.NextDouble() < TARGET_RECOGNITION_PROBABILITY) + double snr = CalculateSNR(tank, distance); + if (snr > RECOGNITION_SNR_THRESHOLD) { - targetPosition = tank.Position; + tankPosition = tank.Position; return true; } } @@ -80,5 +85,32 @@ namespace ActiveProtect.Models return false; } + + /// + /// 获取制导系统状态 + /// + public override string GetStatus() + { + return base.GetStatus() + $", GuidanceAcceleration: {GuidanceAcceleration}, " + + $"Tank Position: {lastTargetPosition}"; + } + + + /// + /// 计算信噪比 + /// + 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 + } } } diff --git a/Models/InfraredImagingTerminalGuidedMissile.cs b/Models/InfraredImagingTerminalGuidedMissile.cs index 68d0595..398c250 100644 --- a/Models/InfraredImagingTerminalGuidedMissile.cs +++ b/Models/InfraredImagingTerminalGuidedMissile.cs @@ -8,7 +8,10 @@ namespace ActiveProtect.Models /// public class InfraredImagingTerminalGuidedMissile : MissileBase { - private enum MissileStage + /// + /// 红外成像末制导导弹阶段 + /// + private enum IRTG_Stage { Launch, Cruise, @@ -17,65 +20,81 @@ namespace ActiveProtect.Models SelfDestruct } - private MissileStage currentStage; + + private IRTG_Stage currentStage; private readonly InfraredImagingGuidanceSystem guidanceSystem; private const double TERMINAL_GUIDANCE_DISTANCE = 1000; // 末制导开始距离(米) + /// + /// 红外成像末制导导弹构造函数 + /// public InfraredImagingTerminalGuidedMissile(MissileConfig config, ISimulationManager manager) : base(config, manager) { Type = MissileType.InfraredImagingTerminalGuidance; - currentStage = MissileStage.Launch; - guidanceSystem = new InfraredImagingGuidanceSystem(manager); + currentStage = IRTG_Stage.Launch; + guidanceSystem = new InfraredImagingGuidanceSystem(config.MaxAcceleration, config.ProportionalNavigationCoefficient, manager); } + /// + /// 更新红外成像末制导导弹 + /// public override void Update(double deltaTime) { base.Update(deltaTime); switch (currentStage) { - case MissileStage.Launch: + case IRTG_Stage.Launch: UpdateLaunchStage(deltaTime); break; - case MissileStage.Cruise: + case IRTG_Stage.Cruise: UpdateCruiseStage(deltaTime); break; - case MissileStage.TerminalGuidance: + case IRTG_Stage.TerminalGuidance: UpdateTerminalGuidanceStage(deltaTime); break; - case MissileStage.Explode: + case IRTG_Stage.Explode: Explode(); break; - case MissileStage.SelfDestruct: + case IRTG_Stage.SelfDestruct: SelfDestruct(); break; } if (ShouldSelfDestruct()) { - currentStage = MissileStage.SelfDestruct; + currentStage = IRTG_Stage.SelfDestruct; } } + /// + /// 更新发射阶段 + /// private void UpdateLaunchStage(double deltaTime) { // 实现发射阶段逻辑 - if (FlightTime > 5) // 假设发射阶段持续5秒 + if (FlightTime > 0.1) // 假设发射阶段持续0.1秒 { - currentStage = MissileStage.Cruise; + currentStage = IRTG_Stage.Cruise; } } + /// + /// 更新巡航阶段 + /// private void UpdateCruiseStage(double deltaTime) { // 实现巡航阶段逻辑 if (DistanceToTarget <= TERMINAL_GUIDANCE_DISTANCE) { - currentStage = MissileStage.TerminalGuidance; + currentStage = IRTG_Stage.TerminalGuidance; } } + /// + /// 更新末制导阶段 + /// private void UpdateTerminalGuidanceStage(double deltaTime) { guidanceSystem.Update(deltaTime, Position, Velocity); @@ -83,19 +102,25 @@ namespace ActiveProtect.Models if (DistanceToTarget <= ExplosionRadius) { - currentStage = MissileStage.Explode; + currentStage = IRTG_Stage.Explode; } } + /// + /// 爆炸 + /// protected override void Explode() { base.Explode(); - currentStage = MissileStage.Explode; + currentStage = IRTG_Stage.Explode; } + /// + /// 获取导弹状态 + /// public override string GetStatus() { - return base.GetStatus() + $"\n 当前阶段: {currentStage}"; + return base.GetStatus() + $"\n 当前阶段: {currentStage}" + guidanceSystem.GetStatus(); } } } diff --git a/Models/InfraredTracker.cs b/Models/InfraredTracker.cs index 9a64f87..d1ba957 100644 --- a/Models/InfraredTracker.cs +++ b/Models/InfraredTracker.cs @@ -49,10 +49,9 @@ namespace ActiveProtect.Models if (TrackedMissileId == null || TargetId == null) return; var target = SimulationManager.GetEntityById(TargetId); - var missile = SimulationManager.GetEntityById(TrackedMissileId) as InfraredCommandGuidedMissile; - if (missile == null || target == null) return; - + if (SimulationManager.GetEntityById(TrackedMissileId) is not InfraredCommandGuidedMissile missile || target == null) return; + // 计算导弹到测角仪的距离 double distanceToMissile = Vector3D.Distance(Position, missile.Position); @@ -97,7 +96,6 @@ namespace ActiveProtect.Models SenderId = senderId }; SimulationManager.PublishEvent(evt); - Console.WriteLine($"55发布制导指令事件: {evt}"); } /// @@ -109,6 +107,15 @@ namespace ActiveProtect.Models TrackedMissileId ??= evt.SenderId; } + /// + /// 处理红外指令制导导弹熄灭红外热源事件 + /// + private void OnInfraredGuidanceMissileLightOff(InfraredGuidanceMissileLightOffEvent evt) + { + // 处理导弹熄灭红外热源事件 + if (evt.SenderId == TrackedMissileId) StopTracking(); + } + /// /// 激活红外测角仪 /// @@ -116,6 +123,7 @@ namespace ActiveProtect.Models { base.Activate(); SimulationManager.SubscribeToEvent(OnInfraredGuidanceMissileLight); + SimulationManager.SubscribeToEvent(OnInfraredGuidanceMissileLightOff); } /// @@ -125,6 +133,7 @@ namespace ActiveProtect.Models { base.Deactivate(); SimulationManager.UnsubscribeFromEvent(OnInfraredGuidanceMissileLight); + SimulationManager.UnsubscribeFromEvent(OnInfraredGuidanceMissileLightOff); } /// diff --git a/Models/LaserBeamRider.cs b/Models/LaserBeamRider.cs index 86c455f..b7935b8 100644 --- a/Models/LaserBeamRider.cs +++ b/Models/LaserBeamRider.cs @@ -71,6 +71,8 @@ namespace ActiveProtect.Models { IsActive = true; Console.WriteLine($"激光驾束仪 {Id} 已激活"); + // 激光驾束仪开始照射 + StartBeamIllumination(); } base.Activate(); } diff --git a/Models/LaserBeamRiderGuidanceSystem.cs b/Models/LaserBeamRiderGuidanceSystem.cs index 89649ae..80ca862 100644 --- a/Models/LaserBeamRiderGuidanceSystem.cs +++ b/Models/LaserBeamRiderGuidanceSystem.cs @@ -41,11 +41,6 @@ namespace ActiveProtect.Models /// private Vector3D IntegralError = Vector3D.Zero; - /// - /// 比例导引系数 - /// - private double ProportionalNavigationCoefficient { get; set; } - /// /// 激光照射是否开启 /// @@ -55,14 +50,13 @@ namespace ActiveProtect.Models /// /// 构造函数 /// - public LaserBeamRiderGuidanceSystem() + public LaserBeamRiderGuidanceSystem(double maxAcceleration, double guidanceCoefficient) : base(maxAcceleration, guidanceCoefficient) { LaserSourcePosition = Vector3D.Zero; LaserDirection = Vector3D.Zero; LaserPower = 0; HasGuidance = false; LastGuidanceAcceleration = Vector3D.Zero; - ProportionalNavigationCoefficient = 3; } /// diff --git a/Models/LaserBeamRiderMissile.cs b/Models/LaserBeamRiderMissile.cs index 2055fda..f634873 100644 --- a/Models/LaserBeamRiderMissile.cs +++ b/Models/LaserBeamRiderMissile.cs @@ -33,7 +33,7 @@ namespace ActiveProtect.Models public LaserBeamRiderMissile(MissileConfig config, ISimulationManager manager) : base(config, manager) { - LaserBeamRiderGuidanceSystem = new LaserBeamRiderGuidanceSystem(); + LaserBeamRiderGuidanceSystem = new LaserBeamRiderGuidanceSystem(config.MaxAcceleration, config.ProportionalNavigationCoefficient); currentStage = LBRM_Stage.Launch; } diff --git a/Models/LaserSemiActiveGuidanceSystem.cs b/Models/LaserSemiActiveGuidanceSystem.cs index d58705f..990f7db 100644 --- a/Models/LaserSemiActiveGuidanceSystem.cs +++ b/Models/LaserSemiActiveGuidanceSystem.cs @@ -44,23 +44,17 @@ namespace ActiveProtect.Models /// private double LaserDivergenceAngle { get; set; } - /// - /// 比例导航系数 - /// - private double ProportionalNavigationCoefficient { get; set; } - /// /// 构造函数 /// - public LaserSemiActiveGuidanceSystem() + public LaserSemiActiveGuidanceSystem(double maxAcceleration, double guidanceCoefficient) : base(maxAcceleration, guidanceCoefficient) { TargetPosition = Vector3D.Zero; TargetVelocity = Vector3D.Zero; LaserIlluminationOn = false; LaserDesignatorPosition = Vector3D.Zero; LaserPower = 0; - ProportionalNavigationCoefficient = 4; } /// diff --git a/Models/LaserSemiActiveGuidedMissile.cs b/Models/LaserSemiActiveGuidedMissile.cs index ba8633f..a479ef3 100644 --- a/Models/LaserSemiActiveGuidedMissile.cs +++ b/Models/LaserSemiActiveGuidedMissile.cs @@ -32,7 +32,7 @@ namespace ActiveProtect.Models public LaserSemiActiveGuidedMissile(MissileConfig config, ISimulationManager manager) : base(config, manager) { - LaserGuidanceSystem = new LaserSemiActiveGuidanceSystem(); + LaserGuidanceSystem = new LaserSemiActiveGuidanceSystem(config.MaxAcceleration, config.ProportionalNavigationCoefficient); currentStage = LSAGM_Stage.Launch; } diff --git a/Models/MillimeterWaveGuidanceSystem.cs b/Models/MillimeterWaveGuidanceSystem.cs index bbdbcd4..64bdc35 100644 --- a/Models/MillimeterWaveGuidanceSystem.cs +++ b/Models/MillimeterWaveGuidanceSystem.cs @@ -8,18 +8,25 @@ namespace ActiveProtect.Models /// public class MillimeterWaveGuidanceSystem : BasicGuidanceSystem { - private const double MAX_DETECTION_RANGE = 8000; // 最大探测范围(米) - private const double FIELD_OF_VIEW = Math.PI / 4; // 视场角(弧度) + private const double MAX_DETECTION_RANGE = 5000; // 最大探测范围(米) + private const double FIELD_OF_VIEW = Math.PI / 4; // 视场角(弧度), 45度 private const double TARGET_RECOGNITION_PROBABILITY = 0.95; // 目标识别概率 private const double WAVE_FREQUENCY = 94e9; // 毫米波频率(Hz), 94GHz private const double PULSE_DURATION = 1e-6; // 脉冲持续时间(秒) + private const double RECOGNITION_SNR_THRESHOLD = 6; // 识别目标信噪比阈值, 单位dB + + private readonly Random random = new(); + private Vector3D lastTargetPosition; - private readonly Random random = new Random(); public ISimulationManager SimulationManager { get; set; } - public MillimeterWaveGuidanceSystem(ISimulationManager simulationManager) : base() + /// + /// 毫米波导引头系统构造函数 + /// + public MillimeterWaveGuidanceSystem(double maxAcceleration, double guidanceCoefficient, ISimulationManager simulationManager) : base(maxAcceleration, guidanceCoefficient) { SimulationManager = simulationManager; + lastTargetPosition = Vector3D.Zero; } /// @@ -29,17 +36,18 @@ namespace ActiveProtect.Models { base.Update(deltaTime, missilePosition, missileVelocity); - if (TryDetectTarget(missilePosition, missileVelocity, out Vector3D targetPosition)) + if (TryDetectTank(missilePosition, missileVelocity, out Vector3D tankPosition)) { - Vector3D toTarget = targetPosition - missilePosition; - Vector3D desiredVelocity = toTarget.Normalize() * missileVelocity.Magnitude(); - GuidanceAcceleration = (desiredVelocity - missileVelocity) / deltaTime; + //根据目标当前位置和上一次位置计算目标速度 + Vector3D targetVelocity = (tankPosition - lastTargetPosition) / deltaTime; + lastTargetPosition = tankPosition; - // 限制最大加速度 - double maxAcceleration = 30; // 30 m/s² - if (GuidanceAcceleration.Magnitude() > maxAcceleration) + // 使用基类的比例控制算法 + GuidanceAcceleration = CalculateProportionalNavigation(ProportionalNavigationCoefficient, missilePosition, missileVelocity, tankPosition, targetVelocity); + + if (GuidanceAcceleration.Magnitude() > MaxAcceleration) { - GuidanceAcceleration = GuidanceAcceleration.Normalize() * maxAcceleration; + GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration; } HasGuidance = true; @@ -53,7 +61,7 @@ namespace ActiveProtect.Models /// /// 尝试探测目标 /// - private bool TryDetectTarget(Vector3D missilePosition, Vector3D missileVelocity, out Vector3D targetPosition) + private bool TryDetectTank(Vector3D missilePosition, Vector3D missileVelocity, out Vector3D targetPosition) { targetPosition = Vector3D.Zero; @@ -71,10 +79,10 @@ namespace ActiveProtect.Models if (angle <= FIELD_OF_VIEW / 2) { // 模拟毫米波探测 - double signalStrength = CalculateSignalStrength(distance); - double detectionProbability = signalStrength * TARGET_RECOGNITION_PROBABILITY; + double snr = CalculateSNR(distance, tank.RadarCrossSection); + Console.WriteLine($" 80信噪比 {snr}"); - if (random.NextDouble() < detectionProbability) + if(snr > RECOGNITION_SNR_THRESHOLD && random.NextDouble() < TARGET_RECOGNITION_PROBABILITY) { targetPosition = tank.Position; return true; @@ -88,20 +96,41 @@ namespace ActiveProtect.Models } /// - /// 计算信号强度 + /// 获取导弹状态 /// - private double CalculateSignalStrength(double distance) + public override string GetStatus() { - // 简化的雷达方程 + return base.GetStatus() + $", Target Position: {lastTargetPosition}"; + } + + /// + /// 计算信噪比 + /// + private static double CalculateSNR(double distance, double radarCrossSection) + { + // 雷达参数 double transmitPower = 100; // 发射功率(W) - double antennaGain = 30; // 天线增益(dB) + double antennaGain = Math.Pow(10, 30/10); // 天线增益(线性值,从dB转换) double wavelength = 3e8 / WAVE_FREQUENCY; // 波长(m) - double radarCrossSection = 10; // 目标雷达截面积(m^2) + double bandwidth = 1e6; // 接收机带宽(Hz),假设为1MHz + double noiseFigure = Math.Pow(10, 3/10); // 噪声系数(线性值,假设为3dB) - double signalStrength = (transmitPower * Math.Pow(10, antennaGain/10) * Math.Pow(wavelength, 2) * radarCrossSection) - / (Math.Pow(4 * Math.PI, 3) * Math.Pow(distance, 4)); + // 常量 + double k = 1.38e-23; // 玻尔兹曼常数 + double T0 = 290; // 标准噪声温度(K) - return Math.Min(1, signalStrength); // 归一化到[0, 1]范围 + // 计算接收信号功率 + double signalPower = (transmitPower * Math.Pow(antennaGain, 2) * Math.Pow(wavelength, 2) * radarCrossSection) + / (Math.Pow(4 * Math.PI, 3) * Math.Pow(distance, 4)); + + // 计算噪声功率 + double noisePower = k * T0 * bandwidth * noiseFigure; + + // 计算信噪比 + double snr = signalPower / noisePower; + + // 转换为dB + return 10 * Math.Log10(snr); } } } diff --git a/Models/MillimeterWaveTerminalGuidedMissile.cs b/Models/MillimeterWaveTerminalGuidedMissile.cs index 7e9bf5e..fa555bf 100644 --- a/Models/MillimeterWaveTerminalGuidedMissile.cs +++ b/Models/MillimeterWaveTerminalGuidedMissile.cs @@ -8,7 +8,10 @@ namespace ActiveProtect.Models /// public class MillimeterWaveTerminalGuidedMissile : MissileBase { - private enum MissileStage + /// + /// 毫米波末制导导弹阶段 + /// + private enum MWTG_Stage { Launch, Cruise, @@ -17,67 +20,82 @@ namespace ActiveProtect.Models SelfDestruct } - private MissileStage currentStage; + private MWTG_Stage currentStage; private readonly MillimeterWaveGuidanceSystem guidanceSystem; private const double TERMINAL_GUIDANCE_DISTANCE = 8000; // 末制导开始距离(米) + /// + /// 毫米波末制导导弹构造函数 + /// public MillimeterWaveTerminalGuidedMissile(MissileConfig config, ISimulationManager manager) : base(config, manager) { Type = MissileType.MillimeterWaveTerminalGuidance; - currentStage = MissileStage.Launch; - guidanceSystem = new MillimeterWaveGuidanceSystem(manager); + currentStage = MWTG_Stage.Launch; + guidanceSystem = new MillimeterWaveGuidanceSystem(config.MaxAcceleration, config.ProportionalNavigationCoefficient, manager); } + /// + /// 更新毫米波末制导导弹 + /// public override void Update(double deltaTime) { base.Update(deltaTime); switch (currentStage) { - case MissileStage.Launch: + case MWTG_Stage.Launch: UpdateLaunchStage(deltaTime); break; - case MissileStage.Cruise: + case MWTG_Stage.Cruise: UpdateCruiseStage(deltaTime); break; - case MissileStage.TerminalGuidance: + case MWTG_Stage.TerminalGuidance: UpdateTerminalGuidanceStage(deltaTime); break; - case MissileStage.Explode: + case MWTG_Stage.Explode: Explode(); break; - case MissileStage.SelfDestruct: + case MWTG_Stage.SelfDestruct: SelfDestruct(); break; } if (ShouldSelfDestruct()) { - currentStage = MissileStage.SelfDestruct; + currentStage = MWTG_Stage.SelfDestruct; } } + /// + /// 更新发射阶段 + /// private void UpdateLaunchStage(double deltaTime) { // 实现发射阶段逻辑 if (FlightTime > 3) // 假设发射阶段持续3秒 { - currentStage = MissileStage.Cruise; + currentStage = MWTG_Stage.Cruise; Console.WriteLine($"导弹 {Id} 进入巡航阶段"); } } + /// + /// 更新巡航阶段 + /// private void UpdateCruiseStage(double deltaTime) { // 实现巡航阶段逻辑 if (DistanceToTarget <= TERMINAL_GUIDANCE_DISTANCE) { - currentStage = MissileStage.TerminalGuidance; + currentStage = MWTG_Stage.TerminalGuidance; Console.WriteLine($"导弹 {Id} 进入末制导阶段"); } } + /// + /// 更新末制导阶段 + /// private void UpdateTerminalGuidanceStage(double deltaTime) { guidanceSystem.Update(deltaTime, Position, Velocity); @@ -85,20 +103,26 @@ namespace ActiveProtect.Models if (DistanceToTarget <= ExplosionRadius) { - currentStage = MissileStage.Explode; + currentStage = MWTG_Stage.Explode; Console.WriteLine($"导弹 {Id} 进入爆炸阶段"); } } + /// + /// 爆炸 + /// protected override void Explode() { base.Explode(); - currentStage = MissileStage.Explode; + currentStage = MWTG_Stage.Explode; } + /// + /// 获取导弹状态 + /// public override string GetStatus() { - return base.GetStatus() + $"\n 当前阶段: {currentStage}"; + return base.GetStatus() + $"\n 当前阶段: {currentStage}, " + guidanceSystem.GetStatus(); } } } diff --git a/Models/Tank.cs b/Models/Tank.cs index df9e432..aa0eb7c 100644 --- a/Models/Tank.cs +++ b/Models/Tank.cs @@ -28,6 +28,16 @@ namespace ActiveProtect.Models /// public double CurrentArmor { get; private set; } + /// + /// 红外辐射强度 (W/sr) + /// + public double InfraredRadiationIntensity { get; set; } + + /// + /// 雷达截面积 (m^2) + /// + public double RadarCrossSection { get; set; } + /// /// 构造函数 /// @@ -40,6 +50,8 @@ namespace ActiveProtect.Models MaxSpeed = tankConfig.MaxSpeed; MaxArmor = tankConfig.MaxArmor; CurrentArmor = tankConfig.MaxArmor; + InfraredRadiationIntensity = tankConfig.InfraredRadiationIntensity; + RadarCrossSection = tankConfig.RadarCrossSection; IsActive = false; } diff --git a/Program.cs b/Program.cs index 3e33beb..b39336f 100644 --- a/Program.cs +++ b/Program.cs @@ -35,6 +35,8 @@ namespace ActiveProtect InitialSpeed = 20, MaxSpeed = 25, MaxArmor = 100, + InfraredRadiationIntensity = 150, + RadarCrossSection = 10, HasLaserWarner = false, HasLaserJammer = true } @@ -86,7 +88,7 @@ namespace ActiveProtect LaunchAcceleration = 50, MaxEngineBurnTime = 10, MaxAcceleration = 400, - ProportionalNavigationCoefficient = 3, + ProportionalNavigationCoefficient = 4, ExplosionRadius = 10, Mass = 50, Type = MissileType.LaserSemiActiveGuidance @@ -143,7 +145,43 @@ namespace ActiveProtect ProportionalNavigationCoefficient = 3, Mass = 50, Type = MissileType.InfraredCommandGuidance - } + }, + // 红外成像末制导导弹配置 + new() { + Id = "ITGM_1", + InitialPosition = new Vector3D(2000, 100, 100), + InitialOrientation = new Orientation(Math.PI, 0.0, 0), + InitialSpeed = 300, + MaxSpeed = 400, + TargetIndex = 0, + MaxFlightTime = 60, + MaxFlightDistance = 5000, + LaunchAcceleration = 50, + MaxEngineBurnTime = 10, + MaxAcceleration = 50, + ExplosionRadius = 1, + ProportionalNavigationCoefficient = 3, + Mass = 50, + Type = MissileType.InfraredImagingTerminalGuidance + }, + // 毫米波导引头制导导弹配置 + new() { + Id = "MMWG_1", + InitialPosition = new Vector3D(2000, 10, 100), + InitialOrientation = new Orientation(Math.PI, 0.0, 0), + InitialSpeed = 300, + MaxSpeed = 400, + TargetIndex = 0, + MaxFlightTime = 60, + MaxFlightDistance = 5000, + LaunchAcceleration = 50, + MaxEngineBurnTime = 10, + MaxAcceleration = 50, + ExplosionRadius = 1, + ProportionalNavigationCoefficient = 3, + Mass = 50, + Type = MissileType.MillimeterWaveTerminalGuidance + } }, // 配置红外测角仪 InfraredTrackerConfig = new InfraredTrackerConfig diff --git a/README.md b/README.md index d02ca2c..5998dcb 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,30 @@ ActiveProtect 是一个用于模拟激光制导导弹和防御系统的仿真环 ## 功能特性 -- 激光半主动制导导弹仿真 -- 激光驾束制导导弹仿真 -- 坦克和激光告警器仿真 -- 激光干扰器仿真 -- 可扩展的仿真框架 +### 组件仿真 + +- 激光半主动制导导弹 +- 激光驾束制导导弹 +- 红外指令制导导弹 +- 红外成像制导导弹 +- 毫米波末制导导弹 +- 末敏弹(母弹和子弹) +- 激光告警器 +- 激光干扰器 +- 激光指示器 +- 激光驾束仪 +- 毫米波测高仪 +- 毫米波辐射计 +- 坦克 + +### 可扩展的仿真框架 + +- 仿真管理器 +- 仿真元素基类 +- 仿真事件定义 +- 导弹基类 +- 导引系统基类 +- 传感器基类 ## Unity 兼容性 @@ -104,28 +123,44 @@ graph TD ```csharp ActiveProtect/ │ +├── Docs/ # 文档目录 +│ ├── Design.md # 设计文档 +│ └── DesignMissile.md # 导弹设计文档 +│ └── DesignSeeker.md # 导引头设计文档 +│ ├── Models/ # 仿真模型目录 -│ ├── BasicGuidanceSystem.cs # 基础制导系统类 -│ ├── ILaserIlluminatable.cs # 可被激光照射的接口定义 -│ ├── LaserBeamRider.cs # 激光驾束仪类 -│ ├── LaserBeamRiderGuidanceSystem.cs # 激光驾束制导系统类 -│ ├── LaserBeamRiderMissile.cs # 激光驾束导弹类 -│ ├── LaserDesignator.cs # 激光指示器类 -│ ├── LaserJammer.cs # 激光干扰器类 -│ ├── LaserSemiActiveGuidedMissile.cs # 激光半主动制导导弹类 -│ ├── LaserWarner.cs # 激光告警器类 -│ ├── MissileClass.cs # 导弹基类 -│ └── Tank.cs # 坦克模型类 +│ ├── BasicGuidanceSystem.cs # 基础制导系统类 +│ ├── Common.cs # 公共类 +│ │── InfraredCommandGuidanceSystem.cs # 红外指令制导系统类 +│ │── InfraredCommandGuidanceMissile.cs # 红外指令制导导弹类 +│ │── InfraredImagingGuidanceSystem.cs # 红外成像制导系统类 +│ │── InfraredImagingGuidanceMissile.cs # 红外成像制导导弹类 +│ │── ILaserIlluminatable.cs # 可被激光照射的接口定义 +│ │── LaserBeamRider.cs # 激光驾束仪类 +│ ├── LaserBeamRiderGuidanceSystem.cs # 激光驾束制导系统类 +│ ├── LaserBeamRiderMissile.cs # 激光驾束导弹类 +│ ├── LaserDesignator.cs # 激光指示器类 +│ ├── LaserJammer.cs # 激光干扰器类 +│ ├── LaserSemiActiveGuidanceSystem.cs # 激光半主动制导系统类 +│ ├── LaserSemiActiveGuidedMissile.cs # 激光半主动制导导弹类 +│ ├── LaserWarner.cs # 激光告警器类 +│ ├── MillimeterWaveGuidanceSystem.cs # 毫米波制导系统类 +│ ├── MillimeterWaveTerminalGuidedMissile.cs # 毫米波末制导导弹类 +│ ├── MissileBase.cs # 导弹基类 +│ ├── SensorBase.cs # 传感器基类 +│ ├── Tank.cs # 坦克模型类 +│ ├── TerminalSensitiveBomb.cs # 末敏弹(母弹)类 +│ ├── TerminalSensitiveBombBullet.cs # 末敏弹(子弹)类 │ -├── SimulationEnvironment/ # 仿真环境目录 -│ ├── SimulationConfig.cs # 仿真配置类 -│ ├── SimulationElement.cs # 仿真元素基类 -│ ├── SimulationEvents.cs # 仿真事件定义类 -│ └── SimulationManager.cs # 仿真管理器类 +├── SimulationEnvironment/ # 仿真环境目录 +│ ├── SimulationConfig.cs # 仿真配置类 +│ ├── SimulationElement.cs # 仿真元素基类 +│ ├── SimulationEvents.cs # 仿真事件定义类 +│ └── SimulationManager.cs # 真管理器类 │ -├── Program.cs # 程序入口点 -├── README.md # 项目说明文档 -└── Design.md # 设计文档 +├── Program.cs # 程序入口点 +├── README.md # 项目说明文档 +└── Design.md # 设计文档 ``` ## 如何运行 diff --git a/SimulationEnvironment/SimulationConfig.cs b/SimulationEnvironment/SimulationConfig.cs index 6d67b81..3c71e63 100644 --- a/SimulationEnvironment/SimulationConfig.cs +++ b/SimulationEnvironment/SimulationConfig.cs @@ -101,6 +101,16 @@ namespace ActiveProtect.SimulationEnvironment /// public double MaxArmor { get; set; } + /// + /// 红外辐射强度(W/sr) + /// + public double InfraredRadiationIntensity { get; set; } + + /// + /// 雷达截面积(m^2) + /// + public double RadarCrossSection { get; set; } + /// /// 是否装备激光告警器 /// @@ -137,6 +147,7 @@ namespace ActiveProtect.SimulationEnvironment MaxArmor = 0; HasLaserWarner = false; HasLaserJammer = false; + InfraredRadiationIntensity = 0; } // 验证方法 @@ -182,8 +193,6 @@ namespace ActiveProtect.SimulationEnvironment /// public int TargetIndex { get; set; } - - /// /// 最大飞行时间(秒) /// diff --git a/SimulationEnvironment/SimulationEvents.cs b/SimulationEnvironment/SimulationEvents.cs index 4fc54db..5d626aa 100644 --- a/SimulationEnvironment/SimulationEvents.cs +++ b/SimulationEnvironment/SimulationEvents.cs @@ -192,10 +192,17 @@ namespace ActiveProtect.SimulationEnvironment /// 红外指令制导导弹点亮红外热源事件 /// public class InfraredGuidanceMissileLightEvent : SimulationEvent - { + { /// /// 红外热源辐射功率(瓦特) /// public double RadiationPower { get; set; } } + + /// + /// 红外指令制导导弹熄灭红外热源事件 + /// + public class InfraredGuidanceMissileLightOffEvent : SimulationEvent + { + } } diff --git a/SimulationEnvironment/SimulationManager.cs b/SimulationEnvironment/SimulationManager.cs index 097d9fa..66f1356 100644 --- a/SimulationEnvironment/SimulationManager.cs +++ b/SimulationEnvironment/SimulationManager.cs @@ -155,6 +155,12 @@ namespace ActiveProtect.SimulationEnvironment case MissileType.InfraredCommandGuidance: missile = new InfraredCommandGuidedMissile(missileConfig, this); break; + case MissileType.InfraredImagingTerminalGuidance: + missile = new InfraredImagingTerminalGuidedMissile(missileConfig, this); + break; + case MissileType.MillimeterWaveTerminalGuidance: + missile = new MillimeterWaveTerminalGuidedMissile(missileConfig, this); + break; default: missile = new MissileBase(missileConfig, this); break; @@ -202,14 +208,10 @@ namespace ActiveProtect.SimulationEnvironment Elements.Add(infraredTracker); // 激活所有元素 - //ActivateAllElements(); + ActivateAllElements(); // 激活部分元素 - ActivateSomeElements(); - - // 激光驾束仪开始照射 - //laserBeamRider.StartBeamIllumination(); - + //ActivateSomeElements(); } //激活所有元素 @@ -233,9 +235,9 @@ namespace ActiveProtect.SimulationEnvironment //Elements.FindAll(e => e.Id == "LJ_1").ForEach(e => e.Activate()); // 激活激光半主动制导导弹 - Elements.FindAll(e => e.Id == "LSGM_1").ForEach(e => e.Activate()); + //Elements.FindAll(e => e.Id == "LSGM_1").ForEach(e => e.Activate()); // 激活激光目标指示器 - Elements.FindAll(e => e.Id == "LD_1").ForEach(e => e.Activate()); + //Elements.FindAll(e => e.Id == "LD_1").ForEach(e => e.Activate()); // 激活激光驾束制导导弹 //Elements.FindAll(e => e.Id == "LBRM_1").ForEach(e => e.Activate()); @@ -243,9 +245,15 @@ namespace ActiveProtect.SimulationEnvironment //Elements.FindAll(e => e.Id == "LBR_1").ForEach(e => e.Activate()); // 激活红外指令制导导弹 - //Elements.FindAll(e => e.Id == "ICGM_1").ForEach(e => e.Activate()); + Elements.FindAll(e => e.Id == "ICGM_1").ForEach(e => e.Activate()); // 激活红外测角仪 - //Elements.FindAll(e => e.Id == "IT_1").ForEach(e => e.Activate()); + Elements.FindAll(e => e.Id == "IT_1").ForEach(e => e.Activate()); + + // 激活红外成像末制导导弹 + Elements.FindAll(e => e.Id == "ITGM_1").ForEach(e => e.Activate()); + + // 激活毫米波末制导导弹 + //Elements.FindAll(e => e.Id == "MMWG_1").ForEach(e => e.Activate()); // 激活末敏弹 //Elements.FindAll(e => e.Id == "TSM_1").ForEach(e => e.Activate()); @@ -257,8 +265,7 @@ namespace ActiveProtect.SimulationEnvironment public void PublishEvent(SimulationEvent evt) { var eventType = evt.GetType(); - //Console.WriteLine($"发布事件: {eventType.Name}, 发送者: {evt.SenderId}"); - if (eventHandlers.TryGetValue(eventType, out var handlers)) + if (eventHandlers.TryGetValue(eventType, out var handlers)) { foreach (var handler in handlers) {