给导弹和坦克的属性单独建类;增加了导弹命中概率,测试命中概率的影响

This commit is contained in:
Tian jianyong 2024-10-30 14:51:35 +08:00
parent 2f1ecf86cf
commit f60b7697fe
19 changed files with 433 additions and 509 deletions

View File

@ -26,7 +26,7 @@ namespace ActiveProtect
var config = new SimulationConfig
{
// 配置坦克
TankConfigs = new List<TankConfig>
TankConfigs = new List<TankProperties>
{
new(tankinfo)
{
@ -73,52 +73,54 @@ namespace ActiveProtect
ControlFieldDiameter = 6
},
// 配置导弹
MissileConfigs = new List<MissileConfig>
MissileConfigs = new List<MissileProperties>
{
// 激光半主动制导导弹配置
new() {
Id = "LSGM_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(2000, 100, 100),
InitialOrientation = new Orientation(Math.PI, -0.1, 0),
InitialSpeed = 700,
MaxSpeed = 800,
TargetIndex = 0,
MaxFlightTime = 10,
MaxFlightDistance = 5000,
LaunchAcceleration = 50,
MaxEngineBurnTime = 10,
MaxAcceleration = 400,
ProportionalNavigationCoefficient = 4,
ExplosionRadius = 10,
ExplosionRadius = 5,
HitProbability = 0.9,
Mass = 50,
Type = MissileType.LaserSemiActiveGuidance
},
// 激光驾束制导导弹配置
new() {
Id = "LBRM_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(2000, 10, 100),
InitialOrientation = new Orientation(Math.PI, 0.0, 0.0),
InitialSpeed = 300,
MaxSpeed = 400,
TargetIndex = 0,
MaxFlightTime = 10,
MaxFlightDistance = 3000,
LaunchAcceleration = 50,
MaxEngineBurnTime = 10,
MaxAcceleration = 400,
ProportionalNavigationCoefficient = 3,
ExplosionRadius = 10,
ExplosionRadius = 5,
HitProbability = 0.9,
Mass = 50,
Type = MissileType.LaserBeamRiderGuidance
},
// 末敏弹配置
new() {
Id = "TSM_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(3000, 0, 100), // 发射位置
InitialOrientation = new Orientation(Math.PI, 0, 0), // 使用计算得到的发射角度
InitialSpeed = 800,
MaxSpeed = 1000,
TargetIndex = 0,
MaxFlightTime = 30,
MaxFlightDistance = 5000,
LaunchAcceleration = 0,
@ -126,23 +128,25 @@ namespace ActiveProtect
MaxAcceleration = 10,
ProportionalNavigationCoefficient = 3,
ExplosionRadius = 5,
HitProbability = 0.9,
Mass = 50,
Type = MissileType.TerminalSensitiveMissile
},
// 红外指令制导导弹配置
new() {
Id = "ICGM_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(2000, 10, 100),
InitialOrientation = new Orientation(Math.PI, 0.0, 0),
InitialSpeed = 300,
MaxSpeed = 400,
TargetIndex = 0,
MaxFlightTime = 60,
MaxFlightDistance = 5000,
LaunchAcceleration = 50,
MaxEngineBurnTime = 10,
MaxAcceleration = 100,
ExplosionRadius = 5,
HitProbability = 0.9,
ProportionalNavigationCoefficient = 3,
Mass = 50,
Type = MissileType.InfraredCommandGuidance
@ -150,17 +154,18 @@ namespace ActiveProtect
// 红外成像末制导导弹配置
new() {
Id = "ITGM_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(2000, 100, 100),
InitialOrientation = new Orientation(Math.PI, 0.0, 0),
InitialSpeed = 300,
MaxSpeed = 400,
TargetIndex = 0,
MaxFlightTime = 60,
MaxFlightDistance = 5000,
LaunchAcceleration = 50,
MaxEngineBurnTime = 10,
MaxAcceleration = 50,
ExplosionRadius = 1,
ExplosionRadius = 5,
HitProbability = 0.9,
ProportionalNavigationCoefficient = 3,
Mass = 50,
Type = MissileType.InfraredImagingTerminalGuidance
@ -168,17 +173,18 @@ namespace ActiveProtect
// 毫米波导引头制导导弹配置
new() {
Id = "MMWG_1",
TargetId = "Tank_1",
InitialPosition = new Vector3D(2000, 10, 100),
InitialOrientation = new Orientation(Math.PI, 0.0, 0),
InitialSpeed = 300,
MaxSpeed = 400,
TargetIndex = 0,
MaxFlightTime = 60,
MaxFlightDistance = 5000,
LaunchAcceleration = 50,
MaxEngineBurnTime = 10,
MaxAcceleration = 50,
ExplosionRadius = 1,
ExplosionRadius = 5,
HitProbability = 0.9,
ProportionalNavigationCoefficient = 3,
Mass = 50,
Type = MissileType.MillimeterWaveTerminalGuidance
@ -193,9 +199,9 @@ namespace ActiveProtect
MaxTrackingRange = 10000, // 10公里
FieldOfView = Math.PI / 4, // 45度
AngleMeasurementAccuracy = 0.0005, // 0.0005弧度 (约0.029度)
UpdateFrequency = 10 // 20赫兹
UpdateFrequency = 100 // 100赫兹
},
SimulationTimeStep = 0.005 // 仿真时间步长, 激光驾束制导导弹需要更小的步长,< 0.025s
SimulationTimeStep = 0.01 // 仿真时间步长, 激光驾束制导导弹需要更小的步长,< 0.025s
};
// 创建仿真管理器
@ -208,7 +214,7 @@ namespace ActiveProtect
{
simulationManager.Update();
simulationManager.PrintStatus();
Thread.Sleep(20); // 暂停100毫秒使输出更易读
Thread.Sleep(10); // 暂停100毫秒使输出更易读
iteration++;
}

View File

@ -9,56 +9,27 @@ namespace ActiveProtect.Models
/// </summary>
public class Tank : SimulationElement
{
/// <summary>
/// 当前速度(米/秒)
/// </summary>
public double Speed { get; set; }
/// <summary>
/// 最大速度(米/秒)
/// </summary>
public double MaxSpeed { get; private set; }
/// <summary>
/// 最大装甲值
/// </summary>
public double MaxArmor { get; private set; }
/// <summary>
/// 当前装甲值
/// </summary>
public double CurrentArmor { get; private set; }
/// <summary>
/// 红外辐射强度 (W/sr)
/// </summary>
public double InfraredRadiationIntensity { get; set; }
/// <summary>
/// 雷达截面积 (m^2)
/// </summary>
public double RadarCrossSection { get; set; }
/// <summary>
/// 坦克配置
/// </summary>
public TankConfig TankConfig { get; private set; }
public TankProperties TankProperties { get; private set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="tankConfig">坦克配置</param>
/// <param name="properties">坦克配置</param>
/// <param name="simulationManager">仿真管理器</param>
public Tank(TankConfig tankConfig, ISimulationManager simulationManager)
: base(tankConfig.Id, tankConfig.InitialPosition, tankConfig.InitialOrientation, tankConfig.InitialSpeed, simulationManager)
public Tank(TankProperties properties, ISimulationManager simulationManager)
: base(properties.Id, properties.InitialPosition, properties.InitialOrientation, properties.InitialSpeed, simulationManager)
{
TankConfig = tankConfig;
Speed = TankConfig.InitialSpeed;
MaxSpeed = TankConfig.MaxSpeed;
MaxArmor = TankConfig.MaxArmor;
CurrentArmor = TankConfig.MaxArmor;
InfraredRadiationIntensity = TankConfig.InfraredRadiationIntensity;
RadarCrossSection = TankConfig.RadarCrossSection;
TankProperties = properties;
Speed = TankProperties.InitialSpeed;
CurrentArmor = TankProperties.MaxArmor;
IsActive = false;
}
@ -111,8 +82,8 @@ namespace ActiveProtect.Models
{
return $"坦克 {Id}:\n" +
$" 位置: {Position}\n" +
$" 速度: {Speed:F2}/{MaxSpeed:F2}\n" +
$" 装甲: {CurrentArmor:F2}/{MaxArmor:F2}\n" +
$" 速度: {Speed:F2}/{TankProperties.MaxSpeed:F2}\n" +
$" 装甲: {CurrentArmor:F2}/{TankProperties.MaxArmor:F2}\n" +
$" 状态: {(IsActive ? "" : "")}\n";
}
}

View File

@ -0,0 +1,102 @@
using ActiveProtect.Utility;
namespace ActiveProtect.Models
{
/// <summary>
/// 坦克配置类
/// </summary>
public class TankProperties
{
/// <summary>
/// 坦克ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 初始位置
/// </summary>
public Vector3D InitialPosition { get; set; }
/// <summary>
/// 初始朝向
/// </summary>
public Orientation InitialOrientation { get; set; }
/// <summary>
/// 初始速度(米/秒)
/// </summary>
public double InitialSpeed { get; set; }
/// <summary>
/// 最大速度(米/秒)
/// </summary>
public double MaxSpeed { get; set; }
/// <summary>
/// 最大装甲值
/// </summary>
public double MaxArmor { get; set; }
/// <summary>
/// 红外辐射强度(W/sr)
/// </summary>
public double InfraredRadiationIntensity { get; set; }
/// <summary>
/// 雷达截面积(m^2)
/// </summary>
public double RadarCrossSection { get; set; }
/// <summary>
/// 是否装备激光告警器
/// </summary>
public bool HasLaserWarner { get; set; }
/// <summary>
/// 是否装备激光干扰器
/// </summary>
public bool HasLaserJammer { get; set; }
/// <summary>
/// 是否装备毫米波干扰器
/// </summary>
public bool HasMillimeterWaveJammer { get; set; }
/// <summary>
/// 构造函数,设置默认值
/// </summary>
public TankProperties()
{
SetDefaultValues();
Id = "";
InitialPosition = new Vector3D(0, 0, 0);
InitialOrientation = new Orientation(0, 0, 0);
}
public TankProperties(TankInfo tankInfo){
SetDefaultValues();
Id = $"Tank_{tankInfo.TankID}";
InitialPosition = new Vector3D(tankInfo.xp, tankInfo.yp, tankInfo.zp);
InitialOrientation = new Orientation(0, 0, 0);
}
public void SetDefaultValues(){
InitialSpeed = 0;
MaxSpeed = 0;
MaxArmor = 0;
HasLaserWarner = false;
HasLaserJammer = false;
HasMillimeterWaveJammer = false;
InfraredRadiationIntensity = 0;
}
// 验证方法
public bool Validate()
{
// 实现验证逻辑
return true;
}
}
}

View File

@ -38,7 +38,7 @@ namespace ActiveProtect.Models
Vector3D targetVelocity = (tankPosition - lastTargetPosition) / deltaTime;
lastTargetPosition = tankPosition;
// 使用基类的比例控制算法
// 使用比例控制算法
GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation(ProportionalNavigationCoefficient, missilePosition, missileVelocity, tankPosition, targetVelocity);
// 限制最大加速度
if (GuidanceAcceleration.Magnitude() > MaxAcceleration)
@ -74,6 +74,7 @@ namespace ActiveProtect.Models
if (angle <= FIELD_OF_VIEW / 2)
{
double snr = CalculateSNR(tank, distance);
Console.WriteLine($"SNR: {snr}");
if (snr > RECOGNITION_SNR_THRESHOLD)
{
tankPosition = tank.Position;
@ -102,7 +103,7 @@ namespace ActiveProtect.Models
/// </summary>
private static double CalculateSNR(Tank tank, double distance)
{
double targetRadiation = tank.InfraredRadiationIntensity;
double targetRadiation = tank.TankProperties.InfraredRadiationIntensity;
double backgroundRadiation = BACKGROUND_RADIATION_INTENSITY;
// 考虑距离衰减

View File

@ -98,7 +98,7 @@ namespace ActiveProtect.Models
if (angle <= FIELD_OF_VIEW / 2)
{
// 模拟毫米波探测
double snr = CalculateSNR(distance, tank.RadarCrossSection);
double snr = CalculateSNR(distance, tank.TankProperties.RadarCrossSection);
Console.WriteLine($" 80信噪比 {snr}");
if(snr > RECOGNITION_SNR_THRESHOLD && random.NextDouble() < TARGET_RECOGNITION_PROBABILITY)

View File

@ -45,7 +45,7 @@ namespace ActiveProtect.Models
/// <summary>
/// 构造函数
/// </summary>
public InfraredCommandGuidedMissile(MissileConfig config, ISimulationManager manager) : base(config, manager)
public InfraredCommandGuidedMissile(MissileProperties config, ISimulationManager manager) : base(config, manager)
{
infraredTracker = null!;
RadiationPower = 1000;
@ -105,9 +105,10 @@ namespace ActiveProtect.Models
/// <param name="deltaTime">时间步长</param>
private void UpdateCruiseStage(double deltaTime)
{
HasGuidance = true;
guidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= ExplosionRadius)
if (DistanceToTarget <= MissileProperties.ExplosionRadius)
{
currentStage = ICGM_Stage.Explode;
}

View File

@ -29,10 +29,9 @@ namespace ActiveProtect.Models
/// <summary>
/// 红外成像末制导导弹构造函数
/// </summary>
public InfraredImagingTerminalGuidedMissile(MissileConfig config, ISimulationManager manager)
public InfraredImagingTerminalGuidedMissile(MissileProperties config, ISimulationManager manager)
: base(config, manager)
{
Type = MissileType.InfraredImagingTerminalGuidance;
currentStage = IRTG_Stage.Launch;
guidanceSystem = new InfraredImagingGuidanceSystem(config.MaxAcceleration, config.ProportionalNavigationCoefficient, manager);
}
@ -98,10 +97,11 @@ namespace ActiveProtect.Models
/// </summary>
private void UpdateTerminalGuidanceStage(double deltaTime)
{
HasGuidance = true;
guidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= ExplosionRadius)
if (DistanceToTarget <= MissileProperties.ExplosionRadius)
{
currentStage = IRTG_Stage.Explode;
}

View File

@ -30,7 +30,7 @@ namespace ActiveProtect.Models
/// </summary>
/// <param name="config">导弹配置</param>
/// <param name="manager">模拟管理器</param>
public LaserBeamRiderMissile(MissileConfig config, ISimulationManager manager)
public LaserBeamRiderMissile(MissileProperties config, ISimulationManager manager)
: base(config, manager)
{
LaserBeamRiderGuidanceSystem = new LaserBeamRiderGuidanceSystem(config.MaxAcceleration, config.ProportionalNavigationCoefficient);
@ -119,9 +119,10 @@ namespace ActiveProtect.Models
private void UpdateCruiseStage(double deltaTime)
{
// 巡航阶段
HasGuidance = true;
LaserBeamRiderGuidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = LaserBeamRiderGuidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= ExplosionRadius)
if (DistanceToTarget <= MissileProperties.ExplosionRadius)
{
currentStage = LBRM_Stage.Explode;
}

View File

@ -30,7 +30,7 @@ namespace ActiveProtect.Models
/// <param name="laserDesignatorId">激光指示器ID</param>
/// <param name="config">导弹配置</param>
/// <param name="simulationManager">仿真管理器</param>
public LaserSemiActiveGuidedMissile(MissileConfig config, ISimulationManager manager)
public LaserSemiActiveGuidedMissile(MissileProperties config, ISimulationManager manager)
: base(config, manager)
{
LaserGuidanceSystem = new LaserSemiActiveGuidanceSystem(config.MaxAcceleration, config.ProportionalNavigationCoefficient);
@ -139,9 +139,10 @@ namespace ActiveProtect.Models
/// <param name="deltaTime">时间步长</param>
private void UpdateCruiseStage(double deltaTime)
{
HasGuidance = true;
LaserGuidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = LaserGuidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= ExplosionRadius)
if (DistanceToTarget <= MissileProperties.ExplosionRadius)
{
currentStage = LSAGM_Stage.Explode;
}

View File

@ -28,12 +28,11 @@ namespace ActiveProtect.Models
/// <summary>
/// 毫米波末制导导弹构造函数
/// </summary>
public MillimeterWaveTerminalGuidedMissile(MissileConfig config, ISimulationManager manager)
: base(config, manager)
public MillimeterWaveTerminalGuidedMissile(MissileProperties properties, ISimulationManager manager)
: base(properties, manager)
{
Type = MissileType.MillimeterWaveTerminalGuidance;
currentStage = MWTG_Stage.Launch;
guidanceSystem = new MillimeterWaveGuidanceSystem(config.MaxAcceleration, config.ProportionalNavigationCoefficient, manager);
guidanceSystem = new MillimeterWaveGuidanceSystem(properties.MaxAcceleration, properties.ProportionalNavigationCoefficient, manager);
}
/// <summary>
@ -99,10 +98,11 @@ namespace ActiveProtect.Models
/// </summary>
private void UpdateTerminalGuidanceStage(double deltaTime)
{
HasGuidance = true;
guidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= ExplosionRadius)
if (DistanceToTarget <= MissileProperties.ExplosionRadius)
{
currentStage = MWTG_Stage.Explode;
Console.WriteLine($"导弹 {Id} 进入爆炸阶段");

View File

@ -5,41 +5,12 @@ using ActiveProtect.Utility;
namespace ActiveProtect.Models
{
/// <summary>
/// 表示仿真中的导弹
/// </summary>
public class MissileBase : SimulationElement
{
/// <summary>
/// 导弹类型
/// </summary>
public MissileType Type { get; protected set; }
/// <summary>
/// 当前速度(米/秒)
/// </summary>
public double Speed { get; protected set; }
/// <summary>
/// 最大速度(米/秒)
/// </summary>
public double MaxSpeed { get; protected set; }
/// <summary>
/// 目标ID
/// </summary>
public string TargetId { get; protected set; }
/// <summary>
/// 最大飞行时间(秒)
/// </summary>
public double MaxFlightTime { get; protected set; }
/// <summary>
/// 最大飞行距离(米)
/// </summary>
public double MaxFlightDistance { get; protected set; }
{
/// <summary>
/// 当前飞行时间(秒)
/// </summary>
@ -55,45 +26,10 @@ namespace ActiveProtect.Models
/// </summary>
public double DistanceToTarget { get; protected set; }
/// <summary>
/// 爆炸半径(米)
/// </summary>
public double ExplosionRadius { get; protected set; }
/// <summary>
/// 上一帧目标位置
/// </summary>
private Vector3D LastTargetPosition;
/// <summary>
/// 比例导引系数
/// </summary>
private const double N = 3;
/// <summary>
/// 推力加速度(米/秒²)
/// </summary>
public double LaunchAcceleration { get; protected set; }
/// <summary>
/// 当前发动机燃烧时间(秒)
/// </summary>
public double EngineBurnTime { get; protected set; }
/// <summary>
/// 最大发动机燃烧时间(秒)
/// </summary>
public double MaxEngineBurnTime { get; protected set; }
/// <summary>
/// 最大加速度(米/秒²)
/// </summary>
public double MaxAcceleration { get; protected set; }
/// <summary>
/// 比例导引系数
/// </summary>
public double ProportionalNavigationCoefficient { get; set; }
/// <summary>
/// 是否有制导
@ -110,11 +46,6 @@ namespace ActiveProtect.Models
/// </summary>
protected Vector3D LastKnownVelocity = Vector3D.Zero;
/// <summary>
/// 导弹质量(千克)
/// </summary>
public double Mass { get; protected set; }
/// <summary>
/// 制导加速度
/// </summary>
@ -125,17 +56,19 @@ namespace ActiveProtect.Models
/// </summary>
protected Vector3D ThrustAcceleration { get; set; }
protected readonly MissileConfig MissileConfig;
/// <summary>
/// 导弹固定配置参数
/// </summary>
public readonly MissileProperties MissileProperties;
/// <summary>
/// 构造函数
/// </summary>
public MissileBase(MissileConfig config, ISimulationManager manager)
: base(config.Id, config.InitialPosition, config.InitialOrientation, config.InitialSpeed, manager)
public MissileBase(MissileProperties properties, ISimulationManager manager)
: base(properties.Id, properties.InitialPosition, properties.InitialOrientation, properties.InitialSpeed, manager)
{
MissileConfig = config;
MissileProperties = properties;
SimulationManager = manager;
InitializeFromConfig();
IsActive = false;
HasGuidance = false;
@ -144,26 +77,7 @@ namespace ActiveProtect.Models
EngineBurnTime = 0;
GuidanceAcceleration = Vector3D.Zero;
ThrustAcceleration = Vector3D.Zero;
LastTargetPosition = Vector3D.Zero;
TargetId = $"Tank_{config.TargetIndex + 1}";
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
}
/// <summary>
/// 从配置初始化导弹
/// </summary>
private void InitializeFromConfig()
{
// 初始化导弹属性
Speed = MissileConfig.InitialSpeed;
MaxSpeed = MissileConfig.MaxSpeed;
MaxFlightTime = MissileConfig.MaxFlightTime;
MaxFlightDistance = MissileConfig.MaxFlightDistance;
ExplosionRadius = MissileConfig.ExplosionRadius;
LaunchAcceleration = MissileConfig.LaunchAcceleration;
MaxEngineBurnTime = MissileConfig.MaxEngineBurnTime;
MaxAcceleration = MissileConfig.MaxAcceleration;
ProportionalNavigationCoefficient = MissileConfig.ProportionalNavigationCoefficient;
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(properties.TargetId).Position);
}
/// <summary>
@ -192,7 +106,6 @@ namespace ActiveProtect.Models
}
else
{
Console.WriteLine($"无制导条件下,使用运动学方程更新导弹的位置和速度");
// 无制导条件下,使用运动学方程更新导弹的位置和速度
(Position, Velocity) = MotionAlgorithm.CalculateBallisticMotion(Position, Velocity, acceleration, deltaTime);
}
@ -200,16 +113,21 @@ namespace ActiveProtect.Models
// 限制速度不超过最大速度
if (Velocity.Magnitude() > MaxSpeed)
if (Velocity.Magnitude() > MissileProperties.MaxSpeed)
{
Velocity = Velocity.Normalize() * MaxSpeed;
Velocity = Velocity.Normalize() * MissileProperties.MaxSpeed;
}
Speed = Velocity.Magnitude();
Orientation = Orientation.FromVector(Velocity);
// 添加高斯噪声(测试用,用于测试运动中概率的影响)
// Position = MotionAlgorithm.AddRandomPerturbation(Position);
// Velocity = MotionAlgorithm.AddRandomPerturbation(Velocity);
FlightTime += deltaTime;
FlightDistance += Speed * deltaTime;
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(MissileProperties.TargetId).Position);
}
/// <summary>
@ -218,14 +136,14 @@ namespace ActiveProtect.Models
private Vector3D CalculateAcceleration(Vector3D velocity)
{
// 计算空气阻力的影响
Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / Mass;
Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / MissileProperties.Mass;
Vector3D totalAcceleration = GuidanceAcceleration + ThrustAcceleration + dragAcceleration;
Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {GuidanceAcceleration}, 推力加速度: {ThrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
if (totalAcceleration.Magnitude() > MaxAcceleration)
if (totalAcceleration.Magnitude() > MissileProperties.MaxAcceleration)
{
totalAcceleration = totalAcceleration.Normalize() * MaxAcceleration;
totalAcceleration = totalAcceleration.Normalize() * MissileProperties.MaxAcceleration;
}
return totalAcceleration;
@ -248,14 +166,14 @@ namespace ActiveProtect.Models
/// </summary>
protected bool ShouldSelfDestruct()
{
if (FlightTime >= MaxFlightTime)
if (FlightTime >= MissileProperties.MaxFlightTime)
{
Console.WriteLine($"导弹 {Id} 超出最大飞行时间 ({FlightTime:F2}/{MaxFlightTime:F2}),准备自毁");
Console.WriteLine($"导弹 {Id} 超出最大飞行时间 ({FlightTime:F2}/{MissileProperties.MaxFlightTime:F2}),准备自毁");
return true;
}
if (FlightDistance >= MaxFlightDistance)
if (FlightDistance >= MissileProperties.MaxFlightDistance)
{
Console.WriteLine($"导弹 {Id} 超出最大飞行距离 ({FlightDistance:F2}/{MaxFlightDistance:F2}),准备自毁");
Console.WriteLine($"导弹 {Id} 超出最大飞行距离 ({FlightDistance:F2}/{MissileProperties.MaxFlightDistance:F2}),准备自毁");
return true;
}
if (Position.Y <= -1.0) // 数字略小于0
@ -283,8 +201,7 @@ namespace ActiveProtect.Models
protected virtual void Explode()
{
Deactivate();
SimulationManager.HandleTargetHit(TargetId, Id);
Console.WriteLine($"导弹 {Id} 在 {Position} 爆炸,命中目标!");
SimulationManager.HandleTargetHit(MissileProperties.TargetId, Id);
}
/// <summary>
@ -294,8 +211,8 @@ namespace ActiveProtect.Models
{
if (IsActive)
{
string reason = FlightTime >= MaxFlightTime ? "超出最大飞行时间" :
FlightDistance >= MaxFlightDistance ? "超出最大飞行距离" :
string reason = FlightTime >= MissileProperties.MaxFlightTime ? "超出最大飞行时间" :
FlightDistance >= MissileProperties.MaxFlightDistance ? "超出最大飞行距离" :
Position.Y <= 0 ? "高度小于等于0" :
!HasGuidance ? "失去引导" : "未知原因";
@ -304,15 +221,6 @@ namespace ActiveProtect.Models
}
}
/// <summary>
/// 设置比例导引系数
/// </summary>
public void SetProportionalNavigationCoefficient(double newCoefficient)
{
ProportionalNavigationCoefficient = newCoefficient;
Console.WriteLine($"导弹 {Id} 的比例导引系数已更新为 {newCoefficient}");
}
/// <summary>
/// 获取导弹状态
/// </summary>
@ -324,10 +232,10 @@ namespace ActiveProtect.Models
$" 速度: {missileRunningState.Speed:F2} m/s\n" +
$" 速度分量: {missileRunningState.Velocity}\n" +
$" 朝向: {missileRunningState.Orientation}\n" +
$" 飞行时间: {missileRunningState.FlightTime:F2}/{MaxFlightTime:F2}\n" +
$" 飞行距离: {missileRunningState.FlightDistance:F2}/{MaxFlightDistance:F2}\n" +
$" 飞行时间: {missileRunningState.FlightTime:F2}/{MissileProperties.MaxFlightTime:F2}\n" +
$" 飞行距离: {missileRunningState.FlightDistance:F2}/{MissileProperties.MaxFlightDistance:F2}\n" +
$" 距离目标: {missileRunningState.DistanceToTarget:F2}\n" +
$" 发动机工作时间: {missileRunningState.EngineBurnTime:F2}/{MaxEngineBurnTime:F2}\n" +
$" 发动机工作时间: {missileRunningState.EngineBurnTime:F2}/{MissileProperties.MaxEngineBurnTime:F2}\n" +
$" 有引导: {(missileRunningState.HasGuidance ? "" : "")}\n" +
$" 失去引导时间: {missileRunningState.LostGuidanceTime:F2}\n";
}
@ -345,12 +253,11 @@ namespace ActiveProtect.Models
return new MissileRunningState
{
Id = Id,
Type = Type,
Type = MissileProperties.Type,
Position = Position,
Velocity = Velocity,
Orientation = Orientation,
Speed = Speed,
TargetId = TargetId,
FlightTime = FlightTime,
FlightDistance = FlightDistance,
DistanceToTarget = DistanceToTarget,
@ -397,11 +304,6 @@ namespace ActiveProtect.Models
/// </summary>
public double Speed { get; set; }
/// <summary>
/// 目标ID
/// </summary>
public string TargetId { get; set; }
/// <summary>
/// 当前飞行时间(秒)
/// </summary>

View File

@ -0,0 +1,147 @@
using System.Runtime;
using ActiveProtect.Utility;
namespace ActiveProtect.Models
{
/// <summary>
/// 导弹类型枚举
/// </summary>
public enum MissileType
{
StandardMissile, // 标准导弹
LaserSemiActiveGuidance, // 激光半主动制导
LaserBeamRiderGuidance, // 激光驾束制导
InfraredCommandGuidance, // 红外指令制导
InfraredImagingTerminalGuidance, // 红外成像末制导
MillimeterWaveTerminalGuidance, // 毫米波末制导
TerminalSensitiveMissile // 末敏弹
}
/// <summary>
/// 导弹配置类
/// </summary>
public class MissileProperties
{
/// <summary>
/// 导弹ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 目标ID
/// </summary>
public string TargetId { get; set; }
/// <summary>
/// 初始位置
/// </summary>
public Vector3D InitialPosition { get; set; }
/// <summary>
/// 初始朝向
/// </summary>
public Orientation InitialOrientation { get; set; }
/// <summary>
/// 初始速度(米/秒)
/// </summary>
public double InitialSpeed { get; set; }
/// <summary>
/// 最大速度(米/秒)
/// </summary>
public double MaxSpeed { get; set; }
/// <summary>
/// 最大飞行时间(秒)
/// </summary>
public double MaxFlightTime { get; set; }
/// <summary>
/// 最大飞行距离(米)
/// </summary>
public double MaxFlightDistance { get; set; }
/// <summary>
/// 最大加速度(米/秒²)
/// </summary>
public double MaxAcceleration { get; set; }
/// <summary>
/// 比例导引系数
/// </summary>
public double ProportionalNavigationCoefficient { get; set; }
/// <summary>
/// 发射推力加速度(米/秒²)
/// </summary>
public double LaunchAcceleration { get; set; }
/// <summary>
/// 最大发动机燃烧时间(秒)
/// </summary>
public double MaxEngineBurnTime { get; set; }
/// <summary>
/// 导弹质量(千克)
/// </summary>
public double Mass { get; set; }
/// <summary>
/// 爆炸半径(米)
/// </summary>
public double ExplosionRadius { get; set; }
/// <summary>
/// 命中概率
/// </summary>
public double HitProbability { get; set; }
/// <summary>
/// 导弹类型
/// </summary>
public MissileType Type { get; set; }
/// <summary>
/// 构造函数,设置默认值
/// </summary>
public MissileProperties()
{
SetDefaultValues();
Id = "";
TargetId = "";
InitialPosition = new Vector3D(0, 0, 0);
InitialOrientation = new Orientation(0, 0, 0);
Type = MissileType.LaserSemiActiveGuidance;
}
/// <summary>
/// 构造函数,根据导弹初始信息初始化导弹配置
/// </summary>
/// <param name="mIniInfo">导弹初始信息</param>
public MissileProperties(MIniInfo mIniInfo){
SetDefaultValues();
Id = $"Missile_{mIniInfo.nMisID}";
TargetId = "";
InitialPosition = new Vector3D(mIniInfo.xm, mIniInfo.ym, mIniInfo.zm);
InitialOrientation = new Orientation(mIniInfo.psi_m, mIniInfo.theta_m, 0);
InitialSpeed = mIniInfo.vm;
}
/// <summary>
/// 设置默认值
/// </summary>
public void SetDefaultValues(){
InitialSpeed = 0;
MaxSpeed = 0;
MaxFlightTime = 0;
MaxFlightDistance = 0;
LaunchAcceleration = 0;
MaxEngineBurnTime = 0;
MaxAcceleration = 0;
ExplosionRadius = 0;
ProportionalNavigationCoefficient = 0;
}
}
}

View File

@ -11,10 +11,8 @@ namespace ActiveProtect.Models
private const double SeparationHeight = 1000;
// 分离点距离目标水平距离,默认 1000 米
private const double SeparationDistance = 1000;
// 分离时距离分离点的距离阈值,默认 50米
private const double SeparationRange = 0.5;
// 分离时距目标距离阈值,默认 1200 米
private const double SeparationTargetDistance = 1200;
// 分离时距离分离点的距离阈值,默认 5米必须 > 导弹速度 * 时间步长 / 2
private const double SeparationRange = 5;
// 子弹数量, 155 口径母弹,默认 2 个
private const int SubmunitionCount = 1;
// 子弹数组
@ -22,13 +20,14 @@ namespace ActiveProtect.Models
// 分离点位置
private readonly Vector3D separationPoint;
public TerminalSensitiveMissile(MissileConfig config, ISimulationManager manager)
: base(config, manager)
public TerminalSensitiveMissile(MissileProperties properties, ISimulationManager manager)
: base(properties, manager)
{
submunitions = new TerminalSensitiveSubmunition[SubmunitionCount];
//计算分离点坐标高度为SeparationHeight距离目标的距离为SeparationDistance
separationPoint = Vector3D.PointOnLine(base.SimulationManager.GetEntityById(TargetId).Position, base.Position, SeparationDistance) + new Vector3D(0, SeparationHeight, 0);
separationPoint = Vector3D.PointOnLine(base.SimulationManager.GetEntityById(properties.TargetId).Position, base.Position, SeparationDistance) + new Vector3D(0, SeparationHeight, 0);
Console.WriteLine($"Position: {Position}, 分离点: {separationPoint}, speed: {Speed}, Speed: {properties.InitialSpeed}");
//计算导弹发射角度
(Orientation? launchOrientation, Vector3D? launchVelocity) = MotionAlgorithm.CalculateBestLaunchOrientation(Position, separationPoint, Speed);
@ -58,11 +57,8 @@ namespace ActiveProtect.Models
Console.WriteLine($"分离点距离: {(separationPoint - Position).Magnitude()}");
//计算到目标的距离
double distanceToTarget = (SimulationManager.GetEntityById(TargetId).Position - Position).Magnitude();
//距离分离点距离小于50米或者距离目标小于1400米则分离
if ((separationPoint - Position).Magnitude() <= SeparationRange || distanceToTarget <= SeparationTargetDistance)
//距离分离点距离小于50米则分离
if ((separationPoint - Position).Magnitude() <= SeparationRange)
{
Console.WriteLine("分离");
PerformSeparation();
@ -75,30 +71,30 @@ namespace ActiveProtect.Models
private void PerformSeparation()
{
// 获取目标位置
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
Vector3D targetPosition = SimulationManager.GetEntityById(MissileProperties.TargetId).Position;
// 计算子弹朝向目标的方向
Vector3D directionToTarget = (targetPosition - this.Position).Normalize();
Orientation orientationToTarget = Orientation.FromVector(directionToTarget);
// 创建并释子弹
for (int i = 0; i < SubmunitionCount; i++)
{
// 计算子弹朝向目标的方向
Vector3D directionToTarget = (targetPosition - this.Position).Normalize();
Orientation orientationToTarget = Orientation.FromVector(directionToTarget);
submunitions[i] = new TerminalSensitiveSubmunition(
new MissileConfig
new MissileProperties
{
Id = $"{Id}_Sub_{i}",
InitialPosition = this.Position,
InitialOrientation = orientationToTarget, // 设置为朝向目标的方向
TargetId = MissileProperties.TargetId,
InitialPosition = Position,
InitialOrientation = orientationToTarget,
InitialSpeed = 200, // 子弹初始速度
MaxSpeed = 2000,
TargetIndex = 0,
MaxFlightTime = 50,
MaxFlightDistance = 1000,
MaxAcceleration = 50,
ProportionalNavigationCoefficient = 3,
Mass = 10,
ExplosionRadius = this.ExplosionRadius
ExplosionRadius = MissileProperties.ExplosionRadius,
HitProbability = MissileProperties.HitProbability
},
SimulationManager);

View File

@ -62,10 +62,10 @@ namespace ActiveProtect.Models
/// <summary>
/// 构造函数
/// </summary>
/// <param name="config">导弹配置</param>
/// <param name="properites">导弹配置</param>
/// <param name="manager">模拟管理器</param>
public TerminalSensitiveSubmunition(MissileConfig config, ISimulationManager manager)
: base(config, manager)
public TerminalSensitiveSubmunition(MissileProperties properties, ISimulationManager manager)
: base(properties, manager)
{
currentStage = SubmunitionStage.Separation;
spiralAngle = 0;
@ -226,11 +226,10 @@ namespace ActiveProtect.Models
{
Console.WriteLine("攻击阶段");
// 攻击逻辑
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
Vector3D targetPosition = SimulationManager.GetEntityById(MissileProperties.TargetId).Position;
Vector3D direction = (targetPosition - Position).Normalize();
Velocity = direction * AttackSpeed;
Console.WriteLine($"导弹ID: {Id}, 距离目标: {DistanceToTarget}, 爆炸半径: {ExplosionRadius}");
if (DistanceToTarget <= ExplosionRadius)
if ((targetPosition - Position).Magnitude() <= MissileProperties.ExplosionRadius)
{
currentStage = SubmunitionStage.Explode;
}
@ -259,7 +258,7 @@ namespace ActiveProtect.Models
/// <returns>是否检测到目标</returns>
private bool DetectTarget(Vector3D scanDirection)
{
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
Vector3D targetPosition = SimulationManager.GetEntityById(MissileProperties.TargetId).Position;
Vector3D toTarget = (targetPosition - Position).Normalize();
// 检查目标是否在扫描线上

View File

@ -7,27 +7,30 @@ namespace ActiveProtect.Models
public class MillimeterWaveRadiometer : Sensor
{
/// <summary>
/// 工作频率3mm 或 8mm
/// 工作波段3mm 或 8mm
/// </summary>
public double Frequency { get; set; }
public double Wavelength { get; set; }
/// <summary>
/// 辐射温度差检测阈值辐射计高温物体与低温物体的检测温差单位K默认 50K
/// </summary>
public double DetectionTemperatureDifferenceThreshold { get; set; } = 50;
private double lastDetectionTemperature = 0;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="position">辐射计的位置</param>
/// <param name="orientation">辐射计的朝向</param>
/// <param name="frequency">工作频率</param>
/// <param name="wavelength">工作波段</param>
/// <param name="detectionTemperatureDifferenceThreshold">辐射温差检测阈值</param>
public MillimeterWaveRadiometer(Vector3D position, Orientation orientation, double frequency, double detectionTemperatureDifferenceThreshold)
public MillimeterWaveRadiometer(Vector3D position, Orientation orientation, double wavelength, double detectionTemperatureDifferenceThreshold)
: base(position, orientation)
{
Frequency = frequency;
Wavelength = wavelength;
DetectionTemperatureDifferenceThreshold = detectionTemperatureDifferenceThreshold;
lastDetectionTemperature = 0;
}
/// <summary>

View File

@ -13,12 +13,12 @@ namespace ActiveProtect.Simulation
/// <summary>
/// 坦克配置列表
/// </summary>
public List<TankConfig> TankConfigs { get; set; }
public List<TankProperties> TankConfigs { get; set; }
/// <summary>
/// 导弹配置列表
/// </summary>
public List<MissileConfig> MissileConfigs { get; set; }
public List<MissileProperties> MissileConfigs { get; set; }
/// <summary>
/// 激光指示器配置列表
@ -60,8 +60,8 @@ namespace ActiveProtect.Simulation
/// </summary>
public SimulationConfig()
{
TankConfigs = new List<TankConfig>();
MissileConfigs = new List<MissileConfig>();
TankConfigs = new List<TankProperties>();
MissileConfigs = new List<MissileProperties>();
LaserDesignatorConfig = new LaserDesignatorConfig();
LaserBeamRiderConfig = new LaserBeamRiderConfig();
LaserWarnerConfig = new LaserWarnerConfig();
@ -72,250 +72,6 @@ namespace ActiveProtect.Simulation
}
}
/// <summary>
/// 坦克配置类
/// </summary>
public class TankConfig
{
/// <summary>
/// 坦克ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 初始位置
/// </summary>
public Vector3D InitialPosition { get; set; }
/// <summary>
/// 初始朝向
/// </summary>
public Orientation InitialOrientation { get; set; }
/// <summary>
/// 初始速度(米/秒)
/// </summary>
public double InitialSpeed { get; set; }
/// <summary>
/// 最大速度(米/秒)
/// </summary>
public double MaxSpeed { get; set; }
/// <summary>
/// 最大装甲值
/// </summary>
public double MaxArmor { get; set; }
/// <summary>
/// 红外辐射强度(W/sr)
/// </summary>
public double InfraredRadiationIntensity { get; set; }
/// <summary>
/// 雷达截面积(m^2)
/// </summary>
public double RadarCrossSection { get; set; }
/// <summary>
/// 是否装备激光告警器
/// </summary>
public bool HasLaserWarner { get; set; }
/// <summary>
/// 是否装备激光干扰器
/// </summary>
public bool HasLaserJammer { get; set; }
/// <summary>
/// 是否装备毫米波干扰器
/// </summary>
public bool HasMillimeterWaveJammer { get; set; }
/// <summary>
/// 构造函数,设置默认值
/// </summary>
public TankConfig()
{
SetDefaultValues();
Id = "";
InitialPosition = new Vector3D(0, 0, 0);
InitialOrientation = new Orientation(0, 0, 0);
}
public TankConfig(TankInfo tankInfo){
SetDefaultValues();
Id = $"Tank_{tankInfo.TankID}";
InitialPosition = new Vector3D(tankInfo.xp, tankInfo.yp, tankInfo.zp);
InitialOrientation = new Orientation(0, 0, 0);
}
public void SetDefaultValues(){
InitialSpeed = 0;
MaxSpeed = 0;
MaxArmor = 0;
HasLaserWarner = false;
HasLaserJammer = false;
HasMillimeterWaveJammer = false;
InfraredRadiationIntensity = 0;
}
// 验证方法
public bool Validate()
{
// 实现验证逻辑
return true;
}
}
/// <summary>
/// 导弹配置类
/// </summary>
public class MissileConfig
{
/// <summary>
/// 导弹ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 初始位置
/// </summary>
public Vector3D InitialPosition { get; set; }
/// <summary>
/// 初始朝向
/// </summary>
public Orientation InitialOrientation { get; set; }
/// <summary>
/// 初始速度(米/秒)
/// </summary>
public double InitialSpeed { get; set; }
/// <summary>
/// 最大速度(米/秒)
/// </summary>
public double MaxSpeed { get; set; }
/// <summary>
/// 目标索引
/// </summary>
public int TargetIndex { get; set; }
/// <summary>
/// 最大飞行时间(秒)
/// </summary>
public double MaxFlightTime { get; set; }
/// <summary>
/// 最大飞行距离(米)
/// </summary>
public double MaxFlightDistance { get; set; }
/// <summary>
/// 最大加速度(米/秒²)
/// </summary>
public double MaxAcceleration { get; set; }
/// <summary>
/// 比例导引系数
/// </summary>
public double ProportionalNavigationCoefficient { get; set; }
/// <summary>
/// 发射推力加速度(米/秒²)
/// </summary>
public double LaunchAcceleration { get; set; }
/// <summary>
/// 最大发动机燃烧时间(秒)
/// </summary>
public double MaxEngineBurnTime { get; set; }
/// <summary>
/// 导弹质量(千克)
/// </summary>
public double Mass { get; set; }
/// <summary>
/// 爆炸半径(米)
/// </summary>
public double ExplosionRadius { get; set; }
/// <summary>
/// 导弹类型
/// </summary>
public MissileType Type { get; set; }
/// <summary>
/// 比例增益
/// </summary>
public double Kp { get; set; }
/// <summary>
/// 积分增益
/// </summary>
public double Ki { get; set; }
/// <summary>
/// 微分增益
/// </summary>
public double Kd { get; set; }
/// <summary>
/// 自适应速率
/// </summary>
public double AdaptiveRate { get; set; }
/// <summary>
/// 期望性能指标
/// </summary>
public double DesiredPerformance { get; set; }
/// <summary>
/// 构造函数,设置默认值
/// </summary>
public MissileConfig()
{
SetDefaultValues();
Id = "";
InitialPosition = new Vector3D(0, 0, 0);
InitialOrientation = new Orientation(0, 0, 0);
}
/// <summary>
/// 构造函数,根据导弹初始信息初始化导弹配置
/// </summary>
/// <param name="mIniInfo">导弹初始信息</param>
public MissileConfig(MIniInfo mIniInfo){
SetDefaultValues();
Id = $"Missile_{mIniInfo.nMisID}";
InitialPosition = new Vector3D(mIniInfo.xm, mIniInfo.ym, mIniInfo.zm);
InitialOrientation = new Orientation(mIniInfo.psi_m, mIniInfo.theta_m, 0);
InitialSpeed = mIniInfo.vm;
}
/// <summary>
/// 设置默认值
/// </summary>
public void SetDefaultValues(){
InitialSpeed = 0;
MaxSpeed = 0;
TargetIndex = 0;
MaxFlightTime = 0;
MaxFlightDistance = 0;
LaunchAcceleration = 0;
MaxEngineBurnTime = 0;
MaxAcceleration = 0;
ExplosionRadius = 0;
ProportionalNavigationCoefficient = 0;
Type = MissileType.StandardMissile;
}
}
/// <summary>
/// 激光指示器配置类
/// </summary>
@ -396,19 +152,7 @@ namespace ActiveProtect.Simulation
}
}
/// <summary>
/// 导弹类型枚举
/// </summary>
public enum MissileType
{
StandardMissile, // 标准导弹
LaserSemiActiveGuidance, // 激光半主动制导
LaserBeamRiderGuidance, // 激光驾束制导
InfraredCommandGuidance, // 红外指令制导
InfraredImagingTerminalGuidance, // 红外成像末制导
MillimeterWaveTerminalGuidance, // 毫米波末制导
TerminalSensitiveMissile // 末敏弹
}
/// <summary>

View File

@ -1,4 +1,5 @@
using System;
using System.Reflection.Metadata.Ecma335;
using ActiveProtect.Utility;
namespace ActiveProtect.Simulation
@ -21,6 +22,11 @@ namespace ActiveProtect.Simulation
/// <summary>
/// 仿真元素的当前速度
/// </summary>
public virtual double Speed { get; set; }
/// <summary>
/// 仿真元素的当前速度向量
/// </summary>
public virtual Vector3D Velocity { get; set; }
/// <summary>
@ -50,6 +56,7 @@ namespace ActiveProtect.Simulation
Id = id;
Position = position;
Orientation = orientation;
Speed = speed;
Velocity = orientation.ToVector() * speed;
this.SimulationManager = simulationManager;
IsActive = false;

View File

@ -148,36 +148,34 @@ namespace ActiveProtect.Simulation
}
}
// 创建导弹
for (int i = 0; i < config.MissileConfigs.Count; i++)
{
var missileConfig = config.MissileConfigs[i];
var missileProperties = config.MissileConfigs[i];
MissileBase missile;
switch (missileConfig.Type)
switch (missileProperties.Type)
{
case MissileType.LaserSemiActiveGuidance:
missile = new LaserSemiActiveGuidedMissile(missileConfig, this);
missile = new LaserSemiActiveGuidedMissile(missileProperties, this);
break;
case MissileType.LaserBeamRiderGuidance:
missile = new LaserBeamRiderMissile(missileConfig, this);
missile = new LaserBeamRiderMissile(missileProperties, this);
break;
case MissileType.TerminalSensitiveMissile:
missile = new TerminalSensitiveMissile(missileConfig, this);
missile = new TerminalSensitiveMissile(missileProperties, this);
break;
case MissileType.InfraredCommandGuidance:
missile = new InfraredCommandGuidedMissile(missileConfig, this);
missile = new InfraredCommandGuidedMissile(missileProperties, this);
break;
case MissileType.InfraredImagingTerminalGuidance:
missile = new InfraredImagingTerminalGuidedMissile(missileConfig, this);
missile = new InfraredImagingTerminalGuidedMissile(missileProperties, this);
break;
case MissileType.MillimeterWaveTerminalGuidance:
missile = new MillimeterWaveTerminalGuidedMissile(missileConfig, this);
missile = new MillimeterWaveTerminalGuidedMissile(missileProperties, this);
break;
default:
missile = new MissileBase(missileConfig, this);
missile = new MissileBase(missileProperties, this);
break;
}
@ -223,10 +221,10 @@ namespace ActiveProtect.Simulation
Elements.Add(infraredTracker);
// 激活所有元素
//ActivateAllElements();
ActivateAllElements();
// 激活部分元素
ActivateSomeElements();
//ActivateSomeElements();
}
//激活所有元素
@ -431,6 +429,15 @@ namespace ActiveProtect.Simulation
{
if (GetEntityById(targetId) is Tank tank && GetEntityById(missileId) is MissileBase missile)
{
// 生成随机数决定是否命中
Random random = new();
//bool isHit = random.NextDouble() <= missile.MissileProperties.HitProbability;
bool isHit = true;
if (!isHit)
{
Console.WriteLine($"导弹 {missileId} 未命中目标 {targetId}");
return;
}
// 计算导弹造成的伤害
double damage = CalculateMissileDamage(missile);

View File

@ -169,5 +169,41 @@ namespace ActiveProtect.Utility
return acceleration;
}
/// <summary>
/// 添加高斯噪声
/// </summary>
/// <param name="vector">向量</param>
/// <returns>添加高斯噪声后的向量</returns>
public static Vector3D AddRandomPerturbation(Vector3D vector)
{
Random random = new();
// 添加高斯噪声
double sigma = 0.1; // 扰动标准差
// 使用Box-Muller变换来生成高斯随机数
double u1 = random.NextDouble(); // 生成[0, 1)之间的随机数
double u2 = random.NextDouble(); // 生成[0, 1)之间的随机数
double r = Math.Sqrt(-2.0 * Math.Log(u1));
double theta = 2.0 * Math.PI * u2;
double gaussianX = r * Math.Cos(theta);
double gaussianY = r * Math.Sin(theta);
// 由于我们需要三个高斯随机数,我们将再次生成
u1 = random.NextDouble(); // 生成[0, 1)之间的随机数
u2 = random.NextDouble(); // 生成[0, 1)之间的随机数
r = Math.Sqrt(-2.0 * Math.Log(u1));
theta = 2.0 * Math.PI * u2;
double gaussianZ = r * Math.Cos(theta);
// 将高斯随机数转换为指定标准差的高斯随机数
gaussianX *= sigma;
gaussianY *= sigma;
gaussianZ *= sigma;
return new Vector3D(
vector.X + gaussianX,
vector.Y + gaussianY,
vector.Z + gaussianZ
);
}
}
}