添加了KinematicState类,统一处理仿真元素的运动学状态
This commit is contained in:
parent
d872c8ece3
commit
ca3897a415
@ -37,11 +37,11 @@ namespace ThreatSource.Tests.Indicator
|
||||
JammingResistanceThreshold = 1e-3
|
||||
};
|
||||
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -53,11 +53,11 @@ namespace ThreatSource.Tests.Indicator
|
||||
};
|
||||
_tank = new Tank("target1", tankProperties, tankInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("target1", _tank);
|
||||
var trackerInitialMotion = new MotionParameters
|
||||
var trackerInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
_infraredTracker = new InfraredTracker(
|
||||
@ -137,11 +137,11 @@ namespace ThreatSource.Tests.Indicator
|
||||
ProportionalNavigationCoefficient = 3
|
||||
};
|
||||
|
||||
var missileInitialMotion = new MotionParameters
|
||||
var missileInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(50, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
// 注册一个导弹实体
|
||||
@ -206,11 +206,11 @@ namespace ThreatSource.Tests.Indicator
|
||||
Type = MissileType.InfraredCommandGuidance
|
||||
};
|
||||
|
||||
var missileMotion = new MotionParameters
|
||||
var missileMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var missile = new InfraredCommandGuidedMissile("missile1", missileProperties, missileMotion, _guidanceConfig, _simulationManager);
|
||||
|
||||
@ -28,11 +28,11 @@ namespace ThreatSource.Tests.Indicator
|
||||
MaxGuidanceDistance = 5000
|
||||
};
|
||||
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -44,11 +44,11 @@ namespace ThreatSource.Tests.Indicator
|
||||
};
|
||||
_tank = new Tank("target1", tankProperties, tankInitialMotion, _simulationManager);
|
||||
|
||||
var beamRiderInitialMotion = new MotionParameters
|
||||
var beamRiderInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
_laserBeamRider = new LaserBeamRider(
|
||||
@ -121,8 +121,8 @@ namespace ThreatSource.Tests.Indicator
|
||||
_testAdapter.ClearEvents(); // 清除 Activate 产生的事件
|
||||
|
||||
// 强制移动目标,以确保 Update 会更新激光方向并发布事件
|
||||
var newTargetPosition = _tank.Position + new Vector3D(0, 10, 0);
|
||||
_tank.Position = newTargetPosition;
|
||||
var newTargetPosition = _tank.KState.Position + new Vector3D(0, 10, 0);
|
||||
_tank.KState.Position = newTargetPosition;
|
||||
|
||||
// Act
|
||||
_laserBeamRider.Update(0.1);
|
||||
|
||||
@ -27,11 +27,11 @@ namespace ThreatSource.Tests.Indicator
|
||||
DivergenceAngle = 0.001
|
||||
};
|
||||
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -45,11 +45,11 @@ namespace ThreatSource.Tests.Indicator
|
||||
_tank = new Tank("target1", tankProperties, tankInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("target1", _tank);
|
||||
|
||||
var designatorInitialMotion = new MotionParameters
|
||||
var designatorInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
_laserDesignator = new LaserDesignator(
|
||||
|
||||
@ -30,11 +30,11 @@ namespace ThreatSource.Tests.Indicator
|
||||
Wavelength = 1.06
|
||||
};
|
||||
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -47,11 +47,11 @@ namespace ThreatSource.Tests.Indicator
|
||||
_tank = new Tank("target1", tankProperties, tankInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity("target1", _tank);
|
||||
|
||||
var designatorInitialMotion = new MotionParameters
|
||||
var designatorInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 100, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
_laserDesignator = new LaserDesignator(
|
||||
|
||||
@ -26,11 +26,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
// 创建末敏子弹
|
||||
var initialParams = new MotionParameters
|
||||
var initialParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 100, 0),
|
||||
Orientation = new Orientation(0, -Math.PI/2, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var missileProperties = new MissileProperties();
|
||||
@ -225,11 +225,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
{
|
||||
// Arrange
|
||||
// 添加一个模拟目标以产生传感器数据
|
||||
var targetInitialMotion = new MotionParameters
|
||||
var targetInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 500),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
var targetProperties = new EquipmentProperties
|
||||
{
|
||||
|
||||
@ -43,11 +43,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 创建并注册目标实体
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0), // 修改为100米,与激光指示器一致
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -64,10 +64,10 @@ namespace ThreatSource.Tests.Jamming
|
||||
// 创建导弹对象
|
||||
var initialPosition = new Vector3D(500, 0, 0);
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
var missileMotion = new MotionParameters
|
||||
var missileMotion = new KinematicState
|
||||
{
|
||||
Position = initialPosition,
|
||||
InitialSpeed = initialVelocity.Magnitude()
|
||||
Speed = initialVelocity.Magnitude()
|
||||
};
|
||||
missileMotion.Orientation = new Orientation(0, 0, 0);
|
||||
|
||||
@ -130,7 +130,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
Assert.IsNotNull(_guidanceSystem);
|
||||
Assert.IsNotNull(_missile);
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {_missile.Position}, 初始速度: {_missile.Velocity}");
|
||||
System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {_missile.KState.Position}, 初始速度: {_missile.KState.Speed}");
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
|
||||
@ -35,11 +35,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 初始化红外测角仪
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
_infraredTracker = new InfraredTracker(
|
||||
|
||||
@ -55,11 +55,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 创建并注册目标实体
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -76,10 +76,10 @@ namespace ThreatSource.Tests.Jamming
|
||||
// 创建导弹对象
|
||||
var initialPosition = new Vector3D(500, 0, 0);
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
var missileMotion = new MotionParameters
|
||||
var missileMotion = new KinematicState
|
||||
{
|
||||
Position = initialPosition,
|
||||
InitialSpeed = initialVelocity.Magnitude()
|
||||
Speed = initialVelocity.Magnitude()
|
||||
};
|
||||
missileMotion.Orientation = new Orientation(0, 0, 0);
|
||||
|
||||
@ -146,7 +146,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
Assert.IsNotNull(_guidanceSystem, "激光驾束引导系统不应为空");
|
||||
Assert.IsNotNull(_missile, "导弹不应为空");
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {_missile.Position}, 初始速度: {_missile.Velocity}");
|
||||
System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {_missile.KState.Position}, 初始速度: {_missile.KState.Speed}");
|
||||
|
||||
// 更新激光波束参数
|
||||
_guidanceSystem.UpdateLaserBeamRider(
|
||||
|
||||
@ -34,19 +34,19 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 初始化激光驾束仪
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
// 添加一个坦克作为目标,确保激光束能够正确启动
|
||||
var targetInitialMotion = new MotionParameters
|
||||
var targetInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var targetProperties = new EquipmentProperties
|
||||
|
||||
@ -62,11 +62,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 创建并注册真实目标实体
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0), // 减小距离,便于锁定
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -87,11 +87,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
}
|
||||
|
||||
// 创建并注册诱偏源(敌方坦克)
|
||||
var decoySourceInitialMotion = new MotionParameters
|
||||
var decoySourceInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(80, 10, 0), // 减小距离,便于锁定
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var decoySourceProperties = new EquipmentProperties
|
||||
@ -112,11 +112,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
}
|
||||
|
||||
// 创建导弹对象
|
||||
var missileInitialMotion = new MotionParameters
|
||||
var missileInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(10, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 50
|
||||
Speed = 50
|
||||
};
|
||||
|
||||
var missileProperties = new MissileProperties
|
||||
@ -209,11 +209,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 创建诱偏目标运动参数
|
||||
var decoyMotion = new MotionParameters
|
||||
var decoyMotion = new KinematicState
|
||||
{
|
||||
Position = decoyPosition,
|
||||
Orientation = Orientation.FromVector(decoyDirection),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
// 创建诱偏目标
|
||||
@ -269,11 +269,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 创建虚拟激光指示器并注册 - 更靠近目标
|
||||
var designatorMotion = new MotionParameters
|
||||
var designatorMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(10, 0, 10), // 更靠近目标位置
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var designator = new LaserDesignator(
|
||||
@ -292,8 +292,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
designator?.Activate();
|
||||
|
||||
// 直接更新制导系统的激光指示器参数,确保能正确接收激光源
|
||||
var targetPosition = _target?.Position ?? Vector3D.Zero;
|
||||
var designatorPosition = designator?.Position ?? Vector3D.Zero;
|
||||
var targetPosition = _target?.KState.Position ?? Vector3D.Zero;
|
||||
var designatorPosition = designator?.KState.Position ?? Vector3D.Zero;
|
||||
var updateLaserDesignatorMethod = typeof(LaserSemiActiveGuidanceSystem).GetMethod("UpdateLaserDesignator",
|
||||
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
||||
|
||||
@ -330,7 +330,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
Debug.WriteLine($"诱偏源距离目标: {decoyDistance}米,功率: {decoyPower}W");
|
||||
|
||||
// 计算诱偏目标位置
|
||||
Vector3D decoyPosVector = (_decoySource?.Position ?? Vector3D.Zero) + decoyDirection * decoyDistance;
|
||||
Vector3D decoyPosVector = (_decoySource?.KState.Position ?? Vector3D.Zero) + decoyDirection * decoyDistance;
|
||||
|
||||
// 创建并注册激光诱偏目标
|
||||
var decoyTarget = CreateAndRegisterLaserDecoy(decoyPosVector, decoyDirection, decoyPower);
|
||||
@ -405,11 +405,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 创建虚拟激光指示器并注册
|
||||
var designatorMotion = new MotionParameters
|
||||
var designatorMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(10, 0, 10), // 更靠近目标位置
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var designator = new LaserDesignator(
|
||||
@ -428,8 +428,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
designator?.Activate();
|
||||
|
||||
// 直接更新制导系统的激光指示器参数
|
||||
var targetPosition = _target?.Position ?? Vector3D.Zero;
|
||||
var designatorPosition = designator?.Position ?? Vector3D.Zero;
|
||||
var targetPosition = _target?.KState.Position ?? Vector3D.Zero;
|
||||
var designatorPosition = designator?.KState.Position ?? Vector3D.Zero;
|
||||
var updateLaserDesignatorMethod = typeof(LaserSemiActiveGuidanceSystem).GetMethod("UpdateLaserDesignator",
|
||||
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
||||
|
||||
@ -461,7 +461,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
double decoyPower = 2000; // 远高于真实目标的功率
|
||||
|
||||
// 计算诱偏目标位置
|
||||
Vector3D decoyPosition = (_decoySource?.Position ?? Vector3D.Zero) + decoyDirection * decoyDistance;
|
||||
Vector3D decoyPosition = (_decoySource?.KState.Position ?? Vector3D.Zero) + decoyDirection * decoyDistance;
|
||||
|
||||
// 创建并注册激光诱偏目标
|
||||
var decoy = CreateAndRegisterLaserDecoy(decoyPosition, decoyDirection, decoyPower);
|
||||
@ -530,11 +530,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 创建虚拟激光指示器并注册
|
||||
var designatorMotion = new MotionParameters
|
||||
var designatorMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(10, 0, 10), // 更靠近目标位置
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var designator = new LaserDesignator(
|
||||
@ -553,8 +553,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
designator?.Activate();
|
||||
|
||||
// 直接更新制导系统的激光指示器参数
|
||||
var targetPosition = _target?.Position ?? Vector3D.Zero;
|
||||
var designatorPosition = designator?.Position ?? Vector3D.Zero;
|
||||
var targetPosition = _target?.KState.Position ?? Vector3D.Zero;
|
||||
var designatorPosition = designator?.KState.Position ?? Vector3D.Zero;
|
||||
var updateLaserDesignatorMethod = typeof(LaserSemiActiveGuidanceSystem).GetMethod("UpdateLaserDesignator",
|
||||
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
||||
|
||||
@ -591,7 +591,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
double decoyLifetime = 2.0; // 短生命周期,2秒
|
||||
|
||||
// 计算诱偏目标位置
|
||||
Vector3D decoyPosition = (_decoySource?.Position ?? Vector3D.Zero) + decoyDirection * decoyDistance;
|
||||
Vector3D decoyPosition = (_decoySource?.KState.Position ?? Vector3D.Zero) + decoyDirection * decoyDistance;
|
||||
|
||||
// 创建并注册激光诱偏目标
|
||||
var decoy = CreateAndRegisterLaserDecoy(decoyPosition, decoyDirection, decoyPower, decoyLifetime);
|
||||
@ -671,15 +671,15 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 创建虚拟激光指示器并注册
|
||||
var designatorMotion = new MotionParameters
|
||||
var designatorMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(-1900, 0, 10), // 距离目标2000米
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
// 计算真实指示器到目标的实际距离
|
||||
double actualDesignatorDistance = (designatorMotion.Position - (_target?.Position ?? Vector3D.Zero)).Magnitude();
|
||||
double actualDesignatorDistance = (designatorMotion.Position - (_target?.KState.Position ?? Vector3D.Zero)).Magnitude();
|
||||
Debug.WriteLine($"激光指示器到目标的实际距离: {actualDesignatorDistance}米");
|
||||
Debug.WriteLine($"激光指示器功率: {designatorConfig.Power}W, 发散角: {designatorConfig.DivergenceAngle}弧度");
|
||||
|
||||
@ -699,8 +699,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
designator?.Activate();
|
||||
|
||||
// 获取实际目标位置
|
||||
var realTargetPosition = _target?.Position ?? Vector3D.Zero;
|
||||
var designatorPosition = designator?.Position ?? Vector3D.Zero;
|
||||
var realTargetPosition = _target?.KState.Position ?? Vector3D.Zero;
|
||||
var designatorPosition = designator?.KState.Position ?? Vector3D.Zero;
|
||||
|
||||
// 通过反射设置CurrentTargetId字段为target1,确保制导系统能正确识别目标
|
||||
var targetIdField = typeof(LaserSemiActiveGuidanceSystem).GetField("CurrentTargetId",
|
||||
@ -749,7 +749,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
Debug.WriteLine($"诱偏源距离目标: {decoyDistance}米,功率: {decoyPower}W");
|
||||
|
||||
// 计算诱偏目标位置
|
||||
Vector3D decoyPosVector = (_decoySource?.Position ?? Vector3D.Zero) + decoyDirection * decoyDistance;
|
||||
Vector3D decoyPosVector = (_decoySource?.KState.Position ?? Vector3D.Zero) + decoyDirection * decoyDistance;
|
||||
|
||||
// 创建并注册激光诱偏目标
|
||||
var decoyTarget = CreateAndRegisterLaserDecoy(decoyPosVector, decoyDirection, decoyPower);
|
||||
@ -769,13 +769,13 @@ namespace ThreatSource.Tests.Jamming
|
||||
Debug.WriteLine($"诱偏目标位置: {decoyPosition}");
|
||||
|
||||
// 计算诱偏目标到诱偏源的实际距离
|
||||
Vector3D decoySourcePosition = _decoySource?.Position ?? Vector3D.Zero;
|
||||
Vector3D decoySourcePosition = _decoySource?.KState.Position ?? Vector3D.Zero;
|
||||
double actualDecoyDistance = (decoyPosition - decoySourcePosition).Magnitude();
|
||||
Debug.WriteLine($"诱偏源位置: {decoySourcePosition}, 诱偏目标实际距离: {actualDecoyDistance}米");
|
||||
|
||||
// 计算导弹到真实目标和诱偏目标的距离
|
||||
double missileToDReal = (realTargetPosition - (_guidanceSystem?.Position ?? Vector3D.Zero)).Magnitude();
|
||||
double missileToDDecoy = (decoyPosition - (_guidanceSystem?.Position ?? Vector3D.Zero)).Magnitude();
|
||||
double missileToDReal = (realTargetPosition - (_guidanceSystem?.KState.Position ?? Vector3D.Zero)).Magnitude();
|
||||
double missileToDDecoy = (decoyPosition - (_guidanceSystem?.KState.Position ?? Vector3D.Zero)).Magnitude();
|
||||
Debug.WriteLine($"导弹到真实目标距离: {missileToDReal}米, 导弹到诱偏目标距离: {missileToDDecoy}米");
|
||||
|
||||
// 获取诱偏后制导系统识别的目标位置
|
||||
@ -802,8 +802,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
}
|
||||
|
||||
// 计算目标与导弹之间的角度
|
||||
Vector3D missileToReal = realTargetPosition - (_guidanceSystem?.Position ?? Vector3D.Zero);
|
||||
Vector3D missileToDecoy = decoyPosition - (_guidanceSystem?.Position ?? Vector3D.Zero);
|
||||
Vector3D missileToReal = realTargetPosition - (_guidanceSystem?.KState.Position ?? Vector3D.Zero);
|
||||
Vector3D missileToDecoy = decoyPosition - (_guidanceSystem?.KState.Position ?? Vector3D.Zero);
|
||||
double angleToReal = Math.Atan2(missileToReal.Y, missileToReal.X) * 180 / Math.PI;
|
||||
double angleToDecoy = Math.Atan2(missileToDecoy.Y, missileToDecoy.X) * 180 / Math.PI;
|
||||
|
||||
@ -907,15 +907,15 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 创建虚拟激光指示器并注册 - 距离目标2000米
|
||||
var designatorMotion = new MotionParameters
|
||||
var designatorMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(-1900, 0, 10), // 距离目标2000米
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
// 计算真实指示器到目标的实际距离
|
||||
double actualDesignatorDistance = (designatorMotion.Position - (_target?.Position ?? Vector3D.Zero)).Magnitude();
|
||||
double actualDesignatorDistance = (designatorMotion.Position - (_target?.KState.Position ?? Vector3D.Zero)).Magnitude();
|
||||
Debug.WriteLine($"激光指示器到目标的实际距离: {actualDesignatorDistance}米");
|
||||
Debug.WriteLine($"激光指示器功率: {designatorConfig.Power}W, 发散角: {designatorConfig.DivergenceAngle}弧度");
|
||||
|
||||
@ -935,8 +935,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
designator?.Activate();
|
||||
|
||||
// 获取实际目标位置
|
||||
var realTargetPosition = _target?.Position ?? Vector3D.Zero;
|
||||
var designatorPosition = designator?.Position ?? Vector3D.Zero;
|
||||
var realTargetPosition = _target?.KState.Position ?? Vector3D.Zero;
|
||||
var designatorPosition = designator?.KState.Position ?? Vector3D.Zero;
|
||||
|
||||
// 通过反射设置CurrentTargetId字段为target1,确保制导系统能正确识别目标
|
||||
var targetIdField = typeof(LaserSemiActiveGuidanceSystem).GetField("CurrentTargetId",
|
||||
@ -1036,7 +1036,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
Debug.WriteLine($"诱偏源距离目标: {decoyDistance}米,功率: {decoyPower}W");
|
||||
|
||||
// 计算诱偏目标位置
|
||||
Vector3D decoyTestPosition = (_decoySource?.Position ?? Vector3D.Zero) + decoyDirection * decoyDistance;
|
||||
Vector3D decoyTestPosition = (_decoySource?.KState.Position ?? Vector3D.Zero) + decoyDirection * decoyDistance;
|
||||
|
||||
// 创建并注册激光诱偏目标
|
||||
var decoyInstance = CreateAndRegisterLaserDecoy(decoyTestPosition, decoyDirection, decoyPower);
|
||||
@ -1084,13 +1084,13 @@ namespace ThreatSource.Tests.Jamming
|
||||
Debug.WriteLine($"诱偏目标位置: {decoyPosition}");
|
||||
|
||||
// 计算诱偏目标到诱偏源的实际距离
|
||||
Vector3D decoySourcePosition = _decoySource?.Position ?? Vector3D.Zero;
|
||||
Vector3D decoySourcePosition = _decoySource?.KState.Position ?? Vector3D.Zero;
|
||||
double actualDecoyDistance = (decoyPosition - decoySourcePosition).Magnitude();
|
||||
Debug.WriteLine($"诱偏源位置: {decoySourcePosition}, 诱偏目标实际距离: {actualDecoyDistance}米");
|
||||
|
||||
// 计算导弹到真实目标和诱偏目标的距离
|
||||
double missileToDReal = (realTargetPosition - (_guidanceSystem?.Position ?? Vector3D.Zero)).Magnitude();
|
||||
double missileToDDecoy = (decoyPosition - (_guidanceSystem?.Position ?? Vector3D.Zero)).Magnitude();
|
||||
double missileToDReal = (realTargetPosition - (_guidanceSystem?.KState.Position ?? Vector3D.Zero)).Magnitude();
|
||||
double missileToDDecoy = (decoyPosition - (_guidanceSystem?.KState.Position ?? Vector3D.Zero)).Magnitude();
|
||||
Debug.WriteLine($"导弹到真实目标距离: {missileToDReal}米, 导弹到诱偏目标距离: {missileToDDecoy}米");
|
||||
|
||||
break;
|
||||
|
||||
@ -33,19 +33,19 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 初始化激光指示器
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
// 创建并注册目标实体
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
var tankProperties = new EquipmentProperties
|
||||
{
|
||||
|
||||
@ -26,11 +26,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
// 创建末敏子弹
|
||||
var initialParams = new MotionParameters
|
||||
var initialParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 100, 0),
|
||||
Orientation = new Orientation(0, -Math.PI/2, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var missileProperties = new MissileProperties();
|
||||
|
||||
@ -52,11 +52,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 创建并注册目标实体
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -71,11 +71,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
_testAdapter.AddTestEntity("target1", _target);
|
||||
|
||||
// 创建并注册导弹实体
|
||||
var missileInitialMotion = new MotionParameters
|
||||
var missileInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(500, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var missileProperties = new MissileProperties
|
||||
@ -137,8 +137,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {initialPosition}, 初始速度: {initialVelocity}");
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
@ -184,8 +184,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
@ -227,8 +227,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
@ -270,8 +270,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
@ -323,8 +323,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
@ -373,8 +373,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
|
||||
@ -26,11 +26,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
// 创建末敏子弹
|
||||
var initialParams = new MotionParameters
|
||||
var initialParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 100, 0),
|
||||
Orientation = new Orientation(0, -Math.PI/2, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var missileProperties = new MissileProperties();
|
||||
|
||||
@ -50,11 +50,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 创建并注册目标实体
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -69,11 +69,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
_testAdapter.AddTestEntity("target1", _target);
|
||||
|
||||
// 创建并注册导弹实体
|
||||
var missileInitialMotion = new MotionParameters
|
||||
var missileInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(500, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var missileProperties = new MissileProperties
|
||||
@ -133,8 +133,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
System.Diagnostics.Debug.WriteLine($"测试开始 - 初始位置: {initialPosition}, 初始速度: {initialVelocity}");
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
@ -180,8 +180,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
@ -222,8 +222,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
@ -262,8 +262,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
@ -315,8 +315,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
@ -365,8 +365,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
var initialVelocity = new Vector3D(100, 0, 0);
|
||||
|
||||
// 更新导弹位置和速度
|
||||
_missile.Position = initialPosition;
|
||||
_missile.Velocity = initialVelocity;
|
||||
_missile.KState.Position = initialPosition;
|
||||
_missile.KState.Velocity = initialVelocity;
|
||||
|
||||
// 更新一次系统,使其跟踪目标
|
||||
_guidanceSystem.Update(0.1);
|
||||
|
||||
@ -26,11 +26,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
// 创建末敏子弹
|
||||
var initialParams = new MotionParameters
|
||||
var initialParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 100, 0),
|
||||
Orientation = new Orientation(0, -Math.PI/2, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var missileProperties = new MissileProperties();
|
||||
@ -223,11 +223,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
{
|
||||
// Arrange
|
||||
// 添加一个模拟目标以产生传感器数据
|
||||
var targetInitialMotion = new MotionParameters
|
||||
var targetInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 500),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
var targetProperties = new EquipmentProperties
|
||||
{
|
||||
|
||||
@ -65,7 +65,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// Act
|
||||
var smokeGrenade = new SmokeGrenade("test_wall", config, new MotionParameters(), _simulationManager);
|
||||
var smokeGrenade = new SmokeGrenade("test_wall", config, new KinematicState(), _simulationManager);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(SmokeScreenType.Wall, config.SmokeType);
|
||||
@ -90,7 +90,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// Act
|
||||
var smokeGrenade = new SmokeGrenade("test_cloud", config, new MotionParameters(), _simulationManager);
|
||||
var smokeGrenade = new SmokeGrenade("test_cloud", config, new KinematicState(), _simulationManager);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(SmokeScreenType.Cloud, config.SmokeType);
|
||||
@ -108,7 +108,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
Concentration = 0.2,
|
||||
Duration = 60.0
|
||||
};
|
||||
var smokeGrenade = new SmokeGrenade("test", config, new MotionParameters(), _simulationManager);
|
||||
var smokeGrenade = new SmokeGrenade("test", config, new KinematicState(), _simulationManager);
|
||||
|
||||
// Act
|
||||
smokeGrenade.Activate();
|
||||
@ -134,7 +134,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
Thickness = 5.0
|
||||
};
|
||||
|
||||
var motionParams = new MotionParameters
|
||||
var motionParams = new KinematicState
|
||||
{
|
||||
Position = Vector3D.Zero,
|
||||
Orientation = Orientation.FromVector(Vector3D.UnitZ) // 使用Z轴单位向量设置朝向
|
||||
@ -191,7 +191,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
CloudDiameter = 20.0
|
||||
};
|
||||
var initialPosition = new Vector3D(0, 0, 0);
|
||||
var motionParams = new MotionParameters { Position = initialPosition };
|
||||
var motionParams = new KinematicState { Position = initialPosition };
|
||||
var smokeGrenade = new SmokeGrenade("test", config, motionParams, _simulationManager);
|
||||
smokeGrenade.Activate();
|
||||
|
||||
@ -205,8 +205,8 @@ namespace ThreatSource.Tests.Jamming
|
||||
double expectedZ = windSpeed * updateTime * Math.Cos(windDirectionRad);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedX, smokeGrenade.Position.X, 2); // 允许2米的误差
|
||||
Assert.Equal(expectedZ, smokeGrenade.Position.Z, 2);
|
||||
Assert.Equal(expectedX, smokeGrenade.KState.Position.X, 2); // 允许2米的误差
|
||||
Assert.Equal(expectedZ, smokeGrenade.KState.Position.Z, 2);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@ -229,7 +229,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
};
|
||||
|
||||
// 设置烟墙朝向为Z轴正方向
|
||||
var motionParams = new MotionParameters
|
||||
var motionParams = new KinematicState
|
||||
{
|
||||
Position = Vector3D.Zero,
|
||||
Orientation = Orientation.FromVector(Vector3D.UnitZ) // 使用Z轴单位向量设置朝向
|
||||
@ -273,7 +273,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
CloudDiameter = 20.0,
|
||||
Thickness = 5.0
|
||||
};
|
||||
var smokeGrenade = new SmokeGrenade("test", config, new MotionParameters(), _simulationManager);
|
||||
var smokeGrenade = new SmokeGrenade("test", config, new KinematicState(), _simulationManager);
|
||||
smokeGrenade.Activate();
|
||||
|
||||
Vector3D observer = new(offsetX, offsetY, -10);
|
||||
@ -314,7 +314,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
Duration = 60.0
|
||||
};
|
||||
|
||||
var motionParams = new MotionParameters { Position = smokeCenterPosition };
|
||||
var motionParams = new KinematicState { Position = smokeCenterPosition };
|
||||
var smokeGrenade = new SmokeGrenade("smoke_high_obs_test", config, motionParams, _simulationManager);
|
||||
|
||||
smokeGrenade.Activate();
|
||||
|
||||
@ -29,11 +29,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
// 创建目标
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100),
|
||||
Orientation = new Orientation(-Math.PI/2, Math.PI/4, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
var tankProperties = new EquipmentProperties
|
||||
{
|
||||
@ -60,11 +60,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
Type = MissileType.TerminalSensitiveSubmunition
|
||||
};
|
||||
|
||||
var submunitionInitialMotion = new MotionParameters
|
||||
var submunitionInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(20, 150, 0),
|
||||
Orientation = new Orientation(-Math.PI/2, -Math.PI/4, 0),
|
||||
InitialSpeed = 20
|
||||
Speed = 20
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
@ -226,11 +226,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
public void TestSubmunitionHitDetection()
|
||||
{
|
||||
// 创建目标
|
||||
var tank3InitialMotion = new MotionParameters
|
||||
var tank3InitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
var tankProperties = new EquipmentProperties
|
||||
{
|
||||
@ -256,11 +256,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
Type = MissileType.TerminalSensitiveSubmunition
|
||||
};
|
||||
|
||||
var submunitionInitialMotion = new MotionParameters
|
||||
var submunitionInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 6, 0),
|
||||
Orientation = new Orientation(0, -Math.PI/2, 0),
|
||||
InitialSpeed = 10
|
||||
Speed = 10
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
@ -292,7 +292,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
tank.Update(0.02);
|
||||
|
||||
// 计算目标方向
|
||||
var direction = tank.Position - submunition.Position;
|
||||
var direction = tank.KState.Position - submunition.KState.Position;
|
||||
direction = direction.Normalize();
|
||||
|
||||
// 计算所需朝向
|
||||
@ -302,19 +302,19 @@ namespace ThreatSource.Tests.Jamming
|
||||
0);
|
||||
|
||||
// 更新子弹朝向和速度
|
||||
submunition.Orientation = targetOrientation;
|
||||
submunition.Velocity = direction * submunition.Speed;
|
||||
submunition.KState.Orientation = targetOrientation;
|
||||
submunition.KState.Velocity = direction * submunition.KState.Speed;
|
||||
|
||||
// 更新子弹位置
|
||||
submunition.Update(0.02);
|
||||
|
||||
// 输出调试信息
|
||||
Console.WriteLine($"更新 {i}:");
|
||||
Console.WriteLine($"子弹位置: {submunition.Position}");
|
||||
Console.WriteLine($"目标位置: {tank.Position}");
|
||||
Console.WriteLine($"距离: {(tank.Position - submunition.Position).Magnitude()}");
|
||||
Console.WriteLine($"子弹位置: {submunition.KState.Position}");
|
||||
Console.WriteLine($"目标位置: {tank.KState.Position}");
|
||||
Console.WriteLine($"距离: {(tank.KState.Position - submunition.KState.Position).Magnitude()}");
|
||||
|
||||
if ((tank.Position - submunition.Position).Magnitude() < 5)
|
||||
if ((tank.KState.Position - submunition.KState.Position).Magnitude() < 5)
|
||||
{
|
||||
hasExploded = true;
|
||||
break;
|
||||
@ -329,11 +329,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
public void TestDecelerationStageJamming()
|
||||
{
|
||||
// 创建目标
|
||||
var tank5InitialMotion = new MotionParameters
|
||||
var tank5InitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100),
|
||||
Orientation = new Orientation(-Math.PI/2, Math.PI/4, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
var tankProperties = new EquipmentProperties
|
||||
{
|
||||
@ -355,11 +355,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
ExplosionRadius = 5
|
||||
};
|
||||
|
||||
var submunitionInitialMotion = new MotionParameters
|
||||
var submunitionInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 400, 0),
|
||||
Orientation = new Orientation(-Math.PI/2, -Math.PI/4, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
@ -439,11 +439,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
public void TestParachuteDeploymentStageJamming()
|
||||
{
|
||||
// 创建目标
|
||||
var tank6InitialMotion = new MotionParameters
|
||||
var tank6InitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100),
|
||||
Orientation = new Orientation(-Math.PI/2, Math.PI/4, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
var tankProperties = new EquipmentProperties
|
||||
{
|
||||
@ -466,11 +466,11 @@ namespace ThreatSource.Tests.Jamming
|
||||
ExplosionRadius = 5
|
||||
};
|
||||
|
||||
var submunitionInitialMotion = new MotionParameters
|
||||
var submunitionInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 300, 0),
|
||||
Orientation = new Orientation(0.0, -Math.PI/2, 0.0), // Vertically downwards (-Z along world -Y)
|
||||
InitialSpeed = 40 // 设置为减速阶段末速度
|
||||
Speed = 40 // 设置为减速阶段末速度
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
@ -534,7 +534,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
Assert.IsTrue(status.ExtendedProperties["IsSensorsJammed"].ToString() == "True", "子弹状态应该反映传感器受到干扰");
|
||||
|
||||
// 记录干扰时的位置
|
||||
var jammedPosition = submunition.Position;
|
||||
var jammedPosition = submunition.KState.Position;
|
||||
|
||||
// 继续更新一段时间
|
||||
for (int i = 0; i < 10; i++)
|
||||
@ -543,7 +543,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
}
|
||||
|
||||
// 验证在干扰期间的行为
|
||||
var currentPosition = submunition.Position;
|
||||
var currentPosition = submunition.KState.Position;
|
||||
Console.WriteLine($"干扰期间位置变化:从 {jammedPosition} 到 {currentPosition}");
|
||||
|
||||
// 清除干扰
|
||||
@ -557,7 +557,7 @@ namespace ThreatSource.Tests.Jamming
|
||||
Assert.IsFalse(status.ExtendedProperties["IsSensorsJammed"].ToString() == "True", "子弹状态应该反映传感器恢复正常");
|
||||
|
||||
// 验证速度变化
|
||||
Assert.IsTrue(submunition.Speed <= 40, "速度应该保持在开伞阶段的限制范围内");
|
||||
Assert.IsTrue(submunition.KState.Speed <= 40, "速度应该保持在开伞阶段的限制范围内");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,11 +34,11 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.LaserSemiActiveGuidance
|
||||
};
|
||||
|
||||
var missileInitialMotion = new MotionParameters
|
||||
var missileInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var laserCodeConfig = new LaserCodeConfig
|
||||
@ -77,9 +77,9 @@ namespace ThreatSource.Tests.Missile
|
||||
public void Constructor_InitializesPropertiesCorrectly()
|
||||
{
|
||||
Assert.Equal("missile1", _missile.Id);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.Orientation);
|
||||
Assert.Equal(100, _missile.Speed);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.KState.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.KState.Orientation);
|
||||
Assert.Equal(100, _missile.KState.Speed);
|
||||
Assert.False(_missile.IsActive);
|
||||
Assert.False(_missile.IsGuidance);
|
||||
Assert.Equal(0, _missile.FlightTime);
|
||||
@ -106,7 +106,7 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_missile.Activate();
|
||||
_missile.Fire();
|
||||
var initialPosition = _missile.Position;
|
||||
var initialPosition = _missile.KState.Position;
|
||||
var deltaTime = 1.0;
|
||||
|
||||
// Act
|
||||
@ -114,8 +114,8 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
// Assert
|
||||
Assert.Equal(deltaTime, _missile.FlightTime);
|
||||
Assert.Equal(_missile.Speed * deltaTime, _missile.FlightDistance);
|
||||
Assert.NotEqual(initialPosition, _missile.Position);
|
||||
Assert.Equal(_missile.KState.Speed * deltaTime, _missile.FlightDistance);
|
||||
Assert.NotEqual(initialPosition, _missile.KState.Position);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -129,7 +129,7 @@ namespace ThreatSource.Tests.Missile
|
||||
_missile.Update(deltaTime);
|
||||
|
||||
// Assert
|
||||
Assert.True(_missile.Speed <= _properties.MaxSpeed);
|
||||
Assert.True(_missile.KState.Speed <= _properties.MaxSpeed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -166,8 +166,8 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
// Assert
|
||||
Assert.Contains(_missile.Id, status);
|
||||
Assert.Contains(_missile.Position.ToString(), status);
|
||||
Assert.Contains(_missile.Speed.ToString(), status);
|
||||
Assert.Contains(_missile.KState.Position.ToString(), status);
|
||||
Assert.Contains(_missile.KState.Speed.ToString(), status);
|
||||
Assert.Contains(_missile.FlightTime.ToString(), status);
|
||||
Assert.Contains(_missile.FlightDistance.ToString(), status);
|
||||
}
|
||||
@ -181,10 +181,10 @@ namespace ThreatSource.Tests.Missile
|
||||
// Assert
|
||||
Assert.Equal(_missile.Id, state.Id);
|
||||
Assert.Equal(_properties.Type, state.ExtendedProperties["Type"]);
|
||||
Assert.Equal(_missile.Position, state.Position);
|
||||
Assert.Equal(_missile.Velocity, state.ExtendedProperties["Velocity"]);
|
||||
Assert.Equal(_missile.Orientation, state.Orientation);
|
||||
Assert.Equal(_missile.Speed, state.Speed);
|
||||
Assert.Equal(_missile.KState.Position, state.KState.Position);
|
||||
Assert.Equal(_missile.KState.Velocity, state.KState.Velocity);
|
||||
Assert.Equal(_missile.KState.Orientation, state.KState.Orientation);
|
||||
Assert.Equal(_missile.KState.Speed, state.KState.Speed);
|
||||
Assert.Equal(_missile.FlightTime, state.ExtendedProperties["FlightTime"]);
|
||||
Assert.Equal(_missile.FlightDistance, state.ExtendedProperties["FlightDistance"]);
|
||||
Assert.Equal(_missile.IsGuidance, state.ExtendedProperties["IsGuidance"]);
|
||||
|
||||
@ -39,11 +39,11 @@ namespace ThreatSource.Tests.Missile
|
||||
JammingResistanceThreshold = 1e-3
|
||||
};
|
||||
|
||||
var missileInitialMotion = new MotionParameters
|
||||
var missileInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
_missile = new InfraredCommandGuidedMissile(
|
||||
@ -60,9 +60,9 @@ namespace ThreatSource.Tests.Missile
|
||||
public void Constructor_InitializesPropertiesCorrectly()
|
||||
{
|
||||
Assert.Equal("missile1", _missile.Id);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.Orientation);
|
||||
Assert.Equal(100, _missile.Speed);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.KState.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.KState.Orientation);
|
||||
Assert.Equal(100, _missile.KState.Speed);
|
||||
Assert.False(_missile.IsActive);
|
||||
Assert.False(_missile.IsGuidance);
|
||||
Assert.Equal(1000, _missile.RadiationPower); // 默认红外辐射功率
|
||||
@ -174,10 +174,10 @@ namespace ThreatSource.Tests.Missile
|
||||
// Assert
|
||||
Assert.Equal(_missile.Id, state.Id);
|
||||
Assert.Equal(MissileType.InfraredCommandGuidance, state.ExtendedProperties["Type"]);
|
||||
Assert.Equal(_missile.Position, state.Position);
|
||||
Assert.Equal(_missile.Velocity, state.ExtendedProperties["Velocity"]);
|
||||
Assert.Equal(_missile.Orientation, state.Orientation);
|
||||
Assert.Equal(_missile.Speed, state.Speed);
|
||||
Assert.Equal(_missile.KState.Position, state.KState.Position);
|
||||
Assert.Equal(_missile.KState.Velocity, state.KState.Velocity);
|
||||
Assert.Equal(_missile.KState.Orientation, state.KState.Orientation);
|
||||
Assert.Equal(_missile.KState.Speed, state.KState.Speed);
|
||||
Assert.Equal(_missile.FlightTime, state.ExtendedProperties["FlightTime"]);
|
||||
Assert.Equal(_missile.FlightDistance, state.ExtendedProperties["FlightDistance"]);
|
||||
Assert.Equal(_missile.IsGuidance, state.ExtendedProperties["IsGuidance"]);
|
||||
|
||||
@ -13,7 +13,7 @@ namespace ThreatSource.Tests.Missile
|
||||
private readonly SimulationManager _simulationManager;
|
||||
private readonly InfraredImagingTerminalGuidedMissile _missile;
|
||||
private readonly MissileProperties _properties;
|
||||
private readonly MotionParameters _initialMotion;
|
||||
private readonly KinematicState _initialMotion;
|
||||
|
||||
public InfraredImagingTerminalGuidedMissileTests()
|
||||
{
|
||||
@ -32,11 +32,11 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.InfraredImagingTerminalGuidance
|
||||
};
|
||||
|
||||
_initialMotion = new MotionParameters
|
||||
_initialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var guidanceConfig = new InfraredImagingGuidanceConfig
|
||||
@ -63,9 +63,9 @@ namespace ThreatSource.Tests.Missile
|
||||
public void Constructor_InitializesPropertiesCorrectly()
|
||||
{
|
||||
Assert.Equal("missile1", _missile.Id);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.Orientation);
|
||||
Assert.Equal(100, _missile.Speed);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.KState.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.KState.Orientation);
|
||||
Assert.Equal(100, _missile.KState.Speed);
|
||||
Assert.False(_missile.IsActive);
|
||||
Assert.False(_missile.IsGuidance);
|
||||
}
|
||||
@ -100,11 +100,11 @@ namespace ThreatSource.Tests.Missile
|
||||
}
|
||||
|
||||
// 7. 末制导阶段
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(500, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
var tankProperties = new EquipmentProperties
|
||||
{
|
||||
@ -162,10 +162,10 @@ namespace ThreatSource.Tests.Missile
|
||||
// Assert
|
||||
Assert.Equal(_missile.Id, state.Id);
|
||||
Assert.Equal(MissileType.InfraredImagingTerminalGuidance, state.ExtendedProperties["Type"]);
|
||||
Assert.Equal(_missile.Position, state.Position);
|
||||
Assert.Equal(_missile.Velocity, state.ExtendedProperties["Velocity"]);
|
||||
Assert.Equal(_missile.Orientation, state.Orientation);
|
||||
Assert.Equal(_missile.Speed, state.Speed);
|
||||
Assert.Equal(_missile.KState.Position, state.KState.Position);
|
||||
Assert.Equal(_missile.KState.Velocity, state.KState.Velocity);
|
||||
Assert.Equal(_missile.KState.Orientation, state.KState.Orientation);
|
||||
Assert.Equal(_missile.KState.Speed, state.KState.Speed);
|
||||
Assert.Equal(_missile.FlightTime, state.ExtendedProperties["FlightTime"]);
|
||||
Assert.Equal(_missile.FlightDistance, state.ExtendedProperties["FlightDistance"]);
|
||||
Assert.Equal(_missile.IsGuidance, state.ExtendedProperties["IsGuidance"]);
|
||||
@ -195,9 +195,9 @@ namespace ThreatSource.Tests.Missile
|
||||
_missile.Fire();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(_initialMotion.InitialSpeed, _missile.Speed);
|
||||
Assert.Equal(_initialMotion.Position, _missile.Position);
|
||||
Assert.Equal(_initialMotion.Orientation, _missile.Orientation);
|
||||
Assert.Equal(_initialMotion.Speed, _missile.KState.Speed);
|
||||
Assert.Equal(_initialMotion.Position, _missile.KState.Position);
|
||||
Assert.Equal(_initialMotion.Orientation, _missile.KState.Orientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -33,11 +33,11 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.LaserBeamRiderGuidance
|
||||
};
|
||||
|
||||
var missileInitialMotion = new MotionParameters
|
||||
var missileInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var laserCodeConfig = new LaserCodeConfig
|
||||
@ -71,9 +71,9 @@ namespace ThreatSource.Tests.Missile
|
||||
public void Constructor_InitializesPropertiesCorrectly()
|
||||
{
|
||||
Assert.Equal("missile1", _missile.Id);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.Orientation);
|
||||
Assert.Equal(100, _missile.Speed);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.KState.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.KState.Orientation);
|
||||
Assert.Equal(100, _missile.KState.Speed);
|
||||
Assert.False(_missile.IsActive);
|
||||
Assert.False(_missile.IsGuidance);
|
||||
}
|
||||
@ -152,10 +152,10 @@ namespace ThreatSource.Tests.Missile
|
||||
// Assert
|
||||
Assert.Equal(_missile.Id, state.Id);
|
||||
Assert.Equal(MissileType.LaserBeamRiderGuidance, state.ExtendedProperties["Type"]);
|
||||
Assert.Equal(_missile.Position, state.Position);
|
||||
Assert.Equal(_missile.Velocity, state.ExtendedProperties["Velocity"]);
|
||||
Assert.Equal(_missile.Orientation, state.Orientation);
|
||||
Assert.Equal(_missile.Speed, state.Speed);
|
||||
Assert.Equal(_missile.KState.Position, state.KState.Position);
|
||||
Assert.Equal(_missile.KState.Velocity, state.KState.Velocity);
|
||||
Assert.Equal(_missile.KState.Orientation, state.KState.Orientation);
|
||||
Assert.Equal(_missile.KState.Speed, state.KState.Speed);
|
||||
Assert.Equal(_missile.FlightTime, state.ExtendedProperties["FlightTime"]);
|
||||
Assert.Equal(_missile.FlightDistance, state.ExtendedProperties["FlightDistance"]);
|
||||
Assert.Equal(_missile.IsGuidance, state.ExtendedProperties["IsGuidance"]);
|
||||
|
||||
@ -38,22 +38,22 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.LaserSemiActiveGuidance
|
||||
};
|
||||
|
||||
var missileInitialMotion = new MotionParameters
|
||||
var missileInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
// 创建并注册模拟的激光指示器,位置在导弹后方100米处
|
||||
_laserDesignator = new MockLaserDesignator("laser1", _simulationManager);
|
||||
_laserDesignator.Position = new Vector3D(-100, 0, 0);
|
||||
_laserDesignator.KState.Position = new Vector3D(-100, 0, 0);
|
||||
_laserDesignator.config.Power = 100; // 设置足够高的激光功率
|
||||
_testAdapter.AddTestEntity("laser1", _laserDesignator);
|
||||
|
||||
// 创建并注册模拟的目标,位置在导弹前方1000米处
|
||||
_target = new MockTarget("target1", _simulationManager);
|
||||
_target.Position = new Vector3D(1000, 0, 0);
|
||||
_target.KState.Position = new Vector3D(1000, 0, 0);
|
||||
_testAdapter.AddTestEntity("target1", _target);
|
||||
|
||||
var laserCodeConfig = new LaserCodeConfig
|
||||
@ -97,11 +97,11 @@ namespace ThreatSource.Tests.Missile
|
||||
Power = 100,
|
||||
DivergenceAngle = 0.001,
|
||||
Wavelength = 1.06
|
||||
}, new MotionParameters
|
||||
}, new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
}, simulationManager)
|
||||
{
|
||||
// 不需要额外设置属性,因为基类构造函数已经设置了
|
||||
@ -112,11 +112,11 @@ namespace ThreatSource.Tests.Missile
|
||||
private class MockTarget : Tank
|
||||
{
|
||||
public MockTarget(string id, ISimulationManager simulationManager)
|
||||
: base(id, new EquipmentProperties(), new MotionParameters
|
||||
: base(id, new EquipmentProperties(), new KinematicState
|
||||
{
|
||||
Position = new Vector3D(1000, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
}, simulationManager)
|
||||
{
|
||||
// 不需要额外设置属性,因为基类构造函数已经设置了
|
||||
@ -234,8 +234,8 @@ namespace ThreatSource.Tests.Missile
|
||||
_missile.Update(0.1); // Move past launch stage
|
||||
|
||||
// 设置激光指示器和目标位置,确保在视场角内
|
||||
_laserDesignator.Position = new Vector3D(-100, 0, 0);
|
||||
_target.Position = new Vector3D(1000, 0, 0);
|
||||
_laserDesignator.KState.Position = new Vector3D(-100, 0, 0);
|
||||
_target.KState.Position = new Vector3D(1000, 0, 0);
|
||||
_laserDesignator.config.Power = 100; // 设置足够高的激光功率
|
||||
|
||||
// Act - Send illumination with disabled code
|
||||
@ -276,8 +276,8 @@ namespace ThreatSource.Tests.Missile
|
||||
_missile.Update(0.1); // Move past launch stage
|
||||
|
||||
// 设置激光指示器和目标位置,确保在视场角内
|
||||
_laserDesignator.Position = new Vector3D(-100, 0, 0);
|
||||
_target.Position = new Vector3D(1000, 0, 0);
|
||||
_laserDesignator.KState.Position = new Vector3D(-100, 0, 0);
|
||||
_target.KState.Position = new Vector3D(1000, 0, 0);
|
||||
_laserDesignator.config.Power = 100; // 设置足够高的激光功率
|
||||
|
||||
// First enable guidance with matching code
|
||||
|
||||
@ -32,11 +32,11 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.LaserSemiActiveGuidance
|
||||
};
|
||||
|
||||
var missileInitialMotion = new MotionParameters
|
||||
var missileInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var laserCodeConfig = new LaserCodeConfig
|
||||
@ -75,9 +75,9 @@ namespace ThreatSource.Tests.Missile
|
||||
public void Constructor_InitializesPropertiesCorrectly()
|
||||
{
|
||||
Assert.Equal("missile1", _missile.Id);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.Orientation);
|
||||
Assert.Equal(100, _missile.Speed);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.KState.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.KState.Orientation);
|
||||
Assert.Equal(100, _missile.KState.Speed);
|
||||
Assert.False(_missile.IsActive);
|
||||
Assert.False(_missile.IsGuidance);
|
||||
}
|
||||
@ -156,10 +156,10 @@ namespace ThreatSource.Tests.Missile
|
||||
// Assert
|
||||
Assert.Equal(_missile.Id, state.Id);
|
||||
Assert.Equal(MissileType.LaserSemiActiveGuidance, state.ExtendedProperties["Type"]);
|
||||
Assert.Equal(_missile.Position, state.Position);
|
||||
Assert.Equal(_missile.Velocity, state.ExtendedProperties["Velocity"]);
|
||||
Assert.Equal(_missile.Orientation, state.Orientation);
|
||||
Assert.Equal(_missile.Speed, state.Speed);
|
||||
Assert.Equal(_missile.KState.Position, state.KState.Position);
|
||||
Assert.Equal(_missile.KState.Velocity, state.KState.Velocity);
|
||||
Assert.Equal(_missile.KState.Orientation, state.KState.Orientation);
|
||||
Assert.Equal(_missile.KState.Speed, state.KState.Speed);
|
||||
Assert.Equal(_missile.FlightTime, state.ExtendedProperties["FlightTime"]);
|
||||
Assert.Equal(_missile.FlightDistance, state.ExtendedProperties["FlightDistance"]);
|
||||
Assert.Equal(_missile.IsGuidance, state.ExtendedProperties["IsGuidance"]);
|
||||
|
||||
@ -34,11 +34,11 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.MillimeterWaveTerminalGuidance
|
||||
};
|
||||
|
||||
var missileInitialMotion = new MotionParameters
|
||||
var missileInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 100
|
||||
Speed = 100
|
||||
};
|
||||
|
||||
var guidanceConfig = new MillimeterWaveGuidanceConfig
|
||||
@ -63,9 +63,9 @@ namespace ThreatSource.Tests.Missile
|
||||
public void Constructor_InitializesPropertiesCorrectly()
|
||||
{
|
||||
Assert.Equal("missile1", _missile.Id);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.Orientation);
|
||||
Assert.Equal(100, _missile.Speed);
|
||||
Assert.Equal(new Vector3D(0, 0, 0), _missile.KState.Position);
|
||||
Assert.Equal(new Orientation(0, 0, 0), _missile.KState.Orientation);
|
||||
Assert.Equal(100, _missile.KState.Speed);
|
||||
Assert.False(_missile.IsActive);
|
||||
Assert.False(_missile.IsGuidance);
|
||||
}
|
||||
@ -116,10 +116,10 @@ namespace ThreatSource.Tests.Missile
|
||||
// Assert
|
||||
Assert.Equal(_missile.Id, state.Id);
|
||||
Assert.Equal(MissileType.MillimeterWaveTerminalGuidance, state.ExtendedProperties["Type"]);
|
||||
Assert.Equal(_missile.Position, state.Position);
|
||||
Assert.Equal(_missile.Velocity, state.ExtendedProperties["Velocity"]);
|
||||
Assert.Equal(_missile.Orientation, state.Orientation);
|
||||
Assert.Equal(_missile.Speed, state.Speed);
|
||||
Assert.Equal(_missile.KState.Position, state.KState.Position);
|
||||
Assert.Equal(_missile.KState.Velocity, state.KState.Velocity);
|
||||
Assert.Equal(_missile.KState.Orientation, state.KState.Orientation);
|
||||
Assert.Equal(_missile.KState.Speed, state.KState.Speed);
|
||||
Assert.Equal(_missile.FlightTime, state.ExtendedProperties["FlightTime"]);
|
||||
Assert.Equal(_missile.FlightDistance, state.ExtendedProperties["FlightDistance"]);
|
||||
Assert.Equal(_missile.IsGuidance, state.ExtendedProperties["IsGuidance"]);
|
||||
|
||||
@ -17,7 +17,7 @@ namespace ThreatSource.Tests.Missile
|
||||
private readonly MissileProperties _properties;
|
||||
private readonly MissileProperties _submunitionProperties;
|
||||
private readonly Tank _tank;
|
||||
private readonly MotionParameters _missileInitialMotion;
|
||||
private readonly KinematicState _missileInitialMotion;
|
||||
|
||||
public TerminalSensitiveMissileTests(ITestOutputHelper output)
|
||||
{
|
||||
@ -27,11 +27,11 @@ namespace ThreatSource.Tests.Missile
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
// 先创建并注册目标
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100),
|
||||
Orientation = new Orientation(-Math.PI/2, Math.PI/4, 0), // 目标朝向45度 (原Yaw=PI/4)
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -64,11 +64,11 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.TerminalSensitiveMissile
|
||||
};
|
||||
|
||||
_missileInitialMotion = new MotionParameters
|
||||
_missileInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(3000, 0, 100),
|
||||
Orientation = new Orientation(Math.PI/2, 0.0, 0.0), // 原Yaw=PI
|
||||
InitialSpeed = 800
|
||||
Speed = 800
|
||||
};
|
||||
|
||||
_submunitionProperties = new MissileProperties
|
||||
@ -109,8 +109,8 @@ namespace ThreatSource.Tests.Missile
|
||||
public void Constructor_InitializesPropertiesCorrectly()
|
||||
{
|
||||
Assert.Equal("missile1", _missile.Id);
|
||||
Assert.Equal(new Vector3D(3000, 0, 100), _missile.Position);
|
||||
Assert.Equal(800, _missile.Speed);
|
||||
Assert.Equal(new Vector3D(3000, 0, 100), _missile.KState.Position);
|
||||
Assert.Equal(800, _missile.KState.Speed);
|
||||
Assert.False(_missile.IsActive);
|
||||
Assert.False(_missile.IsGuidance);
|
||||
}
|
||||
@ -126,13 +126,13 @@ namespace ThreatSource.Tests.Missile
|
||||
var publishedEvents = _testAdapter.GetPublishedEvents();
|
||||
bool submunitionsRegistered = false;
|
||||
double totalTime = 0;
|
||||
Vector3D lastPosition = _missile.Position;
|
||||
Vector3D lastPosition = _missile.KState.Position;
|
||||
|
||||
_output.WriteLine("\n开始测试导弹分离:");
|
||||
_output.WriteLine($"初始位置:{_missile.Position}");
|
||||
_output.WriteLine($"初始速度:{_missile.Velocity},大小:{_missile.Velocity.Magnitude():F1}米/秒");
|
||||
_output.WriteLine($"目标位置:{_tank.Position}");
|
||||
Vector3D separationPoint = Vector3D.PointOnLine(_tank.Position, _missile.Position, 1000) + new Vector3D(0, 1000, 0);
|
||||
_output.WriteLine($"初始位置:{_missile.KState.Position}");
|
||||
_output.WriteLine($"初始速度:{_missile.KState.Velocity},大小:{_missile.KState.Velocity.Magnitude():F1}米/秒");
|
||||
_output.WriteLine($"目标位置:{_tank.KState.Position}");
|
||||
Vector3D separationPoint = Vector3D.PointOnLine(_tank.KState.Position, _missile.KState.Position, 1000) + new Vector3D(0, 1000, 0);
|
||||
_output.WriteLine($"分离点:{separationPoint}");
|
||||
_output.WriteLine($"制导状态:{_missile.IsGuidance}");
|
||||
_output.WriteLine("-------------------");
|
||||
@ -146,12 +146,12 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
// 每一步都输出状态
|
||||
_output.WriteLine($"\n时间:{totalTime:F1}秒");
|
||||
_output.WriteLine($"位置:({_missile.Position.X:F1}, {_missile.Position.Y:F1}, {_missile.Position.Z:F1})");
|
||||
_output.WriteLine($"速度:{_missile.Velocity.Magnitude():F1}米/秒");
|
||||
_output.WriteLine($"速度方向:({_missile.Velocity.X:F1}, {_missile.Velocity.Y:F1}, {_missile.Velocity.Z:F1})");
|
||||
_output.WriteLine($"位置:({_missile.KState.Position.X:F1}, {_missile.KState.Position.Y:F1}, {_missile.KState.Position.Z:F1})");
|
||||
_output.WriteLine($"速度:{_missile.KState.Velocity.Magnitude():F1}米/秒");
|
||||
_output.WriteLine($"速度方向:({_missile.KState.Velocity.X:F1}, {_missile.KState.Velocity.Y:F1}, {_missile.KState.Velocity.Z:F1})");
|
||||
_output.WriteLine($"制导状态:{_missile.IsGuidance}");
|
||||
_output.WriteLine($"距离分离点:{(separationPoint - _missile.Position).Magnitude():F1}米");
|
||||
lastPosition = _missile.Position;
|
||||
_output.WriteLine($"距离分离点:{(separationPoint - _missile.KState.Position).Magnitude():F1}米");
|
||||
lastPosition = _missile.KState.Position;
|
||||
|
||||
// 检查是否有子弹被注册
|
||||
var entities = _simulationManager.GetAllEntities();
|
||||
@ -160,7 +160,7 @@ namespace ThreatSource.Tests.Missile
|
||||
if (submunitionsRegistered)
|
||||
{
|
||||
_output.WriteLine($"\n分离发生在时间:{totalTime:F1}秒");
|
||||
_output.WriteLine($"分离位置:{_missile.Position}");
|
||||
_output.WriteLine($"分离位置:{_missile.KState.Position}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -213,10 +213,10 @@ namespace ThreatSource.Tests.Missile
|
||||
// Assert
|
||||
Assert.Equal(_missile.Id, state.Id);
|
||||
Assert.Equal(MissileType.TerminalSensitiveMissile, state.ExtendedProperties["Type"]);
|
||||
Assert.Equal(_missile.Position, state.Position);
|
||||
Assert.Equal(_missile.Velocity, state.ExtendedProperties["Velocity"]);
|
||||
Assert.Equal(_missile.Orientation, state.Orientation);
|
||||
Assert.Equal(_missile.Speed, state.Speed);
|
||||
Assert.Equal(_missile.KState.Position, state.KState.Position);
|
||||
Assert.Equal(_missile.KState.Velocity, state.KState.Velocity);
|
||||
Assert.Equal(_missile.KState.Orientation, state.KState.Orientation);
|
||||
Assert.Equal(_missile.KState.Speed, state.KState.Speed);
|
||||
Assert.Equal(_missile.FlightTime, state.ExtendedProperties["FlightTime"]);
|
||||
Assert.Equal(_missile.FlightDistance, state.ExtendedProperties["FlightDistance"]);
|
||||
Assert.Equal(_missile.IsGuidance, state.ExtendedProperties["IsGuidance"]);
|
||||
|
||||
@ -17,7 +17,7 @@ namespace ThreatSource.Tests.Missile
|
||||
private readonly MissileProperties _properties;
|
||||
private readonly Tank _tank;
|
||||
private readonly ITestOutputHelper _output;
|
||||
private readonly MotionParameters _submunitionInitialMotion;
|
||||
private readonly KinematicState _submunitionInitialMotion;
|
||||
|
||||
public TerminalSensitiveSubmunitionTests(ITestOutputHelper output)
|
||||
{
|
||||
@ -27,11 +27,11 @@ namespace ThreatSource.Tests.Missile
|
||||
_simulationManager.SetSimulationAdapter(_testAdapter);
|
||||
|
||||
// 先创建并注册目标
|
||||
var tankInitialMotion = new MotionParameters
|
||||
var tankInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 100), // 目标位置
|
||||
Orientation = new Orientation(-Math.PI/2, Math.PI/4, 0), // 目标朝向45度 (Original Yaw=PI/4)
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -63,11 +63,11 @@ namespace ThreatSource.Tests.Missile
|
||||
Type = MissileType.TerminalSensitiveMissile
|
||||
};
|
||||
|
||||
_submunitionInitialMotion = new MotionParameters
|
||||
_submunitionInitialMotion = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(1100, 400, 100), // 在目标前方1000米,高度400米
|
||||
Orientation = new Orientation(-Math.PI/2, -Math.PI/4, 0), // 向下45度 (Original Pitch=-PI/4, Yaw=0)
|
||||
InitialSpeed = 200
|
||||
Speed = 200
|
||||
};
|
||||
|
||||
var submunitionConfig = new TerminalSensitiveSubmunitionConfig
|
||||
@ -92,8 +92,8 @@ namespace ThreatSource.Tests.Missile
|
||||
public void Constructor_InitializesPropertiesCorrectly()
|
||||
{
|
||||
Assert.Equal("missile1_Sub_0", _submunition.Id);
|
||||
Assert.Equal(_submunitionInitialMotion.Position, _submunition.Position);
|
||||
Assert.Equal(_submunitionInitialMotion.InitialSpeed, _submunition.Speed);
|
||||
Assert.Equal(_submunitionInitialMotion.Position, _submunition.KState.Position);
|
||||
Assert.Equal(_submunitionInitialMotion.Speed, _submunition.KState.Speed);
|
||||
Assert.False(_submunition.IsActive);
|
||||
Assert.False(_submunition.IsGuidance);
|
||||
}
|
||||
@ -104,14 +104,14 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_submunition.Fire();
|
||||
_submunition.Activate();
|
||||
var initialPosition = _submunition.Position;
|
||||
var initialPosition = _submunition.KState.Position;
|
||||
|
||||
// Act
|
||||
_submunition.Update(0.1);
|
||||
|
||||
// Assert
|
||||
Assert.True(_submunition.IsActive);
|
||||
Assert.NotEqual(initialPosition, _submunition.Position);
|
||||
Assert.NotEqual(initialPosition, _submunition.KState.Position);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -120,7 +120,7 @@ namespace ThreatSource.Tests.Missile
|
||||
// Arrange
|
||||
_submunition.Fire();
|
||||
_submunition.Activate();
|
||||
var initialSpeed = _submunition.Speed;
|
||||
var initialSpeed = _submunition.KState.Speed;
|
||||
|
||||
// Act - 等待进入减速阶段
|
||||
for (double time = 0; time < 2.0; time += 0.1)
|
||||
@ -129,7 +129,7 @@ namespace ThreatSource.Tests.Missile
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.True(_submunition.Speed < initialSpeed);
|
||||
Assert.True(_submunition.KState.Speed < initialSpeed);
|
||||
}
|
||||
|
||||
/* // 注释掉此测试,因为它涉及复杂的扫描探测逻辑,难以在单元测试中精确模拟
|
||||
@ -179,10 +179,10 @@ namespace ThreatSource.Tests.Missile
|
||||
{
|
||||
// Arrange
|
||||
// 设置子弹位置为原点
|
||||
_submunition.Position = new Vector3D(0, 0, 0);
|
||||
_submunition.KState.Position = new Vector3D(0, 0, 0);
|
||||
|
||||
// 设置目标位置为 (100, 0, 0),即正东方向
|
||||
_tank.Position = new Vector3D(100, 0, 0);
|
||||
_tank.KState.Position = new Vector3D(100, 0, 0);
|
||||
|
||||
// 设置扫描角度为 90 度(正北为 0 度,顺时针),即向东
|
||||
double spiralAngle = 90 * Math.PI / 180; // 转换为弧度
|
||||
@ -202,7 +202,7 @@ namespace ThreatSource.Tests.Missile
|
||||
);
|
||||
|
||||
// 计算目标方向
|
||||
Vector3D toTarget = (_tank.Position - _submunition.Position).Normalize();
|
||||
Vector3D toTarget = (_tank.KState.Position - _submunition.KState.Position).Normalize();
|
||||
|
||||
// 计算水平面上的目标方向
|
||||
Vector3D horizontalTargetDirection = new Vector3D(
|
||||
@ -241,7 +241,7 @@ namespace ThreatSource.Tests.Missile
|
||||
|
||||
// 输出调试信息
|
||||
_output.WriteLine($"原始扫描角度: {spiralAngle * 180 / Math.PI:F2}°");
|
||||
_output.WriteLine($"目标位置: {_tank.Position}");
|
||||
_output.WriteLine($"目标位置: {_tank.KState.Position}");
|
||||
_output.WriteLine($"水平扫描方向: {horizontalScanDirection}");
|
||||
_output.WriteLine($"水平目标方向: {horizontalTargetDirection}");
|
||||
_output.WriteLine($"水平面夹角: {horizontalAngle:F2}°");
|
||||
@ -263,11 +263,11 @@ namespace ThreatSource.Tests.Missile
|
||||
{
|
||||
// 设置目标位置
|
||||
var targetPosition = new Vector3D(targetX, targetY, targetZ);
|
||||
_tank.Position = targetPosition;
|
||||
_tank.KState.Position = targetPosition;
|
||||
|
||||
// 设置子弹位置
|
||||
var submunitionPosition = new Vector3D(submunitionX, submunitionY, submunitionZ);
|
||||
_submunition.Position = submunitionPosition;
|
||||
_submunition.KState.Position = submunitionPosition;
|
||||
|
||||
// 计算从子弹到目标的向量
|
||||
var toTarget = (targetPosition - submunitionPosition).Normalize();
|
||||
@ -329,16 +329,16 @@ namespace ThreatSource.Tests.Missile
|
||||
bool detectedAtLeastOnce = false;
|
||||
double radius = 50; // 扫描半径
|
||||
double subHeight = 100; // 子弹高度
|
||||
_submunition.Position = new Vector3D(0, subHeight, 0);
|
||||
_submunition.KState.Position = new Vector3D(0, subHeight, 0);
|
||||
|
||||
for (int angleDeg = 0; angleDeg < 360; angleDeg += 10)
|
||||
{
|
||||
double angleRad = angleDeg * Math.PI / 180;
|
||||
var targetPosition = new Vector3D(radius * Math.Cos(angleRad), 0, radius * Math.Sin(angleRad));
|
||||
_tank.Position = targetPosition;
|
||||
_tank.KState.Position = targetPosition;
|
||||
|
||||
// 使用反射设置 scanDirection 指向目标
|
||||
var toTarget = (targetPosition - _submunition.Position).Normalize();
|
||||
var toTarget = (targetPosition - _submunition.KState.Position).Normalize();
|
||||
var field = typeof(TerminalSensitiveSubmunition)
|
||||
.GetField("scanDirection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
|
||||
|
||||
@ -258,7 +258,7 @@ namespace ThreatSource.Tests.Simulation
|
||||
internal class MockSimulationElement : SimulationElement
|
||||
{
|
||||
public MockSimulationElement(string id)
|
||||
: base(id, new MotionParameters(), null!)
|
||||
: base(id, new KinematicState(), null!)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -18,11 +18,11 @@ namespace ThreatSource.Tests.Target
|
||||
_simulationManager = new SimulationManager();
|
||||
|
||||
// 创建初始运动参数
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(100, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 10
|
||||
Speed = 10
|
||||
};
|
||||
|
||||
// 使用默认值初始化
|
||||
@ -34,11 +34,11 @@ namespace ThreatSource.Tests.Target
|
||||
public void Constructor_InitializesPropertiesCorrectly()
|
||||
{
|
||||
// Arrange & Act
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(200, 0, 0),
|
||||
Orientation = new Orientation(0, 0, 0),
|
||||
InitialSpeed = 10
|
||||
Speed = 10
|
||||
};
|
||||
|
||||
var tankProperties = new EquipmentProperties
|
||||
@ -52,24 +52,24 @@ namespace ThreatSource.Tests.Target
|
||||
// Assert
|
||||
Assert.IsNotNull(tank);
|
||||
Assert.AreEqual("tank2", tank.Id);
|
||||
Assert.IsNotNull(tank.Position);
|
||||
Assert.IsNotNull(tank.Velocity);
|
||||
Assert.IsNotNull(tank.KState.Position);
|
||||
Assert.IsNotNull(tank.KState.Velocity);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Update_UpdatesPositionBasedOnVelocity()
|
||||
{
|
||||
// Arrange
|
||||
var initialPosition = _tank.Position;
|
||||
var initialPosition = _tank.KState.Position;
|
||||
var deltaTime = 1.0f;
|
||||
|
||||
// Act
|
||||
_tank.Update(deltaTime);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(initialPosition.X + _tank.Velocity.X * deltaTime, _tank.Position.X);
|
||||
Assert.AreEqual(initialPosition.Y + _tank.Velocity.Y * deltaTime, _tank.Position.Y);
|
||||
Assert.AreEqual(initialPosition.Z + _tank.Velocity.Z * deltaTime, _tank.Position.Z);
|
||||
Assert.AreEqual(initialPosition.X + _tank.KState.Velocity.X * deltaTime, _tank.KState.Position.X);
|
||||
Assert.AreEqual(initialPosition.Y + _tank.KState.Velocity.Y * deltaTime, _tank.KState.Position.Y);
|
||||
Assert.AreEqual(initialPosition.Z + _tank.KState.Velocity.Z * deltaTime, _tank.KState.Position.Z);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
@ -35,7 +35,7 @@ namespace ThreatSource.Data
|
||||
/// <param name="missileModel">导弹型号</param>
|
||||
/// <param name="launchParams">发射参数</param>
|
||||
/// <returns>导弹实例</returns>
|
||||
public BaseMissile CreateMissile(string missileId, string missileModel, string targetId, MotionParameters launchParams)
|
||||
public BaseMissile CreateMissile(string missileId, string missileModel, string targetId, KinematicState launchParams)
|
||||
{
|
||||
var data = _dataManager.GetMissile(missileModel);
|
||||
|
||||
@ -133,7 +133,7 @@ namespace ThreatSource.Data
|
||||
/// <param name="missileId">导弹ID</param>
|
||||
/// <param name="motionParameters">初始运动参数</param>
|
||||
/// <returns>指示器实例</returns>
|
||||
public BaseIndicator CreateIndicator(string indicatorId, string indicatorModel, string targetId, string missileId, MotionParameters motionParameters)
|
||||
public BaseIndicator CreateIndicator(string indicatorId, string indicatorModel, string targetId, string missileId, KinematicState motionParameters)
|
||||
{
|
||||
var data = _dataManager.GetIndicator(indicatorModel);
|
||||
|
||||
@ -173,7 +173,7 @@ namespace ThreatSource.Data
|
||||
/// <param name="targetModel">目标型号</param>
|
||||
/// <param name="motionParameters">初始运动参数</param>
|
||||
/// <returns>目标实例</returns>
|
||||
public SimulationElement CreateTarget(string targetId, string targetModel, MotionParameters motionParameters)
|
||||
public SimulationElement CreateTarget(string targetId, string targetModel, KinematicState motionParameters)
|
||||
{
|
||||
var data = _dataManager.GetTarget(targetModel);
|
||||
|
||||
@ -227,7 +227,7 @@ namespace ThreatSource.Data
|
||||
/// <param name="motionParameters">初始运动参数</param>
|
||||
/// <param name="sourceId">干扰源ID</param>
|
||||
/// <returns>干扰机实例</returns>
|
||||
public IJammer CreateJammer(string jammerId, string jammerModel, MotionParameters motionParameters, string sourceId)
|
||||
public IJammer CreateJammer(string jammerId, string jammerModel, KinematicState motionParameters, string sourceId)
|
||||
{
|
||||
var data = _dataManager.GetJammer(jammerModel);
|
||||
return data.Type switch
|
||||
|
||||
@ -24,7 +24,7 @@ namespace ThreatSource.Equipment
|
||||
/// 构造函数设置装甲运输车的初始状态:
|
||||
/// - 调用基类构造函数初始化基本属性
|
||||
/// </remarks>
|
||||
public APC(string id, EquipmentProperties equipmentProperties, MotionParameters motionParameters, ISimulationManager simulationManager)
|
||||
public APC(string id, EquipmentProperties equipmentProperties, KinematicState motionParameters, ISimulationManager simulationManager)
|
||||
: base(id, equipmentProperties, motionParameters, simulationManager)
|
||||
{
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ namespace ThreatSource.Equipment
|
||||
/// - 设置初始位置和速度
|
||||
/// - 生命值初始化为100
|
||||
/// </remarks>
|
||||
protected BaseEquipment(string id, EquipmentProperties equipmentProperties, MotionParameters motionParameters, ISimulationManager simulationManager)
|
||||
protected BaseEquipment(string id, EquipmentProperties equipmentProperties, KinematicState motionParameters, ISimulationManager simulationManager)
|
||||
: base(id, motionParameters, simulationManager)
|
||||
{
|
||||
Properties = equipmentProperties;
|
||||
@ -60,7 +60,7 @@ namespace ThreatSource.Equipment
|
||||
public double[,] GetCurrentThermalPattern()
|
||||
{
|
||||
// 根据当前速度判断是否在运动
|
||||
bool isMoving = Velocity.Magnitude() > 0.1; // 速度大于0.1米/秒认为在运动
|
||||
bool isMoving = KState.Velocity.Magnitude() > 0.1; // 速度大于0.1米/秒认为在运动
|
||||
return Properties.ThermalPattern.GetPattern(isMoving);
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ namespace ThreatSource.Equipment
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 更新目标的位置
|
||||
Position += Velocity * deltaTime;
|
||||
KState.Position += KState.Velocity * deltaTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -23,7 +23,7 @@ namespace ThreatSource.Equipment
|
||||
/// 构造函数设置直升机的初始状态:
|
||||
/// - 调用基类构造函数初始化基本属性
|
||||
/// </remarks>
|
||||
public Helicopter(string id, EquipmentProperties equipmentProperties, MotionParameters motionParameters, ISimulationManager simulationManager)
|
||||
public Helicopter(string id, EquipmentProperties equipmentProperties, KinematicState motionParameters, ISimulationManager simulationManager)
|
||||
: base(id, equipmentProperties, motionParameters, simulationManager)
|
||||
{
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ namespace ThreatSource.Equipment
|
||||
/// 构造函数设置坦克的初始状态:
|
||||
/// - 调用基类构造函数初始化基本属性
|
||||
/// </remarks>
|
||||
public Tank(string id, EquipmentProperties equipmentProperties, MotionParameters motionParameters, ISimulationManager simulationManager)
|
||||
public Tank(string id, EquipmentProperties equipmentProperties, KinematicState motionParameters, ISimulationManager simulationManager)
|
||||
: base(id, equipmentProperties, motionParameters, simulationManager)
|
||||
{
|
||||
}
|
||||
|
||||
@ -112,14 +112,12 @@ namespace ThreatSource.Guidance
|
||||
/// - 初始化干扰处理
|
||||
/// </remarks>
|
||||
public BaseGuidanceSystem(string id, string missileId, double maxAcceleration, double proportionalNavigationCoefficient, ISimulationManager simulationManager)
|
||||
: base(id, new MotionParameters(), simulationManager)
|
||||
: base(id, new KinematicState(), simulationManager)
|
||||
{
|
||||
MissileId = missileId;
|
||||
if (SimulationManager.GetEntityById(MissileId) is BaseMissile missile)
|
||||
{
|
||||
Position = missile.Position;
|
||||
Orientation = missile.Orientation;
|
||||
Velocity = missile.Velocity;
|
||||
KState = missile.KState;
|
||||
}
|
||||
|
||||
HasGuidance = false;
|
||||
@ -129,7 +127,7 @@ namespace ThreatSource.Guidance
|
||||
|
||||
// 初始化干扰处理组件
|
||||
_jammingComponent = new JammableComponent(
|
||||
positionProvider: () => base.Position
|
||||
positionProvider: () => base.KState.Position
|
||||
);
|
||||
|
||||
// Subscribe to the events instead
|
||||
@ -185,9 +183,7 @@ namespace ThreatSource.Guidance
|
||||
{
|
||||
if (SimulationManager.GetEntityById(MissileId) is BaseMissile missile)
|
||||
{
|
||||
Position = missile.Position;
|
||||
Orientation = missile.Orientation;
|
||||
Velocity = missile.Velocity;
|
||||
KState = missile.KState;
|
||||
}
|
||||
// 更新干扰状态
|
||||
_jammingComponent.UpdateJammingStatus(deltaTime);
|
||||
|
||||
@ -184,7 +184,7 @@ namespace ThreatSource.Guidance
|
||||
|
||||
Vector3D currentDesiredDirection = (LastTrackerToTargetVector - LastTrackerToMissileVector).Normalize();
|
||||
|
||||
Vector3D currentDirection = Velocity.Normalize();
|
||||
Vector3D currentDirection = KState.Velocity.Normalize();
|
||||
|
||||
if (LastDesiredDirection != null && deltaTime > 0)
|
||||
{
|
||||
@ -200,7 +200,7 @@ namespace ThreatSource.Guidance
|
||||
Vector3D desiredDirectionWithLead = (currentDesiredDirection + leadDirection * turnRate * LeadTimeFactor).Normalize();
|
||||
Vector3D turnAxis = Vector3D.CrossProduct(currentDirection, desiredDirectionWithLead).Normalize();
|
||||
double turnAngle = Vector3D.AngleBetween(currentDirection, desiredDirectionWithLead);
|
||||
double accelerationMagnitude = ProportionalNavigationCoefficient * turnAngle * Velocity.Magnitude();
|
||||
double accelerationMagnitude = ProportionalNavigationCoefficient * turnAngle * KState.Speed;
|
||||
GuidanceAcceleration = Vector3D.CrossProduct(turnAxis, currentDirection) * accelerationMagnitude;
|
||||
|
||||
if (GuidanceAcceleration.Magnitude() > MaxAcceleration)
|
||||
|
||||
@ -189,7 +189,7 @@ namespace ThreatSource.Guidance
|
||||
// 确保 config 和 RadiationTemperature 存在
|
||||
if (smoke.IsActive ==false || smoke.config == null || !smoke.config.IsObscuring || smoke.config.RadiationTemperature <= 0) continue;
|
||||
|
||||
Vector3D toSmoke = smoke.Position - missilePosition;
|
||||
Vector3D toSmoke = smoke.KState.Position - missilePosition;
|
||||
double distance = toSmoke.Magnitude();
|
||||
|
||||
// 粗略检查烟幕是否在前方视野内
|
||||
@ -200,7 +200,7 @@ namespace ThreatSource.Guidance
|
||||
double smokeIntensity = SMOKE_TEMPERATURE_FACTOR * Math.Pow(smoke.config.RadiationTemperature, 4);
|
||||
|
||||
// 投影烟幕中心
|
||||
var (angleX, angleY) = ProjectToImagePlane(smoke.Position, missilePosition);
|
||||
var (angleX, angleY) = ProjectToImagePlane(smoke.KState.Position, missilePosition);
|
||||
var (smokeCenterX, smokeCenterY) = AngleToPixel(angleX, angleY);
|
||||
|
||||
// 检查投影中心是否大致在图像内 (允许部分超出)
|
||||
@ -218,7 +218,7 @@ namespace ThreatSource.Guidance
|
||||
case SmokeScreenType.Wall:
|
||||
// 墙状烟幕,考虑其朝向
|
||||
// 获取烟幕墙朝向(法线方向)与视线方向的夹角
|
||||
Vector3D smokeForward = smoke.Orientation.ToVector().Normalize(); // 烟幕墙的朝向(法线方向)
|
||||
Vector3D smokeForward = smoke.KState.Orientation.ToVector().Normalize(); // 烟幕墙的朝向(法线方向)
|
||||
double angleToViewLine = Math.Acos(Math.Abs(Vector3D.DotProduct(smokeForward, forward)));
|
||||
|
||||
// 计算墙在视线方向的有效投影尺寸
|
||||
@ -302,7 +302,7 @@ namespace ThreatSource.Guidance
|
||||
public InfraredImage GenerateImage(BaseEquipment target, Vector3D missilePosition, double smokeAttenuation, ISimulationManager simulationManager)
|
||||
{
|
||||
// 更新视线坐标系
|
||||
UpdateLineOfSightFrame(missilePosition, target.Position);
|
||||
UpdateLineOfSightFrame(missilePosition, target.KState.Position);
|
||||
|
||||
// 创建并初始化烟幕强度图层 (-1表示无烟幕)
|
||||
double[,] smokeIntensityLayer = new double[imageHeight, imageWidth];
|
||||
@ -333,11 +333,11 @@ namespace ThreatSource.Guidance
|
||||
// --- 结束新增 ---
|
||||
|
||||
// 计算目标中心投影
|
||||
var (angleX, angleY) = ProjectToImagePlane(target.Position, missilePosition);
|
||||
var (angleX, angleY) = ProjectToImagePlane(target.KState.Position, missilePosition);
|
||||
var (centerX, centerY) = AngleToPixel(angleX, angleY);
|
||||
|
||||
// 计算目标尺寸
|
||||
double distance = (target.Position - missilePosition).Magnitude();
|
||||
double distance = (target.KState.Position - missilePosition).Magnitude();
|
||||
double targetLengthAngle = Math.Atan2(target.Properties.Length, distance);
|
||||
double targetWidthAngle = Math.Atan2(target.Properties.Width, distance);
|
||||
|
||||
|
||||
@ -224,7 +224,7 @@ namespace ThreatSource.Guidance
|
||||
base.Update(deltaTime);
|
||||
if (!IsBlockingJammed)
|
||||
{
|
||||
if (TryDetectAndIdentifyTarget(Position, Velocity, deltaTime, out Vector3D currentTargetPosition))
|
||||
if (TryDetectAndIdentifyTarget(KState.Position, KState.Velocity, deltaTime, out Vector3D currentTargetPosition))
|
||||
{
|
||||
targetLostTimer = 0; // 重置丢失计时器
|
||||
Vector3D? currentTargetVelocity = null; // Initialize as nullable
|
||||
@ -237,8 +237,8 @@ namespace ThreatSource.Guidance
|
||||
|
||||
GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation(
|
||||
ProportionalNavigationCoefficient,
|
||||
Position,
|
||||
Velocity,
|
||||
KState.Position,
|
||||
KState.Velocity,
|
||||
currentTargetPosition, // Non-nullable from out parameter
|
||||
currentTargetVelocity ?? Vector3D.Zero // Provide default if null
|
||||
);
|
||||
@ -374,7 +374,7 @@ namespace ThreatSource.Guidance
|
||||
{
|
||||
if (element is BaseEquipment target)
|
||||
{
|
||||
Vector3D toTarget = target.Position - missilePosition;
|
||||
Vector3D toTarget = target.KState.Position - missilePosition;
|
||||
double distance = toTarget.Magnitude();
|
||||
|
||||
// 检查距离条件
|
||||
@ -393,7 +393,7 @@ namespace ThreatSource.Guidance
|
||||
}
|
||||
|
||||
// 实时计算当前目标到导弹之间的烟幕透过率
|
||||
double liveSmokeTransmittance = CalculateLiveSmokeTransmittance(missilePosition, target.Position);
|
||||
double liveSmokeTransmittance = CalculateLiveSmokeTransmittance(missilePosition, target.KState.Position);
|
||||
|
||||
// 生成红外图像
|
||||
var image = imageGenerator.GenerateImage(target, missilePosition, liveSmokeTransmittance, SimulationManager);
|
||||
@ -407,7 +407,7 @@ namespace ThreatSource.Guidance
|
||||
{
|
||||
if (distance < minDistance)
|
||||
{
|
||||
targetPosition = target.Position;
|
||||
targetPosition = target.KState.Position;
|
||||
minDistance = distance;
|
||||
foundTarget = true;
|
||||
// 切换到跟踪模式
|
||||
@ -423,7 +423,7 @@ namespace ThreatSource.Guidance
|
||||
{
|
||||
if (distance < minDistance)
|
||||
{
|
||||
targetPosition = target.Position;
|
||||
targetPosition = target.KState.Position;
|
||||
minDistance = distance;
|
||||
foundTarget = true;
|
||||
|
||||
@ -442,7 +442,7 @@ namespace ThreatSource.Guidance
|
||||
lockConfirmationTimer = 0;
|
||||
if (distance < minDistance)
|
||||
{
|
||||
targetPosition = target.Position;
|
||||
targetPosition = target.KState.Position;
|
||||
minDistance = distance;
|
||||
foundTarget = true;
|
||||
}
|
||||
@ -458,7 +458,7 @@ namespace ThreatSource.Guidance
|
||||
// 锁定模式:只进行位置跟踪,不做类型识别
|
||||
if (distance < minDistance)
|
||||
{
|
||||
targetPosition = target.Position;
|
||||
targetPosition = target.KState.Position;
|
||||
minDistance = distance;
|
||||
foundTarget = true;
|
||||
}
|
||||
@ -492,8 +492,8 @@ namespace ThreatSource.Guidance
|
||||
}
|
||||
|
||||
const double ObscurationThreshold = 0.8; // 80%遮挡视为完全遮挡
|
||||
Vector3D targetCenter = target.Position;
|
||||
Orientation targetOrient = target.Orientation;
|
||||
Vector3D targetCenter = target.KState.Position;
|
||||
Orientation targetOrient = target.KState.Orientation;
|
||||
Vector3D targetDims = new Vector3D(target.Properties.Width, target.Properties.Height, target.Properties.Length);
|
||||
|
||||
foreach (var smoke in smokeGrenades)
|
||||
@ -514,7 +514,7 @@ namespace ThreatSource.Guidance
|
||||
// 使用ObscurationUtils计算烟幕对目标的遮挡比例
|
||||
double overlapRatio = ObscurationUtils.CalculateProjectedOverlapRatio(
|
||||
observerPosition, // 观察者位置(导弹)
|
||||
smoke.Position, smokeDims, smoke.Orientation, // 烟幕数据(前景)
|
||||
smoke.KState.Position, smokeDims, smoke.KState.Orientation, // 烟幕数据(前景)
|
||||
targetCenter, targetDims, targetOrient // 目标数据(背景)
|
||||
);
|
||||
|
||||
|
||||
@ -407,7 +407,7 @@ namespace ThreatSource.Guidance
|
||||
|
||||
Debug.WriteLine($"激光驾束引导系统: 在控制场内, 距离: {shortestDistance}");
|
||||
|
||||
Vector3D missileToSource = LaserSourcePosition - Position;
|
||||
Vector3D missileToSource = LaserSourcePosition - KState.Position;
|
||||
double distance = missileToSource.Magnitude();
|
||||
|
||||
double receivedPower = CalculateReceivedLaserPower(distance);
|
||||
@ -511,10 +511,10 @@ namespace ThreatSource.Guidance
|
||||
}
|
||||
|
||||
Vector3D forwardDirection = LaserDirection;
|
||||
Vector3D currentDirection = Velocity.Normalize();
|
||||
Vector3D currentDirection = KState.Velocity.Normalize();
|
||||
Vector3D rotationAxis = Vector3D.CrossProduct(currentDirection, forwardDirection);
|
||||
double rotationAngle = Math.Acos(Vector3D.DotProduct(currentDirection, forwardDirection));
|
||||
Vector3D forwardAcceleration = Vector3D.CrossProduct(rotationAxis, Velocity) * rotationAngle * ProportionalNavigationCoefficient;
|
||||
Vector3D forwardAcceleration = Vector3D.CrossProduct(rotationAxis, KState.Velocity) * rotationAngle * ProportionalNavigationCoefficient;
|
||||
|
||||
GuidanceAcceleration = lateralAcceleration + forwardAcceleration;
|
||||
GuidanceAcceleration = GuidanceAcceleration * config.LowPassFilterCoefficient +
|
||||
@ -618,10 +618,10 @@ namespace ThreatSource.Guidance
|
||||
return Vector3D.Zero;
|
||||
}
|
||||
|
||||
Vector3D missileToSource = LaserSourcePosition - Position;
|
||||
Vector3D missileToSource = LaserSourcePosition - KState.Position;
|
||||
double projectionLength = Vector3D.DotProduct(missileToSource, LaserDirection);
|
||||
Vector3D closestPointOnBeam = LaserSourcePosition - LaserDirection * projectionLength;
|
||||
Vector3D shortestDistanceVector = closestPointOnBeam - Position;
|
||||
Vector3D shortestDistanceVector = closestPointOnBeam - KState.Position;
|
||||
|
||||
return shortestDistanceVector;
|
||||
}
|
||||
|
||||
@ -312,7 +312,7 @@ namespace ThreatSource.Guidance
|
||||
// 添加激光目标
|
||||
if (!laserTargets.Any(t => t.Target.Id == decoyTarget.Id))
|
||||
{
|
||||
laserTargets.Add((decoyTarget, decoyTarget.Position, decoySource));
|
||||
laserTargets.Add((decoyTarget, decoyTarget.KState.Position, decoySource));
|
||||
Console.WriteLine($"[LASER_SEMI_ACTIVE] 诱偏目标添加到激光目标列表。当前激光目标数量: {laserTargets.Count}");
|
||||
}
|
||||
}
|
||||
@ -443,13 +443,13 @@ namespace ThreatSource.Guidance
|
||||
if (target.Target is LaserDecoy decoy)
|
||||
{
|
||||
// 计算接收功率
|
||||
receivedPower = CalculateReceivedPower(target.Source.Position, target.SpotPosition, decoy.config.Power, decoy.config.DivergenceAngle);
|
||||
receivedPower = CalculateReceivedPower(target.Source.KState.Position, target.SpotPosition, decoy.config.Power, decoy.config.DivergenceAngle);
|
||||
Console.WriteLine($"处理激光信号: 诱偏目标接收功率={receivedPower:E}W, 诱偏目标ID: {target.Target.Id}, 诱偏目标位置: {target.SpotPosition}");
|
||||
}
|
||||
else if (target.Source is LaserDesignator laserDesignator)
|
||||
{
|
||||
// 计算接收功率
|
||||
receivedPower = CalculateReceivedPower(target.Source.Position, target.SpotPosition, laserDesignator.config.Power, laserDesignator.config.DivergenceAngle);
|
||||
receivedPower = CalculateReceivedPower(target.Source.KState.Position, target.SpotPosition, laserDesignator.config.Power, laserDesignator.config.DivergenceAngle);
|
||||
Console.WriteLine($"处理激光信号: 真实目标接收功率={receivedPower:E}W, 真实目标ID: {target.Target.Id}, 真实目标位置: {target.SpotPosition}");
|
||||
}
|
||||
|
||||
@ -519,9 +519,9 @@ namespace ThreatSource.Guidance
|
||||
double totalPowerReflectedByTarget = powerDensityOnTargetSurface * config.TargetReflectiveArea * config.ReflectionCoefficient;
|
||||
|
||||
// --- 路径2: 目标 (target) 到导弹 (missile) ---
|
||||
double distanceTargetToMissile = (targetPos - Position).Magnitude();
|
||||
double distanceTargetToMissile = (targetPos - KState.Position).Magnitude();
|
||||
if (distanceTargetToMissile < 1e-9) distanceTargetToMissile = 1e-9; // 防止除零
|
||||
double smokeTransmittance_T2M = CalculateLiveSmokeTransmittanceForPath(targetPos, Position);
|
||||
double smokeTransmittance_T2M = CalculateLiveSmokeTransmittanceForPath(targetPos, KState.Position);
|
||||
double atmTransmittance_T2M = 1.0;
|
||||
if (SimulationManager.CurrentWeather != null)
|
||||
{
|
||||
@ -558,10 +558,10 @@ namespace ThreatSource.Guidance
|
||||
private double CalculateAngleDeviation(Vector3D targetPos)
|
||||
{
|
||||
// 计算目标方向
|
||||
Vector3D targetDirection = (targetPos - Position).Normalize();
|
||||
Vector3D targetDirection = (targetPos - KState.Position).Normalize();
|
||||
|
||||
// 计算当前导弹朝向
|
||||
Vector3D missileDirection = Velocity.Normalize();
|
||||
Vector3D missileDirection = KState.Velocity.Normalize();
|
||||
|
||||
// 计算夹角
|
||||
double dotProduct = Vector3D.DotProduct(targetDirection, missileDirection);
|
||||
@ -590,10 +590,10 @@ namespace ThreatSource.Guidance
|
||||
}
|
||||
|
||||
// No cast needed, just use TargetPosition directly
|
||||
Vector3D idealDirection = (TargetPosition - Position).Normalize();
|
||||
Vector3D idealDirection = (TargetPosition - KState.Position).Normalize();
|
||||
|
||||
// 计算当前导弹前向方向
|
||||
Vector3D currentDirection = Velocity.Normalize();
|
||||
Vector3D currentDirection = KState.Velocity.Normalize();
|
||||
|
||||
// 计算右向量和上向量
|
||||
Vector3D right = Vector3D.CrossProduct(Vector3D.UnitY, currentDirection).Normalize();
|
||||
@ -637,7 +637,7 @@ namespace ThreatSource.Guidance
|
||||
protected void CalculateGuidanceAcceleration(double deltaTime)
|
||||
{
|
||||
// 获取当前导弹指向方向
|
||||
Vector3D currentDirection = Velocity.Normalize();
|
||||
Vector3D currentDirection = KState.Velocity.Normalize();
|
||||
|
||||
// 使用四象限探测器获取修正后的目标方向
|
||||
Vector3D targetDirection = quadrantDetector.GetTargetDirection(currentDirection, SpotOffsetSensitivity);
|
||||
@ -655,7 +655,7 @@ namespace ThreatSource.Guidance
|
||||
}
|
||||
|
||||
// 计算新的制导加速度,与速度垂直
|
||||
Vector3D newGuidanceAcceleration = guidanceDirection * ProportionalNavigationCoefficient * Velocity.Magnitude();
|
||||
Vector3D newGuidanceAcceleration = guidanceDirection * ProportionalNavigationCoefficient * KState.Velocity.Magnitude();
|
||||
|
||||
// 限制最大加速度
|
||||
double maxAcceleration = MaxAcceleration;
|
||||
|
||||
@ -471,7 +471,7 @@ namespace ThreatSource.Guidance
|
||||
// 更新扫描参数
|
||||
UpdateConicalScan(deltaTime);
|
||||
|
||||
if (TryDetectAndTrackTarget(Position, Velocity, deltaTime, out Vector3D currentTargetPosition))
|
||||
if (TryDetectAndTrackTarget(KState.Position, KState.Velocity, deltaTime, out Vector3D currentTargetPosition))
|
||||
{
|
||||
targetLostTimer = 0;
|
||||
Vector3D? currentTargetVelocity = null;
|
||||
@ -485,8 +485,8 @@ namespace ThreatSource.Guidance
|
||||
|
||||
GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation(
|
||||
ProportionalNavigationCoefficient,
|
||||
Position,
|
||||
Velocity,
|
||||
KState.Position,
|
||||
KState.Velocity,
|
||||
currentTargetPosition,
|
||||
currentTargetVelocity ?? Vector3D.Zero
|
||||
);
|
||||
@ -545,12 +545,12 @@ namespace ThreatSource.Guidance
|
||||
{
|
||||
if (element is BaseEquipment target && target.Id != MissileId && target.IsActive)
|
||||
{
|
||||
Vector3D toTarget = target.Position - missilePosition;
|
||||
Vector3D toTarget = target.KState.Position - missilePosition;
|
||||
double distance = toTarget.Magnitude();
|
||||
|
||||
if (distance <= config.MaxDetectionRange && distance > 0)
|
||||
{
|
||||
double liveSmokeTransmittance = CalculateLiveSmokeTransmittance(missilePosition, target.Position);
|
||||
double liveSmokeTransmittance = CalculateLiveSmokeTransmittance(missilePosition, target.KState.Position);
|
||||
double snr_dB = CalculateSNR(distance, target.Properties.RadarCrossSection, liveSmokeTransmittance);
|
||||
|
||||
if (currentMode == WorkMode.Search)
|
||||
@ -559,7 +559,7 @@ namespace ThreatSource.Guidance
|
||||
{
|
||||
if (distance < minDistance)
|
||||
{
|
||||
targetPosition = target.Position;
|
||||
targetPosition = target.KState.Position;
|
||||
minDistance = distance;
|
||||
foundTarget = true;
|
||||
currentSNR_dB = snr_dB;
|
||||
@ -572,7 +572,7 @@ namespace ThreatSource.Guidance
|
||||
if (LastTargetPosition != null)
|
||||
{
|
||||
double proximityThreshold = (target.Properties.Length > 0) ? target.Properties.Length * 5.0 : 100.0;
|
||||
isPotentiallyTrackedTarget = Vector3D.Distance(target.Position, LastTargetPosition) < proximityThreshold;
|
||||
isPotentiallyTrackedTarget = Vector3D.Distance(target.KState.Position, LastTargetPosition) < proximityThreshold;
|
||||
}
|
||||
|
||||
if (IsTargetInBeam(missileVelocity, toTarget) && isPotentiallyTrackedTarget)
|
||||
@ -582,7 +582,7 @@ namespace ThreatSource.Guidance
|
||||
|
||||
if (snr_dB >= requiredSNR_dB)
|
||||
{
|
||||
targetPosition = target.Position;
|
||||
targetPosition = target.KState.Position;
|
||||
foundTarget = true;
|
||||
currentSNR_dB = snr_dB;
|
||||
break;
|
||||
|
||||
@ -94,11 +94,11 @@ namespace ThreatSource.Indicator
|
||||
/// - 初始化基本属性
|
||||
/// - 初始化干扰处理组件
|
||||
/// </remarks>
|
||||
protected BaseIndicator(string id, MotionParameters motionParameters, ISimulationManager manager)
|
||||
protected BaseIndicator(string id, KinematicState motionParameters, ISimulationManager manager)
|
||||
: base(id, motionParameters, manager)
|
||||
{
|
||||
_jammingComponent = new JammableComponent(
|
||||
positionProvider: () => base.Position
|
||||
positionProvider: () => base.KState.Position
|
||||
);
|
||||
|
||||
_jammingComponent.JammingApplied += HandleJammingApplied;
|
||||
@ -273,8 +273,8 @@ namespace ThreatSource.Indicator
|
||||
// 仅当目标被看到 (未遮挡) 且目标有效时,才更新最后已知状态
|
||||
if (!currentlyObscured && currentTarget != null)
|
||||
{
|
||||
_lastKnownTargetPosition = currentTarget.Position;
|
||||
_lastKnownTargetOrientation = currentTarget.Orientation;
|
||||
_lastKnownTargetPosition = currentTarget.KState.Position;
|
||||
_lastKnownTargetOrientation = currentTarget.KState.Orientation;
|
||||
}
|
||||
}
|
||||
|
||||
@ -308,9 +308,9 @@ namespace ThreatSource.Indicator
|
||||
}
|
||||
|
||||
// 4. 准备计算所需数据
|
||||
Vector3D observerPos = Position;
|
||||
Vector3D targetCenter = targetFound.Position;
|
||||
Orientation targetOrient = targetFound.Orientation;
|
||||
Vector3D observerPos = KState.Position;
|
||||
Vector3D targetCenter = targetFound.KState.Position;
|
||||
Orientation targetOrient = targetFound.KState.Orientation;
|
||||
Vector3D targetDims = new(targetFound.Properties.Width, targetFound.Properties.Height, targetFound.Properties.Length);
|
||||
|
||||
// 5. 遍历烟幕检查遮挡
|
||||
@ -323,8 +323,8 @@ namespace ThreatSource.Indicator
|
||||
|
||||
try
|
||||
{
|
||||
Vector3D smokeCenter = smokeGrenade.Position;
|
||||
Orientation smokeOrient = smokeGrenade.Orientation;
|
||||
Vector3D smokeCenter = smokeGrenade.KState.Position;
|
||||
Orientation smokeOrient = smokeGrenade.KState.Orientation;
|
||||
Vector3D smokeDims;
|
||||
|
||||
if (smokeGrenade.config.SmokeType == SmokeScreenType.Cloud)
|
||||
|
||||
@ -72,7 +72,7 @@ namespace ThreatSource.Indicator
|
||||
/// - 配置工作参数
|
||||
/// - 设置初始状态
|
||||
/// </remarks>
|
||||
public InfraredTracker(string id, string targetId, InfraredTrackerConfig config, MotionParameters motionParameters, ISimulationManager manager)
|
||||
public InfraredTracker(string id, string targetId, InfraredTrackerConfig config, KinematicState motionParameters, ISimulationManager manager)
|
||||
: base(id, motionParameters, manager)
|
||||
{
|
||||
TargetId = targetId;
|
||||
@ -157,21 +157,21 @@ namespace ThreatSource.Indicator
|
||||
StopTracking();
|
||||
return;
|
||||
}
|
||||
currentTargetPosition = targetElement.Position;
|
||||
currentTargetPosition = targetElement.KState.Position;
|
||||
}
|
||||
|
||||
IsTracking = true;
|
||||
|
||||
// 计算导弹到测角仪的距离
|
||||
double distanceToMissile = Vector3D.Distance(Position, missileElement.Position);
|
||||
double distanceToMissile = Vector3D.Distance(KState.Position, missileElement.KState.Position);
|
||||
|
||||
// 检查导弹是否在跟踪范围内
|
||||
if (distanceToMissile <= config.MaxTrackingRange)
|
||||
{
|
||||
// 计算测角仪到导弹的向量
|
||||
Vector3D trackerToMissile = missileElement.Position - Position;
|
||||
Vector3D trackerToMissile = missileElement.KState.Position - KState.Position;
|
||||
// 计算测角仪到目标的向量 (使用确定的目标位置)
|
||||
Vector3D trackerToTarget = currentTargetPosition - Position;
|
||||
Vector3D trackerToTarget = currentTargetPosition - KState.Position;
|
||||
|
||||
// 发送制导指令事件
|
||||
PublishGuidanceCommandEvent(missileElement.Id, trackerToMissile, trackerToTarget, Id);
|
||||
|
||||
@ -73,7 +73,7 @@ namespace ThreatSource.Indicator
|
||||
/// <param name="missileId">导弹ID</param>
|
||||
/// <param name="targetId">目标ID</param>
|
||||
/// <param name="config">配置参数</param>
|
||||
/// <param name="motionParameters">初始运动参数</param>
|
||||
/// <param name="kinematicState">初始运动参数</param>
|
||||
/// <param name="simulationManager">仿真管理器实例</param>
|
||||
/// <remarks>
|
||||
/// 构造过程:
|
||||
@ -82,11 +82,11 @@ namespace ThreatSource.Indicator
|
||||
/// - 配置制导范围
|
||||
/// - 建立目标关联
|
||||
/// </remarks>
|
||||
public LaserBeamRider(string id, string targetId, string missileId, LaserBeamRiderConfig config, MotionParameters motionParameters, ISimulationManager simulationManager)
|
||||
: base(id, motionParameters, simulationManager)
|
||||
public LaserBeamRider(string id, string targetId, string missileId, LaserBeamRiderConfig config, KinematicState kinematicState, ISimulationManager simulationManager)
|
||||
: base(id, kinematicState, simulationManager)
|
||||
{
|
||||
this.config = config;
|
||||
LaserDirection = Orientation.ToVector();
|
||||
LaserDirection = KState.Orientation.ToVector();
|
||||
IsBeamOn = false;
|
||||
MissileId = missileId;
|
||||
TargetId = targetId;
|
||||
@ -133,8 +133,8 @@ namespace ThreatSource.Indicator
|
||||
{
|
||||
if (TargetId != null && SimulationManager.GetEntityById(TargetId) is SimulationElement target)
|
||||
{
|
||||
Vector3D targetPosition = target.Position;
|
||||
Vector3D newDirection = (targetPosition - Position).Normalize();
|
||||
Vector3D targetPosition = target.KState.Position;
|
||||
Vector3D newDirection = (targetPosition - KState.Position).Normalize();
|
||||
if ((newDirection - LaserDirection).MagnitudeSquared() > 1e-9)
|
||||
{
|
||||
LaserDirection = newDirection;
|
||||
@ -235,7 +235,7 @@ namespace ThreatSource.Indicator
|
||||
{
|
||||
if (TargetId != null && SimulationManager.GetEntityById(TargetId) is SimulationElement target)
|
||||
{
|
||||
LaserDirection = (target.Position - Position).Normalize();
|
||||
LaserDirection = (target.KState.Position - KState.Position).Normalize();
|
||||
IsBeamOn = true;
|
||||
PublishLaserBeamEvent();
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ namespace ThreatSource.Indicator
|
||||
/// <param name="targetId">目标ID</param>
|
||||
/// <param name="missileId">导弹ID</param>
|
||||
/// <param name="config">配置参数</param>
|
||||
/// <param name="motionParameters">初始运动参数</param>
|
||||
/// <param name="kinematicState">初始运动参数</param>
|
||||
/// <param name="simulationManager">仿真管理器实例</param>
|
||||
/// <remarks>
|
||||
/// 构造过程:
|
||||
@ -77,8 +77,8 @@ namespace ThreatSource.Indicator
|
||||
/// - 配置激光参数
|
||||
/// - 设置初始状态
|
||||
/// </remarks>
|
||||
public LaserDesignator(string id, string targetId, string missileId, LaserDesignatorConfig config, MotionParameters motionParameters, ISimulationManager simulationManager)
|
||||
: base(id, motionParameters, simulationManager)
|
||||
public LaserDesignator(string id, string targetId, string missileId, LaserDesignatorConfig config, KinematicState kinematicState, ISimulationManager simulationManager)
|
||||
: base(id, kinematicState, simulationManager)
|
||||
{
|
||||
TargetId = targetId;
|
||||
MissileId = missileId;
|
||||
@ -129,15 +129,15 @@ namespace ThreatSource.Indicator
|
||||
{
|
||||
if (SimulationManager.GetEntityById(TargetId) is SimulationElement target)
|
||||
{
|
||||
Vector3D direction = (target.Position - Position).Normalize();
|
||||
Vector3D direction = (target.KState.Position - KState.Position).Normalize();
|
||||
if (direction.MagnitudeSquared() < 1e-9) return;
|
||||
|
||||
double yaw = Math.PI + Math.Atan2(direction.Z, direction.X);
|
||||
double pitch = -Math.Asin(direction.Y);
|
||||
Orientation = new Orientation(yaw, pitch, 0);
|
||||
_lastKnownTargetPosition = target.Position;
|
||||
KState.Orientation = new Orientation(yaw, pitch, 0);
|
||||
_lastKnownTargetPosition = target.KState.Position;
|
||||
|
||||
Console.WriteLine($"激光指示器 {Id} 更新朝向: {Orientation}, _lastKnownTargetPosition: {_lastKnownTargetPosition}");
|
||||
Console.WriteLine($"激光指示器 {Id} 更新朝向: {KState.Orientation}, _lastKnownTargetPosition: {_lastKnownTargetPosition}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,10 +39,10 @@ namespace ThreatSource.Jammer
|
||||
/// 初始化干扰器基类的新实例
|
||||
/// </summary>
|
||||
/// <param name="id">干扰器ID</param>
|
||||
/// <param name="motionParameters">初始运动参数</param>
|
||||
/// <param name="kinematicState">初始运动参数</param>
|
||||
/// <param name="manager">仿真管理器实例</param>
|
||||
protected BaseJammer(string id, MotionParameters motionParameters, ISimulationManager manager)
|
||||
: base(id, motionParameters, manager)
|
||||
protected BaseJammer(string id, KinematicState kinematicState, ISimulationManager manager)
|
||||
: base(id, kinematicState, manager)
|
||||
{
|
||||
State = JammerState.Idle;
|
||||
IsJamming = false;
|
||||
|
||||
@ -27,7 +27,7 @@ namespace ThreatSource.Jammer
|
||||
/// <param name="config">红外干扰器配置</param>
|
||||
/// <param name="motionParameters">初始运动参数</param>
|
||||
/// <param name="manager">仿真管理器实例</param>
|
||||
public InfraredJammer(string id, InfraredJammerConfig config, MotionParameters motionParameters, ISimulationManager manager)
|
||||
public InfraredJammer(string id, InfraredJammerConfig config, KinematicState motionParameters, ISimulationManager manager)
|
||||
: base(id, motionParameters, manager)
|
||||
{
|
||||
this.config = config;
|
||||
@ -44,8 +44,8 @@ namespace ThreatSource.Jammer
|
||||
JammerId = Id,
|
||||
Power = config.Power,
|
||||
Wavelength = config.Wavelength,
|
||||
Direction = Orientation.ToVector(),
|
||||
SourcePosition = Position,
|
||||
Direction = KState.Orientation.ToVector(),
|
||||
SourcePosition = KState.Position,
|
||||
AngleRange = config.AngleRange,
|
||||
Mode = config.Mode,
|
||||
Duration = config.Duration,
|
||||
@ -61,7 +61,7 @@ namespace ThreatSource.Jammer
|
||||
base.UpdateJamming(deltaTime);
|
||||
|
||||
// 更新位置
|
||||
Position += Velocity * deltaTime;
|
||||
KState.Position += KState.Velocity * deltaTime;
|
||||
|
||||
// 更新干扰事件
|
||||
if (CurrentParameters != null)
|
||||
|
||||
@ -34,7 +34,7 @@ namespace ThreatSource.Jammer
|
||||
/// <param name="motionParameters">运动参数</param>
|
||||
/// <param name="sourceId">干扰源ID</param>
|
||||
/// <param name="simulationManager">仿真管理器</param>
|
||||
public LaserDecoy(string id, LaserDecoyConfig config, MotionParameters motionParameters, string sourceId, ISimulationManager simulationManager)
|
||||
public LaserDecoy(string id, LaserDecoyConfig config, KinematicState motionParameters, string sourceId, ISimulationManager simulationManager)
|
||||
: base(id, motionParameters, simulationManager)
|
||||
{
|
||||
this.config = config;
|
||||
@ -47,7 +47,7 @@ namespace ThreatSource.Jammer
|
||||
protected override JammingParameters CreateJammingParameters()
|
||||
{
|
||||
SimulationElement source = SimulationManager.GetEntityById(SourceId) as SimulationElement ?? throw new Exception("诱偏源不存在");
|
||||
Vector3D sourcePosition = source.Position;
|
||||
Vector3D sourcePosition = source.KState.Position;
|
||||
|
||||
return new JammingParameters
|
||||
{
|
||||
@ -58,8 +58,8 @@ namespace ThreatSource.Jammer
|
||||
Power = config.Power,
|
||||
Wavelength = config.Wavelength,
|
||||
SourcePosition = sourcePosition,
|
||||
Direction = Orientation.ToVector(),
|
||||
DecoyPosition = Position,
|
||||
Direction = source.KState.Orientation.ToVector(),
|
||||
DecoyPosition = KState.Position,
|
||||
AngleRange = config.DivergenceAngle,
|
||||
Duration = config.Duration,
|
||||
ReflectiveArea = config.ReflectiveArea,
|
||||
@ -75,7 +75,7 @@ namespace ThreatSource.Jammer
|
||||
{
|
||||
base.UpdateJamming(deltaTime);
|
||||
// 更新诱偏目标的位置
|
||||
Position += Velocity * deltaTime;
|
||||
KState.Position += KState.Velocity * deltaTime;
|
||||
|
||||
if (CurrentParameters != null)
|
||||
{
|
||||
|
||||
@ -24,7 +24,7 @@ namespace ThreatSource.Jammer
|
||||
/// <param name="config">激光干扰器配置</param>
|
||||
/// <param name="motionParameters">初始运动参数</param>
|
||||
/// <param name="manager">仿真管理器实例</param>
|
||||
public LaserJammer(string id, LaserJammerConfig config, MotionParameters motionParameters, ISimulationManager manager)
|
||||
public LaserJammer(string id, LaserJammerConfig config, KinematicState motionParameters, ISimulationManager manager)
|
||||
: base(id, motionParameters, manager)
|
||||
{
|
||||
this.config = config;
|
||||
@ -41,9 +41,9 @@ namespace ThreatSource.Jammer
|
||||
JammerId = Id,
|
||||
Power = config.Power,
|
||||
Wavelength = config.Wavelength,
|
||||
Direction = Orientation.ToVector(),
|
||||
Direction = KState.Orientation.ToVector(),
|
||||
AngleRange = config.AngleRange,
|
||||
SourcePosition = Position,
|
||||
SourcePosition = KState.Position,
|
||||
Mode = config.Mode,
|
||||
Duration = config.Duration,
|
||||
StartTime = DateTime.UtcNow
|
||||
@ -58,7 +58,7 @@ namespace ThreatSource.Jammer
|
||||
base.UpdateJamming(deltaTime);
|
||||
|
||||
// 更新位置
|
||||
Position += Velocity * deltaTime;
|
||||
KState.Position += KState.Velocity * deltaTime;
|
||||
|
||||
// 更新干扰事件
|
||||
if (CurrentParameters != null)
|
||||
|
||||
@ -33,7 +33,7 @@ namespace ThreatSource.Jammer
|
||||
public MillimeterWaveCompensationJammer(
|
||||
string id,
|
||||
MillimeterWaveCompensationJammerConfig config,
|
||||
MotionParameters motionParameters,
|
||||
KinematicState motionParameters,
|
||||
ISimulationManager manager)
|
||||
: base(id, motionParameters, manager)
|
||||
{
|
||||
@ -59,8 +59,8 @@ namespace ThreatSource.Jammer
|
||||
Wavelength = _config.Wavelength,
|
||||
AngleRange = _config.AngleRange,
|
||||
Duration = _config.Duration,
|
||||
Direction = Orientation.ToVector(),
|
||||
SourcePosition = Position,
|
||||
Direction = KState.Orientation.ToVector(),
|
||||
SourcePosition = KState.Position,
|
||||
StartTime = DateTime.UtcNow
|
||||
};
|
||||
}
|
||||
@ -74,7 +74,7 @@ namespace ThreatSource.Jammer
|
||||
base.UpdateJamming(deltaTime);
|
||||
|
||||
// 更新位置 (如果干扰器是移动的)
|
||||
Position += Velocity * deltaTime;
|
||||
KState.Position += KState.Velocity * deltaTime;
|
||||
|
||||
if (CurrentParameters != null)
|
||||
{
|
||||
|
||||
@ -27,7 +27,7 @@ namespace ThreatSource.Jammer
|
||||
/// <param name="config">毫米波干扰器配置</param>
|
||||
/// <param name="motionParameters">初始运动参数</param>
|
||||
/// <param name="manager">仿真管理器实例</param>
|
||||
public MillimeterWaveJammer(string id, MillimeterWaveJammerConfig config, MotionParameters motionParameters, ISimulationManager manager)
|
||||
public MillimeterWaveJammer(string id, MillimeterWaveJammerConfig config, KinematicState motionParameters, ISimulationManager manager)
|
||||
: base(id, motionParameters, manager)
|
||||
{
|
||||
this.config = config;
|
||||
@ -44,9 +44,9 @@ namespace ThreatSource.Jammer
|
||||
JammerId = Id,
|
||||
Power = config.Power,
|
||||
Wavelength = config.Wavelength,
|
||||
Direction = Orientation.ToVector(),
|
||||
Direction = KState.Orientation.ToVector(),
|
||||
AngleRange = config.AngleRange,
|
||||
SourcePosition = Position,
|
||||
SourcePosition = KState.Position,
|
||||
Mode = config.Mode,
|
||||
Duration = config.Duration,
|
||||
StartTime = DateTime.UtcNow
|
||||
@ -61,7 +61,7 @@ namespace ThreatSource.Jammer
|
||||
base.UpdateJamming(deltaTime);
|
||||
|
||||
// 更新位置
|
||||
Position += Velocity * deltaTime;
|
||||
KState.Position += KState.Velocity * deltaTime;
|
||||
|
||||
// 更新干扰事件
|
||||
if (CurrentParameters != null)
|
||||
|
||||
@ -33,7 +33,7 @@ namespace ThreatSource.Jammer
|
||||
public SmokeGrenade(
|
||||
string id,
|
||||
SmokeGrenadeConfig config,
|
||||
MotionParameters motionParameters,
|
||||
KinematicState motionParameters,
|
||||
ISimulationManager simulationManager)
|
||||
: base(id, motionParameters, simulationManager)
|
||||
{
|
||||
@ -52,8 +52,8 @@ namespace ThreatSource.Jammer
|
||||
Mode = config.Mode,
|
||||
JammerId = Id,
|
||||
Power = 0, // 烟幕不需要功率参数
|
||||
Direction = Orientation.ToVector(),
|
||||
SourcePosition = Position,
|
||||
Direction = KState.Orientation.ToVector(),
|
||||
SourcePosition = KState.Position,
|
||||
AngleRange = 180, // 烟幕影响正面
|
||||
Duration = config.Duration,
|
||||
StartTime = DateTime.UtcNow,
|
||||
@ -93,7 +93,7 @@ namespace ThreatSource.Jammer
|
||||
);
|
||||
|
||||
// 烟雾位置随风移动
|
||||
Position += windVector * windSpeed * deltaTime;
|
||||
KState.Position += windVector * windSpeed * deltaTime;
|
||||
|
||||
// 计算浓度衰减
|
||||
double decayRate = Math.Log(2) / config.Duration;
|
||||
@ -148,7 +148,7 @@ namespace ThreatSource.Jammer
|
||||
if (thickness > 0.1 && config.IsObscuring)
|
||||
{
|
||||
effectiveTransmittance = physicalTransmittance * 1e-3;
|
||||
Console.WriteLine($"[烟幕透过率计算] 屏蔽型烟幕生效,透射率调整为: {effectiveTransmittance} (物理透射率: {physicalTransmittance})");
|
||||
Console.WriteLine($"[烟幕透过率计算] 屏蔽型烟幕生效,透射率调整为: {effectiveTransmittance:F5} (物理透射率: {physicalTransmittance:F5})");
|
||||
}
|
||||
|
||||
return effectiveTransmittance;
|
||||
@ -198,7 +198,7 @@ namespace ThreatSource.Jammer
|
||||
if (!IsActive || !IsJamming || CurrentParameters == null) return 0;
|
||||
|
||||
// 将射线起点转换到烟幕的局部坐标系(烟幕中心为原点)
|
||||
Vector3D localOrigin = origin - Position;
|
||||
Vector3D localOrigin = origin - KState.Position;
|
||||
double currentThickness = CurrentParameters.SmokeThickness ?? config.Thickness; // 当前烟幕高度/厚度
|
||||
double halfHeight = currentThickness / 2.0; // 半高
|
||||
|
||||
@ -304,7 +304,7 @@ namespace ThreatSource.Jammer
|
||||
// Right -> local X axis
|
||||
// Up -> local Y axis
|
||||
// Forward -> local -Z axis (which is the wall's normal / primary orientation vector)
|
||||
var (localX, localY, localNegativeZ) = ObscurationUtils.GetOrientationBasisVectors(this.Orientation);
|
||||
var (localX, localY, localNegativeZ) = ObscurationUtils.GetOrientationBasisVectors(KState.Orientation);
|
||||
|
||||
// 对于墙状烟幕:
|
||||
// obbAxisX (宽度方向) 对应局部X轴
|
||||
@ -320,7 +320,7 @@ namespace ThreatSource.Jammer
|
||||
{
|
||||
if (!IsActive || !IsJamming || CurrentParameters == null) return 0.0;
|
||||
|
||||
Vector3D obbCenter_world = Position;
|
||||
Vector3D obbCenter_world = KState.Position;
|
||||
Vector3D obbDimensions = new(
|
||||
CurrentParameters.SmokeWallWidth ?? config.WallWidth,
|
||||
CurrentParameters.SmokeWallHeight ?? config.WallHeight,
|
||||
|
||||
@ -114,7 +114,7 @@ namespace ThreatSource.Missile
|
||||
/// </summary>
|
||||
/// <param name="missileId">导弹ID</param>
|
||||
/// <param name="properties">导弹属性配置</param>
|
||||
/// <param name="motionParameters">发射参数</param>
|
||||
/// <param name="kinematicState">发射参数</param>
|
||||
/// <param name="manager">仿真管理器实例</param>
|
||||
/// <remarks>
|
||||
/// 构造过程:
|
||||
@ -126,9 +126,9 @@ namespace ThreatSource.Missile
|
||||
protected BaseMissile(
|
||||
string missileId,
|
||||
MissileProperties properties,
|
||||
MotionParameters motionParameters,
|
||||
KinematicState kinematicState,
|
||||
ISimulationManager manager)
|
||||
: base(missileId, motionParameters, manager)
|
||||
: base(missileId, kinematicState, manager)
|
||||
{
|
||||
// 设置性能限制
|
||||
Properties = properties;
|
||||
@ -180,34 +180,31 @@ namespace ThreatSource.Missile
|
||||
protected virtual void UpdateMotionState(double deltaTime)
|
||||
{
|
||||
// 计算包含风影响的合加速度
|
||||
Vector3D acceleration = CalculateAcceleration(Velocity);
|
||||
Vector3D acceleration = CalculateAcceleration(KState.Velocity);
|
||||
|
||||
if (IsGuidance)
|
||||
{
|
||||
// 制导条件下,使用四阶龙格-库塔方法更新导弹的位置和速度
|
||||
(Position, Velocity) = MotionAlgorithm.RungeKutta4(deltaTime, Position, Velocity, acceleration);
|
||||
(KState.Position, KState.Velocity) = MotionAlgorithm.RungeKutta4(deltaTime, KState.Position, KState.Velocity, acceleration);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 无制导条件下,使用运动学方程更新导弹的位置和速度
|
||||
(Position, Velocity) = MotionAlgorithm.CalculateBallisticMotion(Position, Velocity, acceleration, deltaTime);
|
||||
(KState.Position, KState.Velocity) = MotionAlgorithm.CalculateBallisticMotion(KState.Position, KState.Velocity, acceleration, deltaTime);
|
||||
}
|
||||
|
||||
// 限制速度不超过最大速度
|
||||
if (Velocity.Magnitude() > Properties.MaxSpeed)
|
||||
if (KState.Speed > Properties.MaxSpeed)
|
||||
{
|
||||
Velocity = Velocity.Normalize() * Properties.MaxSpeed;
|
||||
KState.Speed = Properties.MaxSpeed;
|
||||
}
|
||||
|
||||
Speed = Velocity.Magnitude();
|
||||
Orientation = Orientation.FromVector(Velocity);
|
||||
|
||||
// 添加高斯噪声(测试用,用于测试运动中概率的影响)
|
||||
// Position = MotionAlgorithm.AddRandomPerturbation(Position);
|
||||
// Velocity = MotionAlgorithm.AddRandomPerturbation(Velocity);
|
||||
|
||||
FlightTime += deltaTime;
|
||||
FlightDistance += Speed * deltaTime;
|
||||
FlightDistance += KState.Speed * deltaTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -344,12 +341,12 @@ namespace ThreatSource.Missile
|
||||
if (IsGuidance)
|
||||
{
|
||||
// 有制导时,在负爆炸半径高度自毁(考虑仿真步长)
|
||||
return Position.Y <= -Properties.ExplosionRadius;
|
||||
return KState.Position.Y <= -Properties.ExplosionRadius;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 无制导时,在自毁高度自毁
|
||||
return Position.Y <= Properties.SelfDestructHeight;
|
||||
return KState.Position.Y <= Properties.SelfDestructHeight;
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,11 +400,11 @@ namespace ThreatSource.Missile
|
||||
{
|
||||
reason = "超出最大飞行距离";
|
||||
}
|
||||
else if (IsGuidance && Position.Y <= -Properties.ExplosionRadius)
|
||||
else if (IsGuidance && KState.Position.Y <= -Properties.ExplosionRadius)
|
||||
{
|
||||
reason = "有制导状态下高度低于负爆炸半径";
|
||||
}
|
||||
else if (!IsGuidance && Position.Y <= Properties.SelfDestructHeight)
|
||||
else if (!IsGuidance && KState.Position.Y <= Properties.SelfDestructHeight)
|
||||
{
|
||||
reason = "无制导状态下高度低于自毁高度";
|
||||
}
|
||||
@ -499,7 +496,6 @@ namespace ThreatSource.Missile
|
||||
statusInfo.ExtendedProperties["EngineBurnTime"] = EngineBurnTime;
|
||||
statusInfo.ExtendedProperties["IsGuidance"] = IsGuidance;
|
||||
statusInfo.ExtendedProperties["LostGuidanceTime"] = LostGuidanceTime;
|
||||
statusInfo.ExtendedProperties["Velocity"] = Velocity;
|
||||
statusInfo.ExtendedProperties["GuidanceAcceleration"] = GuidanceAcceleration;
|
||||
|
||||
return statusInfo;
|
||||
|
||||
@ -75,15 +75,6 @@ namespace ThreatSource.Missile
|
||||
/// </remarks>
|
||||
public struct MissileRunningState
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置导弹的唯一标识符
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 在仿真系统中必须唯一
|
||||
/// 用于标识和追踪特定的导弹
|
||||
/// </remarks>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置导弹的类型
|
||||
/// </summary>
|
||||
@ -93,42 +84,6 @@ namespace ThreatSource.Missile
|
||||
/// </remarks>
|
||||
public MissileType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置导弹的当前位置
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 使用三维向量表示空间位置
|
||||
/// 坐标系:右手坐标系,X向右,Y向上,Z向前
|
||||
/// </remarks>
|
||||
public Vector3D Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置导弹的当前速度向量
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 包含速度的大小和方向信息
|
||||
/// 单位:米/秒
|
||||
/// </remarks>
|
||||
public Vector3D Velocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置导弹的当前朝向
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 使用欧拉角表示导弹的姿态
|
||||
/// 包含偏航角、俯仰角和滚转角
|
||||
/// </remarks>
|
||||
public Orientation Orientation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置导弹的当前速度大小
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 单位:米/秒
|
||||
/// 表示导弹运动的标量速度
|
||||
/// </remarks>
|
||||
public double Speed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置导弹的当前飞行时间
|
||||
/// </summary>
|
||||
@ -176,15 +131,6 @@ namespace ThreatSource.Missile
|
||||
/// </remarks>
|
||||
public double EngineBurnTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置导弹是否处于活动状态
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// true表示导弹正常工作
|
||||
/// false表示导弹已停止工作(销毁或自毁)
|
||||
/// </remarks>
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置导弹的制导加速度
|
||||
/// </summary>
|
||||
|
||||
@ -89,7 +89,7 @@ namespace ThreatSource.Missile
|
||||
public InfraredCommandGuidedMissile(
|
||||
string missileId,
|
||||
MissileProperties properties,
|
||||
MotionParameters launchParams,
|
||||
KinematicState launchParams,
|
||||
InfraredCommandGuidanceConfig guidanceConfig,
|
||||
ISimulationManager manager)
|
||||
: base(missileId, properties, launchParams, manager)
|
||||
|
||||
@ -93,7 +93,7 @@ namespace ThreatSource.Missile
|
||||
string missileId,
|
||||
EquipmentType targetType,
|
||||
MissileProperties properties,
|
||||
MotionParameters launchParams,
|
||||
KinematicState launchParams,
|
||||
InfraredImagingGuidanceConfig guidanceConfig,
|
||||
ISimulationManager manager)
|
||||
: base(missileId, properties, launchParams, manager)
|
||||
|
||||
@ -71,7 +71,7 @@ namespace ThreatSource.Missile
|
||||
public LaserBeamRiderMissile(
|
||||
string missileId,
|
||||
MissileProperties properties,
|
||||
MotionParameters launchParams,
|
||||
KinematicState launchParams,
|
||||
LaserCodeConfig laserCodeConfig,
|
||||
LaserBeamRiderGuidanceSystemConfig guidanceSystemConfig,
|
||||
ISimulationManager manager)
|
||||
@ -102,7 +102,7 @@ namespace ThreatSource.Missile
|
||||
if (evt?.LaserBeamRiderId != null)
|
||||
{
|
||||
LaserBeamRider laserBeamRider = SimulationManager.GetEntityById(evt.LaserBeamRiderId) as LaserBeamRider ?? throw new Exception("激光驾束仪不存在");
|
||||
guidanceSystem?.UpdateLaserBeamRider(laserBeamRider.Position, laserBeamRider.LaserDirection, laserBeamRider.config.Power);
|
||||
guidanceSystem?.UpdateLaserBeamRider(laserBeamRider.KState.Position, laserBeamRider.LaserDirection, laserBeamRider.config.Power);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -89,7 +89,7 @@ namespace ThreatSource.Missile
|
||||
public LaserSemiActiveGuidedMissile(
|
||||
string missileId,
|
||||
MissileProperties properties,
|
||||
MotionParameters launchParams,
|
||||
KinematicState launchParams,
|
||||
LaserCodeConfig laserCodeConfig,
|
||||
LaserSemiActiveGuidanceConfig guidanceConfig,
|
||||
ISimulationManager manager)
|
||||
|
||||
@ -86,7 +86,7 @@ namespace ThreatSource.Missile
|
||||
public MillimeterWaveTerminalGuidedMissile(
|
||||
string missileId,
|
||||
MissileProperties properties,
|
||||
MotionParameters launchParams,
|
||||
KinematicState launchParams,
|
||||
MillimeterWaveGuidanceConfig guidanceConfig,
|
||||
ISimulationManager manager)
|
||||
: base(missileId, properties, launchParams, manager)
|
||||
|
||||
@ -121,7 +121,7 @@ namespace ThreatSource.Missile
|
||||
string missileId,
|
||||
string targetId,
|
||||
MissileProperties properties,
|
||||
MotionParameters launchParams,
|
||||
KinematicState launchParams,
|
||||
MissileProperties submunitionProperties,
|
||||
int submunitionCount,
|
||||
TerminalSensitiveSubmunitionConfig submunitionConfig,
|
||||
@ -136,18 +136,18 @@ namespace ThreatSource.Missile
|
||||
|
||||
//计算分离点坐标,使用配置中的分离高度和距离
|
||||
SimulationElement target = SimulationManager.GetEntityById(targetId) as SimulationElement ?? throw new Exception("目标不存在");
|
||||
separationPoint = Vector3D.PointOnLine(target.Position, base.Position, config.SeparationDistance) + new Vector3D(0, config.SeparationHeight, 0);
|
||||
separationPoint = Vector3D.PointOnLine(target.KState.Position, base.KState.Position, config.SeparationDistance) + new Vector3D(0, config.SeparationHeight, 0);
|
||||
|
||||
//计算导弹发射角度
|
||||
(Orientation? launchOrientation, Vector3D? launchVelocity) = MotionAlgorithm.CalculateBestLaunchOrientation(Position, separationPoint, Speed);
|
||||
(Orientation? launchOrientation, Vector3D? launchVelocity) = MotionAlgorithm.CalculateBestLaunchOrientation(base.KState.Position, separationPoint, base.KState.Speed);
|
||||
if (!launchOrientation.HasValue || launchVelocity is null)
|
||||
{
|
||||
throw new InvalidOperationException("无法计算发射方向");
|
||||
}
|
||||
else
|
||||
{
|
||||
Orientation = launchOrientation.Value;
|
||||
Velocity = launchVelocity;
|
||||
KState.Orientation = launchOrientation.Value;
|
||||
KState.Velocity = launchVelocity;
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,7 +232,7 @@ namespace ThreatSource.Missile
|
||||
/// </remarks>
|
||||
private void UpdateCruiseStage(double deltaTime)
|
||||
{
|
||||
double distanceToSeparationPoint = (separationPoint - Position).Magnitude();
|
||||
double distanceToSeparationPoint = (separationPoint - base.KState.Position).Magnitude();
|
||||
//距离分离点距离小于配置的分离范围,则分离
|
||||
if (distanceToSeparationPoint <= config.SeparationRange)
|
||||
{
|
||||
@ -269,7 +269,7 @@ namespace ThreatSource.Missile
|
||||
private void PerformSeparation()
|
||||
{
|
||||
// 获取母弹当前的方向向量
|
||||
Vector3D currentDirection = Orientation.ToVector();
|
||||
Vector3D currentDirection = KState.Orientation.ToVector();
|
||||
|
||||
// 计算水平方向(保持母弹的水平方向分量)
|
||||
Vector3D horizontalDirection = new Vector3D(currentDirection.X, 0, currentDirection.Z).Normalize();
|
||||
@ -309,11 +309,11 @@ namespace ThreatSource.Missile
|
||||
MaxEngineBurnTime = submunitionProperties.MaxEngineBurnTime,
|
||||
Type = submunitionProperties.Type
|
||||
},
|
||||
new MotionParameters
|
||||
new KinematicState
|
||||
{
|
||||
Position = Position,
|
||||
Position = KState.Position,
|
||||
Orientation = separationOrientation,
|
||||
InitialSpeed = Velocity.Magnitude(),
|
||||
Speed = KState.Speed,
|
||||
},
|
||||
config,
|
||||
SimulationManager
|
||||
|
||||
@ -186,7 +186,7 @@ namespace ThreatSource.Missile
|
||||
string missileId,
|
||||
string targetId,
|
||||
MissileProperties properties,
|
||||
MotionParameters launchParams,
|
||||
KinematicState launchParams,
|
||||
TerminalSensitiveSubmunitionConfig submunitionConfig,
|
||||
ISimulationManager manager)
|
||||
: base(missileId, properties, launchParams, manager)
|
||||
@ -274,8 +274,8 @@ namespace ThreatSource.Missile
|
||||
{
|
||||
// 分离阶段
|
||||
Vector3D deceleration = new(0, 9.8, 0);
|
||||
Velocity += deceleration * deltaTime;
|
||||
Position += Velocity * deltaTime;
|
||||
KState.Velocity += deceleration * deltaTime;
|
||||
KState.Position += KState.Velocity * deltaTime;
|
||||
|
||||
// 分离阶段结束,进入减速阶段
|
||||
currentStage = SubmunitionStage.Deceleration;
|
||||
@ -303,13 +303,13 @@ namespace ThreatSource.Missile
|
||||
}
|
||||
|
||||
// 减速减旋,垂直速度减小
|
||||
Vector3D deceleration = - Velocity.Normalize() * config.DecelerationAcceleration;
|
||||
Velocity += deceleration * deltaTime;
|
||||
Vector3D deceleration = - KState.Velocity.Normalize() * config.DecelerationAcceleration;
|
||||
KState.Velocity += deceleration * deltaTime;
|
||||
|
||||
if (Velocity.Magnitude() <= config.DecelerationEndSpeed)
|
||||
if (KState.Speed <= config.DecelerationEndSpeed)
|
||||
{
|
||||
//垂直速度设为减速阶段末速
|
||||
Velocity = new Vector3D(Velocity.X, -config.DecelerationEndSpeed, Velocity.Z);
|
||||
KState.Velocity = new Vector3D(KState.Velocity.X, -config.DecelerationEndSpeed, KState.Velocity.Z);
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
}
|
||||
|
||||
@ -321,7 +321,7 @@ namespace ThreatSource.Missile
|
||||
currentStage = SubmunitionStage.ParachuteDeployment;
|
||||
|
||||
//垂直速度设为减速阶段末速
|
||||
Velocity = new Vector3D(Velocity.X, -config.DecelerationEndSpeed, Velocity.Z);
|
||||
KState.Velocity = new Vector3D(KState.Velocity.X, -config.DecelerationEndSpeed, KState.Velocity.Z);
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
}
|
||||
}
|
||||
@ -342,25 +342,25 @@ namespace ThreatSource.Missile
|
||||
private void UpdateParachuteDeploymentStage(double deltaTime)
|
||||
{
|
||||
// 计算当前速度与目标速度的差值
|
||||
double currentSpeed = Velocity.Magnitude();
|
||||
double currentSpeed = KState.Speed;
|
||||
if (currentSpeed > config.VerticalDeclineSpeed)
|
||||
{
|
||||
// 开伞,用较大的减速度快速降低速度
|
||||
Vector3D deceleration = -Velocity.Normalize() * config.ParachuteDeceleration;
|
||||
Vector3D deceleration = -KState.Velocity.Normalize() * config.ParachuteDeceleration;
|
||||
|
||||
// 更新速度
|
||||
Velocity += deceleration * deltaTime;
|
||||
KState.Velocity += deceleration * deltaTime;
|
||||
|
||||
// 如果速度低于稳定扫描下降速度,直接设置为稳定扫描下降速度
|
||||
if (Velocity.Magnitude() <= config.VerticalDeclineSpeed)
|
||||
if (KState.Speed <= config.VerticalDeclineSpeed)
|
||||
{
|
||||
Velocity = new Vector3D(0, -config.VerticalDeclineSpeed, 0);
|
||||
KState.Velocity = new Vector3D(0, -config.VerticalDeclineSpeed, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 维持稳定的垂直下降速度
|
||||
Velocity = new Vector3D(0, -config.VerticalDeclineSpeed, 0);
|
||||
KState.Velocity = new Vector3D(0, -config.VerticalDeclineSpeed, 0);
|
||||
}
|
||||
|
||||
// 清除制导加速度
|
||||
@ -561,7 +561,7 @@ namespace ThreatSource.Missile
|
||||
).Normalize();
|
||||
|
||||
// 使用 AttackSpeed 设置攻击速度
|
||||
Velocity = scanDirection * config.AttackSpeed;
|
||||
KState.Velocity = scanDirection * config.AttackSpeed;
|
||||
GuidanceAcceleration = Vector3D.Zero; // 清除任何可能的加速度
|
||||
}
|
||||
|
||||
@ -588,11 +588,11 @@ namespace ThreatSource.Missile
|
||||
double targetWidth = equipment.Properties.Width; // 目标宽度
|
||||
|
||||
// 获取目标的朝向向量
|
||||
Vector3D targetForward = target.Orientation.ToVector();
|
||||
Vector3D targetForward = target.KState.Orientation.ToVector();
|
||||
Vector3D targetRight = Vector3D.CrossProduct(Vector3D.UnitY, targetForward).Normalize();
|
||||
|
||||
// 计算矩形四个顶点的位置
|
||||
Vector3D targetPosition = target.Position;
|
||||
Vector3D targetPosition = target.KState.Position;
|
||||
Vector3D[] vertices =
|
||||
[
|
||||
// 前后左右四个顶点
|
||||
@ -603,7 +603,7 @@ namespace ThreatSource.Missile
|
||||
];
|
||||
|
||||
// 计算目标方位角(弧度值)
|
||||
Vector3D toTarget = (targetPosition - Position).Normalize();
|
||||
Vector3D toTarget = (targetPosition - KState.Position).Normalize();
|
||||
double targetAzimuth = Math.Atan2(toTarget.X, toTarget.Z); // 修改为 atan2(X, Z) 使正北为0度
|
||||
if (targetAzimuth < 0)
|
||||
{
|
||||
@ -614,7 +614,7 @@ namespace ThreatSource.Missile
|
||||
double cosFieldOfView = Math.Cos(fieldOfView * Math.PI / 180);
|
||||
foreach(var vertex in vertices)
|
||||
{
|
||||
Vector3D toVertex = (vertex - Position).Normalize();
|
||||
Vector3D toVertex = (vertex - KState.Position).Normalize();
|
||||
if(Vector3D.DotProduct(scanDirection, toVertex) > cosFieldOfView)
|
||||
{
|
||||
// 如果目标的任何一个顶点在视场角内,返回目标方位角和目标引用
|
||||
@ -675,14 +675,14 @@ namespace ThreatSource.Missile
|
||||
var statusInfo = base.GetStatusInfo();
|
||||
// 获取目标对象并计算距离
|
||||
SimulationElement target = SimulationManager.GetEntityById(TargetId) as SimulationElement ?? throw new Exception("目标不存在");
|
||||
double distanceToTarget = (target.Position - Position).Magnitude();
|
||||
double distanceToTarget = (target.KState.Position - KState.Position).Magnitude();
|
||||
|
||||
statusInfo.ExtendedProperties["CurrentStage"] = currentStage.ToString();
|
||||
statusInfo.ExtendedProperties["SpiralAngle"] = spiralAngle * 180 / Math.PI;
|
||||
statusInfo.ExtendedProperties["LastDetectionTime"] = lastDetectionTime?.ToString() ?? "null";
|
||||
statusInfo.ExtendedProperties["FirstDetectionAngle"] = firstDetectionAngle?.ToString() ?? "null";
|
||||
statusInfo.ExtendedProperties["IsTargetDetected"] = isTargetDetected.ToString();
|
||||
statusInfo.ExtendedProperties["TargetPosition"] = target.Position.ToString();
|
||||
statusInfo.ExtendedProperties["TargetPosition"] = target.KState.Position.ToString();
|
||||
statusInfo.ExtendedProperties["DistanceToTarget"] = distanceToTarget.ToString();
|
||||
statusInfo.ExtendedProperties["IsSensorsJammed"] = IsSensorsJammed().ToString();
|
||||
|
||||
|
||||
@ -84,14 +84,14 @@ namespace ThreatSource.Sensor
|
||||
/// - 初始化工作状态
|
||||
/// - 创建干扰处理组件
|
||||
/// </remarks>
|
||||
protected BaseSensor(string id, MotionParameters motionParameters, ISimulationManager simulationManager)
|
||||
protected BaseSensor(string id, KinematicState motionParameters, ISimulationManager simulationManager)
|
||||
: base(id, motionParameters, simulationManager)
|
||||
{
|
||||
IsActive = false;
|
||||
|
||||
// 初始化干扰处理组件
|
||||
_jammingComponent = new JammableComponent(
|
||||
positionProvider: () => Position
|
||||
positionProvider: () => KState.Position
|
||||
);
|
||||
|
||||
// Subscribe to the events instead
|
||||
|
||||
@ -72,7 +72,7 @@ namespace ThreatSource.Sensor
|
||||
/// - 继承基类位置和姿态
|
||||
/// </remarks>
|
||||
public InfraredDetector(string id, TerminalSensitiveSubmunition submunition, InfraredDetectorConfig config, ISimulationManager simulationManager)
|
||||
: base(id, new MotionParameters(submunition.Position, submunition.Orientation, submunition.Speed), simulationManager)
|
||||
: base(id, new KinematicState(submunition.KState.Position, submunition.KState.Orientation, submunition.KState.Speed), simulationManager)
|
||||
{
|
||||
this.config = config;
|
||||
this.submunition = submunition;
|
||||
@ -99,8 +99,8 @@ namespace ThreatSource.Sensor
|
||||
protected override void UpdateSensor(double deltaTime)
|
||||
{
|
||||
// 从子弹更新位置和朝向
|
||||
Position = submunition.Position;
|
||||
Orientation = Orientation.FromVector(submunition.ScanDirection);
|
||||
KState.Position = submunition.KState.Position;
|
||||
KState.Orientation = Orientation.FromVector(submunition.ScanDirection);
|
||||
|
||||
// 实时计算烟幕衰减
|
||||
double smokeAttenuation = 1.0; // 默认无衰减
|
||||
@ -111,13 +111,13 @@ namespace ThreatSource.Sensor
|
||||
if (SimulationManager.GetEntityById(jammerId) is SmokeGrenade smokeGrenade)
|
||||
{
|
||||
// 计算视线目标点
|
||||
var targetPointForLos = MotionAlgorithm.CalculateIntersectionWithGround(Position, Orientation.ToVector(), 0);
|
||||
var targetPointForLos = MotionAlgorithm.CalculateIntersectionWithGround(KState.Position, KState.Orientation.ToVector(), 0);
|
||||
if (targetPointForLos != null)
|
||||
{
|
||||
var wavelength = config.Band == InfraredBand.Long ? 10.0 : 4.0; // 代表性波长
|
||||
|
||||
// 计算此烟幕的透射率
|
||||
double singleSmokeTransmittance = smokeGrenade.GetSmokeTransmittanceOnLine(Position, targetPointForLos, wavelength);
|
||||
double singleSmokeTransmittance = smokeGrenade.GetSmokeTransmittanceOnLine(KState.Position, targetPointForLos, wavelength);
|
||||
smokeAttenuation *= singleSmokeTransmittance; // 累乘透射率
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ namespace ThreatSource.Sensor
|
||||
/// - 初始化工作状态
|
||||
/// </remarks>
|
||||
public LaserRangefinder(string id, TerminalSensitiveSubmunition submunition, LaserRangefinderConfig config, ISimulationManager simulationManager)
|
||||
: base(id, new MotionParameters(submunition.Position, submunition.Orientation, submunition.Speed), simulationManager)
|
||||
: base(id, new KinematicState(submunition.KState.Position, submunition.KState.Orientation, submunition.KState.Speed), simulationManager)
|
||||
{
|
||||
this.config = config;
|
||||
this.submunition = submunition;
|
||||
@ -105,8 +105,8 @@ namespace ThreatSource.Sensor
|
||||
protected override void UpdateSensor(double deltaTime)
|
||||
{
|
||||
// 从submunition更新位置和朝向
|
||||
Position = submunition.Position;
|
||||
Orientation = Orientation.FromVector(submunition.ScanDirection);
|
||||
KState.Position = submunition.KState.Position;
|
||||
KState.Orientation = Orientation.FromVector(submunition.ScanDirection);
|
||||
|
||||
// 实时计算烟幕衰减
|
||||
double smokeAttenuation = 1.0; // 默认无衰减
|
||||
@ -117,13 +117,13 @@ namespace ThreatSource.Sensor
|
||||
if (SimulationManager.GetEntityById(jammerId) is SmokeGrenade smokeGrenade)
|
||||
{
|
||||
// 计算视线目标点 (地面交点)
|
||||
var targetPointForLos = MotionAlgorithm.CalculateIntersectionWithGround(Position, Orientation.ToVector(), 0);
|
||||
var targetPointForLos = MotionAlgorithm.CalculateIntersectionWithGround(KState.Position, KState.Orientation.ToVector(), 0);
|
||||
if (targetPointForLos != null)
|
||||
{
|
||||
var wavelength = config.Wavelength;
|
||||
|
||||
// 计算此烟幕的透射率
|
||||
double singleSmokeTransmittance = smokeGrenade.GetSmokeTransmittanceOnLine(Position, targetPointForLos, wavelength);
|
||||
double singleSmokeTransmittance = smokeGrenade.GetSmokeTransmittanceOnLine(KState.Position, targetPointForLos, wavelength);
|
||||
smokeAttenuation *= singleSmokeTransmittance; // 累乘透射率
|
||||
}
|
||||
}
|
||||
@ -255,14 +255,14 @@ namespace ThreatSource.Sensor
|
||||
private double GetTargetDistance()
|
||||
{
|
||||
// 获取视线目标点
|
||||
var targetPoint = MotionAlgorithm.CalculateIntersectionWithGround(Position, Orientation.ToVector(), 0);
|
||||
var targetPoint = MotionAlgorithm.CalculateIntersectionWithGround(KState.Position, KState.Orientation.ToVector(), 0);
|
||||
|
||||
if (targetPoint != null)
|
||||
{
|
||||
// 计算到目标点的斜距
|
||||
double dx = targetPoint.X - Position.X;
|
||||
double dy = targetPoint.Y - Position.Y;
|
||||
double dz = targetPoint.Z - Position.Z;
|
||||
double dx = targetPoint.X - KState.Position.X;
|
||||
double dy = targetPoint.Y - KState.Position.Y;
|
||||
double dz = targetPoint.Z - KState.Position.Z;
|
||||
double calculatedSlantRange = Math.Sqrt(dx * dx + dy * dy + dz * dz);
|
||||
|
||||
// 确保距离不超过最大探测范围
|
||||
|
||||
@ -75,10 +75,10 @@ namespace ThreatSource.Sensor
|
||||
/// - 继承基类位置和姿态
|
||||
/// </remarks>
|
||||
public MillimeterWaveAltimeter(string id, TerminalSensitiveSubmunition submunition, MillimeterWaveAltimeterConfig config, ISimulationManager simulationManager)
|
||||
: base(id, new MotionParameters(submunition.Position, submunition.Orientation, submunition.Speed), simulationManager)
|
||||
: base(id, new KinematicState(submunition.KState.Position, submunition.KState.Orientation, submunition.KState.Speed), simulationManager)
|
||||
{
|
||||
this.config = config;
|
||||
currentAltitude = submunition.Position.Y;
|
||||
currentAltitude = submunition.KState.Position.Y;
|
||||
this.submunition = submunition;
|
||||
sensorData = new AltimeterSensorData();
|
||||
// 初始化干扰处理
|
||||
@ -137,8 +137,8 @@ namespace ThreatSource.Sensor
|
||||
protected override void UpdateSensor(double deltaTime)
|
||||
{
|
||||
// 从submunition更新位置和朝向
|
||||
Position = submunition.Position;
|
||||
Orientation = submunition.Orientation;
|
||||
KState.Position = submunition.KState.Position;
|
||||
KState.Orientation = submunition.KState.Orientation;
|
||||
|
||||
// 实时计算烟幕衰减
|
||||
double smokeAttenuation = 1.0; // 默认无衰减
|
||||
@ -149,7 +149,7 @@ namespace ThreatSource.Sensor
|
||||
if (SimulationManager.GetEntityById(jammerId) is SmokeGrenade smokeGrenade)
|
||||
{
|
||||
// 计算视线目标点 (地面交点)
|
||||
var targetPointForLos = MotionAlgorithm.CalculateIntersectionWithGround(Position, Orientation.ToVector(), 0);
|
||||
var targetPointForLos = MotionAlgorithm.CalculateIntersectionWithGround(KState.Position, KState.Orientation.ToVector(), 0);
|
||||
|
||||
if (targetPointForLos != null)
|
||||
{
|
||||
@ -160,7 +160,7 @@ namespace ThreatSource.Sensor
|
||||
_ => 0.0
|
||||
};
|
||||
// 计算此烟幕的透射率
|
||||
double singleSmokeTransmittance = smokeGrenade.GetSmokeTransmittanceOnLine(Position, targetPointForLos, wavelength);
|
||||
double singleSmokeTransmittance = smokeGrenade.GetSmokeTransmittanceOnLine(KState.Position, targetPointForLos, wavelength);
|
||||
smokeAttenuation *= singleSmokeTransmittance; // 累乘透射率
|
||||
}
|
||||
}
|
||||
@ -169,7 +169,7 @@ namespace ThreatSource.Sensor
|
||||
if ((!IsJammed || IsJammed && !IsBlockingJammed) && smokeAttenuation > 0.1)
|
||||
{
|
||||
// 更新当前高度,考虑测量精度
|
||||
currentAltitude = submunition.Position.Y + (2 * new Random().NextDouble() - 1) * config.MeasurementAccuracy;
|
||||
currentAltitude = submunition.KState.Position.Y + (2 * new Random().NextDouble() - 1) * config.MeasurementAccuracy;
|
||||
sensorData.Altitude = currentAltitude;
|
||||
}
|
||||
else
|
||||
|
||||
@ -110,7 +110,7 @@ namespace ThreatSource.Sensor
|
||||
/// - 继承基类位置和姿态
|
||||
/// </remarks>
|
||||
public MillimeterWaveRadiometer(string id, TerminalSensitiveSubmunition submunition, MillimeterWaveRadiometerConfig config, ISimulationManager simulationManager)
|
||||
: base(id, new MotionParameters(submunition.Position, submunition.Orientation, submunition.Speed), simulationManager)
|
||||
: base(id, new KinematicState(submunition.KState.Position, submunition.KState.Orientation, submunition.KState.Speed), simulationManager)
|
||||
{
|
||||
// 设置设备参数
|
||||
this.config = config;
|
||||
@ -150,8 +150,8 @@ namespace ThreatSource.Sensor
|
||||
protected override void UpdateSensor(double deltaTime)
|
||||
{
|
||||
// 从submunition更新位置和朝向
|
||||
Position = submunition.Position;
|
||||
Orientation = Orientation.FromVector(submunition.ScanDirection);
|
||||
KState.Position = submunition.KState.Position;
|
||||
KState.Orientation = Orientation.FromVector(submunition.ScanDirection);
|
||||
|
||||
// 实时计算烟幕衰减
|
||||
double smokeAttenuation = 1.0; // 默认无衰减
|
||||
@ -162,7 +162,7 @@ namespace ThreatSource.Sensor
|
||||
if (SimulationManager.GetEntityById(jammerId) is SmokeGrenade smokeGrenade)
|
||||
{
|
||||
// 计算视线目标点 (地面交点)
|
||||
var targetPointForLos = MotionAlgorithm.CalculateIntersectionWithGround(Position, Orientation.ToVector(), 0);
|
||||
var targetPointForLos = MotionAlgorithm.CalculateIntersectionWithGround(KState.Position, KState.Orientation.ToVector(), 0);
|
||||
|
||||
if (targetPointForLos != null)
|
||||
{
|
||||
@ -173,7 +173,7 @@ namespace ThreatSource.Sensor
|
||||
_ => 0.0
|
||||
};
|
||||
// 计算此烟幕的透射率
|
||||
double singleSmokeTransmittance = smokeGrenade.GetSmokeTransmittanceOnLine(Position, targetPointForLos, wavelength);
|
||||
double singleSmokeTransmittance = smokeGrenade.GetSmokeTransmittanceOnLine(KState.Position, targetPointForLos, wavelength);
|
||||
smokeAttenuation *= singleSmokeTransmittance; // 累乘透射率
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,21 +19,11 @@ namespace ThreatSource.Simulation
|
||||
/// 仿真元素的类型名称
|
||||
/// </summary>
|
||||
public string ElementType { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 仿真元素的当前位置
|
||||
/// 仿真元素的运动学状态
|
||||
/// </summary>
|
||||
public Vector3D Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仿真元素的当前朝向
|
||||
/// </summary>
|
||||
public Orientation Orientation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仿真元素的当前速度
|
||||
/// </summary>
|
||||
public double Speed { get; set; }
|
||||
public KinematicState KState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仿真元素是否处于活动状态
|
||||
@ -55,14 +45,13 @@ namespace ThreatSource.Simulation
|
||||
/// </summary>
|
||||
public ElementStatusInfo()
|
||||
{
|
||||
ExtendedProperties = new Dictionary<string, object>();
|
||||
ExtendedProperties = [];
|
||||
Timestamp = DateTime.UtcNow.Ticks;
|
||||
|
||||
// 初始化非空属性
|
||||
Id = string.Empty;
|
||||
ElementType = string.Empty;
|
||||
Position = Vector3D.Zero;
|
||||
Orientation = new Orientation();
|
||||
KState = new KinematicState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -71,7 +60,7 @@ namespace ThreatSource.Simulation
|
||||
/// <returns>状态的字符串表示</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
string baseInfo = $"仿真元素 {ElementType} {Id} at {Position}, Orientation: {Orientation}, Active: {IsActive}";
|
||||
string baseInfo = $"仿真元素 {ElementType} {Id} at {KState.Position}, Active: {IsActive}";
|
||||
|
||||
if (ExtendedProperties.Count > 0)
|
||||
{
|
||||
|
||||
@ -7,7 +7,7 @@ namespace ThreatSource.Simulation
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 该接口定义了仿真实体的核心功能:
|
||||
/// - 位置和运动状态管理
|
||||
/// - 运动学状态管理 (通过 KinematicState)
|
||||
/// - 生命周期管理(激活/停用)
|
||||
/// - 状态更新机制
|
||||
/// 所有参与仿真的实体都必须实现此接口
|
||||
@ -20,24 +20,14 @@ namespace ThreatSource.Simulation
|
||||
string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置仿真元素的当前位置
|
||||
/// 获取仿真元素的当前运动学状态,包括位置、速度、朝向等。
|
||||
/// </summary>
|
||||
Vector3D Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置仿真元素的当前速度向量
|
||||
/// </summary>
|
||||
Vector3D Velocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置仿真元素的当前速度大小
|
||||
/// </summary>
|
||||
double Speed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置仿真元素的当前朝向
|
||||
/// </summary>
|
||||
Orientation Orientation { get; set; }
|
||||
/// <remarks>
|
||||
/// 通过此属性可以读取和修改元素的运动学参数。
|
||||
/// 例如: element.KState.Position = newPosition;
|
||||
/// element.KState.Velocity = newVelocity;
|
||||
/// </remarks>
|
||||
KinematicState KState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取仿真元素是否处于活动状态
|
||||
|
||||
170
ThreatSource/src/Simulation/KinematicState.cs
Normal file
170
ThreatSource/src/Simulation/KinematicState.cs
Normal file
@ -0,0 +1,170 @@
|
||||
using ThreatSource.Utils;
|
||||
|
||||
namespace ThreatSource.Simulation
|
||||
{
|
||||
/// <summary>
|
||||
/// 运动学状态类,定义了仿真元素的运动学状态
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 该类用于:
|
||||
/// - 设置仿真元素的位置和姿态
|
||||
/// - 配置速度和目标
|
||||
/// 这些参数在实际使用时动态设置,而不是存储在配置文件中
|
||||
/// </remarks>
|
||||
public class KinematicState
|
||||
{
|
||||
private Vector3D _velocity = Vector3D.Zero;
|
||||
private double _speed = 0.0;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置仿真元素的位置
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 使用三维向量表示发射位置
|
||||
/// 坐标系:右手坐标系,X向右,Y向上,Z向前 (根据项目约定,-Z 为前)
|
||||
/// </remarks>
|
||||
public Vector3D Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置仿真元素的姿态
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 使用欧拉角表示姿态
|
||||
/// 包含偏航角、俯仰角和滚转角
|
||||
/// </remarks>
|
||||
public Orientation Orientation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置仿真元素的速率(标量)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 单位:米/秒。
|
||||
/// 当设置此值时:
|
||||
/// - 如果当前速度向量 (Velocity) 非零,则其方向保持不变,模长更新为新的 Speed。
|
||||
/// - 如果当前速度向量为零,则其方向将根据当前的 Orientation 确定。
|
||||
/// 当读取此值时,它反映的是当前速度向量 (Velocity) 的模长。
|
||||
/// </remarks>
|
||||
public double Speed
|
||||
{
|
||||
get => _speed;
|
||||
set
|
||||
{
|
||||
_speed = value;
|
||||
if (_velocity != null && _velocity.MagnitudeSquared() > 1e-9) // 容差,避免浮点问题
|
||||
{
|
||||
// 保持现有方向,更新模长
|
||||
_velocity = _velocity.Normalize() * _speed;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Velocity 是零向量或未初始化,使用 Orientation 确定方向
|
||||
Vector3D direction = Orientation.ToVector();
|
||||
if (direction.MagnitudeSquared() < 1e-9 && _speed != 0)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot set Speed to a non-zero value if Orientation.ToVector() results in a zero vector (e.g. from a zero orientation).");
|
||||
}
|
||||
_velocity = direction.Normalize() * _speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置仿真元素的速度向量 (Vector3D)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 单位:米/秒。
|
||||
/// 包含运动的方向和速率。
|
||||
/// 当设置此值时,Speed 属性会自动更新为该向量的模长。
|
||||
/// </remarks>
|
||||
public Vector3D Velocity
|
||||
{
|
||||
get => _velocity;
|
||||
set
|
||||
{
|
||||
_velocity = value ?? Vector3D.Zero; //确保 _velocity 不为 null
|
||||
_speed = _velocity.Magnitude();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化仿真元素运动学状态类的新实例 (默认构造函数)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 构造过程:
|
||||
/// - 设置默认的位置(原点)
|
||||
/// - 设置默认的姿态(零角度)
|
||||
/// - 设置默认的速度为零
|
||||
/// </remarks>
|
||||
public KinematicState()
|
||||
{
|
||||
Position = Vector3D.Zero;
|
||||
Orientation = new Orientation(0, 0, 0);
|
||||
Velocity = Vector3D.Zero; // Setter 会同时更新 Speed
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化仿真元素运动学状态类的新实例 (使用标量速率)
|
||||
/// </summary>
|
||||
/// <param name="position">初始位置</param>
|
||||
/// <param name="orientation">初始朝向</param>
|
||||
/// <param name="speed">初始速率 (标量)</param>
|
||||
/// <remarks>
|
||||
/// 速度向量将根据朝向和速率计算得出。
|
||||
/// </remarks>
|
||||
public KinematicState(Vector3D position, Orientation orientation, double speed)
|
||||
{
|
||||
Position = position;
|
||||
// 必须先设置 Orientation,因为 Speed 的 setter 可能会依赖它
|
||||
// Orientation is a struct, so it cannot be null.
|
||||
Orientation = orientation;
|
||||
Speed = speed; // Setter 会计算并设置 Velocity
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化仿真元素运动学状态类的新实例 (使用速度向量)
|
||||
/// </summary>
|
||||
/// <param name="position">初始位置</param>
|
||||
/// <param name="orientation">初始朝向</param>
|
||||
/// <param name="velocity">初始速度向量</param>
|
||||
public KinematicState(Vector3D position, Orientation orientation, Vector3D velocity)
|
||||
{
|
||||
Position = position;
|
||||
// Orientation is a struct, so it cannot be null.
|
||||
Orientation = orientation;
|
||||
Velocity = velocity; // Setter 会同时更新 Speed
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化仿真元素运动学状态类的新实例 (仅使用位置和速度向量)
|
||||
/// </summary>
|
||||
/// <param name="position">初始位置</param>
|
||||
/// <param name="velocity">初始速度向量</param>
|
||||
/// <remarks>
|
||||
/// 初始朝向 (Orientation) 将根据提供的速度向量 (velocity) 的方向自动设置。
|
||||
/// 如果速度向量为零或其模长接近于零,则朝向将设为默认值 (Yaw:0, Pitch:0, Roll:0)。
|
||||
/// 如果需要独立于初始速度方向来指定初始朝向,请使用 MotionParameters(Vector3D, Orientation, Vector3D) 构造函数。
|
||||
/// </remarks>
|
||||
public KinematicState(Vector3D position, Vector3D velocity)
|
||||
{
|
||||
Position = position;
|
||||
Velocity = velocity; // Setter 会同时更新 Speed
|
||||
if (velocity != null && velocity.MagnitudeSquared() > 1e-9)
|
||||
{
|
||||
Orientation = Orientation.FromVector(velocity.Normalize());
|
||||
}
|
||||
else
|
||||
{
|
||||
Orientation = new Orientation(0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重写ToString方法,返回KinematicState对象的字符串表示
|
||||
/// </summary>
|
||||
/// <returns>KinematicState对象的字符串表示</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Position: {Position}, Orientation: {Orientation}, Speed: {Speed:F2}, Velocity: {Velocity}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,76 +0,0 @@
|
||||
using ThreatSource.Utils;
|
||||
|
||||
namespace ThreatSource.Simulation
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化运动参数类,定义了仿真元素初始化时的运动学参数
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 该类用于:
|
||||
/// - 设置仿真元素的初始位置和姿态
|
||||
/// - 配置初始速度和目标
|
||||
/// - 提供战术场景相关的参数
|
||||
/// 这些参数在实际使用时动态设置,而不是存储在配置文件中
|
||||
/// </remarks>
|
||||
public class MotionParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置仿真元素的初始位置
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 使用三维向量表示发射位置
|
||||
/// 坐标系:右手坐标系,X向右,Y向上,Z向前
|
||||
/// </remarks>
|
||||
public Vector3D Position { get; set; } = new Vector3D(0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置仿真元素的初始朝向
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 使用欧拉角表示初始姿态
|
||||
/// 包含偏航角、俯仰角和滚转角
|
||||
/// </remarks>
|
||||
public Orientation Orientation { get; set; } = new Orientation(0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置仿真元素的初始速度
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 单位:米/秒
|
||||
/// 初始运动速度
|
||||
/// </remarks>
|
||||
public double InitialSpeed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始化仿真元素初始化参数类的新实例
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 构造过程:
|
||||
/// - 设置默认的初始位置(原点)
|
||||
/// - 设置默认的初始朝向(零角度)
|
||||
/// - 初始化其他参数为默认值
|
||||
/// </remarks>
|
||||
public MotionParameters()
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0);
|
||||
Orientation = new Orientation(0, 0, 0);
|
||||
InitialSpeed = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化仿真元素运动参数类的新实例
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 构造过程:
|
||||
/// - 设置初始位置
|
||||
/// - 设置初始朝向
|
||||
/// - 设置初始速度
|
||||
/// </remarks>
|
||||
public MotionParameters(Vector3D position, Orientation orientation, double initialSpeed)
|
||||
{
|
||||
Position = position;
|
||||
Orientation = orientation;
|
||||
InitialSpeed = initialSpeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@ namespace ThreatSource.Simulation
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 该类提供了仿真实体的基本功能的默认实现:
|
||||
/// - 位置和运动状态管理
|
||||
/// - 运动学状态管理 (通过 KinematicState)
|
||||
/// - 生命周期管理(激活/停用)
|
||||
/// - 事件发布机制
|
||||
/// - 状态更新机制
|
||||
@ -20,16 +20,7 @@ namespace ThreatSource.Simulation
|
||||
public virtual string Id { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual Vector3D Position { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual double Speed { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual Vector3D Velocity { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual Orientation Orientation { get; set; }
|
||||
public virtual KinematicState KState { get; protected set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual bool IsActive { get; protected set; }
|
||||
@ -47,22 +38,18 @@ namespace ThreatSource.Simulation
|
||||
/// 初始化仿真元素的新实例
|
||||
/// </summary>
|
||||
/// <param name="id">仿真元素的唯一标识符</param>
|
||||
/// <param name="motionParameters">初始运动参数</param>
|
||||
/// <param name="kinematicState">初始运动学状态 (现在是 KinematicState)</param>
|
||||
/// <param name="simulationManager">仿真管理器实例</param>
|
||||
/// <remarks>
|
||||
/// 构造函数设置实体的初始状态:
|
||||
/// - 根据ID、位置、朝向和速度初始化实体
|
||||
/// - 计算初始速度向量
|
||||
/// - 根据ID和 KinematicState 初始化实体
|
||||
/// - 设置初始状态为未激活
|
||||
/// </remarks>
|
||||
protected SimulationElement(string id, MotionParameters motionParameters, ISimulationManager simulationManager)
|
||||
protected SimulationElement(string id, KinematicState kinematicState, ISimulationManager simulationManager)
|
||||
{
|
||||
Id = id;
|
||||
Position = motionParameters.Position;
|
||||
Orientation = motionParameters.Orientation;
|
||||
Speed = motionParameters.InitialSpeed;
|
||||
Velocity = motionParameters.Orientation.ToVector() * motionParameters.InitialSpeed;
|
||||
this.SimulationManager = simulationManager;
|
||||
KState = kinematicState;
|
||||
SimulationManager = simulationManager;
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
@ -72,8 +59,7 @@ namespace ThreatSource.Simulation
|
||||
/// <param name="deltaTime">时间步长,单位:秒</param>
|
||||
/// <remarks>
|
||||
/// 抽象方法,需要在派生类中实现具体的更新逻辑:
|
||||
/// - 更新位置和朝向
|
||||
/// - 计算新的速度和加速度
|
||||
/// - 更新 KinematicState (位置、速度、朝向等)
|
||||
/// - 处理碰撞和其他物理效果
|
||||
/// - 触发相关事件
|
||||
/// </remarks>
|
||||
@ -87,8 +73,7 @@ namespace ThreatSource.Simulation
|
||||
/// 返回的字符串包含:
|
||||
/// - 实体类型
|
||||
/// - 实体ID
|
||||
/// - 当前位置
|
||||
/// - 当前朝向
|
||||
/// - 当前 KinematicState (位置、朝向等)
|
||||
/// - 活动状态
|
||||
/// </remarks>
|
||||
public virtual string GetStatus()
|
||||
@ -103,9 +88,7 @@ namespace ThreatSource.Simulation
|
||||
{
|
||||
Id = Id,
|
||||
ElementType = GetType().Name,
|
||||
Position = Position,
|
||||
Orientation = Orientation,
|
||||
Speed = Speed,
|
||||
KState = KState,
|
||||
IsActive = IsActive
|
||||
};
|
||||
|
||||
@ -124,10 +107,9 @@ namespace ThreatSource.Simulation
|
||||
/// </remarks>
|
||||
protected void PublishEvent<T>(T evt) where T : SimulationEvent
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(evt);
|
||||
evt.SenderId = Id;
|
||||
evt.Timestamp = DateTime.UtcNow.Ticks;
|
||||
SimulationManager.PublishEvent(evt);
|
||||
Console.WriteLine($"[仿真元素] 发布事件: 事件类型={evt.GetType().Name}, 发送者ID={evt.SenderId}, 时间戳={evt.Timestamp}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -136,7 +118,7 @@ namespace ThreatSource.Simulation
|
||||
/// <remarks>
|
||||
/// 激活操作会:
|
||||
/// - 将IsActive设置为true
|
||||
/// - 发布实体激活事件
|
||||
/// - 发布实体激活事件 (可选, 如果有此设计)
|
||||
/// - 允许实体参与仿真计算
|
||||
/// </remarks>
|
||||
public virtual void Activate()
|
||||
@ -153,7 +135,7 @@ namespace ThreatSource.Simulation
|
||||
/// <remarks>
|
||||
/// 停用操作会:
|
||||
/// - 将IsActive设置为false
|
||||
/// - 发布实体停用事件
|
||||
/// - 发布实体停用事件 (可选, 如果有此设计)
|
||||
/// - 停止实体参与仿真计算
|
||||
/// </remarks>
|
||||
public virtual void Deactivate()
|
||||
|
||||
@ -185,8 +185,8 @@ namespace ThreatSource.Simulation
|
||||
{
|
||||
foreach (var target in activeTargets)
|
||||
{
|
||||
double distance = Vector3D.Distance(missile.Position, target.Position);
|
||||
Console.WriteLine($"导弹 {missile.Id} 和目标 {target.Id} 之间的距离: {distance}");
|
||||
double distance = Vector3D.Distance(missile.KState.Position, target.KState.Position);
|
||||
Console.WriteLine($"导弹 {missile.Id} 和目标 {target.Id} 之间的距离: {distance:F2}");
|
||||
if (distance <= missile.Properties.ExplosionRadius)
|
||||
{
|
||||
double damage = CalculateMissileDamage(missile);
|
||||
|
||||
@ -189,11 +189,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
/// </summary>
|
||||
private void AddTankTarget()
|
||||
{
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 1.2, 0),
|
||||
Orientation = new Orientation(0.0, 0.0, 0.0),
|
||||
InitialSpeed = 1.0
|
||||
Speed = 1.0
|
||||
};
|
||||
string targetId = "Tank_1";
|
||||
var target = _threatSourceFactory.CreateTarget(targetId, "mbt_001", motionParameters);
|
||||
@ -207,11 +207,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
/// </summary>
|
||||
private void AddLaserDecoy()
|
||||
{
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 50),
|
||||
Orientation = new Orientation(Math.PI/2, 0.0, 0.0),
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
string laserDecoyId = "LDY_1";
|
||||
var laserDecoy = _threatSourceFactory.CreateJammer(laserDecoyId, "laser_decoy", motionParameters, "Tank_1") as LaserDecoy;
|
||||
@ -228,11 +228,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
/// </summary>
|
||||
private void AddSmokeGrenade()
|
||||
{
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(50, 5, 0),
|
||||
Orientation = new Orientation(Math.PI/2, 0.0, 0.0),
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
string smokeGrenadeId = "SG_1";
|
||||
var smokeGrenade = _threatSourceFactory.CreateJammer(smokeGrenadeId, "surround", motionParameters, "Tank_1");
|
||||
@ -261,11 +261,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
Console.WriteLine($"注册烟幕弹 {smokeGrenadeId}");
|
||||
}
|
||||
|
||||
var motionParametersTop = new MotionParameters
|
||||
var motionParametersTop = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 10, 0),
|
||||
Orientation = new Orientation(0, Math.PI/2, 0.0),
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
smokeGrenadeId = "SG_4";
|
||||
smokeGrenade = _threatSourceFactory.CreateJammer(smokeGrenadeId, "top", motionParametersTop, "Tank_1");
|
||||
@ -282,11 +282,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
/// </summary>
|
||||
private void AddLaserSemiActiveMissile()
|
||||
{
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(2000, 10, 10),
|
||||
Orientation = new Orientation(Math.PI/2, -0.01, 0),
|
||||
InitialSpeed = 700
|
||||
Speed = 700
|
||||
};
|
||||
string missileId = "LSGM_1";
|
||||
var missile = _threatSourceFactory.CreateMissile(missileId, "lsgm_001", "Tank_1", motionParameters);
|
||||
@ -300,11 +300,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
/// </summary>
|
||||
private void AddLaserBeamRiderMissile()
|
||||
{
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(2000, 10, 10),
|
||||
Orientation = new Orientation(Math.PI/2, -0.01, 0.0),
|
||||
InitialSpeed = 300
|
||||
Speed = 300
|
||||
};
|
||||
string missileId = "LBRM_1";
|
||||
var missile = _threatSourceFactory.CreateMissile(missileId, "hj10", "Tank_1", motionParameters);
|
||||
@ -318,11 +318,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
/// </summary>
|
||||
private void AddTerminalSensitiveMissile()
|
||||
{
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(3000, 0, 20),
|
||||
Orientation = new Orientation(Math.PI/2, 0.0, 0.0),
|
||||
InitialSpeed = 800
|
||||
Speed = 800
|
||||
};
|
||||
|
||||
string missileId = "TSM_1";
|
||||
@ -338,11 +338,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
/// </summary>
|
||||
private void AddInfraredCommandMissile()
|
||||
{
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(2000, 1, 20),
|
||||
Orientation = new Orientation(Math.PI/2, 0.01, 0),
|
||||
InitialSpeed = 300
|
||||
Speed = 300
|
||||
};
|
||||
|
||||
string missileId = "ICGM_1";
|
||||
@ -357,11 +357,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
/// </summary>
|
||||
private void AddInfraredImagingMissile()
|
||||
{
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(2000, 10, 0),
|
||||
Orientation = new Orientation(Math.PI/2, -0.001, 0),
|
||||
InitialSpeed = 300
|
||||
Speed = 300
|
||||
};
|
||||
string missileId = "ITGM_1";
|
||||
var missile = _threatSourceFactory.CreateMissile(missileId, "itg_001", "Tank_1", motionParameters);
|
||||
@ -375,11 +375,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
/// </summary>
|
||||
private void AddMillimeterWaveMissile()
|
||||
{
|
||||
var motionParameters = new MotionParameters
|
||||
var motionParameters = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(2000, 1, 20),
|
||||
Orientation = new Orientation(Math.PI/2, 0.01, 0),
|
||||
InitialSpeed = 300
|
||||
Speed = 300
|
||||
};
|
||||
string missileId = "MMWG_1";
|
||||
var missile = _threatSourceFactory.CreateMissile(missileId, "mmw_001", "Tank_1", motionParameters);
|
||||
@ -395,11 +395,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
{
|
||||
// 添加激光目标指示器
|
||||
string laserDesignatorId = "LD_1";
|
||||
var laserDesignatorLaunchParams = new MotionParameters
|
||||
var laserDesignatorLaunchParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(2100, 1, 100),
|
||||
Orientation = new Orientation(Math.PI/2, 0.01, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
var laserDesignator = _threatSourceFactory.CreateIndicator(laserDesignatorId, "ld_001", "Tank_1", "LSGM_1", laserDesignatorLaunchParams);
|
||||
indicators[laserDesignatorId] = (SimulationElement)laserDesignator;
|
||||
@ -408,11 +408,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
|
||||
// 添加激光驾束仪
|
||||
string laserBeamRiderId = "LBR_1";
|
||||
var laserBeamRiderLaunchParams = new MotionParameters
|
||||
var laserBeamRiderLaunchParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(2100, 1, 10),
|
||||
Orientation = new Orientation(Math.PI/2, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
var laserBeamRider = _threatSourceFactory.CreateIndicator(laserBeamRiderId, "br_001", "Tank_1", "LBRM_1", laserBeamRiderLaunchParams);
|
||||
indicators[laserBeamRiderId] = (SimulationElement)laserBeamRider;
|
||||
@ -421,11 +421,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
|
||||
// 添加红外测角仪
|
||||
string infraredTrackerId = "IT_1";
|
||||
var infraredTrackerLaunchParams = new MotionParameters
|
||||
var infraredTrackerLaunchParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(2100, 1, 0),
|
||||
Orientation = new Orientation(Math.PI/2, 0, 0),
|
||||
InitialSpeed = 0
|
||||
Speed = 0
|
||||
};
|
||||
var infraredTracker = _threatSourceFactory.CreateIndicator(infraredTrackerId, "ir_001", "Tank_1", "ITGM_1", infraredTrackerLaunchParams);
|
||||
indicators[infraredTrackerId] = (SimulationElement)infraredTracker;
|
||||
@ -439,11 +439,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
private void AddJammers()
|
||||
{
|
||||
// 添加激光干扰器 - 指向指示器
|
||||
var laserJammerParams = new MotionParameters
|
||||
var laserJammerParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = CalculateOrientationToEntity(indicators["LD_1"]), // 朝向激光指示器
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
string laserJammerId = "LaserJammer_Designator";
|
||||
var laserJammer = _threatSourceFactory.CreateJammer(laserJammerId, "laser_blocking", laserJammerParams, "Tank_1");
|
||||
@ -455,11 +455,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
}
|
||||
|
||||
// 添加激光干扰器 - 指向导弹
|
||||
laserJammerParams = new MotionParameters
|
||||
laserJammerParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = CalculateOrientationToEntity(missiles["LSGM_1"]), // 朝向激光半主动导弹
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
laserJammerId = "LaserJammer_Missile";
|
||||
laserJammer = _threatSourceFactory.CreateJammer(laserJammerId, "laser_blocking", laserJammerParams, "Tank_1");
|
||||
@ -471,11 +471,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
}
|
||||
|
||||
// 添加红外干扰器 - 指向指示器
|
||||
var irJammerParams = new MotionParameters
|
||||
var irJammerParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = CalculateOrientationToEntity(indicators["IT_1"]), // 朝向红外指示器
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
string irJammerId = "InfraredJammer_Designator";
|
||||
var irJammer = _threatSourceFactory.CreateJammer(irJammerId, "infrared_blocking", irJammerParams, "Tank_1");
|
||||
@ -487,11 +487,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
}
|
||||
|
||||
// 添加红外干扰器 - 指向导弹
|
||||
irJammerParams = new MotionParameters
|
||||
irJammerParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = CalculateOrientationToEntity(missiles["ITGM_1"]), // 朝向红外成像导弹
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
irJammerId = "InfraredJammer_Missile";
|
||||
irJammer = _threatSourceFactory.CreateJammer(irJammerId, "infrared_blocking", irJammerParams, "Tank_1");
|
||||
@ -503,11 +503,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
}
|
||||
|
||||
// 添加毫米波干扰器 - 指向导弹
|
||||
var mmwJammerParams = new MotionParameters
|
||||
var mmwJammerParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = CalculateOrientationToEntity(missiles["MMWG_1"]), // 朝向毫米波导弹
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
string mmwJammerId = "MillimeterWaveJammer_Missile";
|
||||
var mmwJammer = _threatSourceFactory.CreateJammer(mmwJammerId, "mmw_blocking", mmwJammerParams, "Tank_1");
|
||||
@ -519,11 +519,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
}
|
||||
|
||||
// 添加激光干扰器 - 指向子弹药
|
||||
laserJammerParams = new MotionParameters
|
||||
laserJammerParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, Math.PI/2, 0), // 朝向垂直向上
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
laserJammerId = "LaserJammer_Submunition";
|
||||
laserJammer = _threatSourceFactory.CreateJammer(laserJammerId, "laser_top_blocking", laserJammerParams, "Tank_1");
|
||||
@ -535,11 +535,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
}
|
||||
|
||||
// 添加红外干扰器 - 指向子弹药
|
||||
irJammerParams = new MotionParameters
|
||||
irJammerParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, Math.PI/2, 0), // 朝向垂直向上
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
irJammerId = "InfraredJammer_Submunition";
|
||||
irJammer = _threatSourceFactory.CreateJammer(irJammerId, "infrared_top_blocking", irJammerParams, "Tank_1");
|
||||
@ -551,11 +551,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
}
|
||||
|
||||
// 添加毫米波干扰器 - 指向子弹药
|
||||
mmwJammerParams = new MotionParameters
|
||||
mmwJammerParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, Math.PI/2, 0), // 朝向垂直向上
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
mmwJammerId = "MillimeterWaveJammer_Submunition";
|
||||
mmwJammer = _threatSourceFactory.CreateJammer(mmwJammerId, "mmw_top_blocking", mmwJammerParams, "Tank_1");
|
||||
@ -567,11 +567,11 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
}
|
||||
|
||||
// 添加毫米波补偿干扰器 - 指向导弹
|
||||
mmwJammerParams = new MotionParameters
|
||||
mmwJammerParams = new KinematicState
|
||||
{
|
||||
Position = new Vector3D(0, 0, 0),
|
||||
Orientation = new Orientation(0, Math.PI/2, 0), // 朝向垂直向上
|
||||
InitialSpeed = 0.0
|
||||
Speed = 0.0
|
||||
};
|
||||
string mmwCompensationJammerId = "MillimeterWaveCompensationJammer_Submunition";
|
||||
var mmwCompensationJammer = _threatSourceFactory.CreateJammer(mmwCompensationJammerId, "mmw_compensation", mmwJammerParams, "Tank_1");
|
||||
@ -589,7 +589,7 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
private Orientation CalculateOrientationToEntity(SimulationElement target)
|
||||
{
|
||||
// 使用CalculateDirectionToTarget获取归一化方向向量
|
||||
Vector3D direction = CalculateDirectionToTarget(new Vector3D(0, 0, 0), target.Position);
|
||||
Vector3D direction = CalculateDirectionToTarget(new Vector3D(0, 0, 0), target.KState.Position);
|
||||
|
||||
// 创建朝向目标的方向
|
||||
return Orientation.FromVector(direction);
|
||||
@ -808,8 +808,8 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
JammerId = jammerId,
|
||||
SourceId = jammer.Id,
|
||||
Power = 800, // 设置合适功率
|
||||
Direction = CalculateDirectionToTarget(jammer.Position, indicator.Position),
|
||||
SourcePosition = jammer.Position,
|
||||
Direction = CalculateDirectionToTarget(jammer.KState.Position, indicator.KState.Position),
|
||||
SourcePosition = jammer.KState.Position,
|
||||
StartTime = DateTime.UtcNow,
|
||||
Duration = 600 // 10分钟
|
||||
};
|
||||
@ -891,8 +891,8 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
JammerId = jammerId,
|
||||
SourceId = jammer.Id,
|
||||
Power = 1000, // 设置高功率
|
||||
Direction = CalculateDirectionToTarget(jammer.Position, missile.Position),
|
||||
SourcePosition = jammer.Position,
|
||||
Direction = CalculateDirectionToTarget(jammer.KState.Position, missile.KState.Position),
|
||||
SourcePosition = jammer.KState.Position,
|
||||
StartTime = DateTime.UtcNow,
|
||||
Duration = 600 // 10分钟
|
||||
};
|
||||
@ -1192,13 +1192,13 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
// 获取导弹的初始属性
|
||||
var motionParameters = missile.GetType().GetField("motionParameters",
|
||||
System.Reflection.BindingFlags.NonPublic |
|
||||
System.Reflection.BindingFlags.Instance)?.GetValue(missile) as MotionParameters;
|
||||
System.Reflection.BindingFlags.Instance)?.GetValue(missile) as KinematicState;
|
||||
|
||||
if (motionParameters != null)
|
||||
{
|
||||
// 重置导弹位置和状态
|
||||
missile.Position = motionParameters.Position;
|
||||
missile.Velocity = Vector3D.Zero;
|
||||
missile.KState.Position = motionParameters.Position;
|
||||
missile.KState.Velocity = Vector3D.Zero;
|
||||
}
|
||||
missile.Deactivate();
|
||||
}
|
||||
@ -1215,9 +1215,9 @@ namespace ThreatSource.Tools.MissileSimulation
|
||||
var activeTargets = simulationManager.GetEntitiesByType<Tank>();
|
||||
foreach (var target in activeTargets)
|
||||
{
|
||||
var initialPosition = target.Position;
|
||||
var initialPosition = target.KState.Position;
|
||||
target.Deactivate();
|
||||
target.Position = initialPosition;
|
||||
target.KState.Position = initialPosition;
|
||||
target.Activate();
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user