纠正末敏弹分离算法,增加对小值的输出格式
This commit is contained in:
parent
ca3897a415
commit
e630dc3a4c
@ -102,7 +102,7 @@ namespace ThreatSource.Missile
|
||||
/// <param name="missileId">导弹的唯一标识符</param>
|
||||
/// <param name="targetId">目标的唯一标识符</param>
|
||||
/// <param name="properties">导弹的配置参数</param>
|
||||
/// <param name="launchParams">发射参数</param>
|
||||
/// <param name="kinematicState">发射参数</param>
|
||||
/// <param name="submunitionProperties">子弹的配置参数</param>
|
||||
/// <param name="submunitionCount">子弹的数量</param>
|
||||
/// <param name="submunitionConfig">子弹药配置参数</param>
|
||||
@ -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
|
||||
/// </remarks>
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@ -172,7 +172,7 @@ namespace ThreatSource.Missile
|
||||
/// <param name="missileId">导弹ID</param>
|
||||
/// <param name="targetId">目标ID</param>
|
||||
/// <param name="properties">子弹配置参数</param>
|
||||
/// <param name="launchParams">发射参数</param>
|
||||
/// <param name="kinemateState">发射参数</param>
|
||||
/// <param name="submunitionConfig">子弹性能参数配置</param>
|
||||
/// <param name="manager">仿真管理器实例</param>
|
||||
/// <remarks>
|
||||
@ -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;
|
||||
|
||||
@ -32,7 +32,7 @@ namespace ThreatSource.Sensor
|
||||
/// <returns>传感器数据字符串表示</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"IsValid: {IsValid}";
|
||||
return $"IsValid={IsValid}";
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ namespace ThreatSource.Sensor
|
||||
/// <returns>传感器数据字符串表示</returns>
|
||||
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
|
||||
/// <returns>传感器数据字符串表示</returns>
|
||||
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
|
||||
/// <returns>传感器数据字符串表示</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return base.ToString() + $", Altitude: {Altitude:F2}";
|
||||
return base.ToString() + $", Altitude={Altitude:F2}";
|
||||
}
|
||||
|
||||
}
|
||||
@ -191,7 +191,7 @@ namespace ThreatSource.Sensor
|
||||
/// <returns>传感器数据字符串表示</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return base.ToString() + $", Distance: {Distance:F2}";
|
||||
return base.ToString() + $", Distance={Distance:F2}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,11 +60,30 @@ namespace ThreatSource.Simulation
|
||||
/// <returns>状态的字符串表示</returns>
|
||||
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}";
|
||||
}
|
||||
|
||||
|
||||
@ -23,12 +23,12 @@ namespace ThreatSource.Utils
|
||||
/// <param name="startPos">发射位置坐标</param>
|
||||
/// <param name="targetPos">目标位置坐标</param>
|
||||
/// <param name="initialSpeed">发射初速度,单位:米/秒</param>
|
||||
/// <returns>包含最佳发射方向和初始速度向量的元组,如果无解则返回null</returns>
|
||||
/// <returns>最佳发射初始速度,如果无解则返回null</returns>
|
||||
/// <remarks>
|
||||
/// 该方法使用弹道方程计算两个可能的发射角度,并选择较小的仰角作为最佳发射方向。
|
||||
/// 计算考虑了重力影响,但未考虑空气阻力。
|
||||
/// </remarks>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -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];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -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 秒,自毁
|
||||
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user