增加了激光驾束导弹和激光驾束仪, 精调了激光驾束算法; 重构导弹引导逻辑, 将引导和轨迹计算分开.

This commit is contained in:
Tian jianyong 2024-10-18 21:55:33 +08:00
parent 354f80440b
commit f574c1be6b
871 changed files with 5828 additions and 302 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

53
.gitignore vendored
View File

@ -1,51 +1,2 @@
# 构建结果
[Bb]in/
[Oo]bj/
[Ll]ib/
# Visual Studio 文件
.vs/
*.user
*.userosscache
*.suo
*.userprefs
# 编译文件
*.dll
*.exe
*.pdb
# 日志文件
*.log
# 临时文件
[Tt]emp/
[Tt]mp/
# 缓存文件
*.cache
*.bak
# 测试结果
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NuGet包
*.nupkg
**/packages/*
!**/packages/build/
# Visual Studio Code 设置
.vscode/
# Rider 设置
.idea/
# 操作系统文件
.DS_Store
Thumbs.db
# 其他
*.swp
*.*~
project.lock.json
build/
.vscode/

105
DesignMissile.md Normal file
View File

@ -0,0 +1,105 @@
# 实体设计
在仿真环境中,每个实体(如导弹)有几类参数:
1. 固有属性参数:如弹长、弹径、质量,最大速度、最大飞行距离、发动机推力等
2. 运行时状态参数:如当前位置、速度、朝向、加速度,接收的辐射能量、导引头视野中目标角度等
为了设计一个结构清晰的实体类,我们采用组合模式和接口分离原则。这样可以将不同类型的参数和状态分开管理,同时保持良好的扩展性。
## 基础接口
首先,我们定义几个基础接口来表示不同类型的参数:
```csharp
public interface IProperties
{
double Length { get; }
double Diameter { get; }
double Mass { get; }
}
public interface IState
{
Vector3 Position { get; set; }
Vector3 Velocity { get; set; }
Vector3 Acceleration { get; set; }
double Heading { get; set; }
double ReceivedRadiation { get; set; }
double TargetDeviation { get; set; }
}
```
## 实现类
然后,我们为每个接口创建实现类:
public class MissileProperties : IProperties
{
public double Length { get; }
public double Diameter { get; }
public double Mass { get; }
}
public class MissileState : IState
{
public Vector3 Position { get; set; }
public Vector3 Velocity { get; set; }
public Vector3 Acceleration { get; set; }
public double Heading { get; set; }
public double ReceivedRadiation { get; set; }
public double TargetDeviation { get; set; }
}
## 导弹实体类
接下来,我们创建一个导弹实体类,它将实现上述接口:
```csharp
public class Missile : IProperties, IState
{
public MissileProperties Properties { get; set; }
public MissileState State { get; set; }
public Missile()
{
Properties = new MissileProperties();
State = new MissileState();
}
// 其他方法,如更新状态、执行导航等
public void Update(double deltaTime)
{
// 更新运行时状态和导引参数
}
public void Navigate()
{
// 执行导航逻辑
}
}
```
## 设计优点
1. 清晰的结构:每种类型的参数或状态都有自己的接口和实现类,使得结构非常清晰。
2. 高度的模块化:可以轻松地替换或修改某一类参数,而不影响其他部分。
3. 易于扩展:如果需要添加新的参数类型,只需创建新的接口和实现类,然后在 Missile 类中添加相应的属性。
4. 符合单一职责原则:每个类都只负责一种类型的参数。
5. 便于测试:可以轻松地为每种参数类型创建模拟对象,便于单元测试。
6. 灵活性:可以为不同类型的导弹创建不同的参数实现,而保持相同的接口。
## 在激光驾束制导中, 为了实现更平滑的控制同时将加速度控制在25 m/s²以下并保持偏移在1.5米以内,我们可以采用以下几种方法
1. 使用PID控制器
PID比例-积分-微分)控制器可以提供更平滑和精确的控制。它考虑了误差的历史、当前值和变化率。
2. 非线性增益:
使用非线性函数来计算增益,使得在接近目标时增益减小,远离目标时增益增大。
3. 低通滤波:
对计算出的加速度进行低通滤波,以减少高频振荡。
4. 预测控制:
基于当前状态预测未来的位置,提前做出调整。

BIN
Models/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,93 @@
using System;
namespace ActiveProtect.Models
{
public class BasicGuidanceSystem : IGuidanceSystem
{
public bool HasGuidance { get; protected set; }
protected double ProportionalNavigationCoefficient { get; set; }
protected Vector3D Position { get; set; }
protected Vector3D Velocity { get; set; }
protected Vector3D GuidanceCommand { get; set; }
public BasicGuidanceSystem(double proportionalNavigationCoefficient)
{
ProportionalNavigationCoefficient = proportionalNavigationCoefficient;
HasGuidance = false;
GuidanceCommand = Vector3D.Zero;
Position = Vector3D.Zero;
Velocity = Vector3D.Zero;
}
public virtual void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
{
Position = missilePosition;
Velocity = missileVelocity;
}
public Vector3D GetGuidanceCommand()
{
return GuidanceCommand;
}
protected virtual void CalculateGuidanceCommand(double deltaTime)
{
// 基础制导系统不计算制导指令
// 派生类应该重写这个方法来实现特定的制导逻辑
}
protected Vector3D CalculateProportionalNavigation(Vector3D missilePosition, Vector3D missileVelocity, Vector3D targetPosition, Vector3D targetVelocity)
{
// 预测时间(可以根据实际情况调整)
double predictionTime = 2.0;
// 预测目标位置
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();
// 添加调试输出
Console.WriteLine($"PN Calculation: r = {r}, v = {v}, LOS = {LOS}, LOSRate = {LOSRate}, Acceleration = {acceleration}");
return acceleration;
}
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);
}
}
}

View File

@ -7,6 +7,12 @@ namespace ActiveProtect.Models
/// </summary>
public class Vector3D(double x, double y, double z)
{
// 添加静态单位向量属性
public static Vector3D UnitX => new(1, 0, 0);
public static Vector3D UnitY => new(0, 1, 0);
public static Vector3D UnitZ => new(0, 0, 1);
public static Vector3D Zero => new(0, 0, 0);
/// <summary>
/// X 坐标
/// </summary>
@ -33,10 +39,6 @@ namespace ActiveProtect.Models
return Math.Sqrt(Math.Pow(v1.X - v2.X, 2) + Math.Pow(v1.Y - v2.Y, 2) + Math.Pow(v1.Z - v2.Z, 2));
}
/// <summary>
/// 零向量
/// </summary>
public static Vector3D Zero => new(0, 0, 0);
/// <summary>
/// 将向量转换为字符串表示
@ -79,6 +81,14 @@ namespace ActiveProtect.Models
return new Vector3D(a.X / scalar, a.Y / scalar, a.Z / scalar);
}
/// <summary>
/// 向量反向
/// </summary>
public static Vector3D operator -(Vector3D a)
{
return new Vector3D(-a.X, -a.Y, -a.Z);
}
/// <summary>
/// 计算向量的模长
/// </summary>
@ -250,4 +260,18 @@ namespace ActiveProtect.Models
return new Orientation(yaw, pitch, 0);
}
}
public struct Vector2D
{
public double X { get; set; }
public double Y { get; set; }
public Vector2D(double x, double y)
{
X = x;
Y = y;
}
public static Vector2D Zero => new(0, 0);
}
}

View File

@ -0,0 +1,9 @@
namespace ActiveProtect.Models
{
public interface IGuidanceSystem
{
bool HasGuidance { get; }
void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity);
Vector3D GetGuidanceCommand();
}
}

161
Models/LaserBeamRider.cs Normal file
View File

