重构了代码结构, 对事件调度进行了优化, 对导弹的制导算法进行了优化

This commit is contained in:
Tian jianyong 2024-10-19 08:33:31 +08:00
parent f574c1be6b
commit e14978c785
26 changed files with 471 additions and 579 deletions

BIN
Models/.DS_Store vendored

Binary file not shown.

View File

@ -0,0 +1,10 @@
{
"folders": [
{
"path": "../../ActiveProtect.Tests"
},
{
"path": ".."
}
]
}

View File

@ -52,9 +52,6 @@ namespace ActiveProtect.Models
Vector3D acceleration = Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), missileVelocity.Normalize()) * ProportionalNavigationCoefficient * missileVelocity.Magnitude();
// 添加调试输出
Console.WriteLine($"PN Calculation: r = {r}, v = {v}, LOS = {LOS}, LOSRate = {LOSRate}, Acceleration = {acceleration}");
return acceleration;
}

View File

@ -45,9 +45,7 @@ namespace ActiveProtect.Models
public override void Update(double deltaTime)
{
if (!IsActive) return;
if (IsBeamOn)
if (IsActive && IsBeamOn)
{
// 更新驾束仪的激光指向
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
@ -92,11 +90,9 @@ namespace ActiveProtect.Models
public void StartBeamIllumination()
{
if (IsBeamOn) return;
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
if (!IsBeamOn)
{
LaserDirection = (target.Position - Position).Normalize();
LaserDirection = (SimulationManager.GetEntityById(TargetId).Position - Position).Normalize();
IsBeamOn = true;
PublishLaserBeamStartEvent();
}
@ -104,11 +100,12 @@ namespace ActiveProtect.Models
public void StopBeamIllumination()
{
if (!IsBeamOn) return;
IsBeamOn = false;
LaserDirection = Vector3D.Zero;
PublishLaserBeamStopEvent();
if (IsBeamOn)
{
IsBeamOn = false;
LaserDirection = Vector3D.Zero;
PublishLaserBeamStopEvent();
}
}
/// <summary>
@ -118,32 +115,31 @@ namespace ActiveProtect.Models
{
PublishEvent(new LaserBeamStartEvent
{
SourcePosition = Position,
LaserDirection = LaserDirection,
LaserPower = LaserPower
});
}
private void PublishLaserBeamStopEvent()
{
PublishEvent(new LaserBeamStopEvent
{
SourcePosition = Position,
LaserDirection = LaserDirection,
LaserPower = LaserPower
LaserBeamRider = this
});
}
/// <summary>
/// 发布激光束更新事件
/// </summary>
private void PublishLaserBeamUpdateEvent()
{
PublishEvent(new LaserBeamUpdateEvent
{
SourcePosition = Position,
LaserDirection = LaserDirection,
LaserPower = LaserPower
LaserBeamRider = this
});
}
/// <summary>
/// 发布激光束停止事件
/// </summary>
private void PublishLaserBeamStopEvent()
{
PublishEvent(new LaserBeamStopEvent
{
LaserBeamRider = this
});
}
public override string GetStatus()
{

View File

@ -9,7 +9,7 @@ namespace ActiveProtect.Models
public double LaserPower { get; set; }
private const double MinDetectablePower = 1e-3; // 假设最小可探测功率为1毫瓦
private const double DetectorDiameter = 0.1; // 假设探测器直径为10厘米
private const double ControlFieldDiameter = 6.0; // 控制场直径(米)
private const double ControlFieldDiameter = 20.0; // 控制场直径(米)
private Vector3D LastError = Vector3D.Zero;
@ -28,19 +28,26 @@ namespace ActiveProtect.Models
LastGuidanceCommand = Vector3D.Zero;
}
public void UpdateLaserBeamRider(Vector3D sourcePosition, Vector3D direction)
public void ActivateLaserBeam(Vector3D sourcePosition, Vector3D direction, double laserPower)
{
LaserSourcePosition = sourcePosition;
LaserDirection = direction.Normalize();
}
public void ActivateLaserBeam()
{
LaserPower = laserPower;
HasGuidance = true;
}
public void DeactivateLaserBeam()
public void UpdateLaserBeamRider(Vector3D sourcePosition, Vector3D direction, double laserPower)
{
LaserSourcePosition = sourcePosition;
LaserDirection = direction.Normalize();
LaserPower = laserPower;
}
public void DeactivateLaserBeam(Vector3D sourcePosition, Vector3D direction)
{
LaserSourcePosition = Vector3D.Zero;
LaserDirection = Vector3D.Zero;
LaserPower = 0;
HasGuidance = false;
}
@ -58,8 +65,6 @@ namespace ActiveProtect.Models
{
GuidanceCommand = Vector3D.Zero;
}
Console.WriteLine($"Missile Position: {Position}, Velocity: {Velocity}, Has Guidance: {HasGuidance}");
}
private void UpdateGuidanceStatus()
@ -76,7 +81,7 @@ namespace ActiveProtect.Models
return;
}
//Console.WriteLine($"激光驾束引导系统: 在控制场内, 距离: {shortestDistance}");
Console.WriteLine($"激光驾束引导系统: 在控制场内, 距离: {shortestDistance}");
// 计算接收到的激光功率
double beamArea = Math.PI * Math.Pow(ControlFieldDiameter / 2, 2);
@ -103,15 +108,13 @@ namespace ActiveProtect.Models
}
// 计算导弹到激光束的最短距离
Vector3D shortestDistanceVector = CalculateShortestDistanceToLaserBeam();
// PID控制
double Kp = 30; // 增加比例系数,使系统对误差更敏感,反应更快
double Ki = 0.05; // 减小积分系数,减少长期误差累积的影响
double Kd = 5; // 增加微分系数,减少系统的超调量,提高稳定性
double Kc = 0.5; // 减小非线性增益系数, 控制偏移量, 使得在更小的误差范围内有更大的修正
double Kp = 30; // 增加比例系数,使系统对误差更敏感,反应更快 30
double Ki = 0.05; // 减小积分系数,减少长期误差累积的影响 0.05
double Kd = 5; // 增加微分系数,减少系统的超调量,提高稳定性 5
double Kc = 0.5; // 减小非线性增益系数, 控制偏移量, 使得在更小的误差范围内有更大的修正 0.5
// 计算误差
Vector3D error = shortestDistanceVector;
@ -133,7 +136,7 @@ namespace ActiveProtect.Models
Vector3D lateralAcceleration = pidOutput * nonLinearGain;
// 限制最大加速度
double maxAcceleration = 30; // 稍微增加最大加速度
double maxAcceleration = 50; // 稍微增加最大加速度 50
if (lateralAcceleration.Magnitude() > maxAcceleration)
{
lateralAcceleration = lateralAcceleration.Normalize() * maxAcceleration;
@ -157,7 +160,12 @@ namespace ActiveProtect.Models
LastError = error;
LastGuidanceCommand = GuidanceCommand;
Console.WriteLine($"Guidance Command: {GuidanceCommand.Magnitude()}, Lateral Error: {shortestDistanceVector.Magnitude()}, Lateral Acceleration: {lateralAcceleration.Magnitude()}, Forward Acceleration: {forwardAcceleration.Magnitude()}");
Console.WriteLine($"Current Position: {Position}");
Console.WriteLine($"Laser Source Position: {LaserSourcePosition}");
Console.WriteLine($"Laser Direction: {LaserDirection}");
Console.WriteLine($"Shortest Distance Vector: {shortestDistanceVector}");
//Console.WriteLine($"Guidance Command: {GuidanceCommand.Magnitude()}, Lateral Error: {shortestDistanceVector.Magnitude()}, Lateral Acceleration: {lateralAcceleration.Magnitude()}, Forward Acceleration: {forwardAcceleration.Magnitude()}");
}
public override string ToString()

