diff --git a/ThreatSource/src/MIssile/TerminalSensitiveMissile.cs b/ThreatSource/src/MIssile/TerminalSensitiveMissile.cs index f9b0cea..64d4ea2 100644 --- a/ThreatSource/src/MIssile/TerminalSensitiveMissile.cs +++ b/ThreatSource/src/MIssile/TerminalSensitiveMissile.cs @@ -102,7 +102,7 @@ namespace ThreatSource.Missile /// 导弹的唯一标识符 /// 目标的唯一标识符 /// 导弹的配置参数 - /// 发射参数 + /// 发射参数 /// 子弹的配置参数 /// 子弹的数量 /// 子弹药配置参数 @@ -121,12 +121,12 @@ namespace ThreatSource.Missile string missileId, string targetId, MissileProperties properties, - KinematicState launchParams, + KinematicState kinematicState, MissileProperties submunitionProperties, int submunitionCount, TerminalSensitiveSubmunitionConfig submunitionConfig, ISimulationManager manager) - : base(missileId, properties, launchParams, manager) + : base(missileId, properties, kinematicState, manager) { this.targetId = targetId; this.submunitionProperties = submunitionProperties; @@ -136,18 +136,18 @@ namespace ThreatSource.Missile //计算分离点坐标,使用配置中的分离高度和距离 SimulationElement target = SimulationManager.GetEntityById(targetId) as SimulationElement ?? throw new Exception("目标不存在"); - separationPoint = Vector3D.PointOnLine(target.KState.Position, base.KState.Position, config.SeparationDistance) + new Vector3D(0, config.SeparationHeight, 0); + separationPoint = Vector3D.PointOnLine(target.KState.Position, KState.Position, config.SeparationDistance) + new Vector3D(0, config.SeparationHeight, 0); //计算导弹发射角度 - (Orientation? launchOrientation, Vector3D? launchVelocity) = MotionAlgorithm.CalculateBestLaunchOrientation(base.KState.Position, separationPoint, base.KState.Speed); - if (!launchOrientation.HasValue || launchVelocity is null) + Vector3D? launchVelocityNullable = MotionAlgorithm.CalculateBestLaunchOrientation(KState.Position, separationPoint, KState.Speed); + if (launchVelocityNullable == null) { throw new InvalidOperationException("无法计算发射方向"); } else { - KState.Orientation = launchOrientation.Value; - KState.Velocity = launchVelocity; + KState.Velocity = launchVelocityNullable; + KState.Orientation = Orientation.FromVector(launchVelocityNullable); } } @@ -232,7 +232,7 @@ namespace ThreatSource.Missile /// private void UpdateCruiseStage(double deltaTime) { - double distanceToSeparationPoint = (separationPoint - base.KState.Position).Magnitude(); + double distanceToSeparationPoint = (separationPoint - KState.Position).Magnitude(); //距离分离点距离小于配置的分离范围,则分离 if (distanceToSeparationPoint <= config.SeparationRange) { @@ -323,6 +323,10 @@ namespace ThreatSource.Missile Debug.WriteLine($"注册末敏弹子弹 {submunitions[i].Id}"); submunitions[i].Activate(); Debug.WriteLine($"激活末敏弹子弹 {submunitions[i].Id}"); + + Console.WriteLine($"[末敏弹分离] 母弹 KS: Pos={KState.Position}, Orient={KState.Orientation}, Speed={KState.Speed}, Vel={KState.Velocity}"); + Console.WriteLine($"[末敏弹分离] 子弹 {i} KS: Pos={submunitions[i].KState.Position}, Orient={submunitions[i].KState.Orientation}, Speed={submunitions[i].KState.Speed}, Vel={submunitions[i].KState.Velocity}"); + submunitions[i].Fire(); } diff --git a/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs b/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs index bded552..be57548 100644 --- a/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs +++ b/ThreatSource/src/MIssile/TerminalSensitiveSubmunition.cs @@ -172,7 +172,7 @@ namespace ThreatSource.Missile /// 导弹ID /// 目标ID /// 子弹配置参数 - /// 发射参数 + /// 发射参数 /// 子弹性能参数配置 /// 仿真管理器实例 /// @@ -186,10 +186,10 @@ namespace ThreatSource.Missile string missileId, string targetId, MissileProperties properties, - KinematicState launchParams, + KinematicState kinemateState, TerminalSensitiveSubmunitionConfig submunitionConfig, ISimulationManager manager) - : base(missileId, properties, launchParams, manager) + : base(missileId, properties, kinemateState, manager) { TargetId = targetId; this.config = submunitionConfig; diff --git a/ThreatSource/src/Sensor/SensorData.cs b/ThreatSource/src/Sensor/SensorData.cs index fff9520..d324c28 100644 --- a/ThreatSource/src/Sensor/SensorData.cs +++ b/ThreatSource/src/Sensor/SensorData.cs @@ -32,7 +32,7 @@ namespace ThreatSource.Sensor /// 传感器数据字符串表示 public override string ToString() { - return $"IsValid: {IsValid}"; + return $"IsValid={IsValid}"; } } @@ -82,7 +82,7 @@ namespace ThreatSource.Sensor /// 传感器数据字符串表示 public override string ToString() { - return base.ToString() + $", Temperature: {Temperature:F2}, IsTargetDetected: {IsTargetDetected}, TargetAngle: {TargetAngle:F2}"; + return base.ToString() + $", Temperature={Temperature:F2}, IsTargetDetected={IsTargetDetected}, TargetAngle={TargetAngle:F2}"; } } @@ -132,7 +132,7 @@ namespace ThreatSource.Sensor /// 传感器数据字符串表示 public override string ToString() { - return base.ToString() + $", RadiationIntensity: {RadiationIntensity:F2}, IsTargetDetected: {IsTargetDetected}, TargetAngle: {TargetAngle:F2}"; + return base.ToString() + $", RadiationIntensity={RadiationIntensity:F2}, IsTargetDetected={IsTargetDetected}, TargetAngle={TargetAngle:F2}"; } } @@ -161,7 +161,7 @@ namespace ThreatSource.Sensor /// 传感器数据字符串表示 public override string ToString() { - return base.ToString() + $", Altitude: {Altitude:F2}"; + return base.ToString() + $", Altitude={Altitude:F2}"; } } @@ -191,7 +191,7 @@ namespace ThreatSource.Sensor /// 传感器数据字符串表示 public override string ToString() { - return base.ToString() + $", Distance: {Distance:F2}"; + return base.ToString() + $", Distance={Distance:F2}"; } } } diff --git a/ThreatSource/src/Simulation/ElementStatusInfo.cs b/ThreatSource/src/Simulation/ElementStatusInfo.cs index fc97016..09c93b8 100644 --- a/ThreatSource/src/Simulation/ElementStatusInfo.cs +++ b/ThreatSource/src/Simulation/ElementStatusInfo.cs @@ -60,11 +60,30 @@ namespace ThreatSource.Simulation /// 状态的字符串表示 public override string ToString() { - string baseInfo = $"仿真元素 {ElementType} {Id} at {KState.Position}, Active: {IsActive}"; + string baseInfo = $"[{ElementType}] Id={Id}, Active={IsActive}, 位置={KState.Position}, 方向={KState.Orientation}, 速度={KState.Speed:F2}, 速度矢量={KState.Velocity}"; if (ExtendedProperties.Count > 0) { - string extendedInfo = string.Join(", ", ExtendedProperties.Select(p => $"{p.Key}={p.Value}")); + string extendedInfo = string.Join(", ", ExtendedProperties.Select(p => + { + string valueStr; + if (p.Value is double d) + { + if (d > 0 && d < 1e-4) + { + valueStr = d.ToString("E2"); + } + else + { + valueStr = d.ToString("F2"); + } + } + else + { + valueStr = p.Value?.ToString() ?? "null"; // 处理可能的null值 + } + return $"{p.Key}={valueStr}"; + })); return $"{baseInfo}, {extendedInfo}"; } diff --git a/ThreatSource/src/Utils/MotionAlgorithm.cs b/ThreatSource/src/Utils/MotionAlgorithm.cs index 5c5d35f..9705d2f 100644 --- a/ThreatSource/src/Utils/MotionAlgorithm.cs +++ b/ThreatSource/src/Utils/MotionAlgorithm.cs @@ -23,12 +23,12 @@ namespace ThreatSource.Utils /// 发射位置坐标 /// 目标位置坐标 /// 发射初速度,单位:米/秒 - /// 包含最佳发射方向和初始速度向量的元组,如果无解则返回null + /// 最佳发射初始速度,如果无解则返回null /// /// 该方法使用弹道方程计算两个可能的发射角度,并选择较小的仰角作为最佳发射方向。 /// 计算考虑了重力影响,但未考虑空气阻力。 /// - public static (Orientation? orientation, Vector3D? velocity) CalculateBestLaunchOrientation(Vector3D startPos, Vector3D targetPos, double initialSpeed) + public static Vector3D? CalculateBestLaunchOrientation(Vector3D startPos, Vector3D targetPos, double initialSpeed) { // 计算水平距离 double dx = targetPos.X - startPos.X; @@ -43,7 +43,7 @@ namespace ThreatSource.Utils if (angles == null) { Debug.WriteLine("无法计算发射角度"); - return (null, null); + return null; } double bestAngle = Math.Min(angles[0], angles[1]); @@ -54,7 +54,7 @@ namespace ThreatSource.Utils double vz = initialSpeed * Math.Cos(bestAngle) * Math.Sin(azimuth); // 返回方向和速度 - return (new Orientation(bestAngle, azimuth, 0), new Vector3D(vx, vy, vz)); + return new Vector3D(vx, vy, vz); } /// @@ -89,7 +89,7 @@ namespace ThreatSource.Utils Debug.WriteLine($"计算得到的两个角度: {angle1 * 180 / Math.PI:F2}° 和 {angle2 * 180 / Math.PI:F2}°"); - return new[] { angle1, angle2 }; + return [angle1, angle2]; } /// diff --git a/docs/project/tunning.md b/docs/project/tunning.md index afe09cf..a0b7062 100644 --- a/docs/project/tunning.md +++ b/docs/project/tunning.md @@ -304,4 +304,25 @@ 2. 接近计算出的落点时,两个目标都离开了导引头视野,不再计算落点。导弹会惯性飞行,会偏离之前计算出的落点。 +## 末敏弹实验记录(v0.2.16) + +时间:2025-05-10 10:00:00 +版本:v0.2.16 + +### 初始设置 +1. 末敏弹初始位置 +(300.0,0.0,20.0) + +2. 子弹分离点 +高度 1000米,距离 1000米,分离角 45度 + +3. 坦克初始参数 +位置(0.0,1.2,0.0) +朝向(0.0,0.0,0.0)(-Z轴) + +### 实验结果 +1. 坦克初速 0米/秒,仿真运行 30.2 秒,命中 +2. 坦克速度 0.5米/秒,仿真运行 29.7 秒,命中 +3. 坦克速度 1米/秒,仿真运行 38 秒,自毁 + diff --git a/tools/ComprehensiveMissileSimulator.cs b/tools/ComprehensiveMissileSimulator.cs index 7b76c51..a1878b6 100644 --- a/tools/ComprehensiveMissileSimulator.cs +++ b/tools/ComprehensiveMissileSimulator.cs @@ -193,7 +193,7 @@ namespace ThreatSource.Tools.MissileSimulation { Position = new Vector3D(0, 1.2, 0), Orientation = new Orientation(0.0, 0.0, 0.0), - Speed = 1.0 + Speed = 0.0 }; string targetId = "Tank_1"; var target = _threatSourceFactory.CreateTarget(targetId, "mbt_001", motionParameters);