using ThreatSource.Utils;
using ThreatSource.Simulation;
using ThreatSource.Sensor;
using ThreatSource.Indicator;
using ThreatSource.Jammer;
using System.Diagnostics;
using AirTransmission;
namespace ThreatSource.Guidance
{
///
/// 激光半主动制导系统类,实现了基于激光照射的目标跟踪和制导功能
///
///
/// 该类提供了激光半主动制导系统的核心功能:
/// - 激光目标照射
/// - 反射光探测
/// - 信号处理
/// - 比例导引控制
/// 用于实现精确制导打击
///
public class LaserSemiActiveGuidanceSystem : BaseGuidanceSystem
{
private readonly LaserSemiActiveGuidanceConfig config;
///
/// 获取或设置目标位置 (使用可空类型)
///
///
/// 记录当前跟踪目标的三维位置
/// 用于制导计算
///
private Vector3D? TargetPosition { get; set; }
///
/// 获取或设置接收到的激光功率
///
///
/// 记录接收到的激光功率
/// 用于制导计算
///
private double ReceivedLaserPower { get; set; }
///
/// 获取或设置激光照射状态
///
///
/// 指示当前是否有激光照射目标
/// 影响系统的工作状态
///
private bool LaserIlluminationOn { get; set; }
///
/// 获取或设置期望的激光编码
///
///
/// 导弹期望接收的编码信息
/// 用于验证接收到的激光信号
/// 默认编码为PPM编码,值为1234
///
private LaserCodeConfig? InternalLaserCodeConfig { get; set; }
///
/// 获取或设置支持的编码类型列表
///
///
/// 定义导弹支持的编码类型
/// 默认支持PRF、PPM和PWM编码
///
private readonly List supportedCodeTypes =
[
LaserCodeType.PRF,
LaserCodeType.PPM,
LaserCodeType.PWM
];
///
/// 四象限探测器实例
///
///
/// 用于精确测量光斑位置
/// 计算目标方向误差
/// 提供高精度制导信号
///
private readonly QuadrantDetector quadrantDetector;
///
/// 获取或设置光斑偏移灵敏度
///
///
/// 定义了四象限探测器对光斑偏移的响应灵敏度
/// 影响制导系统的响应速度和稳定性
/// 典型值为0.05
///
private double SpotOffsetSensitivity { get; set; } = 0.05;
///
/// 上一次的制导加速度,用于平滑处理
///
///
/// 用于实现加速度平滑处理
/// 减少加速度突变,使导弹飞行更稳定
///
private Vector3D PreviousGuidanceAcceleration { get; set; } = Vector3D.Zero;
///
/// 加速度平滑系数
///
///
/// 范围(0,1],值越小平滑效果越强
/// 影响加速度的平滑程度
///
private const double AccelerationSmoothingFactor = 0.5;
///
/// 烟幕衰减
///
private double SmokeAttenuation { get; set; } = 1.0;
///
/// 激光目标列表,包括真实目标和诱偏目标
///
private readonly List<(SimulationElement Target, SimulationElement Source)> laserTargets = [];
///
/// 初始化激光半主动制导系统的新实例
///
/// 制导系统ID
/// 最大加速度,单位:米/平方秒
/// 制导系数
/// 激光编码配置
/// 激光半主动导引系统配置
/// 仿真管理器实例
///
/// 构造过程:
/// - 初始化基类参数
/// - 初始化目标信息
/// - 初始化激光参数
/// - 创建四象限探测器
/// - 加载干扰阈值配置
///
public LaserSemiActiveGuidanceSystem(
string id,
double maxAcceleration,
double guidanceCoefficient,
LaserCodeConfig laserCodeConfig,
LaserSemiActiveGuidanceConfig guidanceConfig,
ISimulationManager simulationManager)
: base(id, maxAcceleration, guidanceCoefficient, simulationManager)
{
config = guidanceConfig;
LaserIlluminationOn = false;
InternalLaserCodeConfig = laserCodeConfig;
// 创建四象限探测器实例,使用配置中的参数
quadrantDetector = new QuadrantDetector(
config.SensorDiameter,
config.FocusedSpotDiameter,
config.LockThreshold);
// 设置光斑偏移灵敏度
SpotOffsetSensitivity = config.SpotOffsetSensitivity;
// 初始化加速度平滑处理
PreviousGuidanceAcceleration = Vector3D.Zero;
InitializeJamming(guidanceConfig.JammingResistanceThreshold, [JammingType.Laser, JammingType.SmokeScreen]);
}
///
/// 激活制导系统
///
///
/// 激活过程:
/// - 调用基类激活
/// - 订阅激光照射事件
/// - 订阅激光干扰事件
///
public override void Activate()
{
base.Activate();
// 订阅激光照射事件
SimulationManager.SubscribeToEvent(OnLaserIlluminationUpdate);
SimulationManager.SubscribeToEvent(OnLaserIlluminationStop);
// 订阅激光干扰事件
SimulationManager.SubscribeToEvent(OnLaserJamming);
// 订阅烟幕事件
SimulationManager.SubscribeToEvent(OnSmokeScreen);
// 订阅诱偏目标照射事件
SimulationManager.SubscribeToEvent(OnLaserDecoy);
SimulationManager.SubscribeToEvent(OnLaserDecoyStop);
}
///
/// 停用制导系统
///
///
/// 停用过程:
/// - 调用基类停用
/// - 取消订阅激光照射事件
///
public override void Deactivate()
{
base.Deactivate();
// 取消订阅激光照射事件
SimulationManager.UnsubscribeFromEvent(OnLaserIlluminationUpdate);
SimulationManager.UnsubscribeFromEvent(OnLaserIlluminationStop);
// 取消订阅激光干扰事件
SimulationManager.UnsubscribeFromEvent(OnLaserJamming);
// 取消订阅烟幕事件
SimulationManager.UnsubscribeFromEvent(OnSmokeScreen);
// 取消订阅诱偏目标照射事件
SimulationManager.UnsubscribeFromEvent(OnLaserDecoy);
SimulationManager.UnsubscribeFromEvent(OnLaserDecoyStop);
TargetPosition = null;
}
///
/// 处理激光照射更新事件
///
/// 激光照射更新事件
private void OnLaserIlluminationUpdate(LaserIlluminationUpdateEvent evt)
{
if (evt?.LaserDesignatorId != null && evt?.TargetId != null)
{
try
{
LaserDesignator laserDesignator = SimulationManager.GetEntityById(evt.LaserDesignatorId) as LaserDesignator ?? throw new Exception("激光指示器不存在");
SimulationElement target = SimulationManager.GetEntityById(evt.TargetId) as SimulationElement ?? throw new Exception("目标不存在");
// 添加激光目标
if (!laserTargets.Any(t => t.Target.Id == target.Id))
{
laserTargets.Add((target, laserDesignator));
}
// 处理激光照射更新事件
ProcessLaserIlluminationUpdateEvent(evt);
}
catch (Exception ex)
{
Trace.WriteLine($"处理激光照射更新事件时出错: {ex.Message}");
}
}
else
{
Trace.WriteLine("警告:激光照射更新事件缺少必要参数");
}
}
///
/// 处理激光照射停止事件
///
/// 激光照射停止事件
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
{
LaserIlluminationOn = false;
HasGuidance = false; // 禁用制导
PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
TargetPosition = null;
}
///
/// 处理诱偏目标照射事件
///
/// 诱偏目标照射事件
private void OnLaserDecoy(LaserDecoyEvent evt)
{
if (evt.LaserDecoyId != null && evt.SourceId != null)
{
LaserDecoy decoyTarget = SimulationManager.GetEntityById(evt.LaserDecoyId) as LaserDecoy ?? throw new Exception("诱偏目标不存在");
SimulationElement decoySource = SimulationManager.GetEntityById(evt.SourceId) as SimulationElement ?? throw new Exception("诱偏源不存在");
// 添加激光目标
if (!laserTargets.Any(t => t.Target.Id == decoyTarget.Id))
{
laserTargets.Add((decoyTarget, decoySource));
}
}
}
///
/// 处理诱偏目标照射停止事件
///
/// 诱偏目标照射停止事件
private void OnLaserDecoyStop(LaserDecoyStopEvent evt)
{
if (evt?.LaserDecoyId != null)
{
laserTargets.RemoveAll(t => t.Target.Id == evt.LaserDecoyId);
}
}
///
/// 处理激光干扰事件
///
/// 激光干扰事件
private void OnLaserJamming(LaserJammingEvent evt)
{
if (evt == null) return;
// 创建干扰参数
var parameters = new JammingParameters
{
Type = JammingType.Laser,
Power = evt.JammingPower,
Direction = evt.JammingDirection,
SourcePosition = evt.JammingSourcePosition,
AngleRange = evt.JammingAngleRange,
Mode = evt.JammingMode,
Duration = evt.Duration
};
// 使用JammableComponent进行干扰判断
ApplyJamming(parameters);
// 如果被硬干扰,切换到搜索模式
if (IsHardJammed)
{
// 清除目标信息
TargetPosition = null;
LaserIlluminationOn = false;
// 记录干扰信息
Trace.WriteLine($"激光半主动制导系统被硬干扰 - 功率: {evt.JammingPower}W, 位置: {evt.JammingSourcePosition}, 方向: {evt.JammingDirection}");
}
}
///
/// 处理烟幕事件
///
/// 烟幕事件
private void OnSmokeScreen(SmokeScreenEvent evt)
{
if (evt != null && evt.SmokeGrenadeId != null)
{
// 获取烟幕弹的配置
if (SimulationManager.GetEntityById(evt.SmokeGrenadeId) is SmokeGrenade smokeGrenade)
{
var config = smokeGrenade.config;
// 创建干扰参数
var parameters = new JammingParameters
{
Type = JammingType.SmokeScreen,
JammerId = smokeGrenade.Id,
SourcePosition = smokeGrenade.Position,
Direction = smokeGrenade.Orientation.ToVector(),
AngleRange = config.SmokeType == SmokeScreenType.Wall ? Math.PI : Math.PI * 2, // 墙状烟幕为半球形覆盖,云状为全方位
SmokeConcentration = config.Concentration,
SmokeType = config.SmokeType,
SmokeThickness = config.Thickness,
Duration = config.Duration,
Mode = JammingMode.Obscuration
};
// 使用JammableComponent进行干扰判断
ApplyJamming(parameters);
}
}
}
///
/// 处理系统被干扰的事件
///
/// 干扰参数
protected override void HandleJammingApplied(JammingParameters parameters)
{
base.HandleJammingApplied(parameters);
if (parameters.Type == JammingType.Laser)
{
// 在硬干扰下切换到搜索模式
if (LaserIlluminationOn)
{
LaserIlluminationOn = false;
PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
}
}
else if (parameters.Type == JammingType.SmokeScreen)
{
if (SimulationManager.GetEntityById(parameters.JammerId) is SmokeGrenade smokeGrenade)
{
// 检查目标位置是否有效,并且激光照射是否开启 (烟幕只影响接收到的信号)
if (TargetPosition != null && LaserIlluminationOn)
{
// 计算烟幕衰减 (1.0 表示无衰减)
SmokeAttenuation = smokeGrenade.GetSmokeTransmittanceOnLine(Position, TargetPosition, config.LaserWavelength);
Console.WriteLine($"[烟幕干扰应用 Laser] 视线透过率/衰减系数: {SmokeAttenuation:F3}");
}
else
{
// 目标无效或激光未照射,暂不计算特定视线衰减
SmokeAttenuation = 1.0;
Console.WriteLine("[烟幕干扰应用 Laser] 目标位置无效或激光未照射,暂不计算烟幕衰减。");
}
}
else
{
// 未找到烟幕弹,假定无衰减
SmokeAttenuation = 1.0;
}
}
}
///
/// 处理系统干扰被清除的事件
///
/// 被清除的干扰类型
protected override void HandleJammingCleared(JammingType type)
{
base.HandleJammingCleared(type);
}
///
/// 更新制导系统的状态和计算结果
///
/// 时间步长,单位:秒
/// 导弹位置,单位:米
/// 导弹速度,单位:米/秒
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
{
base.Update(deltaTime, missilePosition, missileVelocity);
// 处理接收到的所有激光信号
ProcessLaserTargets();
if (LaserIlluminationOn && !IsHardJammed)
{
// 更新制导状态
HasGuidance = quadrantDetector.IsTargetLocked;
if (HasGuidance)
{
CalculateGuidanceAcceleration(deltaTime);
}
else
{
GuidanceAcceleration = Vector3D.Zero;
PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
}
}
else
{
HasGuidance = false;
GuidanceAcceleration = Vector3D.Zero;
PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
}
}
///
/// 处理接收到的所有激光目标
///
///
/// 基于接收到的激光目标计算合成光斑位置
///
private void ProcessLaserTargets()
{
try
{
Console.WriteLine($"处理激光信号: 激光目标数量={laserTargets.Count}");
// 如果没有激光源,返回
if (laserTargets.Count == 0)
{
LaserIlluminationOn = false;
return;
}
// 计算所有激光源的总接收功率和加权位置
ReceivedLaserPower = 0.0;
Vector3D weightedPosition = Vector3D.Zero;
foreach (var target in laserTargets)
{
// 计算角度偏差,判断是否在视野范围内
double angleDeviation = CalculateAngleDeviation(target.Target.Position);
if (angleDeviation > config.FieldOfViewAngleInRadians / 2)
{
Console.WriteLine($"处理激光信号: 目标超出视野范围,目标ID: {target.Target.Id}, 角度偏差: {angleDeviation:F2}弧度, 视野范围: {config.FieldOfViewAngleInRadians:F2}弧度");
continue; // 目标超出视野范围
}
double receivedPower = 0;
if (target.Target is LaserDecoy decoy)
{
// 计算接收功率
receivedPower = CalculateReceivedPower(target.Source.Position, target.Target.Position, decoy.DecoyPower, decoy.DecoyLaserDivergenceAngle);
Console.WriteLine($"处理激光信号: 诱偏目标接收功率={receivedPower:E}W, 诱偏目标ID: {target.Target.Id}");
}
else if (target.Source is LaserDesignator laserDesignator)
{
// 计算接收功率
receivedPower = CalculateReceivedPower(target.Source.Position, target.Target.Position, laserDesignator.LaserPower, laserDesignator.LaserDivergenceAngle);
Console.WriteLine($"处理激光信号: 真实目标接收功率={receivedPower:E}W, 真实目标ID: {target.Target.Id}");
}
// 累加功率
ReceivedLaserPower += receivedPower;
// 加权位置
weightedPosition += target.Target.Position * receivedPower;
Console.WriteLine($"处理激光信号: 累加功率={ReceivedLaserPower:E}W, 加权位置={weightedPosition}");
}
// 如果总功率为0,表示没有在视野范围内的激光源
if (ReceivedLaserPower <= 0)
{
LaserIlluminationOn = false;
return;
}
// 计算加权平均位置
TargetPosition = weightedPosition / ReceivedLaserPower;
Console.WriteLine($"处理激光信号: 总功率={ReceivedLaserPower:E}W, 加权平均目标位置={TargetPosition}");
// 更新激光照射参数
LaserIlluminationOn = true;
// 计算光斑偏移
Vector2D spotOffset = CalculateSpotOffset();
// 将合成激光信号传递给四象限探测器
quadrantDetector.ProcessLaserSignal(ReceivedLaserPower, spotOffset);
Debug.WriteLine($"处理激光信号: 总功率={ReceivedLaserPower:E}W, 目标位置={TargetPosition}");
}
catch (Exception ex)
{
Trace.WriteLine($"处理激光信号时出错: {ex.Message}");
}
}
///
/// 计算从特定位置接收到的激光功率
///
/// 激光源位置
/// 目标位置
/// 激光功率
/// 激光发散角
/// 接收到的激光功率,单位:瓦特
private double CalculateReceivedPower(Vector3D sourcePos, Vector3D targetPos, double laserPower, double laserDivergenceAngle)
{
double distanceDesignatorToTarget = (sourcePos - targetPos).Magnitude();
double distanceMissileToTarget = (Position - targetPos).Magnitude();
// 计算大气透过率 (1.使用从激光源到目标的单程透过率,2.使用从目标到导弹的单程透过率)
// 如果当前天气为null,则认为大气透过率为1.0
double atmosphericTransmittanceToTarget = 1.0;
double atmosphericTransmittanceToMissile = 1.0;
// 考虑烟幕衰减,计算大气透过率
if(SimulationManager.CurrentWeather != null)
{
atmosphericTransmittanceToTarget = SmokeAttenuation * AtmosphereDllWrapper.CalculateTransmittance(
distanceDesignatorToTarget,
RadiationType.Laser,
config.LaserWavelength,
SimulationManager.CurrentWeather);
atmosphericTransmittanceToMissile = SmokeAttenuation * AtmosphereDllWrapper.CalculateTransmittance(
distanceMissileToTarget,
RadiationType.Laser,
config.LaserWavelength,
SimulationManager.CurrentWeather);
}
// 计算目标处的光斑面积
double spotAreaAtTarget = Math.PI * Math.Pow(distanceDesignatorToTarget * Math.Tan(laserDivergenceAngle), 2);
// 计算目标处的激光功率密度,考虑大气衰减和发射系统透过率
double powerDensityAtTarget = laserPower * atmosphericTransmittanceToTarget * config.TransmitterEfficiency / spotAreaAtTarget;
// 计算从目标反射的总功率
double reflectedPower = powerDensityAtTarget * config.TargetReflectiveArea * config.ReflectionCoefficient;
// 计算反射光在导弹处的扩散面积(假设漫反射)
double reflectedSpotArea = 2 * Math.PI * Math.Pow(distanceMissileToTarget, 2);
// 计算导弹接收到的功率,考虑大气衰减和接收系统透过率
double receivedPower = reflectedPower * atmosphericTransmittanceToMissile * config.ReceiverEfficiency / reflectedSpotArea;
// 计算镜头接收到的功率比例
double lensArea = Math.PI * Math.Pow(config.LensDiameter / 2, 2);
double illuminatedArea = Math.PI * Math.Pow(distanceMissileToTarget * Math.Tan(config.FieldOfViewAngleInRadians / 2), 2);
double powerRatio = Math.Min(1, lensArea / illuminatedArea);
// 计算聚焦后的功率密度增加
double sensorArea = Math.PI * Math.Pow(config.SensorDiameter / 2, 2);
double focusedArea = Math.PI * Math.Pow(config.FocusedSpotDiameter / 2, 2);
double focusingFactor = sensorArea / focusedArea;
// 计算最终接收到的功率
double finalReceivedPower = receivedPower * powerRatio * focusingFactor;
Debug.WriteLine($"激光功率计算: 源->目标距离={distanceDesignatorToTarget:F1}m (透过率={atmosphericTransmittanceToTarget:F3}), " +
$"目标->导弹距离={distanceMissileToTarget:F1}m (透过率={atmosphericTransmittanceToMissile:F3}), " +
$"最终功率={finalReceivedPower:E}W");
return finalReceivedPower;
}
///
/// 计算目标的角度偏差
///
/// 目标位置
/// 角度偏差,单位:弧度
///
/// 计算目标方向与导弹当前朝向的夹角
///
private double CalculateAngleDeviation(Vector3D targetPos)
{
// 计算目标方向
Vector3D targetDirection = (targetPos - Position).Normalize();
// 计算当前导弹朝向
Vector3D missileDirection = Velocity.Normalize();
// 计算夹角
double dotProduct = Vector3D.DotProduct(targetDirection, missileDirection);
dotProduct = Math.Max(-1.0, Math.Min(1.0, dotProduct)); // 确保在[-1,1]范围内
return Math.Acos(dotProduct);
}
///
/// 计算光斑偏移量
///
/// 光斑中心相对于探测器中心的偏移量,单位:米
///
/// 计算过程:
/// - 计算理想指向方向
/// - 计算当前指向方向
/// - 计算角度偏差
/// - 转换为光斑偏移量
///
private Vector2D CalculateSpotOffset()
{
// Check TargetPosition != null before using it
if (TargetPosition == null)
{
return Vector2D.Zero;
}
// No cast needed, just use TargetPosition directly
Vector3D idealDirection = (TargetPosition - Position).Normalize();
// 计算当前导弹前向方向
Vector3D currentDirection = Velocity.Normalize();
// 计算右向量和上向量
Vector3D right = Vector3D.CrossProduct(Vector3D.UnitY, currentDirection).Normalize();
Vector3D up = Vector3D.CrossProduct(currentDirection, right).Normalize();
// 计算理想方向在当前坐标系中的投影
double forwardComponent = Vector3D.DotProduct(idealDirection, currentDirection);
double rightComponent = Vector3D.DotProduct(idealDirection, right);
double upComponent = Vector3D.DotProduct(idealDirection, up);
// 确保前向分量为正(目标在前方)
if (forwardComponent <= 0)
{
// 目标在后方,无法探测
return new Vector2D(0, 0);
}
// 计算角度偏差
double horizontalAngle = Math.Atan2(rightComponent, forwardComponent);
double verticalAngle = Math.Atan2(upComponent, forwardComponent);
// 转换为光斑偏移量(假设小角度近似)
double focalLength = config.SensorDiameter / (2 * Math.Tan(config.FieldOfViewAngleInRadians / 2));
double horizontalOffset = focalLength * Math.Tan(horizontalAngle);
double verticalOffset = focalLength * Math.Tan(verticalAngle);
return new Vector2D(horizontalOffset, verticalOffset);
}
///
/// 计算制导加速度
///
/// 时间步长,单位:秒
///
/// 计算过程:
/// - 使用四象限探测器获取目标方向
/// - 计算比例导引加速度
/// - 限制最大加速度
/// - 应用加速度平滑处理
///
protected void CalculateGuidanceAcceleration(double deltaTime)
{
// 获取当前导弹指向方向
Vector3D currentDirection = Velocity.Normalize();
// 使用四象限探测器获取修正后的目标方向
Vector3D targetDirection = quadrantDetector.GetTargetDirection(currentDirection, SpotOffsetSensitivity);
// 计算方向差异向量
Vector3D directionDifference = targetDirection - currentDirection;
// 确保差异向量与当前速度垂直(只保留横向分量)
Vector3D guidanceDirection = directionDifference - currentDirection * Vector3D.DotProduct(directionDifference, currentDirection);
// 如果差异太小,可以适当放大
if (guidanceDirection.Magnitude() < 0.01)
{
guidanceDirection = guidanceDirection.Normalize() * 0.01;
}
// 计算新的制导加速度,与速度垂直
Vector3D newGuidanceAcceleration = guidanceDirection * ProportionalNavigationCoefficient * Velocity.Magnitude();
// 限制最大加速度
double maxAcceleration = MaxAcceleration;
if (newGuidanceAcceleration.Magnitude() > maxAcceleration)
{
newGuidanceAcceleration = newGuidanceAcceleration.Normalize() * maxAcceleration;
}
// 应用加速度平滑处理
GuidanceAcceleration = PreviousGuidanceAcceleration * (1 - AccelerationSmoothingFactor) +
newGuidanceAcceleration * AccelerationSmoothingFactor;
// 保存当前加速度用于下次平滑计算
PreviousGuidanceAcceleration = GuidanceAcceleration;
}
///
/// 获取制导系统的详细状态信息
///
/// 包含完整状态参数的字符串
///
/// 返回信息:
/// - 基本状态信息
/// - 接收功率数据
/// - 锁定阈值
/// - 四象限探测器状态
/// 用于系统监控和调试
///
public override string GetStatus()
{
return base.GetStatus() +
$" 接收到的激光功率: {ReceivedLaserPower:E} W," +
$" 锁定阈值: {config.LockThreshold:E} W," +
$" 四象限探测器: {quadrantDetector.GetStatus()}";
}
///
/// 获取四象限探测器的水平误差
///
/// 水平误差值,范围[-1, 1]
///
/// 正值表示右侧偏移,负值表示左侧偏移
///
public double GetHorizontalError()
{
return quadrantDetector.HorizontalError;
}
///
/// 获取四象限探测器的垂直误差
///
/// 垂直误差值,范围[-1, 1]
///
/// 正值表示上方偏移,负值表示下方偏移
///
public double GetVerticalError()
{
return quadrantDetector.VerticalError;
}
///
/// 设置光斑偏移灵敏度
///
/// 灵敏度值
///
/// 灵敏度值越高,制导系统对光斑偏移的响应越强烈
/// 典型值范围:0.1-1.0
///
public void SetSpotOffsetSensitivity(double sensitivity)
{
SpotOffsetSensitivity = sensitivity;
}
///
/// 获取四象限探测器的锁定状态
///
/// 如果四象限探测器锁定目标则返回true,否则返回false
///
/// 用于外部系统监控四象限探测器的工作状态
///
public bool IsQuadrantDetectorLocked()
{
return quadrantDetector.IsTargetLocked;
}
///
/// 设置期望的激光编码
///
/// 编码类型
/// 编码值
///
/// 设置过程:
/// - 检查编码类型是否支持
/// - 创建新的编码对象
/// - 设置编码类型和值
///
public void SetExpectedLaserCode(LaserCodeType codeType, int codeValue)
{
if (supportedCodeTypes.Contains(codeType))
{
InternalLaserCodeConfig = new LaserCodeConfig
{
Code = new LaserCode { CodeType = codeType, CodeValue = codeValue }
};
Debug.WriteLine($"激光半主动制导系统设置期望编码:类型={codeType},值={codeValue}");
}
else
{
Debug.WriteLine($"激光半主动制导系统不支持编码类型:{codeType}");
}
}
///
/// 添加期望编码参数
///
/// 参数名称
/// 参数值
///
/// 添加特定编码类型的额外参数
/// 如PPM编码的脉冲位置模式、PWM编码的脉冲宽度等
///
public void AddExpectedCodeParameter(string key, object value)
{
if (InternalLaserCodeConfig != null)
{
InternalLaserCodeConfig.Code.Parameters[key] = value;
Debug.WriteLine($"激光半主动制导系统添加期望编码参数:{key}={value}");
}
}
///
/// 处理激光照射更新事件
///
/// 激光照射更新事件
///
/// 处理过程:
/// - 检查编码是否匹配
/// - 如果要求匹配且不匹配,则忽略信号
/// - 如果匹配或不要求匹配,则处理信号
/// - 更新激光照射状态
///
public void ProcessLaserIlluminationUpdateEvent(LaserIlluminationUpdateEvent illuminationEvent)
{
if (illuminationEvent.LaserCodeConfig != null)
{
// 只有在编码启用的情况下才进行编码匹配检查
if (illuminationEvent.LaserCodeConfig.IsCodeEnabled)
{
bool codeMatched = InternalLaserCodeConfig?.CheckCodeMatch(illuminationEvent.LaserCodeConfig) ?? false;
if (!codeMatched)
{
// 发布编码不匹配事件
PublishCodeMismatchEvent(illuminationEvent.LaserDesignatorId, illuminationEvent.LaserCodeConfig);
Trace.WriteLine("激光半主动制导系统接收到不匹配的激光编码,忽略信号");
HasGuidance = false; // 禁用制导
LaserIlluminationOn = false; // 禁用激光照射状态,确保四象限探测器不处理信号
// 重置四象限探测器状态
quadrantDetector.ProcessLaserSignal(0, new Vector2D(0, 0));
PreviousGuidanceAcceleration = Vector3D.Zero; // 重置历史加速度
return;
}
}
// 更新激光照射状态
LaserIlluminationOn = true;
}
}
///
/// 处理激光照射停止事件
///
/// 激光照射停止事件
///
/// 处理过程:
/// - 停止激光照射状态
/// - 清理相关参数
///
public void ProcessLaserIlluminationStopEvent(LaserIlluminationStopEvent illuminationEvent)
{
LaserIlluminationOn = false;
HasGuidance = false; // 禁用制导
}
///
/// 发布编码不匹配事件
///
/// 激光定位器ID
/// 接收到的编码配置
///
/// 发布过程:
/// - 创建事件对象
/// - 设置事件属性
/// - 发布到事件系统
///
private void PublishCodeMismatchEvent(string? designatorId, LaserCodeConfig? receivedCodeConfig)
{
var mismatchEvent = new LaserCodeMismatchEvent
{
MissileId = ParentId,
DesignatorId = designatorId,
ExpectedCodeConfig = InternalLaserCodeConfig,
ReceivedCodeConfig = receivedCodeConfig
};
PublishEvent(mismatchEvent);
}
///
/// 计算烟幕对激光的衰减因子
///
/// 烟幕干扰参数
/// 衰减因子,范围:0-1,0表示完全衰减,1表示无衰减
private double CalculateSmokeAttenuation(JammingParameters parameters)
{
if (!parameters.SmokeConcentration.HasValue)
return 1.0; // 无衰减
// 获取烟幕浓度
double concentration = parameters.SmokeConcentration.Value;
// 计算烟幕厚度(设备到烟幕边缘的距离)
double effectiveThickness = 0;
if (parameters.SmokeType == SmokeScreenType.Cloud)
{
// 对于云状烟幕,使用设备到烟幕中心的距离
double distanceToCenter = (Position - parameters.SourcePosition).Magnitude();
double radius = parameters.SmokeThickness.HasValue ? parameters.SmokeThickness.Value / 2 : 10.0;
effectiveThickness = Math.Max(0, radius - distanceToCenter);
if (distanceToCenter < radius) // 如果在烟幕内部
effectiveThickness = 2 * (radius - distanceToCenter); // 双倍路径
}
else // SmokeScreenType.Wall
{
// 对于墙状烟幕,使用烟幕厚度
effectiveThickness = parameters.SmokeThickness.HasValue ? parameters.SmokeThickness.Value : 5.0;
// 可以进一步计算有效厚度,但这里简化处理
}
// 使用 AtmosphereDllWrapper 计算烟幕透过率
double transmittance = AtmosphereDllWrapper.CalculateSmokeScreenTransmittance(
config.LaserWavelength, // 激光波长(微米)
concentration, // 烟幕浓度(g/m³)
effectiveThickness // 烟幕厚度(米)
);
Debug.WriteLine($"烟幕衰减计算 - 波长: {config.LaserWavelength:F2}um, 浓度: {concentration}g/m³, 厚度: {effectiveThickness}m, 透过率: {transmittance:P2}");
return transmittance;
}
}
}