View File

@ -23,21 +23,17 @@ namespace ActiveProtect.Models
private void OnLaserBeamStart(LaserBeamStartEvent evt)
{
LaserBeamRiderGuidanceSystem.ActivateLaserBeam();
LaserBeamRiderGuidanceSystem.UpdateLaserBeamRider(evt.SourcePosition, evt.LaserDirection);
LaserBeamRiderGuidanceSystem.LaserPower = evt.LaserPower;
}
private void OnLaserBeamStop(LaserBeamStopEvent evt)
{
LaserBeamRiderGuidanceSystem.DeactivateLaserBeam();
LaserBeamRiderGuidanceSystem.LaserPower = 0;
LaserBeamRiderGuidanceSystem.ActivateLaserBeam(evt.LaserBeamRider.Position, evt.LaserBeamRider.LaserDirection, evt.LaserBeamRider.LaserPower);
}
private void OnLaserBeamUpdate(LaserBeamUpdateEvent evt)
{
LaserBeamRiderGuidanceSystem.UpdateLaserBeamRider(evt.SourcePosition, evt.LaserDirection);
LaserBeamRiderGuidanceSystem.LaserPower = evt.LaserPower;
LaserBeamRiderGuidanceSystem.UpdateLaserBeamRider(evt.LaserBeamRider.Position, evt.LaserBeamRider.LaserDirection, evt.LaserBeamRider.LaserPower);
}
private void OnLaserBeamStop(LaserBeamStopEvent evt)
{
LaserBeamRiderGuidanceSystem.DeactivateLaserBeam(evt.LaserBeamRider.Position, evt.LaserBeamRider.LaserDirection);
}
public override void Update(double deltaTime)

View File

@ -28,15 +28,21 @@ namespace ActiveProtect.Models
/// </summary>
public bool IsJammed { get; private set; } = false;
/// <summary>
/// 最大照射范围(米)
/// </summary>
public double MaxIlluminationRange { get; private set; }
/// <summary>
/// 是否正在照射
/// </summary>
private bool IsIlluminating { get; set; } = false;
public bool IlluminationOn { get; private set; } = false;
/// <summary>
/// 激光功率
/// </summary>
public double LaserPower { get; private set; } = 0;
/// <summary>
/// 激光发散角
/// </summary>
public double LaserDivergenceAngle { get; private set; } = 0;
/// <summary>
/// 构造函数
@ -51,10 +57,10 @@ namespace ActiveProtect.Models
{
TargetId = targetId;
MissileId = missileId;
IsActive = true;
MaxIlluminationRange = config.MaxIlluminationRange;
SimulationManager.SubscribeToEvent<LaserJammingEvent>(OnLaserJamming);
SimulationManager.SubscribeToEvent<EntityDeactivatedEvent>(OnEntityDeactivatedEvent);
IsActive = false;
IlluminationOn = false;
LaserPower = config.LaserPower;
LaserDivergenceAngle = config.LaserDivergenceAngle;
}
/// <summary>
@ -65,73 +71,37 @@ namespace ActiveProtect.Models
{
if (IsActive && !IsJammed)
{
UpdateIllumination();
}
else if (IsIlluminating)
{
StopIllumination();
}
}
/// <summary>
/// 更新照射状态
/// </summary>
private void UpdateIllumination()
{
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
{
double distanceToTarget = Vector3D.Distance(Position, target.Position);
bool shouldIlluminate = distanceToTarget <= MaxIlluminationRange;
Console.WriteLine($"激光目标指示器 {Id} 状态更新:");
Console.WriteLine($" 目标: {TargetId}");
Console.WriteLine($" 距离目标: {distanceToTarget:F2} m (最大照射范围: {MaxIlluminationRange} m)");
Console.WriteLine($" 是否应该照射: {shouldIlluminate}");
Console.WriteLine($" 当前照射状态: {IsIlluminating}");
if (shouldIlluminate && !IsIlluminating)
if (IlluminationOn)
{
StartIllumination(target);
}
else if (!shouldIlluminate && IsIlluminating)
{
StopIllumination();
}
}
else
{
Console.WriteLine($"激光目标指示器 {Id} 无法找到目标 {TargetId}");
if (IsIlluminating)
{
StopIllumination();
PublishIlluminationUpdateEvent();
}
}
}
/// <summary>
/// 开始照射目标
/// 开始激光照射
/// </summary>
/// <param name="target">目标</param>
private void StartIllumination(ILaserIlluminatable target)
private void StartLaserIllumination()
{
target.Illuminate();
IsIlluminating = true;
Console.WriteLine($"激光目标指示器 {Id} 开始照射目标 {TargetId}");
PublishIlluminationEvent();
if (!IlluminationOn)
{
IlluminationOn = true;
Console.WriteLine($"激光目标指示器 {Id} 开始照射目标 {TargetId}");
PublishIlluminationStartEvent();
}
}
/// <summary>
/// 停止照射目标
/// 停止激光照射
/// </summary>
private void StopIllumination()
private void StopLaserIllumination()
{
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
if (IlluminationOn)
{
target.StopIllumination();
IlluminationOn = false;
Console.WriteLine($"激光目标指示器 {Id} 停止照射目标 {TargetId}");
PublishIlluminationStopEvent();
}
IsIlluminating = false;
Console.WriteLine($"激光目标指示器 {Id} 停止照射目标 {TargetId}");
PublishIlluminationStopEvent();
}
/// <summary>
@ -156,7 +126,7 @@ namespace ActiveProtect.Models
{
Console.WriteLine($"激光目标指示器 {Id} 被干扰,停止工作");
IsJammed = true;
StopIllumination();
StopLaserIllumination();
}
}
else
@ -181,7 +151,9 @@ namespace ActiveProtect.Models
IsActive = true;
IsJammed = false;
Console.WriteLine($"激光目标指示器 {Id} 已激活");
UpdateIllumination();
StartLaserIllumination();
SimulationManager.SubscribeToEvent<LaserJammingEvent>(OnLaserJamming);
SimulationManager.SubscribeToEvent<EntityDeactivatedEvent>(OnEntityDeactivatedEvent);
}
base.Activate();
}
@ -194,8 +166,10 @@ namespace ActiveProtect.Models
if (IsActive)
{
IsActive = false;
StopIllumination();
StopLaserIllumination();
Console.WriteLine($"激光目标指示器 {Id} 已停用");
SimulationManager.UnsubscribeFromEvent<LaserJammingEvent>(OnLaserJamming);
SimulationManager.UnsubscribeFromEvent<EntityDeactivatedEvent>(OnEntityDeactivatedEvent);
}
base.Deactivate();
}
@ -203,15 +177,21 @@ namespace ActiveProtect.Models
/// <summary>
/// 发布激光照射事件
/// </summary>
private void PublishIlluminationEvent()
private void PublishIlluminationStartEvent()
{
var evt = new LaserIlluminationEvent
{
TargetId = TargetId,
SenderId = Id
};
var evt = new LaserIlluminationStartEvent { LaserDesignator = this, Target = SimulationManager.GetEntityById(TargetId) as SimulationElement };
PublishEvent(evt);
Console.WriteLine($"激光指示器 {Id} 发布激光照射事件, 目标ID: {TargetId}");
Console.WriteLine($"激光指示器 {Id} 发布激光照射事件");
}
/// <summary>
/// 发布激光照射更新事件
/// </summary>
private void PublishIlluminationUpdateEvent()
{
var evt = new LaserIlluminationUpdateEvent { LaserDesignator = this, Target = SimulationManager.GetEntityById(TargetId) as SimulationElement };
PublishEvent(evt);
Console.WriteLine($"激光指示器 {Id} 发布激光照射更新事件");
}
/// <summary>
@ -219,13 +199,9 @@ namespace ActiveProtect.Models
/// </summary>
private void PublishIlluminationStopEvent()
{
var evt = new LaserIlluminationStopEvent
{
TargetId = TargetId,
SenderId = Id
};
var evt = new LaserIlluminationStopEvent { LaserDesignator = this, Target = SimulationManager.GetEntityById(TargetId) as SimulationElement };
PublishEvent(evt);
Console.WriteLine($"激光指示器 {Id} 发布激光照射停止事件, 目标ID: {TargetId}");
Console.WriteLine($"激光指示器 {Id} 发布激光照射停止事件");
}
/// <summary>
@ -236,7 +212,7 @@ namespace ActiveProtect.Models
{
if (evt.DeactivatedEntityId == TargetId || evt.DeactivatedEntityId == MissileId)
{
Deactivate();
StopLaserIllumination();
}
}
@ -251,9 +227,9 @@ namespace ActiveProtect.Models
$" 目标: {TargetId}\n" +
$" 导弹: {MissileId}\n" +
$" 激活状态: {(IsActive ? "" : "")}\n" +
$" 照射状态: {(IsIlluminating ? "" : "")}\n" +
$" 照射状态: {(IlluminationOn ? "" : "")}\n" +
$" 干扰状态: {(IsJammed ? "" : "")}\n" +
$" 最大照射范围: {MaxIlluminationRange}";
$" 激光功率: {LaserPower:E} W";
}
}
}

