From 612b8638f1d38139d671309b05f2f794d8e5e5c3 Mon Sep 17 00:00:00 2001 From: Tian jianyong <11429339@qq.com> Date: Tue, 27 May 2025 16:04:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8A=8A=E5=88=B6=E5=AF=BC=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E6=B7=BB=E5=8A=A0=E5=88=B0=E5=AF=BC=E5=BC=B9?= =?UTF-8?q?=E5=9F=BA=E7=B1=BB=E4=B8=AD=EF=BC=8C=E5=B9=B6=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E4=BA=86=E5=88=B6=E5=AF=BC=E7=8A=B6=E6=80=81=E7=9A=84=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E9=80=BB=E8=BE=91=EF=BC=8C=E5=AE=8C=E5=96=84=E4=BA=86?= =?UTF-8?q?=E5=AF=BC=E5=BC=95=E5=A4=B4=E7=9A=84=E6=9C=9D=E5=90=91=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E9=80=BB=E8=BE=91=E5=92=8C=E5=AF=BC=E5=BC=B9=E7=9A=84?= =?UTF-8?q?=E6=9C=9D=E5=90=91=E6=8E=A7=E5=88=B6=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 + RcsPatternTests.cs | 1 - .../src/Indicator/InfraredTrackerTests.cs | 7 +- .../Jamming/InfraredTrackerJammingTests.cs | 1 + .../data/missiles/composite/cg_001.toml | 2 +- .../data/missiles/composite/cg_002.toml | 2 +- ThreatSource/src/Data/ThreatSourceFactory.cs | 1 + .../src/Guidance/BaseGuidanceSystem.cs | 92 ++++++++--- .../Guidance/InfraredCommandGuidanceSystem.cs | 28 ++++ .../Guidance/InfraredImagingGuidanceSystem.cs | 71 ++++++++- .../Guidance/LaserBeamRiderGuidanceSystem.cs | 27 ++++ .../Guidance/LaserSemiActiveGuidanceSystem.cs | 37 ++++- .../Guidance/MillimeterWaveGuidanceSystem.cs | 38 +++++ ThreatSource/src/Indicator/IIndicator.cs | 21 --- ThreatSource/src/Indicator/InfraredTracker.cs | 26 +-- ThreatSource/src/MIssile/BaseMissile.cs | 150 ++++++++++++++---- .../src/MIssile/CompositeGuidedMissile.cs | 72 ++++++--- .../MIssile/InfraredCommandGuidedMissile.cs | 40 +++-- .../InfraredImagingTerminalGuidedMissile.cs | 39 +++-- .../src/MIssile/LaserBeamRiderMissile.cs | 48 ++++-- .../MIssile/LaserSemiActiveGuidedMissile.cs | 32 ++-- .../MillimeterWaveTerminalGuidedMissile.cs | 40 +++-- .../MIssile/TerminalSensitiveSubmunition.cs | 14 +- docs/project/simulation_events_checklist.md | 18 +++ docs/project/test_method.md | 5 + missile_lift_model.md | 76 --------- tools/ComprehensiveMissileSimulator.cs | 42 +---- 27 files changed, 615 insertions(+), 317 deletions(-) delete mode 100644 RcsPatternTests.cs delete mode 100644 missile_lift_model.md diff --git a/CHANGELOG.md b/CHANGELOG.md index a9b85da..ac559e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ ## [1.1.22] - 2025-05-26 - 完善了集成测试的菜单逻辑,干扰器正常工作了 - 增加了导弹生命周期的状态事件和制导事件 +- 把制导系统引用添加到导弹基类中,并完善了制导状态的判断逻辑 +- 完善了导引头的朝向控制逻辑和导弹的朝向控制逻辑 ## [1.1.21] - 2025-05-24 - 增加了升力加速度的计算 diff --git a/RcsPatternTests.cs b/RcsPatternTests.cs deleted file mode 100644 index 0519ecb..0000000 --- a/RcsPatternTests.cs +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ThreatSource.Tests/src/Indicator/InfraredTrackerTests.cs b/ThreatSource.Tests/src/Indicator/InfraredTrackerTests.cs index 7e564e1..449c390 100644 --- a/ThreatSource.Tests/src/Indicator/InfraredTrackerTests.cs +++ b/ThreatSource.Tests/src/Indicator/InfraredTrackerTests.cs @@ -61,7 +61,8 @@ namespace ThreatSource.Tests.Indicator _infraredTracker = new InfraredTracker( "tracker1", - "target1", + "target1", + "missile1", _config, trackerInitialMotion, _simulationManager @@ -74,7 +75,7 @@ namespace ThreatSource.Tests.Indicator { Assert.Equal("tracker1", _infraredTracker.Id); Assert.Equal("target1", _infraredTracker.TargetId); - Assert.Null(_infraredTracker.MissileId); + Assert.Equal("missile1", _infraredTracker.MissileId); Assert.False(_infraredTracker.IsActive); } @@ -234,7 +235,7 @@ namespace ThreatSource.Tests.Indicator _infraredTracker.Update(0.1); // Assert - Assert.Null(_infraredTracker.MissileId); + Assert.Equal("missile1", _infraredTracker.MissileId); } } } \ No newline at end of file diff --git a/ThreatSource.Tests/src/Jamming/InfraredTrackerJammingTests.cs b/ThreatSource.Tests/src/Jamming/InfraredTrackerJammingTests.cs index e29054b..b8ecb5f 100644 --- a/ThreatSource.Tests/src/Jamming/InfraredTrackerJammingTests.cs +++ b/ThreatSource.Tests/src/Jamming/InfraredTrackerJammingTests.cs @@ -45,6 +45,7 @@ namespace ThreatSource.Tests.Jamming _infraredTracker = new InfraredTracker( "tracker1", "target1", + "missile1", config, motionParameters, _simulationManager diff --git a/ThreatSource/data/missiles/composite/cg_001.toml b/ThreatSource/data/missiles/composite/cg_001.toml index 1cdbe11..d35f51e 100644 --- a/ThreatSource/data/missiles/composite/cg_001.toml +++ b/ThreatSource/data/missiles/composite/cg_001.toml @@ -21,7 +21,7 @@ HitProbability = 0.9 SelfDestructHeight = 0.0 CruiseAttackAngle = 5.0 # 巡航阶段攻角 (度) GuidanceSeekingAngle = 15.0 # 制导阶段导引头下视角 (度) -InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度) +InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度) UltravioletRadiationIntensity = 100.0 # 紫外辐射强度 (瓦特/球面度) # --- 复合制导特定属性 --- CompositeWorkMode = "Serial" # 工作模式:Serial (串行) 或 Parallel (并行) diff --git a/ThreatSource/data/missiles/composite/cg_002.toml b/ThreatSource/data/missiles/composite/cg_002.toml index 811736a..6eda733 100644 --- a/ThreatSource/data/missiles/composite/cg_002.toml +++ b/ThreatSource/data/missiles/composite/cg_002.toml @@ -21,7 +21,7 @@ HitProbability = 0.9 SelfDestructHeight = 0.0 CruiseAttackAngle = 5.0 # 巡航阶段攻角 (度) GuidanceSeekingAngle = 15.0 # 制导阶段导引头下视角 (度) -InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度) +InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度) UltravioletRadiationIntensity = 100.0 # 紫外辐射强度 (瓦特/球面度) # --- 复合制导特定属性 --- CompositeWorkMode = "Serial" # 工作模式:Serial (串行) 或 Parallel (并行) diff --git a/ThreatSource/src/Data/ThreatSourceFactory.cs b/ThreatSource/src/Data/ThreatSourceFactory.cs index 243e54f..8897910 100644 --- a/ThreatSource/src/Data/ThreatSourceFactory.cs +++ b/ThreatSource/src/Data/ThreatSourceFactory.cs @@ -164,6 +164,7 @@ namespace ThreatSource.Data IndicatorType.InfraredTracker when data.InfraredTrackerConfig != null => new InfraredTracker( indicatorId, targetId, + missileId, data.InfraredTrackerConfig, motionParameters, _simulationManager diff --git a/ThreatSource/src/Guidance/BaseGuidanceSystem.cs b/ThreatSource/src/Guidance/BaseGuidanceSystem.cs index e9366a4..4318d9e 100644 --- a/ThreatSource/src/Guidance/BaseGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/BaseGuidanceSystem.cs @@ -25,7 +25,12 @@ namespace ThreatSource.Guidance /// /// 干扰处理组件 /// - protected readonly JammableComponent _jammingComponent; + protected readonly JammableComponent JammingComponent; + + /// + /// 标记是否保持当前朝向不被导弹状态覆盖 + /// + protected bool PreserveOrientation { get; set; } = false; /// /// 获取设备支持的干扰类型 @@ -40,12 +45,12 @@ namespace ThreatSource.Guidance /// /// 获取设备当前是否处于被干扰状态 /// - public bool IsJammed => _jammingComponent.IsJammed; + public bool IsJammed => JammingComponent.IsJammed; /// /// 获取设备当前是否正受到有效的阻塞式干扰 /// - public bool IsBlockingJammed => _jammingComponent.IsBlockingJammed; + public bool IsBlockingJammed => JammingComponent.IsBlockingJammed; /// /// 获取或设置父实体ID @@ -87,13 +92,18 @@ namespace ThreatSource.Guidance public double ProportionalNavigationCoefficient { get; set; } /// - /// 获取或设置制导加速度,单位:米/平方秒 + /// 制导加速度向量 /// /// - /// 存储计算得到的制导指令 - /// 用于控制导弹的运动轨迹 + /// 由子类计算得出的制导加速度 + /// 用于导弹的轨迹控制 /// protected Vector3D GuidanceAcceleration { get; set; } + + /// + /// 标记制导阶段朝向是否已初始化 + /// + private bool hasInitializedGuidanceOrientation = false; /// /// 初始化基础制导系统的新实例 @@ -126,32 +136,39 @@ namespace ThreatSource.Guidance ProportionalNavigationCoefficient = proportionalNavigationCoefficient; // 初始化干扰处理组件 - _jammingComponent = new JammableComponent( + JammingComponent = new JammableComponent( positionProvider: () => base.KState.Position ); // Subscribe to the events instead - _jammingComponent.JammingApplied += HandleJammingApplied; - _jammingComponent.JammingCleared += HandleJammingCleared; + JammingComponent.JammingApplied += HandleJammingApplied; + JammingComponent.JammingCleared += HandleJammingCleared; // 子类需要在构造函数中设置支持的干扰类型和阈值 } /// - /// 激活制导系统 (基类处理干扰事件订阅) + /// 激活制导系统 /// + /// + /// 激活后,制导系统开始工作 + /// 可以接收仿真更新 + /// public override void Activate() { - if (!IsActive) - { + // 重置制导阶段朝向初始化标志 + hasInitializedGuidanceOrientation = false; + + if (!IsActive) + { IsActive = true; // 统一订阅 JammingEvent SimulationManager.SubscribeToEvent(HandleJammingEvent); SimulationManager.SubscribeToEvent(HandleJammingStoppedEvent); // 子类应在此方法中调用 base.Activate() 并订阅其他需要的事件 - } - // 调用 SimulationElement 的基类 Activate (如果存在) - // base.Activate(); // SimulationElement 似乎没有公开的 Activate + } + // 调用 SimulationElement 的基类 Activate (如果存在) + // base.Activate(); // SimulationElement 似乎没有公开的 Activate } /// @@ -183,10 +200,35 @@ namespace ThreatSource.Guidance { if (SimulationManager.GetEntityById(MissileId) is BaseMissile missile) { - KState = missile.KState; + // 同步位置、速度和速度大小 + KState.Position = missile.KState.Position; + KState.Velocity = missile.KState.Velocity; + KState.Speed = missile.KState.Speed; + + // 阶段性朝向管理 + var missileStageField = missile.GetType().GetField("currentStage", + System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + + if (missileStageField != null) + { + var currentStage = missileStageField.GetValue(missile); + string stageName = currentStage?.ToString() ?? "Unknown"; + + if (stageName == "Launch" || stageName == "Cruise") + { + // 发射和巡航阶段:导引头朝向与导弹朝向一致 + KState.Orientation = missile.KState.Orientation; + } + else if (stageName == "Guidance") + { + // 制导阶段:朝向管理由导弹统一负责,制导系统不再自己初始化朝向 + // 制导阶段的朝向调整由子类的UpdateSeekerOrientation()等方法控制 + } + } } + // 更新干扰状态 - _jammingComponent.UpdateJammingStatus(deltaTime); + JammingComponent.UpdateJammingStatus(deltaTime); } /// @@ -280,7 +322,7 @@ namespace ThreatSource.Guidance /// 阈值值(单位:瓦特) protected void SetJammingThreshold(JammingType type, double threshold) { - _jammingComponent.SetJammingThreshold(type, threshold); + JammingComponent.SetJammingThreshold(type, threshold); } /// @@ -289,7 +331,7 @@ namespace ThreatSource.Guidance /// 干扰类型 protected void AddSupportedJammingType(JammingType type) { - _jammingComponent.AddSupportedJammingType(type); + JammingComponent.AddSupportedJammingType(type); } /// @@ -299,7 +341,7 @@ namespace ThreatSource.Guidance /// 干扰阈值(单位:瓦特) protected void AddSupportedBlockingJammingType(JammingType type, double threshold) { - _jammingComponent.AddSupportedBlockingJammingType(type, threshold); + JammingComponent.AddSupportedBlockingJammingType(type, threshold); } /// @@ -308,7 +350,7 @@ namespace ThreatSource.Guidance /// 干扰参数 public virtual void ApplyJamming(JammingParameters parameters) { - _jammingComponent.ApplyJamming(parameters); + JammingComponent.ApplyJamming(parameters); } /// @@ -317,7 +359,7 @@ namespace ThreatSource.Guidance /// 干扰参数 public virtual void ClearJamming(JammingParameters parameters) { - _jammingComponent.ClearJamming(parameters); + JammingComponent.ClearJamming(parameters); } /// @@ -342,7 +384,7 @@ namespace ThreatSource.Guidance protected virtual void HandleJammingCleared(JammingParameters parameters) { // 检查整体干扰状态 - if (!_jammingComponent.IsJammed) + if (!JammingComponent.IsJammed) { HasGuidance = true; Trace.TraceInformation($"[{GetType().Name}] 所有干扰已清除。"); @@ -363,10 +405,10 @@ namespace ThreatSource.Guidance /// protected void InitializeJamming(double jammingResistanceThreshold, IEnumerable supportedTypes, IEnumerable supportedBlockingTypes) { - _jammingComponent.LoadJammingConfigFromThreshold(jammingResistanceThreshold, supportedBlockingTypes); + JammingComponent.LoadJammingConfigFromThreshold(jammingResistanceThreshold, supportedBlockingTypes); foreach (var type in supportedTypes) { - _jammingComponent.AddSupportedJammingType(type); + JammingComponent.AddSupportedJammingType(type); } } } diff --git a/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs b/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs index fcdd98a..241bfbe 100644 --- a/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/InfraredCommandGuidanceSystem.cs @@ -1,6 +1,7 @@ using ThreatSource.Utils; using ThreatSource.Simulation; using ThreatSource.Jammer; +using System.Diagnostics; namespace ThreatSource.Guidance { @@ -113,6 +114,7 @@ namespace ThreatSource.Guidance /// 更新过程: /// - 更新基类状态 /// - 计算制导加速度 + /// - 更新导引头朝向 /// public override void Update(double deltaTime) { @@ -122,6 +124,9 @@ namespace ThreatSource.Guidance if (HasGuidance) { CalculateGuidanceAcceleration(deltaTime); + + // 调整导引头朝向目标方向 + UpdateSeekerOrientation(); } else { @@ -143,6 +148,29 @@ namespace ThreatSource.Guidance } } + /// + /// 更新导引头朝向,使其指向目标方向 + /// + /// + /// 在制导阶段,导引头需要指向目标方向以保持跟踪 + /// + private void UpdateSeekerOrientation() + { + if (LastTrackerToTargetVector.HasValue && LastTrackerToMissileVector.HasValue) + { + // 计算从导弹到目标的方向向量 + Vector3D toTarget = (LastTrackerToTargetVector.Value - LastTrackerToMissileVector.Value).Normalize(); + + // 将方向向量转换为朝向 + Orientation targetOrientation = Orientation.FromVector(toTarget); + + // 更新导引头朝向 + KState.Orientation = targetOrientation; + + Debug.WriteLine($"[INFRARED_COMMAND] 导引头朝向已调整指向目标: {targetOrientation}"); + } + } + /// /// 接收并处理制导指令 /// diff --git a/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs b/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs index 7f0af82..649962c 100644 --- a/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs @@ -229,14 +229,14 @@ namespace ThreatSource.Guidance } /// - /// 更新引导系统的状态和计算结果 + /// 更新制导系统状态 /// - /// 自上次更新以来的时间间隔,单位:秒 + /// 时间步长,单位:秒 /// /// 更新过程: - /// - 探测目标位置 - /// - 计算目标速度 - /// - 生成制导指令 + /// - 尝试探测和识别目标 + /// - 计算制导加速度 + /// - 更新导引头朝向(Track和Lock模式) /// - 限制最大加速度 /// public override void Update(double deltaTime) @@ -271,6 +271,12 @@ namespace ThreatSource.Guidance } HasGuidance = true; + // 在Track和Lock模式下持续调整导引头朝向 + if (currentMode == WorkMode.Track || currentMode == WorkMode.Lock) + { + UpdateSeekerOrientation(); + } + if (currentMode == WorkMode.Lock) { lockModeTargetLostTimer = 0; } @@ -353,6 +359,7 @@ namespace ThreatSource.Guidance /// - 设置小视场角 /// - 更新图像生成器参数 /// - 提高目标识别概率要求 + /// - 调整导引头朝向目标 /// public void SwitchToTrackMode() { @@ -371,6 +378,10 @@ namespace ThreatSource.Guidance backgroundIntensity: config.BackgroundIntensity, wavelength: config.Wavelength ); + + // 调整导引头朝向目标 + UpdateSeekerOrientation(); + Debug.WriteLine($"切换到跟踪模式, 视场角: {config.TrackFieldOfView} 度"); } @@ -382,14 +393,42 @@ namespace ThreatSource.Guidance /// - 设置锁定状态 /// - 保持当前图像生成器参数 /// - 不再进行目标类型识别 + /// - 调整导引头朝向目标 /// public void SwitchToLockMode() { currentMode = WorkMode.Lock; lockModeTargetLostTimer = 0; + + // 调整导引头朝向目标 + UpdateSeekerOrientation(); + Debug.WriteLine("切换到锁定模式 - 目标类型确认"); } + /// + /// 更新导引头朝向,使其指向当前跟踪的目标 + /// + /// + /// 在Track和Lock模式下,导引头需要持续指向目标以保持跟踪 + /// + private void UpdateSeekerOrientation() + { + if (currentlyTrackedTargetId != null && LastTargetPosition.HasValue) + { + // 计算从导弹到目标的方向向量 + Vector3D toTarget = (LastTargetPosition.Value - KState.Position).Normalize(); + + // 将方向向量转换为朝向 + Orientation targetOrientation = Orientation.FromVector(toTarget); + + // 更新导引头朝向 + KState.Orientation = targetOrientation; + + Debug.WriteLine($"[IR IMAGING] 导引头朝向已调整指向目标 {currentlyTrackedTargetId}: {targetOrientation}"); + } + } + /// /// 尝试探测和识别目标 /// @@ -415,23 +454,39 @@ namespace ThreatSource.Guidance double searchFovRadians = config.SearchFieldOfView * Math.PI / 180.0; double trackFovRadians = config.TrackFieldOfView * Math.PI / 180.0; + // 获取导引头的朝向向量(搜索中心线方向) + Vector3D missileDirection = KState.Orientation.ToVector(); + + Debug.WriteLine($"[IR IMAGING DEBUG] 导弹位置: {missilePosition:F2}, 导引头朝向: {missileDirection:F3}"); + Debug.WriteLine($"[IR IMAGING DEBUG] 搜索视场角: {config.SearchFieldOfView}°, 最大探测距离: {config.MaxDetectionRange}m"); + foreach (var element in SimulationManager.GetEntitiesByType()) { if (element is BaseEquipment currentEntity) { Vector3D toTarget = currentEntity.KState.Position - missilePosition; double distanceToCurrentEntity = toTarget.Magnitude(); + + Debug.WriteLine($"[IR IMAGING DEBUG] 检查目标 {currentEntity.Id}: 位置={currentEntity.KState.Position:F2}, 距离={distanceToCurrentEntity:F2}m"); var (isGeometricallyObscured, overallTransmittance) = EvaluateSmokeImpact(missilePosition, currentEntity); bool isWithinFovAndRange; double relevantFovRadians = currentMode == WorkMode.Search ? searchFovRadians : trackFovRadians; + // 使用导引头朝向而不是速度向量进行视场角检查 + double angleToTarget = Math.Acos(Vector3D.DotProduct(toTarget.Normalize(), missileDirection)); + double angleToTargetDegrees = angleToTarget * 180.0 / Math.PI; + double fovHalfAngleDegrees = relevantFovRadians / 2 * 180.0 / Math.PI; + isWithinFovAndRange = distanceToCurrentEntity <= config.MaxDetectionRange && - Math.Acos(Vector3D.DotProduct(toTarget.Normalize(), missileVelocity.Normalize())) <= (relevantFovRadians / 2); + angleToTarget <= (relevantFovRadians / 2); + + Debug.WriteLine($"[IR IMAGING DEBUG] 目标 {currentEntity.Id}: 角度={angleToTargetDegrees:F2}°, FOV半角={fovHalfAngleDegrees:F2}°, 在FOV内={angleToTarget <= (relevantFovRadians / 2)}, 在距离内={distanceToCurrentEntity <= config.MaxDetectionRange}"); if (!isWithinFovAndRange || isGeometricallyObscured) { + Debug.WriteLine($"[IR IMAGING DEBUG] 目标 {currentEntity.Id} 不满足基本条件: FOV={isWithinFovAndRange}, 遮挡={isGeometricallyObscured}"); // 如果是 Search 模式下的焦点目标,但它不再满足基本条件,则清除焦点 if (currentMode == WorkMode.Search && currentEntity.Id == searchModeFocusCandidateId) { @@ -442,6 +497,8 @@ namespace ThreatSource.Guidance continue; // 不满足基本FOV、距离或被烟幕遮挡,处理下一个实体 } + Debug.WriteLine($"[IR IMAGING DEBUG] 目标 {currentEntity.Id} 通过基本检查,进入模式处理"); + switch (currentMode) { case WorkMode.Search: @@ -474,7 +531,7 @@ namespace ThreatSource.Guidance if (successRate >= COMMON_RECOGNITION_SUCCESS_RATE_THRESHOLD) { // 检查是否也在Track模式的FOV内 (因为search FOV可能比track FOV宽) - double angleToTargetForTrackCheck = Math.Acos(Vector3D.DotProduct(toTarget.Normalize(), missileVelocity.Normalize())); + double angleToTargetForTrackCheck = Math.Acos(Vector3D.DotProduct(toTarget.Normalize(), missileDirection)); if (angleToTargetForTrackCheck <= (trackFovRadians / 2)) { currentlyTrackedTargetId = searchModeFocusCandidateId; diff --git a/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs b/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs index f589cdb..ba08cad 100644 --- a/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs @@ -339,6 +339,7 @@ namespace ThreatSource.Guidance /// - 检查激光照射状态 /// - 更新制导状态 /// - 计算制导指令 + /// - 更新导引头朝向 /// - 更新输出参数 /// public override void Update(double deltaTime) @@ -352,20 +353,26 @@ namespace ThreatSource.Guidance if (HasGuidance) { CalculateGuidanceAcceleration(deltaTime); + + // 调整导引头朝向激光束方向 + UpdateSeekerOrientation(); } else { + // 搜索阶段:制导加速度清零,朝向由基类管理 GuidanceAcceleration = Vector3D.Zero; } } else { + // 无激光束照射时,清除制导 HasGuidance = false; GuidanceAcceleration = Vector3D.Zero; } } else { + // 被阻塞干扰时,清除制导 HasGuidance = false; GuidanceAcceleration = Vector3D.Zero; } @@ -519,6 +526,26 @@ namespace ThreatSource.Guidance LastGuidanceAcceleration = GuidanceAcceleration; } + /// + /// 更新导引头朝向,使其指向激光束方向 + /// + /// + /// 在制导阶段,导引头需要指向激光束方向以保持跟踪 + /// + private void UpdateSeekerOrientation() + { + if (LaserDirection.HasValue) + { + // 将激光束方向转换为朝向 + Orientation beamOrientation = Orientation.FromVector(LaserDirection.Value); + + // 更新导引头朝向 + KState.Orientation = beamOrientation; + + Debug.WriteLine($"[LASER_BEAM_RIDER] 导引头朝向已调整指向激光束: {beamOrientation}"); + } + } + /// /// 处理系统被干扰的事件 /// diff --git a/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs b/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs index 9164adb..b8324a3 100644 --- a/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs @@ -387,15 +387,20 @@ namespace ThreatSource.Guidance if (HasGuidance) { CalculateGuidanceAcceleration(deltaTime); + + // 跟踪阶段:调整导引头朝向目标 + UpdateSeekerOrientation(); } else { + // 搜索阶段:制导加速度清零,朝向由基类管理 GuidanceAcceleration = Vector3D.Zero; PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度 } } else { + // 无激光照射或被阻塞干扰时,清除制导 HasGuidance = false; GuidanceAcceleration = Vector3D.Zero; PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度 @@ -547,18 +552,19 @@ namespace ThreatSource.Guidance /// 目标位置 /// 角度偏差,单位:弧度 /// - /// 计算目标方向与导弹当前朝向的夹角 + /// 计算目标方向与导引头朝向的夹角,用于FOV检查 + /// 导引头可能相对弹体有下视角,用于扩大搜索范围 /// private double CalculateAngleDeviation(Vector3D targetPos) { // 计算目标方向 Vector3D targetDirection = (targetPos - KState.Position).Normalize(); - // 计算当前导弹朝向 - Vector3D missileDirection = KState.Velocity.Normalize(); + // 计算当前导引头朝向(可能相对弹体有下视角) + Vector3D seekerDirection = KState.Orientation.ToVector(); // 计算夹角 - double dotProduct = Vector3D.DotProduct(targetDirection, missileDirection); + double dotProduct = Vector3D.DotProduct(targetDirection, seekerDirection); dotProduct = Math.Max(-1.0, Math.Min(1.0, dotProduct)); // 确保在[-1,1]范围内 return Math.Acos(dotProduct); @@ -666,6 +672,29 @@ namespace ThreatSource.Guidance PreviousGuidanceAcceleration = GuidanceAcceleration; } + /// + /// 更新导引头朝向,使其指向当前目标 + /// + /// + /// 在制导阶段,导引头需要指向目标以保持跟踪 + /// + private void UpdateSeekerOrientation() + { + if (TargetPosition.HasValue) + { + // 计算从导弹到目标的方向向量 + Vector3D toTarget = (TargetPosition.Value - KState.Position).Normalize(); + + // 将方向向量转换为朝向 + Orientation targetOrientation = Orientation.FromVector(toTarget); + + // 更新导引头朝向 + KState.Orientation = targetOrientation; + + Debug.WriteLine($"[LASER_SEMI_ACTIVE] 导引头朝向已调整指向目标: {targetOrientation}"); + } + } + /// /// 获取四象限探测器的水平误差 /// diff --git a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs index 7626ccb..9cb1e2b 100644 --- a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs @@ -235,6 +235,9 @@ namespace ThreatSource.Guidance activeDetectionHistory.Clear(); + // 调整导引头朝向目标 + UpdateSeekerOrientation(); + Trace.TraceInformation($"切换到跟踪模式,波束宽度: {config.TrackBeamWidth}度"); } @@ -245,9 +248,36 @@ namespace ThreatSource.Guidance { currentMode = WorkMode.Lock; HasGuidance = true; + + // 调整导引头朝向目标 + UpdateSeekerOrientation(); + Trace.TraceInformation("切换到锁定模式 - 目标锁定成功"); } + /// + /// 更新导引头朝向,使其指向当前跟踪的目标 + /// + /// + /// 在Track和Lock模式下,导引头需要持续指向目标以保持跟踪 + /// + private void UpdateSeekerOrientation() + { + if (currentlyTrackedTargetId != null && LastTargetPosition.HasValue) + { + // 计算从导弹到目标的方向向量 + Vector3D toTarget = (LastTargetPosition.Value - KState.Position).Normalize(); + + // 将方向向量转换为朝向 + Orientation targetOrientation = Orientation.FromVector(toTarget); + + // 更新导引头朝向 + KState.Orientation = targetOrientation; + + Debug.WriteLine($"[MMW_GUIDANCE] 导引头朝向已调整指向目标 {currentlyTrackedTargetId}: {targetOrientation}"); + } + } + /// /// 激活制导系统 /// @@ -550,6 +580,7 @@ namespace ThreatSource.Guidance /// - 探测目标位置 /// - 计算目标速度 /// - 生成制导指令 + /// - 更新导引头朝向(Track和Lock模式) /// - 限制最大加速度 /// public override void Update(double deltaTime) @@ -592,6 +623,13 @@ namespace ThreatSource.Guidance { GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration; } + + // 在Track和Lock模式下持续调整导引头朝向 + if (currentMode == WorkMode.Track || currentMode == WorkMode.Lock) + { + UpdateSeekerOrientation(); + } + Debug.WriteLine($"制导加速度: {GuidanceAcceleration}"); } else diff --git a/ThreatSource/src/Indicator/IIndicator.cs b/ThreatSource/src/Indicator/IIndicator.cs index 2e60d6b..04718af 100644 --- a/ThreatSource/src/Indicator/IIndicator.cs +++ b/ThreatSource/src/Indicator/IIndicator.cs @@ -80,25 +80,4 @@ namespace ThreatSource.Indicator /// Idle } - - /// - /// 干扰状态枚举,定义了指示器的干扰状态 - /// - /// - /// 包含两种基本状态: - /// - Normal:正常状态,未受到干扰 - /// - Jammed:干扰状态,受到干扰影响 - /// 用于干扰状态监控和防护 - /// - public enum JammingState - { - /// - /// 正常状态 - /// - Normal, - /// - /// 干扰状态 - /// - Jammed - } } diff --git a/ThreatSource/src/Indicator/InfraredTracker.cs b/ThreatSource/src/Indicator/InfraredTracker.cs index 588331c..1c40c2d 100644 --- a/ThreatSource/src/Indicator/InfraredTracker.cs +++ b/ThreatSource/src/Indicator/InfraredTracker.cs @@ -61,6 +61,7 @@ namespace ThreatSource.Indicator /// /// 测角仪ID /// 目标ID + /// 要跟踪的导弹ID /// 配置参数 /// 初始运动参数 /// 仿真管理器实例 @@ -68,14 +69,15 @@ namespace ThreatSource.Indicator /// 构造过程: /// - 初始化基本属性 /// - 设置目标关联 + /// - 设置导弹跟踪配置 /// - 配置工作参数 /// - 设置初始状态 /// - public InfraredTracker(string id, string targetId, InfraredTrackerConfig config, KinematicState motionParameters, ISimulationManager manager) + public InfraredTracker(string id, string targetId, string missileId, InfraredTrackerConfig config, KinematicState motionParameters, ISimulationManager manager) : base(id, motionParameters, manager) { TargetId = targetId; - MissileId = null; + MissileId = missileId; this.config = config; IsTracking = false; @@ -230,13 +232,16 @@ namespace ThreatSource.Indicator /// 红外热源点亮事件数据 /// /// 处理过程: - /// - 记录导弹ID - /// - 准备开始跟踪 + /// - 验证事件来源是否为指定导弹 + /// - 开始跟踪 /// private void OnInfraredGuidanceMissileLight(InfraredGuidanceMissileLightEvent evt) { - // 处理导弹点亮红外热源事件 - MissileId = evt.SenderId ?? ""; + // 只处理指定导弹的点亮事件 + if (evt.SenderId == MissileId) + { + // 导弹点亮红外热源,测角仪开始跟踪 + } } /// @@ -245,13 +250,16 @@ namespace ThreatSource.Indicator /// 红外热源熄灭事件数据 /// /// 处理过程: - /// - 验证导弹ID + /// - 验证事件来源是否为指定导弹 /// - 停止跟踪 /// private void OnInfraredGuidanceMissileLightOff(InfraredGuidanceMissileLightOffEvent evt) { - // 处理导弹熄灭红外热源事件 - if (evt.SenderId == MissileId) StopTracking(); + // 只处理指定导弹的熄灭事件 + if (evt.SenderId == MissileId) + { + StopTracking(); + } } /// diff --git a/ThreatSource/src/MIssile/BaseMissile.cs b/ThreatSource/src/MIssile/BaseMissile.cs index 233b36d..89baf43 100644 --- a/ThreatSource/src/MIssile/BaseMissile.cs +++ b/ThreatSource/src/MIssile/BaseMissile.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using ThreatSource.Simulation; using ThreatSource.Utils; using System.Reflection; +using ThreatSource.Guidance; namespace ThreatSource.Missile { @@ -49,6 +50,19 @@ namespace ThreatSource.Missile /// public double EngineBurnTime { get; protected set; } + /// + /// 获取或设置导弹的制导系统引用 + /// + /// 制导系统实例,对于没有制导系统的导弹(如末敏弹)为null + /// + /// 提供对制导系统的直接访问: + /// - 可以直接获取制导系统的干扰状态 + /// - 可以直接获取制导系统的工作状态 + /// - 避免通过SimulationManager查找的开销 + /// 对于末敏弹等没有制导系统的导弹,此属性为null + /// + public BaseGuidanceSystem? GuidanceSystem { get; protected set; } + /// /// 获取导弹是否处于制导状态 /// @@ -57,8 +71,23 @@ namespace ThreatSource.Missile /// 影响导弹的运动学计算方法 /// 制导状态下使用制导律计算加速度 /// 非制导状态下使用弹道方程计算运动 + /// + /// 状态判断逻辑: + /// - 如果有制导系统:基于制导系统的HasGuidance和干扰状态 + /// - 如果无制导系统:始终为false(如末敏弹) /// - public bool IsGuidance { get; protected set; } + public virtual bool IsGuidance + { + get + { + // 如果没有制导系统,始终返回false(如末敏弹) + if (GuidanceSystem == null) + return false; + + // 如果有制导系统,基于制导系统状态判断 + return GuidanceSystem.HasGuidance && !GuidanceSystem.IsBlockingJammed; + } + } /// /// 获取或设置前一个制导状态 @@ -149,6 +178,11 @@ namespace ThreatSource.Missile /// protected MissileFlightStage currentStage = MissileFlightStage.Launch; + /// + /// 标记是否已完成制导阶段的初始化 + /// + private bool hasInitializedGuidanceStage = false; + /// /// 初始化导弹基类的新实例 /// @@ -178,7 +212,6 @@ namespace ThreatSource.Missile FlightTime = 0; FlightDistance = 0; IsActive = false; - IsGuidance = false; GuidanceAcceleration = Vector3D.Zero; LiftAcceleration = Vector3D.Zero; @@ -187,6 +220,19 @@ namespace ThreatSource.Missile ThrustAcceleration = launchDirection * properties.LaunchAcceleration; } + /// + /// 设置导弹的制导系统引用 + /// + /// 制导系统实例 + /// + /// 此方法应在导弹初始化时调用,用于建立导弹与制导系统的关联 + /// 对于没有制导系统的导弹(如末敏弹),不需要调用此方法 + /// + public void SetGuidanceSystem(BaseGuidanceSystem? guidanceSystem) + { + GuidanceSystem = guidanceSystem; + } + /// /// 判断是否为末敏弹类型 /// @@ -300,6 +346,49 @@ namespace ThreatSource.Missile /// protected virtual void OnGuidanceStage(double deltaTime) { + // 制导阶段初始化:首次进入制导阶段时,将导弹调整为水平飞行 + if (!hasInitializedGuidanceStage) + { + // 保持当前偏航角,将俯仰角调整为0(水平飞行) + KState.Orientation = new Orientation(KState.Orientation.Yaw, 0.0, KState.Orientation.Roll); + + // 初始化制导系统的导引头朝向 + if (GuidanceSystem != null) + { + double seekingAngleRad = Properties.GuidanceSeekingAngle * Math.PI / 180.0; + double newPitch = 0.0 - seekingAngleRad; // 基于水平朝向计算下视角 + + GuidanceSystem.KState.Orientation = new Orientation( + KState.Orientation.Yaw, + newPitch, + KState.Orientation.Roll + ); + + Debug.WriteLine($"导弹 {Id}: 初始化制导系统导引头朝向,下视角 {Properties.GuidanceSeekingAngle}度,朝向: {GuidanceSystem.KState.Orientation}"); + } + + Debug.WriteLine($"导弹 {Id}: 进入制导阶段,调整为水平飞行姿态。新朝向: {KState.Orientation}"); + hasInitializedGuidanceStage = true; + } + + // 如果有制导系统且制导系统有效,获取制导加速度 + if (GuidanceSystem != null && GuidanceSystem.HasGuidance && !GuidanceSystem.IsBlockingJammed) + { + GuidanceAcceleration = GuidanceSystem.GetGuidanceAcceleration(); + + // 有制导时,导弹朝向跟随速度方向(导弹沿速度方向飞行) + if (KState.Velocity.Magnitude() > 0.1) + { + KState.Orientation = Orientation.FromVector(KState.Velocity.Normalize()); + } + } + else + { + // 没有制导系统或制导系统无效时,清零制导加速度 + GuidanceAcceleration = Vector3D.Zero; + // 无制导时保持当前朝向(不修改朝向,让搜索继续) + } + // 计算升力加速度。在制导阶段,升力加速度和攻角相关; LiftAcceleration = LiftModel.CalculateLiftAcceleration(KState.Orientation.Pitch * 180 / Math.PI); } @@ -345,19 +434,6 @@ namespace ThreatSource.Missile (KState.Position, KState.Velocity) = MotionAlgorithm.CalculateBallisticMotion(KState.Position, KState.Velocity, acceleration, deltaTime); } - // 在制导阶段,根据是否获得制导来调整导弹朝向 - if(currentStage == MissileFlightStage.Guidance) - { - if (!IsGuidance) - { - // 导引头搜索阶段:保持水平飞行,导弹朝向向下一个固定角度进行搜索 - // 不改变速度向量,让导引头在下视角范围内搜索目标 - double seekingAngleRad = Properties.GuidanceSeekingAngle * Math.PI / 180.0; - KState.Orientation = new Orientation(KState.Orientation.Yaw, -seekingAngleRad, KState.Orientation.Roll); - } - // 如果IsGuidance为true,制导系统会通过GuidanceAcceleration自动调整导弹的飞行轨迹和朝向 - } - // 限制速度不超过最大速度 if (KState.Speed > Properties.MaxSpeed) { @@ -611,6 +687,7 @@ namespace ThreatSource.Missile /// - 基本状态信息 /// - 导弹固有属性 /// - 导弹运行时状态 + /// - 制导系统状态(如果有) /// public override ElementStatusInfo GetStatusInfo() { @@ -642,7 +719,17 @@ namespace ThreatSource.Missile statusInfo.ExtendedProperties["EngineBurnTime"] = EngineBurnTime; statusInfo.ExtendedProperties["CurrentStage"] = currentStage.ToString(); statusInfo.ExtendedProperties["IsGuidance"] = IsGuidance; - statusInfo.ExtendedProperties["GuidanceAcceleration"] = GuidanceAcceleration; + statusInfo.ExtendedProperties["GuidanceAcceleration"] = GuidanceAcceleration; + + // 添加制导系统状态信息(如果有制导系统) + if (GuidanceSystem != null) + { + statusInfo.ExtendedProperties["GuidanceSystem"] = GuidanceSystem.GetStatusInfo(); + } + else + { + statusInfo.ExtendedProperties["GuidanceSystem"] = "无制导系统"; + } return statusInfo; } @@ -667,7 +754,7 @@ namespace ThreatSource.Missile { SenderId = Id, GuidanceType = GetCurrentGuidanceType(), - GuidanceSystemId = GetCurrentGuidanceSystemId() + GuidanceSystemId = GuidanceSystem?.Id }; SimulationManager.PublishEvent(guidanceAcquiredEvent); @@ -714,29 +801,28 @@ namespace ThreatSource.Missile }; } - /// - /// 获取当前制导系统ID - /// - /// 制导系统ID,基类返回null - /// - /// 子类可以重写此方法以提供具体的制导系统ID - /// - protected virtual string? GetCurrentGuidanceSystemId() - { - return null; - } - /// /// 获取失去制导的原因 /// /// 失去制导的原因描述 /// - /// 子类可以重写此方法以提供更具体的失去制导原因 - /// 基类默认返回通用描述 + /// 基于制导系统状态提供具体的失去制导原因: + /// - 如果制导系统被阻塞干扰:返回干扰相关原因 + /// - 如果制导系统失去制导能力:返回系统失效原因 + /// - 如果没有制导系统:返回通用原因 /// protected virtual string GetGuidanceLostReason() { - return "制导系统失效或信号中断"; + if (GuidanceSystem == null) + return "导弹无制导系统"; + + if (GuidanceSystem.IsBlockingJammed) + return "制导系统受到阻塞干扰"; + + if (!GuidanceSystem.HasGuidance) + return "制导系统失去目标或信号中断"; + + return "制导系统失效或信号中断"; } } } diff --git a/ThreatSource/src/MIssile/CompositeGuidedMissile.cs b/ThreatSource/src/MIssile/CompositeGuidedMissile.cs index daa8bbf..5bb142a 100644 --- a/ThreatSource/src/MIssile/CompositeGuidedMissile.cs +++ b/ThreatSource/src/MIssile/CompositeGuidedMissile.cs @@ -80,7 +80,11 @@ namespace ThreatSource.Missile : base(missileId, properties, kinematicState, manager) { targetType = primaryTargetType; - InitializeGuidanceSuite(); + InitializeGuidanceSuite(); + + // 对于复合制导导弹,制导系统引用会在激活特定制导系统时动态设置 + // 初始时设置为null,表示没有激活的制导系统 + SetGuidanceSystem(null); } /// @@ -195,11 +199,6 @@ namespace ThreatSource.Missile return; } - if (currentActiveGuidance is SimulationElement se) - { - se.Update(deltaTime); - } - if (currentActiveConfig == null) { Debug.WriteLine("[CompositeGuidance.Logic] 错误:currentActiveGuidance 不为null,但 currentActiveConfig 为null。"); @@ -274,13 +273,29 @@ namespace ThreatSource.Missile /// 是否应停用当前活动的制导系统(如果存在)。 private void TryActivateNextGuidanceSystem(bool deactivatePrevious = false) { + // 保存前一个制导系统的目标方向信息 + Vector3D? previousTargetDirection = null; + if (deactivatePrevious && currentActiveGuidance != null) { Debug.WriteLine($"[CompositeGuidance.ActivateNext] 停用先前模块: {currentActiveConfig?.ComponentName ?? "Unknown"}"); - if (currentActiveGuidance is BaseGuidanceSystem prevBaseGs) + + // 尝试获取前一个制导系统的目标方向 + if (currentActiveGuidance is BaseGuidanceSystem prevBaseGs && prevBaseGs.HasGuidance) { - prevBaseGs.Deactivate(); + // 使用制导系统当前的朝向作为目标方向 + previousTargetDirection = prevBaseGs.KState.Orientation.ToVector(); + Debug.WriteLine($"[CompositeGuidance.ActivateNext] 保存前一制导系统的目标方向: {previousTargetDirection:F3}"); } + + if (currentActiveGuidance is BaseGuidanceSystem prevGs) + { + prevGs.Deactivate(); + // 注销先前的制导系统 + SimulationManager.UnregisterEntity(prevGs.Id); + } + // 清除基类的制导系统引用 + SetGuidanceSystem(null); } currentGuidancePhaseIndex++; @@ -291,6 +306,8 @@ namespace ThreatSource.Missile guidanceChainHaltedOrCompleted = true; currentActiveGuidance = null; currentActiveConfig = null; + // 清除基类的制导系统引用 + SetGuidanceSystem(null); return; } @@ -300,7 +317,26 @@ namespace ThreatSource.Missile Debug.WriteLine($"[CompositeGuidance.ActivateNext] 尝试激活模块: {currentActiveConfig.ComponentName} (类型: {currentActiveConfig.GuidanceSystemType})"); if (currentActiveGuidance is BaseGuidanceSystem currentBaseGs) { + // 注册制导系统为独立实体 + SimulationManager.RegisterEntity(currentBaseGs.Id, currentBaseGs); currentBaseGs.Activate(); + + // 如果有前一个制导系统的目标方向信息,则调整新制导系统的导引头朝向 + if (previousTargetDirection.HasValue) + { + Debug.WriteLine($"[CompositeGuidance.ActivateNext] 为新制导系统设置目标方向"); + + // 将目标方向转换为朝向 + Orientation targetOrientation = Orientation.FromVector(previousTargetDirection.Value); + + // 更新导引头朝向指向目标方向 + currentBaseGs.KState.Orientation = targetOrientation; + + Debug.WriteLine($"[CompositeGuidance.ActivateNext] 制导系统导引头朝向已调整为: {targetOrientation}"); + } + + // 设置基类的制导系统引用为当前激活的制导系统 + SetGuidanceSystem(currentBaseGs); } currentPhaseActivationTime = FlightTime; @@ -323,11 +359,15 @@ namespace ThreatSource.Missile if (currentActiveGuidance is BaseGuidanceSystem baseGsToDeactivate) { baseGsToDeactivate.Deactivate(); + // 注销失败的制导系统 + SimulationManager.UnregisterEntity(baseGsToDeactivate.Id); } } currentActiveGuidance = null; currentActiveConfig = null; + // 清除基类的制导系统引用 + SetGuidanceSystem(null); if (continueChain) { @@ -353,16 +393,7 @@ namespace ThreatSource.Missile UpdateGuidanceLogic(deltaTime); } - if (currentActiveGuidance != null && currentActiveGuidance.HasGuidance) - { - IsGuidance = true; - GuidanceAcceleration = currentActiveGuidance.GetGuidanceAcceleration(); - } - else - { - IsGuidance = false; - GuidanceAcceleration = Vector3D.Zero; - } + // 制导加速度和状态由基类自动处理,基于当前设置的GuidanceSystem引用 base.Update(deltaTime); // 调用基类更新,处理运动学等 } @@ -393,6 +424,7 @@ namespace ThreatSource.Missile UpdateGuidanceLogic(deltaTime); + // 调用基类方法处理制导加速度和升力计算 base.OnGuidanceStage(deltaTime); } @@ -408,11 +440,15 @@ namespace ThreatSource.Missile if (currentActiveGuidance is BaseGuidanceSystem activeBaseGs) { activeBaseGs.Deactivate(); + // 注销当前活动的制导系统 + SimulationManager.UnregisterEntity(activeBaseGs.Id); } currentActiveGuidance = null; } guidanceChainHaltedOrCompleted = true; currentActiveConfig = null; + // 清除基类的制导系统引用 + SetGuidanceSystem(null); Debug.WriteLine($"[CompositeGuidedMissile.Deactivate] 导弹 {Id} 已停用. 活动制导系统已处理."); } diff --git a/ThreatSource/src/MIssile/InfraredCommandGuidedMissile.cs b/ThreatSource/src/MIssile/InfraredCommandGuidedMissile.cs index a864376..d87c019 100644 --- a/ThreatSource/src/MIssile/InfraredCommandGuidedMissile.cs +++ b/ThreatSource/src/MIssile/InfraredCommandGuidedMissile.cs @@ -80,6 +80,9 @@ namespace ThreatSource.Missile properties.ProportionalNavigationCoefficient, manager ); + + // 设置制导系统引用到基类 + SetGuidanceSystem(guidanceSystem); } /// @@ -89,17 +92,21 @@ namespace ThreatSource.Missile /// /// 制导阶段处理: /// - 启用制导控制 - /// - 更新制导系统 - /// - 计算制导加速度 + /// - 制导加速度和状态由基类自动处理 + /// - 制导系统作为独立实体由仿真管理器更新 /// protected override void OnGuidanceStage(double deltaTime) { - // 点亮红外热源 - LightInfraredSource(); - // 更新制导系统 - guidanceSystem.Update(deltaTime); - GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration(); - IsGuidance = guidanceSystem.HasGuidance; + // 激活制导系统 + if(!guidanceSystem.IsActive) + { + guidanceSystem.Activate(); + } + + // 制导系统作为独立实体由仿真管理器更新,不需要在这里手动调用Update + + // 调用基类方法处理制导加速度和升力计算 + base.OnGuidanceStage(deltaTime); } /// @@ -157,12 +164,18 @@ namespace ThreatSource.Missile /// /// 激活过程: /// - 调用基类激活方法 + /// - 注册制导系统为独立实体 + /// - 激活制导系统 + /// - 点亮红外热源 /// - 订阅制导指令事件 - /// - 准备接收制导指令 /// public override void Activate() { base.Activate(); + + // 将制导系统注册到仿真管理器 + SimulationManager.RegisterEntity(guidanceSystem.Id, guidanceSystem); + guidanceSystem.Activate(); // 点亮红外热源 LightInfraredSource(); @@ -176,8 +189,10 @@ namespace ThreatSource.Missile /// /// 停用过程: /// - 调用基类停用方法 + /// - 停用制导系统 /// - 熄灭红外热源 /// - 取消订阅制导事件 + /// - 注销制导系统 /// public override void Deactivate() { @@ -187,6 +202,8 @@ namespace ThreatSource.Missile LightOffInfraredSource(); // 取消订阅红外指令制导事件 SimulationManager.UnsubscribeFromEvent(HandleGuidanceCommand); + // 取消制导系统注册 + SimulationManager.UnregisterEntity(guidanceSystem.Id); } /// @@ -195,12 +212,13 @@ namespace ThreatSource.Missile /// 包含导弹状态的详细描述 /// /// 返回信息包括: - /// - 基本状态信息 + /// - 基本状态信息(由基类提供) + /// - 制导系统状态(由基类提供) /// public override ElementStatusInfo GetStatusInfo() { var statusInfo = base.GetStatusInfo(); - statusInfo.ExtendedProperties["GuidanceSystem"] = guidanceSystem.GetStatusInfo(); + // 制导系统信息现在由基类统一处理 return statusInfo; } } diff --git a/ThreatSource/src/MIssile/InfraredImagingTerminalGuidedMissile.cs b/ThreatSource/src/MIssile/InfraredImagingTerminalGuidedMissile.cs index 6784b24..0115fd2 100644 --- a/ThreatSource/src/MIssile/InfraredImagingTerminalGuidedMissile.cs +++ b/ThreatSource/src/MIssile/InfraredImagingTerminalGuidedMissile.cs @@ -78,17 +78,20 @@ namespace ThreatSource.Missile properties.ProportionalNavigationCoefficient, manager ); + + // 设置制导系统引用到基类 + SetGuidanceSystem(guidanceSystem); } /// - /// 更新制导阶段的状态 + /// 更新制导阶段状态 /// /// 时间步长,单位:秒 /// - /// 制导阶段特点: - /// - 完全依赖导航系统的工作模式 - /// - 根据导航系统状态更新制导 - /// - 持续到命中目标 + /// 制导阶段处理: + /// - 启用制导控制 + /// - 制导加速度和状态由基类自动处理 + /// - 制导系统作为独立实体由仿真管理器更新 /// protected override void OnGuidanceStage(double deltaTime) { @@ -96,15 +99,11 @@ namespace ThreatSource.Missile if(!guidanceSystem.IsActive) { guidanceSystem.Activate(); - KState.Orientation = new Orientation(KState.Orientation.Yaw, -0.1, KState.Orientation.Roll); - KState.Velocity = KState.Orientation.ToVector() * KState.Speed; } - // 更新制导系统 - guidanceSystem.Update(deltaTime); - GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration(); - IsGuidance = guidanceSystem.HasGuidance; - + // 制导系统作为独立实体由仿真管理器更新,不需要在这里手动调用Update + + // 调用基类方法处理制导加速度和升力计算 base.OnGuidanceStage(deltaTime); } @@ -114,11 +113,18 @@ namespace ThreatSource.Missile /// /// 激活过程: /// - 调用基类激活方法 + /// - 注册制导系统为独立实体 /// - 激活制导系统 /// public override void Activate() { base.Activate(); + + // 将制导系统注册到仿真管理器 + SimulationManager.RegisterEntity(guidanceSystem.Id, guidanceSystem); + + // 激活制导系统 + guidanceSystem.Activate(); } /// @@ -128,11 +134,14 @@ namespace ThreatSource.Missile /// 停用过程: /// - 调用基类停用方法 /// - 停用制导系统 + /// - 注销制导系统 /// public override void Deactivate() { base.Deactivate(); guidanceSystem.Deactivate(); + // 取消制导系统注册 + SimulationManager.UnregisterEntity(guidanceSystem.Id); } /// @@ -141,13 +150,13 @@ namespace ThreatSource.Missile /// 包含导弹状态的详细描述 /// /// 返回信息包括: - /// - 基本状态信息 - /// - 当前飞行阶段 + /// - 基本状态信息(由基类提供) + /// - 制导系统状态(由基类提供) /// public override ElementStatusInfo GetStatusInfo() { var statusInfo = base.GetStatusInfo(); - statusInfo.ExtendedProperties["GuidanceSystem"] = guidanceSystem.GetStatusInfo(); + // 制导系统信息现在由基类统一处理 return statusInfo; } } diff --git a/ThreatSource/src/MIssile/LaserBeamRiderMissile.cs b/ThreatSource/src/MIssile/LaserBeamRiderMissile.cs index 82d8298..0426e37 100644 --- a/ThreatSource/src/MIssile/LaserBeamRiderMissile.cs +++ b/ThreatSource/src/MIssile/LaserBeamRiderMissile.cs @@ -56,26 +56,33 @@ namespace ThreatSource.Missile properties.ProportionalNavigationCoefficient, guidanceSystemConfig, manager); + + // 设置制导系统引用到基类 + SetGuidanceSystem(guidanceSystem); } /// - /// 制导阶段默认实现 + /// 更新制导阶段状态 + /// /// 时间步长,单位:秒 /// /// 制导阶段处理: - /// - 更新制导系统 - /// - 获取制导加速度 - /// - 设置制导状态 + /// - 启用制导控制 + /// - 制导加速度和状态由基类自动处理 + /// - 制导系统作为独立实体由仿真管理器更新 /// - /// protected override void OnGuidanceStage(double deltaTime) { - // 更新制导系统 - guidanceSystem.Update(deltaTime); - // 获取制导加速度 - GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration(); - // 设置制导状态 - IsGuidance = guidanceSystem.HasGuidance; + // 激活制导系统 + if(!guidanceSystem.IsActive) + { + guidanceSystem.Activate(); + } + + // 制导系统作为独立实体由仿真管理器更新,不需要在这里手动调用Update + + // 调用基类方法处理制导加速度和升力计算 + base.OnGuidanceStage(deltaTime); } /// @@ -84,12 +91,16 @@ namespace ThreatSource.Missile /// /// 激活过程: /// - 调用基类激活方法 - /// - 订阅激光波束事件 - /// - 准备波束跟踪 + /// - 注册制导系统为独立实体 + /// - 激活制导系统 /// public override void Activate() { base.Activate(); + + // 将制导系统注册到仿真管理器 + SimulationManager.RegisterEntity(guidanceSystem.Id, guidanceSystem); + // 激活制导系统 guidanceSystem.Activate(); } @@ -100,14 +111,16 @@ namespace ThreatSource.Missile /// /// 停用过程: /// - 调用基类停用方法 - /// - 取消订阅波束事件 - /// - 清理制导状态 + /// - 停用制导系统 + /// - 注销制导系统 /// public override void Deactivate() { base.Deactivate(); // 停用制导系统 guidanceSystem.Deactivate(); + // 取消制导系统注册 + SimulationManager.UnregisterEntity(guidanceSystem.Id); } /// @@ -116,12 +129,13 @@ namespace ThreatSource.Missile /// 包含导弹状态的详细描述 /// /// 返回信息包括: - /// - 基本状态信息 + /// - 基本状态信息(由基类提供) + /// - 制导系统状态(由基类提供) /// public override ElementStatusInfo GetStatusInfo() { var statusInfo = base.GetStatusInfo(); - statusInfo.ExtendedProperties["GuidanceSystem"] = guidanceSystem.GetStatusInfo(); + // 制导系统信息现在由基类统一处理 return statusInfo; } } diff --git a/ThreatSource/src/MIssile/LaserSemiActiveGuidedMissile.cs b/ThreatSource/src/MIssile/LaserSemiActiveGuidedMissile.cs index 8ee5066..68e1ae8 100644 --- a/ThreatSource/src/MIssile/LaserSemiActiveGuidedMissile.cs +++ b/ThreatSource/src/MIssile/LaserSemiActiveGuidedMissile.cs @@ -66,6 +66,9 @@ namespace ThreatSource.Missile properties.ProportionalNavigationCoefficient, guidanceConfig, manager); + + // 设置制导系统引用到基类 + SetGuidanceSystem(guidanceSystem); } /// @@ -106,9 +109,8 @@ namespace ThreatSource.Missile /// /// 制导阶段处理: /// - 启用制导控制 - /// - 更新制导系统 - /// - 计算制导加速度 - /// - 检查自毁条件 + /// - 制导加速度和状态由基类自动处理 + /// - 制导系统作为独立实体由仿真管理器更新 /// protected override void OnGuidanceStage(double deltaTime) { @@ -118,19 +120,10 @@ namespace ThreatSource.Missile guidanceSystem.Activate(); } - // 更新制导系统 - guidanceSystem.Update(deltaTime); - GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration(); - IsGuidance = guidanceSystem.HasGuidance; - } - - /// - /// 获取制导加速度 - /// - /// 制导加速度向量 - public Vector3D GetGuidanceAcceleration() - { - return GuidanceAcceleration; + // 制导系统作为独立实体由仿真管理器更新,不需要在这里手动调用Update + + // 调用基类方法处理制导加速度和升力计算 + base.OnGuidanceStage(deltaTime); } /// @@ -203,14 +196,13 @@ namespace ThreatSource.Missile /// 包含导弹状态的详细描述 /// /// 返回信息包括: - /// - 基本状态信息 - /// - 当前飞行阶段 + /// - 基本状态信息(由基类提供) + /// - 制导系统状态(由基类提供) /// public override ElementStatusInfo GetStatusInfo() { var statusInfo = base.GetStatusInfo(); - statusInfo.ExtendedProperties["CurrentStage"] = currentStage.ToString(); - statusInfo.ExtendedProperties["GuidanceSystem"] = guidanceSystem.GetStatusInfo(); + // 制导系统信息现在由基类统一处理 return statusInfo; } } diff --git a/ThreatSource/src/MIssile/MillimeterWaveTerminalGuidedMissile.cs b/ThreatSource/src/MIssile/MillimeterWaveTerminalGuidedMissile.cs index df9bb14..fc8f164 100644 --- a/ThreatSource/src/MIssile/MillimeterWaveTerminalGuidedMissile.cs +++ b/ThreatSource/src/MIssile/MillimeterWaveTerminalGuidedMissile.cs @@ -73,17 +73,20 @@ namespace ThreatSource.Missile properties.ProportionalNavigationCoefficient, guidanceConfig, manager); + + // 设置制导系统引用到基类 + SetGuidanceSystem(guidanceSystem); } /// - /// 更新制导阶段的状态 + /// 更新制导阶段状态 /// /// 时间步长,单位:秒 /// - /// 制导阶段特点: - /// - 完全依赖导航系统的工作模式 - /// - 根据导航系统状态更新制导 - /// - 持续到命中目标 + /// 制导阶段处理: + /// - 启用制导控制 + /// - 制导加速度和状态由基类自动处理 + /// - 制导系统作为独立实体由仿真管理器更新 /// protected override void OnGuidanceStage(double deltaTime) { @@ -91,15 +94,11 @@ namespace ThreatSource.Missile if(!guidanceSystem.IsActive) { guidanceSystem.Activate(); - KState.Orientation = new Orientation(KState.Orientation.Yaw, -0.02, KState.Orientation.Roll); - KState.Velocity = KState.Orientation.ToVector() * KState.Speed; } - // 更新制导系统 - guidanceSystem.Update(deltaTime); - GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration(); - IsGuidance = guidanceSystem.HasGuidance; - + // 制导系统作为独立实体由仿真管理器更新,不需要在这里手动调用Update + + // 调用基类方法处理制导加速度和升力计算 base.OnGuidanceStage(deltaTime); } @@ -109,11 +108,18 @@ namespace ThreatSource.Missile /// /// 激活过程: /// - 调用基类激活方法 + /// - 注册制导系统为独立实体 /// - 激活制导系统 /// public override void Activate() { base.Activate(); + + // 将制导系统注册到仿真管理器 + SimulationManager.RegisterEntity(guidanceSystem.Id, guidanceSystem); + + // 激活制导系统 + guidanceSystem.Activate(); } /// @@ -123,11 +129,14 @@ namespace ThreatSource.Missile /// 停用过程: /// - 调用基类停用方法 /// - 停用制导系统 + /// - 注销制导系统 /// public override void Deactivate() { base.Deactivate(); guidanceSystem.Deactivate(); + // 取消制导系统注册 + SimulationManager.UnregisterEntity(guidanceSystem.Id); } /// @@ -136,14 +145,13 @@ namespace ThreatSource.Missile /// 包含导弹状态的详细描述 /// /// 返回信息包括: - /// - 基本状态信息 - /// - 当前飞行阶段 + /// - 基本状态信息(由基类提供) + /// - 制导系统状态(由基类提供) /// public override ElementStatusInfo GetStatusInfo() { var statusInfo = base.GetStatusInfo(); - statusInfo.ExtendedProperties["CurrentStage"] = currentStage.ToString(); - statusInfo.ExtendedProperties["GuidanceSystem"] = guidanceSystem.GetStatusInfo().ToString(); + // 制导系统信息现在由基类统一处理 return statusInfo; } } diff --git a/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs b/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs index 887ce21..6bc809e 100644 --- a/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs +++ b/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs @@ -487,7 +487,6 @@ namespace ThreatSource.Missile { // 二次确认成功,进入攻击阶段 Debug.WriteLine($"二次确认成功,进入攻击阶段,当前角度: {spiralAngle * 180 / Math.PI:F2}°"); - IsGuidance = true; currentSubmunitionStage = SubmunitionStage.Attack; return; } @@ -711,5 +710,18 @@ namespace ThreatSource.Missile return false; } } + + /// + /// 获取末敏弹子弹是否处于制导状态 + /// + /// + /// 对于末敏弹子弹,制导状态基于攻击阶段而非传统制导系统 + /// 攻击阶段表示子弹已锁定目标并进行精确攻击 + /// 与传统导弹不同,末敏弹子弹使用传感器制导而非制导系统 + /// + public override bool IsGuidance + { + get => currentSubmunitionStage == SubmunitionStage.Attack; + } } } diff --git a/docs/project/simulation_events_checklist.md b/docs/project/simulation_events_checklist.md index 6e66a26..4d9162a 100644 --- a/docs/project/simulation_events_checklist.md +++ b/docs/project/simulation_events_checklist.md @@ -284,6 +284,24 @@ --- +## 事件设计原则 + +### 包含的事件类型 +1. **关键业务动作**: 导弹发射、激光照射、制导指令等 +2. **重要结果状态**: 目标命中、摧毁、爆炸等 +3. **系统级变化**: 实体激活/停用、仿真控制等 + +### 不包含的事件类型 +1. **运行时状态变化**: 目标丢失、FOV变化、临时干扰等 +2. **可查询的状态**: 通过属性直接获取的信息 +3. **高频变化状态**: 可能产生事件泛滥的状态变化 + +### 设计理念 +保持事件系统的简洁性和高效性,专注于用户真正需要响应的关键事件, +避免因过度细化而增加系统复杂性。 + +--- + **文档结束** *此文档将随着系统发展持续更新,请定期检查事件完整性。* \ No newline at end of file diff --git a/docs/project/test_method.md b/docs/project/test_method.md index 0ff7232..187c342 100644 --- a/docs/project/test_method.md +++ b/docs/project/test_method.md @@ -20,6 +20,11 @@ dotnet test --filter "FullyQualifiedName=ThreatSource.Tests.Utils.Vector3DPerfor dotnet test --filter "FullyQualifiedName=ThreatSource.Tests.Utils.Vector3DPerformanceTests.Baseline_Vector3D_Class_Performance" --logger "console;verbosity=detailed" | cat ``` +4. 测试是否编译正常 +```bash +dotnet build +``` + ### 测试报告 时间:2025-05-16 测试目的:测试 Vector3D 作为类和结构体的性能差异 diff --git a/missile_lift_model.md b/missile_lift_model.md deleted file mode 100644 index 22aa878..0000000 --- a/missile_lift_model.md +++ /dev/null @@ -1,76 +0,0 @@ -# 上下文 -文件名:[missile_lift_model.md] -创建于:[2024-05-23T10:00:00Z] -创建者:[AI] - -# 任务描述 -用户请求设计并实现导弹的升力加速度模型。 -升力加速度az =(功角a - 5 度)* 1 米每秒的平方。 -功角 a 的范围是大于等于负 5 度且小于等于 15 度。在其他情况下,az=0。 -功角 a 定义为导弹速度矢量与XY平面(水平面)的夹角。 -升力加速度作用在导弹的垂直方向(垂直于速度矢量,并在由速度矢量和世界Y轴定义的平面内)。 - -# 项目概述 -项目为一个导弹仿真系统,需要修改导弹基类及其运动算法来集成新的升力模型。 - ---- -*以下部分由 AI 在协议执行过程中维护* ---- - -# 分析 (由 RESEARCH 模式填充) -- 升力计算的核心位置在 `BaseMissile.cs` 的 `CalculateAcceleration` 方法。 -- 攻角 (alpha) 用户定义为速度矢量与水平面 (XZ平面,假设Y为垂直轴) 的夹角。 -- 升力方向垂直于速度矢量,并位于由速度矢量和世界Y轴(`Vector3D.UnitY`)定义的平面内。 -- `MotionAlgorithm.cs` 是存放运动相关计算的工具类。 - -# 提议的解决方案 (由 INNOVATE 模式填充) -方案:在 `MotionAlgorithm.cs` 中增加计算攻角和升力矢量的方法。在 `BaseMissile.cs` 中调用这些方法并将升力加入总加速度。 - -# 实施计划 (由 PLAN 模式生成) -见下方实施检查清单。 - -实施检查清单: -1. **在 `ThreatSource/src/Utils/MotionAlgorithm.cs` 中**: - 1. 创建 `public static double CalculateAngleOfAttackFromHorizontal(Vector3D velocity)` 方法。 - * 输入: `Vector3D velocity`。 - * 计算水平速度大小 `horizontalMagnitude = Math.Sqrt(velocity.X * velocity.X + velocity.Z * velocity.Z)`。 - * 处理 `horizontalMagnitude < 1e-6` 的情况: - * If `velocity.Y > 0`, return `Math.PI / 2`. - * If `velocity.Y < 0`, return `-Math.PI / 2`. - * Else, return `0.0`. - * 否则,计算 `alpha_rad = Math.Atan2(velocity.Y, horizontalMagnitude)`。 - * Return `alpha_rad`. -2. **在 `ThreatSource/src/Utils/MotionAlgorithm.cs` 中**: - 1. 创建 `public static Vector3D CalculateLiftAccelerationVector(Vector3D velocity, double angleOfAttackDegrees)` 方法。 - * 输入: `Vector3D velocity`, `double angleOfAttackDegrees`. - * 定义常量: `MIN_AOA_DEG = -5.0`, `MAX_AOA_DEG = 15.0`, `AOA_OFFSET_DEG = 5.0`. - * 计算 `az_magnitude`: - * If `angleOfAttackDegrees >= MIN_AOA_DEG && angleOfAttackDegrees <= MAX_AOA_DEG`: - * `az_magnitude = (angleOfAttackDegrees - AOA_OFFSET_DEG) * 1.0`. - * Else: - * `az_magnitude = 0.0`. - * If `Math.Abs(az_magnitude) < 1e-6 || velocity.MagnitudeSquared() < 1e-9`, return `Vector3D.Zero`. - * 定义 `WorldUp = Vector3D.UnitY`. - * `velocityNormalized = velocity.Normalize()`. - * `RightVec = Vector3D.CrossProduct(velocityNormalized, WorldUp)`. - * If `RightVec.MagnitudeSquared() < 1e-9`, return `Vector3D.Zero` (处理垂直飞行情况). - * `LiftDir = Vector3D.CrossProduct(RightVec, velocityNormalized).Normalize()`. - * `liftAcceleration = LiftDir * az_magnitude`. - * Return `liftAcceleration`. -3. **在 `ThreatSource/src/Missile/BaseMissile.cs` 的 `CalculateAcceleration(Vector3D velocity)` 方法中**: - 1. 在计算 `totalAcceleration` 之前,获取当前速度 `currentMissileVelocity = velocity` (或直接用 `velocity` 参数)。 - 2. 计算攻角(度): `double currentAoARad = MotionAlgorithm.CalculateAngleOfAttackFromHorizontal(currentMissileVelocity);` - 3. `double currentAoADegrees = currentAoARad * 180.0 / Math.PI;` - 4. 计算升力加速度矢量: `Vector3D liftAcceleration = MotionAlgorithm.CalculateLiftAccelerationVector(currentMissileVelocity, currentAoADegrees);` - 5. 修改 `totalAcceleration` 的计算公式,加入 `liftAcceleration`: - `Vector3D totalAcceleration = GuidanceAcceleration + ThrustAcceleration + dragAcceleration + GravityAcceleration + liftAcceleration;` - 6. 更新 `Debug.WriteLine` 语句,包含 `liftAcceleration` 的值。例如,在原有的基础上追加 `$", 升力: {liftAcceleration}"`。 - -# 当前执行步骤 (由 EXECUTE 模式在开始执行某步骤时更新) -> 正在执行: "1. 在 `ThreatSource/src/Utils/MotionAlgorithm.cs` 中:1. 创建 `public static double CalculateAngleOfAttackFromHorizontal(Vector3D velocity)` 方法。" - -# 任务进度 (由 EXECUTE 模式在每步完成后追加) -* [待填写] - -# 最终审查 (由 REVIEW 模式填充) -[待填写] \ No newline at end of file diff --git a/tools/ComprehensiveMissileSimulator.cs b/tools/ComprehensiveMissileSimulator.cs index efad49e..e96d31e 100644 --- a/tools/ComprehensiveMissileSimulator.cs +++ b/tools/ComprehensiveMissileSimulator.cs @@ -185,42 +185,6 @@ namespace ThreatSource.Tools.MissileSimulation }; } - /// - /// 初始化仿真环境 - /// - private void InitializeSimulation() - { - // 添加天气 - AddWeathers(); - - // 添加目标(坦克) - AddTankTarget(); - - // 添加各种类型的导弹 - AddLaserSemiActiveMissile(); - AddLaserBeamRiderMissile(); - AddTerminalSensitiveMissile(); - AddInfraredCommandMissile(); - AddInfraredImagingMissile(); - AddMillimeterWaveMissile(); - AddCompositeGuidanceMissile(); - - // 添加各种传感器和指示器 - AddIndicators(); - - // 添加烟幕弹 - AddSmokeGrenade(); - - // 添加激光诱偏目标 - AddLaserDecoy(); - - // 添加各类型干扰器 - AddJammers(); - - // 打印所有注册的干扰器 - PrintAllJammers(); - } - /// /// 添加天气 /// @@ -493,7 +457,7 @@ namespace ThreatSource.Tools.MissileSimulation Speed = 0 }; var laserDesignator = _threatSourceFactory.CreateIndicator(laserDesignatorId, "ld_001", "Tank_1", "LSGM_1", laserDesignatorLaunchParams); - indicators[laserDesignatorId] = (SimulationElement)laserDesignator; + indicators[laserDesignatorId] = laserDesignator; simulationManager.RegisterEntity(laserDesignatorId, laserDesignator); Console.WriteLine($"注册激光目标指示器 {laserDesignatorId}"); @@ -506,7 +470,7 @@ namespace ThreatSource.Tools.MissileSimulation Speed = 0 }; var laserBeamRider = _threatSourceFactory.CreateIndicator(laserBeamRiderId, "br_001", "Tank_1", "LBRM_1", laserBeamRiderLaunchParams); - indicators[laserBeamRiderId] = (SimulationElement)laserBeamRider; + indicators[laserBeamRiderId] = laserBeamRider; simulationManager.RegisterEntity(laserBeamRiderId, laserBeamRider); Console.WriteLine($"注册激光驾束仪 {laserBeamRiderId}"); @@ -519,7 +483,7 @@ namespace ThreatSource.Tools.MissileSimulation Speed = 0 }; var infraredTracker = _threatSourceFactory.CreateIndicator(infraredTrackerId, "ir_001", "Tank_1", "ICGM_1", infraredTrackerLaunchParams); - indicators[infraredTrackerId] = (SimulationElement)infraredTracker; + indicators[infraredTrackerId] = infraredTracker; simulationManager.RegisterEntity(infraredTrackerId, infraredTracker); Console.WriteLine($"注册红外测角仪 {infraredTrackerId}"); }