@ -0,0 +1,161 @@
using ActiveProtect.SimulationEnvironment;
using System;
namespace ActiveProtect.Models
{
public class LaserBeamRider : SimulationElement
{
// 激光功率(瓦特)
public double LaserPower { get; private set; }
// 激光发散角(毫弧度)
public double BeamDivergence { get; private set; } = 0.0;
// 控制场直径(米)
public double ControlFieldDiameter { get; private set; }
// 激光方向
public Vector3D LaserDirection { get; private set; }
// 最大导引距离(米)
public double MaxGuidanceDistance { get; private set; }
// 激光束是否开启
public bool IsBeamOn { get; private set; }
// 导弹
public string MissileId { get; private set; }
// 目标
public string TargetId { get; private set; }
public LaserBeamRider(string id, string missileId, string targetId, LaserBeamRiderConfig config, ISimulationManager simulationManager)
: base(id, config.InitialPosition, new Orientation(0, 0, 0), simulationManager)
{
LaserPower = config.LaserPower;
ControlFieldDiameter = config.ControlFieldDiameter;
LaserDirection = Vector3D.Zero;
MaxGuidanceDistance = config.MaxGuidanceDistance;
IsActive = false; // 初始状态为非激活
IsBeamOn = false;
MissileId = missileId;
TargetId = targetId;
SimulationManager = simulationManager;
}
public override void Update(double deltaTime)
{
if (!IsActive) return;
if (IsBeamOn)
{
// 更新驾束仪的激光指向
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
LaserDirection = (targetPosition - Position).Normalize();
Console.WriteLine($"激光驾束仪 {Id} 更新激光指向: {LaserDirection}");
PublishLaserBeamUpdateEvent();
}
}
/// <summary>
/// 激活激光驾束仪
/// </summary>
public override void Activate()
{
if (!IsActive)
{
IsActive = true;
Console.WriteLine($"激光驾束仪 {Id} 已激活");
}
base.Activate();
}
/// <summary>
/// 停用激光驾束仪
/// </summary>
public override void Deactivate()
{
if (IsActive)
{
IsActive = false;
if (IsBeamOn)
{
StopBeamIllumination();
}
Console.WriteLine($"激光驾束仪 {Id} 已停用");
}
base.Deactivate();
}
public void StartBeamIllumination()
{
if (IsBeamOn) return;
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
{
LaserDirection = (target.Position - Position).Normalize();
IsBeamOn = true;
PublishLaserBeamStartEvent();
}
}
public void StopBeamIllumination()
{
if (!IsBeamOn) return;
IsBeamOn = false;
LaserDirection = Vector3D.Zero;
PublishLaserBeamStopEvent();
}
/// <summary>
/// 发布激光束开始事件
/// </summary>
private void PublishLaserBeamStartEvent()
{
PublishEvent(new LaserBeamStartEvent
{
SourcePosition = Position,
LaserDirection = LaserDirection,
LaserPower = LaserPower
});
}
private void PublishLaserBeamStopEvent()
{
PublishEvent(new LaserBeamStopEvent
{
SourcePosition = Position,
LaserDirection = LaserDirection,
LaserPower = LaserPower
});
}
private void PublishLaserBeamUpdateEvent()
{
PublishEvent(new LaserBeamUpdateEvent
{
SourcePosition = Position,
LaserDirection = LaserDirection,
LaserPower = LaserPower
});
}
public override string GetStatus()
{
return $"激光驾束仪 {Id}:\n" +
$" 位置: {Position}\n" +
$" 方向: {LaserDirection}\n" +
$" 激活状态: {(IsActive ? "" : "")}\n" +
$" 激光功率: {LaserPower} W\n" +
$" 发散角: {BeamDivergence} rad\n" +
$" 控制场直径: {ControlFieldDiameter} m\n" +
$" 最大导引距离: {MaxGuidanceDistance} m\n" +
$" 激光束状态: {(IsBeamOn ? "" : "")}";
}
}
}

View File

@ -0,0 +1,185 @@
using System;
namespace ActiveProtect.Models
{
public class LaserBeamRiderGuidanceSystem : BasicGuidanceSystem
{
private Vector3D LaserSourcePosition { get; set; }
private Vector3D LaserDirection { get; set; }
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 Vector3D LastError = Vector3D.Zero;
public Vector3D LastGuidanceCommand { get; private set; }
private Vector3D IntegralError = Vector3D.Zero;
public LaserBeamRiderGuidanceSystem(double proportionalNavigationCoefficient)
: base(proportionalNavigationCoefficient)
{
LaserSourcePosition = Vector3D.Zero;
LaserDirection = Vector3D.Zero;
LaserPower = 0;
HasGuidance = false;
LastGuidanceCommand = Vector3D.Zero;
}
public void UpdateLaserBeamRider(Vector3D sourcePosition, Vector3D direction)
{
LaserSourcePosition = sourcePosition;
LaserDirection = direction.Normalize();
}
public void ActivateLaserBeam()
{
HasGuidance = true;
}
public void DeactivateLaserBeam()
{
HasGuidance = false;
}
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
{
base.Update(deltaTime, missilePosition, missileVelocity);
UpdateGuidanceStatus();
if (HasGuidance)
{
CalculateGuidanceCommand(deltaTime);
}
else
{
GuidanceCommand = Vector3D.Zero;
}
Console.WriteLine($"Missile Position: {Position}, Velocity: {Velocity}, Has Guidance: {HasGuidance}");
}
private void UpdateGuidanceStatus()
{
// 计算导弹到激光束的最短距离
Vector3D shortestDistanceVector = CalculateShortestDistanceToLaserBeam();
double shortestDistance = shortestDistanceVector.Magnitude();
// 检查导弹是否在控制场内
if (shortestDistance > ControlFieldDiameter / 2)
{
HasGuidance = false;
Console.WriteLine($"激光驾束引导系统: 失去引导, 原因: 超出控制场范围, 距离: {shortestDistance}");
return;
}
//Console.WriteLine($"激光驾束引导系统: 在控制场内, 距离: {shortestDistance}");
// 计算接收到的激光功率
double beamArea = Math.PI * Math.Pow(ControlFieldDiameter / 2, 2);
double powerDensity = LaserPower / beamArea;
double receivedPower = powerDensity * (Math.PI * Math.Pow(DetectorDiameter / 2, 2));
if(HasGuidance = receivedPower >= MinDetectablePower)
{
HasGuidance = true;
}
else
{
HasGuidance = false;
Console.WriteLine($"激光驾束引导系统: 失去引导, 原因: 接收到的激光功率低于最小可探测功率,{LaserPower:E} W/{receivedPower:E} W");
}
}
protected override void CalculateGuidanceCommand(double deltaTime)
{
if (!HasGuidance)
{
GuidanceCommand = Vector3D.Zero;
return;
}
// 计算导弹到激光束的最短距离
Vector3D shortestDistanceVector = CalculateShortestDistanceToLaserBeam();
// PID控制
double Kp = 30; // 增加比例系数,使系统对误差更敏感,反应更快
double Ki = 0.05; // 减小积分系数,减少长期误差累积的影响
double Kd = 5; // 增加微分系数,减少系统的超调量,提高稳定性
double Kc = 0.5; // 减小非线性增益系数, 控制偏移量, 使得在更小的误差范围内有更大的修正
// 计算误差
Vector3D error = shortestDistanceVector;
// 积分项
IntegralError += error * deltaTime;
// 微分项
Vector3D derivativeError = (error - LastError) / deltaTime;
// 计算PID输出
Vector3D pidOutput = error * Kp + IntegralError * Ki + derivativeError * Kd;
// 非线性增益
double distance = shortestDistanceVector.Magnitude();
double nonLinearGain = Math.Tanh(distance / Kc);
// 计算横向加速度
Vector3D lateralAcceleration = pidOutput * nonLinearGain;
// 限制最大加速度
double maxAcceleration = 30; // 稍微增加最大加速度
if (lateralAcceleration.Magnitude() > maxAcceleration)
{
lateralAcceleration = lateralAcceleration.Normalize() * maxAcceleration;
}
// 计算前向加速度
Vector3D forwardDirection = LaserDirection;
Vector3D currentDirection = Velocity.Normalize();
Vector3D rotationAxis = Vector3D.CrossProduct(currentDirection, forwardDirection);
double rotationAngle = Math.Acos(Vector3D.DotProduct(currentDirection, forwardDirection));
Vector3D forwardAcceleration = Vector3D.CrossProduct(rotationAxis, Velocity) * rotationAngle * ProportionalNavigationCoefficient;
// 合并横向和前向加速度
GuidanceCommand = lateralAcceleration + forwardAcceleration;
// 低通滤波
const double alpha = 0.2;
GuidanceCommand = GuidanceCommand * alpha + LastGuidanceCommand * (1 - alpha);
// 更新上一次的误差和制导命令
LastError = error;
LastGuidanceCommand = GuidanceCommand;
Console.WriteLine($"Guidance Command: {GuidanceCommand.Magnitude()}, Lateral Error: {shortestDistanceVector.Magnitude()}, Lateral Acceleration: {lateralAcceleration.Magnitude()}, Forward Acceleration: {forwardAcceleration.Magnitude()}");
}
public override string ToString()
{
return $"LaserBeamRiderGuidanceSystem: HasGuidance={HasGuidance}, LaserSourcePosition={LaserSourcePosition}, LaserDirection={LaserDirection}, GuidanceCommand={GuidanceCommand}";
}
private Vector3D CalculateShortestDistanceToLaserBeam()
{
// 计算导弹到激光源的向量
Vector3D missileToSource = LaserSourcePosition - Position;
// 计算导弹在激光方向上的投影长度
double projectionLength = Vector3D.DotProduct(missileToSource, LaserDirection);
// 计算激光束上最接近导弹的点
Vector3D closestPointOnBeam = LaserSourcePosition - LaserDirection * projectionLength;
// 计算导弹到激光束最近点的向量(即最短距离向量)
Vector3D shortestDistanceVector = closestPointOnBeam - Position;
return shortestDistanceVector;
}
}
}

View File