View File

@ -4,22 +4,17 @@ namespace ActiveProtect.Models
{
public class LaserSemiActiveGuidanceSystem : BasicGuidanceSystem
{
private const double LaserLockDistance = 1500; // 最大锁定距离(米)
private const double FieldOfViewAngle = Math.PI / 6; // 30度视场角
private const double DetectorDiameter = 0.1; // 探测器直径(米)
private const double FocusedSpotDiameter = 0.003; // 聚焦后光斑直径(米)
private const double LaserEnergy = 0.13; // 激光能量(焦耳)
private const double PulseWidth = 15e-9; // 脉冲宽度(秒)
private const double PulseRepetitionFrequency = 10; // 脉冲重复频率(赫兹)
private const double ReflectionCoefficient = 0.2; // 反射系数
private const double LockThreshold = 1e-12; // 锁定阈值(瓦特)
private bool IsTargetIlluminated { get; set; }
private const double TargetReflectiveArea = 1.0; // 目标有效反射面积(平方米)
private Vector3D TargetPosition { get; set; }
private Vector3D TargetVelocity { get; set; }
private Vector3D LaserDesignatorPosition { get; set; }
private double FlightTime { get; set; }
private double LaserPower { get; set; }
private double LaserDivergenceAngle { get; set; }
public LaserSemiActiveGuidanceSystem(double proportionalNavigationCoefficient, Vector3D initialMissilePosition, Vector3D initialTargetPosition, Vector3D initialTargetVelocity)
: base(proportionalNavigationCoefficient)
{
@ -27,33 +22,43 @@ namespace ActiveProtect.Models
TargetPosition = initialTargetPosition;
TargetVelocity = initialTargetVelocity;
LaserDesignatorPosition = Vector3D.Zero;
FlightTime = 0;
LaserPower = 0;
}
public void SetTargetIllumination(bool isIlluminated)
public void ActivateLaserDesignator(Vector3D sourcePosition, Vector3D targetPosition, Vector3D targetVelocity, double laserPower, double laserDivergenceAngle)
{
IsTargetIlluminated = isIlluminated;
HasGuidance = true;
LaserDesignatorPosition = sourcePosition;
TargetPosition = targetPosition;
TargetVelocity = targetVelocity;
LaserPower = laserPower;
LaserDivergenceAngle = laserDivergenceAngle;
}
public void SetTargetPosition(Vector3D position)
public void UpdateLaserDesignator(Vector3D sourcePosition, Vector3D targetPosition, Vector3D targetVelocity, double laserPower, double laserDivergenceAngle)
{
TargetPosition = position;
LaserDesignatorPosition = sourcePosition;
TargetPosition = targetPosition;
TargetVelocity = targetVelocity;
LaserPower = laserPower;
LaserDivergenceAngle = laserDivergenceAngle;
}
public void SetLaserDesignatorPosition(Vector3D position)
public void DeactivateLaserDesignator()
{
LaserDesignatorPosition = position;
HasGuidance = false;
LaserDesignatorPosition = Vector3D.Zero;
TargetPosition = Vector3D.Zero;
TargetVelocity = Vector3D.Zero;
LaserPower = 0;
LaserDivergenceAngle = 0;
}
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
{
base.Update(deltaTime, missilePosition, missileVelocity);
Position = missilePosition;
Velocity = missileVelocity;
FlightTime += deltaTime;
UpdateGuidanceStatus();
HasGuidance = CalculateReceivedLaserPower() > LockThreshold;
if (HasGuidance)
{
CalculateGuidanceCommand(deltaTime);
@ -66,37 +71,25 @@ namespace ActiveProtect.Models
PrintGuidanceInfo();
}
private void UpdateGuidanceStatus()
{
if (!IsTargetIlluminated)
{
HasGuidance = false;
return;
}
double distanceToTarget = (TargetPosition - Position).Magnitude();
if (distanceToTarget > LaserLockDistance)
{
HasGuidance = false;
return;
}
double receivedPower = CalculateReceivedLaserPower();
HasGuidance = receivedPower > LockThreshold;
}
private double CalculateReceivedLaserPower()
{
double distanceToTarget = (TargetPosition - LaserDesignatorPosition).Magnitude();
double distanceToMissile = (Position - TargetPosition).Magnitude();
// 计算激光功率(瓦特)
double laserPower = LaserEnergy / PulseWidth;
// 计算激光能量衰减
double powerAtTarget = laserPower / (4 * Math.PI * Math.Pow(distanceToTarget, 2));
double reflectedPower = powerAtTarget * ReflectionCoefficient;
double receivedPower = reflectedPower / (4 * Math.PI * Math.Pow(distanceToMissile, 2));
// 计算目标处的光斑面积
double spotAreaAtTarget = Math.PI * Math.Pow(distanceToTarget * Math.Tan(LaserDivergenceAngle), 2);
// 计算目标处的激光功率密度
double powerDensityAtTarget = LaserPower / spotAreaAtTarget;
// 计算从目标反射的总功率
double reflectedPower = powerDensityAtTarget * TargetReflectiveArea * ReflectionCoefficient;
// 计算反射光在导弹处的扩散面积(假设漫反射)
double reflectedSpotArea = 2 * Math.PI * Math.Pow(distanceToMissile, 2);
// 计算导弹接收到的功率
double receivedPower = reflectedPower / reflectedSpotArea;
// 计算探测器接收到的功率比例
double detectorArea = Math.PI * Math.Pow(DetectorDiameter / 2, 2);
@ -122,25 +115,14 @@ namespace ActiveProtect.Models
}
// 计算比例导引加速度
Vector3D proportionalNavigation = CalculateProportionalNavigation(Position, Velocity, TargetPosition, TargetVelocity);
// 计算重力补偿
Vector3D gravityCompensation = new(0, 9.81, 0);
// 合并比例导引和重力补偿
GuidanceCommand = proportionalNavigation + gravityCompensation;
GuidanceCommand = CalculateProportionalNavigation(Position, Velocity, TargetPosition, TargetVelocity);
// 限制最大加速度
double maxAcceleration = 1000; // 根据实际情况调整
double maxAcceleration = 100; // 根据实际情况调整
if (GuidanceCommand.Magnitude() > maxAcceleration)
{
GuidanceCommand = GuidanceCommand.Normalize() * maxAcceleration;
}
// 添加调试输出
// Console.WriteLine($"CalculateGuidanceCommand: Position = {Position}, Velocity = {Velocity}, TargetPosition = {TargetPosition}");
// Console.WriteLine($"ProportionalNavigation = {proportionalNavigation}, GravityCompensation = {gravityCompensation}");
// Console.WriteLine($"FinalGuidanceCommand = {GuidanceCommand}");
}
private void PrintGuidanceInfo()
@ -150,7 +132,6 @@ namespace ActiveProtect.Models
Console.WriteLine($" 速度: {Velocity}");
Console.WriteLine($" 速度大小: {Velocity.Magnitude():F2} m/s");
Console.WriteLine($" 是否有引导: {HasGuidance}");
Console.WriteLine($" 目标是否被照射: {IsTargetIlluminated}");
Console.WriteLine($" 目标位置: {TargetPosition}");
Console.WriteLine($" 制导指令: {GuidanceCommand}");
Console.WriteLine($" 接收到的激光功率: {CalculateReceivedLaserPower():E} W");

View File

@ -10,6 +10,7 @@ namespace ActiveProtect.Models
{
private LaserSemiActiveGuidanceSystem LaserGuidanceSystem;
private string LaserDesignatorId;
/// <summary>
/// 构造函数
/// </summary>
@ -17,11 +18,7 @@ namespace ActiveProtect.Models
/// <param name="laserDesignatorId">激光指示器ID</param>
/// <param name="missileConfig">导弹配置</param>
/// <param name="simulationManager">仿真管理器</param>
public LaserSemiActiveGuidedMissile(
string id,
MissileConfig missileConfig,
string laserDesignatorId,
ISimulationManager simulationManager)
public LaserSemiActiveGuidedMissile(string id, MissileConfig missileConfig, string laserDesignatorId, ISimulationManager simulationManager)
: base(id, missileConfig, simulationManager)
{
Vector3D initialTargetPosition = simulationManager.GetEntityById($"Tank_{missileConfig.TargetIndex + 1}").Position;
@ -32,24 +29,27 @@ namespace ActiveProtect.Models
initialTargetPosition,
initialTargetVelocity
);
LaserDesignatorId = laserDesignatorId;
// 订阅事件
simulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
simulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
LaserDesignatorId = laserDesignatorId;
}
/// <summary>
/// 处理激光照射事件
/// </summary>
/// <param name="evt">激光照射事件</param>
private void OnLaserIllumination(LaserIlluminationEvent evt)
private void OnLaserIlluminationStart(LaserIlluminationStartEvent evt)
{
Console.WriteLine($"激光半主动导弹 {Id} 接收到激光照射事件, 目标ID: {evt.TargetId}");
if (evt.TargetId == TargetId)
{
LaserGuidanceSystem.SetTargetIllumination(true);
}
LaserGuidanceSystem.ActivateLaserDesignator(evt.LaserDesignator.Position, evt.Target.Position, evt.Target.Velocity,
evt.LaserDesignator.LaserPower, evt.LaserDesignator.LaserDivergenceAngle);
}
/// <summary>
/// 处理激光照射更新事件
/// </summary>
/// <param name="evt">激光照射更新事件</param>
private void OnLaserIlluminationUpdate(LaserIlluminationUpdateEvent evt)
{
LaserGuidanceSystem.UpdateLaserDesignator(evt.LaserDesignator.Position, evt.Target.Position, evt.Target.Velocity,
evt.LaserDesignator.LaserPower, evt.LaserDesignator.LaserDivergenceAngle);
}
/// <summary>
@ -58,11 +58,7 @@ namespace ActiveProtect.Models
/// <param name="evt">激光照射停止事件</param>
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
{
Console.WriteLine($"激光半主动导弹 {Id} 接收到激光照射停止事件, 目标ID: {evt.TargetId}");
if (evt.TargetId == TargetId)
{
LaserGuidanceSystem.SetTargetIllumination(false);
}
LaserGuidanceSystem.DeactivateLaserDesignator();
}
/// <summary>
@ -82,7 +78,8 @@ namespace ActiveProtect.Models
public override void Activate()
{
base.Activate();
SimulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
SimulationManager.SubscribeToEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
SimulationManager.SubscribeToEvent<LaserIlluminationUpdateEvent>(OnLaserIlluminationUpdate);
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
}
@ -92,55 +89,29 @@ namespace ActiveProtect.Models
public override void Deactivate()
{
base.Deactivate();
SimulationManager.UnsubscribeFromEvent<LaserIlluminationEvent>(OnLaserIllumination);
SimulationManager.UnsubscribeFromEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
SimulationManager.UnsubscribeFromEvent<LaserIlluminationUpdateEvent>(OnLaserIlluminationUpdate);
SimulationManager.UnsubscribeFromEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
}
public override void Update(double deltaTime)
{
// base.Update(deltaTime);
// 获取目标和激光指示器的位置
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
Vector3D laserDesignatorPosition = SimulationManager.GetEntityById(LaserDesignatorId).Position;
// 更新制导系统
LaserGuidanceSystem.SetTargetPosition(targetPosition);
LaserGuidanceSystem.SetLaserDesignatorPosition(laserDesignatorPosition);
LaserGuidanceSystem.Update(deltaTime, Position, Velocity);
if (LaserGuidanceSystem.HasGuidance)
{
LaserGuidanceSystem.Update(deltaTime, Position, Velocity);
this.HasGuidance = true;
}
else
{
this.HasGuidance = false;
}
base.Update(deltaTime);
// Vector3D guidanceCommand = LaserGuidanceSystem.GetGuidanceCommand();
// // 应用重力
// Vector3D gravity = new Vector3D(0, -9.8, 0);
// // 计算总加速度
// Vector3D totalAcceleration = guidanceCommand + gravity;
// // 使用四阶龙格-库塔方法更新导弹的位置和速度
// (Position, Velocity) = BasicGuidanceSystem.RungeKutta4(deltaTime, Position, Velocity, totalAcceleration);
// // 限制速度不超过最大速度
// if (Velocity.Magnitude() > MaxSpeed)
// {
// Velocity = Velocity.Normalize() * MaxSpeed;
// }
// // 更新其他状态
// Speed = Velocity.Magnitude();
// Orientation = Orientation.FromVector(Velocity);
// FlightTime += deltaTime;
// FlightDistance += Speed * deltaTime;
// DistanceToTarget = Vector3D.Distance(Position, targetPosition);
// // 添加调试输出
// Console.WriteLine($"Missile Update: Position = {Position}, Velocity = {Velocity}, Acceleration = {totalAcceleration}, TargetPosition = {targetPosition}");
// currentStage.Update(deltaTime);
}
/// <summary>
/// 获取制导命令
/// </summary>
/// <returns>制导命令</returns>
protected override Vector3D GetGuidanceCommand()
{
return LaserGuidanceSystem.GetGuidanceCommand();

View File

@ -43,7 +43,7 @@ namespace ActiveProtect.Models
MonitoredEntityId = monitoredEntityId;
IsAlarming = false;
alarmDuration = config.AlarmDuration;
SimulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
SimulationManager.SubscribeToEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
}
@ -76,9 +76,9 @@ namespace ActiveProtect.Models
/// 处理激光照射事件
/// </summary>
/// <param name="evt">激光照射事件</param>
private void OnLaserIllumination(LaserIlluminationEvent evt)
private void OnLaserIlluminationStart(LaserIlluminationStartEvent evt)
{
if (evt.TargetId == MonitoredEntityId)
if (evt.Target.Id == MonitoredEntityId)
{
TriggerAlarm();
}
@ -90,7 +90,7 @@ namespace ActiveProtect.Models
/// <param name="evt">激光照射停止事件</param>
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
{
if (evt.TargetId == MonitoredEntityId)
if (evt.Target.Id == MonitoredEntityId)
{
StopAlarm();
}
@ -142,7 +142,7 @@ namespace ActiveProtect.Models
public override void Activate()
{
base.Activate();
SimulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
SimulationManager.SubscribeToEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
}
@ -152,7 +152,7 @@ namespace ActiveProtect.Models
public override void Deactivate()
{
base.Deactivate();
SimulationManager.UnsubscribeFromEvent<LaserIlluminationEvent>(OnLaserIllumination);
SimulationManager.UnsubscribeFromEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
SimulationManager.UnsubscribeFromEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
}
}

View File

@ -272,16 +272,16 @@ namespace ActiveProtect.Models
guidanceAcceleration = guidanceCommand;
break;
case FlightStage.Cruise:
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.1);
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.05);
guidanceAcceleration = guidanceCommand * 1;
break;
case FlightStage.TerminalGuidance:
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.2);
guidanceAcceleration = guidanceCommand * 1.2;
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.05);
guidanceAcceleration = guidanceCommand * 1;
break;
case FlightStage.Attack:
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
guidanceAcceleration = guidanceCommand * 1.5;
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration*0.05;
guidanceAcceleration = guidanceCommand * 1;
break;
}
@ -297,13 +297,16 @@ namespace ActiveProtect.Models
}
}
//计算重力加速度(反坦克导弹一般升力很小, 主要依靠初始发射动能和持续的推力来维持飞行)
//Vector3D gravityCompensation = new(0, 9.81, 0);
Vector3D gravityAcceleration = new(0, -9.81, 0);
// 计算空气阻力的影响
Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / Mass;
Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration + gravityAcceleration +dragAcceleration;
//Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration +dragAcceleration;
Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration + dragAcceleration;
//Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {guidanceAcceleration}, 推力加速度: {thrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {guidanceAcceleration}, 推力加速度: {thrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
if (totalAcceleration.Magnitude() > MaxAcceleration)
{
totalAcceleration = totalAcceleration.Normalize() * MaxAcceleration;
@ -377,63 +380,63 @@ namespace ActiveProtect.Models
/// <summary>
/// 计算导弹的加速度
/// </summary>
private (Vector3D, Vector3D) CalculateDerivatives_RK4(Vector3D position, Vector3D velocity, double deltaTime)
{
Vector3D guidanceAcceleration = Vector3D.Zero;
Vector3D thrustAcceleration = Vector3D.Zero;
// private (Vector3D, Vector3D) CalculateDerivatives_RK4(Vector3D position, Vector3D velocity, double deltaTime)
// {
// Vector3D guidanceAcceleration = Vector3D.Zero;
// Vector3D thrustAcceleration = Vector3D.Zero;
switch (CurrentStage)
{
case FlightStage.Launch:
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
break;
case FlightStage.Acceleration:
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
guidanceAcceleration = CalculateProportionalNavigation(position);
break;
case FlightStage.Cruise:
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.1);
guidanceAcceleration = CalculateProportionalNavigation(position) * 0.5;
break;
case FlightStage.TerminalGuidance:
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.1);
guidanceAcceleration = CalculateProportionalNavigation(position) * 1.5;
break;
case FlightStage.Attack:
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
guidanceAcceleration = CalculateProportionalNavigation(position) * 2;
break;
}
// switch (CurrentStage)
// {
// case FlightStage.Launch:
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
// break;
// case FlightStage.Acceleration:
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
// guidanceAcceleration = CalculateProportionalNavigation(position);
// break;
// case FlightStage.Cruise:
// thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.1);
// guidanceAcceleration = CalculateProportionalNavigation(position) * 0.5;
// break;
// case FlightStage.TerminalGuidance:
// thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.1);
// guidanceAcceleration = CalculateProportionalNavigation(position) * 1.5;
// break;
// case FlightStage.Attack:
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
// guidanceAcceleration = CalculateProportionalNavigation(position) * 2;
// break;
// }
if (!HasGuidance)
{
guidanceAcceleration = Vector3D.Zero;
if (velocity.Magnitude() > 0)
{
thrustAcceleration = velocity.Normalize() * ThrustAcceleration;
}
else
{
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
}
}
// if (!HasGuidance)
// {
// guidanceAcceleration = Vector3D.Zero;
// if (velocity.Magnitude() > 0)
// {
// thrustAcceleration = velocity.Normalize() * ThrustAcceleration;
// }
// else
// {
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
// }
// }
// 计算空气阻力的影响
Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / Mass;
// // 计算空气阻力的影响
// Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / Mass;
// 计算重力加速度
Vector3D gravityCompensation = new(0, 9.81, 0);
Vector3D gravityAcceleration = new(0, -9.81, 0);
// // 计算重力加速度(反坦克导弹一般升力很小, 主要依靠初始发射动能和持续的推力来维持飞行)
// //Vector3D gravityCompensation = new(0, 9.81, 0);
// Vector3D gravityAcceleration = new(0, -9.81, 0);
Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration + gravityCompensation + gravityAcceleration + dragAcceleration;
// Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration + gravityAcceleration + dragAcceleration;
if (totalAcceleration.Magnitude() > MaxAcceleration)
{
totalAcceleration = totalAcceleration.Normalize() * MaxAcceleration;
}
// if (totalAcceleration.Magnitude() > MaxAcceleration)
// {
// totalAcceleration = totalAcceleration.Normalize() * MaxAcceleration;
// }
return (velocity, totalAcceleration);
}
// return (velocity, totalAcceleration);
// }
/// <summary>
/// 计算空气阻力
@ -447,31 +450,6 @@ namespace ActiveProtect.Models
return 0.5 * dragCoefficient * airDensity * referenceArea * speed * speed;
}
/// <summary>
/// 使用 Runge-Kutta 方法更新位置和速度
/// </summary>
// private (Vector3D, Vector3D) UpdatePositionAndVelocityRK4(double deltaTime)
// {
// Vector3D k1, k2, k3, k4;
// Vector3D v1, v2, v3, v4;
// (k1, v1) = CalculateDerivatives(Position, Velocity, deltaTime);
// (k2, v2) = CalculateDerivatives(Position + k1 * (deltaTime / 2), Velocity + v1 * (deltaTime / 2), deltaTime / 2);
// (k3, v3) = CalculateDerivatives(Position + k2 * (deltaTime / 2), Velocity + v2 * (deltaTime / 2), deltaTime / 2);
// (k4, v4) = CalculateDerivatives(Position + k3 * deltaTime, Velocity + v3 * deltaTime, deltaTime);
// Vector3D newPosition = Position + (k1 + k2 * 2 + k3 * 2 + k4) * (deltaTime / 6);
// Vector3D newVelocity = Velocity + (v1 + v2 * 2 + v3 * 2 + v4) * (deltaTime / 6);
// // 限制速度不超过最大速度
// if (newVelocity.Magnitude() > MaxSpeed)
// {
// newVelocity = newVelocity.Normalize() * MaxSpeed;
// }
// return (newPosition, newVelocity);
// }
/// <summary>
/// 检查是否命中目标
/// </summary>
@ -614,132 +592,7 @@ namespace ActiveProtect.Models
}
/// <summary>
/// 导弹飞行阶段策略接口
/// </summary>
public interface IMissileStageStrategy
{
void Update(double deltaTime);
}
/// <summary>
/// 发射阶段策略
/// </summary>
public class LaunchStageStrategy : IMissileStageStrategy
{
private readonly MissileBase missile;
private double launchTime = 0;
public LaunchStageStrategy(MissileBase missile)
{
this.missile = missile;
}
public void Update(double deltaTime)
{
launchTime += deltaTime;
if (launchTime >= MissileBase.LAUNCH_DURATION || missile.Speed >= missile.MaxSpeed * 0.1)
{
missile.ChangeStage(FlightStage.Acceleration);
}
}
}
/// <summary>
/// 加速阶段策略
/// </summary>
public class AccelerationStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
if (missile.EngineBurnTime >= missile.MaxEngineBurnTime || missile.Speed >= missile.MaxSpeed)
{
missile.ChangeStage(FlightStage.Cruise);
}
}
}
/// <summary>
/// 巡航阶段策略
/// </summary>
public class CruiseStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
if (missile.DistanceToTarget <= missile.DistanceParams.TerminalGuidanceDistance)
{
missile.ChangeStage(FlightStage.TerminalGuidance);
}
}
}
/// <summary>
/// 终端制导阶段策略
/// </summary>
public class TerminalGuidanceStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
if (missile.DistanceToTarget <= missile.DistanceParams.AttackDistance)
{
missile.ChangeStage(FlightStage.Attack);
}
}
}
/// <summary>
/// 攻击阶段策略
/// </summary>
public class AttackStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
if (missile.DistanceToTarget <= missile.DistanceParams.ExplosionDistance)
{
missile.Explode();
}
}
}
/// <summary>
/// 无制导阶段策略
/// </summary>
public class UnguidedStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
// 检查是否重新获得引导
if (missile.HasGuidance)
{
Console.WriteLine($"导弹 {missile.Id} 重新获得引导,退出无制导阶段");
if (missile.DistanceToTarget <= missile.DistanceParams.AttackDistance)
{
missile.ChangeStage(FlightStage.Attack);
}
else if (missile.DistanceToTarget <= missile.DistanceParams.TerminalGuidanceDistance)
{
missile.ChangeStage(FlightStage.TerminalGuidance);
}
else
{
missile.ChangeStage(FlightStage.Cruise);
}
}
}
}
/// <summary>
/// 表示导弹的当前状态
/// 表示导弹的运行状态信息
/// </summary>
public struct MissileRunningState
{

View File

@ -0,0 +1,140 @@
namespace ActiveProtect.Models
{
/// <summary>
/// 导弹飞行阶段枚举
/// </summary>
public enum FlightStage
{
Launch, // 发射阶段
Acceleration, // 加速阶段
Cruise, // 巡航阶段
TerminalGuidance, // 终端制导阶段
Attack, // 攻击阶段
Explosion, // 爆炸阶段
}
/// <summary>
/// 导弹飞行阶段策略接口
/// </summary>
public interface IMissileStageStrategy
{
void Update(double deltaTime);
}
/// <summary>
/// 发射阶段策略
/// </summary>
public class LaunchStageStrategy : IMissileStageStrategy
{
private readonly MissileBase missile;
private double launchTime = 0;
public LaunchStageStrategy(MissileBase missile)
{
this.missile = missile;
}
public void Update(double deltaTime)
{
launchTime += deltaTime;
if (launchTime >= MissileBase.LAUNCH_DURATION || missile.Speed >= missile.MaxSpeed * 0.1)
{
missile.ChangeStage(FlightStage.Acceleration);
}
}
}
/// <summary>
/// 加速阶段策略
/// </summary>
public class AccelerationStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
if (missile.EngineBurnTime >= missile.MaxEngineBurnTime || missile.Speed >= missile.MaxSpeed)
{
missile.ChangeStage(FlightStage.Cruise);
}
}
}
/// <summary>
/// 巡航阶段策略
/// </summary>
public class CruiseStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
if (missile.DistanceToTarget <= missile.DistanceParams.TerminalGuidanceDistance)
{
missile.ChangeStage(FlightStage.TerminalGuidance);
}
}
}
/// <summary>
/// 终端制导阶段策略
/// </summary>
public class TerminalGuidanceStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
if (missile.DistanceToTarget <= missile.DistanceParams.AttackDistance)
{
missile.ChangeStage(FlightStage.Attack);
}
}
}
/// <summary>
/// 攻击阶段策略
/// </summary>
public class AttackStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
if (missile.DistanceToTarget <= missile.DistanceParams.ExplosionDistance)
{
missile.Explode();
}
}
}
/// <summary>
/// 无制导阶段策略
/// </summary>
public class UnguidedStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
// 检查是否重新获得引导
if (missile.HasGuidance)
{
Console.WriteLine($"导弹 {missile.Id} 重新获得引导,退出无制导阶段");
if (missile.DistanceToTarget <= missile.DistanceParams.AttackDistance)
{
missile.ChangeStage(FlightStage.Attack);
}
else if (missile.DistanceToTarget <= missile.DistanceParams.TerminalGuidanceDistance)
{
missile.ChangeStage(FlightStage.TerminalGuidance);
}
else
{
missile.ChangeStage(FlightStage.Cruise);
}
}
}
}
}

