修改了项目结构;增加了无制导状态下的运动算法;增加了末敏弹发射角度的自动计算。
This commit is contained in:
parent
a5c0bfc3d9
commit
2f1ecf86cf
BIN
Models/.DS_Store
vendored
BIN
Models/.DS_Store
vendored
Binary file not shown.
@ -1,168 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 制导系统接口
|
||||
/// </summary>
|
||||
public interface IGuidanceSystem
|
||||
{
|
||||
bool HasGuidance { get; }
|
||||
void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity);
|
||||
Vector3D GetGuidanceAcceleration();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 基础制导系统
|
||||
/// </summary>
|
||||
public class BasicGuidanceSystem : IGuidanceSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否有制导
|
||||
/// </summary>
|
||||
public bool HasGuidance { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大加速度
|
||||
/// </summary>
|
||||
public double MaxAcceleration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 制导系数
|
||||
/// </summary>
|
||||
public double ProportionalNavigationCoefficient { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹位置
|
||||
/// </summary>
|
||||
protected Vector3D Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹速度
|
||||
/// </summary>
|
||||
protected Vector3D Velocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 制导加速度
|
||||
/// </summary>
|
||||
protected Vector3D GuidanceAcceleration { get; set; }
|
||||
|
||||
public BasicGuidanceSystem(double maxAcceleration, double proportionalNavigationCoefficient)
|
||||
{
|
||||
HasGuidance = false;
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
Position = Vector3D.Zero;
|
||||
Velocity = Vector3D.Zero;
|
||||
MaxAcceleration = maxAcceleration;
|
||||
ProportionalNavigationCoefficient = proportionalNavigationCoefficient;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新制导系统
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
/// <param name="missilePosition">导弹位置</param>
|
||||
/// <param name="missileVelocity">导弹速度</param>
|
||||
public virtual void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
|
||||
{
|
||||
Position = missilePosition;
|
||||
Velocity = missileVelocity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取制导加速度
|
||||
/// </summary>
|
||||
/// <returns>制导加速度</returns>
|
||||
public Vector3D GetGuidanceAcceleration()
|
||||
{
|
||||
return GuidanceAcceleration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算制导加速度
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
protected virtual void CalculateGuidanceAcceleration(double deltaTime)
|
||||
{
|
||||
// 基础制导系统不计算制导指令
|
||||
// 派生类应该重写这个方法来实现特定的制导逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算比例导引加速度
|
||||
/// </summary>
|
||||
/// <param name="proportionalNavigationCoefficient">比例导引系数</param>
|
||||
/// <param name="missilePosition">导弹位置</param>
|
||||
/// <param name="missileVelocity">导弹速度</param>
|
||||
/// <param name="targetPosition">目标位置</param>
|
||||
/// <param name="targetVelocity">目标速度</param>
|
||||
/// <returns>比例导引加速度</returns>
|
||||
protected static Vector3D CalculateProportionalNavigation(double proportionalNavigationCoefficient, Vector3D missilePosition, Vector3D missileVelocity, Vector3D targetPosition, Vector3D targetVelocity)
|
||||
{
|
||||
// 预测时间(预测目标前进方向该时间后到达的位置,可以调整)
|
||||
double predictionTime = 0.01;
|
||||
|
||||
// 预测目标位置
|
||||
Vector3D predictedTargetPosition = targetPosition + targetVelocity * predictionTime;
|
||||
|
||||
Vector3D r = predictedTargetPosition - missilePosition;
|
||||
Vector3D v = targetVelocity - missileVelocity;
|
||||
|
||||
Vector3D LOS = r.Normalize();
|
||||
Vector3D LOSRate = (v - (LOS * Vector3D.DotProduct(v, LOS))) / r.Magnitude();
|
||||
|
||||
Vector3D acceleration = Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), missileVelocity.Normalize()) * proportionalNavigationCoefficient * missileVelocity.Magnitude();
|
||||
|
||||
return acceleration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 四阶龙格库塔法计算导弹运动状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
/// <param name="position">导弹位置</param>
|
||||
/// <param name="velocity">导弹速度</param>
|
||||
/// <param name="acceleration">导弹加速度</param>
|
||||
/// <returns>新的位置和速度</returns>
|
||||
public static (Vector3D newPosition, Vector3D newVelocity) RungeKutta4(double deltaTime, Vector3D position, Vector3D velocity, Vector3D acceleration)
|
||||
{
|
||||
// 定义一个局部函数来计算加速度
|
||||
Vector3D AccelerationFunction(Vector3D pos, Vector3D vel)
|
||||
{
|
||||
// 这里可以添加更复杂的加速度计算,比如考虑空气阻力等
|
||||
return acceleration;
|
||||
}
|
||||
|
||||
// 第一步
|
||||
Vector3D k1v = AccelerationFunction(position, velocity) * deltaTime;
|
||||
Vector3D k1r = velocity * deltaTime;
|
||||
|
||||
// 第二步
|
||||
Vector3D k2v = AccelerationFunction(position + k1r * 0.5, velocity + k1v * 0.5) * deltaTime;
|
||||
Vector3D k2r = (velocity + k1v * 0.5) * deltaTime;
|
||||
|
||||
// 第三步
|
||||
Vector3D k3v = AccelerationFunction(position + k2r * 0.5, velocity + k2v * 0.5) * deltaTime;
|
||||
Vector3D k3r = (velocity + k2v * 0.5) * deltaTime;
|
||||
|
||||
// 第四步
|
||||
Vector3D k4v = AccelerationFunction(position + k3r, velocity + k3v) * deltaTime;
|
||||
Vector3D k4r = (velocity + k3v) * deltaTime;
|
||||
|
||||
// 计算新的位置和速度
|
||||
Vector3D newPosition = position + (k1r + k2r * 2 + k3r * 2 + k4r) / 6;
|
||||
Vector3D newVelocity = velocity + (k1v + k2v * 2 + k3v * 2 + k4v) / 6;
|
||||
|
||||
return (newPosition, newVelocity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取制导系统状态
|
||||
/// </summary>
|
||||
/// <returns>制导系统状态</returns>
|
||||
public virtual string GetStatus()
|
||||
{
|
||||
return $" 导引头状态: 有制导={HasGuidance}, 位置={Position}, 速度={Velocity}, 制导加速度={GuidanceAcceleration}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,366 +0,0 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义传感器的基本接口
|
||||
/// </summary>
|
||||
public interface ISensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置传感器是否处于激活状态
|
||||
/// </summary>
|
||||
bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激活传感器
|
||||
/// </summary>
|
||||
void Activate();
|
||||
|
||||
/// <summary>
|
||||
/// 停用传感器
|
||||
/// </summary>
|
||||
void Deactivate();
|
||||
|
||||
/// <summary>
|
||||
/// 更新传感器状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
void Update(double deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// 获取传感器数据
|
||||
/// </summary>
|
||||
/// <returns>传感器采集的数据</returns>
|
||||
SensorData GetSensorData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 传感器的抽象基类,实现了ISensor接口的基本功能
|
||||
/// </summary>
|
||||
public abstract class Sensor : ISensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置传感器是否处于激活状态
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 传感器的位置
|
||||
/// </summary>
|
||||
protected Vector3D Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 传感器的朝向
|
||||
/// </summary>
|
||||
protected Orientation Orientation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">传感器的初始位置</param>
|
||||
/// <param name="orientation">传感器的初始朝向</param>
|
||||
protected Sensor(Vector3D position, Orientation orientation)
|
||||
{
|
||||
Position = position;
|
||||
Orientation = orientation;
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活传感器
|
||||
/// </summary>
|
||||
public virtual void Activate()
|
||||
{
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停用传感器
|
||||
/// </summary>
|
||||
public virtual void Deactivate()
|
||||
{
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新传感器状态(需要在子类中实现)
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public abstract void Update(double deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// 获取传感器数据(需要在子类中实现)
|
||||
/// </summary>
|
||||
/// <returns>传感器采集的数据</returns>
|
||||
public abstract SensorData GetSensorData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 红外探测器类
|
||||
/// </summary>
|
||||
public class InfraredDetector : Sensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 探测范围
|
||||
/// </summary>
|
||||
public double DetectionRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 视场角
|
||||
/// </summary>
|
||||
public double FieldOfView { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">探测器的位置</param>
|
||||
/// <param name="orientation">探测器的朝向</param>
|
||||
/// <param name="detectionRange">探测范围</param>
|
||||
/// <param name="fieldOfView">视场角</param>
|
||||
public InfraredDetector(Vector3D position, Orientation orientation, double detectionRange, double fieldOfView)
|
||||
: base(position, orientation)
|
||||
{
|
||||
DetectionRange = detectionRange;
|
||||
FieldOfView = fieldOfView;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新红外探测器的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 实现红外探测器的更新逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取红外探测器的数据
|
||||
/// </summary>
|
||||
/// <returns>红外探测器采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回红外探测器的数据
|
||||
return new InfraredSensorData();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 毫米波辐射计类
|
||||
/// </summary>
|
||||
public class MillimeterWaveRadiometer : Sensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 工作频率(3mm 或 8mm)
|
||||
/// </summary>
|
||||
public double Frequency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 辐射温度差检测阈值,辐射计高温物体与低温物体的检测温差,单位K,默认 50K
|
||||
/// </summary>
|
||||
public double DetectionTemperatureDifferenceThreshold { get; set; } = 50;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">辐射计的位置</param>
|
||||
/// <param name="orientation">辐射计的朝向</param>
|
||||
/// <param name="frequency">工作频率</param>
|
||||
/// <param name="detectionTemperatureDifferenceThreshold">辐射温差检测阈值</param>
|
||||
public MillimeterWaveRadiometer(Vector3D position, Orientation orientation, double frequency, double detectionTemperatureDifferenceThreshold)
|
||||
: base(position, orientation)
|
||||
{
|
||||
Frequency = frequency;
|
||||
DetectionTemperatureDifferenceThreshold = detectionTemperatureDifferenceThreshold;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新毫米波辐射计的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 实现毫米波辐射计的更新逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取毫米波辐射计的数据
|
||||
/// </summary>
|
||||
/// <returns>毫米波辐射计采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回毫米波辐射计的数据
|
||||
return new RadiometerSensorData();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 毫米波测高雷达类
|
||||
/// </summary>
|
||||
public class MillimeterWaveAltimeter : Sensor
|
||||
{
|
||||
private double currentAltitude;
|
||||
|
||||
private readonly TerminalSensitiveSubmunition submunition;
|
||||
|
||||
/// <summary>
|
||||
/// 最大测量高度
|
||||
/// </summary>
|
||||
public double MaxAltitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 测量精度
|
||||
/// </summary>
|
||||
public double Accuracy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">测高雷达的位置</param>
|
||||
/// <param name="orientation">测高雷达的朝向</param>
|
||||
/// <param name="maxAltitude">最大测量高度</param>
|
||||
/// <param name="accuracy">测量精度</param>
|
||||
public MillimeterWaveAltimeter(TerminalSensitiveSubmunition submunition, double maxAltitude, double accuracy)
|
||||
: base(submunition.Position, submunition.Orientation)
|
||||
{
|
||||
MaxAltitude = maxAltitude;
|
||||
Accuracy = accuracy;
|
||||
currentAltitude = 0;
|
||||
this.submunition = submunition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新毫米波测高雷达的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 更新当前高度,考虑测量精度
|
||||
currentAltitude = submunition.Position.Y + Accuracy * new Random().NextDouble();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取毫米波测高雷达的数据
|
||||
/// </summary>
|
||||
/// <returns>毫米波测高雷达采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回毫米波测高雷达的数据
|
||||
AltimeterSensorData altimeterSensorData = new AltimeterSensorData
|
||||
{
|
||||
Altitude = currentAltitude
|
||||
};
|
||||
return altimeterSensorData;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光测距仪类
|
||||
/// </summary>
|
||||
public class LaserRangefinder : Sensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 最大测量距离
|
||||
/// </summary>
|
||||
public double MaxRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 脉冲频率
|
||||
/// </summary>
|
||||
public double PulseRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">测距仪的位置</param>
|
||||
/// <param name="orientation">测距仪的朝向</param>
|
||||
/// <param name="maxRange">最大测量距离</param>
|
||||
/// <param name="pulseRate">脉冲频率</param>
|
||||
public LaserRangefinder(Vector3D position, Orientation orientation, double maxRange, double pulseRate)
|
||||
: base(position, orientation)
|
||||
{
|
||||
MaxRange = maxRange;
|
||||
PulseRate = pulseRate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新激光测距仪的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 实现激光测距仪的更新逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取激光测距仪的数据
|
||||
/// </summary>
|
||||
/// <returns>激光测距仪采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回激光测距仪的数据
|
||||
return new RangefinderSensorData();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 传感器数据的抽象基类
|
||||
/// </summary>
|
||||
public abstract class SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据采集的时间戳
|
||||
/// </summary>
|
||||
public DateTime Timestamp { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 红外传感器数据类
|
||||
/// </summary>
|
||||
public class InfraredSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 探测到的温度
|
||||
/// </summary>
|
||||
public double Temperature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标方向(如果检测到目标)
|
||||
/// </summary>
|
||||
public Vector3D? TargetDirection { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 辐射计传感器数据类
|
||||
/// </summary>
|
||||
public class RadiometerSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 探测到的辐射强度
|
||||
/// </summary>
|
||||
public double RadiationIntensity { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测高仪传感器数据类
|
||||
/// </summary>
|
||||
public class AltimeterSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 测量的高度
|
||||
/// </summary>
|
||||
public double Altitude { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测距仪传感器数据类
|
||||
/// </summary>
|
||||
public class RangefinderSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 测量的距离
|
||||
/// </summary>
|
||||
public double Distance { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Models;
|
||||
using Model;
|
||||
using ActiveProtect.Utility;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ActiveProtect
|
||||
@ -114,8 +114,8 @@ namespace ActiveProtect
|
||||
// 末敏弹配置
|
||||
new() {
|
||||
Id = "TSM_1",
|
||||
InitialPosition = new Vector3D(4000, 0, 100), // 发射位置
|
||||
InitialOrientation = new Orientation(Math.PI, Math.PI/8, 0), // 使用计算得到的发射角度
|
||||
InitialPosition = new Vector3D(3000, 0, 100), // 发射位置
|
||||
InitialOrientation = new Orientation(Math.PI, 0, 0), // 使用计算得到的发射角度
|
||||
InitialSpeed = 800,
|
||||
MaxSpeed = 1000,
|
||||
TargetIndex = 0,
|
||||
@ -125,6 +125,7 @@ namespace ActiveProtect
|
||||
MaxEngineBurnTime = 0,
|
||||
MaxAcceleration = 10,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
ExplosionRadius = 5,
|
||||
Mass = 50,
|
||||
Type = MissileType.TerminalSensitiveMissile
|
||||
},
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using System;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -38,6 +39,11 @@ namespace ActiveProtect.Models
|
||||
/// </summary>
|
||||
public double RadarCrossSection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 坦克配置
|
||||
/// </summary>
|
||||
public TankConfig TankConfig { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
@ -46,12 +52,13 @@ namespace ActiveProtect.Models
|
||||
public Tank(TankConfig tankConfig, ISimulationManager simulationManager)
|
||||
: base(tankConfig.Id, tankConfig.InitialPosition, tankConfig.InitialOrientation, tankConfig.InitialSpeed, simulationManager)
|
||||
{
|
||||
Speed = tankConfig.InitialSpeed;
|
||||
MaxSpeed = tankConfig.MaxSpeed;
|
||||
MaxArmor = tankConfig.MaxArmor;
|
||||
CurrentArmor = tankConfig.MaxArmor;
|
||||
InfraredRadiationIntensity = tankConfig.InfraredRadiationIntensity;
|
||||
RadarCrossSection = tankConfig.RadarCrossSection;
|
||||
TankConfig = tankConfig;
|
||||
Speed = TankConfig.InitialSpeed;
|
||||
MaxSpeed = TankConfig.MaxSpeed;
|
||||
MaxArmor = TankConfig.MaxArmor;
|
||||
CurrentArmor = TankConfig.MaxArmor;
|
||||
InfraredRadiationIntensity = TankConfig.InfraredRadiationIntensity;
|
||||
RadarCrossSection = TankConfig.RadarCrossSection;
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
101
src/Models/Guidance/BasicGuidanceSystem.cs
Normal file
101
src/Models/Guidance/BasicGuidanceSystem.cs
Normal file
@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 制导系统接口
|
||||
/// </summary>
|
||||
public interface IGuidanceSystem
|
||||
{
|
||||
bool HasGuidance { get; }
|
||||
void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity);
|
||||
Vector3D GetGuidanceAcceleration();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 基础制导系统
|
||||
/// </summary>
|
||||
public class BasicGuidanceSystem : IGuidanceSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否有制导
|
||||
/// </summary>
|
||||
public bool HasGuidance { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大加速度
|
||||
/// </summary>
|
||||
public double MaxAcceleration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 制导系数
|
||||
/// </summary>
|
||||
public double ProportionalNavigationCoefficient { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹位置
|
||||
/// </summary>
|
||||
protected Vector3D Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹速度
|
||||
/// </summary>
|
||||
protected Vector3D Velocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 制导加速度
|
||||
/// </summary>
|
||||
protected Vector3D GuidanceAcceleration { get; set; }
|
||||
|
||||
public BasicGuidanceSystem(double maxAcceleration, double proportionalNavigationCoefficient)
|
||||
{
|
||||
HasGuidance = false;
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
Position = Vector3D.Zero;
|
||||
Velocity = Vector3D.Zero;
|
||||
MaxAcceleration = maxAcceleration;
|
||||
ProportionalNavigationCoefficient = proportionalNavigationCoefficient;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新制导系统
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
/// <param name="missilePosition">导弹位置</param>
|
||||
/// <param name="missileVelocity">导弹速度</param>
|
||||
public virtual void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
|
||||
{
|
||||
Position = missilePosition;
|
||||
Velocity = missileVelocity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取制导加速度
|
||||
/// </summary>
|
||||
/// <returns>制导加速度</returns>
|
||||
public Vector3D GetGuidanceAcceleration()
|
||||
{
|
||||
return GuidanceAcceleration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算制导加速度
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
protected virtual void CalculateGuidanceAcceleration(double deltaTime)
|
||||
{
|
||||
// 基础制导系统不计算制导指令
|
||||
// 派生类应该重写这个方法来实现特定的制导逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取制导系统状态
|
||||
/// </summary>
|
||||
/// <returns>制导系统状态</returns>
|
||||
public virtual string GetStatus()
|
||||
{
|
||||
return $" 导引头状态: 有制导={HasGuidance}, 位置={Position}, 速度={Velocity}, 制导加速度={GuidanceAcceleration}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -38,7 +39,7 @@ namespace ActiveProtect.Models
|
||||
lastTargetPosition = tankPosition;
|
||||
|
||||
// 使用基类的比例控制算法
|
||||
GuidanceAcceleration = CalculateProportionalNavigation(ProportionalNavigationCoefficient, missilePosition, missileVelocity, tankPosition, targetVelocity);
|
||||
GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation(ProportionalNavigationCoefficient, missilePosition, missileVelocity, tankPosition, targetVelocity);
|
||||
// 限制最大加速度
|
||||
if (GuidanceAcceleration.Magnitude() > MaxAcceleration)
|
||||
{
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -161,7 +162,7 @@ namespace ActiveProtect.Models
|
||||
protected override void CalculateGuidanceAcceleration(double deltaTime)
|
||||
{
|
||||
// 计算比例导引加速度
|
||||
GuidanceAcceleration = CalculateProportionalNavigation(ProportionalNavigationCoefficient, Position, Velocity, TargetPosition, TargetVelocity);
|
||||
GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation(ProportionalNavigationCoefficient, Position, Velocity, TargetPosition, TargetVelocity);
|
||||
|
||||
// 限制最大加速度
|
||||
double maxAcceleration = 100; // 根据实际情况调整
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -17,6 +18,8 @@ namespace ActiveProtect.Models
|
||||
|
||||
private readonly Random random = new();
|
||||
private Vector3D lastTargetPosition;
|
||||
private bool isJammed = false;
|
||||
private double jammingPower = 0;
|
||||
|
||||
public ISimulationManager SimulationManager { get; set; }
|
||||
|
||||
@ -27,6 +30,15 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
SimulationManager = simulationManager;
|
||||
lastTargetPosition = Vector3D.Zero;
|
||||
|
||||
// 订阅干扰事件
|
||||
simulationManager.SubscribeToEvent<MillimeterWaveJammingEvent>(HandleJammingEvent);
|
||||
}
|
||||
|
||||
private void HandleJammingEvent(MillimeterWaveJammingEvent evt)
|
||||
{
|
||||
isJammed = true;
|
||||
jammingPower = evt.JammingPower;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -43,7 +55,7 @@ namespace ActiveProtect.Models
|
||||
lastTargetPosition = tankPosition;
|
||||
|
||||
// 使用基类的比例控制算法
|
||||
GuidanceAcceleration = CalculateProportionalNavigation(ProportionalNavigationCoefficient, missilePosition, missileVelocity, tankPosition, targetVelocity);
|
||||
GuidanceAcceleration = MotionAlgorithm.CalculateProportionalNavigation(ProportionalNavigationCoefficient, missilePosition, missileVelocity, tankPosition, targetVelocity);
|
||||
|
||||
if (GuidanceAcceleration.Magnitude() > MaxAcceleration)
|
||||
{
|
||||
@ -65,6 +77,13 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
targetPosition = Vector3D.Zero;
|
||||
|
||||
// 如果被干扰,直接返回false
|
||||
if (isJammed)
|
||||
{
|
||||
Console.WriteLine($"毫米波导引头受到干扰,干扰功率: {jammingPower:F2}W");
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var element in SimulationManager.GetElements())
|
||||
{
|
||||
if (element is Tank tank)
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -1,5 +1,6 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using System;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -1,5 +1,6 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using System;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
34
src/Models/Jammer/IJammer.cs
Normal file
34
src/Models/Jammer/IJammer.cs
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 干扰设备接口
|
||||
/// </summary>
|
||||
public interface IJammer
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否正在干扰
|
||||
/// </summary>
|
||||
bool IsJamming { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前干扰功率
|
||||
/// </summary>
|
||||
double CurrentJammingPower { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始干扰
|
||||
/// </summary>
|
||||
void StartJamming();
|
||||
|
||||
/// <summary>
|
||||
/// 停止干扰
|
||||
/// </summary>
|
||||
void StopJamming();
|
||||
|
||||
/// <summary>
|
||||
/// 获取干扰状态
|
||||
/// </summary>
|
||||
string GetJammingStatus();
|
||||
}
|
||||
}
|
||||
120
src/Models/Jammer/JammerBase.cs
Normal file
120
src/Models/Jammer/JammerBase.cs
Normal file
@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 干扰设备基类
|
||||
/// </summary>
|
||||
public abstract class JammerBase : SimulationElement, IJammer
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否正在干扰
|
||||
/// </summary>
|
||||
public bool IsJamming { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前干扰功率
|
||||
/// </summary>
|
||||
public double CurrentJammingPower { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大干扰功率
|
||||
/// </summary>
|
||||
protected double MaxJammingPower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功率增长率
|
||||
/// </summary>
|
||||
protected double PowerIncreaseRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大冷却时间
|
||||
/// </summary>
|
||||
protected double MaxCooldownTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前冷却时间
|
||||
/// </summary>
|
||||
protected double CurrentCooldownTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属坦克ID
|
||||
/// </summary>
|
||||
protected string TankId { get; set; }
|
||||
|
||||
protected JammerBase(string id, Vector3D position, Orientation orientation,
|
||||
ISimulationManager manager, string tankId, double maxJammingPower,
|
||||
double initialJammingPower, double powerIncreaseRate, double maxCooldownTime)
|
||||
: base(id, position, orientation, 0, manager)
|
||||
{
|
||||
TankId = tankId;
|
||||
MaxJammingPower = maxJammingPower;
|
||||
CurrentJammingPower = initialJammingPower;
|
||||
PowerIncreaseRate = powerIncreaseRate;
|
||||
MaxCooldownTime = maxCooldownTime;
|
||||
CurrentCooldownTime = 0;
|
||||
IsJamming = false;
|
||||
}
|
||||
|
||||
public virtual void StartJamming()
|
||||
{
|
||||
if (CurrentCooldownTime <= 0 && !IsJamming)
|
||||
{
|
||||
IsJamming = true;
|
||||
Console.WriteLine($"干扰器 {Id} 开始干扰");
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StopJamming()
|
||||
{
|
||||
if (IsJamming)
|
||||
{
|
||||
IsJamming = false;
|
||||
CurrentCooldownTime = MaxCooldownTime;
|
||||
CurrentJammingPower = MaxJammingPower * 0.4; // 重置为最大功率的40%
|
||||
Console.WriteLine($"干扰器 {Id} 停止干扰,进入冷却");
|
||||
}
|
||||
}
|
||||
|
||||
public abstract string GetJammingStatus();
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
if (IsJamming)
|
||||
{
|
||||
UpdateJammingPower(deltaTime);
|
||||
PublishJammingEvent();
|
||||
}
|
||||
else if (CurrentCooldownTime > 0)
|
||||
{
|
||||
CurrentCooldownTime = Math.Max(0, CurrentCooldownTime - deltaTime);
|
||||
}
|
||||
|
||||
// 更新位置(跟随坦克)
|
||||
if (SimulationManager.GetEntityById(TankId) is Tank tank)
|
||||
{
|
||||
Position = tank.Position;
|
||||
Orientation = tank.Orientation;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
StartJamming();
|
||||
}
|
||||
|
||||
public override void Deactivate()
|
||||
{
|
||||
StopJamming();
|
||||
base.Deactivate();
|
||||
}
|
||||
|
||||
protected abstract void UpdateJammingPower(double deltaTime);
|
||||
protected abstract void PublishJammingEvent();
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
151
src/Models/Jammer/MillimeterWaveJammer.cs
Normal file
151
src/Models/Jammer/MillimeterWaveJammer.cs
Normal file
@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 毫米波干扰器
|
||||
/// </summary>
|
||||
public class MillimeterWaveJammer : SimulationElement
|
||||
{
|
||||
/// <summary>
|
||||
/// 最大干扰功率(瓦特)
|
||||
/// </summary>
|
||||
private readonly double maxJammingPower;
|
||||
|
||||
/// <summary>
|
||||
/// 当前干扰功率(瓦特)
|
||||
/// </summary>
|
||||
private double currentJammingPower;
|
||||
|
||||
/// <summary>
|
||||
/// 干扰功率增长率(瓦特/秒)
|
||||
/// </summary>
|
||||
private readonly double powerIncreaseRate;
|
||||
|
||||
/// <summary>
|
||||
/// 最大干扰冷却时间(秒)
|
||||
/// </summary>
|
||||
private readonly double maxJammingCooldown;
|
||||
|
||||
/// <summary>
|
||||
/// 当前冷却时间(秒)
|
||||
/// </summary>
|
||||
private double currentCooldown;
|
||||
|
||||
/// <summary>
|
||||
/// 是否正在干扰
|
||||
/// </summary>
|
||||
private bool isJamming;
|
||||
|
||||
/// <summary>
|
||||
/// 所属坦克ID
|
||||
/// </summary>
|
||||
private readonly string tankId;
|
||||
|
||||
/// <summary>
|
||||
/// 干扰器构造函数
|
||||
/// </summary>
|
||||
public MillimeterWaveJammer(string id, Vector3D position, Orientation orientation,
|
||||
ISimulationManager manager, string tankId, MillimeterWaveJammerConfig config)
|
||||
: base(id, position, orientation, 0, manager)
|
||||
{
|
||||
this.tankId = tankId;
|
||||
maxJammingPower = config.MaxJammingPower;
|
||||
currentJammingPower = config.InitialJammingPower;
|
||||
powerIncreaseRate = config.PowerIncreaseRate;
|
||||
maxJammingCooldown = config.MaxJammingCooldown;
|
||||
currentCooldown = 0;
|
||||
isJamming = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新干扰器状态
|
||||
/// </summary>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
if (isJamming)
|
||||
{
|
||||
// 增加干扰功率
|
||||
currentJammingPower = Math.Min(maxJammingPower,
|
||||
currentJammingPower + powerIncreaseRate * deltaTime);
|
||||
|
||||
// 发布干扰事件
|
||||
SimulationManager.PublishEvent(new MillimeterWaveJammingEvent
|
||||
{
|
||||
SenderId = Id,
|
||||
Timestamp = SimulationManager.CurrentTime,
|
||||
TargetId = tankId,
|
||||
JammingPower = currentJammingPower
|
||||
});
|
||||
}
|
||||
else if (currentCooldown > 0)
|
||||
{
|
||||
// 更新冷却时间
|
||||
currentCooldown = Math.Max(0, currentCooldown - deltaTime);
|
||||
}
|
||||
|
||||
// 更新位置(跟随坦克)
|
||||
if (SimulationManager.GetEntityById(tankId) is Tank tank)
|
||||
{
|
||||
Position = tank.Position;
|
||||
Orientation = tank.Orientation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始干扰
|
||||
/// </summary>
|
||||
public void StartJamming()
|
||||
{
|
||||
if (currentCooldown <= 0 && !isJamming)
|
||||
{
|
||||
isJamming = true;
|
||||
Console.WriteLine($"毫米波干扰器 {Id} 开始干扰");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止干扰
|
||||
/// </summary>
|
||||
public void StopJamming()
|
||||
{
|
||||
if (isJamming)
|
||||
{
|
||||
isJamming = false;
|
||||
currentCooldown = maxJammingCooldown;
|
||||
currentJammingPower = maxJammingPower * 0.4; // 重置为最大功率的40%
|
||||
Console.WriteLine($"毫米波干扰器 {Id} 停止干扰,进入冷却");
|
||||
}
|
||||
}
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
StartJamming();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁干扰器
|
||||
/// </summary>
|
||||
public override void Deactivate()
|
||||
{
|
||||
StopJamming();
|
||||
base.Deactivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取干扰器状态
|
||||
/// </summary>
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"毫米波干扰器 {Id}:\n" +
|
||||
$" 位置: {Position}\n" +
|
||||
$" 干扰功率: {currentJammingPower:F2}/{maxJammingPower:F2}\n" +
|
||||
$" 冷却时间: {currentCooldown:F2}/{maxJammingCooldown:F2}\n" +
|
||||
$" 状态: {(isJamming ? "干扰中" : "待机中")}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -1,5 +1,5 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public class LaserBeamRiderMissile : MissileBase
|
||||
@ -1,5 +1,6 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using System;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using Model;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -98,7 +98,7 @@ namespace ActiveProtect.Models
|
||||
/// <summary>
|
||||
/// 是否有制导
|
||||
/// </summary>
|
||||
public bool HasGuidance { get; protected set; } = false;
|
||||
public bool HasGuidance { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 失去制导的时间(秒)
|
||||
@ -109,16 +109,11 @@ namespace ActiveProtect.Models
|
||||
/// 最后已知的速度向量
|
||||
/// </summary>
|
||||
protected Vector3D LastKnownVelocity = Vector3D.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// 发射速度(米/秒)
|
||||
/// </summary>
|
||||
public const double LAUNCH_SPEED = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 导弹质量(千克)
|
||||
/// </summary>
|
||||
public double Mass { get; protected set; } = 100;
|
||||
public double Mass { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 制导加速度
|
||||
@ -143,6 +138,7 @@ namespace ActiveProtect.Models
|
||||
InitializeFromConfig();
|
||||
|
||||
IsActive = false;
|
||||
HasGuidance = false;
|
||||
FlightTime = 0;
|
||||
FlightDistance = 0;
|
||||
EngineBurnTime = 0;
|
||||
@ -189,8 +185,19 @@ namespace ActiveProtect.Models
|
||||
|
||||
Vector3D acceleration = GuidanceAcceleration;
|
||||
|
||||
// 使用四阶龙格-库塔方法更新导弹的位置和速度
|
||||
(Position, Velocity) = BasicGuidanceSystem.RungeKutta4(deltaTime, Position, Velocity, acceleration);
|
||||
if (HasGuidance)
|
||||
{
|
||||
// 制导条件下,使用四阶龙格-库塔方法更新导弹的位置和速度
|
||||
(Position, Velocity) = MotionAlgorithm.RungeKutta4(deltaTime, Position, Velocity, acceleration);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"无制导条件下,使用运动学方程更新导弹的位置和速度");
|
||||
// 无制导条件下,使用运动学方程更新导弹的位置和速度
|
||||
(Position, Velocity) = MotionAlgorithm.CalculateBallisticMotion(Position, Velocity, acceleration, deltaTime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 限制速度不超过最大速度
|
||||
if (Velocity.Magnitude() > MaxSpeed)
|
||||
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Model
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 坦克消息结构
|
||||
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
@ -11,9 +12,9 @@ namespace ActiveProtect.Models
|
||||
// 分离点距离目标水平距离,默认 1000 米
|
||||
private const double SeparationDistance = 1000;
|
||||
// 分离时距离分离点的距离阈值,默认 50米
|
||||
private const double SeparationRange = 50;
|
||||
// 分离时距目标距离阈值,默认 1400 米
|
||||
private const double SeparationTargetDistance = 1400;
|
||||
private const double SeparationRange = 0.5;
|
||||
// 分离时距目标距离阈值,默认 1200 米
|
||||
private const double SeparationTargetDistance = 1200;
|
||||
// 子弹数量, 155 口径母弹,默认 2 个
|
||||
private const int SubmunitionCount = 1;
|
||||
// 子弹数组
|
||||
@ -28,6 +29,22 @@ namespace ActiveProtect.Models
|
||||
|
||||
//计算分离点坐标,高度为SeparationHeight,距离目标的距离为SeparationDistance
|
||||
separationPoint = Vector3D.PointOnLine(base.SimulationManager.GetEntityById(TargetId).Position, base.Position, SeparationDistance) + new Vector3D(0, SeparationHeight, 0);
|
||||
|
||||
//计算导弹发射角度
|
||||
(Orientation? launchOrientation, Vector3D? launchVelocity) = MotionAlgorithm.CalculateBestLaunchOrientation(Position, separationPoint, Speed);
|
||||
if (!launchOrientation.HasValue || launchVelocity is null)
|
||||
{
|
||||
// 处理错误情况
|
||||
throw new InvalidOperationException("无法计算发射方向");
|
||||
}
|
||||
else
|
||||
{
|
||||
Orientation = launchOrientation.Value;
|
||||
Velocity = launchVelocity;
|
||||
Console.WriteLine($"发射方向: {launchOrientation}");
|
||||
}
|
||||
|
||||
GuidanceAcceleration = new Vector3D(0, -9.81, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -36,9 +53,8 @@ namespace ActiveProtect.Models
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
|
||||
GuidanceAcceleration = new Vector3D(0, -9.8, 0);
|
||||
base.Update(deltaTime);
|
||||
|
||||
Console.WriteLine($"分离点距离: {(separationPoint - Position).Magnitude()}");
|
||||
|
||||
@ -61,7 +77,7 @@ namespace ActiveProtect.Models
|
||||
// 获取目标位置
|
||||
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
||||
|
||||
// 创建并释放子弹
|
||||
// 创建并释子弹
|
||||
for (int i = 0; i < SubmunitionCount; i++)
|
||||
{
|
||||
// 计算子弹朝向目标的方向
|
||||
@ -82,7 +98,7 @@ namespace ActiveProtect.Models
|
||||
MaxAcceleration = 50,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
Mass = 10,
|
||||
ExplosionRadius = 10
|
||||
ExplosionRadius = this.ExplosionRadius
|
||||
},
|
||||
SimulationManager);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public class TerminalSensitiveSubmunition : MissileBase
|
||||
@ -30,6 +30,9 @@ namespace ActiveProtect.Models
|
||||
// 减速高度 400米
|
||||
private const double DecelerationHeight = 400;
|
||||
|
||||
// 减速加速度 50 m/s^2
|
||||
private const double DecelerationAcceleration = 50;
|
||||
|
||||
// 扫描高度 200米
|
||||
private const double ScanningHeight = 200;
|
||||
|
||||
@ -141,14 +144,15 @@ namespace ActiveProtect.Models
|
||||
/// </summary>
|
||||
private void UpdateDecelerationStage(double deltaTime)
|
||||
{
|
||||
HasGuidance = true;
|
||||
// 减速减旋,垂直速度减小
|
||||
Vector3D deceleration = new Vector3D(0, 9.8, 0) - Velocity.Normalize() * 50; // 假设减速度为5m/s^2
|
||||
Console.WriteLine($"降落伞打开,减速速度: {deceleration}");
|
||||
Vector3D deceleration = - Velocity.Normalize() * DecelerationAcceleration;
|
||||
Velocity += deceleration * deltaTime;
|
||||
|
||||
if (Velocity.Magnitude() <= VerticalDescentSpeed)
|
||||
{
|
||||
Velocity = new Vector3D(0, -VerticalDescentSpeed, 0);
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
}
|
||||
|
||||
if (((AltimeterSensorData)altimeter.GetSensorData()).Altitude <= ScanningHeight)
|
||||
@ -162,6 +166,7 @@ namespace ActiveProtect.Models
|
||||
/// </summary>
|
||||
private void UpdateSpiralScanStage(double deltaTime)
|
||||
{
|
||||
Velocity = new Vector3D(0, -VerticalDescentSpeed, 0);
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
|
||||
// 更新螺旋角度
|
||||
35
src/Models/Sensor/ISensor.cs
Normal file
35
src/Models/Sensor/ISensor.cs
Normal file
@ -0,0 +1,35 @@
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义传感器的基本接口
|
||||
/// </summary>
|
||||
public interface ISensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置传感器是否处于激活状态
|
||||
/// </summary>
|
||||
bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激活传感器
|
||||
/// </summary>
|
||||
void Activate();
|
||||
|
||||
/// <summary>
|
||||
/// 停用传感器
|
||||
/// </summary>
|
||||
void Deactivate();
|
||||
|
||||
/// <summary>
|
||||
/// 更新传感器状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
void Update(double deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// 获取传感器数据
|
||||
/// </summary>
|
||||
/// <returns>传感器采集的数据</returns>
|
||||
SensorData GetSensorData();
|
||||
}
|
||||
}
|
||||
54
src/Models/Sensor/InfraredDetector.cs
Normal file
54
src/Models/Sensor/InfraredDetector.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using ActiveProtect.Utility;
|
||||
using System;
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 红外探测器类
|
||||
/// </summary>
|
||||
public class InfraredDetector : Sensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 探测范围
|
||||
/// </summary>
|
||||
public double DetectionRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 视场角
|
||||
/// </summary>
|
||||
public double FieldOfView { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">探测器的位置</param>
|
||||
/// <param name="orientation">探测器的朝向</param>
|
||||
/// <param name="detectionRange">探测范围</param>
|
||||
/// <param name="fieldOfView">视场角</param>
|
||||
public InfraredDetector(Vector3D position, Orientation orientation, double detectionRange, double fieldOfView)
|
||||
: base(position, orientation)
|
||||
{
|
||||
DetectionRange = detectionRange;
|
||||
FieldOfView = fieldOfView;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新红外探测器的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 实现红外探测器的更新逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取红外探测器的数据
|
||||
/// </summary>
|
||||
/// <returns>红外探测器采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回红外探测器的数据
|
||||
return new InfraredSensorData();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
54
src/Models/Sensor/LaserRangefinder.cs
Normal file
54
src/Models/Sensor/LaserRangefinder.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光测距仪类
|
||||
/// </summary>
|
||||
public class LaserRangefinder : Sensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 最大测量距离
|
||||
/// </summary>
|
||||
public double MaxRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 脉冲频率
|
||||
/// </summary>
|
||||
public double PulseRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">测距仪的位置</param>
|
||||
/// <param name="orientation">测距仪的朝向</param>
|
||||
/// <param name="maxRange">最大测量距离</param>
|
||||
/// <param name="pulseRate">脉冲频率</param>
|
||||
public LaserRangefinder(Vector3D position, Orientation orientation, double maxRange, double pulseRate)
|
||||
: base(position, orientation)
|
||||
{
|
||||
MaxRange = maxRange;
|
||||
PulseRate = pulseRate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新激光测距仪的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 实现激光测距仪的更新逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取激光测距仪的数据
|
||||
/// </summary>
|
||||
/// <returns>激光测距仪采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回激光测距仪的数据
|
||||
return new RangefinderSensorData();
|
||||
}
|
||||
}
|
||||
}
|
||||
70
src/Models/Sensor/MillimeterWaveAltimeter.cs
Normal file
70
src/Models/Sensor/MillimeterWaveAltimeter.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 毫米波测高雷达类
|
||||
/// </summary>
|
||||
public class MillimeterWaveAltimeter : Sensor
|
||||
{
|
||||
private double currentAltitude;
|
||||
|
||||
private readonly TerminalSensitiveSubmunition submunition;
|
||||
|
||||
/// <summary>
|
||||
/// 最大测量高度
|
||||
/// </summary>
|
||||
public double MaxAltitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 测量精度
|
||||
/// </summary>
|
||||
public double Accuracy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">测高雷达的位置</param>
|
||||
/// <param name="orientation">测高雷达的朝向</param>
|
||||
/// <param name="maxAltitude">最大测量高度</param>
|
||||
/// <param name="accuracy">测量精度</param>
|
||||
public MillimeterWaveAltimeter(TerminalSensitiveSubmunition submunition, double maxAltitude, double accuracy)
|
||||
: base(submunition.Position, submunition.Orientation)
|
||||
{
|
||||
MaxAltitude = maxAltitude;
|
||||
Accuracy = accuracy;
|
||||
currentAltitude = 0;
|
||||
this.submunition = submunition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新毫米波测高雷达的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 更新当前高度,考虑测量精度
|
||||
currentAltitude = submunition.Position.Y + Accuracy * new Random().NextDouble();
|
||||
}
|
||||
|
||||
//监听毫米波干扰事件
|
||||
public void OnMillimeterWaveJamming(object sender, EventArgs e)
|
||||
{
|
||||
Console.WriteLine("毫米波测高雷达受到干扰");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取毫米波测高雷达的数据
|
||||
/// </summary>
|
||||
/// <returns>毫米波测高雷达采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回毫米波测高雷达的数据
|
||||
AltimeterSensorData altimeterSensorData = new AltimeterSensorData
|
||||
{
|
||||
Altitude = currentAltitude
|
||||
};
|
||||
return altimeterSensorData;
|
||||
}
|
||||
}
|
||||
}
|
||||
52
src/Models/Sensor/MillimeterWaveRadiometer.cs
Normal file
52
src/Models/Sensor/MillimeterWaveRadiometer.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using ActiveProtect.Utility;
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 毫米波辐射计类
|
||||
/// </summary>
|
||||
public class MillimeterWaveRadiometer : Sensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 工作频率(3mm 或 8mm)
|
||||
/// </summary>
|
||||
public double Frequency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 辐射温度差检测阈值,辐射计高温物体与低温物体的检测温差,单位K,默认 50K
|
||||
/// </summary>
|
||||
public double DetectionTemperatureDifferenceThreshold { get; set; } = 50;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">辐射计的位置</param>
|
||||
/// <param name="orientation">辐射计的朝向</param>
|
||||
/// <param name="frequency">工作频率</param>
|
||||
/// <param name="detectionTemperatureDifferenceThreshold">辐射温差检测阈值</param>
|
||||
public MillimeterWaveRadiometer(Vector3D position, Orientation orientation, double frequency, double detectionTemperatureDifferenceThreshold)
|
||||
: base(position, orientation)
|
||||
{
|
||||
Frequency = frequency;
|
||||
DetectionTemperatureDifferenceThreshold = detectionTemperatureDifferenceThreshold;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新毫米波辐射计的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 实现毫米波辐射计的更新逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取毫米波辐射计的数据
|
||||
/// </summary>
|
||||
/// <returns>毫米波辐射计采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回毫米波辐射计的数据
|
||||
return new RadiometerSensorData();
|
||||
}
|
||||
}
|
||||
}
|
||||
65
src/Models/Sensor/SensorData.cs
Normal file
65
src/Models/Sensor/SensorData.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 传感器数据的抽象基类
|
||||
/// </summary>
|
||||
public abstract class SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据采集的时间戳
|
||||
/// </summary>
|
||||
public DateTime Timestamp { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 红外传感器数据类
|
||||
/// </summary>
|
||||
public class InfraredSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 探测到的温度
|
||||
/// </summary>
|
||||
public double Temperature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标方向(如果检测到目标)
|
||||
/// </summary>
|
||||
public Vector3D? TargetDirection { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 辐射计传感器数据类
|
||||
/// </summary>
|
||||
public class RadiometerSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 探测到的辐射强度
|
||||
/// </summary>
|
||||
public double RadiationIntensity { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测高仪传感器数据类
|
||||
/// </summary>
|
||||
public class AltimeterSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 测量的高度
|
||||
/// </summary>
|
||||
public double Altitude { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测距仪传感器数据类
|
||||
/// </summary>
|
||||
public class RangefinderSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 测量的距离
|
||||
/// </summary>
|
||||
public double Distance { get; set; }
|
||||
}
|
||||
}
|
||||
67
src/Models/Sensor/Sensors.cs
Normal file
67
src/Models/Sensor/Sensors.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 传感器的抽象基类,实现了ISensor接口的基本功能
|
||||
/// </summary>
|
||||
public abstract class Sensor : ISensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置传感器是否处于激活状态
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 传感器的位置
|
||||
/// </summary>
|
||||
protected Vector3D Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 传感器的朝向
|
||||
/// </summary>
|
||||
protected Orientation Orientation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">传感器的初始位置</param>
|
||||
/// <param name="orientation">传感器的初始朝向</param>
|
||||
protected Sensor(Vector3D position, Orientation orientation)
|
||||
{
|
||||
Position = position;
|
||||
Orientation = orientation;
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活传感器
|
||||
/// </summary>
|
||||
public virtual void Activate()
|
||||
{
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停用传感器
|
||||
/// </summary>
|
||||
public virtual void Deactivate()
|
||||
{
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新传感器状态(需要在子类中实现)
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public abstract void Update(double deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// 获取传感器数据(需要在子类中实现)
|
||||
/// </summary>
|
||||
/// <returns>传感器采集的数据</returns>
|
||||
public abstract SensorData GetSensorData();
|
||||
}
|
||||
}
|
||||
28
src/Models/Wanner/IWarner.cs
Normal file
28
src/Models/Wanner/IWarner.cs
Normal file
@ -0,0 +1,28 @@
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 告警设备接口
|
||||
/// </summary>
|
||||
public interface IWarner
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否处于告警状态
|
||||
/// </summary>
|
||||
bool IsWarning { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始告警
|
||||
/// </summary>
|
||||
void StartWarning();
|
||||
|
||||
/// <summary>
|
||||
/// 停止告警
|
||||
/// </summary>
|
||||
void StopWarning();
|
||||
|
||||
/// <summary>
|
||||
/// 获取告警状态
|
||||
/// </summary>
|
||||
string GetWarningStatus();
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Simulation;
|
||||
using System;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
98
src/Models/Wanner/WarnerBase.cs
Normal file
98
src/Models/Wanner/WarnerBase.cs
Normal file
@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using ActiveProtect.Simulation;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 告警设备基类
|
||||
/// </summary>
|
||||
public abstract class WarnerBase : SimulationElement, IWarner
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否处于告警状态
|
||||
/// </summary>
|
||||
public bool IsWarning { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 告警持续时间(秒)
|
||||
/// </summary>
|
||||
protected double WarningDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前告警时间(秒)
|
||||
/// </summary>
|
||||
protected double CurrentWarningTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所属坦克ID
|
||||
/// </summary>
|
||||
protected string TankId { get; set; }
|
||||
|
||||
protected WarnerBase(string id, Vector3D position, Orientation orientation,
|
||||
ISimulationManager manager, string tankId, double warningDuration)
|
||||
: base(id, position, orientation, 0, manager)
|
||||
{
|
||||
TankId = tankId;
|
||||
WarningDuration = warningDuration;
|
||||
CurrentWarningTime = 0;
|
||||
IsWarning = false;
|
||||
}
|
||||
|
||||
public virtual void StartWarning()
|
||||
{
|
||||
if (!IsWarning)
|
||||
{
|
||||
IsWarning = true;
|
||||
CurrentWarningTime = 0;
|
||||
Console.WriteLine($"告警器 {Id} 开始告警");
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StopWarning()
|
||||
{
|
||||
if (IsWarning)
|
||||
{
|
||||
IsWarning = false;
|
||||
CurrentWarningTime = 0;
|
||||
Console.WriteLine($"告警器 {Id} 停止告警");
|
||||
}
|
||||
}
|
||||
|
||||
public abstract string GetWarningStatus();
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
if (IsWarning)
|
||||
{
|
||||
CurrentWarningTime += deltaTime;
|
||||
if (CurrentWarningTime >= WarningDuration)
|
||||
{
|
||||
StopWarning();
|
||||
}
|
||||
}
|
||||
|
||||
// 更新位置(跟随坦克)
|
||||
if (SimulationManager.GetEntityById(TankId) is Tank tank)
|
||||
{
|
||||
Position = tank.Position;
|
||||
Orientation = tank.Orientation;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
Console.WriteLine($"告警器 {Id} 已激活");
|
||||
}
|
||||
|
||||
public override void Deactivate()
|
||||
{
|
||||
StopWarning();
|
||||
base.Deactivate();
|
||||
Console.WriteLine($"告警器 {Id} 已停用");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ActiveProtect.Utility;
|
||||
using ActiveProtect.Models;
|
||||
using Model;
|
||||
|
||||
namespace ActiveProtect.SimulationEnvironment
|
||||
namespace ActiveProtect.Simulation
|
||||
{
|
||||
/// <summary>
|
||||
/// 仿真配置类,包含整个仿真所需的所有配置信息
|
||||
@ -40,6 +40,11 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public LaserJammerConfig LaserJammerConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 毫米波干扰器配置
|
||||
/// </summary>
|
||||
public MillimeterWaveJammerConfig MillimeterWaveJammerConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仿真时间步长(秒)
|
||||
/// </summary>
|
||||
@ -61,6 +66,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
LaserBeamRiderConfig = new LaserBeamRiderConfig();
|
||||
LaserWarnerConfig = new LaserWarnerConfig();
|
||||
LaserJammerConfig = new LaserJammerConfig();
|
||||
MillimeterWaveJammerConfig = new MillimeterWaveJammerConfig();
|
||||
InfraredTrackerConfig = new InfraredTrackerConfig();
|
||||
SimulationTimeStep = 0.1; // 默认时间步长为0.1秒
|
||||
}
|
||||
@ -121,6 +127,11 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public bool HasLaserJammer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否装备毫米波干扰器
|
||||
/// </summary>
|
||||
public bool HasMillimeterWaveJammer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,设置默认值
|
||||
/// </summary>
|
||||
@ -147,6 +158,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
MaxArmor = 0;
|
||||
HasLaserWarner = false;
|
||||
HasLaserJammer = false;
|
||||
HasMillimeterWaveJammer = false;
|
||||
InfraredRadiationIntensity = 0;
|
||||
}
|
||||
|
||||
@ -521,4 +533,47 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
UpdateFrequency = 10; // 10赫兹
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 毫米波干扰器配置类
|
||||
/// </summary>
|
||||
public class MillimeterWaveJammerConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 干扰器ID
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大干扰功率(瓦特)
|
||||
/// </summary>
|
||||
public double MaxJammingPower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始干扰功率(瓦特)
|
||||
/// </summary>
|
||||
public double InitialJammingPower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 功率增长率(瓦特/秒)
|
||||
/// </summary>
|
||||
public double PowerIncreaseRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大冷却时间(秒)
|
||||
/// </summary>
|
||||
public double MaxJammingCooldown { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public MillimeterWaveJammerConfig()
|
||||
{
|
||||
Id = "";
|
||||
MaxJammingPower = 1000;
|
||||
InitialJammingPower = 400;
|
||||
PowerIncreaseRate = 200;
|
||||
MaxJammingCooldown = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using ActiveProtect.Models;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.SimulationEnvironment
|
||||
namespace ActiveProtect.Simulation
|
||||
{
|
||||
/// <summary>
|
||||
/// 仿真元素的抽象基类,所有仿真中的实体都继承自此类
|
||||
@ -1,6 +1,7 @@
|
||||
using ActiveProtect.Utility;
|
||||
using ActiveProtect.Models;
|
||||
|
||||
namespace ActiveProtect.SimulationEnvironment
|
||||
namespace ActiveProtect.Simulation
|
||||
{
|
||||
/// <summary>
|
||||
/// 仿真事件的基类
|
||||
@ -61,7 +62,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
public SimulationElement? Target { get; set; }
|
||||
}
|
||||
|
||||
/// <summary
|
||||
/// <summary>
|
||||
/// 激光照射停止事件
|
||||
/// </summary>
|
||||
public class LaserIlluminationStopEvent : SimulationEvent
|
||||
@ -205,4 +206,20 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
public class InfraredGuidanceMissileLightOffEvent : SimulationEvent
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 毫米波干扰事件
|
||||
/// </summary>
|
||||
public class MillimeterWaveJammingEvent : SimulationEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
/// </summary>
|
||||
public string? TargetId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 干扰功率(瓦特)
|
||||
/// </summary>
|
||||
public double JammingPower { get; set; }
|
||||
}
|
||||
}
|
||||
@ -2,8 +2,9 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ActiveProtect.Models;
|
||||
using ActiveProtect.Utility;
|
||||
|
||||
namespace ActiveProtect.SimulationEnvironment
|
||||
namespace ActiveProtect.Simulation
|
||||
{
|
||||
/// <summary>
|
||||
/// 仿真管理器接口,定义了仿真管理器的基本功能
|
||||
@ -131,6 +132,20 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
);
|
||||
Elements.Add(laserJammer);
|
||||
}
|
||||
|
||||
// 为坦克创建毫米波干扰器
|
||||
if (tankConfig.HasMillimeterWaveJammer)
|
||||
{
|
||||
var millimeterWaveJammer = new MillimeterWaveJammer(
|
||||
$"MMWJ_{i}",
|
||||
tank.Position,
|
||||
tank.Orientation,
|
||||
this,
|
||||
tank.Id,
|
||||
config.MillimeterWaveJammerConfig
|
||||
);
|
||||
Elements.Add(millimeterWaveJammer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -208,10 +223,10 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
Elements.Add(infraredTracker);
|
||||
|
||||
// 激活所有元素
|
||||
ActivateAllElements();
|
||||
//ActivateAllElements();
|
||||
|
||||
// 激活部分元素
|
||||
//ActivateSomeElements();
|
||||
ActivateSomeElements();
|
||||
}
|
||||
|
||||
//激活所有元素
|
||||
@ -245,18 +260,21 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
//Elements.FindAll(e => e.Id == "LBR_1").ForEach(e => e.Activate());
|
||||
|
||||
// 激活红外指令制导导弹
|
||||
Elements.FindAll(e => e.Id == "ICGM_1").ForEach(e => e.Activate());
|
||||
//Elements.FindAll(e => e.Id == "ICGM_1").ForEach(e => e.Activate());
|
||||
// 激活红外测角仪
|
||||
Elements.FindAll(e => e.Id == "IT_1").ForEach(e => e.Activate());
|
||||
//Elements.FindAll(e => e.Id == "IT_1").ForEach(e => e.Activate());
|
||||
|
||||
// 激活红外成像末制导导弹
|
||||
Elements.FindAll(e => e.Id == "ITGM_1").ForEach(e => e.Activate());
|
||||
//Elements.FindAll(e => e.Id == "ITGM_1").ForEach(e => e.Activate());
|
||||
|
||||
// 激活毫米波末制导导弹
|
||||
//Elements.FindAll(e => e.Id == "MMWG_1").ForEach(e => e.Activate());
|
||||
|
||||
// 激活末敏弹
|
||||
//Elements.FindAll(e => e.Id == "TSM_1").ForEach(e => e.Activate());
|
||||
Elements.FindAll(e => e.Id == "TSM_1").ForEach(e => e.Activate());
|
||||
|
||||
// 激活毫米波干扰器
|
||||
//Elements.FindAll(e => e.Id == "MMWJ_1").ForEach(e => e.Activate());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
namespace ActiveProtect.Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示三维空间中的向量
|
||||
@ -392,4 +392,6 @@ namespace ActiveProtect.Models
|
||||
/// </summary>
|
||||
public static Vector2D Zero => new Vector2D(0, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
173
src/Utility/MotionAlgorithm.cs
Normal file
173
src/Utility/MotionAlgorithm.cs
Normal file
@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
|
||||
namespace ActiveProtect.Utility
|
||||
{
|
||||
public static class MotionAlgorithm
|
||||
{
|
||||
/// <summary>
|
||||
/// 计算抛物线弹道最佳发射方向(选择较小的仰角)
|
||||
/// </summary>
|
||||
/// <param name="startPos">发射位置</param>
|
||||
/// <param name="targetPos">目标位置</param>
|
||||
/// <param name="initialSpeed">初始速度</param>
|
||||
/// <returns>最佳发射方向,如果无解则返回null</returns>
|
||||
public static (Orientation? orientation, Vector3D? velocity) CalculateBestLaunchOrientation(Vector3D startPos, Vector3D targetPos, double initialSpeed)
|
||||
{
|
||||
// 计算水平距离
|
||||
double dx = targetPos.X - startPos.X;
|
||||
double dz = targetPos.Z - startPos.Z;
|
||||
double horizontalDistance = Math.Sqrt(dx * dx + dz * dz);
|
||||
|
||||
// 计算高度差
|
||||
double dy = targetPos.Y - startPos.Y;
|
||||
|
||||
double[]? angles = CalculateLaunchAngles(initialSpeed, horizontalDistance, dy);
|
||||
|
||||
if (angles == null)
|
||||
{
|
||||
Console.WriteLine("无法计算发射角度");
|
||||
return (null, null);
|
||||
}
|
||||
|
||||
double bestAngle = Math.Min(angles[0], angles[1]);
|
||||
double azimuth = Math.Atan2(dz, dx);
|
||||
// 计算初始速度分量
|
||||
double vx = initialSpeed * Math.Cos(bestAngle) * Math.Cos(azimuth);
|
||||
double vy = initialSpeed * Math.Sin(bestAngle);
|
||||
double vz = initialSpeed * Math.Cos(bestAngle) * Math.Sin(azimuth);
|
||||
|
||||
// 返回方向和速度
|
||||
return (new Orientation(bestAngle, azimuth, 0), new Vector3D(vx, vy, vz));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算抛物线弹道发射角度
|
||||
/// </summary>
|
||||
/// <param name="v0">初始速度(m/s)</param>
|
||||
/// <param name="x">目标点x坐标(m)</param>
|
||||
/// <param name="y">目标点y坐标(m)</param>
|
||||
/// <param name="g">重力加速度(m/s²)</param>
|
||||
/// <returns>两个可能的发射角度(弧度),如果无解则返回null</returns>
|
||||
public static double[]? CalculateLaunchAngles(double v0, double x, double y, double g = 9.81)
|
||||
{
|
||||
double v0_2 = v0 * v0;
|
||||
double v0_4 = v0_2 * v0_2;
|
||||
|
||||
double discriminant = v0_4 - g * (g * x * x + 2 * y * v0_2);
|
||||
|
||||
Console.WriteLine($"判别式: {discriminant}");
|
||||
|
||||
if (discriminant < 0)
|
||||
{
|
||||
Console.WriteLine("无实数解 - 目标不可达");
|
||||
return null;
|
||||
}
|
||||
|
||||
double angle1 = Math.Atan((v0_2 + Math.Sqrt(discriminant)) / (g * x));
|
||||
double angle2 = Math.Atan((v0_2 - Math.Sqrt(discriminant)) / (g * x));
|
||||
|
||||
//Console.WriteLine($"计算得到的两个角度: {angle1 * 180 / Math.PI:F2}° 和 {angle2 * 180 / Math.PI:F2}°");
|
||||
|
||||
return new[] { angle1, angle2 };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用运动学定律计算导弹运动状态,用于无制导状态(无制导时,使用该方法可以降低计算量)
|
||||
/// </summary>
|
||||
/// <param name="currentPosition">当前位置</param>
|
||||
/// <param name="currentVelocity">当前速度</param>
|
||||
/// <param name="acceleration">加速度(通常包含重力加速度)</param>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
/// <returns>包含新位置和新速度的元组</returns>
|
||||
public static (Vector3D newPosition, Vector3D newVelocity) CalculateBallisticMotion(
|
||||
Vector3D currentPosition,
|
||||
Vector3D currentVelocity,
|
||||
Vector3D acceleration,
|
||||
double deltaTime)
|
||||
{
|
||||
// 使用标准运动学方程
|
||||
Vector3D newPosition = new(
|
||||
currentPosition.X + currentVelocity.X * deltaTime + 0.5 * acceleration.X * deltaTime * deltaTime,
|
||||
currentPosition.Y + currentVelocity.Y * deltaTime + 0.5 * acceleration.Y * deltaTime * deltaTime,
|
||||
currentPosition.Z + currentVelocity.Z * deltaTime + 0.5 * acceleration.Z * deltaTime * deltaTime
|
||||
);
|
||||
|
||||
Vector3D newVelocity = new(
|
||||
currentVelocity.X + acceleration.X * deltaTime,
|
||||
currentVelocity.Y + acceleration.Y * deltaTime,
|
||||
currentVelocity.Z + acceleration.Z * deltaTime
|
||||
);
|
||||
|
||||
return (newPosition, newVelocity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用四阶龙格库塔法计算物体运动状态,用于有制导状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
/// <param name="position">导弹位置</param>
|
||||
/// <param name="velocity">导弹速度</param>
|
||||
/// <param name="acceleration">导弹加速度</param>
|
||||
/// <returns>新的位置和速度</returns>
|
||||
public static (Vector3D newPosition, Vector3D newVelocity) RungeKutta4(double deltaTime, Vector3D position, Vector3D velocity, Vector3D acceleration)
|
||||
{
|
||||
// 定义一个局部函数来计算加速度
|
||||
Vector3D AccelerationFunction(Vector3D pos, Vector3D vel)
|
||||
{
|
||||
// 这里可以添加更复杂的加速度计算,比如考虑空气阻力等
|
||||
return acceleration;
|
||||
}
|
||||
|
||||
// 第一步
|
||||
Vector3D k1v = AccelerationFunction(position, velocity) * deltaTime;
|
||||
Vector3D k1r = velocity * deltaTime;
|
||||
|
||||
// 第二步
|
||||
Vector3D k2v = AccelerationFunction(position + k1r * 0.5, velocity + k1v * 0.5) * deltaTime;
|
||||
Vector3D k2r = (velocity + k1v * 0.5) * deltaTime;
|
||||
|
||||
// 第三步
|
||||
Vector3D k3v = AccelerationFunction(position + k2r * 0.5, velocity + k2v * 0.5) * deltaTime;
|
||||
Vector3D k3r = (velocity + k2v * 0.5) * deltaTime;
|
||||
|
||||
// 第四步
|
||||
Vector3D k4v = AccelerationFunction(position + k3r, velocity + k3v) * deltaTime;
|
||||
Vector3D k4r = (velocity + k3v) * deltaTime;
|
||||
|
||||
// 计算新的位置和速度
|
||||
Vector3D newPosition = position + (k1r + k2r * 2 + k3r * 2 + k4r) / 6;
|
||||
Vector3D newVelocity = velocity + (k1v + k2v * 2 + k3v * 2 + k4v) / 6;
|
||||
|
||||
return (newPosition, newVelocity);
|
||||
}
|
||||
/// <summary>
|
||||
/// 计算比例导引加速度
|
||||
/// </summary>
|
||||
/// <param name="proportionalNavigationCoefficient">比例导引系数</param>
|
||||
/// <param name="missilePosition">导弹位置</param>
|
||||
/// <param name="missileVelocity">导弹速度</param>
|
||||
/// <param name="targetPosition">目标位置</param>
|
||||
/// <param name="targetVelocity">目标速度</param>
|
||||
/// <returns>比例导引加速度</returns>
|
||||
public static Vector3D CalculateProportionalNavigation(double proportionalNavigationCoefficient, Vector3D missilePosition, Vector3D missileVelocity, Vector3D targetPosition, Vector3D targetVelocity)
|
||||
{
|
||||
// 预测时间(预测目标前进方向该时间后到达的位置,可以调整)
|
||||
double predictionTime = 0.01;
|
||||
|
||||
// 预测目标位置
|
||||
Vector3D predictedTargetPosition = targetPosition + targetVelocity * predictionTime;
|
||||
|
||||
Vector3D r = predictedTargetPosition - missilePosition;
|
||||
Vector3D v = targetVelocity - missileVelocity;
|
||||
|
||||
Vector3D LOS = r.Normalize();
|
||||
Vector3D LOSRate = (v - (LOS * Vector3D.DotProduct(v, LOS))) / r.Magnitude();
|
||||
|
||||
Vector3D acceleration = Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), missileVelocity.Normalize()) * proportionalNavigationCoefficient * missileVelocity.Magnitude();
|
||||
|
||||
return acceleration;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user