From 0d46538d151e11e82043fbe52333e3443d7e36ee Mon Sep 17 00:00:00 2001
From: Tian jianyong <11429339@qq.com>
Date: Sun, 25 May 2025 17:12:08 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E9=9B=86=E6=88=90?=
=?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=9A=84=E8=8F=9C=E5=8D=95=E9=80=BB=E8=BE=91?=
=?UTF-8?q?=EF=BC=8C=E5=8F=AF=E4=BB=A5=E5=8F=8D=E5=A4=8D=E8=BF=90=E8=A1=8C?=
=?UTF-8?q?=E4=BA=86=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../LaserBeamRiderGuidanceJammingTests.cs | 2 +-
.../Guidance/LaserBeamRiderGuidanceSystem.cs | 8 +-
.../Guidance/LaserSemiActiveGuidanceSystem.cs | 14 +-
.../Guidance/MillimeterWaveGuidanceSystem.cs | 2 +-
ThreatSource/src/Indicator/BaseIndicator.cs | 40 +-
ThreatSource/src/Indicator/InfraredTracker.cs | 6 +-
ThreatSource/src/Indicator/LaserBeamRider.cs | 4 +-
ThreatSource/src/Indicator/LaserDesignator.cs | 6 +-
.../MIssile/TerminalSensitiveSubmunition.cs | 8 +-
ThreatSource/src/Sensor/QuadrantDetector.cs | 8 +-
.../src/Simulation/ISimulationManager.cs | 9 +
.../src/Simulation/SimulationManager.cs | 19 +-
tools/ComprehensiveMissileSimulator.cs | 459 ++++++++++++++----
13 files changed, 430 insertions(+), 155 deletions(-)
diff --git a/ThreatSource.Tests/src/Jamming/LaserBeamRiderGuidanceJammingTests.cs b/ThreatSource.Tests/src/Jamming/LaserBeamRiderGuidanceJammingTests.cs
index 890c1e6..02e7168 100644
--- a/ThreatSource.Tests/src/Jamming/LaserBeamRiderGuidanceJammingTests.cs
+++ b/ThreatSource.Tests/src/Jamming/LaserBeamRiderGuidanceJammingTests.cs
@@ -142,7 +142,7 @@ namespace ThreatSource.Tests.Jamming
Assert.IsNotNull(_guidanceSystem, "激光驾束引导系统不应为空");
Assert.IsNotNull(_missile, "导弹不应为空");
- System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {_missile.KState.Position}, 初始速度: {_missile.KState.Speed}");
+ System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {_missile.KState.Position}, 初始速度: {_missile.KState.Speed:F2}m/s");
// 更新激光波束参数
_guidanceSystem.UpdateLaserBeamRider(
diff --git a/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs b/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs
index 39dca9b..f589cdb 100644
--- a/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs
+++ b/ThreatSource/src/Guidance/LaserBeamRiderGuidanceSystem.cs
@@ -396,17 +396,17 @@ namespace ThreatSource.Guidance
if (shortestDistance > config.ControlFieldDiameter / 2)
{
HasGuidance = false;
- Trace.TraceInformation($"激光驾束引导系统: 失去引导, 原因: 超出控制场范围, 距离: {shortestDistance}");
+ Trace.TraceInformation($"激光驾束引导系统: 失去引导, 原因: 超出控制场范围, 距离: {shortestDistance:F2}m");
return;
}
- Debug.WriteLine($"激光驾束引导系统: 在控制场内, 距离: {shortestDistance}");
+ Debug.WriteLine($"激光驾束引导系统: 在控制场内, 距离中心点: {shortestDistance:F2}m");
Vector3D missileToSource = LaserSourcePosition.Value - KState.Position;
double distance = missileToSource.Magnitude();
double receivedPower = CalculateReceivedLaserPower(distance);
- Debug.WriteLine($"激光驾束引导系统: 接收到的激光功率: {receivedPower:E} W");
+ Debug.WriteLine($"激光驾束引导系统: 接收到的激光功率: {receivedPower:E2} W");
if(receivedPower >= config.MinDetectablePower)
{
@@ -415,7 +415,7 @@ namespace ThreatSource.Guidance
else
{
HasGuidance = false;
- Trace.TraceInformation($"激光驾束引导系统: 失去引导, 原因: 接收到的激光功率低于最小可探测功率,{LaserPower:E} W/{receivedPower:E} W");
+ Trace.TraceInformation($"激光驾束引导系统: 失去引导, 原因: 接收到的激光功率低于最小可探测功率,{LaserPower:E2} W/{receivedPower:E2} W");
}
}
diff --git a/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs b/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs
index 5ad2070..9164adb 100644
--- a/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs
+++ b/ThreatSource/src/Guidance/LaserSemiActiveGuidanceSystem.cs
@@ -440,13 +440,13 @@ namespace ThreatSource.Guidance
{
// 计算接收功率
receivedPower = CalculateReceivedPower(target.Source.KState.Position, target.SpotPosition, decoy.config.Power, decoy.config.DivergenceAngle);
- Debug.WriteLine($"处理激光信号: 诱偏目标接收功率={receivedPower:E}W, 诱偏目标ID: {target.Target.Id}, 诱偏目标位置: {target.SpotPosition}");
+ Debug.WriteLine($"处理激光信号: 诱偏目标接收功率={receivedPower:E2}W, 诱偏目标ID: {target.Target.Id}, 诱偏目标位置: {target.SpotPosition}");
}
else if (target.Source is LaserDesignator laserDesignator)
{
// 计算接收功率
receivedPower = CalculateReceivedPower(target.Source.KState.Position, target.SpotPosition, laserDesignator.config.Power, laserDesignator.config.DivergenceAngle);
- Debug.WriteLine($"处理激光信号: 真实目标接收功率={receivedPower:E}W, 真实目标ID: {target.Target.Id}, 真实目标位置: {target.SpotPosition}");
+ Debug.WriteLine($"处理激光信号: 真实目标接收功率={receivedPower:E2}W, 真实目标ID: {target.Target.Id}, 真实目标位置: {target.SpotPosition}");
}
// 累加功率
@@ -454,7 +454,7 @@ namespace ThreatSource.Guidance
// 加权位置
weightedPosition += target.SpotPosition * receivedPower;
- Debug.WriteLine($"处理激光信号: 累加功率={ReceivedLaserPower:E}W, 加权位置={weightedPosition}");
+ Debug.WriteLine($"处理激光信号: 累加功率={ReceivedLaserPower:E2}W, 加权位置={weightedPosition}");
}
// 如果总功率为0,表示没有在视野范围内的激光源
@@ -467,7 +467,7 @@ namespace ThreatSource.Guidance
// 计算加权平均位置
TargetPosition = weightedPosition / ReceivedLaserPower;
- Debug.WriteLine($"处理激光信号: 总功率={ReceivedLaserPower:E}W, 加权平均目标位置={TargetPosition}");
+ Debug.WriteLine($"处理激光信号: 总功率={ReceivedLaserPower:E2}W, 加权平均目标位置={TargetPosition}");
// 更新激光照射参数
LaserIlluminationOn = true;
@@ -534,9 +534,9 @@ namespace ThreatSource.Guidance
double lensArea = Math.PI * Math.Pow(config.LensDiameter / 2, 2);
double finalReceivedPower = powerDensityAtMissileAperture * lensArea * config.ReceiverEfficiency;
- Debug.WriteLine($"激光功率计算: S2T D={distanceSourceToTarget:F1}m (Path1 T={totalTransmittance_S2T:F3}), " +
- $"T2M D={distanceTargetToMissile:F1}m (Path2 T={totalTransmittance_T2M:F3}), " +
- $"最终功率={finalReceivedPower:E}W");
+ Debug.WriteLine($"激光功率计算: 源到目标距离={distanceSourceToTarget:F1}m (路径1 透过率={totalTransmittance_S2T:F3}), " +
+ $"目标到导弹距离={distanceTargetToMissile:F1}m (路径2 透过率={totalTransmittance_T2M:F3}), " +
+ $"最终功率={finalReceivedPower:E2}W");
return finalReceivedPower;
}
diff --git a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs
index 2c55972..7626ccb 100644
--- a/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs
+++ b/ThreatSource/src/Guidance/MillimeterWaveGuidanceSystem.cs
@@ -685,7 +685,7 @@ namespace ThreatSource.Guidance
rcsLinear = swerlingRcsModel.GetRealtimeRcs(target.Id, target.Properties.Type, motionState, rcsLinear, isNewScanPeriodForRcs);
double rcsDbSmAfterSwerling = 10.0 * Math.Log10(rcsLinear);
double rcsVariationDb = rcsDbSmAfterSwerling - rcsDbSm;
- Debug.WriteLine($"[MMW_GUIDANCE] 目标 {target.Id}: Swerling后RCS: {rcsDbSmAfterSwerling:F2} dBsm ({rcsLinear:F4} m²), 波动: {rcsVariationDb:+F2} dB.");
+ Debug.WriteLine($"[MMW_GUIDANCE] 目标 {target.Id}: Swerling后RCS: {rcsDbSmAfterSwerling:F2} dBsm ({rcsLinear:F4} m²), 波动: {rcsVariationDb:F2} dB.");
double localSnrDb = CalculateSNR(distance, rcsLinear, liveSmokeTransmittance);
switch (currentMode)
diff --git a/ThreatSource/src/Indicator/BaseIndicator.cs b/ThreatSource/src/Indicator/BaseIndicator.cs
index 86373ff..166ba37 100644
--- a/ThreatSource/src/Indicator/BaseIndicator.cs
+++ b/ThreatSource/src/Indicator/BaseIndicator.cs
@@ -27,7 +27,7 @@ namespace ThreatSource.Indicator
///
/// 干扰处理组件
///
- protected readonly JammableComponent _jammingComponent;
+ protected readonly JammableComponent JammingComponent;
///
/// 获取目标是否被烟幕遮挡 (由任何烟幕引起)
@@ -37,12 +37,12 @@ namespace ThreatSource.Indicator
///
/// 最后一次成功获取的目标位置
///
- protected Vector3D? _lastKnownTargetPosition = null;
+ protected Vector3D? LastKnownTargetPosition = null;
///
/// 最后一次成功获取的目标朝向
///
- protected Orientation? _lastKnownTargetOrientation = null;
+ protected Orientation? LastKnownTargetOrientation = null;
///
/// 获取设备支持的干扰类型
@@ -65,12 +65,12 @@ namespace ThreatSource.Indicator
/// true表示指示器当前受到干扰影响
/// false表示指示器正常工作
///
- public bool IsJammed => _jammingComponent.IsJammed;
+ public bool IsJammed => JammingComponent.IsJammed;
///
/// 获取设备当前是否正受到有效的阻塞式干扰
///
- public bool IsBlockingJammed => _jammingComponent.IsBlockingJammed;
+ public bool IsBlockingJammed => JammingComponent.IsBlockingJammed;
///
/// 获取或设置目标ID
@@ -97,12 +97,12 @@ namespace ThreatSource.Indicator
protected BaseIndicator(string id, KinematicState motionParameters, ISimulationManager manager)
: base(id, motionParameters, manager)
{
- _jammingComponent = new JammableComponent(
+ JammingComponent = new JammableComponent(
positionProvider: () => base.KState.Position
);
- _jammingComponent.JammingApplied += HandleJammingApplied;
- _jammingComponent.JammingCleared += HandleJammingCleared;
+ JammingComponent.JammingApplied += HandleJammingApplied;
+ JammingComponent.JammingCleared += HandleJammingCleared;
}
///
@@ -119,10 +119,10 @@ namespace ThreatSource.Indicator
///
protected void InitializeJamming(double jammingResistanceThreshold, IEnumerable supportedTypes, IEnumerable supportedBlockingTypes)
{
- _jammingComponent.LoadJammingConfigFromThreshold(jammingResistanceThreshold, supportedBlockingTypes);
+ JammingComponent.LoadJammingConfigFromThreshold(jammingResistanceThreshold, supportedBlockingTypes);
foreach (var type in supportedTypes)
{
- _jammingComponent.AddSupportedJammingType(type);
+ JammingComponent.AddSupportedJammingType(type);
}
}
@@ -136,7 +136,7 @@ namespace ThreatSource.Indicator
///
public virtual void ApplyJamming(JammingParameters parameters)
{
- _jammingComponent.ApplyJamming(parameters);
+ JammingComponent.ApplyJamming(parameters);
}
///
@@ -149,7 +149,7 @@ namespace ThreatSource.Indicator
///
public virtual void ClearJamming(JammingParameters parameters)
{
- _jammingComponent.ClearJamming(parameters);
+ JammingComponent.ClearJamming(parameters);
}
///
@@ -197,8 +197,8 @@ namespace ThreatSource.Indicator
}
IsTargetObscured = false;
// 重置最后目标状态
- _lastKnownTargetPosition = null;
- _lastKnownTargetOrientation = null;
+ LastKnownTargetPosition = null;
+ LastKnownTargetOrientation = null;
base.Deactivate();
}
@@ -207,7 +207,7 @@ namespace ThreatSource.Indicator
///
public override void Update(double deltaTime)
{
- _jammingComponent.UpdateJammingStatus(deltaTime);
+ JammingComponent.UpdateJammingStatus(deltaTime);
if (IsActive)
{
@@ -254,8 +254,8 @@ namespace ThreatSource.Indicator
// 仅当目标被看到 (未遮挡) 且目标有效时,才更新最后已知状态
if (!currentlyObscured && currentTarget != null)
{
- _lastKnownTargetPosition = currentTarget.KState.Position;
- _lastKnownTargetOrientation = currentTarget.KState.Orientation;
+ LastKnownTargetPosition = currentTarget.KState.Position;
+ LastKnownTargetOrientation = currentTarget.KState.Orientation;
}
}
@@ -282,7 +282,7 @@ namespace ThreatSource.Indicator
}
// 3. 获取活动的烟幕
- var activeJammerIds = _jammingComponent.GetActiveJammerIdsOfType(JammingType.SmokeGrenade);
+ var activeJammerIds = JammingComponent.GetActiveJammerIdsOfType(JammingType.SmokeGrenade);
if (!activeJammerIds.Any())
{
return false; // 没有活动的烟幕,视为未遮挡
@@ -404,8 +404,8 @@ namespace ThreatSource.Indicator
// 添加指示器特有属性
statusInfo.ExtendedProperties["TargetId"] = TargetId ?? "";
statusInfo.ExtendedProperties["MissileId"] = MissileId ?? "";
- statusInfo.ExtendedProperties["lastKnownTargetPosition"] = _lastKnownTargetPosition ?? Vector3D.Zero;
- statusInfo.ExtendedProperties["lastKnownTargetOrientation"] = _lastKnownTargetOrientation ?? new Orientation(0, 0, 0);
+ statusInfo.ExtendedProperties["lastKnownTargetPosition"] = LastKnownTargetPosition ?? Vector3D.Zero;
+ statusInfo.ExtendedProperties["lastKnownTargetOrientation"] = LastKnownTargetOrientation ?? new Orientation(0, 0, 0);
statusInfo.ExtendedProperties["IsTargetObscured"] = IsTargetObscured;
statusInfo.ExtendedProperties["IsJammed"] = IsJammed;
statusInfo.ExtendedProperties["IsBlockingJammed"] = IsBlockingJammed;
diff --git a/ThreatSource/src/Indicator/InfraredTracker.cs b/ThreatSource/src/Indicator/InfraredTracker.cs
index 4613578..588331c 100644
--- a/ThreatSource/src/Indicator/InfraredTracker.cs
+++ b/ThreatSource/src/Indicator/InfraredTracker.cs
@@ -128,9 +128,9 @@ namespace ThreatSource.Indicator
if (IsTargetObscured)
{
// 目标被遮挡,尝试使用最后已知位置
- if (_lastKnownTargetPosition != null)
+ if (LastKnownTargetPosition != null)
{
- currentTargetPosition = _lastKnownTargetPosition.Value;
+ currentTargetPosition = LastKnownTargetPosition.Value;
Debug.WriteLine($"红外测角仪 {Id}: 目标被遮挡,使用最后已知位置 {currentTargetPosition}");
}
else
@@ -157,7 +157,7 @@ namespace ThreatSource.Indicator
return;
}
currentTargetPosition = targetElement.KState.Position;
- _lastKnownTargetPosition = currentTargetPosition; // 记录最后已知的目标位置
+ LastKnownTargetPosition = currentTargetPosition; // 记录最后已知的目标位置
}
IsTracking = true;
diff --git a/ThreatSource/src/Indicator/LaserBeamRider.cs b/ThreatSource/src/Indicator/LaserBeamRider.cs
index a3d8b1a..d3e0c40 100644
--- a/ThreatSource/src/Indicator/LaserBeamRider.cs
+++ b/ThreatSource/src/Indicator/LaserBeamRider.cs
@@ -138,7 +138,7 @@ namespace ThreatSource.Indicator
{
LaserDirection = newDirection;
Debug.WriteLine($"激光驾束仪 {Id} 更新激光指向: {LaserDirection}");
- _lastKnownTargetPosition = targetPosition; // 记录最后已知的目标位置
+ LastKnownTargetPosition = targetPosition; // 记录最后已知的目标位置
PublishLaserBeamEvent();
}
}
@@ -188,7 +188,7 @@ namespace ThreatSource.Indicator
StopBeamIllumination();
}
Debug.WriteLine($"激光驾束仪 {Id} 已停用");
- base.Deactivate(); // Handles IsActive and unsubscribes HandleJammingEvent
+ base.Deactivate();
}
}
diff --git a/ThreatSource/src/Indicator/LaserDesignator.cs b/ThreatSource/src/Indicator/LaserDesignator.cs
index de04307..cdd6788 100644
--- a/ThreatSource/src/Indicator/LaserDesignator.cs
+++ b/ThreatSource/src/Indicator/LaserDesignator.cs
@@ -129,9 +129,9 @@ namespace ThreatSource.Indicator
double yaw = Math.PI + Math.Atan2(direction.Z, direction.X);
double pitch = -Math.Asin(direction.Y);
KState.Orientation = new Orientation(yaw, pitch, 0);
- _lastKnownTargetPosition = target.KState.Position;
+ LastKnownTargetPosition = target.KState.Position;
- Debug.WriteLine($"激光指示器 {Id} 更新朝向: {KState.Orientation}, _lastKnownTargetPosition: {_lastKnownTargetPosition}");
+ Debug.WriteLine($"激光指示器 {Id} 更新朝向: {KState.Orientation}, 最后已知目标位置: {LastKnownTargetPosition}");
}
}
}
@@ -283,7 +283,7 @@ namespace ThreatSource.Indicator
{
LaserDesignatorId = Id,
TargetId = TargetId,
- SpotPosition = _lastKnownTargetPosition,
+ SpotPosition = LastKnownTargetPosition,
LaserCodeConfig = config.LaserCodeConfig
});
}
diff --git a/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs b/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs
index d17bbc6..887ce21 100644
--- a/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs
+++ b/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs
@@ -669,10 +669,10 @@ namespace ThreatSource.Missile
public override string GetStatus()
{
return base.GetStatus()
- + $"\n激光测距仪状态: {rangefinder.GetStatus()}"
- + $"\n红外探测器状态: {infraredDetector.GetStatus()}"
- + $"\n毫米波辐射计状态: {radiometer.GetStatus()}"
- + $"\n测高仪状态: {altimeter.GetStatus()}";
+ + $"\n激光测距仪: {rangefinder.GetStatus()}"
+ + $"\n红外探测器: {infraredDetector.GetStatus()}"
+ + $"\n毫米波辐射计: {radiometer.GetStatus()}"
+ + $"\n测高仪: {altimeter.GetStatus()}";
}
///
diff --git a/ThreatSource/src/Sensor/QuadrantDetector.cs b/ThreatSource/src/Sensor/QuadrantDetector.cs
index a46679c..98f2bb9 100644
--- a/ThreatSource/src/Sensor/QuadrantDetector.cs
+++ b/ThreatSource/src/Sensor/QuadrantDetector.cs
@@ -303,7 +303,7 @@ namespace ThreatSource.Sensor
VerticalError = filteredVerticalError;
// 增强调试输出,同时显示水平和垂直误差
- Debug.WriteLine($"原始误差: 水平={rawHorizontalError:F6}, 垂直={rawVerticalError:F6}, 滤波后: 水平={HorizontalError:F6}, 垂直={VerticalError:F6}");
+ Debug.WriteLine($"原始误差: 水平={rawHorizontalError:E2}, 垂直={rawVerticalError:E2}, 滤波后: 水平={HorizontalError:E2}, 垂直={VerticalError:E2}");
}
else
{
@@ -365,9 +365,9 @@ namespace ThreatSource.Sensor
///
public string GetStatus()
{
- return $"锁定={IsTargetLocked}, 总功率={TotalReceivedPower:E} W, 最小可探测功率={MinDetectablePower:E} W," +
- $" 水平误差={HorizontalError:F4}, 垂直误差={VerticalError:F4}," +
- $" 象限信号=[{quadrantSignals[0]:E}, {quadrantSignals[1]:E}, {quadrantSignals[2]:E}, {quadrantSignals[3]:E}]";
+ return $"锁定={IsTargetLocked}, 总功率={TotalReceivedPower:E2} W, 最小可探测功率={MinDetectablePower:E2} W," +
+ $" 水平误差={HorizontalError:E2}, 垂直误差={VerticalError:E2}," +
+ $" 象限信号=[{quadrantSignals[0]:E2}, {quadrantSignals[1]:E2}, {quadrantSignals[2]:E2}, {quadrantSignals[3]:E2}]";
}
}
}
\ No newline at end of file
diff --git a/ThreatSource/src/Simulation/ISimulationManager.cs b/ThreatSource/src/Simulation/ISimulationManager.cs
index 6d07e02..67ad7c5 100644
--- a/ThreatSource/src/Simulation/ISimulationManager.cs
+++ b/ThreatSource/src/Simulation/ISimulationManager.cs
@@ -179,6 +179,15 @@ namespace ThreatSource.Simulation
/// 事件类型
/// 要取消的事件处理函数
void UnsubscribeFromEvent(Action handler);
+
+ ///
+ /// 清理所有事件处理器和待处理事件
+ ///
+ ///
+ /// 用于导弹切换或仿真重置时清理事件系统状态
+ /// 防止事件残留影响新的制导系统
+ ///
+ void ClearAllEvents();
#endregion
#region 实体管理
diff --git a/ThreatSource/src/Simulation/SimulationManager.cs b/ThreatSource/src/Simulation/SimulationManager.cs
index 74386e4..6aeba71 100644
--- a/ThreatSource/src/Simulation/SimulationManager.cs
+++ b/ThreatSource/src/Simulation/SimulationManager.cs
@@ -186,7 +186,7 @@ namespace ThreatSource.Simulation
foreach (var target in activeTargets)
{
double distance = Vector3D.Distance(missile.KState.Position, target.KState.Position);
- Debug.WriteLine($"导弹 {missile.Id} 和目标 {target.Id} 之间的距离: {distance:F2}");
+ Debug.WriteLine($"导弹 {missile.Id} 和目标 {target.Id} 之间的距离: {distance:F2}m");
if (distance <= missile.Properties.ExplosionRadius)
{
double damage = CalculateMissileDamage(missile);
@@ -365,6 +365,23 @@ namespace ThreatSource.Simulation
}
}
}
+
+ ///
+ /// 清理所有事件处理器和待处理事件
+ ///
+ ///
+ /// 用于导弹切换或仿真重置时清理事件系统状态
+ /// 防止事件残留影响新的制导系统
+ ///
+ public void ClearAllEvents()
+ {
+ Debug.WriteLine("[事件] 清理所有事件处理器和待处理事件");
+
+ // 清理所有事件处理器
+ eventHandlers.Clear();
+
+ Debug.WriteLine("[事件] 事件系统已完全清理");
+ }
#endregion
#region 实体管理
diff --git a/tools/ComprehensiveMissileSimulator.cs b/tools/ComprehensiveMissileSimulator.cs
index 8b67d5c..316d040 100644
--- a/tools/ComprehensiveMissileSimulator.cs
+++ b/tools/ComprehensiveMissileSimulator.cs
@@ -96,8 +96,6 @@ namespace ThreatSource.Tools.MissileSimulation
// 初始化导弹-干扰映射
InitializeMissileJammingMap();
-
- InitializeSimulation();
}
public SourceLevels CurrentLogLevel => logLevelFilter?.EventType ?? SourceLevels.Off;
@@ -245,11 +243,14 @@ namespace ThreatSource.Tools.MissileSimulation
Orientation = new Orientation(0.0, 0.0, 0.0),
Speed = 2.0
};
+
string targetId = "Tank_1";
var target = _threatSourceFactory.CreateEquipment(targetId, "mbt_001", motionParameters);
targets[targetId] = target;
simulationManager.RegisterEntity(targetId, target);
+ target.Activate(); // 激活目标
Console.WriteLine($"添加目标 {targetId},位置:{motionParameters.Position}");
+ Console.WriteLine($"目标创建后实际位置:{target.KState.Position}");
}
///
@@ -337,11 +338,13 @@ namespace ThreatSource.Tools.MissileSimulation
Orientation = new Orientation(Math.PI/2, Math.PI/20, 0),
Speed = 700
};
+
string missileId = "LSGM_1";
+
var missile = _threatSourceFactory.CreateMissile(missileId, "lsgm_001", "Tank_1", motionParameters);
missiles[missileId] = missile;
simulationManager.RegisterEntity(missileId, missile);
- Console.WriteLine($"注册激光半主动制导导弹 {missileId}");
+ Console.WriteLine($"注册激光半主动制导导弹 {missileId},初始位置:{motionParameters.Position}");
}
///
@@ -355,11 +358,13 @@ namespace ThreatSource.Tools.MissileSimulation
Orientation = new Orientation(Math.PI/2, 0.04, 0.0),
Speed = 10
};
+
string missileId = "LBRM_1";
+
var missile = _threatSourceFactory.CreateMissile(missileId, "hj10", "Tank_1", motionParameters);
missiles[missileId] = missile;
simulationManager.RegisterEntity(missileId, missile);
- Console.WriteLine($"注册激光驾束制导导弹 {missileId}");
+ Console.WriteLine($"注册激光驾束制导导弹 {missileId},初始位置:{motionParameters.Position}");
}
///
@@ -375,11 +380,11 @@ namespace ThreatSource.Tools.MissileSimulation
};
string missileId = "TSM_1";
+
var missile = _threatSourceFactory.CreateMissile(missileId, "tsm_001", "Tank_1", motionParameters);
-
missiles[missileId] = missile;
simulationManager.RegisterEntity(missileId, missile);
- Console.WriteLine($"注册末敏弹 {missileId}");
+ Console.WriteLine($"注册末敏弹 {missileId},初始位置:{motionParameters.Position}");
}
///
@@ -395,10 +400,11 @@ namespace ThreatSource.Tools.MissileSimulation
};
string missileId = "ICGM_1";
+
var missile = _threatSourceFactory.CreateMissile(missileId, "irc_001", "Tank_1", motionParameters);
missiles[missileId] = missile;
simulationManager.RegisterEntity(missileId, missile);
- Console.WriteLine($"注册红外指令制导导弹 {missileId}");
+ Console.WriteLine($"注册红外指令制导导弹 {missileId},初始位置:{motionParameters.Position}");
}
///
@@ -412,11 +418,13 @@ namespace ThreatSource.Tools.MissileSimulation
Orientation = new Orientation(Math.PI/2, 0.12, 0),
Speed = 10
};
+
string missileId = "ITGM_1";
+
var missile = _threatSourceFactory.CreateMissile(missileId, "itg_001", "Tank_1", motionParameters);
missiles[missileId] = missile;
simulationManager.RegisterEntity(missileId, missile);
- Console.WriteLine($"注册红外成像末制导导弹 {missileId}");
+ Console.WriteLine($"注册红外成像末制导导弹 {missileId},初始位置:{motionParameters.Position}");
}
///
@@ -430,11 +438,13 @@ namespace ThreatSource.Tools.MissileSimulation
Orientation = new Orientation(Math.PI/2, 0.05, 0),
Speed = 10
};
+
string missileId = "MMWG_1";
+
var missile = _threatSourceFactory.CreateMissile(missileId, "mmw_001", "Tank_1", motionParameters);
missiles[missileId] = missile;
simulationManager.RegisterEntity(missileId, missile);
- Console.WriteLine($"注册毫米波末制导导弹 {missileId}");
+ Console.WriteLine($"注册毫米波末制导导弹 {missileId},初始位置:{motionParameters.Position}");
}
///
@@ -449,10 +459,11 @@ namespace ThreatSource.Tools.MissileSimulation
Orientation = new Orientation(Math.PI/2, 0.05, 0),
Speed = 10
};
+
var missile = _threatSourceFactory.CreateMissile(missileId, "cg_001", "Tank_1", motionParameters);
missiles[missileId] = missile;
simulationManager.RegisterEntity(missileId, missile);
- Console.WriteLine($"注册毫米波/红外复合制导导弹 {missileId}");
+ Console.WriteLine($"注册毫米波/红外复合制导导弹 {missileId},初始位置:{motionParameters.Position}");
missileId = "CGGM_2";
motionParameters = new KinematicState
@@ -461,10 +472,11 @@ namespace ThreatSource.Tools.MissileSimulation
Orientation = new Orientation(Math.PI/2, 0.05, 0),
Speed = 10
};
+
missile = _threatSourceFactory.CreateMissile(missileId, "cg_002", "Tank_1", motionParameters);
missiles[missileId] = missile;
simulationManager.RegisterEntity(missileId, missile);
- Console.WriteLine($"注册激光/红外复合制导导弹 {missileId}");
+ Console.WriteLine($"注册激光/红外复合制导导弹 {missileId},初始位置:{motionParameters.Position}");
}
///
@@ -668,56 +680,27 @@ namespace ThreatSource.Tools.MissileSimulation
private Orientation CalculateOrientationToEntity(SimulationElement target)
{
// 使用CalculateDirectionToTarget获取归一化方向向量
- Vector3D direction = CalculateDirectionToTarget(new Vector3D(0, 0, 0), target.KState.Position);
+ Vector3D direction = target.KState.Position - new Vector3D(0, 0, 0);
// 创建朝向目标的方向
- return Orientation.FromVector(direction);
+ return Orientation.FromVector(direction.Normalize());
}
///
- /// 选择要激活的导弹
+ /// 选择导弹
///
+ /// 导弹ID
public void SelectMissile(string missileId)
{
- if (!missiles.ContainsKey(missileId))
- {
- Console.WriteLine($"错误:找不到导弹 {missileId}");
- return;
- }
-
- // 先停用所有导弹、传感器、干扰器
- foreach (var id in missiles.Keys)
- {
- missileActiveStatus[id] = false;
- missiles[id].Deactivate();
- }
- foreach (var indicator in indicators.Values)
- {
- indicator.Deactivate();
- }
- foreach (var jammer in jammers.Values)
- {
- jammer.Deactivate();
- }
-
- // 激活选中的导弹
- missileActiveStatus[missileId] = true;
- missiles[missileId].Activate();
- SelectedMissileId = missileId;
- Console.WriteLine($"已选择导弹:{missileId} ({SelectedMissileDisplayName})");
-
- // 确保所有目标都处于激活状态
- foreach (var target in targets.Values)
- {
- target.Activate();
- Console.WriteLine($"确保目标 {target.Id} 处于激活状态");
- }
-
- // 激活相关的传感器和指示器
- ActivateRelatedIndicators(missileId);
-
- // 打印所有注册的组件
- PrintSimulationRegisteredComponents();
+ Console.WriteLine($"=== 选择导弹: {missileId} ===");
+
+ // 新架构:完全销毁所有现有实体
+ DestroyAllEntities();
+
+ // 重新创建选中的导弹及其相关实体
+ CreateMissileAndRelatedEntities(missileId);
+
+ Console.WriteLine($"=== 导弹选择完成: {missileId} ===");
}
///
@@ -1085,12 +1068,25 @@ namespace ThreatSource.Tools.MissileSimulation
{
Console.WriteLine("开始综合导弹模拟...");
- // 确保所有激活的导弹和传感器都处于正确状态
- foreach (var missile in missiles.Values)
+ // 使用新架构:销毁重建模式,确保每次都是全新的实体和位置
+ if (missiles.Count > 0 || targets.Count > 0)
{
- if (missileActiveStatus[missile.Id])
+ Console.WriteLine("检测到现有实体,销毁并重新创建...");
+
+ // 保存当前选中的导弹ID,避免在销毁时被清空
+ string currentSelectedMissileId = SelectedMissileId;
+
+ DestroyAllEntities();
+
+ // 重新创建选中的导弹及其相关实体
+ if (!string.IsNullOrEmpty(currentSelectedMissileId))
{
- missile.Fire();
+ CreateMissileAndRelatedEntities(currentSelectedMissileId);
+ }
+ else
+ {
+ Console.WriteLine("错误:没有选中的导弹");
+ return;
}
}
@@ -1113,7 +1109,7 @@ namespace ThreatSource.Tools.MissileSimulation
{
simulationManager.StopSimulation();
SimulationEnded?.Invoke(this, EventArgs.Empty);
- ResetSimulation();
+ Console.WriteLine("仿真结束,所有导弹已完成任务");
break;
}
@@ -1136,7 +1132,7 @@ namespace ThreatSource.Tools.MissileSimulation
Console.WriteLine($"\n========== 模拟状态 (时间: {simulationTime:F3}s)==========");
// 天气状态
- Console.WriteLine("\n--- 天气状态 ---");
+ Console.WriteLine("\n--- 天气环境 ---");
if (weather != null)
{
Console.WriteLine($"天气类型: {weather.Type}");
@@ -1147,7 +1143,7 @@ namespace ThreatSource.Tools.MissileSimulation
}
// 导弹状态
- Console.WriteLine("\n--- 导弹状态 ---");
+ Console.WriteLine("\n--- 导弹 ---");
var activeMissiles = simulationManager.GetEntitiesByType()
.Where(m => m.IsActive)
.ToList();
@@ -1165,7 +1161,7 @@ namespace ThreatSource.Tools.MissileSimulation
}
// 目标状态
- Console.WriteLine("\n--- 目标状态 ---");
+ Console.WriteLine("\n--- 目标 ---");
var activeTargets = targets.Values.Where(t => t.IsActive).ToList();
if (activeTargets.Any())
{
@@ -1181,7 +1177,7 @@ namespace ThreatSource.Tools.MissileSimulation
}
// 传感器状态
- Console.WriteLine("\n--- 指示器状态 ---");
+ Console.WriteLine("\n--- 指示器 ---");
var activeIndicators = indicators.Values.Where(i => i.IsActive).ToList();
if (activeIndicators.Any())
{
@@ -1197,7 +1193,7 @@ namespace ThreatSource.Tools.MissileSimulation
}
// 干扰器状态
- Console.WriteLine("\n--- 干扰器状态 ---");
+ Console.WriteLine("\n--- 干扰器 ---");
var activeJammers = jammers.Values.Where(j => j.IsActive).ToList();
if (activeJammers.Any())
{
@@ -1275,52 +1271,25 @@ namespace ThreatSource.Tools.MissileSimulation
///
/// 重置仿真状态
///
+ ///
+ /// 新架构:由于采用销毁重建模式,此方法已简化
+ /// 主要功能已移至DestroyAllEntities和CreateMissileAndRelatedEntities方法
+ ///
public void ResetSimulation()
{
- // 获取所有活跃的导弹
- var activeMissiles = simulationManager.GetEntitiesByType();
- foreach (var missile in activeMissiles)
- {
- // 获取导弹的初始属性
- var motionParameters = missile.GetType().GetField("motionParameters",
- System.Reflection.BindingFlags.NonPublic |
- System.Reflection.BindingFlags.Instance)?.GetValue(missile) as KinematicState;
-
- if (motionParameters != null)
- {
- // 重置导弹位置和状态
- missile.KState.Position = motionParameters.Position;
- missile.KState.Velocity = Vector3D.Zero;
- }
- missile.Deactivate();
- }
-
- // 重置所有传感器状态
- var activeIndicators = simulationManager.GetEntitiesByType()
- .Where(e => indicators.ContainsValue(e));
- foreach (var indicator in activeIndicators)
- {
- indicator.Deactivate();
- }
-
- // 重置所有目标状态
- var activeTargets = simulationManager.GetEntitiesByType();
- foreach (var target in activeTargets)
- {
- var initialPosition = target.KState.Position;
- target.Deactivate();
- target.KState.Position = initialPosition;
- target.Activate();
- }
-
+ Console.WriteLine("=== 开始重置仿真状态 ===");
+
+ // 停止仿真并清理事件系统
+ simulationManager.StopSimulation();
+ simulationManager.ClearAllEvents();
+
// 重置导弹激活状态
missileActiveStatus.Clear();
- foreach (var missile in missiles.Values)
- {
- missileActiveStatus[missile.Id] = false;
- }
-
- Console.WriteLine("仿真状态已重置");
+
+ // 清理活跃干扰列表
+ activeJammings.Clear();
+
+ Console.WriteLine("=== 仿真状态重置完成 ===");
}
///
@@ -1421,5 +1390,285 @@ namespace ThreatSource.Tools.MissileSimulation
// 返回一个新的列表,防止外部修改内部列表
return [.. activeJammings];
}
+
+ ///
+ /// 销毁所有实体并从仿真管理器中注销
+ ///
+ ///
+ /// 新架构:每次仿真结束后完全销毁所有实体,下次选择时重新创建
+ /// 这样可以避免状态残留问题,确保每次都是全新的实体
+ ///
+ private void DestroyAllEntities()
+ {
+ Console.WriteLine("=== 开始销毁所有实体 ===");
+
+ // 停止仿真并清理事件系统
+ simulationManager.StopSimulation();
+ simulationManager.ClearAllEvents();
+
+ // 销毁所有导弹
+ foreach (var missile in missiles.Values)
+ {
+ missile.Deactivate();
+ simulationManager.UnregisterEntity(missile.Id);
+ Console.WriteLine($"销毁导弹: {missile.Id}");
+ }
+ missiles.Clear();
+
+ // 销毁所有目标
+ foreach (var target in targets.Values)
+ {
+ target.Deactivate();
+ simulationManager.UnregisterEntity(target.Id);
+ Console.WriteLine($"销毁目标: {target.Id}");
+ }
+ targets.Clear();
+
+ // 销毁所有指示器
+ foreach (var indicator in indicators.Values)
+ {
+ indicator.Deactivate();
+ simulationManager.UnregisterEntity(indicator.Id);
+ Console.WriteLine($"销毁指示器: {indicator.Id}");
+ }
+ indicators.Clear();
+
+ // 销毁所有干扰器
+ foreach (var jammer in jammers.Values)
+ {
+ jammer.Deactivate();
+ simulationManager.UnregisterEntity(jammer.Id);
+ Console.WriteLine($"销毁干扰器: {jammer.Id}");
+ }
+ jammers.Clear();
+
+ // 清理状态
+ missileActiveStatus.Clear();
+ activeJammings.Clear();
+ SelectedMissileId = "";
+
+ Console.WriteLine("=== 所有实体销毁完成 ===");
+ }
+
+ ///
+ /// 按需创建特定导弹及其相关实体
+ ///
+ /// 要创建的导弹ID
+ ///
+ /// 新架构:每次选择导弹时重新创建所需的实体
+ /// 包括目标、导弹、指示器、干扰器等
+ ///
+ private void CreateMissileAndRelatedEntities(string missileId)
+ {
+ Console.WriteLine($"=== 开始创建导弹 {missileId} 及相关实体 ===");
+
+ // 首先添加天气(如果还没有)
+ if (simulationManager.CurrentWeather == null)
+ {
+ AddWeathers();
+ }
+
+ // 创建目标
+ AddTankTarget();
+
+ // 根据导弹类型创建对应的导弹
+ switch (missileId)
+ {
+ case "LSGM_1":
+ AddLaserSemiActiveMissile();
+ break;
+
+ case "LBRM_1":
+ AddLaserBeamRiderMissile();
+ break;
+
+ case "TSM_1":
+ AddTerminalSensitiveMissile();
+ break;
+
+ case "ICGM_1":
+ AddInfraredCommandMissile();
+ break;
+
+ case "ITGM_1":
+ AddInfraredImagingMissile();
+ break;
+
+ case "MMWG_1":
+ AddMillimeterWaveMissile();
+ break;
+
+ case "CGGM_1":
+ case "CGGM_2":
+ AddCompositeGuidanceMissile(); // 这个方法会添加两种复合制导导弹
+ break;
+
+ default:
+ Console.WriteLine($"未知的导弹类型: {missileId}");
+ return;
+ }
+
+ // 添加所有指示器、干扰器和烟幕弹
+ AddIndicators();
+
+ // 根据导弹类型添加相应的干扰器
+ AddJammersForMissile(missileId);
+
+ // 添加烟幕弹和激光诱偏目标
+ AddSmokeGrenade();
+ AddLaserDecoy();
+
+ // 激活选中的导弹
+ if (missiles.TryGetValue(missileId, out var selectedMissile))
+ {
+ selectedMissile.Activate();
+ SelectedMissileId = missileId;
+ missileActiveStatus[missileId] = true;
+ Console.WriteLine($"已激活导弹: {missileId}");
+
+ // 激活相关指示器
+ ActivateRelatedIndicators(missileId);
+ }
+
+ Console.WriteLine($"=== 导弹 {missileId} 及相关实体创建完成 ===");
+ }
+
+ private void AddJammersForMissile(string missileId)
+ {
+ Console.WriteLine($"为导弹 {missileId} 创建相应的干扰器");
+
+ // 利用现有的导弹-干扰器映射
+ if (missileJammingMap.TryGetValue(missileId, out var jammingList))
+ {
+ foreach (var (type, displayName, jammerId, mode, target) in jammingList)
+ {
+ CreateJammerById(jammerId, type, target);
+ }
+ }
+ else
+ {
+ Console.WriteLine($"未找到导弹 {missileId} 的干扰器映射");
+ }
+ }
+
+ ///
+ /// 根据干扰器ID创建干扰器实体
+ ///
+ private void CreateJammerById(string jammerId, JammingType type, string target)
+ {
+ try
+ {
+ // 根据干扰器ID确定朝向
+ Orientation orientation = GetJammerOrientation(jammerId, target);
+
+ var jammerParams = new KinematicState
+ {
+ Position = new Vector3D(0, 0, 0),
+ Orientation = orientation,
+ Speed = 0.0
+ };
+
+ // 根据干扰器ID确定类型配置
+ string jammerConfig = GetJammerConfig(jammerId);
+
+ var jammer = _threatSourceFactory.CreateJammer(jammerId, jammerConfig, jammerParams, "Tank_1");
+ if (jammer is BaseJammer baseJammer)
+ {
+ simulationManager.RegisterEntity(jammerId, jammer);
+ jammers[jammerId] = baseJammer;
+ Console.WriteLine($"注册干扰器 {jammerId}");
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"创建干扰器 {jammerId} 时出错: {ex.Message}");
+ }
+ }
+
+ ///
+ /// 根据干扰器ID和目标确定朝向
+ ///
+ private Orientation GetJammerOrientation(string jammerId, string target)
+ {
+ // 根据干扰器ID和目标类型确定朝向
+ return jammerId switch
+ {
+ "LaserJammer_Designator" => GetOrientationToRelatedIndicator(), // 朝向与当前导弹相关的指示器
+ "LaserJammer_Missile" => GetOrientationToCurrentMissile(), // 朝向当前选中的导弹
+ "InfraredJammer_Designator" => GetOrientationToRelatedIndicator(), // 朝向与当前导弹相关的指示器
+ "InfraredJammer_Missile" => GetOrientationToCurrentMissile(), // 朝向当前选中的导弹
+ "MillimeterWaveJammer_Missile" => GetOrientationToCurrentMissile(), // 朝向当前选中的导弹
+ "LaserJammer_Submunition" or "InfraredJammer_Submunition" or "MillimeterWaveJammer_Submunition" or "MillimeterWaveCompensationJammer_Submunition"
+ => new Orientation(0, Math.PI/2, 0), // 垂直向上
+ _ => new Orientation(0, 0, 0) // 默认朝向
+ };
+ }
+
+ ///
+ /// 获取朝向与当前选中导弹相关的指示器的方向
+ ///
+ private Orientation GetOrientationToRelatedIndicator()
+ {
+ // 根据当前选中的导弹确定相关的指示器
+ string[] relatedIndicatorIds = SelectedMissileId switch
+ {
+ "LSGM_1" => ["LD_1"], // 激光半主动导弹 -> 激光指示器
+ "LBRM_1" => ["LBR_1"], // 激光驾束导弹 -> 激光驾束仪
+ "ICGM_1" => ["IT_1"], // 红外指令导弹 -> 红外测角仪
+ "CGGM_2" => ["LD_1"], // 激光/红外复合导弹 -> 激光指示器
+ _ => ["LD_1", "LBR_1", "IT_1"] // 默认尝试所有指示器
+ };
+
+ return GetOrientationToIndicator(relatedIndicatorIds);
+ }
+
+ ///
+ /// 获取朝向当前选中导弹的方向
+ ///
+ private Orientation GetOrientationToCurrentMissile()
+ {
+ if (!string.IsNullOrEmpty(SelectedMissileId) && missiles.TryGetValue(SelectedMissileId, out var missile))
+ {
+ return CalculateOrientationToEntity(missile);
+ }
+ return new Orientation(0, 0, 0); // 默认朝向
+ }
+
+ ///
+ /// 获取朝向指示器的方向
+ ///
+ private Orientation GetOrientationToIndicator(params string[] indicatorIds)
+ {
+ foreach (var indicatorId in indicatorIds)
+ {
+ if (indicators.TryGetValue(indicatorId, out var indicator))
+ {
+ return CalculateOrientationToEntity(indicator);
+ }
+ }
+ return new Orientation(0, 0, 0); // 默认朝向
+ }
+
+ ///
+ /// 根据干扰器ID确定配置类型
+ ///
+ private string GetJammerConfig(string jammerId)
+ {
+ return jammerId switch
+ {
+ "LaserJammer_Designator" or "LaserJammer_Missile" => "laser_blocking",
+ "LaserJammer_Submunition" => "laser_top_blocking",
+ "InfraredJammer_Designator" or "InfraredJammer_Missile" => "infrared_blocking",
+ "InfraredJammer_Submunition" => "infrared_top_blocking",
+ "MillimeterWaveJammer_Missile" or "MillimeterWaveJammer_Submunition" => "mmw_blocking",
+ "MillimeterWaveCompensationJammer_Submunition" => "mmw_compensation",
+ "LDY_1" => "laser_decoy",
+ "SG_1" => "surround",
+ "SG_2" => "infrared",
+ "SG_3" => "mmw",
+ "SG_4" => "top",
+ _ => "laser_blocking" // 默认配置
+ };
+ }
}
}
\ No newline at end of file