增加激光/红外成像复合制导导弹

This commit is contained in:
Tian jianyong 2025-05-23 18:24:21 +08:00
parent 5f76e5b067
commit 3b38e699e5
7 changed files with 133 additions and 60 deletions

View File

@ -29,7 +29,7 @@ CompositeWorkMode = "Serial" # 工作模式Serial (串行) 或 Parallel (并
# 第一个制导阶段:毫米波
[[Properties.GuidanceSuite]]
ComponentName = "MMW_Phase1_Cruise"
GuidanceSystemType = "MillimeterWaveTerminalGuidance" # 必须与C#工厂中的类型字符串匹配
GuidanceSystemType = "MillimeterWaveTerminalGuidance" # 必须与工厂中的类型字符串匹配
ActivationTrigger = "OnLaunch" # 激活触发器OnLaunch, AfterFlightTime, DistanceToTargetThreshold, PreviousStageComplete
ActivationValue = 0.0 # 触发器关联值 (例如:飞行时间秒数,距离米数)
Priority = 0 # 优先级 (例如0为最高)
@ -40,7 +40,7 @@ ContinueChainOnFailure = true # 失败后继续尝试下一个
# 第二个制导阶段:红外成像末制导
[[Properties.GuidanceSuite]]
ComponentName = "IR_Phase2_Terminal"
GuidanceSystemType = "InfraredImagingTerminalGuidance" # 必须与C#工厂中的类型字符串匹配
GuidanceSystemType = "InfraredImagingTerminalGuidance" # 必须与工厂中的类型字符串匹配
ActivationTrigger = "PreviousStageComplete" # 例如:在飞行一段时间后切换 (或者 PreviousStageComplete)
ActivationValue = 10.0 # 例如飞行10秒后激活红外阶段 (如果 CruiseTime 是 5s这里可能需要调整)
Priority = 1 # 优先级低于毫米波

View File

