ThreatSourceLibaray/ThreatSource/src/Indicator/LaserDesignator.cs

365 lines
13 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 System.Diagnostics;
using ThreatSource.Jammer;
namespace ThreatSource.Indicator
{
/// <summary>
/// 激光指示器类,实现了对目标的激光照射和制导功能
/// </summary>
/// <remarks>
/// 该类提供了激光指示器的核心功能:
/// - 激光目标照射
/// - 抗干扰处理
/// - 事件管理
/// - 状态监控
/// 通过激光照射目标实现半主动激光制导
/// </remarks>
public class LaserDesignator : BaseIndicator
{
/// <summary>
/// 定义设备支持的干扰类型
/// </summary>
/// <remarks>
/// 激光目标指示器支持的干扰类型:
/// - 激光干扰
/// - 烟雾干扰
/// </remarks>
public override IEnumerable<JammingType> SupportedJammingTypes => [JammingType.Laser, JammingType.SmokeGrenade];
/// <summary>
/// 定义设备支持的阻塞干扰类型
/// </summary>
public override IEnumerable<JammingType> SupportedBlockingJammingTypes => [JammingType.Laser];
/// <summary>
/// 获取或设置干扰阈值,单位:分贝
/// </summary>
/// <remarks>
/// 定义了激光指示器的抗干扰能力
/// 当干扰信号强度超过此阈值时触发干扰效果
/// </remarks>
public double JammingThreshold { get; private set; } = 0.0;
/// <summary>
/// 获取或设置是否正在照射状态
/// </summary>
/// <remarks>
/// true表示正在执行激光照射
/// false表示未在照射状态
/// 控制激光发射状态
/// </remarks>
public bool IsIlluminationOn { get; private set; } = false;
/// <summary>
/// 获取或设置激光编码配置
/// </summary>
/// <remarks>
/// 包含激光信号的编码信息
/// 用于抗干扰和安全识别
/// </remarks>
public readonly LaserDesignatorConfig config;
/// <summary>
/// 初始化激光指示器的新实例
/// </summary>
/// <param name="id">激光指示器ID</param>
/// <param name="targetId">目标ID</param>
/// <param name="missileId">导弹ID</param>
/// <param name="config">配置参数</param>
/// <param name="kinematicState">初始运动参数</param>
/// <param name="simulationManager">仿真管理器实例</param>
/// <remarks>
/// 构造过程:
/// - 初始化基本属性
/// - 设置目标和导弹关联
/// - 配置激光参数
/// - 设置初始状态
/// </remarks>
public LaserDesignator(string id, string targetId, string missileId, LaserDesignatorConfig config, KinematicState kinematicState, ISimulationManager simulationManager)
: base(id, kinematicState, simulationManager)
{
TargetId = targetId;
MissileId = missileId;
IsActive = false;
IsIlluminationOn = false;
this.config = config;
JammingThreshold = config.JammingResistanceThreshold;
// 设置干扰阈值并添加支持的干扰类型
InitializeJamming(JammingThreshold, SupportedJammingTypes, SupportedBlockingJammingTypes);
}
/// <summary>
/// 更新激光指示器状态
/// </summary>
/// <param name="deltaTime">时间步长,单位:秒</param>
/// <remarks>
/// 更新过程:
/// - 基类 Update 会检查 IsJammed (电子干扰)
/// - 此方法内部检查 IsTargetObscured (烟幕遮挡)
/// - 更新指示器朝向 (仅当未被遮挡时)
/// - 发布状态事件 (仅当未被遮挡且照射开启时)
/// </remarks>
protected override void UpdateIndicator(double deltaTime)
{
// 基类 Update 已经检查了 IsJammed
// if (IsJammed )
// {
// return; // Specific response (stopping illumination) moved to HandleJammingApplied
// }
if (!IsTargetObscured)
{
// 未被遮挡,执行正常更新
UpdateOrientation();
// 如果正在照射,发布更新事件
if (IsIlluminationOn)
{
PublishIlluminationUpdateEvent();
}
}
}
private void UpdateOrientation()
{
if (!string.IsNullOrEmpty(TargetId))
{
if (SimulationManager.GetEntityById(TargetId) is SimulationElement target)
{
Vector3D direction = (target.KState.Position - KState.Position).Normalize();
if (direction.MagnitudeSquared() < 1e-9) return;
double yaw = Math.PI + Math.Atan2(direction.Z, direction.X);
double pitch = -Math.Asin(direction.Y);
KState.Orientation = new Orientation(yaw, pitch, 0);
_lastKnownTargetPosition = target.KState.Position;
Debug.WriteLine($"激光指示器 {Id} 更新朝向: {KState.Orientation}, _lastKnownTargetPosition: {_lastKnownTargetPosition}");
}
}
}
/// <summary>
/// 开始激光照射
/// </summary>
/// <remarks>
/// 启动过程:
/// - 设置照射状态
/// - 记录开始时间
/// - 发布开始事件
/// - 输出状态信息
/// </remarks>
internal void StartLaserIllumination()
{
if (!IsIlluminationOn)
{
IsIlluminationOn = true;
PublishIlluminationUpdateEvent();
}
}
/// <summary>
/// 停止激光照射
/// </summary>
/// <remarks>
/// 停止过程:
/// - 清除照射状态
/// - 记录停止时间
/// - 发布停止事件
/// - 输出状态信息
/// </remarks>
internal void StopLaserIllumination()
{
if (IsIlluminationOn)
{
IsIlluminationOn = false;
PublishIlluminationStopEvent();
}
}
/// <summary>
/// 处理指示器被干扰的事件
/// </summary>
/// <param name="parameters">干扰参数</param>
protected override void HandleJammingApplied(JammingParameters parameters)
{
base.HandleJammingApplied(parameters); // Calls RecalculateObscurationStatus for smoke
// 实现激光指示器的干扰效果
if (parameters.Type == JammingType.Laser)
{
Debug.WriteLine($"[激光指示器] {Id} 受到激光干扰,停止照射。", "Jamming");
// 停止激光照射
StopLaserIllumination();
}
}
/// <summary>
/// 处理指示器干扰被清除的事件
/// </summary>
/// <param name="parameters">干扰参数</param>
protected override void HandleJammingCleared(JammingParameters parameters)
{
base.HandleJammingCleared(parameters); // Calls RecalculateObscurationStatus for smoke
// 添加子类特定响应:如果是激光干扰清除,并且设备仍激活,尝试启动照射
if (parameters.Type == JammingType.Laser)
{
Debug.WriteLine($"[激光指示器] {Id} 激光干扰已清除。", "Jamming");
// 如果设备仍处于激活状态,并且没有其他阻塞性干扰,恢复激光照射
if (IsActive && !IsBlockingJammed)
{
StartLaserIllumination();
}
}
}
/// <summary>
/// 激活激光指示器
/// </summary>
/// <remarks>
/// 激活过程:
/// - 调用基类 Activate (处理 IsActive 和 JammingEvent 订阅)
/// - 开始激光照射
/// </remarks>
public override void Activate()
{
if (!IsActive)
{
base.Activate();
// 子类特定的激活逻辑
Debug.WriteLine($"激光指示器 {Id} 已激活");
StartLaserIllumination();
}
}
/// <summary>
/// 停用激光指示器
/// </summary>
/// <remarks>
/// 停用过程:
/// - 停止激光照射
/// - 调用基类 Deactivate (处理 IsActive 和 JammingEvent 取消订阅)
/// </remarks>
public override void Deactivate()
{
if (IsActive)
{
// 子类特定的停用逻辑
StopLaserIllumination();
Debug.WriteLine($"激光指示器 {Id} 已停用");
base.Deactivate(); // Handles IsActive and unsubscribes HandleJammingEvent
}
}
/// <summary>
/// 添加编码参数
/// </summary>
/// <param name="key">参数名称</param>
/// <param name="value">参数值</param>
/// <remarks>
/// 添加特定编码类型的额外参数
/// 如PPM编码的脉冲位置模式、PWM编码的脉冲宽度等
/// </remarks>
public void AddCodeParameter(string key, object value)
{
if (config.LaserCodeConfig != null)
{
config.LaserCodeConfig.Code.Parameters[key] = value;
}
}
/// <summary>
/// 发布激光照射更新事件
/// </summary>
/// <remarks>
/// 发布过程:
/// - 创建事件对象
/// - 设置事件属性
/// - 添加编码信息
/// - 发布到事件系统
/// </remarks>
private void PublishIlluminationUpdateEvent()
{
Debug.WriteLine($"激光照射更新事件: {Id}, TargetId: {TargetId}");
var illuminationEvent = new LaserIlluminationUpdateEvent
{
LaserDesignatorId = Id,
TargetId = TargetId,
SpotPosition = _lastKnownTargetPosition
};
// 添加编码信息
if (config.LaserCodeConfig != null)
{
illuminationEvent.LaserCodeConfig = config.LaserCodeConfig;
}
PublishEvent(illuminationEvent);
}
/// <summary>
/// 发布激光照射停止事件
/// </summary>
/// <remarks>
/// 发布过程:
/// - 创建停止事件
/// - 设置结束参数
/// - 发布到事件系统
/// - 记录停止日志
/// </remarks>
private void PublishIlluminationStopEvent()
{
var evt = new LaserIlluminationStopEvent { LaserDesignatorId = Id, TargetId = TargetId };
PublishEvent(evt);
}
/// <summary>
/// 判断是否应该处理传入的干扰参数
/// </summary>
/// <param name="parameters">干扰参数</param>
/// <returns>如果应该处理则返回 true否则返回 false</returns>
protected override bool ShouldHandleJamming(JammingParameters parameters)
{
// 首先调用基类的检查,看是否支持此类型
if (!base.ShouldHandleJamming(parameters))
{
return false;
}
// 对激光干扰添加波长检查
if (parameters.Type == JammingType.Laser)
{
// 检查波长匹配 (单位: 微米)
if (Math.Abs((parameters.Wavelength ?? 0) - config.Wavelength) > 1e-6) // 使用配置的波长
{
Debug.WriteLine($"[激光指示器] {Id} 忽略激光干扰:波长 {parameters.Wavelength}um 与工作波长 {config.Wavelength}um 不匹配。", "Jamming");
return false;
}
}
// 对于其他支持的类型 (如 SmokeGrenade它没有额外的检查) 或通过了特定检查的类型,返回 true
return true;
}
/// <summary>
/// 获取激光驾束仪的详细状态信息
/// </summary>
/// <returns>包含激光驾束仪状态的信息对象</returns>
public override ElementStatusInfo GetStatusInfo()
{
// 获取基类状态信息
var statusInfo = base.GetStatusInfo();
// 添加制导系统特有属性
statusInfo.ExtendedProperties["IsIlluminationOn"] = IsIlluminationOn;
statusInfo.ExtendedProperties["Power"] = config.Power;
statusInfo.ExtendedProperties["Wavelength"] = config.Wavelength;
statusInfo.ExtendedProperties["LaserCodeConfig"] = config.LaserCodeConfig;
return statusInfo;
}
}
}