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}");
}