@ -0,0 +1,86 @@
# 毫米波-红外成像末制导导弹-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 = 4.0
LaunchAcceleration = 100.0
MaxEngineBurnTime = 2.5
CruiseTime = 4.0
Mass = 25.0
ExplosionRadius = 5.0
HitProbability = 0.9
SelfDestructHeight = 0.0
InfraredRadiationIntensity = 96.0 # 红外辐射强度 (瓦特/球面度)
UltravioletRadiationIntensity = 100.0 # 紫外辐射强度 (瓦特/球面度)
# --- 复合制导特定属性 ---
CompositeWorkMode = "Serial" # 工作模式Serial (串行) 或 Parallel (并行)
# FusionStrategy = "UseHighestPriority" # 仅在并行模式下相关
# --- 制导组件套件 (GuidanceSuite) ---
# 第一个制导阶段:激光半主动制导
[[Properties.GuidanceSuite]]
ComponentName = "LaserSemiActive_Phase1_Terminal"
GuidanceSystemType = "LaserSemiActiveGuidance" # 必须与工厂中的类型字符串匹配
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" # 必须与工厂中的类型字符串匹配
ActivationTrigger = "PreviousStageComplete" # 例如:在飞行一段时间后切换 (或者 PreviousStageComplete)
ActivationValue = 10.0 # 例如飞行10秒后激活红外阶段 (如果 CruiseTime 是 5s这里可能需要调整)
Priority = 1 # 优先级低于毫米波
MaxTimeToAcquireGuidanceSeconds = 5.0 # 获取制导的最大时间
MinTimeWithGuidanceBeforeSwitchSeconds = 60.0 # 设置为MaxFlightTime使其持续制导
ContinueChainOnFailure = false # 这是最后一个,失败也无需继续
# --- 各制导模式的详细配置 ---
[LaserSemiActiveGuidanceConfig] # 激光半主动制导系统配置
FieldOfViewAngle = 30.0 # 传感器视场角 (度)
LensDiameter = 0.1 # 传感器透镜直径 (米)
SensorDiameter = 0.03 # 探测器/传感器本身直径 (米)
FocusedSpotDiameter = 0.006 # 传感器上聚焦激光光斑直径 (米)
ReflectionCoefficient = 0.2 # 目标激光反射系数 (0.0 到 1.0)
TargetReflectiveArea = 1.0 # 目标有效反射面积 (m^2)
LockThreshold = 1.0e-8 # 锁定目标的最小接收功率 (瓦特, 例如 1.0e-8 W)
SpotOffsetSensitivity = 0.05 # 对光斑偏移的敏感度,用于制导调整
JammingResistanceThreshold = 1.0e-5 # 克服干扰所需的接收功率阈值 (瓦特, 例如 1e-5 W)
TransmitterEfficiency = 0.85 # 激光指示器发射效率 (0.0 到 1.0)
ReceiverEfficiency = 0.8 # 导弹激光接收器效率 (0.0 到 1.0)
Wavelength = 1.06 # 激光波长 (微米, μm)
[LaserSemiActiveGuidanceConfig.LaserCodeConfig] # properties内部的激光编码配置
IsCodeEnabled = true # 激光编码系统是否启用?
IsCodeMatchRequired = true # 制导是否需要匹配激光编码?
[LaserSemiActiveGuidanceConfig.LaserCodeConfig.Code] # 具体的激光编码详情
CodeType = "PRF" # 激光编码类型 (例如 PRF)
CodeValue = 1010 # 激光编码的实际值
[InfraredImagingGuidanceConfig]
MaxDetectionRange = 1000.0 # 最大探测距离 (米)
SearchFieldOfView = 12.0 # 搜索视场角 (度)
TrackFieldOfView = 6.0 # 跟踪视场角 (度)
ImageWidth = 640 # 图像宽度 (像素)
ImageHeight = 480 # 图像高度 (像素)
BackgroundIntensity = 1.0e-4 # 背景辐射强度 (瓦特/球面度)
SearchRecognitionProbability = 0.6 # 搜索模式目标识别概率阈值
TrackRecognitionProbability = 0.8 # 跟踪模式目标识别概率阈值
TargetLostTolerance = 0.3 # 目标丢失容忍时间 (秒)
LockConfirmationTime = 0.5 # 锁定确认时间 (秒)
JammingResistanceThreshold = 1.0e-5 # 干扰抗性阈值 (瓦特)
Wavelength = 3.0 # 波长 (微米)

View File