@ -0,0 +1,81 @@
using ActiveProtect.SimulationEnvironment;
using System;
using System.Formats.Tar;
namespace ActiveProtect.Models
{
public class LaserBeamRiderMissile : MissileBase
{
private LaserBeamRiderGuidanceSystem LaserBeamRiderGuidanceSystem;
public LaserBeamRiderMissile(string id, string targetId, MissileConfig missileConfig, ISimulationManager simulationManager)
: base(id, missileConfig, simulationManager)
{
LaserBeamRiderGuidanceSystem = new LaserBeamRiderGuidanceSystem(missileConfig.ProportionalNavigationCoefficient);
TargetId = targetId;
}
protected override Vector3D GetGuidanceCommand()
{
return LaserBeamRiderGuidanceSystem.GetGuidanceCommand();
}
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;
}
private void OnLaserBeamUpdate(LaserBeamUpdateEvent evt)
{
LaserBeamRiderGuidanceSystem.UpdateLaserBeamRider(evt.SourcePosition, evt.LaserDirection);
LaserBeamRiderGuidanceSystem.LaserPower = evt.LaserPower;
}
public override void Update(double deltaTime)
{
if (LaserBeamRiderGuidanceSystem.HasGuidance)
{
LaserBeamRiderGuidanceSystem.Update(deltaTime, Position, Velocity);
this.HasGuidance = true;
}
else
{
this.HasGuidance = false;
}
base.Update(deltaTime);
}
public override string GetStatus()
{
string baseStatus = base.GetStatus().Replace("导弹", "激光驾束制导导弹");
string additionalStatus = $"\n 激光引导: {(LaserBeamRiderGuidanceSystem.HasGuidance ? "" : "")}";
return baseStatus + additionalStatus;
}
public override void Activate()
{
base.Activate();
SimulationManager.SubscribeToEvent<LaserBeamStartEvent>(OnLaserBeamStart);
SimulationManager.SubscribeToEvent<LaserBeamStopEvent>(OnLaserBeamStop);
SimulationManager.SubscribeToEvent<LaserBeamUpdateEvent>(OnLaserBeamUpdate);
}
public override void Deactivate()
{
base.Deactivate();
SimulationManager.UnsubscribeFromEvent<LaserBeamStartEvent>(OnLaserBeamStart);
SimulationManager.UnsubscribeFromEvent<LaserBeamStopEvent>(OnLaserBeamStop);
SimulationManager.UnsubscribeFromEvent<LaserBeamUpdateEvent>(OnLaserBeamUpdate);
}
}
}

View File

@ -174,18 +174,22 @@ namespace ActiveProtect.Models
/// <summary>
/// 激活激光指示器
/// </summary>
public void ActivateLaser()
public override void Activate()
{
IsActive = true;
IsJammed = false;
Console.WriteLine($"激光目标指示器 {Id} 已激活");
UpdateIllumination();
if (!IsActive)
{
IsActive = true;
IsJammed = false;
Console.WriteLine($"激光目标指示器 {Id} 已激活");
UpdateIllumination();
}
base.Activate();
}
/// <summary>
/// 停用激光指示器
/// </summary>
public void DeactivateLaser()
public override void Deactivate()
{
if (IsActive)
{
@ -193,6 +197,7 @@ namespace ActiveProtect.Models
StopIllumination();
Console.WriteLine($"激光目标指示器 {Id} 已停用");
}
base.Deactivate();
}
/// <summary>
@ -200,10 +205,13 @@ namespace ActiveProtect.Models
/// </summary>
private void PublishIlluminationEvent()
{
PublishEvent(new LaserIlluminationEvent
var evt = new LaserIlluminationEvent
{
TargetId = TargetId
});
TargetId = TargetId,
SenderId = Id
};
PublishEvent(evt);
Console.WriteLine($"激光指示器 {Id} 发布激光照射事件, 目标ID: {TargetId}");
}
/// <summary>
@ -211,10 +219,13 @@ namespace ActiveProtect.Models
/// </summary>
private void PublishIlluminationStopEvent()
{
PublishEvent(new LaserIlluminationStopEvent
var evt = new LaserIlluminationStopEvent
{
TargetId = TargetId
});
TargetId = TargetId,
SenderId = Id
};
PublishEvent(evt);
Console.WriteLine($"激光指示器 {Id} 发布激光照射停止事件, 目标ID: {TargetId}");
}
/// <summary>
@ -225,7 +236,6 @@ namespace ActiveProtect.Models
{
if (evt.DeactivatedEntityId == TargetId || evt.DeactivatedEntityId == MissileId)
{
DeactivateLaser();
Deactivate();
}
}
@ -239,6 +249,7 @@ namespace ActiveProtect.Models
return $"激光目标指示器 {Id}:\n" +
$" 位置: {Position}\n" +
$" 目标: {TargetId}\n" +
$" 导弹: {MissileId}\n" +
$" 激活状态: {(IsActive ? "" : "")}\n" +
$" 照射状态: {(IsIlluminating ? "" : "")}\n" +
$" 干扰状态: {(IsJammed ? "" : "")}\n" +

View File

@ -173,10 +173,20 @@ namespace ActiveProtect.Models
$" 冷却时间: {jammingCooldown:F2}/{maxJammingCooldown:F2}";
}
/// <summary>
/// 激活激光干扰器
/// </summary>
public override void Activate()
{
base.Activate();
SimulationManager.SubscribeToEvent<LaserWarnerAlarmEvent>(OnLaserWarnerAlarmEvent);
SimulationManager.SubscribeToEvent<LaserWarnerAlarmStopEvent>(OnLaserWarnerAlarmStopEvent);
}
/// <summary>
/// 停用激光干扰器
/// </summary>
protected override void Deactivate()
public override void Deactivate()
{
base.Deactivate();
SimulationManager.UnsubscribeFromEvent<LaserWarnerAlarmEvent>(OnLaserWarnerAlarmEvent);

View File

@ -0,0 +1,161 @@
using System;
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 Vector3D TargetPosition { get; set; }
private Vector3D TargetVelocity { get; set; }
private Vector3D LaserDesignatorPosition { get; set; }
private double FlightTime { get; set; }
public LaserSemiActiveGuidanceSystem(double proportionalNavigationCoefficient, Vector3D initialMissilePosition, Vector3D initialTargetPosition, Vector3D initialTargetVelocity)
: base(proportionalNavigationCoefficient)
{
Position = initialMissilePosition;
TargetPosition = initialTargetPosition;
TargetVelocity = initialTargetVelocity;
LaserDesignatorPosition = Vector3D.Zero;
FlightTime = 0;
}
public void SetTargetIllumination(bool isIlluminated)
{
IsTargetIlluminated = isIlluminated;
}
public void SetTargetPosition(Vector3D position)
{
TargetPosition = position;
}
public void SetLaserDesignatorPosition(Vector3D position)
{
LaserDesignatorPosition = position;
}
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
{
base.Update(deltaTime, missilePosition, missileVelocity);
Position = missilePosition;
Velocity = missileVelocity;
FlightTime += deltaTime;
UpdateGuidanceStatus();
if (HasGuidance)
{
CalculateGuidanceCommand(deltaTime);
}
else
{
GuidanceCommand = Vector3D.Zero;
}
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 detectorArea = Math.PI * Math.Pow(DetectorDiameter / 2, 2);
double illuminatedArea = Math.PI * Math.Pow(distanceToMissile * Math.Tan(FieldOfViewAngle / 2), 2);
double powerRatio = Math.Min(1, detectorArea / illuminatedArea);
// 计算聚焦后的功率密度增加
double focusedArea = Math.PI * Math.Pow(FocusedSpotDiameter / 2, 2);
double focusingFactor = detectorArea / focusedArea;
// 计算最终接收到的功率
double finalReceivedPower = receivedPower * powerRatio * focusingFactor;
return finalReceivedPower;
}
protected override void CalculateGuidanceCommand(double deltaTime)
{
if (!HasGuidance)
{
GuidanceCommand = Vector3D.Zero;
return;
}
// 计算比例导引加速度
Vector3D proportionalNavigation = CalculateProportionalNavigation(Position, Velocity, TargetPosition, TargetVelocity);
// 计算重力补偿
Vector3D gravityCompensation = new(0, 9.81, 0);
// 合并比例导引和重力补偿
GuidanceCommand = proportionalNavigation + gravityCompensation;
// 限制最大加速度
double maxAcceleration = 1000; // 根据实际情况调整
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()
{
Console.WriteLine($"激光半主动导弹引导信息:");
Console.WriteLine($" 位置: {Position}");
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");
Console.WriteLine($" 锁定阈值: {LockThreshold:E} W");
Console.WriteLine();
}
}
}

View File

