From 082bf6ea510a314cf01df3bb1e08ef2a746dedcc Mon Sep 17 00:00:00 2001 From: Tian jianyong <11429339@qq.com> Date: Sun, 18 May 2025 15:29:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=A4=9A=E6=A8=A1=E5=88=B6?= =?UTF-8?q?=E5=AF=BC=E5=AF=BC=E5=BC=B9=EF=BC=8C=E6=94=AF=E6=8C=81=E6=AF=AB?= =?UTF-8?q?=E7=B1=B3=E6=B3=A2/=E7=BA=A2=E5=A4=96=E5=8F=8C=E6=A8=A1?= =?UTF-8?q?=E5=88=B6=E5=AF=BC=EF=BC=8C=E6=8F=90=E4=BE=9B=E4=BA=86=E5=A4=9A?= =?UTF-8?q?=E6=A8=A1=E5=88=B6=E5=AF=BC=E6=A1=86=E6=9E=B6=EF=BC=88=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E5=A2=9E=E5=8A=A0=E7=9B=B8=E5=85=B3=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=B9=B6=E9=AA=8C=E8=AF=81=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 9 +- .../data/missiles/composite/cg_001.toml | 97 ++++ .../laser_warners/lw_001.json | 0 .../src/Data/ThreatSourceDataManager.cs | 87 ++- ThreatSource/src/Data/ThreatSourceFactory.cs | 9 + .../Guidance/InfraredImagingGuidanceSystem.cs | 14 +- .../Guidance/MillimeterWaveGuidanceSystem.cs | 7 +- .../src/MIssile/CompositeGuidedMissile.cs | 504 ++++++++++++++++++ ThreatSource/src/MIssile/MissileProperties.cs | 172 +++++- VERSION | 2 +- docs/project/develop_log.md | 4 + docs/project/tunning.md | 30 ++ tools/ComprehensiveMissileSimulator.cs | 44 +- tools/Program.cs | 5 +- 14 files changed, 950 insertions(+), 34 deletions(-) create mode 100644 ThreatSource/data/missiles/composite/cg_001.toml rename ThreatSource/data/{sensors => warners}/laser_warners/lw_001.json (100%) create mode 100644 ThreatSource/src/MIssile/CompositeGuidedMissile.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index e333935..68866aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/ThreatSource/data/missiles/composite/cg_001.toml b/ThreatSource/data/missiles/composite/cg_001.toml new file mode 100644 index 0000000..5da05e5 --- /dev/null +++ b/ThreatSource/data/missiles/composite/cg_001.toml @@ -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 # 干扰抗性阈值 (瓦特) \ No newline at end of file diff --git a/ThreatSource/data/sensors/laser_warners/lw_001.json b/ThreatSource/data/warners/laser_warners/lw_001.json similarity index 100% rename from ThreatSource/data/sensors/laser_warners/lw_001.json rename to ThreatSource/data/warners/laser_warners/lw_001.json diff --git a/ThreatSource/src/Data/ThreatSourceDataManager.cs b/ThreatSource/src/Data/ThreatSourceDataManager.cs index 16f73ac..ac7c731 100644 --- a/ThreatSource/src/Data/ThreatSourceDataManager.cs +++ b/ThreatSource/src/Data/ThreatSourceDataManager.cs @@ -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(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 } /// - /// 加载传感器数据 + /// 加载告警器数据 /// - 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}"); } } diff --git a/ThreatSource/src/Data/ThreatSourceFactory.cs b/ThreatSource/src/Data/ThreatSourceFactory.cs index 6ad79ef..970b130 100644 --- a/ThreatSource/src/Data/ThreatSourceFactory.cs +++ b/ThreatSource/src/Data/ThreatSourceFactory.cs @@ -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}"); } diff --git a/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs b/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs index d8482c6..c5b08ba 100644 --- a/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/InfraredImagingGuidanceSystem.cs @@ -67,7 +67,7 @@ namespace ThreatSource.Guidance /// 记录目标的历史位置 /// 用于计算目标速度 /// - private Vector3D? lastTargetPosition { get; set; } // Changed to nullable Vector3D? + private Vector3D? LastTargetPosition { get; set; } // Changed to nullable Vector3D? /// /// 红外图像生成器 @@ -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; } diff --git a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs index 8314706..5087a4b 100644 --- a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs +++ b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs @@ -16,7 +16,6 @@ namespace ThreatSource.Guidance /// - 信噪比计算 /// - 抗干扰处理 /// - 比例导引控制 - /// 用于实现全天候制导打击 /// 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); } } diff --git a/ThreatSource/src/MIssile/CompositeGuidedMissile.cs b/ThreatSource/src/MIssile/CompositeGuidedMissile.cs new file mode 100644 index 0000000..ecb7596 --- /dev/null +++ b/ThreatSource/src/MIssile/CompositeGuidedMissile.cs @@ -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 // 末制导阶段 + } + + /// + /// 复合制导导弹类,继承自 BaseMissile + /// + /// + /// 该类实现了复合制导导弹的制导系统管理、状态更新和自毁逻辑 + /// + public class CompositeGuidedMissile : BaseMissile + { + /// + /// 制导系统列表 + /// + protected List guidanceSystems = []; + /// + /// 当前活动制导系统 + /// + protected IGuidanceSystem? currentActiveGuidance; + /// + /// 当前活动制导系统索引 + /// + protected int currentActiveGuidanceIndex = -1; + /// + /// 所有制导阶段是否已尝试 + /// + protected bool allGuidancePhasesAttempted = false; + /// + /// 目标类型 + /// + private readonly EquipmentType targetType; + /// + /// 当前飞行阶段 + /// + private CompositeFlightStage currentFlightStage; + + /// + /// 经过优先级排序的制导组件配置列表。 + /// + private List sortedGuidanceConfigs = new List(); + + /// + /// 经过优先级排序的制导系统实例列表,与 sortedGuidanceConfigs 一一对应。 + /// + private List sortedGuidanceSystems = new List(); + + /// + /// 当前活动的制导组件配置。 + /// + private GuidanceComponentConfig? currentActiveConfig; + + /// + /// sortedGuidanceSystems 列表中当前活动或下一个待激活系统的索引。 + /// 初始化为 -1 表示制导链尚未开始。 + /// + private int currentGuidancePhaseIndex = -1; + + /// + /// 标记整个制导链是否已中止或所有阶段已成功完成。 + /// + private bool guidanceChainHaltedOrCompleted = false; + + /// + /// 当前活动制导阶段开始激活的仿真时间(秒)。 + /// + private double currentPhaseActivationTime = -1.0; + + /// + /// 当前活动制导阶段首次获得稳定制导的仿真时间(秒)。 + /// 用于 MinTimeWithGuidanceBeforeSwitchSeconds 判断。 + /// + private double currentPhaseStableGuidanceTime = -1.0; + + /// + /// 复合制导导弹构造函数 + /// + public CompositeGuidedMissile(string missileId, MissileProperties properties, KinematicState kinematicState, ISimulationManager manager, EquipmentType primaryTargetType) + : base(missileId, properties, kinematicState, manager) + { + targetType = primaryTargetType; + InitializeGuidanceSuite(); + } + + /// + /// 初始化制导系统套件,并按优先级排序。 + /// + 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>(); + + foreach (var componentConfig in Properties.GuidanceSuite) + { + IGuidanceSystem? newGuidanceSystem = CreateGuidanceSystemFromConfig(componentConfig); + if (newGuidanceSystem != null) + { + tempGuidanceList.Add(new Tuple(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}"); + } + + /// + /// 从配置创建制导系统 + /// + 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; + } + } + + /// + /// 更新复合制导逻辑,负责制导系统的激活、切换和状态管理。 + /// + /// 时间步长。 + 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; + } + } + + /// + /// 尝试激活制导链中的下一个制导系统。 + /// + /// 是否应停用当前活动的制导系统(如果存在)。 + 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; // 重置稳定制导计时器 + } + + /// + /// 处理当前活动制导阶段的失败。 + /// + /// 内部错误时是否强制尝试继续 + 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; + } + } + + /// + /// 更新导弹状态 + /// + 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); // 调用基类更新,处理运动学等 + } + + /// + /// 发射导弹,并初始化飞行阶段及制导链状态。 + /// + 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}. 制导链已重置."); + } + + /// + /// 更新发射阶段,基于MaxEngineBurnTime转换到巡航阶段。 + /// + protected virtual void UpdateLaunchStage(double deltaTime) + { + if (FlightTime >= Properties.MaxEngineBurnTime) + { + currentFlightStage = CompositeFlightStage.Cruise; + } + } + + /// + /// 更新巡航阶段,基于CruiseTime转换到末制导阶段。 + /// + protected virtual void UpdateCruiseStage(double deltaTime) + { + if (FlightTime >= Properties.CruiseTime) + { + currentFlightStage = CompositeFlightStage.Terminal; + } + } + + /// + /// 更新末制导阶段,调用UpdateGuidanceMode处理制导逻辑。 + /// + protected virtual void UpdateTerminalStage(double deltaTime) + { + UpdateGuidanceLogic(deltaTime); + } + + /// + /// 停用导弹,并清理制导系统状态。 + /// + 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} 已停用. 活动制导系统已处理."); + } + + /// + /// 获取导弹状态信息,包括复合制导的特定状态。 + /// + 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; + } + } +} \ No newline at end of file diff --git a/ThreatSource/src/MIssile/MissileProperties.cs b/ThreatSource/src/MIssile/MissileProperties.cs index dbac1ec..3979de2 100644 --- a/ThreatSource/src/MIssile/MissileProperties.cs +++ b/ThreatSource/src/MIssile/MissileProperties.cs @@ -1,4 +1,6 @@ using ThreatSource.Simulation; +using System.Collections.Generic; // Required for List +using ThreatSource.Equipment; // 添加此 using 指令以识别 EquipmentType namespace ThreatSource.Missile { @@ -48,7 +50,151 @@ namespace ThreatSource.Missile /// /// 末敏弹子弹 /// - TerminalSensitiveSubmunition + TerminalSensitiveSubmunition, + /// + /// 复合制导导弹,使用 GuidanceSuite 配置。 + /// + CompositeGuidance + } + + /// + /// 定义制导组件激活的触发条件类型 + /// + public enum GuidanceActivationTriggerType + { + /// + /// 在发射时激活 + /// + OnLaunch, + /// + /// 在飞行一段时间后激活 + /// + AfterFlightTime, + /// + /// 在距离目标一定距离时激活 + /// + DistanceToTargetThreshold, + /// + /// 在上一阶段完成时激活 + /// + PreviousStageComplete, + /// + /// 根据命令或逻辑激活 + /// + CommandOrLogic, + /// + /// 手动或备用激活 + /// + ManualOrBackup + } + + /// + /// 定义复合制导中多个制导系统的工作方式 + /// + public enum CompositeWorkType + { + /// + /// 串行工作:任何时候只有一个制导系统处于活动状态并提供指令。 + /// + Serial, + /// + /// 并行工作:多个制导系统可以同时活动,可能需要指令融合。 + /// + Parallel + } + + /// + /// 定义并行工作模式下的指令融合策略 + /// + public enum CommandFusionStrategy + { + /// + /// 使用当前活动且优先级最高的制导系统的指令。 + /// + UseHighestPriority, + /// + /// (未来扩展) 加权平均融合来自多个活动制导系统的指令。 + /// + WeightedAverage, + /// + /// (未来扩展) 使用自定义的融合逻辑。 + /// + CustomLogic + } + + /// + /// 单个制导组件的配置 + /// + public class GuidanceComponentConfig + { + /// + /// 制导组件名称 + /// + public string ComponentName { get; set; } = "DefaultGuidanceComponent"; + /// + /// 制导系统类型 + /// + public string GuidanceSystemType { get; set; } = "Inertial"; + /// + /// 特定配置 + /// + public object? SpecificConfig { get; set; } + /// + /// 激活触发类型 + /// + public GuidanceActivationTriggerType ActivationTrigger { get; set; } = GuidanceActivationTriggerType.OnLaunch; + /// + /// 激活值 + /// + public double ActivationValue { get; set; } = 0; + /// + /// 优先级,用于决定串行模式下的执行顺序。数值越小,优先级越高。 + /// + public int Priority { get; set; } = 0; + + /// + /// (可选) 从激活开始,允许该模块尝试获取有效制导(HasGuidance == true)的最大时间(秒)。 + /// 设为0或负数表示不使用此超时。 + /// + public double MaxTimeToAcquireGuidanceSeconds { get; set; } = 5.0; + + /// + /// (可选) 当获得稳定制导(HasGuidance == true)后,在切换到下一阶段之前需要保持制导的最短持续时间(秒)。 + /// 默认为0表示一旦获得制导即满足切换条件(如果其他条件也满足)。 + /// + public double MinTimeWithGuidanceBeforeSwitchSeconds { get; set; } = 0.0; + + /// + /// (可选) 如果此制导阶段失败(例如超时、受干扰等),是否继续尝试激活序列中的下一个制导系统。 + /// 默认为 true。 + /// + public bool ContinueChainOnFailure { get; set; } = true; + + /// + /// 默认构造函数 + /// + public GuidanceComponentConfig() { } + + /// + /// 带参数的构造函数 + /// + 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; + } } /// @@ -201,6 +347,24 @@ namespace ThreatSource.Missile /// public double CruiseTime { get; set; } + /// + /// 制导组件套件。仅当 Type 为 CompositeGuidance 时有效。 + /// 列表中的顺序可能也暗示了串行模式下的默认阶段顺序,除非 ActivationTrigger 另有复杂规定,并结合Priority。 + /// + public List GuidanceSuite { get; set; } + + /// + /// 复合制导模式下,多个制导系统的工作方式。默认为串行。 + /// 仅当 Type 为 CompositeGuidance 时有效。 + /// + public CompositeWorkType CompositeWorkMode { get; set; } = CompositeWorkType.Serial; + + /// + /// 并行工作模式下的指令融合策略。默认为使用最高优先级的指令。 + /// 仅当 Type 为 CompositeGuidance 且 CompositeWorkMode 为 Parallel 时有效。 + /// + public CommandFusionStrategy FusionStrategy { get; set; } = CommandFusionStrategy.UseHighestPriority; + /// /// 初始化导弹配置类的新实例 /// @@ -215,6 +379,7 @@ namespace ThreatSource.Missile SetDefaultValues(); Type = MissileType.StandardMissile; LaserCodeConfig = new LaserCodeConfig(); + GuidanceSuite = []; } /// @@ -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(); } } } \ No newline at end of file diff --git a/VERSION b/VERSION index b0c8928..3a21f22 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.18 \ No newline at end of file +1.1.19 \ No newline at end of file diff --git a/docs/project/develop_log.md b/docs/project/develop_log.md index 6b1ce8b..91e30eb 100644 --- a/docs/project/develop_log.md +++ b/docs/project/develop_log.md @@ -7,6 +7,10 @@ - 事件描述 - 分析处理 +## 2025-05-18 增加了装备的RCS特征矩阵 +- 增加了装备的RCS特征矩阵 +- 在毫米波末制导中,用RCS特征矩阵取值 + ## 2025-05-15 完善了末敏弹的发射角度计算逻辑 - 完善了末敏弹的发射角度计算逻辑,增加目标速度、空气阻力的影响 - 完善了末敏子弹各阶段的控制参数 diff --git a/docs/project/tunning.md b/docs/project/tunning.md index 2857f94..b99efd2 100644 --- a/docs/project/tunning.md +++ b/docs/project/tunning.md @@ -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秒,可以稳定切换到红外制导。 diff --git a/tools/ComprehensiveMissileSimulator.cs b/tools/ComprehensiveMissileSimulator.cs index 70258c1..6449c3c 100644 --- a/tools/ComprehensiveMissileSimulator.cs +++ b/tools/ComprehensiveMissileSimulator.cs @@ -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", "遮蔽", "导弹") + ]; } /// @@ -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}"); } + /// + /// 添加复合制导导弹 + /// + 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}"); + } + /// /// 添加传感器和指示器 /// @@ -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(); diff --git a/tools/Program.cs b/tools/Program.cs index cb38777..0552a81 100644 --- a/tools/Program.cs +++ b/tools/Program.cs @@ -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)