View File

@ -6,7 +6,8 @@ namespace ActiveProtect.Models
/// <summary>
/// 表示仿真中的坦克
/// </summary>
public class Tank(string id, TankConfig tankConfig, ISimulationManager simulationManager) : SimulationElement(id, tankConfig.InitialPosition, tankConfig.InitialOrientation, simulationManager), ILaserIlluminatable
public class Tank(string id, TankConfig tankConfig, ISimulationManager simulationManager)
: SimulationElement(id, tankConfig.InitialPosition, tankConfig.InitialOrientation, simulationManager)
{
/// <summary>
/// 当前速度(米/秒)
@ -28,11 +29,6 @@ namespace ActiveProtect.Models
/// </summary>
public double CurrentArmor { get; private set; } = tankConfig.MaxArmor;
/// <summary>
/// 是否被激光照射
/// </summary>
public bool IsIlluminated { get; private set; } = false;
/// <summary>
/// 更新坦克状态
/// </summary>
@ -74,30 +70,6 @@ namespace ActiveProtect.Models
}
}
/// <summary>
/// 被激光照射
/// </summary>
public void Illuminate()
{
if (!IsIlluminated)
{
IsIlluminated = true;
Console.WriteLine($"坦克 {Id} 被激光照射");
}
}
/// <summary>
/// 停止激光照射
/// </summary>
public void StopIllumination()
{
if (IsIlluminated)
{
IsIlluminated = false;
Console.WriteLine($"坦克 {Id} 激光照射停止");
}
}
/// <summary>
/// 获取坦克状态信息
/// </summary>
@ -108,8 +80,7 @@ namespace ActiveProtect.Models
$" 位置: {Position}\n" +
$" 速度: {Speed:F2}/{MaxSpeed:F2}\n" +
$" 装甲: {CurrentArmor:F2}/{MaxArmor:F2}\n" +
$" 状态: {(IsActive ? "" : "")}\n" +
$" 激光照射: {(IsIlluminated ? "" : "")}\n";
$" 状态: {(IsActive ? "" : "")}\n";
}
}
}