@ -6,78 +6,49 @@ namespace ActiveProtect.Models
/// <summary>
/// 激光半主动制导导弹类,继承自基础导弹类
/// </summary>
public class LaserSemiActiveGuidedMissile : Missile
public class LaserSemiActiveGuidedMissile : MissileBase
{
/// <summary>
/// 激光锁定距离(米)
/// </summary>
private const double LaserLockDistance = 1500;
private LaserSemiActiveGuidanceSystem LaserGuidanceSystem;
private string LaserDesignatorId;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="id">导弹ID</param>
/// <param name="laserDesignatorId">激光指示器ID</param>
/// <param name="missileConfig">导弹配置</param>
/// <param name="simulationManager">仿真管理器</param>
public LaserSemiActiveGuidedMissile(
string id,
MissileConfig missileConfig,
string laserDesignatorId,
ISimulationManager simulationManager)
: base(id, missileConfig, simulationManager)
{
Type = MissileType.LaserSemiActiveGuidance;
Vector3D initialTargetPosition = simulationManager.GetEntityById($"Tank_{missileConfig.TargetIndex + 1}").Position;
Vector3D initialTargetVelocity = simulationManager.GetEntityById($"Tank_{missileConfig.TargetIndex + 1}").Velocity;
LaserGuidanceSystem = new LaserSemiActiveGuidanceSystem(
missileConfig.ProportionalNavigationCoefficient,
missileConfig.InitialPosition,
initialTargetPosition,
initialTargetVelocity
);
LaserDesignatorId = laserDesignatorId;
// 订阅事件
simulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
simulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
}
/// <summary>
/// 更新导弹的制导状态
/// </summary>
protected override void UpdateGuidanceStatus()
{
bool previousHasGuidance = HasGuidance;
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
{
bool isIlluminated = target.IsIlluminated;
bool isWithinRange = DistanceToTarget <= LaserLockDistance;
HasGuidance = isIlluminated && isWithinRange;
Console.WriteLine($"激光半主动制导导弹 {Id} 状态更新:");
Console.WriteLine($" 目标 {TargetId} 是否被照射: {isIlluminated}");
Console.WriteLine($" 距离目标: {DistanceToTarget:F2} m (最大锁定距离: {LaserLockDistance} m)");
Console.WriteLine($" 是否在锁定范围内: {isWithinRange}");
Console.WriteLine($" 引导状态: {(HasGuidance ? "" : "")}");
if (!HasGuidance && previousHasGuidance)
{
Console.WriteLine($"激光半主动制导导弹 {Id} 失去引导");
LastKnownVelocity = Velocity;
}
else if (HasGuidance && !previousHasGuidance)
{
Console.WriteLine($"激光半主动制导导弹 {Id} 获得引导");
}
}
else
{
HasGuidance = false;
Console.WriteLine($"激光半主动制导导弹 {Id} 无法找到目标 {TargetId}");
}
base.UpdateGuidanceStatus();
}
/// <summary>
/// 处理激光照射事件
/// </summary>
/// <param name="evt">激光照射事件</param>
private void OnLaserIllumination(LaserIlluminationEvent evt)
{
Console.WriteLine($"激光半主动导弹 {Id} 接收到激光照射事件, 目标ID: {evt.TargetId}");
if (evt.TargetId == TargetId)
{
Console.WriteLine($"激光半主动制导导弹 {Id} 检测到目标 {TargetId} 被激光照射");
UpdateGuidanceStatus();
LaserGuidanceSystem.SetTargetIllumination(true);
}
}
@ -87,10 +58,10 @@ namespace ActiveProtect.Models
/// <param name="evt">激光照射停止事件</param>
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
{
Console.WriteLine($"激光半主动导弹 {Id} 接收到激光照射停止事件, 目标ID: {evt.TargetId}");
if (evt.TargetId == TargetId)
{
Console.WriteLine($"激光半主动制导导弹 {Id} 检测到目标 {TargetId} 激光照射停止");
UpdateGuidanceStatus();
LaserGuidanceSystem.SetTargetIllumination(false);
}
}
@ -101,18 +72,78 @@ namespace ActiveProtect.Models
public override string GetStatus()
{
string baseStatus = base.GetStatus().Replace("导弹", "激光半主动制导导弹");
string additionalStatus = $"\n 激光引导: {(HasGuidance ? "" : "")}";
string additionalStatus = $"\n 激光引导: {(LaserGuidanceSystem.HasGuidance ? "" : "")}";
return baseStatus + additionalStatus;
}
/// <summary>
/// 激活导弹
/// </summary>
public override void Activate()
{
base.Activate();
SimulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
}
/// <summary>
/// 停用导弹
/// </summary>
protected override void Deactivate()
public override void Deactivate()
{
base.Deactivate();
SimulationManager.UnsubscribeFromEvent<LaserIlluminationEvent>(OnLaserIllumination);
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);
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);
}
protected override Vector3D GetGuidanceCommand()
{
return LaserGuidanceSystem.GetGuidanceCommand();
}
}
}

View File

