把制导系统引用添加到导弹基类中,并完善了制导状态的判断逻辑,完善了导引头的朝向控制逻辑和导弹的朝向控制逻辑
This commit is contained in:
parent
982ceffb73
commit
612b8638f1
@ -21,6 +21,8 @@
|
||||
## [1.1.22] - 2025-05-26
|
||||
- 完善了集成测试的菜单逻辑,干扰器正常工作了
|
||||
- 增加了导弹生命周期的状态事件和制导事件
|
||||
- 把制导系统引用添加到导弹基类中,并完善了制导状态的判断逻辑
|
||||
- 完善了导引头的朝向控制逻辑和导弹的朝向控制逻辑
|
||||
|
||||
## [1.1.21] - 2025-05-24
|
||||
- 增加了升力加速度的计算
|
||||
|
||||
@ -1 +0,0 @@
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -45,6 +45,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
_infraredTracker = new InfraredTracker(
|
||||
"tracker1",
|
||||
"target1",
|
||||
"missile1",
|
||||
config,
|
||||
motionParameters,
|
||||
_simulationManager
|
||||
|
||||
@ -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 (并行)
|
||||
|
||||
@ -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 (并行)
|
||||
|
||||
@ -164,6 +164,7 @@ namespace ThreatSource.Data
|
||||
IndicatorType.InfraredTracker when data.InfraredTrackerConfig != null => new InfraredTracker(
|
||||
indicatorId,
|
||||
targetId,
|
||||
missileId,
|
||||
data.InfraredTrackerConfig,
|
||||
motionParameters,
|
||||
_simulationManager
|
||||
|
||||
@ -25,7 +25,12 @@ namespace ThreatSource.Guidance
|
||||
/// <summary>
|
||||
/// 干扰处理组件
|
||||
/// </summary>
|
||||
protected readonly JammableComponent _jammingComponent;
|
||||
protected readonly JammableComponent JammingComponent;
|
||||
|
||||
/// <summary>
|
||||
/// 标记是否保持当前朝向不被导弹状态覆盖
|
||||
/// </summary>
|
||||
protected bool PreserveOrientation { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备支持的干扰类型
|
||||
@ -40,12 +45,12 @@ namespace ThreatSource.Guidance
|
||||
/// <summary>
|
||||
/// 获取设备当前是否处于被干扰状态
|
||||
/// </summary>
|
||||
public bool IsJammed => _jammingComponent.IsJammed;
|
||||
public bool IsJammed => JammingComponent.IsJammed;
|
||||
|
||||
/// <summary>
|
||||
/// 获取设备当前是否正受到有效的阻塞式干扰
|
||||
/// </summary>
|
||||
public bool IsBlockingJammed => _jammingComponent.IsBlockingJammed;
|
||||
public bool IsBlockingJammed => JammingComponent.IsBlockingJammed;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置父实体ID
|
||||
@ -87,13 +92,18 @@ namespace ThreatSource.Guidance
|
||||
public double ProportionalNavigationCoefficient { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置制导加速度,单位:米/平方秒
|
||||
/// 制导加速度向量
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 存储计算得到的制导指令
|
||||
/// 用于控制导弹的运动轨迹
|
||||
/// 由子类计算得出的制导加速度
|
||||
/// 用于导弹的轨迹控制
|
||||
/// </remarks>
|
||||
protected Vector3D GuidanceAcceleration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标记制导阶段朝向是否已初始化
|
||||
/// </summary>
|
||||
private bool hasInitializedGuidanceOrientation = false;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化基础制导系统的新实例
|
||||
@ -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;
|
||||
|
||||
// 子类需要在构造函数中设置支持的干扰类型和阈值
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活制导系统 (基类处理干扰事件订阅)
|
||||
/// 激活制导系统
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 激活后,制导系统开始工作
|
||||
/// 可以接收仿真更新
|
||||
/// </remarks>
|
||||
public override void Activate()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
// 重置制导阶段朝向初始化标志
|
||||
hasInitializedGuidanceOrientation = false;
|
||||
|
||||
if (!IsActive)
|
||||
{
|
||||
IsActive = true;
|
||||
// 统一订阅 JammingEvent
|
||||
SimulationManager.SubscribeToEvent<JammingEvent>(HandleJammingEvent);
|
||||
SimulationManager.SubscribeToEvent<JammingStoppedEvent>(HandleJammingStoppedEvent);
|
||||
// 子类应在此方法中调用 base.Activate() 并订阅其他需要的事件
|
||||
}
|
||||
// 调用 SimulationElement 的基类 Activate (如果存在)
|
||||
// base.Activate(); // SimulationElement 似乎没有公开的 Activate
|
||||
}
|
||||
// 调用 SimulationElement 的基类 Activate (如果存在)
|
||||
// base.Activate(); // SimulationElement 似乎没有公开的 Activate
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -280,7 +322,7 @@ namespace ThreatSource.Guidance
|
||||
/// <param name="threshold">阈值值(单位:瓦特)</param>
|
||||
protected void SetJammingThreshold(JammingType type, double threshold)
|
||||
{
|
||||
_jammingComponent.SetJammingThreshold(type, threshold);
|
||||
JammingComponent.SetJammingThreshold(type, threshold);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -289,7 +331,7 @@ namespace ThreatSource.Guidance
|
||||
/// <param name="type">干扰类型</param>
|
||||
protected void AddSupportedJammingType(JammingType type)
|
||||
{
|
||||
_jammingComponent.AddSupportedJammingType(type);
|
||||
JammingComponent.AddSupportedJammingType(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -299,7 +341,7 @@ namespace ThreatSource.Guidance
|
||||
/// <param name="threshold">干扰阈值(单位:瓦特)</param>
|
||||
protected void AddSupportedBlockingJammingType(JammingType type, double threshold)
|
||||
{
|
||||
_jammingComponent.AddSupportedBlockingJammingType(type, threshold);
|
||||
JammingComponent.AddSupportedBlockingJammingType(type, threshold);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -308,7 +350,7 @@ namespace ThreatSource.Guidance
|
||||
/// <param name="parameters">干扰参数</param>
|
||||
public virtual void ApplyJamming(JammingParameters parameters)
|
||||
{
|
||||
_jammingComponent.ApplyJamming(parameters);
|
||||
JammingComponent.ApplyJamming(parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -317,7 +359,7 @@ namespace ThreatSource.Guidance
|
||||
/// <param name="parameters">干扰参数</param>
|
||||
public virtual void ClearJamming(JammingParameters parameters)
|
||||
{
|
||||
_jammingComponent.ClearJamming(parameters);
|
||||
JammingComponent.ClearJamming(parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -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
|
||||
/// </remarks>
|
||||
protected void InitializeJamming(double jammingResistanceThreshold, IEnumerable<JammingType> supportedTypes, IEnumerable<JammingType> supportedBlockingTypes)
|
||||
{
|
||||
_jammingComponent.LoadJammingConfigFromThreshold(jammingResistanceThreshold, supportedBlockingTypes);
|
||||
JammingComponent.LoadJammingConfigFromThreshold(jammingResistanceThreshold, supportedBlockingTypes);
|
||||
foreach (var type in supportedTypes)
|
||||
{
|
||||
_jammingComponent.AddSupportedJammingType(type);
|
||||
JammingComponent.AddSupportedJammingType(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
/// 更新过程:
|
||||
/// - 更新基类状态
|
||||
/// - 计算制导加速度
|
||||
/// - 更新导引头朝向
|
||||
/// </remarks>
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导引头朝向,使其指向目标方向
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 在制导阶段,导引头需要指向目标方向以保持跟踪
|
||||
/// </remarks>
|
||||
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}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接收并处理制导指令
|
||||
/// </summary>
|
||||
|
||||
@ -229,14 +229,14 @@ namespace ThreatSource.Guidance
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新引导系统的状态和计算结果
|
||||
/// 更新制导系统状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔,单位:秒</param>
|
||||
/// <param name="deltaTime">时间步长,单位:秒</param>
|
||||
/// <remarks>
|
||||
/// 更新过程:
|
||||
/// - 探测目标位置
|
||||
/// - 计算目标速度
|
||||
/// - 生成制导指令
|
||||
/// - 尝试探测和识别目标
|
||||
/// - 计算制导加速度
|
||||
/// - 更新导引头朝向(Track和Lock模式)
|
||||
/// - 限制最大加速度
|
||||
/// </remarks>
|
||||
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
|
||||
/// - 设置小视场角
|
||||
/// - 更新图像生成器参数
|
||||
/// - 提高目标识别概率要求
|
||||
/// - 调整导引头朝向目标
|
||||
/// </remarks>
|
||||
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
|
||||
/// - 设置锁定状态
|
||||
/// - 保持当前图像生成器参数
|
||||
/// - 不再进行目标类型识别
|
||||
/// - 调整导引头朝向目标
|
||||
/// </remarks>
|
||||
public void SwitchToLockMode()
|
||||
{
|
||||
currentMode = WorkMode.Lock;
|
||||
lockModeTargetLostTimer = 0;
|
||||
|
||||
// 调整导引头朝向目标
|
||||
UpdateSeekerOrientation();
|
||||
|
||||
Debug.WriteLine("切换到锁定模式 - 目标类型确认");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导引头朝向,使其指向当前跟踪的目标
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 在Track和Lock模式下,导引头需要持续指向目标以保持跟踪
|
||||
/// </remarks>
|
||||
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}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试探测和识别目标
|
||||
/// </summary>
|
||||
@ -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<SimulationElement>())
|
||||
{
|
||||
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;
|
||||
|
||||
@ -339,6 +339,7 @@ namespace ThreatSource.Guidance
|
||||
/// - 检查激光照射状态
|
||||
/// - 更新制导状态
|
||||
/// - 计算制导指令
|
||||
/// - 更新导引头朝向
|
||||
/// - 更新输出参数
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导引头朝向,使其指向激光束方向
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 在制导阶段,导引头需要指向激光束方向以保持跟踪
|
||||
/// </remarks>
|
||||
private void UpdateSeekerOrientation()
|
||||
{
|
||||
if (LaserDirection.HasValue)
|
||||
{
|
||||
// 将激光束方向转换为朝向
|
||||
Orientation beamOrientation = Orientation.FromVector(LaserDirection.Value);
|
||||
|
||||
// 更新导引头朝向
|
||||
KState.Orientation = beamOrientation;
|
||||
|
||||
Debug.WriteLine($"[LASER_BEAM_RIDER] 导引头朝向已调整指向激光束: {beamOrientation}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理系统被干扰的事件
|
||||
/// </summary>
|
||||
|
||||
@ -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
|
||||
/// <param name="targetPos">目标位置</param>
|
||||
/// <returns>角度偏差,单位:弧度</returns>
|
||||
/// <remarks>
|
||||
/// 计算目标方向与导弹当前朝向的夹角
|
||||
/// 计算目标方向与导引头朝向的夹角,用于FOV检查
|
||||
/// 导引头可能相对弹体有下视角,用于扩大搜索范围
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导引头朝向,使其指向当前目标
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 在制导阶段,导引头需要指向目标以保持跟踪
|
||||
/// </remarks>
|
||||
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}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取四象限探测器的水平误差
|
||||
/// </summary>
|
||||
|
||||
@ -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("切换到锁定模式 - 目标锁定成功");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导引头朝向,使其指向当前跟踪的目标
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 在Track和Lock模式下,导引头需要持续指向目标以保持跟踪
|
||||
/// </remarks>
|
||||
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}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活制导系统
|
||||
/// </summary>
|
||||
@ -550,6 +580,7 @@ namespace ThreatSource.Guidance
|
||||
/// - 探测目标位置
|
||||
/// - 计算目标速度
|
||||
/// - 生成制导指令
|
||||
/// - 更新导引头朝向(Track和Lock模式)
|
||||
/// - 限制最大加速度
|
||||
/// </remarks>
|
||||
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
|
||||
|
||||
@ -80,25 +80,4 @@ namespace ThreatSource.Indicator
|
||||
/// </summary>
|
||||
Idle
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 干扰状态枚举,定义了指示器的干扰状态
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 包含两种基本状态:
|
||||
/// - Normal:正常状态,未受到干扰
|
||||
/// - Jammed:干扰状态,受到干扰影响
|
||||
/// 用于干扰状态监控和防护
|
||||
/// </remarks>
|
||||
public enum JammingState
|
||||
{
|
||||
/// <summary>
|
||||
/// 正常状态
|
||||
/// </summary>
|
||||
Normal,
|
||||
/// <summary>
|
||||
/// 干扰状态
|
||||
/// </summary>
|
||||
Jammed
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,6 +61,7 @@ namespace ThreatSource.Indicator
|
||||
/// </summary>
|
||||
/// <param name="id">测角仪ID</param>
|
||||
/// <param name="targetId">目标ID</param>
|
||||
/// <param name="missileId">要跟踪的导弹ID</param>
|
||||
/// <param name="config">配置参数</param>
|
||||
/// <param name="motionParameters">初始运动参数</param>
|
||||
/// <param name="manager">仿真管理器实例</param>
|
||||
@ -68,14 +69,15 @@ namespace ThreatSource.Indicator
|
||||
/// 构造过程:
|
||||
/// - 初始化基本属性
|
||||
/// - 设置目标关联
|
||||
/// - 设置导弹跟踪配置
|
||||
/// - 配置工作参数
|
||||
/// - 设置初始状态
|
||||
/// </remarks>
|
||||
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
|
||||
/// <param name="evt">红外热源点亮事件数据</param>
|
||||
/// <remarks>
|
||||
/// 处理过程:
|
||||
/// - 记录导弹ID
|
||||
/// - 准备开始跟踪
|
||||
/// - 验证事件来源是否为指定导弹
|
||||
/// - 开始跟踪
|
||||
/// </remarks>
|
||||
private void OnInfraredGuidanceMissileLight(InfraredGuidanceMissileLightEvent evt)
|
||||
{
|
||||
// 处理导弹点亮红外热源事件
|
||||
MissileId = evt.SenderId ?? "";
|
||||
// 只处理指定导弹的点亮事件
|
||||
if (evt.SenderId == MissileId)
|
||||
{
|
||||
// 导弹点亮红外热源,测角仪开始跟踪
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -245,13 +250,16 @@ namespace ThreatSource.Indicator
|
||||
/// <param name="evt">红外热源熄灭事件数据</param>
|
||||
/// <remarks>
|
||||
/// 处理过程:
|
||||
/// - 验证导弹ID
|
||||
/// - 验证事件来源是否为指定导弹
|
||||
/// - 停止跟踪
|
||||
/// </remarks>
|
||||
private void OnInfraredGuidanceMissileLightOff(InfraredGuidanceMissileLightOffEvent evt)
|
||||
{
|
||||
// 处理导弹熄灭红外热源事件
|
||||
if (evt.SenderId == MissileId) StopTracking();
|
||||
// 只处理指定导弹的熄灭事件
|
||||
if (evt.SenderId == MissileId)
|
||||
{
|
||||
StopTracking();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -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
|
||||
/// </remarks>
|
||||
public double EngineBurnTime { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置导弹的制导系统引用
|
||||
/// </summary>
|
||||
/// <value>制导系统实例,对于没有制导系统的导弹(如末敏弹)为null</value>
|
||||
/// <remarks>
|
||||
/// 提供对制导系统的直接访问:
|
||||
/// - 可以直接获取制导系统的干扰状态
|
||||
/// - 可以直接获取制导系统的工作状态
|
||||
/// - 避免通过SimulationManager查找的开销
|
||||
/// 对于末敏弹等没有制导系统的导弹,此属性为null
|
||||
/// </remarks>
|
||||
public BaseGuidanceSystem? GuidanceSystem { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取导弹是否处于制导状态
|
||||
/// </summary>
|
||||
@ -57,8 +71,23 @@ namespace ThreatSource.Missile
|
||||
/// 影响导弹的运动学计算方法
|
||||
/// 制导状态下使用制导律计算加速度
|
||||
/// 非制导状态下使用弹道方程计算运动
|
||||
///
|
||||
/// 状态判断逻辑:
|
||||
/// - 如果有制导系统:基于制导系统的HasGuidance和干扰状态
|
||||
/// - 如果无制导系统:始终为false(如末敏弹)
|
||||
/// </remarks>
|
||||
public bool IsGuidance { get; protected set; }
|
||||
public virtual bool IsGuidance
|
||||
{
|
||||
get
|
||||
{
|
||||
// 如果没有制导系统,始终返回false(如末敏弹)
|
||||
if (GuidanceSystem == null)
|
||||
return false;
|
||||
|
||||
// 如果有制导系统,基于制导系统状态判断
|
||||
return GuidanceSystem.HasGuidance && !GuidanceSystem.IsBlockingJammed;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置前一个制导状态
|
||||
@ -149,6 +178,11 @@ namespace ThreatSource.Missile
|
||||
/// </summary>
|
||||
protected MissileFlightStage currentStage = MissileFlightStage.Launch;
|
||||
|
||||
/// <summary>
|
||||
/// 标记是否已完成制导阶段的初始化
|
||||
/// </summary>
|
||||
private bool hasInitializedGuidanceStage = false;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化导弹基类的新实例
|
||||
/// </summary>
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置导弹的制导系统引用
|
||||
/// </summary>
|
||||
/// <param name="guidanceSystem">制导系统实例</param>
|
||||
/// <remarks>
|
||||
/// 此方法应在导弹初始化时调用,用于建立导弹与制导系统的关联
|
||||
/// 对于没有制导系统的导弹(如末敏弹),不需要调用此方法
|
||||
/// </remarks>
|
||||
public void SetGuidanceSystem(BaseGuidanceSystem? guidanceSystem)
|
||||
{
|
||||
GuidanceSystem = guidanceSystem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否为末敏弹类型
|
||||
/// </summary>
|
||||
@ -300,6 +346,49 @@ namespace ThreatSource.Missile
|
||||
/// </summary>
|
||||
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
|
||||
/// - 基本状态信息
|
||||
/// - 导弹固有属性
|
||||
/// - 导弹运行时状态
|
||||
/// - 制导系统状态(如果有)
|
||||
/// </remarks>
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前制导系统ID
|
||||
/// </summary>
|
||||
/// <returns>制导系统ID,基类返回null</returns>
|
||||
/// <remarks>
|
||||
/// 子类可以重写此方法以提供具体的制导系统ID
|
||||
/// </remarks>
|
||||
protected virtual string? GetCurrentGuidanceSystemId()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取失去制导的原因
|
||||
/// </summary>
|
||||
/// <returns>失去制导的原因描述</returns>
|
||||
/// <remarks>
|
||||
/// 子类可以重写此方法以提供更具体的失去制导原因
|
||||
/// 基类默认返回通用描述
|
||||
/// 基于制导系统状态提供具体的失去制导原因:
|
||||
/// - 如果制导系统被阻塞干扰:返回干扰相关原因
|
||||
/// - 如果制导系统失去制导能力:返回系统失效原因
|
||||
/// - 如果没有制导系统:返回通用原因
|
||||
/// </remarks>
|
||||
protected virtual string GetGuidanceLostReason()
|
||||
{
|
||||
return "制导系统失效或信号中断";
|
||||
if (GuidanceSystem == null)
|
||||
return "导弹无制导系统";
|
||||
|
||||
if (GuidanceSystem.IsBlockingJammed)
|
||||
return "制导系统受到阻塞干扰";
|
||||
|
||||
if (!GuidanceSystem.HasGuidance)
|
||||
return "制导系统失去目标或信号中断";
|
||||
|
||||
return "制导系统失效或信号中断";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,7 +80,11 @@ namespace ThreatSource.Missile
|
||||
: base(missileId, properties, kinematicState, manager)
|
||||
{
|
||||
targetType = primaryTargetType;
|
||||
InitializeGuidanceSuite();
|
||||
InitializeGuidanceSuite();
|
||||
|
||||
// 对于复合制导导弹,制导系统引用会在激活特定制导系统时动态设置
|
||||
// 初始时设置为null,表示没有激活的制导系统
|
||||
SetGuidanceSystem(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -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
|
||||
/// <param name="deactivatePrevious">是否应停用当前活动的制导系统(如果存在)。</param>
|
||||
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} 已停用. 活动制导系统已处理.");
|
||||
}
|
||||
|
||||
|
||||
@ -80,6 +80,9 @@ namespace ThreatSource.Missile
|
||||
properties.ProportionalNavigationCoefficient,
|
||||
manager
|
||||
);
|
||||
|
||||
// 设置制导系统引用到基类
|
||||
SetGuidanceSystem(guidanceSystem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -89,17 +92,21 @@ namespace ThreatSource.Missile
|
||||
/// <remarks>
|
||||
/// 制导阶段处理:
|
||||
/// - 启用制导控制
|
||||
/// - 更新制导系统
|
||||
/// - 计算制导加速度
|
||||
/// - 制导加速度和状态由基类自动处理
|
||||
/// - 制导系统作为独立实体由仿真管理器更新
|
||||
/// </remarks>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -157,12 +164,18 @@ namespace ThreatSource.Missile
|
||||
/// <remarks>
|
||||
/// 激活过程:
|
||||
/// - 调用基类激活方法
|
||||
/// - 注册制导系统为独立实体
|
||||
/// - 激活制导系统
|
||||
/// - 点亮红外热源
|
||||
/// - 订阅制导指令事件
|
||||
/// - 准备接收制导指令
|
||||
/// </remarks>
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
|
||||
// 将制导系统注册到仿真管理器
|
||||
SimulationManager.RegisterEntity(guidanceSystem.Id, guidanceSystem);
|
||||
|
||||
guidanceSystem.Activate();
|
||||
// 点亮红外热源
|
||||
LightInfraredSource();
|
||||
@ -176,8 +189,10 @@ namespace ThreatSource.Missile
|
||||
/// <remarks>
|
||||
/// 停用过程:
|
||||
/// - 调用基类停用方法
|
||||
/// - 停用制导系统
|
||||
/// - 熄灭红外热源
|
||||
/// - 取消订阅制导事件
|
||||
/// - 注销制导系统
|
||||
/// </remarks>
|
||||
public override void Deactivate()
|
||||
{
|
||||
@ -187,6 +202,8 @@ namespace ThreatSource.Missile
|
||||
LightOffInfraredSource();
|
||||
// 取消订阅红外指令制导事件
|
||||
SimulationManager.UnsubscribeFromEvent<InfraredGuidanceCommandEvent>(HandleGuidanceCommand);
|
||||
// 取消制导系统注册
|
||||
SimulationManager.UnregisterEntity(guidanceSystem.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -195,12 +212,13 @@ namespace ThreatSource.Missile
|
||||
/// <returns>包含导弹状态的详细描述</returns>
|
||||
/// <remarks>
|
||||
/// 返回信息包括:
|
||||
/// - 基本状态信息
|
||||
/// - 基本状态信息(由基类提供)
|
||||
/// - 制导系统状态(由基类提供)
|
||||
/// </remarks>
|
||||
public override ElementStatusInfo GetStatusInfo()
|
||||
{
|
||||
var statusInfo = base.GetStatusInfo();
|
||||
statusInfo.ExtendedProperties["GuidanceSystem"] = guidanceSystem.GetStatusInfo();
|
||||
// 制导系统信息现在由基类统一处理
|
||||
return statusInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,17 +78,20 @@ namespace ThreatSource.Missile
|
||||
properties.ProportionalNavigationCoefficient,
|
||||
manager
|
||||
);
|
||||
|
||||
// 设置制导系统引用到基类
|
||||
SetGuidanceSystem(guidanceSystem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新制导阶段的状态
|
||||
/// 更新制导阶段状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长,单位:秒</param>
|
||||
/// <remarks>
|
||||
/// 制导阶段特点:
|
||||
/// - 完全依赖导航系统的工作模式
|
||||
/// - 根据导航系统状态更新制导
|
||||
/// - 持续到命中目标
|
||||
/// 制导阶段处理:
|
||||
/// - 启用制导控制
|
||||
/// - 制导加速度和状态由基类自动处理
|
||||
/// - 制导系统作为独立实体由仿真管理器更新
|
||||
/// </remarks>
|
||||
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
|
||||
/// <remarks>
|
||||
/// 激活过程:
|
||||
/// - 调用基类激活方法
|
||||
/// - 注册制导系统为独立实体
|
||||
/// - 激活制导系统
|
||||
/// </remarks>
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
|
||||
// 将制导系统注册到仿真管理器
|
||||
SimulationManager.RegisterEntity(guidanceSystem.Id, guidanceSystem);
|
||||
|
||||
// 激活制导系统
|
||||
guidanceSystem.Activate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -128,11 +134,14 @@ namespace ThreatSource.Missile
|
||||
/// 停用过程:
|
||||
/// - 调用基类停用方法
|
||||
/// - 停用制导系统
|
||||
/// - 注销制导系统
|
||||
/// </remarks>
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
guidanceSystem.Deactivate();
|
||||
// 取消制导系统注册
|
||||
SimulationManager.UnregisterEntity(guidanceSystem.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -141,13 +150,13 @@ namespace ThreatSource.Missile
|
||||
/// <returns>包含导弹状态的详细描述</returns>
|
||||
/// <remarks>
|
||||
/// 返回信息包括:
|
||||
/// - 基本状态信息
|
||||
/// - 当前飞行阶段
|
||||
/// - 基本状态信息(由基类提供)
|
||||
/// - 制导系统状态(由基类提供)
|
||||
/// </remarks>
|
||||
public override ElementStatusInfo GetStatusInfo()
|
||||
{
|
||||
var statusInfo = base.GetStatusInfo();
|
||||
statusInfo.ExtendedProperties["GuidanceSystem"] = guidanceSystem.GetStatusInfo();
|
||||
// 制导系统信息现在由基类统一处理
|
||||
return statusInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,26 +56,33 @@ namespace ThreatSource.Missile
|
||||
properties.ProportionalNavigationCoefficient,
|
||||
guidanceSystemConfig,
|
||||
manager);
|
||||
|
||||
// 设置制导系统引用到基类
|
||||
SetGuidanceSystem(guidanceSystem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 制导阶段默认实现
|
||||
/// 更新制导阶段状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长,单位:秒</param>
|
||||
/// <remarks>
|
||||
/// 制导阶段处理:
|
||||
/// - 更新制导系统
|
||||
/// - 获取制导加速度
|
||||
/// - 设置制导状态
|
||||
/// - 启用制导控制
|
||||
/// - 制导加速度和状态由基类自动处理
|
||||
/// - 制导系统作为独立实体由仿真管理器更新
|
||||
/// </remarks>
|
||||
/// </summary>
|
||||
protected override void OnGuidanceStage(double deltaTime)
|
||||
{
|
||||
// 更新制导系统
|
||||
guidanceSystem.Update(deltaTime);
|
||||
// 获取制导加速度
|
||||
GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration();
|
||||
// 设置制导状态
|
||||
IsGuidance = guidanceSystem.HasGuidance;
|
||||
// 激活制导系统
|
||||
if(!guidanceSystem.IsActive)
|
||||
{
|
||||
guidanceSystem.Activate();
|
||||
}
|
||||
|
||||
// 制导系统作为独立实体由仿真管理器更新,不需要在这里手动调用Update
|
||||
|
||||
// 调用基类方法处理制导加速度和升力计算
|
||||
base.OnGuidanceStage(deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -84,12 +91,16 @@ namespace ThreatSource.Missile
|
||||
/// <remarks>
|
||||
/// 激活过程:
|
||||
/// - 调用基类激活方法
|
||||
/// - 订阅激光波束事件
|
||||
/// - 准备波束跟踪
|
||||
/// - 注册制导系统为独立实体
|
||||
/// - 激活制导系统
|
||||
/// </remarks>
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
|
||||
// 将制导系统注册到仿真管理器
|
||||
SimulationManager.RegisterEntity(guidanceSystem.Id, guidanceSystem);
|
||||
|
||||
// 激活制导系统
|
||||
guidanceSystem.Activate();
|
||||
}
|
||||
@ -100,14 +111,16 @@ namespace ThreatSource.Missile
|
||||
/// <remarks>
|
||||
/// 停用过程:
|
||||
/// - 调用基类停用方法
|
||||
/// - 取消订阅波束事件
|
||||
/// - 清理制导状态
|
||||
/// - 停用制导系统
|
||||
/// - 注销制导系统
|
||||
/// </remarks>
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
// 停用制导系统
|
||||
guidanceSystem.Deactivate();
|
||||
// 取消制导系统注册
|
||||
SimulationManager.UnregisterEntity(guidanceSystem.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -116,12 +129,13 @@ namespace ThreatSource.Missile
|
||||
/// <returns>包含导弹状态的详细描述</returns>
|
||||
/// <remarks>
|
||||
/// 返回信息包括:
|
||||
/// - 基本状态信息
|
||||
/// - 基本状态信息(由基类提供)
|
||||
/// - 制导系统状态(由基类提供)
|
||||
/// </remarks>
|
||||
public override ElementStatusInfo GetStatusInfo()
|
||||
{
|
||||
var statusInfo = base.GetStatusInfo();
|
||||
statusInfo.ExtendedProperties["GuidanceSystem"] = guidanceSystem.GetStatusInfo();
|
||||
// 制导系统信息现在由基类统一处理
|
||||
return statusInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,6 +66,9 @@ namespace ThreatSource.Missile
|
||||
properties.ProportionalNavigationCoefficient,
|
||||
guidanceConfig,
|
||||
manager);
|
||||
|
||||
// 设置制导系统引用到基类
|
||||
SetGuidanceSystem(guidanceSystem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -106,9 +109,8 @@ namespace ThreatSource.Missile
|
||||
/// <remarks>
|
||||
/// 制导阶段处理:
|
||||
/// - 启用制导控制
|
||||
/// - 更新制导系统
|
||||
/// - 计算制导加速度
|
||||
/// - 检查自毁条件
|
||||
/// - 制导加速度和状态由基类自动处理
|
||||
/// - 制导系统作为独立实体由仿真管理器更新
|
||||
/// </remarks>
|
||||
protected override void OnGuidanceStage(double deltaTime)
|
||||
{
|
||||
@ -118,19 +120,10 @@ namespace ThreatSource.Missile
|
||||
guidanceSystem.Activate();
|
||||
}
|
||||
|
||||
// 更新制导系统
|
||||
guidanceSystem.Update(deltaTime);
|
||||
GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration();
|
||||
IsGuidance = guidanceSystem.HasGuidance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取制导加速度
|
||||
/// </summary>
|
||||
/// <returns>制导加速度向量</returns>
|
||||
public Vector3D GetGuidanceAcceleration()
|
||||
{
|
||||
return GuidanceAcceleration;
|
||||
// 制导系统作为独立实体由仿真管理器更新,不需要在这里手动调用Update
|
||||
|
||||
// 调用基类方法处理制导加速度和升力计算
|
||||
base.OnGuidanceStage(deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -203,14 +196,13 @@ namespace ThreatSource.Missile
|
||||
/// <returns>包含导弹状态的详细描述</returns>
|
||||
/// <remarks>
|
||||
/// 返回信息包括:
|
||||
/// - 基本状态信息
|
||||
/// - 当前飞行阶段
|
||||
/// - 基本状态信息(由基类提供)
|
||||
/// - 制导系统状态(由基类提供)
|
||||
/// </remarks>
|
||||
public override ElementStatusInfo GetStatusInfo()
|
||||
{
|
||||
var statusInfo = base.GetStatusInfo();
|
||||
statusInfo.ExtendedProperties["CurrentStage"] = currentStage.ToString();
|
||||
statusInfo.ExtendedProperties["GuidanceSystem"] = guidanceSystem.GetStatusInfo();
|
||||
// 制导系统信息现在由基类统一处理
|
||||
return statusInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,17 +73,20 @@ namespace ThreatSource.Missile
|
||||
properties.ProportionalNavigationCoefficient,
|
||||
guidanceConfig,
|
||||
manager);
|
||||
|
||||
// 设置制导系统引用到基类
|
||||
SetGuidanceSystem(guidanceSystem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新制导阶段的状态
|
||||
/// 更新制导阶段状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长,单位:秒</param>
|
||||
/// <remarks>
|
||||
/// 制导阶段特点:
|
||||
/// - 完全依赖导航系统的工作模式
|
||||
/// - 根据导航系统状态更新制导
|
||||
/// - 持续到命中目标
|
||||
/// 制导阶段处理:
|
||||
/// - 启用制导控制
|
||||
/// - 制导加速度和状态由基类自动处理
|
||||
/// - 制导系统作为独立实体由仿真管理器更新
|
||||
/// </remarks>
|
||||
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
|
||||
/// <remarks>
|
||||
/// 激活过程:
|
||||
/// - 调用基类激活方法
|
||||
/// - 注册制导系统为独立实体
|
||||
/// - 激活制导系统
|
||||
/// </remarks>
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
|
||||
// 将制导系统注册到仿真管理器
|
||||
SimulationManager.RegisterEntity(guidanceSystem.Id, guidanceSystem);
|
||||
|
||||
// 激活制导系统
|
||||
guidanceSystem.Activate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -123,11 +129,14 @@ namespace ThreatSource.Missile
|
||||
/// 停用过程:
|
||||
/// - 调用基类停用方法
|
||||
/// - 停用制导系统
|
||||
/// - 注销制导系统
|
||||
/// </remarks>
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
guidanceSystem.Deactivate();
|
||||
// 取消制导系统注册
|
||||
SimulationManager.UnregisterEntity(guidanceSystem.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -136,14 +145,13 @@ namespace ThreatSource.Missile
|
||||
/// <returns>包含导弹状态的详细描述</returns>
|
||||
/// <remarks>
|
||||
/// 返回信息包括:
|
||||
/// - 基本状态信息
|
||||
/// - 当前飞行阶段
|
||||
/// - 基本状态信息(由基类提供)
|
||||
/// - 制导系统状态(由基类提供)
|
||||
/// </remarks>
|
||||
public override ElementStatusInfo GetStatusInfo()
|
||||
{
|
||||
var statusInfo = base.GetStatusInfo();
|
||||
statusInfo.ExtendedProperties["CurrentStage"] = currentStage.ToString();
|
||||
statusInfo.ExtendedProperties["GuidanceSystem"] = guidanceSystem.GetStatusInfo().ToString();
|
||||
// 制导系统信息现在由基类统一处理
|
||||
return statusInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取末敏弹子弹是否处于制导状态
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 对于末敏弹子弹,制导状态基于攻击阶段而非传统制导系统
|
||||
/// 攻击阶段表示子弹已锁定目标并进行精确攻击
|
||||
/// 与传统导弹不同,末敏弹子弹使用传感器制导而非制导系统
|
||||
/// </remarks>
|
||||
public override bool IsGuidance
|
||||
{
|
||||
get => currentSubmunitionStage == SubmunitionStage.Attack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,6 +284,24 @@
|
||||
|
||||
---
|
||||
|
||||
## 事件设计原则
|
||||
|
||||
### 包含的事件类型
|
||||
1. **关键业务动作**: 导弹发射、激光照射、制导指令等
|
||||
2. **重要结果状态**: 目标命中、摧毁、爆炸等
|
||||
3. **系统级变化**: 实体激活/停用、仿真控制等
|
||||
|
||||
### 不包含的事件类型
|
||||
1. **运行时状态变化**: 目标丢失、FOV变化、临时干扰等
|
||||
2. **可查询的状态**: 通过属性直接获取的信息
|
||||
3. **高频变化状态**: 可能产生事件泛滥的状态变化
|
||||
|
||||
### 设计理念
|
||||
保持事件系统的简洁性和高效性,专注于用户真正需要响应的关键事件,
|
||||
避免因过度细化而增加系统复杂性。
|
||||
|
||||
---
|
||||
|
||||
**文档结束**
|
||||
|
||||
*此文档将随着系统发展持续更新,请定期检查事件完整性。*
|
||||
@ -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 作为类和结构体的性能差异
|
||||
|
||||
@ -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 模式填充)
|
||||
[待填写]
|
||||
@ -185,42 +185,6 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化仿真环境
|
||||
/// </summary>
|
||||
private void InitializeSimulation()
|
||||
{
|
||||
// 添加天气
|
||||
AddWeathers();
|
||||
|
||||
// 添加目标(坦克)
|
||||
AddTankTarget();
|
||||
|
||||
// 添加各种类型的导弹
|
||||
AddLaserSemiActiveMissile();
|
||||
AddLaserBeamRiderMissile();
|
||||
AddTerminalSensitiveMissile();
|
||||
AddInfraredCommandMissile();
|
||||
AddInfraredImagingMissile();
|
||||
AddMillimeterWaveMissile();
|
||||
AddCompositeGuidanceMissile();
|
||||
|
||||
// 添加各种传感器和指示器
|
||||
AddIndicators();
|
||||
|
||||
// 添加烟幕弹
|
||||
AddSmokeGrenade();
|
||||
|
||||
// 添加激光诱偏目标
|
||||
AddLaserDecoy();
|
||||
|
||||
// 添加各类型干扰器
|
||||
AddJammers();
|
||||
|
||||
// 打印所有注册的干扰器
|
||||
PrintAllJammers();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加天气
|
||||
/// </summary>
|
||||
@ -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}");
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user