@ -103,7 +103,7 @@ namespace ThreatSource.Data
componentConfig.SpecificConfig = data.InfraredImagingGuidanceConfig;
topLevelConfigName = nameof(data.InfraredImagingGuidanceConfig);
break;
case "lasers semiactiveguidance":
case "lasersemiactiveguidance":
assignedConfig = data.LaserSemiActiveGuidanceConfig;
componentConfig.SpecificConfig = data.LaserSemiActiveGuidanceConfig;
topLevelConfigName = nameof(data.LaserSemiActiveGuidanceConfig);
@ -131,7 +131,7 @@ namespace ThreatSource.Data
{
if (assignedConfig == null &&
(typeKey == "millimeterwaveterminalguidance" || typeKey == "millimeterwave" ||
typeKey == "infraredimagingterminalguidance" || typeKey == "lasers semiactiveguidance" ||
typeKey == "infraredimagingterminalguidance" || typeKey == "lasersemiactiveguidance" ||
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)}'.");

View File

@ -501,7 +501,7 @@ namespace ThreatSource.Guidance
}
else // 窗口未满
{
foundThisFrame = isRecognizedThisFrame; // foundThisFrame反映本帧直接识别结果
foundThisFrame = isRecognizedThisFrame;
if (isRecognizedThisFrame) targetPosition = currentEntity.KState.Position;
Debug.WriteLine($"[IR IMAGING SEARCH] 目标 {searchModeFocusCandidateId} 正在收集数据,窗口 ({activeRecognitionHistory.Count}/{COMMON_RECOGNITION_WINDOW_SIZE}). 本帧识别: {isRecognizedThisFrame}");
}
@ -510,10 +510,9 @@ namespace ThreatSource.Guidance
case WorkMode.Track:
if (currentlyTrackedTargetId == null || currentEntity.Id != currentlyTrackedTargetId)
{
continue; // 不是当前正在跟踪的目标
continue;
}
// 当前是跟踪目标,且已通过外层基本检查
var image_track = imageGenerator.GenerateImage(currentEntity, missilePosition, overallTransmittance, SimulationManager);
var trackResult = targetRecognizer.RecognizeTarget(image_track, currentEntity);
isRecognizedThisFrame = trackResult.Type == targetType && trackResult.Confidence >= config.TrackRecognitionProbability;
@ -583,8 +582,7 @@ namespace ThreatSource.Guidance
Debug.WriteLine($"[IR IMAGING LOCK] 锁定目标 {currentlyTrackedTargetId} 通过基本检查。");
break;
}
// 如果在Search模式下成功切换到Track或者在Track/Lock模式下处理了目标无论成功与否则不再继续遍历此帧中的其他实体
if (foundThisFrame || currentMode != WorkMode.Search || (currentMode == WorkMode.Search && currentlyTrackedTargetId != null) )
{
break;

View File

@ -50,12 +50,12 @@ namespace ThreatSource.Missile
/// <summary>
/// 经过优先级排序的制导组件配置列表。
/// </summary>
private List<GuidanceComponentConfig> sortedGuidanceConfigs = new List<GuidanceComponentConfig>();
private readonly List<GuidanceComponentConfig> sortedGuidanceConfigs = [];
/// <summary>
/// 经过优先级排序的制导系统实例列表,与 sortedGuidanceConfigs 一一对应。
/// </summary>
private List<IGuidanceSystem> sortedGuidanceSystems = new List<IGuidanceSystem>();
private readonly List<IGuidanceSystem> sortedGuidanceSystems = [];
/// <summary>
/// 当前活动的制导组件配置。
@ -99,12 +99,12 @@ namespace ThreatSource.Missile
/// </summary>
protected void InitializeGuidanceSuite()
{
this.sortedGuidanceSystems.Clear();
this.sortedGuidanceConfigs.Clear();
this.guidanceChainHaltedOrCompleted = false;
this.currentGuidancePhaseIndex = -1; // 重置索引,表示从头开始
this.currentActiveGuidance = null;
this.currentActiveConfig = null;
sortedGuidanceSystems.Clear();
sortedGuidanceConfigs.Clear();
guidanceChainHaltedOrCompleted = false;
currentGuidancePhaseIndex = -1;
currentActiveGuidance = null;
currentActiveConfig = null;
if (Properties.GuidanceSuite != null && Properties.GuidanceSuite.Count > 0)
{
@ -128,23 +128,23 @@ namespace ThreatSource.Missile
foreach (var tuple in tempGuidanceList)
{
this.sortedGuidanceConfigs.Add(tuple.Item1);
this.sortedGuidanceSystems.Add(tuple.Item2);
sortedGuidanceConfigs.Add(tuple.Item1);
sortedGuidanceSystems.Add(tuple.Item2);
}
if (this.sortedGuidanceSystems.Count > 0)
if (sortedGuidanceSystems.Count > 0)
{
this.currentGuidancePhaseIndex = -1; // 设置为-1以便TryActivateNextGuidanceSystem能正确激活第一个
currentGuidancePhaseIndex = -1;
}
else
{
this.guidanceChainHaltedOrCompleted = true; // 没有可用的制导系统
guidanceChainHaltedOrCompleted = true;
Debug.WriteLine("[CompositeGuidance.Initialize] 未配置或未能创建任何有效的制导系统。");
}
}
else
{
this.guidanceChainHaltedOrCompleted = true;
guidanceChainHaltedOrCompleted = true;
Debug.WriteLine("[CompositeGuidance.Initialize] GuidanceSuite 为空。");
}
Debug.WriteLine($"[CompositeGuidance.Initialize] 初始化完成。排序后的制导系统数量: {sortedGuidanceSystems.Count}");
@ -175,6 +175,15 @@ namespace ThreatSource.Missile
{
return null;
}
case "lasersemiactiveguidance":
if (config.SpecificConfig is LaserSemiActiveGuidanceConfig laserConfig)
{
return new LaserSemiActiveGuidanceSystem(config.ComponentName, Id, Properties.MaxAcceleration, Properties.ProportionalNavigationCoefficient, laserConfig, SimulationManager);
}
else
{
return null;
}
default:
return null;
}
@ -199,12 +208,7 @@ namespace ThreatSource.Missile
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.
se.Update(deltaTime);
}
if (currentActiveConfig == null)
@ -233,7 +237,7 @@ namespace ThreatSource.Missile
// 如果不是最后一个制导阶段,则尝试切换到下一个
Debug.WriteLine($"[CompositeGuidance.Logic] 模块 {currentActiveConfig.ComponentName} 完成任务 (稳定制导持续达标),切换到下一阶段。");
TryActivateNextGuidanceSystem(deactivatePrevious: true);
return; // 切换后立即返回,避免同一帧内处理新激活的模块
return;
}
else
{
@ -242,9 +246,8 @@ namespace ThreatSource.Missile
if (!guidanceChainHaltedOrCompleted) // 避免重复打印
{
Debug.WriteLine($"[CompositeGuidance.Logic] 最后一个制导模块 {currentActiveConfig.ComponentName} 已满足稳定条件并将持续工作。");
guidanceChainHaltedOrCompleted = true; // 标记配置的切换链已完成
guidanceChainHaltedOrCompleted = true;
}
// 不返回,允许后续的超时和干扰检查继续作用于这个最后一个阶段
}
}
}
@ -355,9 +358,7 @@ namespace ThreatSource.Missile
public override void Update(double deltaTime)
{
if (!IsActive) return;
// 更新飞行阶段 (Launch, Cruise, Terminal)
// 这部分逻辑保持不变,因为它控制导弹的物理飞行状态和阶段转换
switch (currentFlightStage)
{
case CompositeFlightStage.Launch:
@ -377,10 +378,7 @@ namespace ThreatSource.Missile
{
UpdateGuidanceLogic(deltaTime);
}
// else if (Properties.CompositeWorkMode == CompositeWorkType.Parallel) { /* 未来可扩展并行逻辑 */ }
// 在所有逻辑更新后,统一设置导弹的制导状态和加速度
if (currentActiveGuidance != null && currentActiveGuidance.HasGuidance)
{
this.IsGuidance = true;
@ -404,11 +402,7 @@ namespace ThreatSource.Missile
currentFlightStage = CompositeFlightStage.Launch;
// 重置制导链状态
InitializeGuidanceSuite(); // 重新初始化以获取最新的排序和重置内部状态
// currentGuidancePhaseIndex = -1; // InitializeGuidanceSuite 内部会处理
// guidanceChainHaltedOrCompleted = false; // InitializeGuidanceSuite 内部会处理
// currentActiveGuidance = null; // InitializeGuidanceSuite 内部会处理
// currentActiveConfig = null; // InitializeGuidanceSuite 内部会处理
InitializeGuidanceSuite();
currentPhaseActivationTime = -1.0;
currentPhaseStableGuidanceTime = -1.0;
@ -460,10 +454,7 @@ namespace ThreatSource.Missile
}
currentActiveGuidance = null;
}
// sortedGuidanceSystems 中的其他已创建但未活动的系统,如果它们有需要清理的状态,也应考虑
// 但通常 Deactivate 是针对活动组件的。InitializeGuidanceSuite 会在下次 Fire 时重建。
guidanceChainHaltedOrCompleted = true; // 标记为不再活动
guidanceChainHaltedOrCompleted = true;
currentActiveConfig = null;
Debug.WriteLine($"[CompositeGuidedMissile.Deactivate] 导弹 {Id} 已停用. 活动制导系统已处理.");
}
@ -485,16 +476,14 @@ namespace ThreatSource.Missile
for (int i = 0; i < sortedGuidanceSystems.Count; i++)
{
var guidanceSystem = sortedGuidanceSystems[i];
if (guidanceSystem is SimulationElement simElement) // 检查并转换
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记录一个警告或默认值
else if (guidanceSystem != null)
{
string keyName = $"SubGuidanceSystem_Status_{i}";
statusInfo.ExtendedProperties[keyName] = "错误: 制导系统不是 SimulationElement 或为null.";
Debug.WriteLine($"[CompositeGuidedMissile.GetStatusInfo] 警告: 制导系统 at index {i} (type: {guidanceSystem.GetType().Name}) 不是 SimulationElement 或为null.");
}
}

