ThreatSourceLibaray/ThreatSource/src/Indicator/InfraredTracker.cs

431 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using ThreatSource.Simulation;
using ThreatSource.Utils;
using ThreatSource.Missile;
using ThreatSource.Jammer;
using System.Diagnostics;
using System; // Added for Action
namespace ThreatSource.Indicator
{
/// <summary>
/// 红外测角仪类,实现了红外制导导弹的跟踪和制导功能
/// </summary>
/// <remarks>
/// 该类提供了红外测角仪的核心功能:
/// - 红外目标跟踪
/// - 角度测量和计算
/// - 制导指令生成
/// - 事件处理和状态管理
/// - 干扰防护处理
/// 通过测量目标的红外辐射实现对导弹的制导控制
/// </remarks>
public class InfraredTracker : BaseIndicator
{
/// <summary>
/// 定义设备支持的干扰类型
/// </summary>
/// <remarks>
/// 红外测角仪支持的干扰类型:
/// - 红外干扰
/// </remarks>
public override IEnumerable<JammingType> SupportedJammingTypes => [JammingType.Infrared, JammingType.SmokeGrenade];
/// <summary>
/// 红外测角仪配置参数
/// </summary>
/// <remarks>
/// 包含测角仪的工作参数:
/// - 初始位置和姿态
/// - 最大跟踪距离
/// - 视场角等性能参数
/// </remarks>
private readonly InfraredTrackerConfig config;
/// <summary>
/// 获取或设置红外测角仪是否正在跟踪目标
/// </summary>
/// <remarks>
/// true表示正在跟踪目标
/// false表示未在跟踪状态
/// 用于控制测角仪的工作状态
/// </remarks>
public bool IsTracking { get; private set; }
/// <summary>
/// 初始化红外测角仪的新实例
/// </summary>
/// <param name="id">测角仪ID</param>
/// <param name="targetId">目标ID</param>
/// <param name="config">配置参数</param>
/// <param name="motionParameters">初始运动参数</param>
/// <param name="manager">仿真管理器实例</param>
/// <remarks>
/// 构造过程:
/// - 初始化基本属性
/// - 设置目标关联
/// - 配置工作参数
/// - 设置初始状态
/// </remarks>
public InfraredTracker(string id, string targetId, InfraredTrackerConfig config, MotionParameters motionParameters, ISimulationManager manager)
: base(id, motionParameters, manager)
{
TargetId = targetId;
MissileId = null;
this.config = config;
IsTracking = false;
// 初始化干扰处理
InitializeJamming(config.JammingResistanceThreshold, SupportedJammingTypes);
}
/// <summary>
/// 更新指示器特定功能
/// </summary>
/// <param name="deltaTime">时间步长,单位:秒</param>
/// <remarks>
/// 实现红外测角仪特定的更新逻辑:
/// - 基类 Update 会检查 IsJammed (电子干扰)
/// - UpdateTracking 方法内部会处理 IsTargetObscured (烟幕遮挡)
/// - 更新跟踪状态
/// </remarks>
protected override void UpdateIndicator(double deltaTime)
{
// 基类 Update 已经检查了 IsJammed
// if (IsJammed)
// {
// StopTracking(); // Logic moved to HandleJammingApplied
// Console.WriteLine($"InfraredTracker {Id} 受到红外干扰,停止跟踪。");
// return;
// }
// 无论是否被遮挡,都尝试更新跟踪状态
// IsTargetObscured is handled within UpdateTracking
UpdateTracking();
}
/// <summary>
/// 更新跟踪状态
/// </summary>
/// <remarks>
/// 跟踪过程:
/// - 获取目标和导弹实体
/// - 如果被遮挡,使用最后已知目标位置;否则获取当前位置
/// - 计算相对位置和距离
/// - 检查跟踪条件
/// - 生成制导指令
/// </remarks>
private void UpdateTracking()
{
if (MissileId == null)
{
IsTracking = false;
return; // 没有导弹需要制导
}
var missile = SimulationManager.GetEntityById(MissileId);
if (missile is not InfraredCommandGuidedMissile missileElement)
{
StopTracking(); // 导弹无效
return;
}
Vector3D currentTargetPosition;
if (IsTargetObscured)
{
// 目标被遮挡,尝试使用最后已知位置
if (_lastKnownTargetPosition != null)
{
currentTargetPosition = _lastKnownTargetPosition;
Console.WriteLine($"InfraredTracker {Id}: 目标被遮挡,使用最后已知位置 {currentTargetPosition}");
}
else
{
// 没有最后已知位置 (例如首次观测前就被遮挡)
StopTracking();
return;
}
}
else
{
// 目标未被遮挡,获取当前目标状态
if (string.IsNullOrEmpty(TargetId))
{
// 没有目标ID无法跟踪
StopTracking();
return;
}
var target = SimulationManager.GetEntityById(TargetId);
if (target is not SimulationElement targetElement)
{
// 目标无效
StopTracking();
return;
}
currentTargetPosition = targetElement.Position;
}
IsTracking = true;
// 计算导弹到测角仪的距离
double distanceToMissile = Vector3D.Distance(Position, missileElement.Position);
// 检查导弹是否在跟踪范围内
if (distanceToMissile <= config.MaxTrackingRange)
{
// 计算测角仪到导弹的向量
Vector3D trackerToMissile = missileElement.Position - Position;
// 计算测角仪到目标的向量 (使用确定的目标位置)
Vector3D trackerToTarget = currentTargetPosition - Position;
// 发送制导指令事件
PublishGuidanceCommandEvent(missileElement.Id, trackerToMissile, trackerToTarget, Id);
}
else
{
// 导弹超出跟踪范围,停止跟踪
StopTracking();
}
}
/// <summary>
/// 停止跟踪目标
/// </summary>
/// <remarks>
/// 停止过程:
/// - 清除导弹关联
/// - 重置跟踪状态
/// (不再清除 TargetId)
/// </remarks>
public void StopTracking()
{
if (!IsTracking && MissileId == null) return; // 避免重复操作和日志
MissileId = null;
IsTracking = false;
}
/// <summary>
/// 发布制导指令事件
/// </summary>
/// <param name="missileId">导弹ID</param>
/// <param name="trackerToMissileVector">测角仪到导弹的向量</param>
/// <param name="trackerToTargetVector">测角仪到目标的向量</param>
/// <param name="senderId">发送者ID</param>
/// <remarks>
/// 发布过程:
/// - 创建制导指令事件
/// - 设置事件参数
/// - 发布到事件系统
/// </remarks>
private void PublishGuidanceCommandEvent(string missileId, Vector3D trackerToMissileVector, Vector3D trackerToTargetVector, string senderId)
{
var evt = new InfraredGuidanceCommandEvent
{
TargetMissileId = missileId,
TrackerToMissileVector = trackerToMissileVector,
TrackerToTargetVector = trackerToTargetVector,
SenderId = senderId
};
SimulationManager.PublishEvent(evt);
}
/// <summary>
/// 处理红外指令制导导弹点亮红外热源事件
/// </summary>
/// <param name="evt">红外热源点亮事件数据</param>
/// <remarks>
/// 处理过程:
/// - 记录导弹ID
/// - 准备开始跟踪
/// </remarks>
private void OnInfraredGuidanceMissileLight(InfraredGuidanceMissileLightEvent evt)
{
// 处理导弹点亮红外热源事件
MissileId = evt.SenderId ?? "";
}
/// <summary>
/// 处理红外指令制导导弹熄灭红外热源事件
/// </summary>
/// <param name="evt">红外热源熄灭事件数据</param>
/// <remarks>
/// 处理过程:
/// - 验证导弹ID
/// - 停止跟踪
/// </remarks>
private void OnInfraredGuidanceMissileLightOff(InfraredGuidanceMissileLightOffEvent evt)
{
// 处理导弹熄灭红外热源事件
if (evt.SenderId == MissileId) StopTracking();
}
/// <summary>
/// 激活红外测角仪
/// </summary>
/// <remarks>
/// 激活过程:
/// - 调用基类激活方法
/// - 订阅红外事件
/// - 准备开始工作
/// </remarks>
public override void Activate()
{
if (!IsActive)
{
base.Activate(); // Handles IsActive and subscribes HandleJammingEvent
// Removed JammingEvent subscriptions for OnInfraredJamming and HandleSmokeEvent
// Subscribe to missile-specific events (KEEP THESE)
SimulationManager.SubscribeToEvent<InfraredGuidanceMissileLightEvent>(OnInfraredGuidanceMissileLight);
SimulationManager.SubscribeToEvent<InfraredGuidanceMissileLightOffEvent>(OnInfraredGuidanceMissileLightOff);
// 子类特定的激活逻辑
Debug.WriteLine($"红外测角仪 {Id} 已激活");
}
}
/// <summary>
/// 停用红外测角仪
/// </summary>
/// <remarks>
/// 停用过程:
/// - 调用基类停用方法
/// - 取消事件订阅
/// - 清理工作状态
/// </remarks>
public override void Deactivate()
{
if (IsActive)
{
// 子类特定的停用逻辑
StopTracking(); // 停止跟踪
// Unsubscribe from missile-specific events (KEEP THESE)
SimulationManager.UnsubscribeFromEvent<InfraredGuidanceMissileLightEvent>(OnInfraredGuidanceMissileLight);
SimulationManager.UnsubscribeFromEvent<InfraredGuidanceMissileLightOffEvent>(OnInfraredGuidanceMissileLightOff);
// Removed JammingEvent subscriptions for OnInfraredJamming and HandleSmokeEvent
Debug.WriteLine($"红外测角仪 {Id} 已停用");
base.Deactivate(); // Handles IsActive and unsubscribes HandleJammingEvent
}
}
/// <summary>
/// 判断是否应该处理传入的干扰参数
/// </summary>
/// <param name="parameters">干扰参数</param>
/// <returns>如果应该处理则返回 true否则返回 false</returns>
protected override bool ShouldHandleJamming(JammingParameters parameters)
{
// 首先调用基类检查是否支持该干扰类型 (包括 SmokeScreen)
if (!base.ShouldHandleJamming(parameters))
{
return false;
}
// 对红外干扰添加波长检查
if (parameters.Type == JammingType.Infrared)
{
double wavelength = parameters.Wavelength ?? 0;
// 检查波长是否在中波红外 (3-5 微米) 或长波红外 (8-12 微米) 范围内
bool isCompatible = (wavelength >= 3 && wavelength <= 5) || (wavelength >= 8 && wavelength <= 12);
if (!isCompatible)
{
Debug.WriteLine($"[InfraredTracker] {Id} 忽略红外干扰:波长 {wavelength}um 不在兼容范围 (3-5um 或 8-12um) 内。", "Jamming");
return false;
}
}
// 如果是支持的非红外干扰 (例如烟幕) 或通过了红外波长检查,则返回 true
return true;
}
/// <summary>
/// 获取红外测角仪运行状态
/// </summary>
/// <returns>包含测角仪完整状态信息的结构体</returns>
/// <remarks>
/// 返回信息包括:
/// - 目标和导弹关联状态
/// - 工作类型和状态
/// - 位置和姿态信息
/// - 激活状态
/// - 干扰状态 (包括电子干扰和烟幕遮挡)
/// </remarks>
public override IndicatorRunningState GetRunningState()
{
return new IndicatorRunningState
{
TargetId = TargetId ?? "",
MissileId = MissileId ?? "",
Type = IndicatorType.InfraredTracker,
State = IsTracking ? IndicatorState.Indicating : IndicatorState.Idle,
Position = Position,
Orientation = Orientation,
IsActive = IsActive,
JammingState = (IsJammed || IsTargetObscured) ? JammingState.Jammed : JammingState.Normal
};
}
/// <summary>
/// 获取红外测角仪状态信息
/// </summary>
/// <returns>包含测角仪状态的详细描述</returns>
/// <remarks>
/// 返回信息包括:
/// - 基本标识信息
/// - 位置信息
/// - 目标关联状态
/// - 工作状态
/// - 跟踪状态
/// - 干扰/遮挡状态
/// </remarks>
public override string GetStatus()
{
string jammingStatusString = "正常";
if (IsJammed) jammingStatusString = "受红外干扰";
if (IsTargetObscured) jammingStatusString = IsJammed ? "受红外干扰和烟幕遮挡" : "目标被烟幕遮挡";
return base.GetStatus() + "\n" +
$" 位置: {Position}\n" +
$" 跟踪导弹: {MissileId ?? ""}\n" +
$" 目标: {TargetId ?? ""}\n" +
$" 状态: {(IsActive ? "" : "")}\n" +
$" 跟踪状态: {(IsTracking ? "" : "")}\n" +
$" 干扰/遮挡状态: {jammingStatusString}\n";
}
/// <summary>
/// 处理指示器被干扰的事件
/// </summary>
/// <param name="parameters">干扰参数</param>
protected override void HandleJammingApplied(JammingParameters parameters)
{
base.HandleJammingApplied(parameters); // Calls RecalculateObscurationStatus for smoke
// 添加子类特定响应:如果是红外干扰,停止跟踪
if (parameters.Type == JammingType.Infrared)
{
Debug.WriteLine($"[InfraredTracker] {Id} 受到红外干扰,停止跟踪。", "Jamming");
StopTracking();
}
}
/// <summary>
/// 处理指示器干扰被清除的事件
/// </summary>
/// <param name="parameters">干扰参数</param>
protected override void HandleJammingCleared(JammingParameters parameters)
{
base.HandleJammingCleared(parameters); // Calls RecalculateObscurationStatus for smoke
// 红外干扰清除后不需要特殊操作UpdateIndicator 会重新评估跟踪状态
if (parameters.Type == JammingType.Infrared)
{
Debug.WriteLine($"[InfraredTracker] {Id} 红外干扰已清除。", "Jamming");
}
}
}
}