新增多模制导导弹,支持毫米波/红外双模制导,提供了多模制导框架(需要增加相关配置文件并验证)

This commit is contained in:
Tian jianyong 2025-05-18 15:29:11 +08:00
parent 5a0f9f1ece
commit 082bf6ea51
14 changed files with 950 additions and 34 deletions

View File

@ -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

View 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 # 干扰抗性阈值 (瓦特)

View File

@ -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}");
}
}

View File

@ -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}");
}

View File

@ -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;
}

View File

@ -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);
}
}

View 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;
}
}
}

View File

@ -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>();
}
}
}

View File

@ -1 +1 @@
1.1.18
1.1.19

View File

@ -7,6 +7,10 @@
- 事件描述
- 分析处理
## 2025-05-18 增加了装备的RCS特征矩阵
- 增加了装备的RCS特征矩阵
- 在毫米波末制导中用RCS特征矩阵取值
## 2025-05-15 完善了末敏弹的发射角度计算逻辑
- 完善了末敏弹的发射角度计算逻辑,增加目标速度、空气阻力的影响
- 完善了末敏子弹各阶段的控制参数

View File

@ -444,6 +444,36 @@
2. 对目标位置进行预测后,发射距离不再重要。
3. 目标速度不能太大比如超过10米/秒,导弹会飞出范围。(在 10 米/秒以下,也有概率不能命中)
## 复合制导导弹实验记录v1.1.19
时间2025-05-18 10:00:00
版本v1.1.19
### 合理发射参数(与红外和毫米波一样)
- 发射高度1米
- 发射角度0.2
- 导弹初速度10米/秒
### 合理配置参数
多模制导:
(毫米波)
- MinTimeWithGuidanceBeforeSwitchSeconds0.2秒(因为毫米波跟踪不稳定,不能设置过大)
- MaxTimeToAcquireGuidanceSeconds5秒
- ContinueChainOnFailuretrue
(红外)
- MinTimeWithGuidanceBeforeSwitchSeconds60秒这是最后一个制导的持续时间
- MaxTimeToAcquireGuidanceSeconds5秒
- ContinueChainOnFailurefalse
毫米波制导系统参数:
- SearchBeamWidth5.0度
- TrackBeamWidth2.5度
- LockBeamWidth1.0度
### 实验结果
- 毫米波跟踪不稳定,适当加大搜索和跟踪波束宽度,可以提高跟踪稳定性。
- 将MinTimeWithGuidanceBeforeSwitchSeconds设置为0.2秒,可以稳定切换到红外制导。

View File

@ -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();

View File

@ -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)