View File

@ -46,8 +46,9 @@ namespace ActiveProtect
// 配置激光指示器
LaserDesignatorConfig = new LaserDesignatorConfig
{
InitialPosition = new Vector3D(500, 150, 100),
MaxIlluminationRange = 1000
InitialPosition = new Vector3D(2000, 150, 100),
LaserPower = 1e6,
LaserDivergenceAngle = 0.01
},
// 配置激光告警器
LaserWarnerConfig = new LaserWarnerConfig
@ -67,8 +68,7 @@ namespace ActiveProtect
{
InitialPosition = new Vector3D(2000, 10, 100),
LaserPower = 1000,
ControlFieldDiameter = 6,
MaxGuidanceDistance = 5000
ControlFieldDiameter = 6
},
// 配置导弹
MissileConfigs =
@ -131,7 +131,7 @@ namespace ActiveProtect
InitialSpeed = 700,
MaxSpeed = 800,
TargetIndex = 0,
MaxFlightTime = 10, // 增加最大飞行时间
MaxFlightTime = 0.5, // 增加最大飞行时间
MaxFlightDistance = 5000,
ThrustAcceleration = 50, // 添加推力加速度
MaxEngineBurnTime = 10,
@ -145,7 +145,7 @@ namespace ActiveProtect
// 激光驾束制导导弹配置
new() {
InitialPosition = new Vector3D(2000, 10, 100),
InitialOrientation = new Orientation(Math.PI, 0.02, 0.0), // 调整初始俯仰角
InitialOrientation = new Orientation(Math.PI, 0.1, 0.0), // 调整初始俯仰角
InitialSpeed = 300,
MaxSpeed = 400,
TargetIndex = 0,
@ -155,7 +155,7 @@ namespace ActiveProtect
MaxEngineBurnTime = 10,
MaxAcceleration = 400,
ProportionalNavigationCoefficient = 3,
StageConfig = FlightStageConfig.LaserSemiActiveGuidedMissile,
StageConfig = FlightStageConfig.LaserBeamRiderGuidance,
DistanceParams = new MissileDistanceParams(500, 200, 10),
Mass = 50,
Type = MissileType.LaserBeamRiderGuidance

View File

@ -252,9 +252,14 @@ namespace ActiveProtect.SimulationEnvironment
public Vector3D InitialPosition { get; set; }
/// <summary>
/// 最大照射范围(米)
/// 激光功率(瓦特)
/// </summary>
public double MaxIlluminationRange { get; set; }
public double LaserPower { get; set; }
/// <summary>
/// 激光发散角
/// </summary>
public double LaserDivergenceAngle { get; set; }
/// <summary>
/// 构造函数,设置默认值
@ -262,7 +267,8 @@ namespace ActiveProtect.SimulationEnvironment
public LaserDesignatorConfig()
{
InitialPosition = new Vector3D(0, 0, 0);
MaxIlluminationRange = 1000;
LaserPower = 0;
LaserDivergenceAngle = 0;
}
}
@ -300,7 +306,6 @@ namespace ActiveProtect.SimulationEnvironment
InitialPosition = new Vector3D(0, 0, 0);
LaserPower = 0;
ControlFieldDiameter = 0;
MaxGuidanceDistance = 0;
}
}
@ -338,19 +343,6 @@ namespace ActiveProtect.SimulationEnvironment
public double ExplosionDistance { get; set; } = explosionDistance;
}
/// <summary>
/// 导弹飞行阶段枚举
/// </summary>
public enum FlightStage
{
Launch, // 发射阶段
Acceleration, // 加速阶段
Cruise, // 巡航阶段
TerminalGuidance, // 终端制导阶段
Attack, // 攻击阶段
Explosion, // 爆炸阶段
}
/// <summary>
/// 导弹飞行阶段配置结构
/// </summary>