View File

@ -439,7 +439,7 @@ namespace ThreatSource.Tools.MissileSimulation
Speed = 10
};
string missileId = "CGGM_1";
var missile = _threatSourceFactory.CreateMissile(missileId, "cg_001", "Tank_1", motionParameters);
var missile = _threatSourceFactory.CreateMissile(missileId, "cg_002", "Tank_1", motionParameters);
missiles[missileId] = missile;
simulationManager.RegisterEntity(missileId, missile);
Console.WriteLine($"注册复合制导导弹 {missileId}");

View File

@ -42,8 +42,8 @@ namespace ThreatSource.Tools.MissileSimulation
}
Console.WriteLine($"1. 选择导弹 ({missileStatus})");
Console.WriteLine($"2. 配置传感器 {sensorStatusString}");
Console.WriteLine($"3. 配置干扰 {simulator.GetActiveJammingDescription()} {(string.IsNullOrEmpty(simulator.SelectedMissileId) ? "()" : "")}");
Console.WriteLine($"2. 选择指示器 {sensorStatusString}");
Console.WriteLine($"3. 选择干扰方式 {simulator.GetActiveJammingDescription()} {(string.IsNullOrEmpty(simulator.SelectedMissileId) ? "()" : "")}");
Console.WriteLine($"4. 设置日志级别 (当前级别: {simulator.CurrentLogLevel})");
Console.WriteLine($"5. 开始仿真 {(string.IsNullOrEmpty(simulator.SelectedMissileId) ? "()" : "")}");
Console.WriteLine($"6. 设置仿真步长 (当前: {simulator.TimeStep}s)");
@ -225,12 +225,12 @@ namespace ThreatSource.Tools.MissileSimulation
{
while (true)
{
Console.WriteLine("\n--- 配置传感器和指示器 ---");
Console.WriteLine("当前传感器状态:");
Console.WriteLine("\n--- 选择指示器 ---");
Console.WriteLine("当前指示器状态:");
var indicators = simulator.GetActiveIndicators();
if (indicators.Length == 0)
{
Console.WriteLine("当前导弹类型没有可配置的独立传感器/指示器,或未实现获取接口。");
Console.WriteLine("当前导弹类型没有可配置的指示器,或未实现获取接口。");
}
else
{
@ -240,7 +240,7 @@ namespace ThreatSource.Tools.MissileSimulation
}
}
Console.WriteLine(" 0. 返回主菜单");
Console.Write("请选择切换状态的传感器,或返回: ");
Console.Write("请选择切换状态的指示器,或返回: ");
string input = Console.ReadLine()?.ToLower() ?? string.Empty;
if (input == "0")
@ -286,12 +286,12 @@ namespace ThreatSource.Tools.MissileSimulation
while (true)
{
Console.WriteLine("\n--- 配置干扰方式 ---");
Console.WriteLine("\n--- 选择干扰方式 ---");
Console.WriteLine($"当前导弹: {simulator.SelectedMissileDisplayName}");
if (availableJammingOptions.Length == 0)
{
Console.WriteLine("当前导弹类型没有可配置的干扰选项。");
Console.WriteLine("当前导弹类型没有可选择的干扰方式。");
}
else
{