@ -136,10 +136,20 @@ namespace ActiveProtect.Models
$" 警报持续时间: {(IsAlarming ? alarmTimer : 0):F2}/{alarmDuration:F2}";
}
/// <summary>
/// 激活激光告警器
/// </summary>
public override void Activate()
{
base.Activate();
SimulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
}
/// <summary>
/// 停用激光告警器
/// </summary>
protected override void Deactivate()
public override void Deactivate()
{
base.Deactivate();
SimulationManager.UnsubscribeFromEvent<LaserIlluminationEvent>(OnLaserIllumination);

View File

@ -1,12 +1,13 @@
using System;
using ActiveProtect.SimulationEnvironment;
using Model;
namespace ActiveProtect.Models
{
/// <summary>
/// 表示仿真中的导弹
/// </summary>
public class Missile : SimulationElement
public class MissileBase : SimulationElement
{
/// <summary>
/// 导弹类型
@ -68,11 +69,6 @@ namespace ActiveProtect.Models
/// </summary>
public FlightStage CurrentStage { get; protected set; }
/// <summary>
/// 导弹速度向量
/// </summary>
protected Vector3D Velocity;
/// <summary>
/// 上一帧目标位置
/// </summary>
@ -133,7 +129,7 @@ namespace ActiveProtect.Models
/// </summary>
public const double LAUNCH_DURATION = 0.5;
private IMissileStageStrategy currentStage;
protected IMissileStageStrategy currentStage;
private Dictionary<FlightStage, IMissileStageStrategy> stageStrategies;
/// <summary>
@ -144,7 +140,7 @@ namespace ActiveProtect.Models
/// <summary>
/// 构造函数
/// </summary>
public Missile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
public MissileBase(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
: base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, simulationManager)
{
// 初始化导弹属性
@ -215,24 +211,106 @@ namespace ActiveProtect.Models
}
UpdateEngineBurnTime(deltaTime);
(Position, Velocity) = UpdatePositionAndVelocityRK4(deltaTime);
Speed = Velocity.Magnitude();
Orientation = Orientation.FromVector(Velocity);
FlightTime += deltaTime;
FlightDistance += Speed * deltaTime;
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
Vector3D guidanceCommand = GetGuidanceCommand();
UpdateMotionState(deltaTime, guidanceCommand);
if (CheckHit())
{
Explode();
return;
}
UpdateGuidanceStatus();
currentStage.Update(deltaTime);
}
protected virtual Vector3D GetGuidanceCommand()
{
throw new NotImplementedException();
}
private void UpdateMotionState(double deltaTime, Vector3D guidanceCommand)
{
Vector3D acceleration = CalculateAcceleration(Velocity, guidanceCommand);
// 使用四阶龙格-库塔方法更新导弹的位置和速度
(Position, Velocity) = BasicGuidanceSystem.RungeKutta4(deltaTime, Position, Velocity, acceleration);
// 限制速度不超过最大速度
if (Velocity.Magnitude() > MaxSpeed)
{
Velocity = Velocity.Normalize() * MaxSpeed;
}
UpdateMotionStatus(deltaTime);
}
protected virtual void UpdateMotionStatus(double deltaTime)
{
Speed = Velocity.Magnitude();
Orientation = Orientation.FromVector(Velocity);
FlightTime += deltaTime;
FlightDistance += Speed * deltaTime;
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
}
/// <summary>
/// 计算导弹的加速度
/// </summary>
private Vector3D CalculateAcceleration(Vector3D velocity, Vector3D guidanceCommand)
{
Vector3D thrustAcceleration = Vector3D.Zero;
Vector3D guidanceAcceleration = Vector3D.Zero;
switch (CurrentStage)
{
case FlightStage.Launch:
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
break;
case FlightStage.Acceleration:
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
guidanceAcceleration = guidanceCommand;
break;
case FlightStage.Cruise:
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.1);
guidanceAcceleration = guidanceCommand * 1;
break;
case FlightStage.TerminalGuidance:
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.2);
guidanceAcceleration = guidanceCommand * 1.2;
break;
case FlightStage.Attack:
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
guidanceAcceleration = guidanceCommand * 1.5;
break;
}
if (!HasGuidance)
{
if (velocity.Magnitude() > 0)
{
thrustAcceleration = velocity.Normalize() * ThrustAcceleration;
}
else
{
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
}
}
// 计算空气阻力的影响
Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / Mass;
Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration + dragAcceleration;
//Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {guidanceAcceleration}, 推力加速度: {thrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
if (totalAcceleration.Magnitude() > MaxAcceleration)
{
totalAcceleration = totalAcceleration.Normalize() * MaxAcceleration;
}
return totalAcceleration;
}
/// <summary>
/// 切换导弹飞行阶段
/// </summary>
@ -299,7 +377,7 @@ namespace ActiveProtect.Models
/// <summary>
/// 计算导弹的加速度
/// </summary>
private (Vector3D, Vector3D) CalculateDerivatives(Vector3D position, Vector3D velocity, double deltaTime)
private (Vector3D, Vector3D) CalculateDerivatives_RK4(Vector3D position, Vector3D velocity, double deltaTime)
{
Vector3D guidanceAcceleration = Vector3D.Zero;
Vector3D thrustAcceleration = Vector3D.Zero;
@ -372,32 +450,32 @@ namespace ActiveProtect.Models
/// <summary>
/// 使用 Runge-Kutta 方法更新位置和速度
/// </summary>
private (Vector3D, Vector3D) UpdatePositionAndVelocityRK4(double deltaTime)
{
Vector3D k1, k2, k3, k4;
Vector3D v1, v2, v3, v4;
// 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);
// (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);
// 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;
}
// // 限制速度不超过最大速度
// if (newVelocity.Magnitude() > MaxSpeed)
// {
// newVelocity = newVelocity.Normalize() * MaxSpeed;
// }
return (newPosition, newVelocity);
}
// return (newPosition, newVelocity);
// }
/// <summary>
/// 检查是否命中目标
/// </summary>
private bool CheckHit()
protected bool CheckHit()
{
return DistanceToTarget <= DistanceParams.ExplosionDistance;
}
@ -405,7 +483,7 @@ namespace ActiveProtect.Models
/// <summary>
/// 检查是否应该自毁
/// </summary>
private bool ShouldSelfDestruct()
protected bool ShouldSelfDestruct()
{
if (FlightTime >= MaxFlightTime)
{
@ -417,7 +495,7 @@ namespace ActiveProtect.Models
Console.WriteLine($"导弹 {Id} 超出最大飞行距离 ({FlightDistance:F2}/{MaxFlightDistance:F2}),准备自毁");
return true;
}
if (Position.Y <= 0)
if (Position.Y <= -1.0) // 数字略小于0
{
Console.WriteLine($"导弹 {Id} 高度小于等于0 ({Position.Y:F2}),准备自毁");
return true;
@ -491,16 +569,17 @@ namespace ActiveProtect.Models
/// </summary>
public override string GetStatus()
{
return $"导弹 {Id}:\n" +
$" 位置: {Position}\n" +
$" 速度: {Speed:F2} m/s\n" +
$" 当前状态: {GetCurrentStateName()}\n" +
$" 飞行时间: {FlightTime:F2}/{MaxFlightTime:F2}\n" +
$" 飞行距离: {FlightDistance:F2}/{MaxFlightDistance:F2}\n" +
$" 距离目标: {DistanceToTarget:F2}\n" +
$" 发动机工作时间: {EngineBurnTime:F2}/{MaxEngineBurnTime:F2}\n" +
$" 有引导: {(HasGuidance ? "" : "")}\n" +
$" 失去引导时间: {LostGuidanceTime:F2}";
MissileRunningState missileRunningState = GetState();
return $"导弹 {missileRunningState.Id}:\n" +
$" 位置: {missileRunningState.Position}\n" +
$" 速度: {missileRunningState.Speed:F2} m/s\n" +
$" 当前状态: {missileRunningState.CurrentStage}\n" +
$" 飞行时间: {missileRunningState.FlightTime:F2}/{MaxFlightTime:F2}\n" +
$" 飞行距离: {missileRunningState.FlightDistance:F2}/{MaxFlightDistance:F2}\n" +
$" 距离目标: {missileRunningState.DistanceToTarget:F2}\n" +
$" 发动机工作时间: {missileRunningState.EngineBurnTime:F2}/{MaxEngineBurnTime:F2}\n" +
$" 有引导: {(missileRunningState.HasGuidance ? "" : "")}\n" +
$" 失去引导时间: {missileRunningState.LostGuidanceTime:F2}";
}
/// <summary>
@ -511,12 +590,26 @@ namespace ActiveProtect.Models
// 基类中的默认实现
}
/// <summary>
/// 获取当前飞行阶段的名称
/// </summary>
public string GetCurrentStateName()
public MissileRunningState GetState()
{
return currentStage.GetType().Name;
return new MissileRunningState
{
Id = Id,
Type = Type,
Position = Position,
Velocity = Velocity,
Orientation = Orientation,
Speed = Speed,
TargetId = TargetId,
FlightTime = FlightTime,
FlightDistance = FlightDistance,
DistanceToTarget = DistanceToTarget,
CurrentStage = CurrentStage,
HasGuidance = HasGuidance,
LostGuidanceTime = LostGuidanceTime,
EngineBurnTime = EngineBurnTime,
IsActive = IsActive
};
}
}
@ -533,10 +626,10 @@ namespace ActiveProtect.Models
/// </summary>
public class LaunchStageStrategy : IMissileStageStrategy
{
private readonly Missile missile;
private readonly MissileBase missile;
private double launchTime = 0;
public LaunchStageStrategy(Missile missile)
public LaunchStageStrategy(MissileBase missile)
{
this.missile = missile;
}
@ -544,7 +637,7 @@ namespace ActiveProtect.Models
public void Update(double deltaTime)
{
launchTime += deltaTime;
if (launchTime >= Missile.LAUNCH_DURATION || missile.Speed >= missile.MaxSpeed * 0.1)
if (launchTime >= MissileBase.LAUNCH_DURATION || missile.Speed >= missile.MaxSpeed * 0.1)
{
missile.ChangeStage(FlightStage.Acceleration);
}
@ -554,9 +647,9 @@ namespace ActiveProtect.Models
/// <summary>
/// 加速阶段策略
/// </summary>
public class AccelerationStageStrategy(Missile missile) : IMissileStageStrategy
public class AccelerationStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly Missile missile = missile;
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
@ -570,9 +663,9 @@ namespace ActiveProtect.Models
/// <summary>
/// 巡航阶段策略
/// </summary>
public class CruiseStageStrategy(Missile missile) : IMissileStageStrategy
public class CruiseStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly Missile missile = missile;
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
@ -586,9 +679,9 @@ namespace ActiveProtect.Models
/// <summary>
/// 终端制导阶段策略
/// </summary>
public class TerminalGuidanceStageStrategy(Missile missile) : IMissileStageStrategy
public class TerminalGuidanceStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly Missile missile = missile;
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
@ -602,9 +695,9 @@ namespace ActiveProtect.Models
/// <summary>
/// 攻击阶段策略
/// </summary>
public class AttackStageStrategy(Missile missile) : IMissileStageStrategy
public class AttackStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly Missile missile = missile;
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
@ -618,9 +711,9 @@ namespace ActiveProtect.Models
/// <summary>
/// 无制导阶段策略
/// </summary>
public class UnguidedStageStrategy(Missile missile) : IMissileStageStrategy
public class UnguidedStageStrategy(MissileBase missile) : IMissileStageStrategy
{
private readonly Missile missile = missile;
private readonly MissileBase missile = missile;
public void Update(double deltaTime)
{
@ -643,4 +736,86 @@ namespace ActiveProtect.Models
}
}
}
/// <summary>
/// 表示导弹的当前状态
/// </summary>
public struct MissileRunningState
{
/// <summary>
/// 导弹ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 导弹类型
/// </summary>
public MissileType Type { get; set; }
/// <summary>
/// 当前位置
/// </summary>
public Vector3D Position { get; set; }
/// <summary>
/// 当前速度向量
/// </summary>
public Vector3D Velocity { get; set; }
/// <summary>
/// 当前朝向
/// </summary>
public Orientation Orientation { get; set; }
/// <summary>
/// 当前速度(米/秒)
/// </summary>
public double Speed { get; set; }
/// <summary>
/// 目标ID
/// </summary>
public string TargetId { get; set; }
/// <summary>
/// 当前飞行时间(秒)
/// </summary>
public double FlightTime { get; set; }
/// <summary>
/// 当前飞行距离(米)
/// </summary>
public double FlightDistance { get; set; }
/// <summary>
/// 与目标的距离(米)
/// </summary>
public double DistanceToTarget { get; set; }
/// <summary>
/// 当前飞行阶段
/// </summary>
public FlightStage CurrentStage { get; set; }
/// <summary>
/// 是否有制导
/// </summary>
public bool HasGuidance { get; set; }
/// <summary>
/// 失去制导时间(秒)
/// </summary>
public double LostGuidanceTime { get; set; }
/// <summary>
/// 当前发动机燃烧时间(秒)
/// </summary>
public double EngineBurnTime { get; set; }
/// <summary>
/// 是否处于活动状态
/// </summary>
public bool IsActive { get; set; }
}
}