View File

@ -10,33 +10,33 @@ namespace ActiveProtect.SimulationEnvironment
/// <summary>
/// 仿真元素的唯一标识符
/// </summary>
public string Id { get; set; } = id;
public virtual string Id { get; set; } = id;
/// <summary>
/// 仿真元素的当前位置
/// </summary>
public Vector3D Position { get; set; } = position;
public virtual Vector3D Position { get; set; } = position;
/// <summary>
/// 仿真元素的当前速度
/// </summary>
public Vector3D Velocity { get; set; } = Vector3D.Zero;
public virtual Vector3D Velocity { get; set; } = Vector3D.Zero;
/// <summary>
/// 仿真元素的当前朝向
/// </summary>
public Orientation Orientation { get; set; } = orientation;
public virtual Orientation Orientation { get; set; } = orientation;
/// <summary>
/// 仿真元素是否处于活动状态
/// </summary>
public virtual bool IsActive { get; protected set; } = true;
/// <summary>
/// 仿真管理器的引用
/// </summary>
public ISimulationManager SimulationManager { get; set; } = simulationManager;
/// <summary>
/// 仿真元素是否处于活动状态
/// </summary>
public bool IsActive { get; protected set; } = true;
/// <summary>
/// 更新仿真元素的状态
/// </summary>

