diff --git a/.cursor/rules/threat-source-rule.mdc b/.cursor/rules/threat-source-rule.mdc index f07ab18..9b9f528 100644 --- a/.cursor/rules/threat-source-rule.mdc +++ b/.cursor/rules/threat-source-rule.mdc @@ -10,4 +10,7 @@ alwaysApply: true - Y 轴为垂直轴 # 运行命令 -- 在运行命令前,先运行 pwd 命令,了解当前目录 \ No newline at end of file +- 在运行命令前,先运行 pwd 命令,了解当前目录 + +# 测试 +- 项目使用 MSTest 测试框架,使用 MSTest 的方式运行测试 \ No newline at end of file diff --git a/ThreatSource.Tests/src/Indicator/InfraredTrackerTests.cs b/ThreatSource.Tests/src/Indicator/InfraredTrackerTests.cs index 088936c..9b048c8 100644 --- a/ThreatSource.Tests/src/Indicator/InfraredTrackerTests.cs +++ b/ThreatSource.Tests/src/Indicator/InfraredTrackerTests.cs @@ -5,6 +5,7 @@ using ThreatSource.Utils; using ThreatSource.Tests.Simulation; using ThreatSource.Target; using ThreatSource.Missile; +using ThreatSource.Guidance; namespace ThreatSource.Tests.Indicator { @@ -15,6 +16,7 @@ namespace ThreatSource.Tests.Indicator private readonly InfraredTracker _infraredTracker; private readonly InfraredTrackerConfig _config; private readonly Tank _tank; + private readonly InfraredCommandGuidanceConfig _guidanceConfig; public InfraredTrackerTests() { @@ -30,6 +32,11 @@ namespace ThreatSource.Tests.Indicator UpdateFrequency = 10 }; + _guidanceConfig = new InfraredCommandGuidanceConfig + { + JammingResistanceThreshold = 1e-3 + }; + var tankInitialMotion = new InitialMotionParameters { Position = new Vector3D(100, 0, 0), @@ -132,7 +139,7 @@ namespace ThreatSource.Tests.Indicator }; // 注册一个导弹实体 - var missile = new InfraredCommandGuidedMissile("missile1", missileConfig, missileInitialMotion, _simulationManager); + var missile = new InfraredCommandGuidedMissile("missile1", missileConfig, missileInitialMotion, _guidanceConfig, _simulationManager); _simulationManager.RegisterEntity("missile1", missile); // 模拟导弹点亮红外热源 @@ -223,7 +230,7 @@ namespace ThreatSource.Tests.Indicator InitialSpeed = 100 }; - var missile = new InfraredCommandGuidedMissile("missile1", missileProperties, missileMotion, _simulationManager); + var missile = new InfraredCommandGuidedMissile("missile1", missileProperties, missileMotion, _guidanceConfig, _simulationManager); _simulationManager.RegisterEntity("missile1", missile); missile.Activate(); diff --git a/ThreatSource.Tests/src/Indicator/LaserDesignatorTests.cs b/ThreatSource.Tests/src/Indicator/LaserDesignatorTests.cs index 99945ea..83d1ca0 100644 --- a/ThreatSource.Tests/src/Indicator/LaserDesignatorTests.cs +++ b/ThreatSource.Tests/src/Indicator/LaserDesignatorTests.cs @@ -25,7 +25,10 @@ namespace ThreatSource.Tests.Indicator _config = new LaserDesignatorConfig { LaserPower = 1000, - LaserDivergenceAngle = 0.001 + LaserDivergenceAngle = 0.001, + JammingResistanceThreshold = 10000, + MinWavelength = 1.0, + MaxWavelength = 1.1 }; var tankInitialMotion = new InitialMotionParameters @@ -104,8 +107,7 @@ namespace ThreatSource.Tests.Indicator _simulationManager.PublishEvent(new LaserJammingEvent { JammingPower = jammingPower, - WavelengthMin = 1.0, - WavelengthMax = 1.1, + Wavelength = 1.05, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, diff --git a/ThreatSource.Tests/src/Jamming/InfraredImagingGuidanceJammingTests.cs b/ThreatSource.Tests/src/Jamming/InfraredImagingGuidanceJammingTests.cs new file mode 100644 index 0000000..3a03d76 --- /dev/null +++ b/ThreatSource.Tests/src/Jamming/InfraredImagingGuidanceJammingTests.cs @@ -0,0 +1,298 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using ThreatSource.Guidance; +using ThreatSource.Jamming; +using ThreatSource.Simulation; +using ThreatSource.Tests.Simulation; +using ThreatSource.Utils; +using ThreatSource.Target; + +namespace ThreatSource.Tests.Jamming +{ + [TestClass] + public class InfraredImagingGuidanceJammingTests : IDisposable + { + private SimulationManager? _simulationManager; + private TestSimulationAdapter? _testAdapter; + private InfraredImagingGuidanceSystem? _guidanceSystem; + private Tank? _target; + + [TestInitialize] + public void TestInitialize() + { + // 初始化模拟管理器和测试适配器 + _simulationManager = new SimulationManager(); + _testAdapter = new TestSimulationAdapter(_simulationManager); + _simulationManager.SetSimulationAdapter(_testAdapter); + + // 创建红外成像引导系统配置 + var config = new InfraredImagingGuidanceConfig + { + ImageWidth = 640, + ImageHeight = 480, + SearchFieldOfView = Math.PI / 6, // 30度 + TrackFieldOfView = Math.PI / 12, // 15度 + BackgroundIntensity = 0.1, + MaxDetectionRange = 5000, + SearchRecognitionProbability = 0.4, + TrackRecognitionProbability = 0.8, + LockConfirmationTime = 1.5, + TargetLostTolerance = 0.5, + JammingResistanceThreshold = 1e-4 // 修改为1e-4W + }; + + // 创建并注册目标实体 + var tankInitialMotion = new InitialMotionParameters + { + Position = new Vector3D(100, 0, 0), // 修改为100米,与激光指示器一致 + Orientation = new Orientation(0, 0, 0), + InitialSpeed = 0 + }; + + _target = new Tank("target1", tankInitialMotion, _simulationManager); + _simulationManager.RegisterEntity("target1", _target); + _testAdapter.AddTestEntity("target1", _target); + + // 创建红外引导系统 + _guidanceSystem = new InfraredImagingGuidanceSystem( + "infraredGuidance1", + config, + TargetType.Tank, + 100, // 最大加速度 + 3.0, // 比例导引系数 + _simulationManager + ); + + // 注册引导系统 + _simulationManager.RegisterEntity("infraredGuidance1", _guidanceSystem); + _testAdapter.AddTestEntity("infraredGuidance1", _guidanceSystem); + + // 激活引导系统 + _guidanceSystem.Activate(); + } + + public void Dispose() + { + _guidanceSystem?.Deactivate(); + } + + [TestMethod] + public void InfraredJamming_TargetsGuidance_GuidanceIsJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {initialPosition}, 初始速度: {initialVelocity}"); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建干扰事件 + var jammingEvent = new InfraredJammingEvent + { + JammingPower = 2000, // 修改为2000瓦特,与激光指示器一致 + JammingSourcePosition = new Vector3D(50, 0, 0), // 修改为50米,与激光指示器一致 + JammingDirection = new Vector3D(1, 0, 0), // 修改为(1,0,0),指向设备的方向 + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = null + }; + + System.Diagnostics.Debug.WriteLine($"创建干扰事件 - 功率: {jammingEvent.JammingPower}W, 位置: {jammingEvent.JammingSourcePosition}, 方向: {jammingEvent.JammingDirection}, 角度范围: {jammingEvent.JammingAngleRange * 180 / Math.PI}度"); + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + System.Diagnostics.Debug.WriteLine($"测试结果 - IsJammed: {_guidanceSystem.IsJammed}, HasGuidance: {_guidanceSystem.HasGuidance}"); + Assert.IsTrue(_guidanceSystem.IsJammed, "红外引导系统应该处于被干扰状态"); + Assert.IsFalse(_guidanceSystem.HasGuidance, "被干扰时不应该有制导信号"); + } + + [TestMethod] + public void InfraredJamming_OutsideAngleRange_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建角度范围外的干扰事件 + var jammingEvent = new InfraredJammingEvent + { + JammingPower = 500, // 保持不变 + JammingSourcePosition = new Vector3D(0, 50, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = 0.1, + JammingMode = JammingMode.Noise + }; + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + Assert.IsFalse(_guidanceSystem.IsJammed, "引导系统不应该被干扰,因为干扰源不在角度范围内"); + } + + [TestMethod] + public void InfraredJamming_LowPower_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建低功率干扰事件 + var jammingEvent = new InfraredJammingEvent + { + JammingPower = 10, // 保持不变 + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise + }; + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + Assert.IsFalse(_guidanceSystem.IsJammed, "引导系统不应该被干扰,因为干扰功率低于阈值"); + } + + [TestMethod] + public void InfraredJamming_ClearedAfterDuration_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建有限时间的干扰事件 + var jammingEvent = new InfraredJammingEvent + { + JammingPower = 2000, // 修改为2000瓦特,与激光指示器一致 + JammingSourcePosition = new Vector3D(50, 0, 0), // 修改为50米,与激光指示器一致 + JammingDirection = new Vector3D(1, 0, 0), // 修改为(1,0,0),指向设备的方向 + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = 0.5 + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认已被干扰 + Assert.IsTrue(_guidanceSystem.IsJammed, "红外引导系统应该处于被干扰状态"); + + // Act - 等待干扰过期 + // 通过多次更新引导系统,让JammingHandler处理时间 + for (int i = 0; i < 10; i++) + { + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); // 总共更新1秒,超过干扰持续时间 + } + + // Assert - 确认干扰已清除 + Assert.IsFalse(_guidanceSystem.IsJammed, "干扰持续时间结束后,引导系统应该恢复正常"); + } + + [TestMethod] + public void InfraredJamming_ManualClear_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建持续干扰事件 + var jammingEvent = new InfraredJammingEvent + { + JammingPower = 2000, // 修改为2000瓦特,与激光指示器一致 + JammingSourcePosition = new Vector3D(50, 0, 0), // 修改为50米,与激光指示器一致 + JammingDirection = new Vector3D(1, 0, 0), // 修改为(1,0,0),指向设备的方向 + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = null + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认已被干扰 + Assert.IsTrue(_guidanceSystem.IsJammed, "红外引导系统应该处于被干扰状态"); + + // Act - 手动清除干扰 + _guidanceSystem.ClearJamming(JammingType.Infrared); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认干扰已清除 + Assert.IsFalse(_guidanceSystem.IsJammed, "手动清除后,引导系统应该恢复正常"); + } + + [TestMethod] + public void InfraredJamming_GuidanceSwitchesToSearchMode() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建干扰事件 + var jammingEvent = new InfraredJammingEvent + { + JammingPower = 2000, // 修改为2000瓦特,与激光指示器一致 + JammingSourcePosition = new Vector3D(50, 0, 0), // 修改为50米,与激光指示器一致 + JammingDirection = new Vector3D(1, 0, 0), // 修改为(1,0,0),指向设备的方向 + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = null + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认系统切换到搜索模式 + Assert.IsTrue(_guidanceSystem.IsJammed, "红外引导系统应该处于被干扰状态"); + Assert.IsFalse(_guidanceSystem.HasGuidance, "被干扰时不应该有制导信号"); + } + } +} \ No newline at end of file diff --git a/ThreatSource.Tests/src/Jamming/InfraredJammingTests.cs b/ThreatSource.Tests/src/Jamming/InfraredTrackerJammingTests.cs similarity index 91% rename from ThreatSource.Tests/src/Jamming/InfraredJammingTests.cs rename to ThreatSource.Tests/src/Jamming/InfraredTrackerJammingTests.cs index b582616..30c8e80 100644 --- a/ThreatSource.Tests/src/Jamming/InfraredJammingTests.cs +++ b/ThreatSource.Tests/src/Jamming/InfraredTrackerJammingTests.cs @@ -10,7 +10,7 @@ using System.Collections.Generic; namespace ThreatSource.Tests.Jamming { [TestClass] - public class InfraredJammingTests + public class InfraredTrackerJammingTests { private SimulationManager _simulationManager = null!; private TestSimulationAdapter _testAdapter = null!; @@ -31,7 +31,7 @@ namespace ThreatSource.Tests.Jamming FieldOfView = Math.PI / 3, AngleMeasurementAccuracy = 0.001, UpdateFrequency = 10, - JammingResistanceThreshold = 0.05 // 设置干扰抗性阈值为50mW + JammingResistanceThreshold = 0.02 // 设置干扰抗性阈值为20mW }; // 初始化红外测角仪 @@ -63,9 +63,8 @@ namespace ThreatSource.Tests.Jamming // 创建干扰事件 var jammingEvent = new InfraredJammingEvent { - JammingPower = 200, // 高于阈值 - WavelengthMin = 3, - WavelengthMax = 5, + JammingPower = 1000, // 高于阈值 + Wavelength = 4, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), // 指向跟踪器 JammingAngleRange = Math.PI / 4, // 45度角 @@ -92,9 +91,8 @@ namespace ThreatSource.Tests.Jamming // 创建角度范围外的干扰事件 var jammingEvent = new InfraredJammingEvent { - JammingPower = 200, - WavelengthMin = 3, - WavelengthMax = 5, + JammingPower = 1000, + Wavelength = 4, JammingSourcePosition = new Vector3D(0, 50, 0), // 位于上方 JammingDirection = new Vector3D(0, 0, 1), // 指向前方,不是指向跟踪器 JammingAngleRange = 0.1, // 很小的角度范围 @@ -121,8 +119,7 @@ namespace ThreatSource.Tests.Jamming var jammingEvent = new InfraredJammingEvent { JammingPower = 10, // 低于阈值 - WavelengthMin = 3, - WavelengthMax = 5, + Wavelength = 4, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -146,9 +143,8 @@ namespace ThreatSource.Tests.Jamming // 创建错误波长的干扰事件 var jammingEvent = new InfraredJammingEvent { - JammingPower = 200, - WavelengthMin = 6, // 不在3-5μm或8-14μm范围 - WavelengthMax = 7, + JammingPower = 1000, + Wavelength = 6, // 不在3-5μm或8-14μm范围 JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -172,9 +168,8 @@ namespace ThreatSource.Tests.Jamming // 创建干扰事件 var jammingEvent = new InfraredJammingEvent { - JammingPower = 200, - WavelengthMin = 3, - WavelengthMax = 5, + JammingPower = 1000, + Wavelength = 4, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -198,9 +193,8 @@ namespace ThreatSource.Tests.Jamming // 创建有限时间的干扰事件 var jammingEvent = new InfraredJammingEvent { - JammingPower = 200, - WavelengthMin = 3, - WavelengthMax = 5, + JammingPower = 1000, + Wavelength = 4, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -237,9 +231,8 @@ namespace ThreatSource.Tests.Jamming // 创建持续干扰事件 var jammingEvent = new InfraredJammingEvent { - JammingPower = 200, - WavelengthMin = 3, - WavelengthMax = 5, + JammingPower = 1000, + Wavelength = 4, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -274,9 +267,8 @@ namespace ThreatSource.Tests.Jamming // 创建干扰事件 var jammingEvent = new InfraredJammingEvent { - JammingPower = 200, - WavelengthMin = 3, - WavelengthMax = 5, + JammingPower = 1000, + Wavelength = 4, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, diff --git a/ThreatSource.Tests/src/Jamming/LaserBeamRiderGuidanceJammingTests.cs b/ThreatSource.Tests/src/Jamming/LaserBeamRiderGuidanceJammingTests.cs new file mode 100644 index 0000000..0337778 --- /dev/null +++ b/ThreatSource.Tests/src/Jamming/LaserBeamRiderGuidanceJammingTests.cs @@ -0,0 +1,351 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using ThreatSource.Guidance; +using ThreatSource.Jamming; +using ThreatSource.Simulation; +using ThreatSource.Tests.Simulation; +using ThreatSource.Utils; +using ThreatSource.Target; + +namespace ThreatSource.Tests.Jamming +{ + [TestClass] + public class LaserBeamRiderGuidanceJammingTests : IDisposable + { + private SimulationManager? _simulationManager; + private TestSimulationAdapter? _testAdapter; + private LaserBeamRiderGuidanceSystem? _guidanceSystem; + private Tank? _target; + + [TestInitialize] + public void TestInitialize() + { + // 初始化模拟管理器和测试适配器 + _simulationManager = new SimulationManager(); + _testAdapter = new TestSimulationAdapter(_simulationManager); + _simulationManager.SetSimulationAdapter(_testAdapter); + + // 创建激光驾束引导系统配置 + var config = new LaserBeamRiderGuidanceSystemConfig + { + DetectorDiameter = 0.1, + ControlFieldDiameter = 20.0, + MinDetectablePower = 1e-3, + ProportionalGain = 1.0, + IntegralGain = 0.1, + DerivativeGain = 0.5, + NonlinearGain = 5.0, + MaxGuidanceAcceleration = 100.0, + LowPassFilterCoefficient = 0.7, + JammingResistanceThreshold = 1e-4 // 与红外成像引导系统一致 + }; + + // 创建激光编码配置 + var laserCodeConfig = new LaserCodeConfig + { + Code = new LaserCode + { + CodeType = LaserCodeType.PPM, + CodeValue = 1234 + }, + IsCodeEnabled = true, + IsCodeMatchRequired = true + }; + + // 创建并注册目标实体 + var tankInitialMotion = new InitialMotionParameters + { + Position = new Vector3D(100, 0, 0), + Orientation = new Orientation(0, 0, 0), + InitialSpeed = 0 + }; + + _target = new Tank("target1", tankInitialMotion, _simulationManager); + _simulationManager.RegisterEntity("target1", _target); + _testAdapter.AddTestEntity("target1", _target); + + // 创建激光驾束引导系统 + _guidanceSystem = new LaserBeamRiderGuidanceSystem( + "laserBeamRider1", + 100, // 最大加速度 + 3.0, // 比例导引系数 + laserCodeConfig, + config, + _simulationManager + ); + + // 注册引导系统 + _simulationManager.RegisterEntity("laserBeamRider1", _guidanceSystem); + _testAdapter.AddTestEntity("laserBeamRider1", _guidanceSystem); + + // 激活引导系统 + _guidanceSystem.Activate(); + } + + public void Dispose() + { + _guidanceSystem?.Deactivate(); + } + + [TestMethod] + public void LaserBeamJamming_TargetsGuidance_GuidanceIsJammed() + { + // 断言测试所需的组件已正确初始化 + Assert.IsNotNull(_simulationManager, "模拟管理器不应为空"); + Assert.IsNotNull(_guidanceSystem, "激光驾束引导系统不应为空"); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {initialPosition}, 初始速度: {initialVelocity}"); + + // 更新激光波束参数 + _guidanceSystem.UpdateLaserBeamRider( + new Vector3D(0, 0, 0), // 激光源位置 + new Vector3D(1, 0, 0), // 激光方向 + 10.0 // 激光功率 + ); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 2000, // 2000瓦特 + JammingSourcePosition = new Vector3D(50, 0, 0), // 50米 + JammingDirection = new Vector3D(1, 0, 0), // 指向设备的方向 + JammingAngleRange = Math.PI / 4, // 45度 + JammingMode = JammingMode.Noise, + Duration = null + }; + + System.Diagnostics.Debug.WriteLine($"创建干扰事件 - 功率: {jammingEvent.JammingPower}W, 位置: {jammingEvent.JammingSourcePosition}, 方向: {jammingEvent.JammingDirection}, 角度范围: {jammingEvent.JammingAngleRange * 180 / Math.PI}度"); + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + System.Diagnostics.Debug.WriteLine($"测试结果 - IsJammed: {_guidanceSystem.IsJammed}, HasGuidance: {_guidanceSystem.HasGuidance}"); + Assert.IsTrue(_guidanceSystem.IsJammed, "激光驾束引导系统应该处于被干扰状态"); + Assert.IsFalse(_guidanceSystem.HasGuidance, "被干扰时不应该有制导信号"); + } + + [TestMethod] + public void LaserBeamJamming_OutsideAngleRange_GuidanceNotJammed() + { + // 断言测试所需的组件已正确初始化 + Assert.IsNotNull(_simulationManager, "模拟管理器不应为空"); + Assert.IsNotNull(_guidanceSystem, "激光驾束引导系统不应为空"); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新激光波束参数 + _guidanceSystem.UpdateLaserBeamRider( + new Vector3D(0, 0, 0), // 激光源位置 + new Vector3D(1, 0, 0), // 激光方向 + 10.0 // 激光功率 + ); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建角度范围外的干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 500, // 500瓦特 + JammingSourcePosition = new Vector3D(0, 50, 0), // 从Y轴方向 + JammingDirection = new Vector3D(1, 0, 0), // 指向X轴方向 + JammingAngleRange = 0.1, // 约5.7度 + JammingMode = JammingMode.Noise + }; + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + Assert.IsFalse(_guidanceSystem.IsJammed, "引导系统不应该被干扰,因为干扰源不在角度范围内"); + } + + [TestMethod] + public void LaserBeamJamming_LowPower_GuidanceNotJammed() + { + // 断言测试所需的组件已正确初始化 + Assert.IsNotNull(_simulationManager, "模拟管理器不应为空"); + Assert.IsNotNull(_guidanceSystem, "激光驾束引导系统不应为空"); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新激光波束参数 + _guidanceSystem.UpdateLaserBeamRider( + new Vector3D(0, 0, 0), // 激光源位置 + new Vector3D(1, 0, 0), // 激光方向 + 10.0 // 激光功率 + ); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建低功率干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 10, // 10瓦特 + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, // 45度 + JammingMode = JammingMode.Noise + }; + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + Assert.IsFalse(_guidanceSystem.IsJammed, "引导系统不应该被干扰,因为干扰功率低于阈值"); + } + + [TestMethod] + public void LaserBeamJamming_ClearedAfterDuration_GuidanceNotJammed() + { + // 断言测试所需的组件已正确初始化 + Assert.IsNotNull(_simulationManager, "模拟管理器不应为空"); + Assert.IsNotNull(_guidanceSystem, "激光驾束引导系统不应为空"); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新激光波束参数 + _guidanceSystem.UpdateLaserBeamRider( + new Vector3D(0, 0, 0), // 激光源位置 + new Vector3D(1, 0, 0), // 激光方向 + 10.0 // 激光功率 + ); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建有限时间的干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 2000, // 2000瓦特 + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, // 45度 + JammingMode = JammingMode.Noise, + Duration = 0.5 // 0.5秒 + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认已被干扰 + Assert.IsTrue(_guidanceSystem.IsJammed, "激光驾束引导系统应该处于被干扰状态"); + + // Act - 等待干扰过期 + // 通过多次更新引导系统,让JammingHandler处理时间 + for (int i = 0; i < 10; i++) + { + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); // 总共更新1秒,超过干扰持续时间 + } + + // Assert - 确认干扰已清除 + Assert.IsFalse(_guidanceSystem.IsJammed, "干扰持续时间结束后,引导系统应该恢复正常"); + } + + [TestMethod] + public void LaserBeamJamming_ManualClear_GuidanceNotJammed() + { + // 断言测试所需的组件已正确初始化 + Assert.IsNotNull(_simulationManager, "模拟管理器不应为空"); + Assert.IsNotNull(_guidanceSystem, "激光驾束引导系统不应为空"); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新激光波束参数 + _guidanceSystem.UpdateLaserBeamRider( + new Vector3D(0, 0, 0), // 激光源位置 + new Vector3D(1, 0, 0), // 激光方向 + 10.0 // 激光功率 + ); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建持续干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 2000, // 2000瓦特 + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, // 45度 + JammingMode = JammingMode.Noise, + Duration = null + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认已被干扰 + Assert.IsTrue(_guidanceSystem.IsJammed, "激光驾束引导系统应该处于被干扰状态"); + + // Act - 手动清除干扰 + _guidanceSystem.ClearJamming(JammingType.Laser); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认干扰已清除 + Assert.IsFalse(_guidanceSystem.IsJammed, "手动清除后,引导系统应该恢复正常"); + } + + [TestMethod] + public void LaserBeamJamming_GuidanceSwitchesToSearchMode() + { + // 断言测试所需的组件已正确初始化 + Assert.IsNotNull(_simulationManager, "模拟管理器不应为空"); + Assert.IsNotNull(_guidanceSystem, "激光驾束引导系统不应为空"); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新激光波束参数 + _guidanceSystem.UpdateLaserBeamRider( + new Vector3D(0, 0, 0), // 激光源位置 + new Vector3D(1, 0, 0), // 激光方向 + 10.0 // 激光功率 + ); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 2000, // 2000瓦特 + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, // 45度 + JammingMode = JammingMode.Noise, + Duration = null + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认系统切换到搜索模式 + Assert.IsTrue(_guidanceSystem.IsJammed, "激光驾束引导系统应该处于被干扰状态"); + Assert.IsFalse(_guidanceSystem.HasGuidance, "被干扰时不应该有制导信号"); + } + } +} \ No newline at end of file diff --git a/ThreatSource.Tests/src/Jamming/LaserBeamRiderJammingTests.cs b/ThreatSource.Tests/src/Jamming/LaserBeamRiderJammingTests.cs index 6c849be..17c317d 100644 --- a/ThreatSource.Tests/src/Jamming/LaserBeamRiderJammingTests.cs +++ b/ThreatSource.Tests/src/Jamming/LaserBeamRiderJammingTests.cs @@ -76,9 +76,8 @@ namespace ThreatSource.Tests.Jamming // 创建干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 200, // 高于阈值 - WavelengthMin = 1.0, - WavelengthMax = 1.1, + JammingPower = 2000, // 高功率干扰 + Wavelength = 1.05, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), // 指向激光驾束仪 JammingAngleRange = Math.PI / 4, // 45度角 @@ -109,9 +108,8 @@ namespace ThreatSource.Tests.Jamming // 创建干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 200, - WavelengthMin = 1.0, - WavelengthMax = 1.1, + JammingPower = 2000, // 高功率干扰 + Wavelength = 1.05, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -153,9 +151,8 @@ namespace ThreatSource.Tests.Jamming // 创建有限时间的干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 200, - WavelengthMin = 1.0, - WavelengthMax = 1.1, + JammingPower = 2000, // 高功率干扰 + Wavelength = 1.05, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -192,9 +189,8 @@ namespace ThreatSource.Tests.Jamming // 创建持续干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 200, - WavelengthMin = 1.0, - WavelengthMax = 1.1, + JammingPower = 2000, // 高功率干扰 + Wavelength = 1.05, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -228,9 +224,8 @@ namespace ThreatSource.Tests.Jamming // 创建干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 200, - WavelengthMin = 1.0, - WavelengthMax = 1.1, + JammingPower = 2000, // 高功率干扰 + Wavelength = 1.05, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, diff --git a/ThreatSource.Tests/src/Jamming/LaserDesignatorJammingTests.cs b/ThreatSource.Tests/src/Jamming/LaserDesignatorJammingTests.cs index bc72a09..6c974c3 100644 --- a/ThreatSource.Tests/src/Jamming/LaserDesignatorJammingTests.cs +++ b/ThreatSource.Tests/src/Jamming/LaserDesignatorJammingTests.cs @@ -4,6 +4,7 @@ using ThreatSource.Jamming; using ThreatSource.Simulation; using ThreatSource.Tests.Simulation; using ThreatSource.Utils; +using ThreatSource.Target; using System; using System.Collections.Generic; @@ -29,7 +30,9 @@ namespace ThreatSource.Tests.Jamming { LaserPower = 100, LaserDivergenceAngle = 0.001, - JammingResistanceThreshold = 0.05 // 设置干扰抗性阈值为50mW + JammingResistanceThreshold = 0.01, // 设置干扰抗性阈值为10mW,适应球面扩散模型 + MinWavelength = 1.0, + MaxWavelength = 1.1 }; // 初始化激光指示器 @@ -40,6 +43,17 @@ namespace ThreatSource.Tests.Jamming InitialSpeed = 0 }; + // 创建并注册目标实体 + var tankInitialMotion = new InitialMotionParameters + { + Position = new Vector3D(100, 0, 0), + Orientation = new Orientation(0, 0, 0), + InitialSpeed = 0 + }; + var tank = new Tank("target1", tankInitialMotion, _simulationManager); + _simulationManager.RegisterEntity("target1", tank); + _testAdapter.AddTestEntity("target1", tank); + _laserDesignator = new LaserDesignator( "laser1", "target1", @@ -51,6 +65,7 @@ namespace ThreatSource.Tests.Jamming // 注册激光指示器 _simulationManager.RegisterEntity("laser1", _laserDesignator); + _testAdapter.AddTestEntity("laser1", _laserDesignator); } [TestMethod] @@ -62,9 +77,8 @@ namespace ThreatSource.Tests.Jamming // 创建干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 200, // 高于阈值 - WavelengthMin = 1.0, - WavelengthMax = 1.1, + JammingPower = 2000, // 高于阈值 + Wavelength = 1.05, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), // 指向激光指示器 JammingAngleRange = Math.PI / 4, // 45度角 @@ -91,9 +105,8 @@ namespace ThreatSource.Tests.Jamming // 创建角度范围外的干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 200, - WavelengthMin = 1.0, - WavelengthMax = 1.1, + JammingPower = 500, // 角度范围外的干扰 + Wavelength = 1.05, JammingSourcePosition = new Vector3D(0, 50, 0), // 位于上方 JammingDirection = new Vector3D(0, 0, 1), // 指向前方,不是指向指示器 JammingAngleRange = 0.1, // 很小的角度范围 @@ -119,9 +132,8 @@ namespace ThreatSource.Tests.Jamming // 创建低功率干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 10, // 低于阈值 - WavelengthMin = 1.0, - WavelengthMax = 1.1, + JammingPower = 10, // 低功率干扰 + Wavelength = 1.05, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -145,9 +157,8 @@ namespace ThreatSource.Tests.Jamming // 创建错误波长的干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 200, - WavelengthMin = 2.0, // 不在1.0-1.1μm范围 - WavelengthMax = 3.0, + JammingPower = 500, // 波长不匹配的干扰 + Wavelength = 2.5, // 不在1.0-1.1μm范围 JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -171,9 +182,8 @@ namespace ThreatSource.Tests.Jamming // 创建有限时间的干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 200, - WavelengthMin = 1.0, - WavelengthMax = 1.1, + JammingPower = 500, // 有限时间的干扰 + Wavelength = 1.05, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -208,9 +218,8 @@ namespace ThreatSource.Tests.Jamming // 创建持续干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 200, - WavelengthMin = 1.0, - WavelengthMax = 1.1, + JammingPower = 500, // 持续干扰 + Wavelength = 1.05, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -245,9 +254,8 @@ namespace ThreatSource.Tests.Jamming // 创建干扰事件 var jammingEvent = new LaserJammingEvent { - JammingPower = 200, - WavelengthMin = 1.0, - WavelengthMax = 1.1, + JammingPower = 500, // 照射禁用测试 + Wavelength = 1.05, JammingSourcePosition = new Vector3D(50, 0, 0), JammingDirection = new Vector3D(-1, 0, 0), JammingAngleRange = Math.PI / 4, @@ -267,5 +275,50 @@ namespace ThreatSource.Tests.Jamming Assert.IsFalse(_laserDesignator.IsIlluminationOn, "在干扰状态下照射应该被禁用"); Assert.IsTrue(publishedEvents.Any(evt => evt is LaserIlluminationStopEvent), "应该发布照射停止事件"); } + + [TestMethod] + public void LaserJamming_DifferentWavelengths_BehavesCorrectly() + { + // Arrange + _laserDesignator.Activate(); + + // 测试1:波长匹配的情况 + var matchingJammingEvent = new LaserJammingEvent + { + JammingPower = 2000, + Wavelength = 1.05, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(-1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = null + }; + + _simulationManager.PublishEvent(matchingJammingEvent); + _laserDesignator.Update(0.1); + + Assert.IsTrue(_laserDesignator.IsJammed, "波长匹配时应该被干扰"); + + // 清除干扰状态,准备下一个测试 + _laserDesignator.ClearJamming(JammingType.Laser); + _laserDesignator.Update(0.1); + + // 测试2:波长不匹配的情况 + var nonMatchingJammingEvent = new LaserJammingEvent + { + JammingPower = 2000, + Wavelength = 1.55, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(-1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = null + }; + + _simulationManager.PublishEvent(nonMatchingJammingEvent); + _laserDesignator.Update(0.1); + + Assert.IsFalse(_laserDesignator.IsJammed, "波长不匹配时不应该被干扰"); + } } } \ No newline at end of file diff --git a/ThreatSource.Tests/src/Jamming/LaserSemiActiveGuidanceJammingTests.cs b/ThreatSource.Tests/src/Jamming/LaserSemiActiveGuidanceJammingTests.cs new file mode 100644 index 0000000..2be6068 --- /dev/null +++ b/ThreatSource.Tests/src/Jamming/LaserSemiActiveGuidanceJammingTests.cs @@ -0,0 +1,306 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using ThreatSource.Guidance; +using ThreatSource.Jamming; +using ThreatSource.Simulation; +using ThreatSource.Tests.Simulation; +using ThreatSource.Utils; +using ThreatSource.Target; + +namespace ThreatSource.Tests.Jamming +{ + [TestClass] + public class LaserSemiActiveGuidanceJammingTests : IDisposable + { + private SimulationManager? _simulationManager; + private TestSimulationAdapter? _testAdapter; + private LaserSemiActiveGuidanceSystem? _guidanceSystem; + private Tank? _target; + + [TestInitialize] + public void TestInitialize() + { + // 初始化模拟管理器和测试适配器 + _simulationManager = new SimulationManager(); + _testAdapter = new TestSimulationAdapter(_simulationManager); + _simulationManager.SetSimulationAdapter(_testAdapter); + + // 创建激光半主动制导系统配置 + var config = new LaserSemiActiveGuidanceConfig + { + SensorDiameter = 0.1, // 传感器直径 + FocusedSpotDiameter = 0.01, // 聚焦光斑直径 + FieldOfViewAngle = 30, // 30度视场角 + LockThreshold = 1e-4, // 锁定阈值 + SpotOffsetSensitivity = 0.5, // 光斑偏移灵敏度 + TargetReflectiveArea = 1.0, // 目标反射面积 + ReflectionCoefficient = 0.5, // 反射系数 + LensDiameter = 0.05, // 镜头直径 + JammingResistanceThreshold = 1e-4 // 干扰抗性阈值 + }; + + // 创建激光编码配置 + var laserCodeConfig = new LaserCodeConfig + { + Code = new LaserCode + { + CodeType = LaserCodeType.PPM, + CodeValue = 1234 + } + }; + + // 创建并注册目标实体 + var tankInitialMotion = new InitialMotionParameters + { + Position = new Vector3D(100, 0, 0), + Orientation = new Orientation(0, 0, 0), + InitialSpeed = 0 + }; + + _target = new Tank("target1", tankInitialMotion, _simulationManager); + _simulationManager.RegisterEntity("target1", _target); + _testAdapter.AddTestEntity("target1", _target); + + // 创建激光半主动制导系统 + _guidanceSystem = new LaserSemiActiveGuidanceSystem( + "laserGuidance1", + 100, // 最大加速度 + 3.0, // 比例导引系数 + laserCodeConfig, + config, + _simulationManager + ); + + // 注册制导系统 + _simulationManager.RegisterEntity("laserGuidance1", _guidanceSystem); + _testAdapter.AddTestEntity("laserGuidance1", _guidanceSystem); + + // 激活制导系统 + _guidanceSystem.Activate(); + } + + public void Dispose() + { + _guidanceSystem?.Deactivate(); + } + + [TestMethod] + public void LaserJamming_TargetsGuidance_GuidanceIsJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {initialPosition}, 初始速度: {initialVelocity}"); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 2000, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = null + }; + + System.Diagnostics.Debug.WriteLine($"创建干扰事件 - 功率: {jammingEvent.JammingPower}W, 位置: {jammingEvent.JammingSourcePosition}, 方向: {jammingEvent.JammingDirection}, 角度范围: {jammingEvent.JammingAngleRange * 180 / Math.PI}度"); + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + System.Diagnostics.Debug.WriteLine($"测试结果 - IsJammed: {_guidanceSystem.IsJammed}, HasGuidance: {_guidanceSystem.HasGuidance}"); + Assert.IsTrue(_guidanceSystem.IsJammed, "激光半主动制导系统应该处于被干扰状态"); + Assert.IsFalse(_guidanceSystem.HasGuidance, "被干扰时不应该有制导信号"); + } + + [TestMethod] + public void LaserJamming_OutsideAngleRange_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建角度范围外的干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 500, + JammingSourcePosition = new Vector3D(0, 50, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = 0.1, + JammingMode = JammingMode.Noise + }; + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + Assert.IsFalse(_guidanceSystem.IsJammed, "制导系统不应该被干扰,因为干扰源不在角度范围内"); + } + + [TestMethod] + public void LaserJamming_LowPower_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建低功率干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 10, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise + }; + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + Assert.IsFalse(_guidanceSystem.IsJammed, "制导系统不应该被干扰,因为干扰功率低于阈值"); + } + + [TestMethod] + public void LaserJamming_ClearedAfterDuration_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建有限时间的干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 2000, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = 0.5 + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认已被干扰 + Assert.IsTrue(_guidanceSystem.IsJammed, "激光半主动制导系统应该处于被干扰状态"); + + // Act - 等待干扰过期 + // 通过多次更新制导系统,让JammingHandler处理时间 + for (int i = 0; i < 10; i++) + { + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); // 总共更新1秒,超过干扰持续时间 + } + + // Assert - 确认干扰已清除 + Assert.IsFalse(_guidanceSystem.IsJammed, "干扰持续时间结束后,制导系统应该恢复正常"); + } + + [TestMethod] + public void LaserJamming_ManualClear_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建持续干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 2000, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = null + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认已被干扰 + Assert.IsTrue(_guidanceSystem.IsJammed, "激光半主动制导系统应该处于被干扰状态"); + + // Act - 手动清除干扰 + _guidanceSystem.ClearJamming(JammingType.Laser); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认干扰已清除 + Assert.IsFalse(_guidanceSystem.IsJammed, "手动清除后,制导系统应该恢复正常"); + } + + [TestMethod] + public void LaserJamming_GuidanceSwitchesToSearchMode() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建干扰事件 + var jammingEvent = new LaserJammingEvent + { + JammingPower = 2000, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = null + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认系统切换到搜索模式 + Assert.IsTrue(_guidanceSystem.IsJammed, "激光半主动制导系统应该处于被干扰状态"); + Assert.IsFalse(_guidanceSystem.HasGuidance, "被干扰时不应该有制导信号"); + } + } +} \ No newline at end of file diff --git a/ThreatSource.Tests/src/Jamming/MillimeterWaveGuidanceJammingTests.cs b/ThreatSource.Tests/src/Jamming/MillimeterWaveGuidanceJammingTests.cs new file mode 100644 index 0000000..5effeeb --- /dev/null +++ b/ThreatSource.Tests/src/Jamming/MillimeterWaveGuidanceJammingTests.cs @@ -0,0 +1,304 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using ThreatSource.Guidance; +using ThreatSource.Jamming; +using ThreatSource.Simulation; +using ThreatSource.Tests.Simulation; +using ThreatSource.Utils; +using ThreatSource.Target; + +namespace ThreatSource.Tests.Jamming +{ + [TestClass] + public class MillimeterWaveGuidanceJammingTests : IDisposable + { + private SimulationManager? _simulationManager; + private TestSimulationAdapter? _testAdapter; + private MillimeterWaveGuidanceSystem? _guidanceSystem; + private Tank? _target; + + [TestInitialize] + public void TestInitialize() + { + // 初始化模拟管理器和测试适配器 + _simulationManager = new SimulationManager(); + _testAdapter = new TestSimulationAdapter(_simulationManager); + _simulationManager.SetSimulationAdapter(_testAdapter); + + // 创建毫米波导引系统配置 + var config = new MillimeterWaveGuidanceConfig + { + WaveFrequency = 94e9, // 94GHz + TransmitPower = 0.3, // 0.3W + AntennaGainDB = 30, // 30dB + SystemLossDB = 3, // 3dB + NoiseFigureDB = 6, // 6dB + PulseDuration = 1e-6, // 1μs + FieldOfViewAngle = 60, // 60度 + SearchBeamWidth = 3, // 3度 + TrackBeamWidth = 1, // 1度 + LockBeamWidth = 0.5, // 0.5度 + ScanAngularSpeedDeg = 60, // 60度/秒 + ScanRadiusGrowthRateDeg = 5, // 5度/秒 + RecognitionSNRThreshold = 10, // 10dB + LockSNRThreshold = 15, // 15dB + LockConfirmationTime = 1.5, // 1.5秒 + TargetLostTolerance = 0.5, // 0.5秒 + MonopulseSensitivity = 1.0, // 1.0 + JammingResistanceThreshold = 1e-4 // 1e-4W + }; + + // 创建并注册目标实体 + var tankInitialMotion = new InitialMotionParameters + { + Position = new Vector3D(100, 0, 0), + Orientation = new Orientation(0, 0, 0), + InitialSpeed = 0 + }; + + _target = new Tank("target1", tankInitialMotion, _simulationManager); + _simulationManager.RegisterEntity("target1", _target); + _testAdapter.AddTestEntity("target1", _target); + + // 创建毫米波制导系统 + _guidanceSystem = new MillimeterWaveGuidanceSystem( + "millimeterWaveGuidance1", + 100, // 最大加速度 + 3.0, // 比例导引系数 + config, + _simulationManager + ); + + // 注册制导系统 + _simulationManager.RegisterEntity("millimeterWaveGuidance1", _guidanceSystem); + _testAdapter.AddTestEntity("millimeterWaveGuidance1", _guidanceSystem); + + // 激活制导系统 + _guidanceSystem.Activate(); + } + + public void Dispose() + { + _guidanceSystem?.Deactivate(); + } + + [TestMethod] + public void MillimeterWaveJamming_TargetsGuidance_GuidanceIsJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {initialPosition}, 初始速度: {initialVelocity}"); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建干扰事件 + var jammingEvent = new MillimeterWaveJammingEvent + { + JammingPower = 2000, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = null + }; + + System.Diagnostics.Debug.WriteLine($"创建干扰事件 - 功率: {jammingEvent.JammingPower}W, 位置: {jammingEvent.JammingSourcePosition}, 方向: {jammingEvent.JammingDirection}, 角度范围: {jammingEvent.JammingAngleRange * 180 / Math.PI}度"); + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + System.Diagnostics.Debug.WriteLine($"测试结果 - IsJammed: {_guidanceSystem.IsJammed}, HasGuidance: {_guidanceSystem.HasGuidance}"); + Assert.IsTrue(_guidanceSystem.IsJammed, "毫米波制导系统应该处于被干扰状态"); + Assert.IsFalse(_guidanceSystem.HasGuidance, "被干扰时不应该有制导信号"); + } + + [TestMethod] + public void MillimeterWaveJamming_OutsideAngleRange_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建角度范围外的干扰事件 + var jammingEvent = new MillimeterWaveJammingEvent + { + JammingPower = 500, + JammingSourcePosition = new Vector3D(0, 50, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = 0.1, + JammingMode = JammingMode.Noise + }; + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + Assert.IsFalse(_guidanceSystem.IsJammed, "制导系统不应该被干扰,因为干扰源不在角度范围内"); + } + + [TestMethod] + public void MillimeterWaveJamming_LowPower_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建低功率干扰事件 + var jammingEvent = new MillimeterWaveJammingEvent + { + JammingPower = 10, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise + }; + + // Act + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert + Assert.IsFalse(_guidanceSystem.IsJammed, "制导系统不应该被干扰,因为干扰功率低于阈值"); + } + + [TestMethod] + public void MillimeterWaveJamming_ClearedAfterDuration_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建有限时间的干扰事件 + var jammingEvent = new MillimeterWaveJammingEvent + { + JammingPower = 2000, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = 0.5 + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认已被干扰 + Assert.IsTrue(_guidanceSystem.IsJammed, "毫米波制导系统应该处于被干扰状态"); + + // Act - 等待干扰过期 + // 通过多次更新制导系统,让JammingHandler处理时间 + for (int i = 0; i < 10; i++) + { + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); // 总共更新1秒,超过干扰持续时间 + } + + // Assert - 确认干扰已清除 + Assert.IsFalse(_guidanceSystem.IsJammed, "干扰持续时间结束后,制导系统应该恢复正常"); + } + + [TestMethod] + public void MillimeterWaveJamming_ManualClear_GuidanceNotJammed() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建持续干扰事件 + var jammingEvent = new MillimeterWaveJammingEvent + { + JammingPower = 2000, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = null + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认已被干扰 + Assert.IsTrue(_guidanceSystem.IsJammed, "毫米波制导系统应该处于被干扰状态"); + + // Act - 手动清除干扰 + _guidanceSystem.ClearJamming(JammingType.MillimeterWave); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认干扰已清除 + Assert.IsFalse(_guidanceSystem.IsJammed, "手动清除后,制导系统应该恢复正常"); + } + + [TestMethod] + public void MillimeterWaveJamming_GuidanceSwitchesToSearchMode() + { + // 确保组件不为空 + Assert.IsNotNull(_simulationManager); + Assert.IsNotNull(_guidanceSystem); + + // Arrange + var initialPosition = new Vector3D(500, 0, 0); + var initialVelocity = new Vector3D(100, 0, 0); + + // 更新一次系统,使其跟踪目标 + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // 创建干扰事件 + var jammingEvent = new MillimeterWaveJammingEvent + { + JammingPower = 2000, + JammingSourcePosition = new Vector3D(50, 0, 0), + JammingDirection = new Vector3D(1, 0, 0), + JammingAngleRange = Math.PI / 4, + JammingMode = JammingMode.Noise, + Duration = null + }; + + // Act - 应用干扰 + _simulationManager.PublishEvent(jammingEvent); + _guidanceSystem.Update(0.1, initialPosition, initialVelocity); + + // Assert - 确认系统切换到搜索模式 + Assert.IsTrue(_guidanceSystem.IsJammed, "毫米波制导系统应该处于被干扰状态"); + Assert.IsFalse(_guidanceSystem.HasGuidance, "被干扰时不应该有制导信号"); + } + } +} \ No newline at end of file diff --git a/ThreatSource.Tests/src/Jamming/JammingTests.cs b/ThreatSource.Tests/src/Jamming/TerminalSensitiveSubmunitionJammingTests.cs similarity index 91% rename from ThreatSource.Tests/src/Jamming/JammingTests.cs rename to ThreatSource.Tests/src/Jamming/TerminalSensitiveSubmunitionJammingTests.cs index 23f4a6b..097f3cb 100644 --- a/ThreatSource.Tests/src/Jamming/JammingTests.cs +++ b/ThreatSource.Tests/src/Jamming/TerminalSensitiveSubmunitionJammingTests.cs @@ -11,7 +11,7 @@ using System.Linq; namespace ThreatSource.Tests.Jamming { [TestClass] - public class JammingTests + public class TerminalSensitiveSubmunitionJammingTests { private SimulationManager _simulationManager = null!; private TestSimulationAdapter _testAdapter = null!; @@ -98,7 +98,8 @@ namespace ThreatSource.Tests.Jamming Power = 100, AngleRange = 30, Duration = 5, - Direction = new Vector3D(1, 0, 0) + Direction = new Vector3D(1, 0, 0), + SourcePosition = new Vector3D(10, 0, 0) }; _infraredDetector.ApplyJamming(jammingParams); @@ -123,7 +124,8 @@ namespace ThreatSource.Tests.Jamming Power = 200, AngleRange = 45, Duration = 3, - Direction = new Vector3D(1, 0, 0) + Direction = new Vector3D(1, 0, 0), + SourcePosition = new Vector3D(10, 0, 0) }; _radiometer.ApplyJamming(jammingParams); @@ -148,7 +150,8 @@ namespace ThreatSource.Tests.Jamming Power = 150, AngleRange = 15, Duration = 4, - Direction = new Vector3D(1, 0, 0) + Direction = new Vector3D(1, 0, 0), + SourcePosition = new Vector3D(10, 0, 0) }; _rangefinder.ApplyJamming(jammingParams); @@ -319,7 +322,8 @@ namespace ThreatSource.Tests.Jamming Power = 200, AngleRange = 45, Duration = 3, - Direction = new Vector3D(1, 0, 0) + Direction = new Vector3D(1, 0, 0), + SourcePosition = new Vector3D(10, 0, 0) }; // 记录初始高度 @@ -415,7 +419,8 @@ namespace ThreatSource.Tests.Jamming Power = 200, AngleRange = 45, Duration = 3, - Direction = new Vector3D(1, 0, 0) + Direction = new Vector3D(1, 0, 0), + SourcePosition = new Vector3D(10, 0, 0) }; // 记录初始状态 @@ -553,7 +558,8 @@ namespace ThreatSource.Tests.Jamming Power = 150, AngleRange = 30, Duration = 3, - Direction = new Vector3D(1, 0, 0) + Direction = new Vector3D(1, 0, 0), + SourcePosition = new Vector3D(10, 0, 0) }; // 应用干扰 @@ -676,14 +682,58 @@ namespace ThreatSource.Tests.Jamming radiometer.Activate(); // 更新几次状态,确保进入探测阶段 - for (double time = 0; time < 5.0; time += 0.1) + for (double time = 0; time < 10.0; time += 0.1) { // 更新子弹状态 submunition.Update(0.1); } - // Assert - Assert.IsTrue(submunition.IsGuidance); + // 验证初始状态 + Assert.IsTrue(submunition.IsGuidance, "子弹应该处于制导状态"); + Assert.IsTrue(infraredDetector.IsActive, "红外探测器应该处于激活状态"); + Assert.IsTrue(radiometer.IsActive, "毫米波辐射计应该处于激活状态"); + + // 创建干扰参数 + var infraredJamming = new JammingParameters + { + Type = JammingType.Infrared, + Power = 1000, + AngleRange = 30, + Duration = 3, + Direction = new Vector3D(1, 0, 0), + SourcePosition = new Vector3D(10, 0, 0) + }; + + // 应用干扰 + Console.WriteLine("应用干扰..."); + infraredDetector.ApplyJamming(infraredJamming); + + // 验证干扰效果 + Assert.IsFalse(infraredDetector.IsActive, "红外探测器应该在干扰下失效"); + Assert.IsTrue(infraredDetector.IsJammed, "红外探测器应该处于干扰状态"); + + // 更新并验证干扰期间的行为 + for (int i = 0; i < 5; i++) + { + submunition.Update(0.1); + var status = submunition.GetStatus(); + Console.WriteLine($"干扰期间状态 {i+1}:{status}"); + Assert.IsTrue(status.Contains("传感器受到干扰"), "子弹状态应该反映传感器受到干扰"); + } + + // 清除干扰 + Console.WriteLine("清除干扰..."); + infraredDetector.ClearJamming(JammingType.Infrared); + + // 验证恢复效果 + Assert.IsTrue(infraredDetector.IsActive, "红外探测器应该恢复正常工作"); + Assert.IsFalse(infraredDetector.IsJammed, "红外探测器应该解除干扰状态"); + + // 验证恢复后的状态 + submunition.Update(0.1); + var finalStatus = submunition.GetStatus(); + Console.WriteLine($"恢复后状态:{finalStatus}"); + Assert.IsFalse(finalStatus.Contains("传感器受到干扰"), "子弹状态应该反映传感器恢复正常"); } [TestMethod] @@ -767,7 +817,8 @@ namespace ThreatSource.Tests.Jamming Power = 150, AngleRange = 30, Duration = 3, - Direction = new Vector3D(1, 0, 0) + Direction = new Vector3D(1, 0, 0), + SourcePosition = new Vector3D(10, 0, 0) }; // 应用干扰 diff --git a/ThreatSource.Tests/src/Missile/InfraredCommandGuidedMissileTests.cs b/ThreatSource.Tests/src/Missile/InfraredCommandGuidedMissileTests.cs index 15983cb..fe4ec5e 100644 --- a/ThreatSource.Tests/src/Missile/InfraredCommandGuidedMissileTests.cs +++ b/ThreatSource.Tests/src/Missile/InfraredCommandGuidedMissileTests.cs @@ -3,6 +3,7 @@ using ThreatSource.Missile; using ThreatSource.Simulation; using ThreatSource.Utils; using ThreatSource.Tests.Simulation; +using ThreatSource.Guidance; namespace ThreatSource.Tests.Missile { @@ -12,6 +13,7 @@ namespace ThreatSource.Tests.Missile private readonly TestSimulationAdapter _testAdapter; private readonly InfraredCommandGuidedMissile _missile; private readonly MissileProperties _properties; + private readonly InfraredCommandGuidanceConfig _guidanceConfig; public InfraredCommandGuidedMissileTests() { @@ -32,6 +34,11 @@ namespace ThreatSource.Tests.Missile Type = MissileType.InfraredCommandGuidance }; + _guidanceConfig = new InfraredCommandGuidanceConfig + { + JammingResistanceThreshold = 1e-3 + }; + var missileInitialMotion = new InitialMotionParameters { Position = new Vector3D(0, 0, 0), @@ -43,6 +50,7 @@ namespace ThreatSource.Tests.Missile "missile1", _properties, missileInitialMotion, + _guidanceConfig, _simulationManager ); _simulationManager.RegisterEntity("missile1", _missile); diff --git a/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileCodeTests.cs b/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileCodeTests.cs index 5b87b96..95a52c5 100644 --- a/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileCodeTests.cs +++ b/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileCodeTests.cs @@ -111,7 +111,9 @@ namespace ThreatSource.Tests.Missile : base(id, "target1", "missile1", new LaserDesignatorConfig { LaserPower = 100, - LaserDivergenceAngle = 0.001 + LaserDivergenceAngle = 0.001, + MinWavelength = 1.0, + MaxWavelength = 1.1 }, new InitialMotionParameters { Position = new Vector3D(100, 0, 0), diff --git a/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileIntegrationTests.cs b/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileIntegrationTests.cs index ee74407..e4ff4dd 100644 --- a/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileIntegrationTests.cs +++ b/ThreatSource.Tests/src/Missile/LaserSemiActiveGuidedMissileIntegrationTests.cs @@ -76,7 +76,9 @@ namespace ThreatSource.Tests.Missile var laserDesignatorConfig = new LaserDesignatorConfig { LaserPower = 100, - LaserDivergenceAngle = 0.001 + LaserDivergenceAngle = 0.001, + MinWavelength = 1.0, + MaxWavelength = 1.1 }; _laserDesignator = new LaserDesignator( diff --git a/ThreatSource/data/indicators/laser_designators/ld_001.json b/ThreatSource/data/indicators/laser_designators/ld_001.json index a1114b8..bc4b84a 100644 --- a/ThreatSource/data/indicators/laser_designators/ld_001.json +++ b/ThreatSource/data/indicators/laser_designators/ld_001.json @@ -7,6 +7,8 @@ "designatorConfig": { "laserPower": 1000, "laserDivergenceAngle": 0.0002, + "minWavelength": 1.0, + "maxWavelength": 1.1, "laserCodeConfig": { "code": { "codeType": "PRF", diff --git a/ThreatSource/data/missiles/ir_command/irc_001.json b/ThreatSource/data/missiles/ir_command/irc_001.json index fdcf029..a6eaf72 100644 --- a/ThreatSource/data/missiles/ir_command/irc_001.json +++ b/ThreatSource/data/missiles/ir_command/irc_001.json @@ -20,5 +20,8 @@ "trackerSensitivity": null, "commandLatency": null, "irSignature": null + }, + "infraredCommandGuidanceConfig": { + "jammingResistanceThreshold": 1e-3 } } \ No newline at end of file diff --git a/ThreatSource/data/missiles/ir_imaging/itg_001.json b/ThreatSource/data/missiles/ir_imaging/itg_001.json index bbba88d..ee48218 100644 --- a/ThreatSource/data/missiles/ir_imaging/itg_001.json +++ b/ThreatSource/data/missiles/ir_imaging/itg_001.json @@ -28,6 +28,7 @@ "searchRecognitionProbability": 0.6, "trackRecognitionProbability": 0.8, "targetLostTolerance": 0.2, - "lockConfirmationTime": 0.3 + "lockConfirmationTime": 0.3, + "jammingResistanceThreshold": 1e-3 } } \ No newline at end of file diff --git a/ThreatSource/data/missiles/laser_beam_rider/hj10.json b/ThreatSource/data/missiles/laser_beam_rider/hj10.json index dd6edfa..b7a8b2f 100644 --- a/ThreatSource/data/missiles/laser_beam_rider/hj10.json +++ b/ThreatSource/data/missiles/laser_beam_rider/hj10.json @@ -35,6 +35,7 @@ "derivativeGain": 5.0, "nonlinearGain": 0.5, "maxGuidanceAcceleration": 50.0, - "lowPassFilterCoefficient": 0.2 + "lowPassFilterCoefficient": 0.2, + "jammingResistanceThreshold": 1e-3 } } \ No newline at end of file diff --git a/ThreatSource/data/missiles/laser_semi_active/lsgm_001.json b/ThreatSource/data/missiles/laser_semi_active/lsgm_001.json index 9429fe5..bbc0434 100644 --- a/ThreatSource/data/missiles/laser_semi_active/lsgm_001.json +++ b/ThreatSource/data/missiles/laser_semi_active/lsgm_001.json @@ -34,6 +34,7 @@ "reflectionCoefficient": 0.2, "targetReflectiveArea": 1.0, "lockThreshold": 1e-12, - "spotOffsetSensitivity": 0.5 + "spotOffsetSensitivity": 0.5, + "jammingResistanceThreshold": 1e-3 } } \ No newline at end of file diff --git a/ThreatSource/data/missiles/mmw/mmw_001.json b/ThreatSource/data/missiles/mmw/mmw_001.json index eb30a17..799b230 100644 --- a/ThreatSource/data/missiles/mmw/mmw_001.json +++ b/ThreatSource/data/missiles/mmw/mmw_001.json @@ -50,6 +50,7 @@ "monopulseSensitivity": 1, "yawControlEffectiveness": 120.0, - "pitchControlEffectiveness": 150.0 + "pitchControlEffectiveness": 150.0, + "jammingResistanceThreshold": 1e-3 } } \ No newline at end of file diff --git a/ThreatSource/src/Data/Models.cs b/ThreatSource/src/Data/Models.cs index 6509305..43790bd 100644 --- a/ThreatSource/src/Data/Models.cs +++ b/ThreatSource/src/Data/Models.cs @@ -98,6 +98,15 @@ namespace ThreatSource.Data /// public LaserBeamRiderGuidanceSystemConfig? LaserBeamRiderGuidanceConfig { get; set; } + /// + /// 获取或设置红外指令导引配置 + /// + /// + /// 仅当导弹类型为 InfraredCommandGuidance 时有效 + /// 包含红外指令导引系统的性能参数: + /// - 干扰抗性阈值配置 + /// + public InfraredCommandGuidanceConfig? InfraredCommandGuidanceConfig { get; set; } /// /// 获取或设置红外成像导引配置 diff --git a/ThreatSource/src/Data/ThreatSourceFactory.cs b/ThreatSource/src/Data/ThreatSourceFactory.cs index c87c43a..40265ab 100644 --- a/ThreatSource/src/Data/ThreatSourceFactory.cs +++ b/ThreatSource/src/Data/ThreatSourceFactory.cs @@ -64,10 +64,13 @@ namespace ThreatSource.Data ); case MissileType.InfraredCommandGuidance: + if (data.InfraredCommandGuidanceConfig == null) + throw new ArgumentException($"Missing infrared command guidance configuration for missile: {missileModel}"); return new InfraredCommandGuidedMissile( missileId, data.Properties, launchParams, + data.InfraredCommandGuidanceConfig, _simulationManager ); diff --git a/ThreatSource/src/Guidance/BasicGuidanceSystem.cs b/ThreatSource/src/Guidance/BasicGuidanceSystem.cs index 47cb7cb..4bed151 100644 --- a/ThreatSource/src/Guidance/BasicGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/BasicGuidanceSystem.cs @@ -1,7 +1,9 @@ using System; using ThreatSource.Utils; using ThreatSource.Simulation; +using ThreatSource.Jamming; using System.Diagnostics; +using System.Collections.Generic; namespace ThreatSource.Guidance { @@ -14,11 +16,27 @@ namespace ThreatSource.Guidance /// - 运动参数记录 /// - 加速度限制 /// - 比例导引系数 + /// - 干扰处理 /// - 事件发布 /// 是其他具体制导系统的基类 /// - public class BasicGuidanceSystem : SimulationElement, IGuidanceSystem + public class BasicGuidanceSystem : SimulationElement, IGuidanceSystem, IJammable { + /// + /// 干扰处理组件 + /// + protected readonly JammableComponent _jammingComponent; + + /// + /// 获取设备支持的干扰类型 + /// + public IEnumerable SupportedJammingTypes => _jammingComponent.SupportedJammingTypes; + + /// + /// 获取设备当前是否处于被干扰状态 + /// + public bool IsJammed => _jammingComponent.IsJammed; + /// /// 获取或设置父实体ID /// @@ -80,6 +98,7 @@ namespace ThreatSource.Guidance /// - 初始化制导状态 /// - 设置运动参数 /// - 配置制导参数 + /// - 初始化干扰处理 /// public BasicGuidanceSystem(string id, double maxAcceleration, double proportionalNavigationCoefficient, ISimulationManager simulationManager) : base(id, Vector3D.Zero, new Orientation(), 0, simulationManager) @@ -88,6 +107,15 @@ namespace ThreatSource.Guidance GuidanceAcceleration = Vector3D.Zero; MaxAcceleration = maxAcceleration; ProportionalNavigationCoefficient = proportionalNavigationCoefficient; + + // 初始化干扰处理组件 + _jammingComponent = new JammableComponent( + positionProvider: () => base.Position, + onJammingApplied: HandleJammingApplied, + onJammingCleared: HandleJammingCleared + ); + + // 子类需要在构造函数中设置支持的干扰类型和阈值 } /// @@ -100,12 +128,16 @@ namespace ThreatSource.Guidance /// 更新过程: /// - 更新位置信息 /// - 更新速度信息 + /// - 更新干扰状态 /// - 准备制导计算 /// public virtual void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity) { Position = missilePosition; Velocity = missileVelocity; + + // 更新干扰状态 + _jammingComponent.UpdateJammingStatus(deltaTime); } /// @@ -138,24 +170,7 @@ namespace ThreatSource.Guidance { return GuidanceAcceleration; } - - /// - /// 计算制导加速度(需要在子类中实现) - /// - /// 时间间隔,单位:秒 - /// - /// 计算要求: - /// - 实现特定的制导律 - /// - 考虑最大加速度限制 - /// - 更新制导加速度 - /// 基类中不实现具体计算 - /// - protected virtual void CalculateGuidanceAcceleration(double deltaTime) - { - // 基础制导系统不计算制导指令 - // 派生类应该重写这个方法来实现特定的制导逻辑 - } - + /// /// 获取制导系统的状态信息 /// @@ -163,6 +178,7 @@ namespace ThreatSource.Guidance /// /// 返回信息: /// - 制导状态 + /// - 干扰状态 /// - 位置信息 /// - 速度信息 /// - 加速度信息 @@ -170,7 +186,86 @@ namespace ThreatSource.Guidance /// public override string GetStatus() { - return base.GetStatus() + $"导引头状态: 有制导={HasGuidance}, 制导加速度={GuidanceAcceleration}"; + return base.GetStatus() + $"导引头状态: 有制导={HasGuidance}, 被干扰={IsJammed}, 制导加速度={GuidanceAcceleration}"; + } + + /// + /// 设置干扰阈值 + /// + /// 干扰类型 + /// 阈值值(单位:瓦特) + protected void SetJammingThreshold(JammingType type, double threshold) + { + _jammingComponent.SetJammingThreshold(type, threshold); + } + + /// + /// 添加支持的干扰类型 + /// + /// 干扰类型 + /// 干扰阈值(单位:瓦特) + protected void AddSupportedJammingType(JammingType type, double threshold) + { + _jammingComponent.AddSupportedJammingType(type, threshold); + } + + /// + /// 应用干扰 + /// + /// 干扰参数 + public virtual void ApplyJamming(JammingParameters parameters) + { + _jammingComponent.ApplyJamming(parameters); + } + + /// + /// 清除干扰 + /// + /// 要清除的干扰类型 + public virtual void ClearJamming(JammingType type) + { + _jammingComponent.ClearJamming(type); + } + + /// + /// 处理制导系统被干扰的事件 + /// + /// 干扰参数 + protected virtual void HandleJammingApplied(JammingParameters parameters) + { + // 子类可以重写此方法以实现特定的干扰响应 + Console.WriteLine($"导引系统受到{parameters.Type}类型干扰,功率:{parameters.Power}W"); + + // 干扰应用后,设置无有效制导 + HasGuidance = false; + } + + /// + /// 处理制导系统干扰被清除的事件 + /// + /// 被清除的干扰类型 + protected virtual void HandleJammingCleared(JammingType type) + { + // 子类可以重写此方法以实现干扰清除后的特定行为 + Console.WriteLine($"导引系统{type}类型干扰已清除"); + + // 干扰清除后恢复制导状态 + // 注意:实际制导能力需要根据当前情况确定,此处默认为恢复 + HasGuidance = true; + } + + /// + /// 从配置中加载干扰阈值和支持的干扰类型 + /// + /// 配置中的干扰抗性阈值,单位:瓦特 + /// 支持的干扰类型,默认为所有类型 + /// + /// 此方法用于从制导系统配置中加载干扰阈值,使子类可以轻松设置干扰抗性。 + /// + protected void LoadJammingConfigFromThreshold(double jammingResistanceThreshold, + IEnumerable? supportedTypes = null) + { + _jammingComponent.LoadJammingConfigFromThreshold(jammingResistanceThreshold, supportedTypes); } } } diff --git a/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs b/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs index 9ece15b..d4ea08d 100644 --- a/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs @@ -1,5 +1,6 @@ using ThreatSource.Utils; using ThreatSource.Simulation; +using ThreatSource.Jamming; namespace ThreatSource.Guidance { @@ -76,6 +77,7 @@ namespace ThreatSource.Guidance /// 初始化红外指令导引系统的新实例 /// /// 系统标识 + /// 红外指令导引系统配置 /// 最大加速度,单位:米/平方秒 /// 制导系数 /// 模拟管理器 @@ -85,13 +87,14 @@ namespace ThreatSource.Guidance /// - 初始化向量记录 /// - 清零转向速率 /// - public InfraredCommandGuidanceSystem(string id, double maxAcceleration, double guidanceCoefficient, ISimulationManager simulationManager) + public InfraredCommandGuidanceSystem(string id, InfraredCommandGuidanceConfig guidanceConfig, double maxAcceleration, double guidanceCoefficient, ISimulationManager simulationManager) : base(id, maxAcceleration, guidanceCoefficient, simulationManager) { lastTrackerToMissileVector = Vector3D.Zero; lastTrackerToTargetVector = Vector3D.Zero; lastDesiredDirection = Vector3D.Zero; turnRate = 0; + LoadJammingConfigFromThreshold(guidanceConfig.JammingResistanceThreshold, new List { JammingType.Infrared }); } /// @@ -108,7 +111,15 @@ namespace ThreatSource.Guidance public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity) { base.Update(deltaTime, missilePosition, missileVelocity); - CalculateGuidanceAcceleration(deltaTime); + if (!IsJammed) + { + CalculateGuidanceAcceleration(deltaTime); + } + else + { + HasGuidance = false; + GuidanceAcceleration = Vector3D.Zero; + } } /// @@ -141,7 +152,7 @@ namespace ThreatSource.Guidance /// - 生成制导指令 /// - 限制最大加速度 /// - protected override void CalculateGuidanceAcceleration(double deltaTime) + protected void CalculateGuidanceAcceleration(double deltaTime) { if (HasGuidance) { diff --git a/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs b/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs index d951688..bc84f70 100644 --- a/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs @@ -2,6 +2,8 @@ using System; using ThreatSource.Simulation; using ThreatSource.Target; using ThreatSource.Utils; +using ThreatSource.Jamming; +using System.Diagnostics; namespace ThreatSource.Guidance { @@ -125,9 +127,102 @@ namespace ThreatSource.Guidance fieldOfView: guidanceConfig.SearchFieldOfView, backgroundIntensity: guidanceConfig.BackgroundIntensity ); + LoadJammingConfigFromThreshold(guidanceConfig.JammingResistanceThreshold, new List { JammingType.Infrared }); SwitchToSearchMode(); // 初始化为搜索模式 } + /// + /// 处理红外干扰事件 + /// + /// 红外干扰事件数据 + /// + /// 处理过程: + /// - 创建干扰参数 + /// - 使用JammableComponent进行干扰判断 + /// - 更新系统状态 + /// + private void OnInfraredJamming(InfraredJammingEvent evt) + { + if (evt == null) return; + // 创建干扰参数 + var parameters = new JammingParameters + { + Type = JammingType.Infrared, + Power = evt.JammingPower, + Direction = evt.JammingDirection, + SourcePosition = evt.JammingSourcePosition, + AngleRange = evt.JammingAngleRange, + Mode = evt.JammingMode, + Duration = evt.Duration + }; + + // 使用JammableComponent进行干扰判断 + ApplyJamming(parameters); + Debug.WriteLine($"红外引导系统干扰状态 - IsJammed: {IsJammed}, 干扰功率: {evt.JammingPower}W, 抗性阈值: {config.JammingResistanceThreshold}W"); + } + + /// + /// 处理系统被干扰的事件 + /// + /// 干扰参数 + protected override void HandleJammingApplied(JammingParameters parameters) + { + if (parameters.Type == JammingType.Infrared) + { + Debug.WriteLine($"红外引导系统受到红外干扰,功率:{parameters.Power}瓦特"); + // 确保基类的处理逻辑被调用,设置HasGuidance = false + base.HandleJammingApplied(parameters); + + // 在强干扰下切换到搜索模式 + if (currentMode != WorkMode.Search) + { + SwitchToSearchMode(); + } + } + } + + /// + /// 处理系统干扰被清除的事件 + /// + /// 被清除的干扰类型 + protected override void HandleJammingCleared(JammingType type) + { + if (type == JammingType.Infrared) + { + Debug.WriteLine("红外引导系统干扰已清除"); + // 确保基类的处理逻辑被调用 + base.HandleJammingCleared(type); + // 干扰清除后的恢复逻辑 + } + } + + /// + /// 激活引导系统 + /// + public override void Activate() + { + if (!IsActive) + { + IsActive = true; + // 在这里订阅事件,确保只订阅一次 + SimulationManager.SubscribeToEvent(OnInfraredJamming); + } + base.Activate(); + } + + /// + /// 停用引导系统 + /// + public override void Deactivate() + { + if (IsActive) + { + IsActive = false; + SimulationManager.UnsubscribeFromEvent(OnInfraredJamming); + } + base.Deactivate(); + } + /// /// 更新引导系统的状态和计算结果 /// @@ -144,44 +239,51 @@ namespace ThreatSource.Guidance public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity) { base.Update(deltaTime, missilePosition, missileVelocity); - - if (TryDetectAndIdentifyTarget(missilePosition, missileVelocity, deltaTime, out Vector3D tankPosition)) + if (!IsJammed) { - targetLostTimer = 0; // 重置丢失计时器 - //根据目标当前位置和上一次位置计算目标速度 - Vector3D targetVelocity = (tankPosition - lastTargetPosition) / deltaTime; - lastTargetPosition = tankPosition; - - // 使用比例控制算法 - GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation(ProportionalNavigationCoefficient, missilePosition, missileVelocity, tankPosition, targetVelocity); - // 限制最大加速度 - if (GuidanceAcceleration.Magnitude() > MaxAcceleration) + if (TryDetectAndIdentifyTarget(missilePosition, missileVelocity, deltaTime, out Vector3D tankPosition)) { - GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration; - } + targetLostTimer = 0; // 重置丢失计时器 + //根据目标当前位置和上一次位置计算目标速度 + Vector3D targetVelocity = (tankPosition - lastTargetPosition) / deltaTime; + lastTargetPosition = tankPosition; - HasGuidance = true; - } - else - { - // 在跟踪或锁定模式下,增加丢失计时器 - if (currentMode != WorkMode.Search) - { - targetLostTimer += deltaTime; - // 只有当超过容忍时间才认为真正丢失目标 - if (targetLostTimer >= config.TargetLostTolerance) + // 使用比例控制算法 + GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation(ProportionalNavigationCoefficient, missilePosition, missileVelocity, tankPosition, targetVelocity); + // 限制最大加速度 + if (GuidanceAcceleration.Magnitude() > MaxAcceleration) { - HasGuidance = false; - // 切换回搜索模式 - Console.WriteLine($"Target lost for {targetLostTimer:F3}s, switching back to search mode"); - SwitchToSearchMode(); + GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration; } + + HasGuidance = true; } else { - HasGuidance = false; + // 在跟踪或锁定模式下,增加丢失计时器 + if (currentMode != WorkMode.Search) + { + targetLostTimer += deltaTime; + // 只有当超过容忍时间才认为真正丢失目标 + if (targetLostTimer >= config.TargetLostTolerance) + { + HasGuidance = false; + // 切换回搜索模式 + Console.WriteLine($"Target lost for {targetLostTimer:F3}s, switching back to search mode"); + SwitchToSearchMode(); + } + } + else + { + HasGuidance = false; + } } } + else + { + HasGuidance = false; + GuidanceAcceleration = Vector3D.Zero; + } } /// diff --git a/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs b/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs index a9eace3..124715c 100644 --- a/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs @@ -1,6 +1,7 @@ using ThreatSource.Utils; using ThreatSource.Simulation; using System.Diagnostics; +using ThreatSource.Jamming; namespace ThreatSource.Guidance { @@ -182,6 +183,27 @@ namespace ThreatSource.Guidance IsCodeEnabled = true, IsCodeMatchRequired = true }; + LoadJammingConfigFromThreshold(guidanceConfig.JammingResistanceThreshold, new List { JammingType.Laser }); + } + + /// + /// 激活制导系统 + /// + public override void Activate() + { + base.Activate(); + // 在这里订阅事件,确保只订阅一次 + SimulationManager.SubscribeToEvent(OnLaserJamming); + } + + /// + /// 停用制导系统 + /// + public override void Deactivate() + { + base.Deactivate(); + // 取消订阅事件 + SimulationManager.UnsubscribeFromEvent(OnLaserJamming); } /// @@ -352,13 +374,19 @@ namespace ThreatSource.Guidance public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity) { base.Update(deltaTime, missilePosition, missileVelocity); - - if (LaserIlluminationOn) + if (!IsJammed) { - UpdateGuidanceStatus(); - if (HasGuidance) + if (LaserIlluminationOn) { - CalculateGuidanceAcceleration(deltaTime); + UpdateGuidanceStatus(); + if (HasGuidance) + { + CalculateGuidanceAcceleration(deltaTime); + } + else + { + GuidanceAcceleration = Vector3D.Zero; + } } else { @@ -367,6 +395,7 @@ namespace ThreatSource.Guidance } else { + HasGuidance = false; GuidanceAcceleration = Vector3D.Zero; } } @@ -427,7 +456,7 @@ namespace ThreatSource.Guidance /// - 合成最终制导指令 /// - 应用低通滤波 /// - protected override void CalculateGuidanceAcceleration(double deltaTime) + protected void CalculateGuidanceAcceleration(double deltaTime) { if (!HasGuidance) { @@ -484,6 +513,65 @@ namespace ThreatSource.Guidance LastGuidanceAcceleration = GuidanceAcceleration; } + /// + /// 处理激光干扰事件 + /// + /// 激光干扰事件 + private void OnLaserJamming(LaserJammingEvent evt) + { + // 创建干扰参数 + var parameters = new JammingParameters + { + Type = JammingType.Laser, + Power = evt.JammingPower, + Direction = evt.JammingDirection, + SourcePosition = evt.JammingSourcePosition, + AngleRange = evt.JammingAngleRange, + Mode = evt.JammingMode, + Duration = evt.Duration + }; + + // 使用JammableComponent进行干扰判断 + ApplyJamming(parameters); + Debug.WriteLine($"激光驾束制导系统干扰状态 - IsJammed: {IsJammed}, 干扰功率: {evt.JammingPower}W, 抗性阈值: {config.JammingResistanceThreshold}W"); + } + + + /// + /// 处理系统被干扰的事件 + /// + /// 干扰参数 + protected override void HandleJammingApplied(JammingParameters parameters) + { + if (parameters.Type == JammingType.Laser) + { + Debug.WriteLine($"激光驾束制导系统受到激光干扰,功率:{parameters.Power}瓦特"); + // 确保基类的处理逻辑被调用,设置HasGuidance = false + base.HandleJammingApplied(parameters); + + // 在强干扰下切换到搜索模式 + if (LaserIlluminationOn) + { + LaserIlluminationOn = false; + HasGuidance = false; + } + } + } + + /// + /// 处理系统干扰被清除的事件 + /// + /// 被清除的干扰类型 + protected override void HandleJammingCleared(JammingType type) + { + if (type == JammingType.Laser) + { + Debug.WriteLine("激光驾束制导系统干扰已清除"); + // 确保基类的处理逻辑被调用 + base.HandleJammingCleared(type); + } + } + /// /// 获取制导系统的详细状态信息 /// diff --git a/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs b/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs index 127e44f..2d758e1 100644 --- a/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs @@ -3,6 +3,7 @@ using ThreatSource.Simulation; using ThreatSource.Sensor; using ThreatSource.Indicator; using System.Diagnostics; +using ThreatSource.Jamming; namespace ThreatSource.Guidance { @@ -125,6 +126,7 @@ namespace ThreatSource.Guidance /// - 初始化目标信息 /// - 初始化激光参数 /// - 创建四象限探测器 + /// - 加载干扰阈值配置 /// public LaserSemiActiveGuidanceSystem( string id, @@ -151,6 +153,8 @@ namespace ThreatSource.Guidance // 设置光斑偏移灵敏度 SpotOffsetSensitivity = config.SpotOffsetSensitivity; + + LoadJammingConfigFromThreshold(guidanceConfig.JammingResistanceThreshold, new List { JammingType.Laser }); } /// @@ -160,6 +164,7 @@ namespace ThreatSource.Guidance /// 激活过程: /// - 调用基类激活 /// - 订阅激光照射事件 + /// - 订阅激光干扰事件 /// public override void Activate() { @@ -168,6 +173,8 @@ namespace ThreatSource.Guidance SimulationManager.SubscribeToEvent(OnLaserIlluminationStart); SimulationManager.SubscribeToEvent(OnLaserIlluminationUpdate); SimulationManager.SubscribeToEvent(OnLaserIlluminationStop); + // 订阅激光干扰事件 + SimulationManager.SubscribeToEvent(OnLaserJamming); } /// @@ -185,6 +192,7 @@ namespace ThreatSource.Guidance SimulationManager.UnsubscribeFromEvent(OnLaserIlluminationStart); SimulationManager.UnsubscribeFromEvent(OnLaserIlluminationUpdate); SimulationManager.UnsubscribeFromEvent(OnLaserIlluminationStop); + SimulationManager.UnsubscribeFromEvent(OnLaserJamming); } /// @@ -262,6 +270,75 @@ namespace ThreatSource.Guidance HasGuidance = false; // 禁用制导 } + /// + /// 处理激光干扰事件 + /// + /// 激光干扰事件 + private void OnLaserJamming(LaserJammingEvent evt) + { + if (evt == null) return; + + // 创建干扰参数 + var parameters = new JammingParameters + { + Type = JammingType.Laser, + Power = evt.JammingPower, + Direction = evt.JammingDirection, + SourcePosition = evt.JammingSourcePosition, + AngleRange = evt.JammingAngleRange, + Mode = evt.JammingMode, + Duration = evt.Duration + }; + + // 使用JammableComponent进行干扰判断 + ApplyJamming(parameters); + + // 如果被干扰,切换到搜索模式 + if (IsJammed) + { + // 清除目标信息 + TargetPosition = Vector3D.Zero; + LaserIlluminationOn = false; + // 记录干扰信息 + Trace.WriteLine($"激光半主动制导系统被干扰 - 功率: {evt.JammingPower}W, 位置: {evt.JammingSourcePosition}, 方向: {evt.JammingDirection}"); + } + } + + /// + /// 处理系统被干扰的事件 + /// + /// 干扰参数 + protected override void HandleJammingApplied(JammingParameters parameters) + { + if (parameters.Type == JammingType.Laser) + { + Debug.WriteLine($"激光半主动制导系统受到激光干扰,功率:{parameters.Power}瓦特"); + // 确保基类的处理逻辑被调用,设置HasGuidance = false + base.HandleJammingApplied(parameters); + + // 在强干扰下切换到搜索模式 + if (LaserIlluminationOn) + { + LaserIlluminationOn = false; + HasGuidance = false; + } + } + } + + /// + /// 处理系统干扰被清除的事件 + /// + /// 被清除的干扰类型 + protected override void HandleJammingCleared(JammingType type) + { + if (type == JammingType.Laser) + { + Debug.WriteLine("激光半主动制导系统干扰已清除"); + // 确保基类的处理逻辑被调用 + base.HandleJammingCleared(type); + } + } + /// /// 更新激光指示器参数 /// @@ -321,26 +398,33 @@ namespace ThreatSource.Guidance public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity) { base.Update(deltaTime, missilePosition, missileVelocity); - - if (LaserIlluminationOn) + if (!IsJammed) { - // 计算接收到的激光功率 - double receivedPower = CalculateReceivedLaserPower(); - - // 更新四象限探测器 - Vector2D spotOffset = CalculateSpotOffset(); - quadrantDetector.ProcessLaserSignal(receivedPower, spotOffset); - - // 更新制导状态 - bool wasGuidanceEnabled = HasGuidance; - HasGuidance = quadrantDetector.IsTargetLocked; - - if (HasGuidance) + if (LaserIlluminationOn) { - CalculateGuidanceAcceleration(deltaTime); + // 计算接收到的激光功率 + double receivedPower = CalculateReceivedLaserPower(); + + // 更新四象限探测器 + Vector2D spotOffset = CalculateSpotOffset(); + quadrantDetector.ProcessLaserSignal(receivedPower, spotOffset); + + // 更新制导状态 + bool wasGuidanceEnabled = HasGuidance; + HasGuidance = quadrantDetector.IsTargetLocked; + + if (HasGuidance) + { + CalculateGuidanceAcceleration(deltaTime); + } + else + { + GuidanceAcceleration = Vector3D.Zero; + } } else { + HasGuidance = false; GuidanceAcceleration = Vector3D.Zero; } } @@ -348,7 +432,7 @@ namespace ThreatSource.Guidance { HasGuidance = false; GuidanceAcceleration = Vector3D.Zero; - } + } } /// @@ -457,7 +541,7 @@ namespace ThreatSource.Guidance /// - 计算比例导引加速度 /// - 限制最大加速度 /// - protected override void CalculateGuidanceAcceleration(double deltaTime) + protected void CalculateGuidanceAcceleration(double deltaTime) { // 获取当前导弹指向方向 Vector3D currentDirection = Velocity.Normalize(); diff --git a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs index ba1dd15..86da95e 100644 --- a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs @@ -2,6 +2,8 @@ using ThreatSource.Simulation; using ThreatSource.Utils; using ThreatSource.Target; using System.Diagnostics; +using ThreatSource.Jamming; + namespace ThreatSource.Guidance { /// @@ -129,25 +131,7 @@ namespace ThreatSource.Guidance /// private double maxScanRadius => config.FieldOfViewAngle * Math.PI / 180.0 / 2; - /// - /// 激活制导系统 - /// - public override void Activate() - { - base.Activate(); - SwitchToSearchMode(); - } - /// - /// 停用制导系统 - /// - public override void Deactivate() - { - base.Deactivate(); - HasTarget = false; - HasGuidance = false; - GuidanceAcceleration = Vector3D.Zero; - } /// /// 初始化毫米波制导系统的新实例 @@ -163,6 +147,7 @@ namespace ThreatSource.Guidance /// - 设置仿真管理器 /// - 初始化目标位置 /// - 注册干扰事件处理 + /// - 加载干扰阈值配置 /// public MillimeterWaveGuidanceSystem( string id, @@ -176,9 +161,7 @@ namespace ThreatSource.Guidance lastTargetPosition = Vector3D.Zero; lastTargetVelocity = Vector3D.Zero; - // 订阅干扰事件 - simulationManager.SubscribeToEvent(HandleJammingEvent); - + LoadJammingConfigFromThreshold(config.JammingResistanceThreshold, new List { JammingType.MillimeterWave }); SwitchToSearchMode(); // 初始化为搜索模式 } @@ -218,6 +201,37 @@ namespace ThreatSource.Guidance Trace.WriteLine("切换到锁定模式 - 目标锁定成功"); } + /// + /// 激活制导系统 + /// + public override void Activate() + { + if (!IsActive) + { + IsActive = true; + // 在这里订阅事件,确保只订阅一次 + SimulationManager.SubscribeToEvent(OnMillimeterWaveJamming); + } + base.Activate(); + SwitchToSearchMode(); + } + + /// + /// 停用制导系统 + /// + public override void Deactivate() + { + if (IsActive) + { + IsActive = false; + SimulationManager.UnsubscribeFromEvent(OnMillimeterWaveJamming); + } + base.Deactivate(); + HasTarget = false; + HasGuidance = false; + GuidanceAcceleration = Vector3D.Zero; + } + /// /// 处理毫米波干扰事件 /// @@ -227,10 +241,57 @@ namespace ThreatSource.Guidance /// - 更新干扰状态 /// - 记录干扰功率 /// - private void HandleJammingEvent(MillimeterWaveJammingEvent evt) + private void OnMillimeterWaveJamming(MillimeterWaveJammingEvent evt) { - isJammed = true; - jammingPower = evt.JammingPower; + if (evt == null) return; + + // 创建干扰参数 + var parameters = new JammingParameters + { + Type = JammingType.MillimeterWave, + Power = evt.JammingPower, + Direction = evt.JammingDirection, + SourcePosition = evt.JammingSourcePosition, + AngleRange = evt.JammingAngleRange, + Mode = evt.JammingMode, + Duration = evt.Duration + }; + + // 使用JammableComponent进行干扰判断 + ApplyJamming(parameters); + Debug.WriteLine($"毫米波导引头系统干扰状态 - IsJammed: {IsJammed}, 干扰功率: {evt.JammingPower}W, 抗性阈值: {config.JammingResistanceThreshold}W"); + } + + /// + /// 处理系统被干扰的事件 + /// + /// 干扰参数 + protected override void HandleJammingApplied(JammingParameters parameters) + { + if (parameters.Type == JammingType.MillimeterWave) + { + Debug.WriteLine($"毫米波导引头系统受到毫米波干扰,功率:{parameters.Power}瓦特"); + // 确保基类的处理逻辑被调用,设置HasGuidance = false + base.HandleJammingApplied(parameters); + } + // 在强干扰下切换到搜索模式 + if (currentMode != WorkMode.Search) + { + SwitchToSearchMode(); + } + } + + /// + /// 处理系统干扰被清除的事件 + /// + /// 被清除的干扰类型 + protected override void HandleJammingCleared(JammingType type) + { + if (type == JammingType.MillimeterWave) + { + Debug.WriteLine("毫米波导引头系统干扰被清除"); + base.HandleJammingCleared(type); + } } /// @@ -388,49 +449,57 @@ namespace ThreatSource.Guidance base.Update(deltaTime, missilePosition, missileVelocity); - if (TryDetectAndTrackTarget(missilePosition, missileVelocity, deltaTime, out Vector3D targetPosition)) + if (!IsJammed) { - targetLostTimer = 0; - Vector3D targetVelocity = (targetPosition - lastTargetPosition) / deltaTime; - lastTargetPosition = targetPosition; - lastTargetVelocity = targetVelocity; - - // 使用比例导引计算制导加速度 - GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation( - ProportionalNavigationCoefficient, - missilePosition, - missileVelocity, - targetPosition, - targetVelocity - ); - - // 限制最大加速度 - if (GuidanceAcceleration.Magnitude() > MaxAcceleration) + if (TryDetectAndTrackTarget(missilePosition, missileVelocity, deltaTime, out Vector3D targetPosition)) { - GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration; - } + targetLostTimer = 0; + Vector3D targetVelocity = (targetPosition - lastTargetPosition) / deltaTime; + lastTargetPosition = targetPosition; + lastTargetVelocity = targetVelocity; - Console.WriteLine($"制导加速度: {GuidanceAcceleration}"); - HasGuidance = true; - } - else - { - if (currentMode != WorkMode.Search) - { - targetLostTimer += deltaTime; - // 如果目标丢失时间达到阈值,切换回搜索模式 - if (targetLostTimer >= config.TargetLostTolerance) + // 使用比例导引计算制导加速度 + GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation( + ProportionalNavigationCoefficient, + missilePosition, + missileVelocity, + targetPosition, + targetVelocity + ); + + // 限制最大加速度 + if (GuidanceAcceleration.Magnitude() > MaxAcceleration) { - HasGuidance = false; - Trace.WriteLine($"目标丢失 {targetLostTimer:F3}秒,切换回搜索模式"); - SwitchToSearchMode(); + GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration; } + + Console.WriteLine($"制导加速度: {GuidanceAcceleration}"); + HasGuidance = true; } else { - HasGuidance = false; + if (currentMode != WorkMode.Search) + { + targetLostTimer += deltaTime; + // 如果目标丢失时间达到阈值,切换回搜索模式 + if (targetLostTimer >= config.TargetLostTolerance) + { + HasGuidance = false; + Trace.WriteLine($"目标丢失 {targetLostTimer:F3}秒,切换回搜索模式"); + SwitchToSearchMode(); + } + } + else + { + HasGuidance = false; + } } } + else + { + HasGuidance = false; + GuidanceAcceleration = Vector3D.Zero; + } } /// diff --git a/ThreatSource/src/Indicator/IndicatorBase.cs b/ThreatSource/src/Indicator/IndicatorBase.cs index bae11f4..8438704 100644 --- a/ThreatSource/src/Indicator/IndicatorBase.cs +++ b/ThreatSource/src/Indicator/IndicatorBase.cs @@ -15,16 +15,12 @@ namespace ThreatSource.Indicator /// - 干扰处理机制 /// 是具体指示器类的实现基础 /// - public abstract class IndicatorBase : SimulationElement, IIndicator + public abstract class IndicatorBase : SimulationElement, IIndicator, IJammable { /// - /// 干扰处理器 + /// 干扰处理组件 /// - /// - /// 负责处理各类干扰对指示器的影响 - /// 管理干扰状态和恢复 - /// - private protected JammingHandler? JammingHandler { get; set; } + protected readonly JammableComponent _jammingComponent; /// /// 获取设备支持的干扰类型 @@ -42,7 +38,7 @@ namespace ThreatSource.Indicator /// true表示指示器当前受到干扰影响 /// false表示指示器正常工作 /// - public bool IsJammed => JammingHandler?.IsJammed ?? false; + public bool IsJammed => _jammingComponent.IsJammed; /// /// 获取或设置目标ID @@ -66,22 +62,18 @@ namespace ThreatSource.Indicator /// 构造过程: /// - 调用基类构造器 /// - 初始化基本属性 - /// - 初始化干扰处理器 + /// - 初始化干扰处理组件 /// protected IndicatorBase(string id, Vector3D position, Orientation orientation, double initialSpeed, ISimulationManager manager) : base(id, position, orientation, initialSpeed, manager) { - InitializeJammingHandler(); + _jammingComponent = new JammableComponent( + positionProvider: () => base.Position, + onJammingApplied: HandleJammingApplied, + onJammingCleared: HandleJammingCleared + ); } - /// - /// 初始化干扰处理器 - /// - /// - /// 子类需要重写此方法以初始化适合自身的干扰处理器 - /// - protected abstract void InitializeJammingHandler(); - /// /// 应用干扰 /// @@ -92,10 +84,7 @@ namespace ThreatSource.Indicator /// public virtual void ApplyJamming(JammingParameters parameters) { - if (SupportedJammingTypes.Contains(parameters.Type)) - { - JammingHandler?.HandleJamming(parameters); - } + _jammingComponent.ApplyJamming(parameters); } /// @@ -108,10 +97,27 @@ namespace ThreatSource.Indicator /// public virtual void ClearJamming(JammingType type) { - if (SupportedJammingTypes.Contains(type)) - { - JammingHandler?.ClearJamming(); - } + _jammingComponent.ClearJamming(type); + } + + /// + /// 处理指示器被干扰的事件 + /// + /// 干扰参数 + protected virtual void HandleJammingApplied(JammingParameters parameters) + { + // 子类可以重写此方法以实现特定的干扰响应 + Console.WriteLine($"指示器受到{parameters.Type}类型干扰,功率:{parameters.Power}W"); + } + + /// + /// 处理指示器干扰被清除的事件 + /// + /// 被清除的干扰类型 + protected virtual void HandleJammingCleared(JammingType type) + { + // 子类可以重写此方法以实现干扰清除后的特定行为 + Console.WriteLine($"指示器{type}类型干扰已清除"); } /// @@ -120,15 +126,14 @@ namespace ThreatSource.Indicator /// 时间步长,单位:秒 /// /// 更新过程: - /// - 调用基类的更新方法 /// - 检查激活状态 /// - 更新干扰状态 /// - 处理指示器特定逻辑 /// public override void Update(double deltaTime) { - // 首先更新干扰状态,无论设备是否激活 - JammingHandler?.Update(deltaTime); + // 更新干扰状态 + _jammingComponent.UpdateJammingStatus(deltaTime); if (IsActive) { diff --git a/ThreatSource/src/Indicator/InfraredTracker.cs b/ThreatSource/src/Indicator/InfraredTracker.cs index 01e8ec1..34f4e60 100644 --- a/ThreatSource/src/Indicator/InfraredTracker.cs +++ b/ThreatSource/src/Indicator/InfraredTracker.cs @@ -76,17 +76,9 @@ namespace ThreatSource.Indicator MissileId = null; this.config = config; IsTracking = false; - } - - /// - /// 初始化干扰处理器 - /// - /// - /// 创建适用于红外测角仪的干扰处理器 - /// - protected override void InitializeJammingHandler() - { - JammingHandler = new InfraredTrackerJammingHandler(this); + + // 设置干扰阈值并添加支持的干扰类型 + _jammingComponent.LoadJammingConfigFromThreshold(config.JammingResistanceThreshold, new List { JammingType.Infrared }); } /// @@ -273,74 +265,40 @@ namespace ThreatSource.Indicator /// private void OnInfraredJamming(InfraredJammingEvent evt) { - // 计算干扰源与测角仪的相对位置 - Vector3D relativePosition = evt.JammingSourcePosition - Position; - double distance = relativePosition.Magnitude(); - - // 计算干扰源与测角仪的相对方向 - Vector3D jammingToTracker = relativePosition.Normalize(); - - // 计算干扰方向与干扰源到测角仪方向的夹角 - // 注意:干扰源到测角仪的方向应该与干扰方向相反 - double angle = Math.Acos(-Vector3D.DotProduct(evt.JammingDirection.Normalize(), jammingToTracker)); - - Debug.WriteLine($"干扰判断 - 距离: {distance:F2}米, 夹角: {angle * 180 / Math.PI:F2}度, 角度范围: {evt.JammingAngleRange * 180 / Math.PI:F2}度"); - - // 判断是否在干扰角度范围内 - if (angle <= evt.JammingAngleRange) + // 创建干扰参数 + var parameters = new JammingParameters { - // 计算距离衰减后的实际干扰功率 - double attenuatedPower = evt.JammingPower / (distance * distance); - - // 检查测角仪工作波段是否在干扰波长范围内 - bool isWavelengthInRange = IsWavelengthInRange(evt.WavelengthMin, evt.WavelengthMax); - - Debug.WriteLine($"干扰功率 - 原始: {evt.JammingPower:F2}W, 衰减后: {attenuatedPower:F2}W, 阈值: {config.JammingResistanceThreshold:F2}W"); - Debug.WriteLine($"波长范围 - 干扰: {evt.WavelengthMin:F2}-{evt.WavelengthMax:F2}μm, 匹配: {isWavelengthInRange}"); - - // 如果功率足够且波长匹配,则应用干扰 - if (attenuatedPower >= config.JammingResistanceThreshold && isWavelengthInRange) - { - Debug.WriteLine("应用干扰 - 条件满足,创建干扰参数"); - - // 创建干扰参数对象 - var jammingParameters = new JammingParameters - { - Type = JammingType.Infrared, - Power = attenuatedPower, - Direction = evt.JammingDirection, - AngleRange = evt.JammingAngleRange, - Mode = evt.JammingMode, - Duration = evt.Duration - }; - - // 应用干扰 - ApplyJamming(jammingParameters); - Debug.WriteLine($"干扰状态 - IsJammed: {IsJammed}"); - } - else - { - Debug.WriteLine($"不满足干扰条件 - 功率不足或波长不匹配"); - } - } - else + Type = JammingType.Infrared, + Power = evt.JammingPower, + Direction = evt.JammingDirection, + SourcePosition = evt.JammingSourcePosition, + AngleRange = evt.JammingAngleRange, + Mode = evt.JammingMode, + Duration = evt.Duration + }; + + // 检查波长匹配(红外特定逻辑) + bool isWavelengthInRange = IsWavelengthInRange(evt.Wavelength); + + // 使用JammableComponent进行干扰判断 + if (isWavelengthInRange) { - Debug.WriteLine($"不在干扰角度范围内"); + ApplyJamming(parameters); + Debug.WriteLine($"干扰状态 - IsJammed: {IsJammed}"); } } /// /// 检查干扰波长是否在测角仪工作波段范围内 /// - /// 最小波长(微米) - /// 最大波长(微米) + /// 波长(微米) /// 如果波长范围有重叠则返回true - private static bool IsWavelengthInRange(double minWavelength, double maxWavelength) + private static bool IsWavelengthInRange(double wavelength) { // 假设红外测角仪的工作波段为3-5μm(中波红外)和8-14μm(长波红外) // 这里应根据实际的红外测角仪配置来判断 - return (minWavelength <= 5 && maxWavelength >= 3) || // 中波红外 - (minWavelength <= 14 && maxWavelength >= 8); // 长波红外 + return (wavelength >= 3 && wavelength <= 5) || // 中波红外 + (wavelength >= 8 && wavelength <= 14); // 长波红外 } /// @@ -392,5 +350,32 @@ namespace ThreatSource.Indicator $" 跟踪状态: {(IsTracking ? "跟踪中" : "未跟踪")}\n" + $" 干扰状态: {(IsJammed ? "受干扰" : "正常")}\n"; } + + /// + /// 处理指示器被干扰的事件 + /// + /// 干扰参数 + protected override void HandleJammingApplied(JammingParameters parameters) + { + // 记录干扰信息 + Debug.WriteLine($"红外测角仪受到干扰,功率:{parameters.Power}瓦特,类型:{parameters.Type}"); + + // 如果是红外干扰,则停止跟踪 + if (parameters.Type == JammingType.Infrared) + { + // 停止跟踪功能 + StopTracking(); + } + } + + /// + /// 处理指示器干扰被清除的事件 + /// + /// 被清除的干扰类型 + protected override void HandleJammingCleared(JammingType type) + { + Debug.WriteLine("红外测角仪干扰已清除"); + // 不需要特殊的恢复操作,因为tracker会在Update中自动恢复跟踪能力 + } } } diff --git a/ThreatSource/src/Indicator/LaserBeamRider.cs b/ThreatSource/src/Indicator/LaserBeamRider.cs index 2e1711f..84fd49a 100644 --- a/ThreatSource/src/Indicator/LaserBeamRider.cs +++ b/ThreatSource/src/Indicator/LaserBeamRider.cs @@ -39,17 +39,6 @@ namespace ThreatSource.Indicator /// public double JammingThreshold { get; private set; } = 0.0; - /// - /// 初始化干扰处理器 - /// - /// - /// 创建适用于激光波束制导器的干扰处理器 - /// - protected override void InitializeJammingHandler() - { - JammingHandler = new LaserBeamRiderJammingHandler(this); - } - /// /// 获取或设置激光功率 /// @@ -142,7 +131,9 @@ namespace ThreatSource.Indicator TargetId = targetId; LaserCodeConfig = config.LaserCodeConfig; JammingThreshold = config.JammingResistanceThreshold; - base.SimulationManager = simulationManager; + + // 设置干扰阈值并添加支持的干扰类型 + _jammingComponent.LoadJammingConfigFromThreshold(JammingThreshold, new List { JammingType.Laser }); } /// @@ -250,52 +241,26 @@ namespace ThreatSource.Indicator /// private void OnLaserJamming(LaserJammingEvent evt) { - // 计算干扰源与激光驾束仪的相对位置 - Vector3D relativePosition = evt.JammingSourcePosition - Position; - double distance = relativePosition.Magnitude(); - - // 计算干扰源与激光驾束仪的相对方向 - Vector3D jammingToBeamRider = relativePosition.Normalize(); - - // 计算干扰方向与干扰源到激光驾束仪方向的夹角 - double angle = Math.Acos(-Vector3D.DotProduct(evt.JammingDirection.Normalize(), jammingToBeamRider)); - - Debug.WriteLine($"激光干扰判断 - 距离: {distance:F2}米, 夹角: {angle * 180 / Math.PI:F2}度, 角度范围: {evt.JammingAngleRange * 180 / Math.PI:F2}度"); - - // 判断是否在干扰角度范围内 - if (angle <= evt.JammingAngleRange) + // 创建干扰参数 + var parameters = new JammingParameters { - // 计算距离衰减后的实际干扰功率 - double attenuatedPower = evt.JammingPower / (distance * distance); - - // 检查波长是否匹配(假设激光驾束仪工作在1.06微米波长) - bool isWavelengthInRange = evt.WavelengthMin <= 1.1 && evt.WavelengthMax >= 1.0; - - Debug.WriteLine($"激光干扰功率 - 原始: {evt.JammingPower:F2}W, 衰减后: {attenuatedPower:F2}W, 阈值: {JammingThreshold:F2}W"); - Debug.WriteLine($"波长范围 - 干扰: {evt.WavelengthMin:F2}-{evt.WavelengthMax:F2}μm, 匹配: {isWavelengthInRange}"); - - // 如果功率足够且波长匹配,则应用干扰 - if (attenuatedPower >= JammingThreshold && isWavelengthInRange) - { - Debug.WriteLine("应用激光干扰 - 条件满足,创建干扰参数"); - - // 创建干扰参数对象 - var jammingParameters = new JammingParameters - { - Type = JammingType.Laser, - Power = attenuatedPower, - Direction = evt.JammingDirection, - AngleRange = evt.JammingAngleRange, - Mode = evt.JammingMode, - Duration = evt.Duration - }; - - // 应用干扰 - ApplyJamming(jammingParameters); - Debug.WriteLine($"干扰状态 - IsJammed: {IsJammed}"); - - // 注意:停止激光束照射的逻辑已移至LaserBeamRiderJammingHandler.OnJammingApplied方法中 - } + Type = JammingType.Laser, + Power = evt.JammingPower, + Direction = evt.JammingDirection, + SourcePosition = evt.JammingSourcePosition, + AngleRange = evt.JammingAngleRange, + Mode = evt.JammingMode, + Duration = evt.Duration + }; + + // 检查波长匹配(激光特定逻辑) + bool isWavelengthInRange = evt.Wavelength >= 1.0 && evt.Wavelength <= 1.1; + + // 使用JammableComponent进行干扰判断 + if (isWavelengthInRange) + { + ApplyJamming(parameters); + Debug.WriteLine($"干扰状态 - IsJammed: {IsJammed}"); } } @@ -436,5 +401,40 @@ namespace ThreatSource.Indicator $" 控制场直径: {ControlFieldDiameter} m\n" + $" 最大导引距离: {MaxGuidanceDistance} m\n"; } + + /// + /// 处理指示器被干扰的事件 + /// + /// 干扰参数 + protected override void HandleJammingApplied(JammingParameters parameters) + { + // 记录干扰信息 + Debug.WriteLine($"激光驾束仪受到干扰,功率:{parameters.Power}瓦特,类型:{parameters.Type}"); + + // 如果是激光干扰,则停止激光束照射 + if (parameters.Type == JammingType.Laser) + { + // 在干扰期间停止激光束照射 + StopBeamIllumination(); + } + } + + /// + /// 处理指示器干扰被清除的事件 + /// + /// 被清除的干扰类型 + protected override void HandleJammingCleared(JammingType type) + { + if (type == JammingType.Laser) + { + Debug.WriteLine("激光驾束仪干扰已清除"); + + // 在驾束仪仍然处于激活状态时,恢复激光束照射 + if (IsActive) + { + StartBeamIllumination(); + } + } + } } } diff --git a/ThreatSource/src/Indicator/LaserDesignator.cs b/ThreatSource/src/Indicator/LaserDesignator.cs index dc9ca3c..6f1fdcd 100644 --- a/ThreatSource/src/Indicator/LaserDesignator.cs +++ b/ThreatSource/src/Indicator/LaserDesignator.cs @@ -31,17 +31,6 @@ namespace ThreatSource.Indicator JammingType.Laser }; - /// - /// 初始化干扰处理器 - /// - /// - /// 创建适用于激光指示器的干扰处理器 - /// - protected override void InitializeJammingHandler() - { - JammingHandler = new LaserDesignatorJammingHandler(this); - } - /// /// 获取或设置干扰阈值,单位:分贝 /// @@ -91,6 +80,24 @@ namespace ThreatSource.Indicator /// public LaserCodeConfig LaserCodeConfig { get; set; } + /// + /// 获取或设置最小工作波长,单位:微米 + /// + /// + /// 指示器工作所需的最小波长 + /// 用于波长范围匹配检查 + /// + public double MinWavelength { get; private set; } = 1.0; + + /// + /// 获取或设置最大工作波长,单位:微米 + /// + /// + /// 指示器工作所需的最大波长 + /// 用于波长范围匹配检查 + /// + public double MaxWavelength { get; private set; } = 1.1; + /// /// 初始化激光指示器的新实例 /// @@ -118,26 +125,11 @@ namespace ThreatSource.Indicator LaserDivergenceAngle = config.LaserDivergenceAngle; LaserCodeConfig = config.LaserCodeConfig; JammingThreshold = config.JammingResistanceThreshold; - } - - /// - /// 根据目标计算指示器朝向 - /// - /// 位置 - /// 目标ID - /// 仿真管理器 - /// 初始朝向 - private static Orientation CalculateInitialOrientation(Vector3D position, string targetId, ISimulationManager simulationManager) - { - var target = simulationManager.GetEntityById(targetId) as SimulationElement; - if (target != null) - { - Vector3D direction = (target.Position - position).Normalize(); - double yaw = Math.PI + Math.Atan2(direction.Z, direction.X); - double pitch = -Math.Asin(direction.Y); - return new Orientation(yaw, pitch, 0); - } - return new Orientation(Math.PI, 0, 0); // 默认朝向后方 + MinWavelength = config.MinWavelength; + MaxWavelength = config.MaxWavelength; + + // 设置干扰阈值并添加支持的干扰类型 + _jammingComponent.LoadJammingConfigFromThreshold(JammingThreshold, new List { JammingType.Laser }); } /// @@ -229,58 +221,55 @@ namespace ThreatSource.Indicator /// private void OnLaserJamming(LaserJammingEvent evt) { - // 计算干扰源与激光指示器的相对位置 - Vector3D relativePosition = evt.JammingSourcePosition - Position; - double distance = relativePosition.Magnitude(); - - // 计算干扰源与激光指示器的相对方向 - Vector3D jammingToDesignator = relativePosition.Normalize(); - - // 计算干扰方向与干扰源到激光指示器方向的夹角 - double angle = Math.Acos(-Vector3D.DotProduct(evt.JammingDirection.Normalize(), jammingToDesignator)); - - Debug.WriteLine($"激光干扰判断 - 距离: {distance:F2}米, 夹角: {angle * 180 / Math.PI:F2}度, 角度范围: {evt.JammingAngleRange * 180 / Math.PI:F2}度"); - - // 判断是否在干扰角度范围内 - if (angle <= evt.JammingAngleRange) + // 创建干扰参数 + var parameters = new JammingParameters { - // 计算距离衰减后的实际干扰功率 - double attenuatedPower = evt.JammingPower / (distance * distance); - - // 检查波长是否匹配(假设激光指示器工作在1.06微米波长) - bool isWavelengthInRange = evt.WavelengthMin <= 1.1 && evt.WavelengthMax >= 1.0; - - Debug.WriteLine($"激光干扰功率 - 原始: {evt.JammingPower:F2}W, 衰减后: {attenuatedPower:F2}W, 阈值: {JammingThreshold:F2}W"); - Debug.WriteLine($"波长范围 - 干扰: {evt.WavelengthMin:F2}-{evt.WavelengthMax:F2}μm, 匹配: {isWavelengthInRange}"); - - // 如果功率足够且波长匹配,则应用干扰 - if (attenuatedPower >= JammingThreshold && isWavelengthInRange) - { - Debug.WriteLine("应用激光干扰 - 条件满足,创建干扰参数"); - - // 创建干扰参数对象 - var jammingParameters = new JammingParameters - { - Type = JammingType.Laser, - Power = attenuatedPower, - Direction = evt.JammingDirection, - AngleRange = evt.JammingAngleRange, - Mode = evt.JammingMode, - Duration = evt.Duration - }; - - // 应用干扰 - ApplyJamming(jammingParameters); - Debug.WriteLine($"干扰状态 - IsJammed: {IsJammed}"); - } - else - { - Debug.WriteLine($"不满足干扰条件 - 功率不足或波长不匹配"); - } + Type = JammingType.Laser, + Power = evt.JammingPower, + Direction = evt.JammingDirection, + SourcePosition = evt.JammingSourcePosition, + AngleRange = evt.JammingAngleRange, + Mode = evt.JammingMode, + Duration = evt.Duration + }; + + // 检查波长匹配(激光特定逻辑) + bool isWavelengthInRange = evt.Wavelength >= MinWavelength && evt.Wavelength <= MaxWavelength; + + // 使用JammableComponent进行干扰判断 + if (isWavelengthInRange) + { + ApplyJamming(parameters); + Debug.WriteLine($"干扰状态 - IsJammed: {IsJammed}"); } - else + } + + /// + /// 处理指示器被干扰的事件 + /// + /// 干扰参数 + protected override void HandleJammingApplied(JammingParameters parameters) + { + // 实现激光指示器的干扰效果 + if (parameters.Type == JammingType.Laser) { - Debug.WriteLine($"不在干扰角度范围内"); + Debug.WriteLine($"激光指示器受到激光干扰,功率:{parameters.Power}瓦特"); + // 停止激光照射 + StopLaserIllumination(); + } + } + + /// + /// 处理指示器干扰被清除的事件 + /// + /// 被清除的干扰类型 + protected override void HandleJammingCleared(JammingType type) + { + Debug.WriteLine("激光指示器干扰已清除"); + // 如果设备仍处于激活状态,恢复激光照射 + if (IsActive) + { + StartLaserIllumination(); } } diff --git a/ThreatSource/src/Jamming/InfraredTrackerJammingHandler.cs b/ThreatSource/src/Jamming/InfraredTrackerJammingHandler.cs deleted file mode 100644 index 5ce93fd..0000000 --- a/ThreatSource/src/Jamming/InfraredTrackerJammingHandler.cs +++ /dev/null @@ -1,66 +0,0 @@ -using ThreatSource.Indicator; -using System.Diagnostics; - -namespace ThreatSource.Jamming -{ - /// - /// 红外测角仪干扰处理器 - /// - /// - /// 处理红外测角仪的干扰效果: - /// - 降低跟踪精度 - /// - 影响目标识别 - /// - 干扰制导指令 - /// - public class InfraredTrackerJammingHandler : JammingHandler - { - private readonly InfraredTracker tracker; - - /// - /// 初始化红外测角仪干扰处理器的新实例 - /// - /// 要处理的红外测角仪 - public InfraredTrackerJammingHandler(InfraredTracker tracker) - { - this.tracker = tracker; - } - - /// - /// 当干扰被应用时调用 - /// - /// 干扰参数 - /// - /// 实现干扰效果: - /// - 暂停跟踪功能 - /// - 降低测量精度 - /// - 影响目标识别 - /// - protected override void OnJammingApplied(JammingParameters parameters) - { - // 实现红外测角仪的干扰效果 - // 可以根据干扰类型实现不同的干扰效果 - if (parameters.Type == JammingType.Infrared) - { - Debug.WriteLine($"红外测角仪受到红外干扰,功率:{parameters.Power}瓦特"); - // 停止跟踪功能 - tracker.StopTracking(); - } - } - - /// - /// 当干扰被清除时调用 - /// - /// 被清除的干扰参数 - /// - /// 恢复设备功能: - /// - 恢复跟踪能力 - /// - 恢复正常精度 - /// - 重新开始工作 - /// - protected override void OnJammingCleared(JammingParameters? parameters) - { - Debug.WriteLine("红外测角仪干扰已清除"); - // 不需要特殊的恢复操作,因为tracker会在Update中自动恢复跟踪能力 - } - } -} \ No newline at end of file diff --git a/ThreatSource/src/Jamming/JammableComponent.cs b/ThreatSource/src/Jamming/JammableComponent.cs new file mode 100644 index 0000000..81d480a --- /dev/null +++ b/ThreatSource/src/Jamming/JammableComponent.cs @@ -0,0 +1,369 @@ +using System; +using System.Collections.Generic; +using ThreatSource.Utils; + +namespace ThreatSource.Jamming +{ + /// + /// 可干扰组件,提供统一的干扰处理功能 + /// + /// + /// 该类为所有可干扰设备提供了通用的干扰处理实现: + /// - 干扰类型管理 + /// - 干扰阈值设置 + /// - 干扰应用和清除 + /// - 干扰状态更新 + /// + /// 通过组合方式使用,不需要继承,可与现有的继承结构共存 + /// + public class JammableComponent : IJammable + { + /// + /// 干扰处理器接口,用于处理实际的干扰逻辑 + /// + protected interface IJammingProcessor + { + /// + /// 获取当前是否处于被干扰状态 + /// + bool IsJammed { get; } + + /// + /// 设置干扰阈值 + /// + /// 干扰类型 + /// 阈值值(单位:瓦特) + void SetJammingThreshold(JammingType type, double threshold); + + /// + /// 处理干扰 + /// + /// 干扰参数 + /// 干扰是否生效 + bool HandleJamming(JammingParameters parameters); + + /// + /// 清除干扰 + /// + void ClearJamming(); + + /// + /// 更新干扰状态 + /// + /// 时间步长,单位:秒 + void Update(double deltaTime); + } + + /// + /// 干扰处理器实现,使用通用的JammingHandler并增强其功能 + /// + protected class JammingProcessor : IJammingProcessor + { + private readonly JammingHandler _jammingHandler; + private readonly Dictionary _jammingThresholds = new Dictionary(); + private readonly JammableComponent _owner; + + /// + /// 获取当前是否处于被干扰状态 + /// + public bool IsJammed => _jammingHandler.IsJammed; + + /// + /// 初始化干扰处理器实例 + /// + /// 所属的可干扰组件 + public JammingProcessor(JammableComponent owner) + { + _owner = owner; + _jammingHandler = new JammingHandlerAdapter(this); + } + + /// + /// 设置干扰阈值 + /// + /// 干扰类型 + /// 阈值值(单位:瓦特) + public void SetJammingThreshold(JammingType type, double threshold) + { + _jammingThresholds[type] = threshold; + } + + /// + /// 判断干扰是否有效(是否超过阈值) + /// + /// 干扰参数 + /// 如果干扰有效返回true,否则返回false + public bool IsJammingEffective(JammingParameters parameters) + { + // 检查是否支持该干扰类型 + if (!_jammingThresholds.TryGetValue(parameters.Type, out double threshold)) + { + return false; // 不支持的干扰类型 + } + + // 计算干扰源与设备之间的矢量 + Vector3D devicePosition = _owner._positionProvider(); + Vector3D relativePosition = devicePosition - parameters.SourcePosition; // 从干扰源指向设备 + double distance = relativePosition.Magnitude(); + + System.Diagnostics.Debug.WriteLine($"干扰计算 - 设备位置: {devicePosition}, 干扰源位置: {parameters.SourcePosition}"); + System.Diagnostics.Debug.WriteLine($"干扰计算 - 相对位置: {relativePosition}, 距离: {distance:F2}m"); + + if (distance <= 0) + { + distance = 0.1; // 避免除零错误,设置最小距离 + } + + // 使用球面扩散模型计算接收功率 + // P_received = P_transmitted / (4πd²) + double receivedPower = parameters.Power / (4 * Math.PI * distance * distance); + + System.Diagnostics.Debug.WriteLine($"干扰计算 - 发射功率: {parameters.Power:F2}W, 接收功率: {receivedPower:F2}W, 阈值: {threshold:F2}W"); + + // 计算角度因素(如果干扰波束有方向性) + if (parameters.AngleRange > 0 && distance > 1) + { + // 计算干扰方向与干扰源到设备方向的夹角 + Vector3D jammingToDevice = relativePosition.Normalize(); + double dotProduct = Vector3D.DotProduct(parameters.Direction.Normalize(), jammingToDevice); + double angle = Math.Acos(dotProduct); + + System.Diagnostics.Debug.WriteLine($"干扰计算 - 干扰方向: {parameters.Direction}, 到设备方向: {jammingToDevice}"); + System.Diagnostics.Debug.WriteLine($"干扰计算 - 点积: {dotProduct:F2}, 夹角: {angle * 180 / Math.PI:F2}°, 波束范围: {parameters.AngleRange * 180 / Math.PI:F2}°"); + + // 如果夹角超出干扰波束范围,降低接收功率 + if (angle > parameters.AngleRange / 2 && angle < Math.PI - parameters.AngleRange / 2) + { + // 简化模型:角度衰减,超出波束范围接收功率迅速降低 + receivedPower *= 0.1; + System.Diagnostics.Debug.WriteLine($"干扰计算 - 超出波束范围,功率衰减: {receivedPower:F2}W"); + } + } + + // 比较接收功率与阈值 + bool isEffective = receivedPower >= threshold; + System.Diagnostics.Debug.WriteLine($"干扰计算 - 最终结果: {(isEffective ? "有效" : "无效")}"); + return isEffective; + } + + /// + /// 处理干扰 + /// + /// 干扰参数 + /// 干扰是否生效 + public bool HandleJamming(JammingParameters parameters) + { + // 只有当干扰有效时才处理 + if (IsJammingEffective(parameters)) + { + _jammingHandler.HandleJamming(parameters); + return true; + } + return false; + } + + /// + /// 清除干扰 + /// + public void ClearJamming() + { + _jammingHandler.ClearJamming(); + } + + /// + /// 更新干扰状态 + /// + /// 时间步长,单位:秒 + public void Update(double deltaTime) + { + _jammingHandler.Update(deltaTime); + } + + /// + /// JammingHandler适配器类,用于连接JammingHandler和JammingProcessor + /// + private class JammingHandlerAdapter : JammingHandler + { + private readonly JammingProcessor _processor; + + public JammingHandlerAdapter(JammingProcessor processor) + { + _processor = processor; + } + + protected override void OnJammingApplied(JammingParameters parameters) + { + _processor._owner.OnJammingApplied(parameters); + } + + protected override void OnJammingCleared(JammingParameters? parameters) + { + _processor._owner.OnJammingCleared(parameters?.Type ?? JammingType.RadioFrequency); + } + } + } + + /// + /// 干扰处理器实例 + /// + protected readonly IJammingProcessor _jammingProcessor; + + /// + /// 支持的干扰类型列表 + /// + protected readonly List _supportedJammingTypes = new List(); + + /// + /// 位置提供委托,用于获取设备当前位置 + /// + private readonly Func _positionProvider; + + /// + /// 干扰应用事件委托 + /// + private readonly Action _onJammingApplied; + + /// + /// 干扰清除事件委托 + /// + private readonly Action _onJammingCleared; + + /// + /// 获取设备支持的干扰类型 + /// + public IEnumerable SupportedJammingTypes => _supportedJammingTypes; + + /// + /// 获取设备当前是否处于被干扰状态 + /// + public bool IsJammed => _jammingProcessor.IsJammed; + + /// + /// 构造函数 + /// + /// 位置提供委托 + /// 干扰应用事件处理委托 + /// 干扰清除事件处理委托 + public JammableComponent( + Func positionProvider, + Action onJammingApplied, + Action onJammingCleared) + { + _positionProvider = positionProvider ?? throw new ArgumentNullException(nameof(positionProvider)); + _onJammingApplied = onJammingApplied ?? throw new ArgumentNullException(nameof(onJammingApplied)); + _onJammingCleared = onJammingCleared ?? throw new ArgumentNullException(nameof(onJammingCleared)); + _jammingProcessor = new JammingProcessor(this); + } + + /// + /// 更新干扰状态 + /// + /// 时间步长,单位:秒 + public void UpdateJammingStatus(double deltaTime) + { + _jammingProcessor.Update(deltaTime); + } + + /// + /// 设置干扰阈值 + /// + /// 干扰类型 + /// 阈值值(单位:瓦特) + public void SetJammingThreshold(JammingType type, double threshold) + { + _jammingProcessor.SetJammingThreshold(type, threshold); + } + + /// + /// 添加支持的干扰类型 + /// + /// 干扰类型 + /// 干扰阈值(单位:瓦特) + public void AddSupportedJammingType(JammingType type, double threshold) + { + if (!_supportedJammingTypes.Contains(type)) + { + _supportedJammingTypes.Add(type); + SetJammingThreshold(type, threshold); + } + } + + /// + /// 应用干扰 + /// + /// 干扰参数 + public void ApplyJamming(JammingParameters parameters) + { + // 检查是否支持该类型的干扰 + if (_supportedJammingTypes.Contains(parameters.Type)) + { + _jammingProcessor.HandleJamming(parameters); + } + } + + /// + /// 清除干扰 + /// + /// 要清除的干扰类型 + public void ClearJamming(JammingType type) + { + // 这里简化处理,直接清除当前干扰 + _jammingProcessor.ClearJamming(); + } + + /// + /// 当干扰被应用时调用 + /// + /// 干扰参数 + protected void OnJammingApplied(JammingParameters parameters) + { + _onJammingApplied(parameters); + } + + /// + /// 当干扰被清除时调用 + /// + /// 被清除的干扰类型 + protected void OnJammingCleared(JammingType type) + { + _onJammingCleared(type); + } + + /// + /// 从配置中加载干扰阈值和支持的干扰类型 + /// + /// 配置中的干扰抗性阈值,单位:瓦特 + /// 支持的干扰类型,默认为所有类型 + public void LoadJammingConfigFromThreshold(double jammingResistanceThreshold, + IEnumerable? supportedTypes = null) + { + // 如果未指定支持的干扰类型,则默认支持所有类型 + if (supportedTypes == null) + { + // 添加所有干扰类型 + foreach (JammingType jammingType in Enum.GetValues(typeof(JammingType))) + { + AddSupportedJammingType(jammingType, jammingResistanceThreshold); + } + } + else + { + // 添加指定的干扰类型 + foreach (JammingType jammingType in supportedTypes) + { + AddSupportedJammingType(jammingType, jammingResistanceThreshold); + } + } + } + + /// + /// 判断干扰是否有效 + /// + /// 干扰参数 + /// 如果干扰有效返回true,否则返回false + public bool IsJammingEffective(JammingParameters parameters) + { + return ((JammingProcessor)_jammingProcessor).IsJammingEffective(parameters); + } + } +} \ No newline at end of file diff --git a/ThreatSource/src/Jamming/JammingParameters.cs b/ThreatSource/src/Jamming/JammingParameters.cs index d3037f6..34d18d2 100644 --- a/ThreatSource/src/Jamming/JammingParameters.cs +++ b/ThreatSource/src/Jamming/JammingParameters.cs @@ -22,6 +22,11 @@ namespace ThreatSource.Jamming /// public required Vector3D Direction { get; set; } + /// + /// 干扰源位置 + /// + public required Vector3D SourcePosition { get; set; } + /// /// 干扰角度范围,单位:弧度 /// diff --git a/ThreatSource/src/Jamming/LaserBeamRiderJammingHandler.cs b/ThreatSource/src/Jamming/LaserBeamRiderJammingHandler.cs deleted file mode 100644 index 40cea0b..0000000 --- a/ThreatSource/src/Jamming/LaserBeamRiderJammingHandler.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System.Diagnostics; -using ThreatSource.Indicator; - -namespace ThreatSource.Jamming -{ - /// - /// 激光波束制导器干扰处理器 - /// - /// - /// 处理激光波束制导器的干扰效果: - /// - 降低制导精度 - /// - 干扰制导信号 - /// - 影响制导效果 - /// - public class LaserBeamRiderJammingHandler : JammingHandler - { - private readonly LaserBeamRider beamRider; - - /// - /// 初始化激光波束制导器干扰处理器的新实例 - /// - /// 要处理的激光波束制导器 - public LaserBeamRiderJammingHandler(LaserBeamRider beamRider) - { - this.beamRider = beamRider; - } - - /// - /// 当干扰被应用时调用 - /// - /// 干扰参数 - /// - /// 实现干扰效果: - /// - 停止激光束照射 - /// - 干扰制导信号 - /// - 不影响设备的激活状态 - /// - protected override void OnJammingApplied(JammingParameters parameters) - { - // 记录干扰信息 - Debug.WriteLine($"激光驾束仪受到干扰,功率:{parameters.Power}瓦特,类型:{parameters.Type}"); - - // 如果是激光干扰,则停止激光束照射 - if (parameters.Type == JammingType.Laser) - { - // 在干扰期间停止激光束照射 - beamRider.StopBeamIllumination(); - } - - // 不需要在这里直接设置IsJammed,因为基类JammingHandler已经设置了这个状态 - } - - /// - /// 当干扰被清除时调用 - /// - /// 被清除的干扰参数 - /// - /// 恢复设备功能: - /// - 记录干扰清除状态 - /// - 激光束照射的恢复将在LaserBeamRider的Update中处理 - /// - protected override void OnJammingCleared(JammingParameters? parameters) - { - if (parameters?.Type == JammingType.Laser) - { - Debug.WriteLine("激光驾束仪干扰已清除"); - - // 在驾束仪仍然处于激活状态时,恢复激光束照射 - if (beamRider.IsActive) - { - beamRider.StartBeamIllumination(); - } - } - } - } -} \ No newline at end of file diff --git a/ThreatSource/src/Jamming/LaserDesignatorJammingHandler.cs b/ThreatSource/src/Jamming/LaserDesignatorJammingHandler.cs deleted file mode 100644 index 486a976..0000000 --- a/ThreatSource/src/Jamming/LaserDesignatorJammingHandler.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Diagnostics; -using ThreatSource.Indicator; - -namespace ThreatSource.Jamming -{ - /// - /// 激光指示器干扰处理器 - /// - /// - /// 处理激光指示器接收到的干扰,包括: - /// - 停止激光照射 - /// - 影响激光指示器的工作状态 - /// - 处理干扰清除后的恢复 - /// - public class LaserDesignatorJammingHandler : JammingHandler - { - private readonly LaserDesignator designator; - - /// - /// 初始化激光指示器干扰处理器的新实例 - /// - /// 要处理的激光指示器 - public LaserDesignatorJammingHandler(LaserDesignator designator) - { - this.designator = designator; - } - - /// - /// 当干扰被应用时调用 - /// - /// 干扰参数 - /// - /// 在干扰被应用时停止激光照射功能 - /// 但不影响激光指示器的激活状态 - /// - protected override void OnJammingApplied(JammingParameters parameters) - { - Debug.WriteLine($"激光指示器受到干扰,功率:{parameters.Power}瓦特,类型:{parameters.Type}"); - - // 如果是激光干扰,则停止激光照射 - if (parameters.Type == JammingType.Laser) - { - // 停止激光照射 - designator.StopLaserIllumination(); - } - - // 不需要在这里直接设置IsJammed,因为基类JammingHandler已经设置了这个状态 - } - - /// - /// 当干扰被清除时调用 - /// - /// 被清除的干扰参数 - /// - /// 在干扰被清除时恢复激光照射功能 - /// 只有在激光指示器仍处于激活状态时才恢复照射 - /// - protected override void OnJammingCleared(JammingParameters? parameters) - { - if (parameters?.Type == JammingType.Laser) - { - Debug.WriteLine("激光指示器干扰已清除"); - - // 如果激光指示器仍处于激活状态,恢复激光照射 - if (designator.IsActive) - { - designator.StartLaserIllumination(); - } - } - } - } -} \ No newline at end of file diff --git a/ThreatSource/src/MIssile/InfraredCommandGuidedMissile.cs b/ThreatSource/src/MIssile/InfraredCommandGuidedMissile.cs index af53573..5b07469 100644 --- a/ThreatSource/src/MIssile/InfraredCommandGuidedMissile.cs +++ b/ThreatSource/src/MIssile/InfraredCommandGuidedMissile.cs @@ -77,6 +77,7 @@ namespace ThreatSource.Missile /// 导弹ID /// 导弹属性配置 /// 发射参数 + /// 红外指令导引系统配置 /// 仿真管理器实例 /// /// 构造过程: @@ -89,6 +90,7 @@ namespace ThreatSource.Missile string missileId, MissileProperties properties, InitialMotionParameters launchParams, + InfraredCommandGuidanceConfig guidanceConfig, ISimulationManager manager) : base(missileId, properties, launchParams, manager) { @@ -97,6 +99,7 @@ namespace ThreatSource.Missile guidanceSystem = new InfraredCommandGuidanceSystem( missileId + "_guidance", + guidanceConfig, properties.MaxAcceleration, properties.ProportionalNavigationCoefficient, manager diff --git a/ThreatSource/src/Simulation/SimulationConfig.cs b/ThreatSource/src/Simulation/SimulationConfig.cs index c1bf0dc..e2904f7 100644 --- a/ThreatSource/src/Simulation/SimulationConfig.cs +++ b/ThreatSource/src/Simulation/SimulationConfig.cs @@ -149,6 +149,26 @@ namespace ThreatSource.Simulation /// public double JammingResistanceThreshold { get; set; } + /// + /// 获取或设置最小工作波长 + /// + /// + /// 单位:微米 + /// 激光指示器工作的最小波长 + /// 影响激光干扰的匹配判断 + /// + public double MinWavelength { get; set; } + + /// + /// 获取或设置最大工作波长 + /// + /// + /// 单位:微米 + /// 激光指示器工作的最大波长 + /// 影响激光干扰的匹配判断 + /// + public double MaxWavelength { get; set; } + /// /// 初始化激光指示器配置的新实例 /// @@ -166,6 +186,8 @@ namespace ThreatSource.Simulation LaserDivergenceAngle = 0; LaserCodeConfig = new LaserCodeConfig(); JammingResistanceThreshold = 1.0; // 默认抗干扰阈值为1瓦特 + MinWavelength = 1.0; // 默认最小波长为1.0微米 + MaxWavelength = 1.1; // 默认最大波长为1.1微米 } } @@ -644,6 +666,22 @@ namespace ThreatSource.Simulation } } + /// + /// 红外指令导引系统配置类 + /// + public class InfraredCommandGuidanceConfig + { + /// + /// 干扰抗性阈值,单位:瓦特 + /// + /// + /// 定义了系统抵抗干扰的能力 + /// 低于此值时认为无法有效制导 + /// 默认值为1e-3瓦特 + /// + public double JammingResistanceThreshold { get; set; } = 1e-3; + } + /// /// 红外成像导引系统配置类 /// @@ -706,6 +744,16 @@ namespace ThreatSource.Simulation /// public double LockConfirmationTime { get; set; } = 0.3; + /// + /// 干扰抗性阈值,单位:瓦特 + /// + /// + /// 定义了系统抵抗干扰的能力 + /// 低于此值时认为无法有效制导 + /// 默认值为1e-3瓦特 + /// + public double JammingResistanceThreshold { get; set; } = 1e-3; + /// /// 初始化红外成像导引配置的新实例 /// @@ -830,6 +878,16 @@ namespace ThreatSource.Simulation /// public double SpotOffsetSensitivity { get; set; } = 0.5; + /// + /// 干扰抗性阈值,单位:瓦特 + /// + /// + /// 定义了系统抵抗干扰的能力 + /// 低于此值时认为无法有效跟踪目标 + /// 默认值为1e-12瓦特 + /// + public double JammingResistanceThreshold { get; set; } = 1e-12; + /// /// 初始化激光半主动导引配置的新实例 /// @@ -1138,6 +1196,16 @@ namespace ThreatSource.Simulation /// public double LowPassFilterCoefficient { get; set; } = 0.2; + /// + /// 干扰抗性阈值,单位:瓦特 + /// + /// + /// 定义了系统抵抗干扰的能力 + /// 低于此值时认为无法有效制导 + /// 默认值为1e-3瓦特 + /// + public double JammingResistanceThreshold { get; set; } = 1e-3; + /// /// 初始化激光驾束制导系统配置的新实例 /// @@ -1399,6 +1467,16 @@ namespace ThreatSource.Simulation /// public KalmanFilterParams TrackFilterParams { get; set; } = new(); + /// + /// 干扰抗性阈值,单位:瓦特 + /// + /// + /// 定义了系统抵抗干扰的能力 + /// 低于此值时认为无法有效制导 + /// 默认值为1e-3瓦特 + /// + public double JammingResistanceThreshold { get; set; } = 1e-3; + /// /// 初始化毫米波末制导导引系统配置的新实例 /// diff --git a/ThreatSource/src/Simulation/SimulationEvents.cs b/ThreatSource/src/Simulation/SimulationEvents.cs index cc75811..de8f297 100644 --- a/ThreatSource/src/Simulation/SimulationEvents.cs +++ b/ThreatSource/src/Simulation/SimulationEvents.cs @@ -161,22 +161,13 @@ namespace ThreatSource.Simulation public double JammingPower { get; set; } /// - /// 获取或设置最小波长 + /// 获取或设置波长 /// /// /// 单位:微米 - /// 干扰激光的最小波长 + /// 干扰激光的波长 /// - public double WavelengthMin { get; set; } = 1.0; - - /// - /// 获取或设置最大波长 - /// - /// - /// 单位:微米 - /// 干扰激光的最大波长 - /// - public double WavelengthMax { get; set; } = 1.1; + public double Wavelength { get; set; } = 1.0; /// /// 获取或设置干扰源位置 @@ -433,32 +424,6 @@ namespace ThreatSource.Simulation { } - /// - /// 毫米波干扰事件,表示对毫米波雷达的干扰 - /// - /// - /// 用于模拟对毫米波制导系统的干扰 - /// 包含干扰功率信息 - /// - public class MillimeterWaveJammingEvent : SimulationEvent - { - /// - /// 获取或设置被干扰目标的ID - /// - /// - /// 标识受到毫米波干扰的目标实体 - /// - public string? TargetId { get; set; } - - /// - /// 获取或设置干扰功率值 - /// - /// - /// 单位:瓦特 - /// 表示毫米波干扰源的输出功率 - /// - public double JammingPower { get; set; } - } /// /// 目标被击中事件 @@ -627,14 +592,9 @@ namespace ThreatSource.Simulation public double JammingPower { get; set; } /// - /// 最小波长(微米) + /// 波长(微米) /// - public double WavelengthMin { get; set; } - - /// - /// 最大波长(微米) - /// - public double WavelengthMax { get; set; } + public double Wavelength { get; set; } /// /// 干扰源位置 @@ -680,6 +640,74 @@ namespace ThreatSource.Simulation /// public double? Duration { get; set; } } + /// + /// 毫米波干扰事件,表示对毫米波雷达的干扰 + /// + /// + /// 用于模拟对毫米波制导系统的干扰 + /// 包含干扰功率信息 + /// + public class MillimeterWaveJammingEvent : SimulationEvent + { + /// + /// 获取或设置干扰功率值 + /// + /// + /// 单位:瓦特 + /// 表示毫米波干扰源的输出功率 + /// + public double JammingPower { get; set; } + + /// + /// 波长(微米) + /// + public double Wavelength { get; set; } + + /// + /// 干扰源位置 + /// + /// + /// 干扰设备在三维空间中的位置 + /// 用于计算干扰效果衰减 + /// + public Vector3D JammingSourcePosition { get; set; } = Vector3D.Zero; + + /// + /// 干扰方向 + /// + /// + /// 干扰波束的主方向向量 + /// 单位向量 + /// + public Vector3D JammingDirection { get; set; } = Vector3D.UnitX; + + /// + /// 干扰角度范围(弧度) + /// + /// + /// 定义了干扰波束的发散角度 + /// 影响干扰的覆盖范围 + /// + public double JammingAngleRange { get; set; } = 0.5; + + /// + /// 干扰模式 + /// + /// + /// 定义干扰的工作模式 + /// 影响干扰的效果类型 + /// + public JammingMode JammingMode { get; set; } = JammingMode.Noise; + + /// + /// 干扰持续时间(秒) + /// + /// + /// null表示持续干扰,直到显式清除 + /// + public double? Duration { get; set; } + } + /// /// 激光编码匹配事件,表示导弹成功匹配激光编码