351
Models/MissileClass.cs Normal file
View File

@ -0,0 +1,351 @@
using System;
namespace Model
{
/// <summary>
/// 坦克消息结构
/// </summary>
public struct TankInfo
{
/// <summary>
/// 坦克编号
/// </summary>
public int TankID { get; set; }
/// <summary>
/// 坦克类型编号
/// </summary>
public int TankType { get; set; }
/// <summary>
/// 坦克X坐标
/// </summary>
public double xp { get; set; }
/// <summary>
/// 坦克Y坐标
/// </summary>
public double yp { get; set; }
/// <summary>
/// 坦克Z坐标
/// </summary>
public double zp { get; set; }
/// <summary>
/// 烟幕标记
/// </summary>
public double fYMFlag { get; set; }
/// <summary>
/// 烟幕SNR
/// </summary>
public double fYMSNR { get; set; }
/// <summary>
/// 激光致盲标记,1-导弹2-制导站3-两者都不是
/// </summary>
public double fZMJGFlag { get; set; }
/// <summary>
/// 致盲能量
/// </summary>
public double fZMJGPower { get; set; }
/// <summary>
/// 激光诱骗假目标X坐标
/// </summary>
public double fFalseX { get; set; }
/// <summary>
/// 激光诱骗假目标Y坐标
/// </summary>
public double fFalseY { get; set; }
/// <summary>
/// 激光诱骗假目标Z坐标
/// </summary>
public double fFalseZ { get; set; }
/// <summary>
/// 红外诱骗能量值
/// </summary>
public double fFalseIRPower { get; set; }
/// <summary>
/// 激光诱骗能量值
/// </summary>
public double fFalseJGPower { get; set; }
/// <summary>
/// 毫米波补偿//1为开启
/// </summary>
public double fHMBBCFlag { get; set; }
/// <summary>
/// 毫米波干扰能量
/// </summary>
public double fHMBGRPower { get; set; }
/// <summary>
/// 红外干扰能量
/// </summary>
public double fHWGRPower { get; set; }
/// <summary>
/// 坦克辐射红外能量
/// </summary>
public double fTankIRPower { get; set; }
/// <summary>
/// 坦克辐射激光能量
/// </summary>
public double fTankJGPower { get; set; }
/// <summary>
/// 坦克辐射毫米波能量
/// </summary>
public double fTankHMBPower { get; set; }
/// <summary>
/// 毫米波补偿特征值//大于导弹补偿成功,末敏弹子弹爆炸
/// </summary>
public double fFeature { get; set; }
};
/// <summary>
/// 威胁源初始化信息结构
/// </summary>
public struct MIniInfo
{
/// <summary>
/// 导弹ID
/// </summary>
public int nMisID;
/// <summary>
/// 导弹X坐标
/// </summary>
public double xm;
/// <summary>
/// 导弹Y坐标
/// </summary>
public double ym;
/// <summary>
/// 导弹Z坐标
/// </summary>
public double zm;
/// <summary>
/// 导弹方位角
/// </summary>
public double psi_m;
/// <summary>
/// 导弹俯仰角
/// </summary>
public double theta_m;
/// <summary>
/// 导弹飞行速度
/// </summary>
public double vm;
/// <summary>
/// 坦克X坐标
/// </summary>
public double xt;
/// <summary>
/// 坦克Y坐标
/// </summary>
public double yt;
/// <summary>
/// 坦克Z坐标
/// </summary>
public double zt;
/// <summary>
/// 光斑X坐标
/// </summary>
public double xd;
/// <summary>
/// 光斑Y坐标
/// </summary>
public double yd;
/// <summary>
/// 光斑Z坐标
/// </summary>
public double zd;
};
/// <summary>
/// 威胁源运行信息结构
/// </summary>
public struct MRunInfo
{
/// <summary>
/// 杀伤半径
/// </summary>
public double Rx;
/// <summary>
/// 仿真时间
/// </summary>
public double fSimTime;
/// <summary>
/// x坐标
/// </summary>
public double fMisX;
/// <summary>
/// y坐标
/// </summary>
public double fMisY;
/// <summary>
/// z坐标
/// </summary>
public double fMisZ;
/// <summary>
/// 导弹弹道倾角
/// </summary>
public double fMisDeltCw;
/// <summary>
/// 滚转角
/// </summary>
public double fMisRoll;
/// <summary>
/// 导弹弹道偏角
/// </summary>
public double fMisPitch;
/// <summary>
/// 导弹速度
/// </summary>
public double fMisV;
/// <summary>
/// 导弹辐射红外能量
/// </summary>
public double fIRPower;
/// <summary>
/// 导弹辐射红外波长
/// </summary>
public double fIRWaveLen;
/// <summary>
/// 导弹紫外能量
/// </summary>
public double fUVPower;
/// <summary>
/// 导弹紫外波长
/// </summary>
public double fUVWaveLen;
/// <summary>
/// 导弹激光能量
/// </summary>
public double fJGPower;
// 导弹激光波长
public double fJGWaveLen;
/// <summary>
/// 导弹毫米波能量
/// </summary>
public double fHMBPower;
/// <summary>
/// 导弹毫米波波长
/// </summary>
public double fHMBWaveLen;
/// <summary>
/// 制导站批号
/// </summary>
public double nZDZID;
/// <summary>
/// 架束仪位置x
/// </summary>
public double fZDZX;
/// <summary>
/// 架束仪位置Y
/// </summary>
public double fZDZY;
/// <summary>
/// 架束仪位置Z
/// </summary>
public double fZDZZ;
/// <summary>
/// 制导站辐射激光能量
/// </summary>
public double fZDZJGPower;
/// <summary>
/// 制导站辐射激光波长
/// </summary>
public double fZDZJGWaveLen;
/// <summary>
/// 编码
/// </summary>
public double nZDZCode;
/// <summary>
/// 脉冲重复频率
/// </summary>
public double fZDZReFre;
/// <summary>
/// 脉宽
/// </summary>
public double fZDZPulse;
/// <summary>
/// 末敏弹状态 1母弹2子弹3子弹扫描状态
/// </summary>
public double nMMDState;
/// <summary>
/// 子弹数量
/// </summary>
public double nSubNum;
/// <summary>
/// 子弹1批号
/// </summary>
public double nSub1ID;
/// <summary>
/// 子弹1坐标X
/// </summary>
public double fSub1X;
// 子弹1坐标Y
public double fSub1Y;
/// <summary>
/// 子弹1坐标Z
/// </summary>
public double fSub1Z;
/// <summary>
/// 子弹1辐射毫米波能量
/// </summary>
public double fSub1HMBPower;
/// <summary>
/// 子弹1辐射毫米波波长
/// </summary>
public double fSub1HMBWaveLen;
/// <summary>
/// 子弹1扫描坐标X
/// </summary>
public double fSub1ScanX;
/// <summary>
/// 子弹1扫描坐标Y
/// </summary>
public double fSub1ScanY;
/// <summary>
/// 子弹1扫描坐标Z
/// </summary>
public double fSub1ScanZ;
/// <summary>
/// 防护手段 1:激光致盲2激光诱骗3红外干扰4:红外诱骗5毫米波干扰6毫米波补偿7:烟幕防护;8:致盲制导站
/// </summary>
public double nDisType;
/// <summary>
/// 0代表失败 1代表成功
/// </summary>
public double nDisRes;
/// <summary>
/// 后续进一步处理
/// </summary>
public double k1;
/// <summary>
/// 弹道偏角和倾角改变角度当亲步骤数
/// </summary>
public int Xi;
public int JG_GR_success;
/// <summary>
/// 炮弹状态标志0:正常1炸毁目标2自爆
/// </summary>
public int bombFlag;
///// <summary>
///// 激光诱骗假目标X坐标
///// </summary>
//public double fFalseX;
///// <summary>
///// 激光诱骗假目标Y坐标
///// </summary>
//public double fFalseY;
///// <summary>
///// 激光诱骗假目标Z坐标
///// </summary>
//public double fFalseZ;
};
};

View File