View File

@ -32,12 +32,28 @@ namespace ActiveProtect.SimulationEnvironment
/// <summary>
/// 激光照射事件
/// </summary>
public class LaserIlluminationEvent : SimulationEvent
public class LaserIlluminationStartEvent : SimulationEvent
{
/// <summary>
/// 目标ID
/// </summary>
public string? TargetId { get; set; }
public required LaserDesignator LaserDesignator { get; set; }
public required SimulationElement Target { get; set; }
}
/// <summary
/// 激光照射更新事件
/// </summary>
public class LaserIlluminationUpdateEvent : SimulationEvent
{
public required LaserDesignator LaserDesignator { get; set; }
public required SimulationElement Target { get; set; }
}
/// <summary
/// 激光照射停止事件
/// </summary>
public class LaserIlluminationStopEvent : SimulationEvent
{
public required LaserDesignator LaserDesignator { get; set; }
public required SimulationElement Target { get; set; }
}
/// <summary>
@ -67,16 +83,7 @@ namespace ActiveProtect.SimulationEnvironment
public string? DestroyedEntityId { get; set; }
}
/// <summary>
/// 激光照射停止事件
/// </summary>
public class LaserIlluminationStopEvent : SimulationEvent
{
/// <summary>
/// 目标ID
/// </summary>
public string? TargetId { get; set; }
}
/// <summary>
/// 激光告警器警报事件
@ -128,19 +135,7 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public class LaserBeamStartEvent : SimulationEvent
{
public required Vector3D SourcePosition { get; set; }
public required Vector3D LaserDirection { get; set; }
public required double LaserPower { get; set; }
}
/// <summary>
/// 激光停止事件
/// </summary>
public class LaserBeamStopEvent : SimulationEvent
{
public required Vector3D SourcePosition { get; set; }
public required Vector3D LaserDirection { get; set; }
public required double LaserPower { get; set; }
public required LaserBeamRider LaserBeamRider { get; set; }
}
/// <summary>
@ -148,8 +143,14 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public class LaserBeamUpdateEvent : SimulationEvent
{
public required Vector3D SourcePosition { get; set; }
public required Vector3D LaserDirection { get; set; }
public required double LaserPower { get; set; }
public required LaserBeamRider LaserBeamRider { get; set; }
}
/// <summary>
/// 激光停止事件
/// </summary>
public class LaserBeamStopEvent : SimulationEvent
{
public required LaserBeamRider LaserBeamRider { get; set; }
}
}

Binary file not shown.

Binary file not shown.

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("ActiveProtect")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+354f80440b970b4975970b137fc1330bd6059aeb")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+f574c1be6bcbb73b38f2347680d3f4f4e2c241dd")]
[assembly: System.Reflection.AssemblyProductAttribute("ActiveProtect")]
[assembly: System.Reflection.AssemblyTitleAttribute("ActiveProtect")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@ -1 +1 @@
a2a07d3751fad93d33ce1499749fec44ff7d1dd9aeea87a87b7509708ab44429
26cdf876bff1ffe1787c12bced73fbbaf39d90b3e9182600d9597f4f5ccc12d8

View File

@ -1 +1 @@
4109b34a42fd6d13c86fe6fcf7fa10e44af3334bf333a157299982c5522fbd6b
a7ee257a99e11669f23f59cfa7a2bd0d3258b3055019a1b8da60960796073637

Binary file not shown.

Binary file not shown.