新增多模制导导弹,支持毫米波/红外双模制导,提供了多模制导框架(需要增加相关配置文件并验证)
This commit is contained in:
parent
5a0f9f1ece
commit
082bf6ea51
@ -12,8 +12,13 @@
|
||||
- 支持与 Simulink 模型的数据交互
|
||||
- 实现实时仿真数据同步
|
||||
- 处理不同时间步长的协调
|
||||
- 毫米波跟踪和锁定阶段采用脉冲多普勒制导、目标 RCS 特征矩阵
|
||||
- 双模、多模制导
|
||||
- 毫米波跟踪和锁定阶段采用脉冲多普勒制导
|
||||
- 命中概率和系统随机噪声
|
||||
|
||||
## [1.1.19] - 2025-05-18
|
||||
- 增加了装备的RCS特征矩阵
|
||||
- 在毫米波末制导中,用RCS特征矩阵取值
|
||||
- 新增多模制导导弹,实现了毫米波/红外双模制导,也支持多模制导(需要增加相关配置文件并验证)
|
||||
|
||||
## [1.1.18] - 2025-05-14
|
||||
- 修改了版本号格式(0.2.18 -> 1.1.18)
|
||||
|
||||
97
ThreatSource/data/missiles/composite/cg_001.toml
Normal file
97
ThreatSource/data/missiles/composite/cg_001.toml
Normal file
@ -0,0 +1,97 @@
|
||||
# 毫米波-红外成像末制导导弹-001 配置
|
||||
Type = "CompositeGuidance"
|
||||
|
||||
[Name]
|
||||
Zh = "毫米波-红外成像末制导导弹-001"
|
||||
En = "Millimeter Wave-IR Imaging Terminal Guided Missile-001"
|
||||
|
||||
[Properties]
|
||||
Type = "CompositeGuidance"
|
||||
MaxSpeed = 250.0
|
||||
MaxFlightTime = 60.0
|
||||
MaxFlightDistance = 5000.0
|
||||
MaxAcceleration = 100.0
|
||||
ProportionalNavigationCoefficient = 3.0
|
||||
LaunchAcceleration = 100.0
|
||||
MaxEngineBurnTime = 2.5
|
||||
CruiseTime = 5.0 # 假设这是第一阶段(MMW)的巡航时间或总巡航时间的一部分
|
||||
Mass = 25.0
|
||||
ExplosionRadius = 5.5
|
||||
HitProbability = 0.9
|
||||
SelfDestructHeight = 0.0
|
||||
# --- 复合制导特定属性 ---
|
||||
CompositeWorkMode = "Serial" # 工作模式:Serial (串行) 或 Parallel (并行)
|
||||
# FusionStrategy = "UseHighestPriority" # 仅在并行模式下相关
|
||||
|
||||
# --- 制导组件套件 (GuidanceSuite) ---
|
||||
# 第一个制导阶段:毫米波
|
||||
[[Properties.GuidanceSuite]]
|
||||
ComponentName = "MMW_Phase1_Cruise"
|
||||
GuidanceSystemType = "MillimeterWaveTerminalGuidance" # 必须与C#工厂中的类型字符串匹配
|
||||
ActivationTrigger = "OnLaunch" # 激活触发器:OnLaunch, AfterFlightTime, DistanceToTargetThreshold, PreviousStageComplete
|
||||
ActivationValue = 0.0 # 触发器关联值 (例如:飞行时间秒数,距离米数)
|
||||
Priority = 0 # 优先级 (例如:0为最高)
|
||||
MaxTimeToAcquireGuidanceSeconds = 5.0 # 新增:获取制导的最大时间
|
||||
MinTimeWithGuidanceBeforeSwitchSeconds = 0.2 # 新增:稳定跟踪0.2秒后切换(因为毫米波跟踪不稳定)
|
||||
ContinueChainOnFailure = true # 新增:失败后继续尝试下一个
|
||||
|
||||
# 第二个制导阶段:红外成像末制导
|
||||
[[Properties.GuidanceSuite]]
|
||||
ComponentName = "IR_Phase2_Terminal"
|
||||
GuidanceSystemType = "InfraredImagingTerminalGuidance" # 必须与C#工厂中的类型字符串匹配
|
||||
ActivationTrigger = "PreviousStageComplete" # 例如:在飞行一段时间后切换 (或者 PreviousStageComplete)
|
||||
ActivationValue = 10.0 # 例如:飞行10秒后激活红外阶段 (如果 CruiseTime 是 5s,这里可能需要调整)
|
||||
Priority = 1 # 优先级低于毫米波
|
||||
MaxTimeToAcquireGuidanceSeconds = 5.0 # 新增:获取制导的最大时间
|
||||
MinTimeWithGuidanceBeforeSwitchSeconds = 60.0 # 新增:设置为MaxFlightTime,使其持续制导
|
||||
ContinueChainOnFailure = false # 新增:这是最后一个,失败也无需继续
|
||||
|
||||
# --- 各制导模式的详细配置 ---
|
||||
[InfraredImagingGuidanceConfig]
|
||||
MaxDetectionRange = 1000.0 # 最大探测距离 (米), JSON中为1000,对应C#默认为1000.0
|
||||
SearchFieldOfView = 0.209 # 搜索视场角 (弧度), JSON中为0.209, C#默认为 PI/15 ≈ 0.2094
|
||||
TrackFieldOfView = 0.052 # 跟踪视场角 (弧度), JSON中为0.052, C#默认为 PI/60 ≈ 0.0523
|
||||
ImageWidth = 640 # 图像宽度 (像素)
|
||||
ImageHeight = 512 # 图像高度 (像素)
|
||||
BackgroundIntensity = 1.0e-4 # 背景辐射强度 (瓦特/球面度), JSON中为1e-4, C#默认为0.01
|
||||
SearchRecognitionProbability = 0.6 # 搜索模式目标识别概率阈值
|
||||
TrackRecognitionProbability = 0.8 # 跟踪模式目标识别概率阈值
|
||||
TargetLostTolerance = 0.2 # 目标丢失容忍时间 (秒)
|
||||
LockConfirmationTime = 0.3 # 锁定确认时间 (秒)
|
||||
JammingResistanceThreshold = 1.0e-5 # 干扰抗性阈值 (瓦特)
|
||||
Wavelength = 3.0 # 波长 (微米), C#中属性名为Wavelength, JSON中为waveLength
|
||||
|
||||
[MillimeterWaveGuidanceConfig]
|
||||
MaxDetectionRange = 5000.0 # 最大探测距离 (米)
|
||||
FieldOfViewAngle = 45.0 # 视场角 (度)
|
||||
TargetRecognitionProbability = 0.95 # 目标识别概率
|
||||
WaveFrequency = 9.4e10 # 波频率 (赫兹, JSON中为94e9)
|
||||
PulseDuration = 1.0e-6 # 脉冲持续时间 (秒)
|
||||
|
||||
SearchBeamWidth = 5.0 # 搜索波束宽度 (度)
|
||||
TrackBeamWidth = 2.5 # 跟踪波束宽度 (度)
|
||||
LockBeamWidth = 1.0 # 锁定波束宽度 (度)
|
||||
|
||||
ScanAngularSpeedDeg = 360.0 # 扫描角速度 (度/秒)
|
||||
ScanRadiusGrowthRateDeg = 22.5 # 扫描半径增长率 (度)
|
||||
|
||||
RecognitionSNRThreshold = -25.0 # 识别信噪比阈值 (分贝)
|
||||
LockSNRThreshold = -10.0 # 锁定信噪比阈值 (分贝)
|
||||
|
||||
TargetLostTolerance = 0.2 # 目标丢失容忍时间 (秒)
|
||||
LockConfirmationTime = 0.3 # 锁定确认时间 (秒)
|
||||
|
||||
PulseRepetitionFrequency = 1.0e-4 # 脉冲重复频率 (秒, JSON中为1e-4,通常PRT单位是秒,PRF是Hz。这里JSON的注释可能不准确,按数值和C#模型属性名推断,这里应为PulseRepetitionTime,即脉冲重复间隔)
|
||||
TransmitPower = 0.3 # 发射功率 (瓦特)
|
||||
|
||||
DopplerVelocityResolution = 1.0 # 多普勒速度分辨率 (米/秒)
|
||||
MaxMeasurableVelocity = 1000.0 # 最大可测量速度 (米/秒)
|
||||
|
||||
AntennaGainDB = 23.0 # 天线增益 (分贝)
|
||||
NoiseFigureDB = 7.0 # 噪声系数 (分贝)
|
||||
SystemLossDB = 6.0 # 系统损耗 (分贝)
|
||||
MonopulseSensitivity = 1.0 # 单脉冲灵敏度 (单位取决于具体实现,JSON中为1)
|
||||
|
||||
YawControlEffectiveness = 120.0 # 偏航控制有效性 (度/秒^2 或类似单位)
|
||||
PitchControlEffectiveness = 150.0 # 俯仰控制有效性 (度/秒^2 或类似单位)
|
||||
JammingResistanceThreshold = 1.0e-5 # 干扰抗性阈值 (瓦特)
|
||||
@ -50,7 +50,7 @@ namespace ThreatSource.Data
|
||||
{
|
||||
LoadMissiles(Path.Combine(path, "missiles"));
|
||||
LoadIndicators(Path.Combine(path, "indicators"));
|
||||
LoadSensors(Path.Combine(path, "sensors"));
|
||||
LoadWarners(Path.Combine(path, "warners"));
|
||||
LoadTargets(Path.Combine(path, "equipments"));
|
||||
LoadWeathers(Path.Combine(path, "weathers"));
|
||||
LoadJammers(Path.Combine(path, "jammers"));
|
||||
@ -75,12 +75,81 @@ namespace ThreatSource.Data
|
||||
var data = Toml.ToModel<MissileData>(tomlContent, options: _tomlOptions); // Pass options
|
||||
if (data != null)
|
||||
{
|
||||
if (data.Properties?.GuidanceSuite != null && data.Properties.GuidanceSuite.Count > 0)
|
||||
{
|
||||
Debug.WriteLine($"[ThreatSourceDataManager] Post-processing GuidanceSuite for missile file: {Path.GetFileName(file)} with {data.Properties.GuidanceSuite.Count} component(s).");
|
||||
foreach (var componentConfig in data.Properties.GuidanceSuite)
|
||||
{
|
||||
if (componentConfig == null)
|
||||
{
|
||||
Debug.WriteLine($"[ThreatSourceDataManager] Warning: Encountered a null componentConfig in GuidanceSuite for {Path.GetFileName(file)}.");
|
||||
continue;
|
||||
}
|
||||
|
||||
string? typeKey = componentConfig.GuidanceSystemType?.ToLowerInvariant();
|
||||
object? assignedConfig = null; // Will hold the config object from MissileData
|
||||
string? topLevelConfigName = "UnknownPropertyInMissileData"; // For logging
|
||||
|
||||
switch (typeKey)
|
||||
{
|
||||
case "millimeterwave": // Alias
|
||||
case "millimeterwaveterminalguidance":
|
||||
assignedConfig = data.MillimeterWaveGuidanceConfig;
|
||||
componentConfig.SpecificConfig = data.MillimeterWaveGuidanceConfig;
|
||||
topLevelConfigName = nameof(data.MillimeterWaveGuidanceConfig);
|
||||
break;
|
||||
case "infraredimagingterminalguidance":
|
||||
assignedConfig = data.InfraredImagingGuidanceConfig;
|
||||
componentConfig.SpecificConfig = data.InfraredImagingGuidanceConfig;
|
||||
topLevelConfigName = nameof(data.InfraredImagingGuidanceConfig);
|
||||
break;
|
||||
case "lasers semiactiveguidance":
|
||||
assignedConfig = data.LaserSemiActiveGuidanceConfig;
|
||||
componentConfig.SpecificConfig = data.LaserSemiActiveGuidanceConfig;
|
||||
topLevelConfigName = nameof(data.LaserSemiActiveGuidanceConfig);
|
||||
break;
|
||||
case "laserbeamriderguidance":
|
||||
assignedConfig = data.LaserBeamRiderGuidanceConfig;
|
||||
componentConfig.SpecificConfig = data.LaserBeamRiderGuidanceConfig;
|
||||
topLevelConfigName = nameof(data.LaserBeamRiderGuidanceConfig);
|
||||
break;
|
||||
case "infraredcommandguidance":
|
||||
assignedConfig = data.InfraredCommandGuidanceConfig;
|
||||
componentConfig.SpecificConfig = data.InfraredCommandGuidanceConfig;
|
||||
topLevelConfigName = nameof(data.InfraredCommandGuidanceConfig);
|
||||
break;
|
||||
default:
|
||||
Debug.WriteLine($"[ThreatSourceDataManager] Info: Component '{componentConfig.ComponentName}' (GuidanceSystemType: '{componentConfig.GuidanceSystemType}') has no explicit top-level config association logic in the current switch statement.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (componentConfig.SpecificConfig != null) // Check if SpecificConfig was successfully assigned
|
||||
{
|
||||
Debug.WriteLine($"[ThreatSourceDataManager] Successfully associated SpecificConfig for component '{componentConfig.ComponentName}' (Type: {componentConfig.GuidanceSystemType}) with data.{topLevelConfigName} (Actual Type: {componentConfig.SpecificConfig.GetType().FullName}).");
|
||||
}
|
||||
else // SpecificConfig is still null
|
||||
{
|
||||
if (assignedConfig == null &&
|
||||
(typeKey == "millimeterwaveterminalguidance" || typeKey == "millimeterwave" ||
|
||||
typeKey == "infraredimagingterminalguidance" || typeKey == "lasers semiactiveguidance" ||
|
||||
typeKey == "laserbeamriderguidance" || typeKey == "infraredcommandguidance"))
|
||||
{
|
||||
Debug.WriteLine($"[ThreatSourceDataManager] Error: SpecificConfig for component '{componentConfig.ComponentName}' (Type: {componentConfig.GuidanceSystemType}) remains NULL. The corresponding top-level config 'data.{topLevelConfigName}' was likely missing or null in the TOML file '{Path.GetFileName(file)}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"[ThreatSourceDataManager] Info: SpecificConfig for component '{componentConfig.ComponentName}' (Type: {componentConfig.GuidanceSystemType}) is still null after processing. This implies no matching top-level config was found/assigned or the type is unhandled by the switch for top-level association.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data.Properties?.GuidanceSuite != null && data.Properties.GuidanceSuite.Count == 0 && data.Type == ThreatSource.Missile.MissileType.CompositeGuidance)
|
||||
{
|
||||
Debug.WriteLine($"[ThreatSourceDataManager] Warning: Missile file {Path.GetFileName(file)} is of type CompositeGuidance but its GuidanceSuite is empty or null.");
|
||||
}
|
||||
|
||||
string model = Path.GetFileNameWithoutExtension(file);
|
||||
_missiles[model] = data;
|
||||
if (data.MillimeterWaveGuidanceConfig != null)
|
||||
{
|
||||
var config = data.MillimeterWaveGuidanceConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -123,13 +192,13 @@ namespace ThreatSource.Data
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载传感器数据
|
||||
/// 加载告警器数据
|
||||
/// </summary>
|
||||
private void LoadSensors(string path)
|
||||
private void LoadWarners(string path)
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Trace.TraceError($"传感器数据目录不存在:{path}");
|
||||
Trace.TraceError($"告警器数据目录不存在:{path}");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -147,7 +216,7 @@ namespace ThreatSource.Data
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Trace.TraceError($"加载传感器数据文件失败:{file},错误:{ex.Message}");
|
||||
Trace.TraceError($"加载告警器数据文件失败:{file},错误:{ex.Message}");
|
||||
Trace.TraceError($"异常堆栈:{ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,6 +118,15 @@ namespace ThreatSource.Data
|
||||
_simulationManager
|
||||
);
|
||||
|
||||
case MissileType.CompositeGuidance:
|
||||
return new CompositeGuidedMissile(
|
||||
missileId,
|
||||
data.Properties,
|
||||
launchParams,
|
||||
_simulationManager,
|
||||
EquipmentType.Tank
|
||||
);
|
||||
|
||||
default:
|
||||
throw new ArgumentException($"Unsupported missile type: {data.Type}");
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ namespace ThreatSource.Guidance
|
||||
/// 记录目标的历史位置
|
||||
/// 用于计算目标速度
|
||||
/// </remarks>
|
||||
private Vector3D? lastTargetPosition { get; set; } // Changed to nullable Vector3D?
|
||||
private Vector3D? LastTargetPosition { get; set; } // Changed to nullable Vector3D?
|
||||
|
||||
/// <summary>
|
||||
/// 红外图像生成器
|
||||
@ -199,7 +199,7 @@ namespace ThreatSource.Guidance
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
lastTargetPosition = null; // Add reset to null
|
||||
LastTargetPosition = null; // Add reset to null
|
||||
HasTarget = false;
|
||||
HasGuidance = false;
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
@ -225,12 +225,12 @@ namespace ThreatSource.Guidance
|
||||
{
|
||||
targetLostTimer = 0; // 重置丢失计时器
|
||||
Vector3D? currentTargetVelocity = null; // Initialize as nullable
|
||||
if(lastTargetPosition != null && deltaTime > 0)
|
||||
if(LastTargetPosition != null && deltaTime > 0)
|
||||
{
|
||||
currentTargetVelocity = (currentTargetPosition - lastTargetPosition) / deltaTime;
|
||||
currentTargetVelocity = (currentTargetPosition - LastTargetPosition) / deltaTime;
|
||||
}
|
||||
|
||||
lastTargetPosition = currentTargetPosition;
|
||||
LastTargetPosition = currentTargetPosition;
|
||||
|
||||
GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation(
|
||||
ProportionalNavigationCoefficient,
|
||||
@ -289,7 +289,7 @@ namespace ThreatSource.Guidance
|
||||
currentMode = WorkMode.Search;
|
||||
HasTarget = false;
|
||||
targetLostTimer = 0; // 重置丢失计时器
|
||||
lastTargetPosition = null; // Add reset to null
|
||||
LastTargetPosition = null; // Add reset to null
|
||||
|
||||
// 创建图像生成器
|
||||
imageGenerator = new InfraredImageGenerator(
|
||||
@ -577,7 +577,7 @@ namespace ThreatSource.Guidance
|
||||
public override ElementStatusInfo GetStatusInfo()
|
||||
{
|
||||
var statusInfo = base.GetStatusInfo();
|
||||
string lastPosStr = lastTargetPosition.HasValue ? lastTargetPosition.Value.ToString() : "null";
|
||||
string lastPosStr = LastTargetPosition.HasValue ? LastTargetPosition.Value.ToString() : "null";
|
||||
statusInfo.ExtendedProperties["lastPosStr"] = lastPosStr;
|
||||
return statusInfo;
|
||||
}
|
||||
|
||||
@ -16,7 +16,6 @@ namespace ThreatSource.Guidance
|
||||
/// - 信噪比计算
|
||||
/// - 抗干扰处理
|
||||
/// - 比例导引控制
|
||||
/// 用于实现全天候制导打击
|
||||
/// </remarks>
|
||||
public class MillimeterWaveGuidanceSystem : BaseGuidanceSystem
|
||||
{
|
||||
@ -427,15 +426,15 @@ namespace ThreatSource.Guidance
|
||||
Debug.WriteLine($"目标夹角: {angle * 180/Math.PI:F2}度");
|
||||
Debug.WriteLine($"波束宽度: {currentBeamWidth * 180/Math.PI:F2}度,SNR阈值: {config.RecognitionSNRThreshold}dB");
|
||||
|
||||
return angle <= currentBeamWidth;
|
||||
return angle <= (currentBeamWidth / 2.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 跟踪/锁定模式使用单脉冲测角
|
||||
var (azError, elError) = ProcessMonopulse(toTarget.Normalize(), missileVelocity);
|
||||
Debug.WriteLine($"[单脉冲测角] 方位误差: {azError * 180/Math.PI:F3}度, 俯仰误差: {elError * 180/Math.PI:F3}度");
|
||||
Debug.WriteLine($"[波束宽度检查] 当前阈值: {currentBeamWidth * 180/Math.PI:F3}度,实际误差: {Math.Sqrt(azError*azError + elError*elError) * 180/Math.PI:F3}度");
|
||||
return Math.Sqrt(azError*azError + elError*elError) < currentBeamWidth;
|
||||
Debug.WriteLine($"[波束宽度检查] 当前波束宽度的一半: {(currentBeamWidth / 2.0) * 180/Math.PI:F3}度,实际误差合成: {Math.Sqrt(azError*azError + elError*elError) * 180/Math.PI:F3}度");
|
||||
return Math.Sqrt(azError*azError + elError*elError) <= (currentBeamWidth / 2.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
504
ThreatSource/src/MIssile/CompositeGuidedMissile.cs
Normal file
504
ThreatSource/src/MIssile/CompositeGuidedMissile.cs
Normal file
@ -0,0 +1,504 @@
|
||||
using System.Diagnostics;
|
||||
using ThreatSource.Simulation;
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Guidance;
|
||||
using ThreatSource.Equipment;
|
||||
using ThreatSource.Jammable;
|
||||
|
||||
namespace ThreatSource.Missile
|
||||
{
|
||||
internal enum CompositeFlightStage
|
||||
{
|
||||
Launch, // 发射阶段
|
||||
Cruise, // 巡航阶段
|
||||
Terminal // 末制导阶段
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复合制导导弹类,继承自 BaseMissile
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 该类实现了复合制导导弹的制导系统管理、状态更新和自毁逻辑
|
||||
/// </remarks>
|
||||
public class CompositeGuidedMissile : BaseMissile
|
||||
{
|
||||
/// <summary>
|
||||
/// 制导系统列表
|
||||
/// </summary>
|
||||
protected List<IGuidanceSystem> guidanceSystems = [];
|
||||
/// <summary>
|
||||
/// 当前活动制导系统
|
||||
/// </summary>
|
||||
protected IGuidanceSystem? currentActiveGuidance;
|
||||
/// <summary>
|
||||
/// 当前活动制导系统索引
|
||||
/// </summary>
|
||||
protected int currentActiveGuidanceIndex = -1;
|
||||
/// <summary>
|
||||
/// 所有制导阶段是否已尝试
|
||||
/// </summary>
|
||||
protected bool allGuidancePhasesAttempted = false;
|
||||
/// <summary>
|
||||
/// 目标类型
|
||||
/// </summary>
|
||||
private readonly EquipmentType targetType;
|
||||
/// <summary>
|
||||
/// 当前飞行阶段
|
||||
/// </summary>
|
||||
private CompositeFlightStage currentFlightStage;
|
||||
|
||||
/// <summary>
|
||||
/// 经过优先级排序的制导组件配置列表。
|
||||
/// </summary>
|
||||
private List<GuidanceComponentConfig> sortedGuidanceConfigs = new List<GuidanceComponentConfig>();
|
||||
|
||||
/// <summary>
|
||||
/// 经过优先级排序的制导系统实例列表,与 sortedGuidanceConfigs 一一对应。
|
||||
/// </summary>
|
||||
private List<IGuidanceSystem> sortedGuidanceSystems = new List<IGuidanceSystem>();
|
||||
|
||||
/// <summary>
|
||||
/// 当前活动的制导组件配置。
|
||||
/// </summary>
|
||||
private GuidanceComponentConfig? currentActiveConfig;
|
||||
|
||||
/// <summary>
|
||||
/// sortedGuidanceSystems 列表中当前活动或下一个待激活系统的索引。
|
||||
/// 初始化为 -1 表示制导链尚未开始。
|
||||
/// </summary>
|
||||
private int currentGuidancePhaseIndex = -1;
|
||||
|
||||
/// <summary>
|
||||
/// 标记整个制导链是否已中止或所有阶段已成功完成。
|
||||
/// </summary>
|
||||
private bool guidanceChainHaltedOrCompleted = false;
|
||||
|
||||
/// <summary>
|
||||
/// 当前活动制导阶段开始激活的仿真时间(秒)。
|
||||
/// </summary>
|
||||
private double currentPhaseActivationTime = -1.0;
|
||||
|
||||
/// <summary>
|
||||
/// 当前活动制导阶段首次获得稳定制导的仿真时间(秒)。
|
||||
/// 用于 MinTimeWithGuidanceBeforeSwitchSeconds 判断。
|
||||
/// </summary>
|
||||
private double currentPhaseStableGuidanceTime = -1.0;
|
||||
|
||||
/// <summary>
|
||||
/// 复合制导导弹构造函数
|
||||
/// </summary>
|
||||
public CompositeGuidedMissile(string missileId, MissileProperties properties, KinematicState kinematicState, ISimulationManager manager, EquipmentType primaryTargetType)
|
||||
: base(missileId, properties, kinematicState, manager)
|
||||
{
|
||||
targetType = primaryTargetType;
|
||||
InitializeGuidanceSuite();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化制导系统套件,并按优先级排序。
|
||||
/// </summary>
|
||||
protected void InitializeGuidanceSuite()
|
||||
{
|
||||
this.sortedGuidanceSystems.Clear();
|
||||
this.sortedGuidanceConfigs.Clear();
|
||||
this.guidanceChainHaltedOrCompleted = false;
|
||||
this.currentGuidancePhaseIndex = -1; // 重置索引,表示从头开始
|
||||
this.currentActiveGuidance = null;
|
||||
this.currentActiveConfig = null;
|
||||
|
||||
if (Properties.GuidanceSuite != null && Properties.GuidanceSuite.Count > 0)
|
||||
{
|
||||
var tempGuidanceList = new List<Tuple<GuidanceComponentConfig, IGuidanceSystem>>();
|
||||
|
||||
foreach (var componentConfig in Properties.GuidanceSuite)
|
||||
{
|
||||
IGuidanceSystem? newGuidanceSystem = CreateGuidanceSystemFromConfig(componentConfig);
|
||||
if (newGuidanceSystem != null)
|
||||
{
|
||||
tempGuidanceList.Add(new Tuple<GuidanceComponentConfig, IGuidanceSystem>(componentConfig, newGuidanceSystem));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"[CompositeGuidance.Initialize] 创建制导系统 '{componentConfig.ComponentName}' (类型: {componentConfig.GuidanceSystemType}) 失败。");
|
||||
}
|
||||
}
|
||||
|
||||
// 按优先级排序 (数值越小,优先级越高)
|
||||
tempGuidanceList.Sort((item1, item2) => item1.Item1.Priority.CompareTo(item2.Item1.Priority));
|
||||
|
||||
foreach (var tuple in tempGuidanceList)
|
||||
{
|
||||
this.sortedGuidanceConfigs.Add(tuple.Item1);
|
||||
this.sortedGuidanceSystems.Add(tuple.Item2);
|
||||
}
|
||||
|
||||
if (this.sortedGuidanceSystems.Count > 0)
|
||||
{
|
||||
this.currentGuidancePhaseIndex = -1; // 设置为-1,以便TryActivateNextGuidanceSystem能正确激活第一个
|
||||
}
|
||||
else
|
||||
{
|
||||
this.guidanceChainHaltedOrCompleted = true; // 没有可用的制导系统
|
||||
Debug.WriteLine("[CompositeGuidance.Initialize] 未配置或未能创建任何有效的制导系统。");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.guidanceChainHaltedOrCompleted = true;
|
||||
Debug.WriteLine("[CompositeGuidance.Initialize] GuidanceSuite 为空。");
|
||||
}
|
||||
Debug.WriteLine($"[CompositeGuidance.Initialize] 初始化完成。排序后的制导系统数量: {sortedGuidanceSystems.Count}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从配置创建制导系统
|
||||
/// </summary>
|
||||
private IGuidanceSystem? CreateGuidanceSystemFromConfig(GuidanceComponentConfig config)
|
||||
{
|
||||
switch (config.GuidanceSystemType?.ToLowerInvariant())
|
||||
{
|
||||
case "millimeterwaveterminalguidance":
|
||||
if (config.SpecificConfig is MillimeterWaveGuidanceConfig mmwConfig)
|
||||
{
|
||||
return new MillimeterWaveGuidanceSystem(config.ComponentName, Id, Properties.MaxAcceleration, Properties.ProportionalNavigationCoefficient, mmwConfig, SimulationManager);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
case "infraredimagingterminalguidance":
|
||||
if (config.SpecificConfig is InfraredImagingGuidanceConfig irConfig)
|
||||
{
|
||||
return new InfraredImagingGuidanceSystem(config.ComponentName, Id, irConfig, targetType, Properties.MaxAcceleration, Properties.ProportionalNavigationCoefficient, SimulationManager);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新复合制导逻辑,负责制导系统的激活、切换和状态管理。
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长。</param>
|
||||
protected virtual void UpdateGuidanceLogic(double deltaTime)
|
||||
{
|
||||
if (guidanceChainHaltedOrCompleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentActiveGuidance == null)
|
||||
{
|
||||
TryActivateNextGuidanceSystem();
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentActiveGuidance is SimulationElement se)
|
||||
{
|
||||
se.Update(deltaTime); // Assuming Update is part of SimulationElement or BaseGuidanceSystem which inherits it
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback or error if it's not a SimulationElement but Update is needed.
|
||||
// For now, we assume all IGuidanceSystem are also SimulationElement for Update.
|
||||
}
|
||||
|
||||
if (currentActiveConfig == null)
|
||||
{
|
||||
Debug.WriteLine("[CompositeGuidance.Logic] 错误:currentActiveGuidance 不为null,但 currentActiveConfig 为null。");
|
||||
HandleCurrentPhaseFailure(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 成功切换条件: 获得稳定制导
|
||||
if (currentActiveGuidance.HasGuidance)
|
||||
{
|
||||
if (currentPhaseStableGuidanceTime < 0) // 本帧首次获得制导
|
||||
{
|
||||
currentPhaseStableGuidanceTime = FlightTime;
|
||||
Debug.WriteLine($"[CompositeGuidance.Logic] 模块 {currentActiveConfig.ComponentName} 在 {FlightTime:F2}s 首次获得制导。");
|
||||
}
|
||||
|
||||
// 检查是否达到稳定制导时间
|
||||
if (currentActiveConfig.MinTimeWithGuidanceBeforeSwitchSeconds <= 0 ||
|
||||
(FlightTime - currentPhaseStableGuidanceTime) >= currentActiveConfig.MinTimeWithGuidanceBeforeSwitchSeconds)
|
||||
{
|
||||
// 满足稳定时间要求
|
||||
if (currentGuidancePhaseIndex < sortedGuidanceSystems.Count - 1)
|
||||
{
|
||||
// 如果不是最后一个制导阶段,则尝试切换到下一个
|
||||
Debug.WriteLine($"[CompositeGuidance.Logic] 模块 {currentActiveConfig.ComponentName} 完成任务 (稳定制导持续达标),切换到下一阶段。");
|
||||
TryActivateNextGuidanceSystem(deactivatePrevious: true);
|
||||
return; // 切换后立即返回,避免同一帧内处理新激活的模块
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果是最后一个制导阶段,并且已满足稳定条件,则让它继续工作。
|
||||
// 标记制导链"执行完毕",但当前制导继续。
|
||||
if (!guidanceChainHaltedOrCompleted) // 避免重复打印
|
||||
{
|
||||
Debug.WriteLine($"[CompositeGuidance.Logic] 最后一个制导模块 {currentActiveConfig.ComponentName} 已满足稳定条件并将持续工作。");
|
||||
guidanceChainHaltedOrCompleted = true; // 标记配置的切换链已完成
|
||||
}
|
||||
// 不返回,允许后续的超时和干扰检查继续作用于这个最后一个阶段
|
||||
}
|
||||
}
|
||||
}
|
||||
else // 当前帧无制导
|
||||
{
|
||||
currentPhaseStableGuidanceTime = -1.0; // 重置稳定制导开始时间
|
||||
}
|
||||
|
||||
// 2. 失效条件 - 超时 (在未成功切换的前提下检查)
|
||||
if (currentActiveConfig.MaxTimeToAcquireGuidanceSeconds > 0 &&
|
||||
(FlightTime - currentPhaseActivationTime) >= currentActiveConfig.MaxTimeToAcquireGuidanceSeconds)
|
||||
{
|
||||
Debug.WriteLine($"[CompositeGuidance.Logic] 模块 {currentActiveConfig.ComponentName} 超时 ({currentActiveConfig.MaxTimeToAcquireGuidanceSeconds}s) 未能获得并维持稳定制导。");
|
||||
HandleCurrentPhaseFailure();
|
||||
return;
|
||||
}
|
||||
|
||||
bool isJammed = false;
|
||||
if (currentActiveGuidance is IJammable jammableSystem)
|
||||
{
|
||||
isJammed = jammableSystem.IsBlockingJammed;
|
||||
}
|
||||
|
||||
if (isJammed && !currentActiveGuidance.HasGuidance)
|
||||
{
|
||||
Debug.WriteLine($"[CompositeGuidance.Logic] 模块 {currentActiveConfig.ComponentName} 受到阻塞性干扰且无制导。");
|
||||
HandleCurrentPhaseFailure();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试激活制导链中的下一个制导系统。
|
||||
/// </summary>
|
||||
/// <param name="deactivatePrevious">是否应停用当前活动的制导系统(如果存在)。</param>
|
||||
private void TryActivateNextGuidanceSystem(bool deactivatePrevious = false)
|
||||
{
|
||||
if (deactivatePrevious && currentActiveGuidance != null)
|
||||
{
|
||||
Debug.WriteLine($"[CompositeGuidance.ActivateNext] 停用先前模块: {currentActiveConfig?.ComponentName ?? "Unknown"}");
|
||||
if (currentActiveGuidance is BaseGuidanceSystem prevBaseGs)
|
||||
{
|
||||
prevBaseGs.Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
currentGuidancePhaseIndex++;
|
||||
|
||||
if (currentGuidancePhaseIndex >= sortedGuidanceSystems.Count)
|
||||
{
|
||||
Debug.WriteLine("[CompositeGuidance.ActivateNext] 所有制导阶段已尝试完毕。");
|
||||
guidanceChainHaltedOrCompleted = true;
|
||||
currentActiveGuidance = null;
|
||||
currentActiveConfig = null;
|
||||
return;
|
||||
}
|
||||
|
||||
currentActiveGuidance = sortedGuidanceSystems[currentGuidancePhaseIndex];
|
||||
currentActiveConfig = sortedGuidanceConfigs[currentGuidancePhaseIndex];
|
||||
|
||||
Debug.WriteLine($"[CompositeGuidance.ActivateNext] 尝试激活模块: {currentActiveConfig.ComponentName} (类型: {currentActiveConfig.GuidanceSystemType})");
|
||||
if (currentActiveGuidance is BaseGuidanceSystem currentBaseGs)
|
||||
{
|
||||
currentBaseGs.Activate();
|
||||
}
|
||||
|
||||
currentPhaseActivationTime = FlightTime;
|
||||
currentPhaseStableGuidanceTime = -1.0; // 重置稳定制导计时器
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理当前活动制导阶段的失败。
|
||||
/// </summary>
|
||||
/// <param name="forceContinueOnConfigError">内部错误时是否强制尝试继续</param>
|
||||
private void HandleCurrentPhaseFailure(bool forceContinueOnConfigError = false)
|
||||
{
|
||||
string failedComponentName = currentActiveConfig?.ComponentName ?? currentActiveGuidance?.GetType().Name ?? "Unknown";
|
||||
Debug.WriteLine($"[CompositeGuidance.Failure] 制导模块 {failedComponentName} 已失败。");
|
||||
|
||||
bool continueChain = forceContinueOnConfigError || (currentActiveConfig?.ContinueChainOnFailure ?? true);
|
||||
|
||||
if (currentActiveGuidance != null)
|
||||
{
|
||||
if (currentActiveGuidance is BaseGuidanceSystem baseGsToDeactivate)
|
||||
{
|
||||
baseGsToDeactivate.Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
currentActiveGuidance = null;
|
||||
currentActiveConfig = null;
|
||||
|
||||
if (continueChain)
|
||||
{
|
||||
Debug.WriteLine($"[CompositeGuidance.Failure] 配置允许,尝试下一个制导模块。");
|
||||
TryActivateNextGuidanceSystem(deactivatePrevious: false); // deactivatePrevious 为 false,因为已经停用了
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"[CompositeGuidance.Failure] 制导链因模块 {failedComponentName} 失败且配置为不继续而中止。");
|
||||
guidanceChainHaltedOrCompleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导弹状态
|
||||
/// </summary>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
// 更新飞行阶段 (Launch, Cruise, Terminal)
|
||||
// 这部分逻辑保持不变,因为它控制导弹的物理飞行状态和阶段转换
|
||||
switch (currentFlightStage)
|
||||
{
|
||||
case CompositeFlightStage.Launch:
|
||||
UpdateLaunchStage(deltaTime);
|
||||
break;
|
||||
case CompositeFlightStage.Cruise:
|
||||
UpdateCruiseStage(deltaTime);
|
||||
break;
|
||||
case CompositeFlightStage.Terminal:
|
||||
UpdateTerminalStage(deltaTime); // UpdateTerminalStage 内部可以决定是否调用 UpdateGuidanceLogic
|
||||
break;
|
||||
}
|
||||
|
||||
// 具体的制导模式切换和活动制导系统更新由 UpdateGuidanceLogic 处理
|
||||
// 只在特定条件下(例如,串行模式且处于末制导)调用 UpdateGuidanceLogic
|
||||
if (Properties.CompositeWorkMode == CompositeWorkType.Serial && currentFlightStage == CompositeFlightStage.Terminal)
|
||||
{
|
||||
UpdateGuidanceLogic(deltaTime);
|
||||
}
|
||||
// else if (Properties.CompositeWorkMode == CompositeWorkType.Parallel) { /* 未来可扩展并行逻辑 */ }
|
||||
|
||||
|
||||
// 在所有逻辑更新后,统一设置导弹的制导状态和加速度
|
||||
if (currentActiveGuidance != null && currentActiveGuidance.HasGuidance)
|
||||
{
|
||||
this.IsGuidance = true;
|
||||
this.GuidanceAcceleration = currentActiveGuidance.GetGuidanceAcceleration();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.IsGuidance = false;
|
||||
this.GuidanceAcceleration = Vector3D.Zero;
|
||||
}
|
||||
|
||||
base.Update(deltaTime); // 调用基类更新,处理运动学等
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发射导弹,并初始化飞行阶段及制导链状态。
|
||||
/// </summary>
|
||||
public override void Fire()
|
||||
{
|
||||
base.Fire();
|
||||
currentFlightStage = CompositeFlightStage.Launch;
|
||||
|
||||
// 重置制导链状态
|
||||
InitializeGuidanceSuite(); // 重新初始化以获取最新的排序和重置内部状态
|
||||
// currentGuidancePhaseIndex = -1; // InitializeGuidanceSuite 内部会处理
|
||||
// guidanceChainHaltedOrCompleted = false; // InitializeGuidanceSuite 内部会处理
|
||||
// currentActiveGuidance = null; // InitializeGuidanceSuite 内部会处理
|
||||
// currentActiveConfig = null; // InitializeGuidanceSuite 内部会处理
|
||||
currentPhaseActivationTime = -1.0;
|
||||
currentPhaseStableGuidanceTime = -1.0;
|
||||
|
||||
Debug.WriteLine($"[CompositeGuidedMissile.Fire] 导弹 {Id} 发射. 初始阶段: {currentFlightStage}. 制导链已重置.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新发射阶段,基于MaxEngineBurnTime转换到巡航阶段。
|
||||
/// </summary>
|
||||
protected virtual void UpdateLaunchStage(double deltaTime)
|
||||
{
|
||||
if (FlightTime >= Properties.MaxEngineBurnTime)
|
||||
{
|
||||
currentFlightStage = CompositeFlightStage.Cruise;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新巡航阶段,基于CruiseTime转换到末制导阶段。
|
||||
/// </summary>
|
||||
protected virtual void UpdateCruiseStage(double deltaTime)
|
||||
{
|
||||
if (FlightTime >= Properties.CruiseTime)
|
||||
{
|
||||
currentFlightStage = CompositeFlightStage.Terminal;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新末制导阶段,调用UpdateGuidanceMode处理制导逻辑。
|
||||
/// </summary>
|
||||
protected virtual void UpdateTerminalStage(double deltaTime)
|
||||
{
|
||||
UpdateGuidanceLogic(deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停用导弹,并清理制导系统状态。
|
||||
/// </summary>
|
||||
public override void Deactivate()
|
||||
{
|
||||
Debug.WriteLine($"[CompositeGuidedMissile.Deactivate] 开始停用导弹 {Id}.");
|
||||
base.Deactivate();
|
||||
if (currentActiveGuidance != null)
|
||||
{
|
||||
if (currentActiveGuidance is BaseGuidanceSystem activeBaseGs)
|
||||
{
|
||||
activeBaseGs.Deactivate();
|
||||
}
|
||||
currentActiveGuidance = null;
|
||||
}
|
||||
// sortedGuidanceSystems 中的其他已创建但未活动的系统,如果它们有需要清理的状态,也应考虑
|
||||
// 但通常 Deactivate 是针对活动组件的。InitializeGuidanceSuite 会在下次 Fire 时重建。
|
||||
|
||||
guidanceChainHaltedOrCompleted = true; // 标记为不再活动
|
||||
currentActiveConfig = null;
|
||||
Debug.WriteLine($"[CompositeGuidedMissile.Deactivate] 导弹 {Id} 已停用. 活动制导系统已处理.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取导弹状态信息,包括复合制导的特定状态。
|
||||
/// </summary>
|
||||
public override ElementStatusInfo GetStatusInfo()
|
||||
{
|
||||
var statusInfo = base.GetStatusInfo();
|
||||
statusInfo.ExtendedProperties["CurrentFlightStage"] = currentFlightStage.ToString(); // 已有
|
||||
statusInfo.ExtendedProperties["CompositeWorkMode"] = Properties.CompositeWorkMode.ToString(); // 已有
|
||||
statusInfo.ExtendedProperties["ActiveGuidanceSystem"] = currentActiveGuidance?.GetType().Name ?? "None"; // 已有
|
||||
statusInfo.ExtendedProperties["ActiveGuidanceConfig"] = currentActiveConfig?.ComponentName ?? "None";
|
||||
statusInfo.ExtendedProperties["CurrentGuidancePhaseIndex"] = currentGuidancePhaseIndex.ToString();
|
||||
statusInfo.ExtendedProperties["GuidanceChainHaltedOrCompleted"] = guidanceChainHaltedOrCompleted.ToString();
|
||||
statusInfo.ExtendedProperties["ConfiguredGuidanceSystemsCount"] = sortedGuidanceSystems.Count.ToString(); // 改用排序后的列表计数
|
||||
|
||||
for (int i = 0; i < sortedGuidanceSystems.Count; i++)
|
||||
{
|
||||
var guidanceSystem = sortedGuidanceSystems[i];
|
||||
if (guidanceSystem is SimulationElement simElement) // 检查并转换
|
||||
{
|
||||
string statusString = simElement.GetStatusInfo().ToString();
|
||||
string keyName = $"SubGuidanceSystem_Status_{i}";
|
||||
statusInfo.ExtendedProperties[keyName] = statusString;
|
||||
}
|
||||
else if (guidanceSystem != null) // 如果不是SimulationElement但非null,记录一个警告或默认值
|
||||
{
|
||||
string keyName = $"SubGuidanceSystem_Status_{i}";
|
||||
statusInfo.ExtendedProperties[keyName] = "Error: Guidance system is not a SimulationElement or is null.";
|
||||
Debug.WriteLine($"[CompositeGuidedMissile.GetStatusInfo] Warning: Guidance system at index {i} (type: {guidanceSystem.GetType().Name}) is not a SimulationElement or is null.");
|
||||
}
|
||||
}
|
||||
return statusInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
using ThreatSource.Simulation;
|
||||
using System.Collections.Generic; // Required for List<T>
|
||||
using ThreatSource.Equipment; // 添加此 using 指令以识别 EquipmentType
|
||||
|
||||
namespace ThreatSource.Missile
|
||||
{
|
||||
@ -48,7 +50,151 @@ namespace ThreatSource.Missile
|
||||
/// <summary>
|
||||
/// 末敏弹子弹
|
||||
/// </summary>
|
||||
TerminalSensitiveSubmunition
|
||||
TerminalSensitiveSubmunition,
|
||||
/// <summary>
|
||||
/// 复合制导导弹,使用 GuidanceSuite 配置。
|
||||
/// </summary>
|
||||
CompositeGuidance
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定义制导组件激活的触发条件类型
|
||||
/// </summary>
|
||||
public enum GuidanceActivationTriggerType
|
||||
{
|
||||
/// <summary>
|
||||
/// 在发射时激活
|
||||
/// </summary>
|
||||
OnLaunch,
|
||||
/// <summary>
|
||||
/// 在飞行一段时间后激活
|
||||
/// </summary>
|
||||
AfterFlightTime,
|
||||
/// <summary>
|
||||
/// 在距离目标一定距离时激活
|
||||
/// </summary>
|
||||
DistanceToTargetThreshold,
|
||||
/// <summary>
|
||||
/// 在上一阶段完成时激活
|
||||
/// </summary>
|
||||
PreviousStageComplete,
|
||||
/// <summary>
|
||||
/// 根据命令或逻辑激活
|
||||
/// </summary>
|
||||
CommandOrLogic,
|
||||
/// <summary>
|
||||
/// 手动或备用激活
|
||||
/// </summary>
|
||||
ManualOrBackup
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定义复合制导中多个制导系统的工作方式
|
||||
/// </summary>
|
||||
public enum CompositeWorkType
|
||||
{
|
||||
/// <summary>
|
||||
/// 串行工作:任何时候只有一个制导系统处于活动状态并提供指令。
|
||||
/// </summary>
|
||||
Serial,
|
||||
/// <summary>
|
||||
/// 并行工作:多个制导系统可以同时活动,可能需要指令融合。
|
||||
/// </summary>
|
||||
Parallel
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定义并行工作模式下的指令融合策略
|
||||
/// </summary>
|
||||
public enum CommandFusionStrategy
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用当前活动且优先级最高的制导系统的指令。
|
||||
/// </summary>
|
||||
UseHighestPriority,
|
||||
/// <summary>
|
||||
/// (未来扩展) 加权平均融合来自多个活动制导系统的指令。
|
||||
/// </summary>
|
||||
WeightedAverage,
|
||||
/// <summary>
|
||||
/// (未来扩展) 使用自定义的融合逻辑。
|
||||
/// </summary>
|
||||
CustomLogic
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单个制导组件的配置
|
||||
/// </summary>
|
||||
public class GuidanceComponentConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 制导组件名称
|
||||
/// </summary>
|
||||
public string ComponentName { get; set; } = "DefaultGuidanceComponent";
|
||||
/// <summary>
|
||||
/// 制导系统类型
|
||||
/// </summary>
|
||||
public string GuidanceSystemType { get; set; } = "Inertial";
|
||||
/// <summary>
|
||||
/// 特定配置
|
||||
/// </summary>
|
||||
public object? SpecificConfig { get; set; }
|
||||
/// <summary>
|
||||
/// 激活触发类型
|
||||
/// </summary>
|
||||
public GuidanceActivationTriggerType ActivationTrigger { get; set; } = GuidanceActivationTriggerType.OnLaunch;
|
||||
/// <summary>
|
||||
/// 激活值
|
||||
/// </summary>
|
||||
public double ActivationValue { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 优先级,用于决定串行模式下的执行顺序。数值越小,优先级越高。
|
||||
/// </summary>
|
||||
public int Priority { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// (可选) 从激活开始,允许该模块尝试获取有效制导(HasGuidance == true)的最大时间(秒)。
|
||||
/// 设为0或负数表示不使用此超时。
|
||||
/// </summary>
|
||||
public double MaxTimeToAcquireGuidanceSeconds { get; set; } = 5.0;
|
||||
|
||||
/// <summary>
|
||||
/// (可选) 当获得稳定制导(HasGuidance == true)后,在切换到下一阶段之前需要保持制导的最短持续时间(秒)。
|
||||
/// 默认为0表示一旦获得制导即满足切换条件(如果其他条件也满足)。
|
||||
/// </summary>
|
||||
public double MinTimeWithGuidanceBeforeSwitchSeconds { get; set; } = 0.0;
|
||||
|
||||
/// <summary>
|
||||
/// (可选) 如果此制导阶段失败(例如超时、受干扰等),是否继续尝试激活序列中的下一个制导系统。
|
||||
/// 默认为 true。
|
||||
/// </summary>
|
||||
public bool ContinueChainOnFailure { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 默认构造函数
|
||||
/// </summary>
|
||||
public GuidanceComponentConfig() { }
|
||||
|
||||
/// <summary>
|
||||
/// 带参数的构造函数
|
||||
/// </summary>
|
||||
public GuidanceComponentConfig(string name, string type, object? specificConfig = null,
|
||||
GuidanceActivationTriggerType trigger = GuidanceActivationTriggerType.OnLaunch,
|
||||
double triggerValue = 0, int priority = 0,
|
||||
double maxTimeToAcquireGuidance = 5.0,
|
||||
double minTimeWithGuidanceBeforeSwitch = 0.0,
|
||||
bool continueOnFailure = true)
|
||||
{
|
||||
ComponentName = name;
|
||||
GuidanceSystemType = type;
|
||||
SpecificConfig = specificConfig;
|
||||
ActivationTrigger = trigger;
|
||||
ActivationValue = triggerValue;
|
||||
Priority = priority;
|
||||
MaxTimeToAcquireGuidanceSeconds = maxTimeToAcquireGuidance;
|
||||
MinTimeWithGuidanceBeforeSwitchSeconds = minTimeWithGuidanceBeforeSwitch;
|
||||
ContinueChainOnFailure = continueOnFailure;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -201,6 +347,24 @@ namespace ThreatSource.Missile
|
||||
/// </remarks>
|
||||
public double CruiseTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 制导组件套件。仅当 Type 为 CompositeGuidance 时有效。
|
||||
/// 列表中的顺序可能也暗示了串行模式下的默认阶段顺序,除非 ActivationTrigger 另有复杂规定,并结合Priority。
|
||||
/// </summary>
|
||||
public List<GuidanceComponentConfig> GuidanceSuite { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 复合制导模式下,多个制导系统的工作方式。默认为串行。
|
||||
/// 仅当 Type 为 CompositeGuidance 时有效。
|
||||
/// </summary>
|
||||
public CompositeWorkType CompositeWorkMode { get; set; } = CompositeWorkType.Serial;
|
||||
|
||||
/// <summary>
|
||||
/// 并行工作模式下的指令融合策略。默认为使用最高优先级的指令。
|
||||
/// 仅当 Type 为 CompositeGuidance 且 CompositeWorkMode 为 Parallel 时有效。
|
||||
/// </summary>
|
||||
public CommandFusionStrategy FusionStrategy { get; set; } = CommandFusionStrategy.UseHighestPriority;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化导弹配置类的新实例
|
||||
/// </summary>
|
||||
@ -215,6 +379,7 @@ namespace ThreatSource.Missile
|
||||
SetDefaultValues();
|
||||
Type = MissileType.StandardMissile;
|
||||
LaserCodeConfig = new LaserCodeConfig();
|
||||
GuidanceSuite = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -242,6 +407,11 @@ namespace ThreatSource.Missile
|
||||
ExplosionRadius = 5;
|
||||
HitProbability = 0.9;
|
||||
SelfDestructHeight = 0;
|
||||
|
||||
// 重置复合制导相关属性的默认值
|
||||
CompositeWorkMode = CompositeWorkType.Serial;
|
||||
FusionStrategy = CommandFusionStrategy.UseHighestPriority;
|
||||
if (GuidanceSuite != null) GuidanceSuite.Clear(); else GuidanceSuite = new List<GuidanceComponentConfig>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,10 @@
|
||||
- 事件描述
|
||||
- 分析处理
|
||||
|
||||
## 2025-05-18 增加了装备的RCS特征矩阵
|
||||
- 增加了装备的RCS特征矩阵
|
||||
- 在毫米波末制导中,用RCS特征矩阵取值
|
||||
|
||||
## 2025-05-15 完善了末敏弹的发射角度计算逻辑
|
||||
- 完善了末敏弹的发射角度计算逻辑,增加目标速度、空气阻力的影响
|
||||
- 完善了末敏子弹各阶段的控制参数
|
||||
|
||||
@ -444,6 +444,36 @@
|
||||
2. 对目标位置进行预测后,发射距离不再重要。
|
||||
3. 目标速度不能太大,比如超过10米/秒,导弹会飞出范围。(在 10 米/秒以下,也有概率不能命中)
|
||||
|
||||
## 复合制导导弹实验记录(v1.1.19)
|
||||
|
||||
时间:2025-05-18 10:00:00
|
||||
版本:v1.1.19
|
||||
|
||||
### 合理发射参数(与红外和毫米波一样)
|
||||
- 发射高度:1米
|
||||
- 发射角度:0.2
|
||||
- 导弹初速度:10米/秒
|
||||
|
||||
### 合理配置参数
|
||||
|
||||
多模制导:
|
||||
(毫米波)
|
||||
- MinTimeWithGuidanceBeforeSwitchSeconds:0.2秒(因为毫米波跟踪不稳定,不能设置过大)
|
||||
- MaxTimeToAcquireGuidanceSeconds:5秒
|
||||
- ContinueChainOnFailure:true
|
||||
(红外)
|
||||
- MinTimeWithGuidanceBeforeSwitchSeconds:60秒(这是最后一个制导的持续时间)
|
||||
- MaxTimeToAcquireGuidanceSeconds:5秒
|
||||
- ContinueChainOnFailure:false
|
||||
|
||||
毫米波制导系统参数:
|
||||
- SearchBeamWidth:5.0度
|
||||
- TrackBeamWidth:2.5度
|
||||
- LockBeamWidth:1.0度
|
||||
|
||||
### 实验结果
|
||||
- 毫米波跟踪不稳定,适当加大搜索和跟踪波束宽度,可以提高跟踪稳定性。
|
||||
- 将MinTimeWithGuidanceBeforeSwitchSeconds设置为0.2秒,可以稳定切换到红外制导。
|
||||
|
||||
|
||||
|
||||
|
||||
@ -54,6 +54,7 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
"ICGM_1" => "红外指令制导导弹",
|
||||
"ITGM_1" => "红外成像末制导导弹",
|
||||
"MMWG_1" => "毫米波末制导导弹",
|
||||
"CGGM_1" => "复合制导导弹",
|
||||
_ => "未知导弹",
|
||||
};
|
||||
}
|
||||
@ -166,6 +167,14 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
(JammingType.MillimeterWave, "毫米波假信号", "MillimeterWaveCompensationJammer_Submunition", "欺骗", "子弹药"),
|
||||
(JammingType.SmokeGrenade, "烟幕弹", "SG_4", "遮蔽", "子弹药")
|
||||
];
|
||||
|
||||
// 复合制导导弹
|
||||
missileJammingMap["CGGM_1"] =
|
||||
[
|
||||
(JammingType.MillimeterWave, "毫米波干扰", "MillimeterWaveJammer_Missile", "阻塞", "导弹"),
|
||||
(JammingType.Infrared, "红外干扰", "InfraredJammer_Missile", "阻塞", "导弹"),
|
||||
(JammingType.SmokeGrenade, "烟幕弹", "SG_1", "遮蔽", "导弹")
|
||||
];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -186,6 +195,7 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
AddInfraredCommandMissile();
|
||||
AddInfraredImagingMissile();
|
||||
AddMillimeterWaveMissile();
|
||||
AddCompositeGuidanceMissile();
|
||||
|
||||
// 添加各种传感器和指示器
|
||||
AddIndicators();
|
||||
@ -223,7 +233,7 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
{
|
||||
Position = new Vector3D(0, 1.2, 0),
|
||||
Orientation = new Orientation(0.0, 0.0, 0.0),
|
||||
Speed = 2.0
|
||||
Speed = 0.0
|
||||
};
|
||||
string targetId = "Tank_1";
|
||||
var target = _threatSourceFactory.CreateEquipment(targetId, "mbt_001", motionParameters);
|
||||
@ -417,6 +427,24 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
Console.WriteLine($"注册毫米波末制导导弹 {missileId}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加复合制导导弹
|
||||
/// </summary>
|
||||
private void AddCompositeGuidanceMissile()
|
||||
{
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(2000, 1, 20),
|
||||
Orientation = new Orientation(Math.PI/2, 0.2, 0),
|
||||
Speed = 10
|
||||
};
|
||||
string missileId = "CGGM_1";
|
||||
var missile = _threatSourceFactory.CreateMissile(missileId, "cg_001", "Tank_1", motionParameters);
|
||||
missiles[missileId] = missile;
|
||||
simulationManager.RegisterEntity(missileId, missile);
|
||||
Console.WriteLine($"注册复合制导导弹 {missileId}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加传感器和指示器
|
||||
/// </summary>
|
||||
@ -679,22 +707,22 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
switch (missileId)
|
||||
{
|
||||
case "LSGM_1": // 激光半主动制导导弹
|
||||
if (indicators.ContainsKey("LD_1"))
|
||||
if (indicators.TryGetValue("LD_1", out SimulationElement? value1))
|
||||
{
|
||||
indicators["LD_1"].Activate();
|
||||
value1.Activate();
|
||||
}
|
||||
Console.WriteLine($"干扰器数量 {jammers.Count}");
|
||||
break;
|
||||
case "LBRM_1": // 激光驾束制导导弹
|
||||
if (indicators.ContainsKey("LBR_1"))
|
||||
if (indicators.TryGetValue("LBR_1", out SimulationElement? value2))
|
||||
{
|
||||
indicators["LBR_1"].Activate();
|
||||
value2.Activate();
|
||||
}
|
||||
break;
|
||||
case "ICGM_1": // 红外指令制导导弹
|
||||
if (indicators.ContainsKey("IT_1"))
|
||||
if (indicators.TryGetValue("IT_1", out SimulationElement? value3))
|
||||
{
|
||||
indicators["IT_1"].Activate();
|
||||
value3.Activate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -707,7 +735,7 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
{
|
||||
if (string.IsNullOrEmpty(SelectedMissileId) || !missileJammingMap.ContainsKey(SelectedMissileId))
|
||||
{
|
||||
return Array.Empty<(JammingType, string, string, string, string)>();
|
||||
return [];
|
||||
}
|
||||
|
||||
return missileJammingMap[SelectedMissileId].ToArray();
|
||||
|
||||
@ -9,7 +9,7 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
Console.WriteLine("综合导弹模拟程序启动...");
|
||||
var simulator = new ComprehensiveMissileSimulator();
|
||||
// 如果需要,可以在启动时设置默认日志级别,或依赖Simulator的默认值
|
||||
// simulator.SetLogLevel(SourceLevels.Information);
|
||||
simulator.SetLogLevel(SourceLevels.Verbose);
|
||||
ApplicationHostLoop(simulator);
|
||||
Console.WriteLine("\n程序已退出。");
|
||||
}
|
||||
@ -192,7 +192,8 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
("TSM_1", "末敏弹"),
|
||||
("ICGM_1", "红外指令制导导弹"),
|
||||
("ITGM_1", "红外成像末制导导弹"),
|
||||
("MMWG_1", "毫米波末制导导弹")
|
||||
("MMWG_1", "毫米波末制导导弹"),
|
||||
("CGGM_1", "复合制导导弹")
|
||||
};
|
||||
|
||||
while (true)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user