添加了KinematicState类,统一处理仿真元素的运动学状态

This commit is contained in:
Tian jianyong 2025-05-11 09:50:16 +08:00
parent d872c8ece3
commit ca3897a415
73 changed files with 745 additions and 752 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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(

View File

@ -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(

View File

@ -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
{

View File

@ -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);

View File

@ -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(

View File

@ -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(

View File

@ -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

View File

@ -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;

View File

@ -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
{

View File

@ -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();

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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
{

View File

@ -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();

View File

@ -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, "速度应该保持在开伞阶段的限制范围内");
}
}
}

View File

@ -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"]);

View File

@ -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"]);

View File

@ -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);
}
}
}

View File

@ -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"]);

View File

@ -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

View File

@ -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"]);

View File

@ -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"]);

View File

@ -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"]);

View File

@ -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);

View File

@ -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!)
{
}

View File

@ -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]

View File

@ -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

View File

@ -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)
{
}

View File

@ -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>

View File

@ -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)
{
}

View File

@ -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)
{
}

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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 // 目标数据(背景)
);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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();
}

View File

@ -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}");
}
}
}

View File

@ -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;

View File

@ -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)

View File

@ -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)
{

View File

@ -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)

View File

@ -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)
{

View File

@ -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)

View File

@ -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,

View File

@ -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;

View File

@ -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>

View File

@ -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)

View File

@ -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)

View File

@ -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);
}
}

View File

@ -89,7 +89,7 @@ namespace ThreatSource.Missile
public LaserSemiActiveGuidedMissile(
string missileId,
MissileProperties properties,
MotionParameters launchParams,
KinematicState launchParams,
LaserCodeConfig laserCodeConfig,
LaserSemiActiveGuidanceConfig guidanceConfig,
ISimulationManager manager)

View File

@ -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)

View File

@ -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

View File

@ -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();

View File

@ -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

View File

@ -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; // 累乘透射率
}
}

View File

@ -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);
// 确保距离不超过最大探测范围

View File

@ -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

View File

@ -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; // 累乘透射率
}
}

View File

@ -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)
{

View File

@ -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>
/// 获取仿真元素是否处于活动状态

View 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}";
}
}
}

View File

@ -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;
}
}
}

View File

@ -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()

View File

@ -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);

View File

@ -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();
}