@ -2,6 +2,8 @@ using System;
using System.Threading;
using ActiveProtect.SimulationEnvironment;
using ActiveProtect.Models;
using Model;
using System.Security.Cryptography.X509Certificates;
namespace ActiveProtect
{
@ -9,22 +11,44 @@ namespace ActiveProtect
{
static void Main(string[] args)
{
TankInfo tankinfo = new()
{
xp = 100,
yp = 0,
zp = 100
};
MIniInfo mIniInfo = new()
{
xm = 1500,
ym = 200,
zm = 100,
psi_m = Math.PI,
theta_m = -0.1,
vm = 0
};
// 创建仿真配置
var config = new SimulationConfig
{
// 配置坦克
TankConfigs =
[
new() {
InitialPosition = new Vector3D(100, 0, 100),
InitialOrientation = new Orientation(0, 0, 0),
InitialSpeed = 0,
new(tankinfo) {
InitialOrientation = new Orientation(Math.PI/4, 0, 0),
InitialSpeed = 15,
MaxSpeed = 20,
MaxArmor = 100,
HasLaserWarner = false,
HasLaserJammer = true
}
],
// 配置激光指示器
LaserDesignatorConfig = new LaserDesignatorConfig
{
InitialPosition = new Vector3D(500, 150, 100),
MaxIlluminationRange = 1000
},
// 配置激光告警器
LaserWarnerConfig = new LaserWarnerConfig
{
@ -38,92 +62,107 @@ namespace ActiveProtect
InitialJammingPower = 4000.0,
PowerIncreaseRate = 2000.0
},
// 配置激光驾束仪
LaserBeamRiderConfig = new LaserBeamRiderConfig
{
InitialPosition = new Vector3D(2000, 10, 100),
LaserPower = 1000,
ControlFieldDiameter = 6,
MaxGuidanceDistance = 5000
},
// 配置导弹
MissileConfigs =
[
// 标准导弹配置
new() {
InitialPosition = new Vector3D(1500, 200, 100),
InitialOrientation = new Orientation(Math.PI, -0.1, 0),
InitialSpeed = 0,
MaxSpeed = 300,
TargetIndex = 0,
MaxFlightTime = 0.5,
MaxFlightDistance = 3000,
ThrustAcceleration = 50,
MaxEngineBurnTime = 10,
MaxAcceleration = 100,
ProportionalNavigationCoefficient = 3,
StageConfig = FlightStageConfig.StandardMissile,
DistanceParams = new MissileDistanceParams(500, 100, 20),
Mass = 50,
Type = MissileType.StandardMissile,
},
// 红外指令制导导弹配置
new() {
InitialPosition = new Vector3D(2000, 150, 100),
InitialOrientation = new Orientation(Math.PI, -0.15, 0),
InitialSpeed = 0,
MaxSpeed = 300,
TargetIndex = 0,
MaxFlightTime = 1,
MaxFlightDistance = 5000,
ThrustAcceleration = 50,
MaxEngineBurnTime = 10,
MaxAcceleration = 100,
ProportionalNavigationCoefficient = 3,
StageConfig = FlightStageConfig.InfraredCommandGuidance,
DistanceParams = new MissileDistanceParams(500, 100, 20),
Mass = 50,
Type = MissileType.InfraredCommandGuidance
},
// 毫米波终端制导导弹配置
new() {
InitialPosition = new Vector3D(2000, 50, 100),
InitialOrientation = new Orientation(Math.PI, -0.05, 0),
InitialSpeed = 0,
MaxSpeed = 300,
TargetIndex = 0,
MaxFlightTime = 0.5,
MaxFlightDistance = 3000,
ThrustAcceleration = 50,
MaxEngineBurnTime = 10,
MaxAcceleration = 100,
ProportionalNavigationCoefficient = 3,
StageConfig = FlightStageConfig.MillimeterWaveTerminalGuidance,
DistanceParams = new MissileDistanceParams(500, 100, 20),
Mass = 50,
Type = MissileType.MillimeterWaveTerminalGuidance
},
// new(mIniInfo) {
// MaxSpeed = 300,
// TargetIndex = 0,
// MaxFlightTime = 0.5,
// MaxFlightDistance = 3000,
// ThrustAcceleration = 50,
// MaxEngineBurnTime = 10,
// MaxAcceleration = 100,
// ProportionalNavigationCoefficient = 3,
// StageConfig = FlightStageConfig.StandardMissile,
// DistanceParams = new MissileDistanceParams(500, 100, 20),
// Mass = 50,
// Type = MissileType.StandardMissile,
// },
// // 红外指令制导导弹配置
// new() {
// InitialPosition = new Vector3D(2000, 150, 100),
// InitialOrientation = new Orientation(Math.PI, -0.15, 0),
// InitialSpeed = 0,
// MaxSpeed = 300,
// TargetIndex = 0,
// MaxFlightTime = 1,
// MaxFlightDistance = 5000,
// ThrustAcceleration = 50,
// MaxEngineBurnTime = 10,
// MaxAcceleration = 100,
// ProportionalNavigationCoefficient = 3,
// StageConfig = FlightStageConfig.InfraredCommandGuidance,
// DistanceParams = new MissileDistanceParams(500, 100, 20),
// Mass = 50,
// Type = MissileType.InfraredCommandGuidance
// },
// // 毫米波终端制导导弹配置
// new() {
// InitialPosition = new Vector3D(2000, 50, 100),
// InitialOrientation = new Orientation(Math.PI, -0.05, 0),
// InitialSpeed = 0,
// MaxSpeed = 300,
// TargetIndex = 0,
// MaxFlightTime = 0.5,
// MaxFlightDistance = 3000,
// ThrustAcceleration = 50,
// MaxEngineBurnTime = 10,
// MaxAcceleration = 100,
// ProportionalNavigationCoefficient = 3,
// StageConfig = FlightStageConfig.MillimeterWaveTerminalGuidance,
// DistanceParams = new MissileDistanceParams(500, 100, 20),
// Mass = 50,
// Type = MissileType.MillimeterWaveTerminalGuidance
// },
// 激光半主动制导导弹配置
new() {
InitialPosition = new Vector3D(2000, 150, 100),
InitialOrientation = new Orientation(Math.PI, -0.12, 0),
InitialSpeed = 700,
MaxSpeed = 700,
InitialPosition = new Vector3D(2000, 100, 100),
InitialOrientation = new Orientation(Math.PI, -0.1, 0), // 调整初始俯仰角
InitialSpeed = 700,
MaxSpeed = 800,
TargetIndex = 0,
MaxFlightTime = 10,
MaxFlightTime = 10, // 增加最大飞行时间
MaxFlightDistance = 5000,
ThrustAcceleration = 0,
MaxEngineBurnTime = 0,
MaxAcceleration = 100,
ThrustAcceleration = 50, // 添加推力加速度
MaxEngineBurnTime = 10,
MaxAcceleration = 400,
ProportionalNavigationCoefficient = 3,
StageConfig = FlightStageConfig.LaserSemiActiveGuidedMissile,
DistanceParams = new MissileDistanceParams(500, 200, 20),
Mass = 50,
Type = MissileType.LaserSemiActiveGuidance
},
// 激光驾束制导导弹配置
new() {
InitialPosition = new Vector3D(2000, 10, 100),
InitialOrientation = new Orientation(Math.PI, 0.02, 0.0), // 调整初始俯仰角
InitialSpeed = 300,
MaxSpeed = 400,
TargetIndex = 0,
MaxFlightTime = 10, // 增加最大飞行时间
MaxFlightDistance = 3000,
ThrustAcceleration = 50, // 添加推力加速度
MaxEngineBurnTime = 10,
MaxAcceleration = 400,
ProportionalNavigationCoefficient = 3,
StageConfig = FlightStageConfig.LaserSemiActiveGuidedMissile,
DistanceParams = new MissileDistanceParams(500, 200, 10),
Mass = 50,
Type = MissileType.LaserBeamRiderGuidance
}
],
// 配置激光指示器
LaserDesignatorConfigs =
[
new LaserDesignatorConfig
{
InitialPosition = new Vector3D(500, 150, 100),
MaxIlluminationRange = 1000
}
],
SimulationTimeStep = 0.25
SimulationTimeStep = 0.025
};
// 创建仿真管理器

View File

@ -1,5 +1,6 @@
using System.ComponentModel;
using ActiveProtect.Models;
using Model;
namespace ActiveProtect.SimulationEnvironment
{
@ -21,7 +22,12 @@ namespace ActiveProtect.SimulationEnvironment
/// <summary>
/// 激光指示器配置列表
/// </summary>
public List<LaserDesignatorConfig> LaserDesignatorConfigs { get; set; }
public LaserDesignatorConfig LaserDesignatorConfig { get; set; }
/// <summary>
/// 激光驾束仪配置列表
/// </summary>
public LaserBeamRiderConfig LaserBeamRiderConfig { get; set; }
/// <summary>
/// 激光告警器配置
@ -45,7 +51,8 @@ namespace ActiveProtect.SimulationEnvironment
{
TankConfigs = [];
MissileConfigs = [];
LaserDesignatorConfigs = [];
LaserDesignatorConfig = new LaserDesignatorConfig();
LaserBeamRiderConfig = new LaserBeamRiderConfig();
LaserWarnerConfig = new LaserWarnerConfig();
LaserJammerConfig = new LaserJammerConfig();
SimulationTimeStep = 0.1; // 默认时间步长为0.1秒
@ -97,9 +104,26 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public TankConfig()
{
SetDefaultValues();
InitialPosition = new Vector3D(0, 0, 0);
InitialOrientation = new Orientation(0, 0, 0);
}
public TankConfig(TankInfo tankInfo){
SetDefaultValues();
InitialPosition = new Vector3D(tankInfo.xp, tankInfo.yp, tankInfo.zp);
InitialOrientation = new Orientation(0, 0, 0);
}
public void SetDefaultValues(){
InitialSpeed = 0;
MaxSpeed = 0;
MaxArmor = 0;
HasLaserWarner = false;
HasLaserJammer = false;
}
}
/// <summary>
@ -187,8 +211,21 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public MissileConfig()
{
SetDefaultValues();
InitialPosition = new Vector3D(0, 0, 0);
InitialOrientation = new Orientation(0, 0, 0);
}
public MissileConfig(MIniInfo mIniInfo){
SetDefaultValues();
InitialPosition = new Vector3D(mIniInfo.xm, mIniInfo.ym, mIniInfo.zm);
InitialOrientation = new Orientation(mIniInfo.psi_m, mIniInfo.theta_m, 0);
InitialSpeed = mIniInfo.vm;
}
public void SetDefaultValues(){
InitialSpeed = 0;
MaxSpeed = 0;
TargetIndex = 0;
@ -229,6 +266,44 @@ namespace ActiveProtect.SimulationEnvironment
}
}
/// <summary>
/// 激光驾束仪配置类
/// </summary>
public class LaserBeamRiderConfig
{
/// <summary>
/// 初始位置
/// </summary>
public Vector3D InitialPosition { get; set; }
/// <summary>
/// 激光功率(瓦特)
/// </summary>
public double LaserPower { get; set; }
/// <summary>
/// 控制场直径(米)
/// </summary>
public double ControlFieldDiameter { get; set; }
/// <summary>
/// 最大导引距离(米)
/// </summary>
public double MaxGuidanceDistance { get; set; }
/// <summary>
/// 构造函数,设置默认值
/// </summary>
public LaserBeamRiderConfig()
{
InitialPosition = new Vector3D(0, 0, 0);
LaserPower = 0;
ControlFieldDiameter = 0;
MaxGuidanceDistance = 0;
}
}
/// <summary>
/// 导弹类型枚举
/// </summary>

View File

@ -15,7 +15,12 @@ namespace ActiveProtect.SimulationEnvironment
/// <summary>
/// 仿真元素的当前位置
/// </summary>
public Vector3D Position { get; set; } = position;
public Vector3D Position { get; set; } = position;
/// <summary>
/// 仿真元素的当前速度
/// </summary>
public Vector3D Velocity { get; set; } = Vector3D.Zero;
/// <summary>
/// 仿真元素的当前朝向
@ -61,7 +66,7 @@ namespace ActiveProtect.SimulationEnvironment
/// <summary>
/// 激活仿真元素
/// </summary>
protected virtual void Activate()
public virtual void Activate()
{
IsActive = true;
PublishEvent(new EntityActivatedEvent { ActivatedEntityId = Id });
@ -70,7 +75,7 @@ namespace ActiveProtect.SimulationEnvironment
/// <summary>
/// 停用仿真元素
/// </summary>
protected virtual void Deactivate()
public virtual void Deactivate()
{
IsActive = false;
PublishEvent(new EntityDeactivatedEvent { DeactivatedEntityId = Id });

View File

@ -1,3 +1,5 @@
using ActiveProtect.Models;
namespace ActiveProtect.SimulationEnvironment
{
/// <summary>
@ -119,4 +121,35 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public string? DeactivatedEntityId { get; set; }
}
/// <summary>
/// 激光开始事件
/// </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; }
}
/// <summary>
/// 激光更新事件
/// </summary>
public class LaserBeamUpdateEvent : SimulationEvent
{
public required Vector3D SourcePosition { get; set; }
public required Vector3D LaserDirection { get; set; }
public required double LaserPower { get; set; }
}
}

View File

@ -99,35 +99,37 @@ namespace ActiveProtect.SimulationEnvironment
var tank = new Tank($"Tank_{i + 1}", tankConfig, this);
Elements.Add(tank);
// 为坦克创建激光告警器
if (tankConfig.HasLaserWarner)
{
var laserWarner = new LaserWarner(
$"LaserWarner_{tank.Id}",
tank.Position,
tank.Orientation,
this,
tank.Id,
config.LaserWarnerConfig
);
Elements.Add(laserWarner);
}
// // 为坦克创建激光告警器
// if (tankConfig.HasLaserWarner)
// {
// var laserWarner = new LaserWarner(
// $"LaserWarner_{tank.Id}",
// tank.Position,
// tank.Orientation,
// this,
// tank.Id,
// config.LaserWarnerConfig
// );
// Elements.Add(laserWarner);
// }
// 为坦克创建激光干扰机
if (tankConfig.HasLaserJammer)
{
var laserJammer = new LaserJammer(
$"LaserJammer_{tank.Id}",
tank.Position,
tank.Orientation,
this,
tank.Id,
config.LaserJammerConfig
);
Elements.Add(laserJammer);
}
// // 为坦克创建激光干扰机
// if (tankConfig.HasLaserJammer)
// {
// var laserJammer = new LaserJammer(
// $"LaserJammer_{tank.Id}",
// tank.Position,
// tank.Orientation,
// this,
// tank.Id,
// config.LaserJammerConfig
// );
// Elements.Add(laserJammer);
// }
}
// 创建导弹
for (int i = 0; i < config.MissileConfigs.Count; i++)
{
@ -140,14 +142,21 @@ namespace ActiveProtect.SimulationEnvironment
Console.WriteLine($"警告:导弹配置 {i} 的 MaxFlightTime 无效,已设置为默认值 300 秒");
}
Missile missile = missileConfig.Type switch
MissileBase missile = missileConfig.Type switch
{
MissileType.LaserSemiActiveGuidance => new LaserSemiActiveGuidedMissile(
$"LSGM_{i + 1}",
missileConfig,
"LD_1",
this
),
_ => new Missile(
MissileType.LaserBeamRiderGuidance => new LaserBeamRiderMissile(
$"LBRM_{i + 1}",
"Tank_1",
missileConfig,
this
),
_ => new MissileBase(
$"NM_{i + 1}",
missileConfig,
this
@ -157,12 +166,41 @@ namespace ActiveProtect.SimulationEnvironment
}
// 创建激光目标指示器
for (int i = 0; i < config.LaserDesignatorConfigs.Count; i++)
var laserDesignatorConfig = config.LaserDesignatorConfig;
var laserDesignator = new LaserDesignator(
$"LD_1",
"Tank_1",
"LSGM_1",
laserDesignatorConfig,
this
);
Elements.Add(laserDesignator);
// 创建激光驾束仪
var laserBeamRiderConfig = config.LaserBeamRiderConfig;
var laserBeamRider = new LaserBeamRider(
"LBR_1",
"LBRM_2",
"Tank_1",
laserBeamRiderConfig,
this
);
Elements.Add(laserBeamRider);
// 激活所有元素
ActivateAllElements();
// 启动激光驾束仪
laserBeamRider.StartBeamIllumination();
}
//激活所有元素
private void ActivateAllElements()
{
foreach (var element in Elements)
{
var laserDesignatorConfig = config.LaserDesignatorConfigs[i];
var laserDesignator = new LaserDesignator($"LD_{i + 1}", "Tank_1", "LSGM_4",laserDesignatorConfig, this);
Elements.Add(laserDesignator);
laserDesignator.ActivateLaser(); // 激活激光目标指示器
element.Activate();
}
}
@ -172,6 +210,7 @@ namespace ActiveProtect.SimulationEnvironment
public void PublishEvent(SimulationEvent evt)
{
var eventType = evt.GetType();
//Console.WriteLine($"发布事件: {eventType.Name}, 发送者: {evt.SenderId}");
if (eventHandlers.TryGetValue(eventType, out var handlers))
{
foreach (var handler in handlers)
@ -179,6 +218,10 @@ namespace ActiveProtect.SimulationEnvironment
handler.DynamicInvoke(evt);
}
}
else
{
Console.WriteLine($"没有找到事件 {eventType.Name} 的处理程序");
}
}
/// <summary>
@ -271,7 +314,7 @@ namespace ActiveProtect.SimulationEnvironment
Elements.RemoveAll(e => !e.IsActive);
// 检查是否所有导弹都结束飞行
if (!Elements.Any(e => e is Missile && e.IsActive))
if (!Elements.Any(e => e is MissileBase && e.IsActive))
{
EndSimulation();
}
@ -314,7 +357,7 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public void HandleTargetHit(string targetId, string missileId)
{
if (GetEntityById(targetId) is Tank tank && GetEntityById(missileId) is Missile missile)
if (GetEntityById(targetId) is Tank tank && GetEntityById(missileId) is MissileBase missile)
{
// 计算导弹造成的伤害
double damage = CalculateMissileDamage(missile);
@ -330,7 +373,7 @@ namespace ActiveProtect.SimulationEnvironment
/// <summary>
/// 计算导弹造成的伤害
/// </summary>
private double CalculateMissileDamage(Missile missile)
private double CalculateMissileDamage(MissileBase missile)
{
// 这里可以根据导弹类型、速度等因素计算伤害
// 现在我们简单地返回一个固定值

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More