365 lines
13 KiB
C#
365 lines
13 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|