简化了导弹基类设计,将自毁和爆炸的状态判断,放到子类中处理。给所有文档加上注释
This commit is contained in:
parent
6e960f59b3
commit
6fca00b28c
4
.cursorignore
Normal file
4
.cursorignore
Normal file
@ -0,0 +1,4 @@
|
||||
# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)
|
||||
bin/
|
||||
obj/
|
||||
.DS_Store
|
||||
@ -148,3 +148,14 @@ public class FireMissileCommand : ICommand
|
||||
#### 1.3 导弹行为
|
||||
|
||||
导弹行为包括导弹的飞行行为、攻击行为、躲避行为、跟踪行为、锁定行为、发射行为、爆炸行为等。
|
||||
|
||||
## 在激光驾束制导中, 为了实现更平滑的控制,同时将加速度控制在25 m/s²以下,并保持偏移在1.5米以内,我们可以采用以下几种方法
|
||||
|
||||
1. 使用PID控制器:
|
||||
PID(比例-积分-微分)控制器可以提供更平滑和精确的控制。它考虑了误差的历史、当前值和变化率。
|
||||
2. 非线性增益:
|
||||
使用非线性函数来计算增益,使得在接近目标时增益减小,远离目标时增益增大。
|
||||
3. 低通滤波:
|
||||
对计算出的加速度进行低通滤波,以减少高频振荡。
|
||||
4. 预测控制:
|
||||
基于当前状态预测未来的位置,提前做出调整。
|
||||
|
||||
@ -92,14 +92,3 @@ public class Missile : IProperties, IState
|
||||
4. 符合单一职责原则:每个类都只负责一种类型的参数。
|
||||
5. 便于测试:可以轻松地为每种参数类型创建模拟对象,便于单元测试。
|
||||
6. 灵活性:可以为不同类型的导弹创建不同的参数实现,而保持相同的接口。
|
||||
|
||||
## 在激光驾束制导中, 为了实现更平滑的控制,同时将加速度控制在25 m/s²以下,并保持偏移在1.5米以内,我们可以采用以下几种方法
|
||||
|
||||
1. 使用PID控制器:
|
||||
PID(比例-积分-微分)控制器可以提供更平滑和精确的控制。它考虑了误差的历史、当前值和变化率。
|
||||
2. 非线性增益:
|
||||
使用非线性函数来计算增益,使得在接近目标时增益减小,远离目标时增益增大。
|
||||
3. 低通滤波:
|
||||
对计算出的加速度进行低通滤波,以减少高频振荡。
|
||||
4. 预测控制:
|
||||
基于当前状态预测未来的位置,提前做出调整。
|
||||
@ -1,620 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using Model;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示仿真中的导弹
|
||||
/// </summary>
|
||||
public class MissileBase : SimulationElement
|
||||
{
|
||||
/// <summary>
|
||||
/// 导弹类型
|
||||
/// </summary>
|
||||
public MissileType Type { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前速度(米/秒)
|
||||
/// </summary>
|
||||
public double Speed { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大速度(米/秒)
|
||||
/// </summary>
|
||||
public double MaxSpeed { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标ID
|
||||
/// </summary>
|
||||
public string TargetId { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大飞行时间(秒)
|
||||
/// </summary>
|
||||
public double MaxFlightTime { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大飞行距离(米)
|
||||
/// </summary>
|
||||
public double MaxFlightDistance { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前飞行时间(秒)
|
||||
/// </summary>
|
||||
public double FlightTime { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前飞行距离(米)
|
||||
/// </summary>
|
||||
public double FlightDistance { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 与目标的距离(米)
|
||||
/// </summary>
|
||||
public double DistanceToTarget { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹距离参数
|
||||
/// </summary>
|
||||
public MissileDistanceParams DistanceParams { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 飞行阶段配置
|
||||
/// </summary>
|
||||
public FlightStageConfig StageConfig { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前飞行阶段
|
||||
/// </summary>
|
||||
public FlightStage InitialStage { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上一帧目标位置
|
||||
/// </summary>
|
||||
private Vector3D LastTargetPosition;
|
||||
|
||||
/// <summary>
|
||||
/// 比例导引系数
|
||||
/// </summary>
|
||||
private const double N = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 推力加速度(米/秒²)
|
||||
/// </summary>
|
||||
public double ThrustAcceleration { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前发动机燃烧时间(秒)
|
||||
/// </summary>
|
||||
public double EngineBurnTime { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大发动机燃烧时间(秒)
|
||||
/// </summary>
|
||||
public double MaxEngineBurnTime { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大加速度(米/秒²)
|
||||
/// </summary>
|
||||
public double MaxAcceleration { get; protected set; } = 10000;
|
||||
|
||||
/// <summary>
|
||||
/// 比例导引系数
|
||||
/// </summary>
|
||||
public double ProportionalNavigationCoefficient { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否有制导
|
||||
/// </summary>
|
||||
public bool HasGuidance { get; protected set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 失去制导的时间(秒)
|
||||
/// </summary>
|
||||
protected double LostGuidanceTime { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 最后已知的速度向量
|
||||
/// </summary>
|
||||
protected Vector3D LastKnownVelocity = Vector3D.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// 发射速度(米/秒)
|
||||
/// </summary>
|
||||
public const double LAUNCH_SPEED = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 发射阶段持续时间(秒)
|
||||
/// </summary>
|
||||
public const double LAUNCH_DURATION = 0.5;
|
||||
/// <summary>
|
||||
/// 当前飞行阶段策略
|
||||
/// </summary>
|
||||
protected IMissileStageStrategy currentStageStrategy;
|
||||
/// <summary>
|
||||
/// 飞行阶段策略字典
|
||||
/// </summary>
|
||||
private Dictionary<FlightStage, IMissileStageStrategy> stageStrategies;
|
||||
|
||||
/// <summary>
|
||||
/// 导弹质量(千克)
|
||||
/// </summary>
|
||||
public double Mass { get; protected set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public MissileBase(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, missileConfig.InitialSpeed, simulationManager)
|
||||
{
|
||||
// 初始化导弹属性
|
||||
Speed = missileConfig.InitialSpeed;
|
||||
MaxSpeed = missileConfig.MaxSpeed;
|
||||
MaxFlightTime = missileConfig.MaxFlightTime;
|
||||
MaxFlightDistance = missileConfig.MaxFlightDistance;
|
||||
DistanceParams = missileConfig.DistanceParams;
|
||||
StageConfig = missileConfig.StageConfig;
|
||||
IsActive = false;
|
||||
FlightTime = 0;
|
||||
FlightDistance = 0;
|
||||
SimulationManager = simulationManager;
|
||||
ThrustAcceleration = missileConfig.ThrustAcceleration;
|
||||
EngineBurnTime = 0;
|
||||
MaxEngineBurnTime = missileConfig.MaxEngineBurnTime;
|
||||
MaxAcceleration = missileConfig.MaxAcceleration;
|
||||
ProportionalNavigationCoefficient = missileConfig.ProportionalNavigationCoefficient;
|
||||
TargetId = $"Tank_{missileConfig.TargetIndex + 1}";
|
||||
|
||||
// 初始化策略字典
|
||||
stageStrategies = new Dictionary<FlightStage, IMissileStageStrategy>
|
||||
{
|
||||
{ FlightStage.Launch, new LaunchStageStrategy(this) },
|
||||
{ FlightStage.Acceleration, new AccelerationStageStrategy(this) },
|
||||
{ FlightStage.Cruise, new CruiseStageStrategy(this) },
|
||||
{ FlightStage.TerminalGuidance, new TerminalGuidanceStageStrategy(this) },
|
||||
{ FlightStage.Attack, new AttackStageStrategy(this) }
|
||||
};
|
||||
|
||||
// 设置初始阶段
|
||||
SetInitialStage();
|
||||
|
||||
currentStageStrategy = stageStrategies[InitialStage];
|
||||
|
||||
LastTargetPosition = Vector3D.Zero;
|
||||
|
||||
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置导弹的初始飞行阶段
|
||||
/// </summary>
|
||||
private void SetInitialStage()
|
||||
{
|
||||
if (StageConfig.EnableLaunch) InitialStage = FlightStage.Launch;
|
||||
else if (StageConfig.EnableAcceleration) InitialStage = FlightStage.Acceleration;
|
||||
else if (StageConfig.EnableCruise) InitialStage = FlightStage.Cruise;
|
||||
else if (StageConfig.EnableTerminalGuidance) InitialStage = FlightStage.TerminalGuidance;
|
||||
else if (StageConfig.EnableAttack) InitialStage = FlightStage.Attack;
|
||||
|
||||
Console.WriteLine($"导弹 {Id} 的初始阶段: {InitialStage}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导弹状态
|
||||
/// </summary>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
if (ShouldSelfDestruct())
|
||||
{
|
||||
SelfDestruct();
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEngineBurnTime(deltaTime);
|
||||
|
||||
Vector3D guidanceCommand = GetGuidanceCommand();
|
||||
|
||||
UpdateMotionState(deltaTime, guidanceCommand);
|
||||
|
||||
if (CheckHit())
|
||||
{
|
||||
Explode();
|
||||
return;
|
||||
}
|
||||
|
||||
currentStageStrategy.Update(deltaTime);
|
||||
}
|
||||
|
||||
protected virtual Vector3D GetGuidanceCommand()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual 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 (InitialStage)
|
||||
{
|
||||
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.05);
|
||||
guidanceAcceleration = guidanceCommand * 1;
|
||||
break;
|
||||
case FlightStage.TerminalGuidance:
|
||||
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.05);
|
||||
guidanceAcceleration = guidanceCommand * 1;
|
||||
break;
|
||||
case FlightStage.Attack:
|
||||
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration*0.05;
|
||||
guidanceAcceleration = guidanceCommand * 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!HasGuidance)
|
||||
{
|
||||
if (velocity.Magnitude() > 0)
|
||||
{
|
||||
thrustAcceleration = velocity.Normalize() * ThrustAcceleration;
|
||||
}
|
||||
else
|
||||
{
|
||||
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
|
||||
}
|
||||
}
|
||||
|
||||
//计算重力加速度(反坦克导弹一般升力很小, 主要依靠初始发射动能和持续的推力来维持飞行)
|
||||
//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;
|
||||
|
||||
Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {guidanceAcceleration}, 推力加速度: {thrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
|
||||
if (totalAcceleration.Magnitude() > MaxAcceleration)
|
||||
{
|
||||
totalAcceleration = totalAcceleration.Normalize() * MaxAcceleration;
|
||||
}
|
||||
|
||||
return totalAcceleration;
|
||||
}
|
||||
/// <summary>
|
||||
/// 切换导弹飞行阶段
|
||||
/// </summary>
|
||||
public void ChangeStage(FlightStage newStage)
|
||||
{
|
||||
if (stageStrategies.TryGetValue(newStage, out var strategy))
|
||||
{
|
||||
if (IsStageEnabled(newStage))
|
||||
{
|
||||
InitialStage = newStage;
|
||||
currentStageStrategy = strategy;
|
||||
Console.WriteLine($"导弹 {Id} 切换到 {newStage} 阶段");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果目标阶段不可用,尝试切换到下一个可用阶段
|
||||
TryChangeToNextAvailableStage(newStage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"导弹 {Id} 无法切换到未知阶段 {newStage}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查指定飞行阶段是否启用
|
||||
/// </summary>
|
||||
private bool IsStageEnabled(FlightStage stage)
|
||||
{
|
||||
return stage switch
|
||||
{
|
||||
FlightStage.Launch => StageConfig.EnableLaunch,
|
||||
FlightStage.Acceleration => StageConfig.EnableAcceleration,
|
||||
FlightStage.Cruise => StageConfig.EnableCruise,
|
||||
FlightStage.TerminalGuidance => StageConfig.EnableTerminalGuidance,
|
||||
FlightStage.Attack => StageConfig.EnableAttack,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 尝试切换到下一个可用的飞行阶段
|
||||
/// </summary>
|
||||
private void TryChangeToNextAvailableStage(FlightStage startStage)
|
||||
{
|
||||
FlightStage[] stageOrder = new FlightStage[] {FlightStage.Launch, FlightStage.Acceleration, FlightStage.Cruise, FlightStage.TerminalGuidance, FlightStage.Attack};
|
||||
int startIndex = Array.IndexOf(stageOrder, startStage);
|
||||
|
||||
for (int i = startIndex + 1; i < stageOrder.Length; i++)
|
||||
{
|
||||
if (IsStageEnabled(stageOrder[i]))
|
||||
{
|
||||
ChangeStage(stageOrder[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有可用的下一个阶段,导弹自毁
|
||||
Console.WriteLine($"导弹 {Id} 没有可用的下一个阶段,准备自毁");
|
||||
SelfDestruct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算空气阻力
|
||||
/// </summary>
|
||||
private static double CalculateDrag(double speed)
|
||||
{
|
||||
const double dragCoefficient = 0.1; // 减小阻力系数
|
||||
const double airDensity = 1.225; // 海平面空气密度,kg/m^3
|
||||
const double referenceArea = 0.01; // 减小导弹的参考面积,m^2
|
||||
|
||||
return 0.5 * dragCoefficient * airDensity * referenceArea * speed * speed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否命中目标
|
||||
/// </summary>
|
||||
protected bool CheckHit()
|
||||
{
|
||||
return DistanceToTarget <= DistanceParams.ExplosionDistance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否应该自毁
|
||||
/// </summary>
|
||||
protected bool ShouldSelfDestruct()
|
||||
{
|
||||
if (FlightTime >= MaxFlightTime)
|
||||
{
|
||||
Console.WriteLine($"导弹 {Id} 超出最大飞行时间 ({FlightTime:F2}/{MaxFlightTime:F2}),准备自毁");
|
||||
return true;
|
||||
}
|
||||
if (FlightDistance >= MaxFlightDistance)
|
||||
{
|
||||
Console.WriteLine($"导弹 {Id} 超出最大飞行距离 ({FlightDistance:F2}/{MaxFlightDistance:F2}),准备自毁");
|
||||
return true;
|
||||
}
|
||||
if (Position.Y <= -1.0) // 数字略小于0
|
||||
{
|
||||
Console.WriteLine($"导弹 {Id} 高度小于等于0 ({Position.Y:F2}),准备自毁");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新发动机燃烧时间
|
||||
/// </summary>
|
||||
private void UpdateEngineBurnTime(double deltaTime)
|
||||
{
|
||||
if (InitialStage == FlightStage.Acceleration && EngineBurnTime < MaxEngineBurnTime)
|
||||
{
|
||||
EngineBurnTime += deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算比例导引加速度
|
||||
/// </summary>
|
||||
private Vector3D CalculateProportionalNavigation(Vector3D position)
|
||||
{
|
||||
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
||||
Vector3D LOS = targetPosition - position;
|
||||
Vector3D LOSRate = (targetPosition - LastTargetPosition) / FlightTime - Velocity;
|
||||
LastTargetPosition = targetPosition;
|
||||
|
||||
return Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), LOS).Normalize()
|
||||
* ProportionalNavigationCoefficient * Velocity.Magnitude();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导弹爆炸
|
||||
/// </summary>
|
||||
public void Explode()
|
||||
{
|
||||
Deactivate();
|
||||
SimulationManager.HandleTargetHit(TargetId, Id);
|
||||
Console.WriteLine($"导弹 {Id} 在 {Position} 爆炸,命中目标!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导弹自毁
|
||||
/// </summary>
|
||||
public void SelfDestruct()
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
string reason = FlightTime >= MaxFlightTime ? "超出最大飞行时间" :
|
||||
FlightDistance >= MaxFlightDistance ? "超出最大飞行距离" :
|
||||
Position.Y <= 0 ? "高度小于等于0" :
|
||||
!HasGuidance ? "失去引导" : "未知原因";
|
||||
|
||||
Console.WriteLine($"导弹 {Id} 自毁。原因: {reason}");
|
||||
Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置比例导引系数
|
||||
/// </summary>
|
||||
public void SetProportionalNavigationCoefficient(double newCoefficient)
|
||||
{
|
||||
ProportionalNavigationCoefficient = newCoefficient;
|
||||
Console.WriteLine($"导弹 {Id} 的比例导引系数已更新为 {newCoefficient}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取导弹状态
|
||||
/// </summary>
|
||||
public override string GetStatus()
|
||||
{
|
||||
MissileRunningState missileRunningState = GetState();
|
||||
return $"导弹 {missileRunningState.Id}:\n" +
|
||||
$" 位置: {missileRunningState.Position}\n" +
|
||||
$" 速度: {missileRunningState.Speed:F2} m/s\n" +
|
||||
$" 速度分量: {missileRunningState.Velocity}\n" +
|
||||
$" 朝向: {missileRunningState.Orientation}\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>
|
||||
/// 更新导弹的制导状态
|
||||
/// </summary>
|
||||
protected virtual void UpdateGuidanceStatus()
|
||||
{
|
||||
// 基类中的默认实现
|
||||
}
|
||||
|
||||
public MissileRunningState GetState()
|
||||
{
|
||||
return new MissileRunningState
|
||||
{
|
||||
Id = Id,
|
||||
Type = Type,
|
||||
Position = Position,
|
||||
Velocity = Velocity,
|
||||
Orientation = Orientation,
|
||||
Speed = Speed,
|
||||
TargetId = TargetId,
|
||||
FlightTime = FlightTime,
|
||||
FlightDistance = FlightDistance,
|
||||
DistanceToTarget = DistanceToTarget,
|
||||
CurrentStage = InitialStage,
|
||||
HasGuidance = HasGuidance,
|
||||
LostGuidanceTime = LostGuidanceTime,
|
||||
EngineBurnTime = EngineBurnTime,
|
||||
IsActive = IsActive
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <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; }
|
||||
}
|
||||
}
|
||||
@ -1,168 +0,0 @@
|
||||
|
||||
using System;
|
||||
|
||||
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>
|
||||
/// 加速阶段策略
|
||||
/// </summary>
|
||||
public class AccelerationStageStrategy : IMissileStageStrategy
|
||||
{
|
||||
private readonly MissileBase missile;
|
||||
|
||||
public AccelerationStageStrategy(MissileBase missile)
|
||||
{
|
||||
this.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 : IMissileStageStrategy
|
||||
{
|
||||
private readonly MissileBase missile;
|
||||
|
||||
public CruiseStageStrategy(MissileBase missile)
|
||||
{
|
||||
this.missile = missile;
|
||||
}
|
||||
|
||||
public void Update(double deltaTime)
|
||||
{
|
||||
if (missile.DistanceToTarget <= missile.DistanceParams.TerminalGuidanceDistance)
|
||||
{
|
||||
missile.ChangeStage(FlightStage.TerminalGuidance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 终端制导阶段策略
|
||||
/// </summary>
|
||||
public class TerminalGuidanceStageStrategy : IMissileStageStrategy
|
||||
{
|
||||
private readonly MissileBase missile;
|
||||
|
||||
public TerminalGuidanceStageStrategy(MissileBase missile)
|
||||
{
|
||||
this.missile = missile;
|
||||
}
|
||||
|
||||
public void Update(double deltaTime)
|
||||
{
|
||||
if (missile.DistanceToTarget <= missile.DistanceParams.AttackDistance)
|
||||
{
|
||||
missile.ChangeStage(FlightStage.Attack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 攻击阶段策略
|
||||
/// </summary>
|
||||
public class AttackStageStrategy : IMissileStageStrategy
|
||||
{
|
||||
private readonly MissileBase missile;
|
||||
|
||||
public AttackStageStrategy(MissileBase missile)
|
||||
{
|
||||
this.missile = missile;
|
||||
}
|
||||
|
||||
public void Update(double deltaTime)
|
||||
{
|
||||
if (missile.DistanceToTarget <= missile.DistanceParams.ExplosionDistance)
|
||||
{
|
||||
missile.Explode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 无制导阶段策略
|
||||
/// </summary>
|
||||
public class UnguidedStageStrategy : IMissileStageStrategy
|
||||
{
|
||||
private readonly MissileBase missile;
|
||||
|
||||
public UnguidedStageStrategy(MissileBase missile)
|
||||
{
|
||||
this.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,162 +0,0 @@
|
||||
# 末敏弹仿真设计
|
||||
|
||||
## 1. 末敏弹的结构和原理
|
||||
|
||||
### 1.1 末敏弹的结构
|
||||
|
||||
末敏弹是一种远程投放,顶部攻击目标的弹药,其结构包括母弹、子弹、战斗部、导引头。
|
||||
|
||||
### 1.2 末敏弹的制导系统
|
||||
|
||||
末敏弹的制导系统包括毫米波雷达和红外两部分。
|
||||
|
||||
### 1.3 末敏弹的运行阶段
|
||||
|
||||
末敏弹的运行阶段包括发射阶段、分离阶段、减速阶段、螺旋扫描阶段、攻击阶段、自毁阶段等。
|
||||
|
||||
## 2. 末敏弹的仿真
|
||||
|
||||
### 2.1 运动仿真
|
||||
|
||||
运动仿真包括母弹和子弹的运行过程和运动规律,按运行阶段进行仿真。
|
||||
|
||||
### 2.2 导引头仿真
|
||||
|
||||
导引头仿真包括导引头的工作原理、搜索、锁定、攻击过程。
|
||||
|
||||
## 3. 运动仿真
|
||||
|
||||
### 3.1 发射阶段
|
||||
|
||||
行为:母弹发射
|
||||
参数:
|
||||
发射位置:距离目标 20 公里
|
||||
发射角度:俯仰角和方位角,需要根据目标的坐标计算,暂定 45 度
|
||||
发射速度:1000 米/秒
|
||||
|
||||
### 3.2 分离阶段
|
||||
|
||||
动作:子母弹分离
|
||||
参数:
|
||||
分离高度:1000 米
|
||||
分离距离:与目标水平距离 1000 米
|
||||
|
||||
### 3.3 减速阶段
|
||||
|
||||
动作:开伞、减速减旋、稳态扫描
|
||||
参数:
|
||||
减速高度:400 米
|
||||
减速距离:与目标水平距离 300 米
|
||||
|
||||
### 3.4 螺旋扫描阶段
|
||||
|
||||
动作:螺旋扫描
|
||||
参数:
|
||||
扫描高度:200 米
|
||||
扫描距离:与目标水平距离小于 100 米
|
||||
扫描角度:30 度
|
||||
扫描线视场角:15 度
|
||||
扫描速度:2 圈/秒
|
||||
下降速度:10 米/秒
|
||||
|
||||
### 3.5 攻击阶段
|
||||
|
||||
动作:攻击目标
|
||||
参数:
|
||||
攻击高度:小于 200 米,扫描发现目标之后的 0.5 秒
|
||||
攻击距离:与目标水平距离小于 100 米
|
||||
攻击速度:2000 米/秒
|
||||
|
||||
### 3.6 自毁阶段
|
||||
|
||||
动作:自毁
|
||||
参数:
|
||||
自毁高度:20 米
|
||||
自毁条件:扫描未发现目标
|
||||
|
||||
## 4. 导引头仿真
|
||||
|
||||
### 4.1 毫米波雷达
|
||||
|
||||
毫米波雷达的仿真包括雷达的参数模型和行为模型。
|
||||
|
||||
#### 4.1.1 参数模型
|
||||
|
||||
波长:3毫米
|
||||
频率:94GHz
|
||||
脉冲宽度:100ns
|
||||
脉冲重复频率:10kHz
|
||||
天线增益:30dB
|
||||
噪声系数:5dB
|
||||
信噪比阈值:100dB
|
||||
|
||||
#### 4.1.2 行为模型
|
||||
|
||||
测高:到达 20 米,发出自毁信号
|
||||
|
||||
### 4.2 红外导引头
|
||||
|
||||
红外导引头的仿真包括红外导引头的参数模型和行为模型。
|
||||
|
||||
#### 4.2.1 参数模型
|
||||
|
||||
波长:3-5 微米
|
||||
模数:单模、多模
|
||||
信噪比阈值:100dB
|
||||
|
||||
#### 4.2.2 行为模型
|
||||
|
||||
探测目标:探测到目标,发出攻击信号
|
||||
|
||||
## 5. 干扰方式
|
||||
|
||||
干扰方式包括烟幕干扰、毫米波补偿
|
||||
|
||||
### 5.1 烟幕干扰
|
||||
|
||||
坦克顶部烟幕弹装置,发射烟幕弹,形成烟幕,干扰毫米波雷达和红外导引头。
|
||||
|
||||
### 5.2 毫米波补偿
|
||||
|
||||
坦克顶部毫米波干扰机,发射毫米波补偿信号,干扰末敏弹毫米波雷达。
|
||||
|
||||
## 6. 仿真模型设计思路
|
||||
|
||||
基于上述末敏弹的仿真设计,我们可以设计一个末敏弹仿真模型,主要思路如下:
|
||||
|
||||
1. 类结构设计:
|
||||
- 创建一个 `TerminalSensitiveMissile` 类,继承自 `MissileBase`。
|
||||
- 创建 `MillimeterWaveRadar` 和 `InfraredSeeker` 类来模拟导引头。
|
||||
|
||||
2. 飞行阶段管理:
|
||||
- 定义一个枚举 `TerminalSensitiveStage` 来表示末敏弹的不同飞行阶段。
|
||||
- 实现一个状态机来管理这些阶段的转换。
|
||||
|
||||
3. 运动模型:
|
||||
- 为每个飞行阶段实现特定的运动模型。
|
||||
- 使用物理公式计算弹道,考虑重力、空气阻力等因素。
|
||||
|
||||
4. 导引头模拟:
|
||||
- 实现毫米波雷达和红外导引头的探测逻辑。
|
||||
- 模拟信号处理、目标识别和跟踪。
|
||||
|
||||
5. 目标交互:
|
||||
- 实现与目标(如坦克)的交互逻辑。
|
||||
- 模拟目标探测、锁定和攻击过程。
|
||||
|
||||
6. 环境交互:
|
||||
- 考虑环境因素对末敏弹性能的影响,如天气条件。
|
||||
|
||||
7. 干扰模拟:
|
||||
- 实现烟幕干扰和毫米波补偿等干扰方式的影响。
|
||||
|
||||
8. 参数配置:
|
||||
- 设计一个灵活的参数配置系统,允许调整各种性能参数。
|
||||
|
||||
9. 数据记录和分析:
|
||||
- 实现数据记录功能,用于后续分析和可视化。
|
||||
|
||||
10. 集成到仿真系统:
|
||||
- 确保末敏弹模型能够与整个仿真系统无缝集成。
|
||||
|
||||
这个设计应该能够全面模拟末敏弹的行为,包括其复杂的飞行阶段和导引系统。实现时,我们需要逐步完善每个组件,并进行充分的测试和调整。
|
||||
@ -1,347 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public class TerminalSensitiveMissile : MissileBase
|
||||
{
|
||||
// 定义末敏弹工作阶段的枚举
|
||||
private enum TerminalSensitiveStage
|
||||
{
|
||||
Launch, // 发射阶段
|
||||
Separation, // 分离阶段
|
||||
Deceleration, // 减速阶段
|
||||
SpiralScan, // 螺旋扫描阶段
|
||||
Attack, // 攻击阶段
|
||||
SelfDestruct // 自毁阶段
|
||||
}
|
||||
|
||||
// 当前工作阶段
|
||||
private TerminalSensitiveStage currentWorkingStage;
|
||||
|
||||
// 阶段策略字典,用于存储不同阶段的更新策略
|
||||
private Dictionary<TerminalSensitiveStage, Action<double>> stageStrategies;
|
||||
|
||||
// 螺旋扫描相关参数
|
||||
private double spiralAngle;
|
||||
private const double SpiralRotationSpeed = 4 * Math.PI; // 2 rotations per second
|
||||
private const double VerticalDescentSpeed = 10; // 10 m/s
|
||||
private const double ScanAngle = 30 * Math.PI / 180; // 30 degrees in radians
|
||||
|
||||
// 各阶段的距离和高度参数
|
||||
private const double SeparationDistance = 1000; // 分离距离 1000米
|
||||
private const double SeparationHeight = 1000; // 分离高度 1000米
|
||||
private const double DecelerationHeight = 400; // 减速高度 400米
|
||||
private const double ScanningHeight = 200; // 扫描高度 200米
|
||||
private const double SelfDestructHeight = 20; // 自毁高度 20米
|
||||
|
||||
// 扫描和目标检测相关参数
|
||||
private Vector3D lastScanDirection;
|
||||
private bool targetDetected;
|
||||
private double detectionAngle;
|
||||
|
||||
// 目标位置和分离位置
|
||||
private Vector3D TargetPosition;
|
||||
private Vector3D SeparationPosition;
|
||||
|
||||
// 制导指令
|
||||
public Vector3D GuidanceCommand { get; private set; }
|
||||
|
||||
// 传感器
|
||||
private InfraredDetector infraredDetector;
|
||||
private MillimeterWaveRadiometer radiometer;
|
||||
private MillimeterWaveAltimeter altimeter;
|
||||
private LaserRangefinder rangefinder;
|
||||
|
||||
// 构造函数
|
||||
public TerminalSensitiveMissile(string id, MissileConfig missileConfig, string targetId, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig, simulationManager)
|
||||
{
|
||||
// 初始化参数
|
||||
spiralAngle = 0;
|
||||
lastScanDirection = Vector3D.Zero;
|
||||
targetDetected = false;
|
||||
detectionAngle = 0;
|
||||
GuidanceCommand = Vector3D.Zero;
|
||||
|
||||
// 获取目标位置
|
||||
TargetPosition = SimulationManager.GetEntityById(targetId).Position;
|
||||
|
||||
// 计算分离位置
|
||||
SeparationPosition = CalculatePointOnTrajectory(Position, TargetPosition, SeparationDistance, SeparationHeight);
|
||||
|
||||
// 初始化阶段策略字典
|
||||
stageStrategies = new Dictionary<TerminalSensitiveStage, Action<double>>
|
||||
{
|
||||
{ TerminalSensitiveStage.Launch, UpdateLaunchStage },
|
||||
{ TerminalSensitiveStage.Separation, UpdateSeparationStage },
|
||||
{ TerminalSensitiveStage.Deceleration, UpdateDecelerationStage },
|
||||
{ TerminalSensitiveStage.SpiralScan, UpdateSpiralScanStage },
|
||||
{ TerminalSensitiveStage.Attack, UpdateAttackStage },
|
||||
{ TerminalSensitiveStage.SelfDestruct, UpdateSelfDestructStage }
|
||||
};
|
||||
|
||||
// 设置初始阶段
|
||||
currentWorkingStage = TerminalSensitiveStage.Launch;
|
||||
|
||||
// 初始化传感器
|
||||
infraredDetector = new InfraredDetector(Position, Orientation, 1000, 30);
|
||||
radiometer = new MillimeterWaveRadiometer(Position, Orientation, 94e9, 1e-6);
|
||||
altimeter = new MillimeterWaveAltimeter(Position, Orientation, 1000, 0.1);
|
||||
rangefinder = new LaserRangefinder(Position, Orientation, 5000, 1000);
|
||||
}
|
||||
|
||||
// 更新方法,每帧调用
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
if (ShouldSelfDestruct())
|
||||
{
|
||||
SelfDestruct();
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"末敏弹 {Id} 当前位置: {Position}");
|
||||
Console.WriteLine($"末敏弹 {Id} 分离位置: {SeparationPosition}");
|
||||
|
||||
// 更新传感器
|
||||
infraredDetector.Update(deltaTime);
|
||||
radiometer.Update(deltaTime);
|
||||
altimeter.Update(deltaTime);
|
||||
rangefinder.Update(deltaTime);
|
||||
|
||||
// 使用当前阶段的策略更新导弹状态
|
||||
if (stageStrategies.TryGetValue(currentWorkingStage, out var updateStrategy))
|
||||
{
|
||||
updateStrategy(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
// 发射阶段更新方法
|
||||
private void UpdateLaunchStage(double deltaTime)
|
||||
{
|
||||
// 无动力抛物线飞行
|
||||
ApplyGravity(deltaTime);
|
||||
|
||||
base.UpdateMotionState(deltaTime, GuidanceCommand);
|
||||
|
||||
if (Vector3D.Distance(Position, SeparationPosition) <= 200)
|
||||
{
|
||||
currentWorkingStage = TerminalSensitiveStage.Separation;
|
||||
}
|
||||
}
|
||||
|
||||
// 分离阶段更新方法
|
||||
private void UpdateSeparationStage(double deltaTime)
|
||||
{
|
||||
Console.WriteLine($"末敏弹 {Id} 进入分离");
|
||||
|
||||
// 根据速度大小调整制导指令
|
||||
switch(Velocity.Magnitude())
|
||||
{
|
||||
case >= 200:
|
||||
GuidanceCommand = new Vector3D(400, -400, 0);
|
||||
break;
|
||||
case >= 100:
|
||||
GuidanceCommand = new Vector3D(30, -30, 0);
|
||||
break;
|
||||
case >= 50:
|
||||
GuidanceCommand = new Vector3D(20, -20, 0);
|
||||
break;
|
||||
case >= 20:
|
||||
GuidanceCommand = new Vector3D(5, -10, 0);
|
||||
break;
|
||||
default:
|
||||
GuidanceCommand = new Vector3D(0, -10, 0);
|
||||
break;
|
||||
}
|
||||
base.UpdateMotionState(deltaTime, GuidanceCommand);
|
||||
|
||||
if (Position.Y <= DecelerationHeight)
|
||||
{
|
||||
currentWorkingStage = TerminalSensitiveStage.Deceleration;
|
||||
}
|
||||
}
|
||||
|
||||
// 减速阶段更新方法
|
||||
private void UpdateDecelerationStage(double deltaTime)
|
||||
{
|
||||
Console.WriteLine($"末敏弹 {Id} 进入减速");
|
||||
// 减速下降
|
||||
Velocity = new Vector3D(0, -VerticalDescentSpeed, 0);
|
||||
Position += Velocity * deltaTime;
|
||||
|
||||
if (Position.Y <= ScanningHeight)
|
||||
{
|
||||
currentWorkingStage = TerminalSensitiveStage.SpiralScan;
|
||||
}
|
||||
}
|
||||
|
||||
// 螺旋扫描阶段更新方法
|
||||
private void UpdateSpiralScanStage(double deltaTime)
|
||||
{
|
||||
Console.WriteLine($"末敏弹 {Id} 进入螺旋扫描");
|
||||
|
||||
spiralAngle += SpiralRotationSpeed * deltaTime;
|
||||
|
||||
// 计算水平速度分量
|
||||
double horizontalSpeed = VerticalDescentSpeed * Math.Tan(ScanAngle);
|
||||
Vector3D horizontalVelocity = new Vector3D(
|
||||
Math.Cos(spiralAngle) * horizontalSpeed,
|
||||
0,
|
||||
Math.Sin(spiralAngle) * horizontalSpeed
|
||||
);
|
||||
|
||||
// 更新速度
|
||||
Velocity = new Vector3D(horizontalVelocity.X, -VerticalDescentSpeed, horizontalVelocity.Z);
|
||||
|
||||
// 计算扫描方向
|
||||
Vector3D scanDirection = new Vector3D(
|
||||
Math.Cos(spiralAngle) * Math.Sin(ScanAngle),
|
||||
-Math.Cos(ScanAngle),
|
||||
Math.Sin(spiralAngle) * Math.Sin(ScanAngle)
|
||||
);
|
||||
|
||||
if (DetectTarget(scanDirection))
|
||||
{
|
||||
if (!targetDetected)
|
||||
{
|
||||
targetDetected = true;
|
||||
detectionAngle = spiralAngle;
|
||||
}
|
||||
else if (Math.Abs(spiralAngle - detectionAngle) < 0.1) // 允许一定的误差
|
||||
{
|
||||
currentWorkingStage = TerminalSensitiveStage.Attack;
|
||||
}
|
||||
}
|
||||
|
||||
lastScanDirection = scanDirection;
|
||||
|
||||
if (Position.Y <= SelfDestructHeight)
|
||||
{
|
||||
currentWorkingStage = TerminalSensitiveStage.SelfDestruct;
|
||||
}
|
||||
}
|
||||
|
||||
// 攻击阶段更新方法
|
||||
private void UpdateAttackStage(double deltaTime)
|
||||
{
|
||||
// 攻击逻辑
|
||||
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
||||
Vector3D direction = (targetPosition - Position).Normalize();
|
||||
Velocity = direction * MaxSpeed;
|
||||
|
||||
if (Vector3D.Distance(Position, targetPosition) < 1)
|
||||
{
|
||||
Explode();
|
||||
}
|
||||
}
|
||||
|
||||
// 自毁阶段更新方法
|
||||
private void UpdateSelfDestructStage(double deltaTime)
|
||||
{
|
||||
// 实现自毁逻辑
|
||||
Explode();
|
||||
}
|
||||
|
||||
// 目标检测方法
|
||||
private bool DetectTarget(Vector3D scanDirection)
|
||||
{
|
||||
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
||||
Vector3D toTarget = (targetPosition - Position).Normalize();
|
||||
|
||||
// 检查目标是否在扫描线上
|
||||
return Vector3D.DotProduct(scanDirection, toTarget) > Math.Cos(0.5 * Math.PI / 180); // 允许0.5度的误差
|
||||
}
|
||||
|
||||
// 应用重力
|
||||
private void ApplyGravity(double deltaTime)
|
||||
{
|
||||
GuidanceCommand = new Vector3D(0, -9.81, 0);
|
||||
}
|
||||
|
||||
// 获取导弹状态
|
||||
public override string GetStatus()
|
||||
{
|
||||
string baseStatus = base.GetStatus().Replace("导弹", "末敏弹");
|
||||
string additionalStatus = $"\n 扫描阶段: {(currentWorkingStage == TerminalSensitiveStage.SpiralScan ? "有效" : "无效")} \n";
|
||||
return baseStatus + additionalStatus;
|
||||
}
|
||||
|
||||
// 激活导弹
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
// 可以在这里添加订阅事件的代码
|
||||
}
|
||||
|
||||
// 停用导弹
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
// 可以在这里添加取消订阅事件的代码
|
||||
}
|
||||
|
||||
// 静态方法:计算发射参数
|
||||
public static (double angle, double distance) CalculateLaunchParameters(double initialVelocity, double targetHeight, double targetDistance)
|
||||
{
|
||||
double g = 9.8; // 重力加速度
|
||||
double v = initialVelocity;
|
||||
double y = targetHeight;
|
||||
double x = targetDistance;
|
||||
|
||||
// 计算发射角度(弧度)
|
||||
double angle = Math.Atan((v * v + Math.Sqrt(Math.Pow(v, 4) - g * (g * x * x + 2 * y * v * v))) / (g * x));
|
||||
|
||||
// 计算水平飞行距离
|
||||
double t = x / (v * Math.Cos(angle));
|
||||
double totalDistance = v * Math.Cos(angle) * t;
|
||||
|
||||
return (angle, totalDistance);
|
||||
}
|
||||
|
||||
// 静态方法:计算发射位置
|
||||
public static Vector3D CalculateLaunchPosition(Vector3D knownPoint, Vector3D velocity)
|
||||
{
|
||||
double g = 9.8; // 重力加速度
|
||||
double x = knownPoint.X;
|
||||
double y = knownPoint.Y;
|
||||
double vx = velocity.X;
|
||||
double vy = velocity.Y;
|
||||
|
||||
// 计算时间 t
|
||||
double t = (-vy - Math.Sqrt(vy * vy + 2 * g * y)) / -g;
|
||||
|
||||
// 计算发射点的 x 坐标
|
||||
double launchX = x - vx * t;
|
||||
|
||||
// 发射点的 y 和 z 坐标为 0
|
||||
return new Vector3D(launchX, 0, 0);
|
||||
}
|
||||
|
||||
// 静态方法:计算轨迹上的点
|
||||
public static Vector3D CalculatePointOnTrajectory(Vector3D launchPosition, Vector3D targetPosition, double distanceFromTarget, double height)
|
||||
{
|
||||
// 确保发射位置和目标位置的y坐标为0
|
||||
launchPosition = new Vector3D(launchPosition.X, 0, launchPosition.Z);
|
||||
targetPosition = new Vector3D(targetPosition.X, 0, targetPosition.Z);
|
||||
|
||||
// 计算发射方向向量
|
||||
Vector3D direction = targetPosition - launchPosition;
|
||||
|
||||
// 计算总距离
|
||||
double totalDistance = direction.Magnitude();
|
||||
|
||||
// 归一化方向向量
|
||||
direction = direction.Normalize();
|
||||
|
||||
// 计算所需点的位置
|
||||
Vector3D pointOnTrajectory = targetPosition - direction * distanceFromTarget;
|
||||
|
||||
// 返回结果,y坐标设置为指定的高度
|
||||
return new Vector3D(pointOnTrajectory.X, height, pointOnTrajectory.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,12 +2,19 @@ using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public interface IGuidanceSystem
|
||||
/// <summary>
|
||||
/// 制导系统接口
|
||||
/// </summary>
|
||||
public interface IGuidanceSystem
|
||||
{
|
||||
bool HasGuidance { get; }
|
||||
void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity);
|
||||
Vector3D GetGuidanceAcceleration();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 基础制导系统
|
||||
/// </summary>
|
||||
public class BasicGuidanceSystem : IGuidanceSystem
|
||||
{
|
||||
public bool HasGuidance { get; protected set; }
|
||||
@ -23,17 +30,31 @@ namespace ActiveProtect.Models
|
||||
Velocity = Vector3D.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新制导系统
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
/// <param name="missilePosition">导弹位置</param>
|
||||
/// <param name="missileVelocity">导弹速度</param>
|
||||
public virtual void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
|
||||
{
|
||||
Position = missilePosition;
|
||||
Velocity = missileVelocity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取制导加速度
|
||||
/// </summary>
|
||||
/// <returns>制导加速度</returns>
|
||||
public Vector3D GetGuidanceAcceleration()
|
||||
{
|
||||
return GuidanceAcceleration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算制导加速度
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
protected virtual void CalculateGuidanceAcceleration(double deltaTime)
|
||||
{
|
||||
// 基础制导系统不计算制导指令
|
||||
@ -43,12 +64,13 @@ namespace ActiveProtect.Models
|
||||
/// <summary>
|
||||
/// 计算比例导引加速度
|
||||
/// </summary>
|
||||
/// <param name="proportionalNavigationCoefficient">比例导引系数</param>
|
||||
/// <param name="missilePosition">导弹位置</param>
|
||||
/// <param name="missileVelocity">导弹速度</param>
|
||||
/// <param name="targetPosition">目标位置</param>
|
||||
/// <param name="targetVelocity">目标速度</param>
|
||||
/// <returns>比例导引加速度</returns>
|
||||
protected Vector3D CalculateProportionalNavigation(double proportionalNavigationCoefficient, Vector3D missilePosition, Vector3D missileVelocity, Vector3D targetPosition, Vector3D targetVelocity)
|
||||
protected static Vector3D CalculateProportionalNavigation(double proportionalNavigationCoefficient, Vector3D missilePosition, Vector3D missileVelocity, Vector3D targetPosition, Vector3D targetVelocity)
|
||||
{
|
||||
// 预测时间(预测目标前进方向该时间后到达的位置,可以调整)
|
||||
double predictionTime = 0.01;
|
||||
@ -67,6 +89,14 @@ namespace ActiveProtect.Models
|
||||
return acceleration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 四阶龙格库塔法计算导弹运动状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
/// <param name="position">导弹位置</param>
|
||||
/// <param name="velocity">导弹速度</param>
|
||||
/// <param name="acceleration">导弹加速度</param>
|
||||
/// <returns>新的位置和速度</returns>
|
||||
public static (Vector3D newPosition, Vector3D newVelocity) RungeKutta4(double deltaTime, Vector3D position, Vector3D velocity, Vector3D acceleration)
|
||||
{
|
||||
// 定义一个局部函数来计算加速度
|
||||
@ -98,5 +128,14 @@ namespace ActiveProtect.Models
|
||||
|
||||
return (newPosition, newVelocity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取制导系统状态
|
||||
/// </summary>
|
||||
/// <returns>制导系统状态</returns>
|
||||
public virtual string GetStatus()
|
||||
{
|
||||
return $"BasicGuidanceSystem: HasGuidance={HasGuidance}, Position={Position}, Velocity={Velocity}, GuidanceAcceleration={GuidanceAcceleration}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,16 +99,25 @@ namespace ActiveProtect.Models
|
||||
return new Vector3D(-a.X, -a.Y, -a.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向量相等运算符重载
|
||||
/// </summary>
|
||||
public static bool operator ==(Vector3D left, Vector3D right)
|
||||
{
|
||||
return left.X == right.X && left.Y == right.Y && left.Z == right.Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向量不相等运算符重载
|
||||
/// </summary>
|
||||
public static bool operator !=(Vector3D left, Vector3D right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断两个向量是否相等
|
||||
/// </summary>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is Vector3D other)
|
||||
@ -118,6 +127,10 @@ namespace ActiveProtect.Models
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取向量的哈希码
|
||||
/// </summary>
|
||||
/// <returns>向量的哈希码</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(X, Y, Z);
|
||||
@ -320,17 +333,28 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表示二维空间中的向量
|
||||
/// </summary>
|
||||
public struct Vector2D
|
||||
{
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="x">X坐标</param>
|
||||
/// <param name="y">Y坐标</param>
|
||||
public Vector2D(double x, double y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 零向量
|
||||
/// </summary>
|
||||
public static Vector2D Zero => new Vector2D(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,9 +40,13 @@ namespace ActiveProtect.Models
|
||||
IsBeamOn = false;
|
||||
MissileId = missileId;
|
||||
TargetId = targetId;
|
||||
SimulationManager = simulationManager;
|
||||
base.SimulationManager = simulationManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新激光驾束仪
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (IsActive && IsBeamOn)
|
||||
@ -88,6 +92,9 @@ namespace ActiveProtect.Models
|
||||
base.Deactivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开启激光束照射
|
||||
/// </summary>
|
||||
public void StartBeamIllumination()
|
||||
{
|
||||
if (!IsBeamOn)
|
||||
@ -98,6 +105,9 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止激光束照射
|
||||
/// </summary>
|
||||
public void StopBeamIllumination()
|
||||
{
|
||||
if (IsBeamOn)
|
||||
@ -141,6 +151,10 @@ namespace ActiveProtect.Models
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取激光驾束仪状态
|
||||
/// </summary>
|
||||
/// <returns>激光驾束仪状态</returns>
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"激光驾束仪 {Id}:\n" +
|
||||
|
||||
@ -2,26 +2,59 @@ using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光驾束制导系统
|
||||
/// </summary>
|
||||
public class LaserBeamRiderGuidanceSystem : BasicGuidanceSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光源位置
|
||||
/// </summary>
|
||||
private Vector3D LaserSourcePosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光方向
|
||||
/// </summary>
|
||||
private Vector3D LaserDirection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光功率
|
||||
/// </summary>
|
||||
public double LaserPower { get; set; }
|
||||
|
||||
private const double MinDetectablePower = 1e-3; // 假设最小可探测功率为1毫瓦
|
||||
private const double DetectorDiameter = 0.1; // 假设探测器直径为10厘米
|
||||
private const double ControlFieldDiameter = 20.0; // 控制场直径(米)
|
||||
|
||||
/// <summary>
|
||||
/// 上一次的误差
|
||||
/// </summary>
|
||||
private Vector3D LastError = Vector3D.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// 上一次的制导加速度
|
||||
/// </summary>
|
||||
public Vector3D LastGuidanceAcceleration { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 积分误差
|
||||
/// </summary>
|
||||
private Vector3D IntegralError = Vector3D.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// 比例导引系数
|
||||
/// </summary>
|
||||
private double ProportionalNavigationCoefficient { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光照射是否开启
|
||||
/// </summary>
|
||||
private bool LaserIlluminationOn { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public LaserBeamRiderGuidanceSystem()
|
||||
{
|
||||
LaserSourcePosition = Vector3D.Zero;
|
||||
@ -32,6 +65,12 @@ namespace ActiveProtect.Models
|
||||
ProportionalNavigationCoefficient = 3;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新激光驾束仪
|
||||
/// </summary>
|
||||
/// <param name="sourcePosition">激光源位置</param>
|
||||
/// <param name="direction">激光方向</param>
|
||||
/// <param name="laserPower">激光功率</param>
|
||||
public void UpdateLaserBeamRider(Vector3D sourcePosition, Vector3D direction, double laserPower)
|
||||
{
|
||||
LaserIlluminationOn = true;
|
||||
@ -40,7 +79,10 @@ namespace ActiveProtect.Models
|
||||
LaserPower = laserPower;
|
||||
}
|
||||
|
||||
public void DeactivateLaserBeam(Vector3D sourcePosition, Vector3D direction)
|
||||
/// <summary>
|
||||
/// 关闭激光照射
|
||||
/// </summary>
|
||||
public void DeactivateLaserBeam()
|
||||
{
|
||||
LaserSourcePosition = Vector3D.Zero;
|
||||
LaserDirection = Vector3D.Zero;
|
||||
@ -48,6 +90,12 @@ namespace ActiveProtect.Models
|
||||
HasGuidance = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新制导系统
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
/// <param name="missilePosition">导弹位置</param>
|
||||
/// <param name="missileVelocity">导弹速度</param>
|
||||
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
|
||||
{
|
||||
base.Update(deltaTime, missilePosition, missileVelocity);
|
||||
@ -70,6 +118,9 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新制导状态
|
||||
/// </summary>
|
||||
private void UpdateGuidanceStatus()
|
||||
{
|
||||
// 计算导弹到激光束的最短距离
|
||||
@ -102,6 +153,10 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算制导加速度
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
protected override void CalculateGuidanceAcceleration(double deltaTime)
|
||||
{
|
||||
if (!HasGuidance)
|
||||
@ -171,11 +226,19 @@ namespace ActiveProtect.Models
|
||||
//Console.WriteLine($"Guidance Command: {GuidanceCommand.Magnitude()}, Lateral Error: {shortestDistanceVector.Magnitude()}, Lateral Acceleration: {lateralAcceleration.Magnitude()}, Forward Acceleration: {forwardAcceleration.Magnitude()}");
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
/// <summary>
|
||||
/// 获取制导系统状态
|
||||
/// </summary>
|
||||
/// <returns>制导系统状态</returns>
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"LaserBeamRiderGuidanceSystem: HasGuidance={HasGuidance}, LaserSourcePosition={LaserSourcePosition}, LaserDirection={LaserDirection}, GuidanceAcceleration={GuidanceAcceleration}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算导弹到激光束的最短距离
|
||||
/// </summary>
|
||||
/// <returns>最短距离向量</returns>
|
||||
private Vector3D CalculateShortestDistanceToLaserBeam()
|
||||
{
|
||||
// 计算导弹到激光源的向量
|
||||
|
||||
@ -14,19 +14,33 @@ namespace ActiveProtect.Models
|
||||
Explode, // 爆炸阶段
|
||||
SelfDestruct // 自毁阶段
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前阶段
|
||||
/// </summary>
|
||||
private LBRM_Stage currentStage;
|
||||
private LaserBeamRiderGuidanceSystem LaserBeamRiderGuidanceSystem;
|
||||
private MissileConfig missileConfig;
|
||||
|
||||
/// <summary>
|
||||
/// 激光驾束制导系统
|
||||
/// </summary>
|
||||
private readonly LaserBeamRiderGuidanceSystem LaserBeamRiderGuidanceSystem;
|
||||
|
||||
public LaserBeamRiderMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig, simulationManager)
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="config">导弹配置</param>
|
||||
/// <param name="manager">模拟管理器</param>
|
||||
public LaserBeamRiderMissile(MissileConfig config, ISimulationManager manager)
|
||||
: base(config, manager)
|
||||
{
|
||||
LaserBeamRiderGuidanceSystem = new LaserBeamRiderGuidanceSystem();
|
||||
currentStage = LBRM_Stage.Launch;
|
||||
this.missileConfig = missileConfig;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光束开启事件
|
||||
/// </summary>
|
||||
/// <param name="evt">激光束开启事件</param>
|
||||
private void OnLaserBeamStart(LaserBeamStartEvent evt)
|
||||
{
|
||||
if (evt?.LaserBeamRider != null)
|
||||
@ -35,6 +49,10 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光束更新事件
|
||||
/// </summary>
|
||||
/// <param name="evt">激光束更新事件</param>
|
||||
private void OnLaserBeamUpdate(LaserBeamUpdateEvent evt)
|
||||
{
|
||||
if (evt?.LaserBeamRider != null)
|
||||
@ -43,14 +61,22 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光束停止事件
|
||||
/// </summary>
|
||||
/// <param name="evt">激光束停止事件</param>
|
||||
private void OnLaserBeamStop(LaserBeamStopEvent evt)
|
||||
{
|
||||
if (evt?.LaserBeamRider != null)
|
||||
{
|
||||
LaserBeamRiderGuidanceSystem?.DeactivateLaserBeam(evt.LaserBeamRider.Position, evt.LaserBeamRider.LaserDirection);
|
||||
LaserBeamRiderGuidanceSystem?.DeactivateLaserBeam();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导弹
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
switch (currentStage)
|
||||
@ -65,13 +91,17 @@ namespace ActiveProtect.Models
|
||||
UpdateExplodeStage(deltaTime);
|
||||
break;
|
||||
case LBRM_Stage.SelfDestruct:
|
||||
SelfDestruct();
|
||||
UpdateSelfDestructStage(deltaTime);
|
||||
break;
|
||||
}
|
||||
|
||||
base.Update(deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新发射阶段
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
private void UpdateLaunchStage(double deltaTime)
|
||||
{
|
||||
// 发射阶段
|
||||
@ -82,29 +112,49 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新巡航阶段
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
private void UpdateCruiseStage(double deltaTime)
|
||||
{
|
||||
// 巡航阶段
|
||||
LaserBeamRiderGuidanceSystem.Update(deltaTime, Position, Velocity);
|
||||
GuidanceAcceleration = LaserBeamRiderGuidanceSystem.GetGuidanceAcceleration();
|
||||
if (DistanceToTarget <= missileConfig.DistanceParams.ExplosionDistance)
|
||||
if (DistanceToTarget <= ExplosionRadius)
|
||||
{
|
||||
currentStage = LBRM_Stage.Explode;
|
||||
}
|
||||
if(ShouldSelfDestruct())
|
||||
{
|
||||
currentStage = LBRM_Stage.SelfDestruct;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新爆炸阶段
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
private void UpdateExplodeStage(double deltaTime)
|
||||
{
|
||||
// 爆炸阶段
|
||||
Explode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新自毁阶段
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
private void UpdateSelfDestructStage(double deltaTime)
|
||||
{
|
||||
// 自毁阶段
|
||||
SelfDestruct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取导弹状态
|
||||
/// </summary>
|
||||
/// <returns>导弹状态</returns>
|
||||
public override string GetStatus()
|
||||
{
|
||||
string baseStatus = base.GetStatus().Replace("导弹", "激光驾束制导导弹");
|
||||
@ -112,6 +162,9 @@ namespace ActiveProtect.Models
|
||||
return baseStatus + additionalStatus;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活导弹
|
||||
/// </summary>
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
@ -120,6 +173,9 @@ namespace ActiveProtect.Models
|
||||
SimulationManager.SubscribeToEvent<LaserBeamUpdateEvent>(OnLaserBeamUpdate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭导弹
|
||||
/// </summary>
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
|
||||
@ -112,8 +112,7 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
if (evt.TargetId == TargetId)
|
||||
{
|
||||
var tank = SimulationManager.GetEntityById(TargetId) as Tank;
|
||||
if (tank != null)
|
||||
if (SimulationManager.GetEntityById(TargetId) is Tank tank)
|
||||
{
|
||||
double distanceToTarget = Vector3D.Distance(Position, tank.Position);
|
||||
double jammingEffectiveness = 20 * Math.Log10(evt.JammingPower) - 20 * Math.Log10(distanceToTarget) - 20 * Math.Log10(4 * Math.PI);
|
||||
|
||||
@ -67,8 +67,8 @@ namespace ActiveProtect.Models
|
||||
maxJammingPower = config.MaxJammingPower;
|
||||
initialJammingPower = config.InitialJammingPower;
|
||||
powerIncreaseRate = config.PowerIncreaseRate;
|
||||
SimulationManager.SubscribeToEvent<LaserWarnerAlarmEvent>(OnLaserWarnerAlarmEvent);
|
||||
SimulationManager.SubscribeToEvent<LaserWarnerAlarmStopEvent>(OnLaserWarnerAlarmStopEvent);
|
||||
base.SimulationManager.SubscribeToEvent<LaserWarnerAlarmEvent>(OnLaserWarnerAlarmEvent);
|
||||
base.SimulationManager.SubscribeToEvent<LaserWarnerAlarmStopEvent>(OnLaserWarnerAlarmStopEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -2,6 +2,9 @@ using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光半主动制导系统
|
||||
/// </summary>
|
||||
public class LaserSemiActiveGuidanceSystem : BasicGuidanceSystem
|
||||
{
|
||||
private const double FieldOfViewAngle = Math.PI / 6; // 30度视场角
|
||||
@ -10,16 +13,46 @@ namespace ActiveProtect.Models
|
||||
private const double ReflectionCoefficient = 0.2; // 反射系数
|
||||
private const double LockThreshold = 1e-12; // 锁定阈值(瓦特)
|
||||
private const double TargetReflectiveArea = 1.0; // 目标有效反射面积(平方米)
|
||||
|
||||
/// <summary>
|
||||
/// 目标位置
|
||||
/// </summary>
|
||||
private Vector3D TargetPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标速度
|
||||
/// </summary>
|
||||
private Vector3D TargetVelocity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光照射是否开启
|
||||
/// </summary>
|
||||
private bool LaserIlluminationOn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光指示器位置
|
||||
/// </summary>
|
||||
private Vector3D LaserDesignatorPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光功率
|
||||
/// </summary>
|
||||
private double LaserPower { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激光发散角
|
||||
/// </summary>
|
||||
private double LaserDivergenceAngle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 比例导航系数
|
||||
/// </summary>
|
||||
private double ProportionalNavigationCoefficient { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public LaserSemiActiveGuidanceSystem()
|
||||
{
|
||||
TargetPosition = Vector3D.Zero;
|
||||
@ -30,6 +63,14 @@ namespace ActiveProtect.Models
|
||||
ProportionalNavigationCoefficient = 4;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新激光指示器
|
||||
/// </summary>
|
||||
/// <param name="sourcePosition">激光源位置</param>
|
||||
/// <param name="targetPosition">目标位置</param>
|
||||
/// <param name="targetVelocity">目标速度</param>
|
||||
/// <param name="laserPower">激光功率</param>
|
||||
/// <param name="laserDivergenceAngle">激光发散角</param>
|
||||
public void UpdateLaserDesignator(Vector3D sourcePosition, Vector3D targetPosition, Vector3D targetVelocity, double laserPower, double laserDivergenceAngle)
|
||||
{
|
||||
LaserIlluminationOn = true;
|
||||
@ -40,6 +81,9 @@ namespace ActiveProtect.Models
|
||||
LaserDivergenceAngle = laserDivergenceAngle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭激光照射
|
||||
/// </summary>
|
||||
public void DeactivateLaserDesignator()
|
||||
{
|
||||
LaserIlluminationOn = false;
|
||||
@ -50,6 +94,12 @@ namespace ActiveProtect.Models
|
||||
LaserDivergenceAngle = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新制导系统
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
/// <param name="missilePosition">导弹位置</param>
|
||||
/// <param name="missileVelocity">导弹速度</param>
|
||||
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
|
||||
{
|
||||
base.Update(deltaTime, missilePosition, missileVelocity);
|
||||
@ -69,10 +119,12 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
}
|
||||
|
||||
PrintGuidanceInfo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算接收到的激光功率
|
||||
/// </summary>
|
||||
/// <returns>接收到的激光功率</returns>
|
||||
private double CalculateReceivedLaserPower()
|
||||
{
|
||||
double distanceDesignatorToTarget = (LaserDesignatorPosition - TargetPosition).Magnitude();
|
||||
@ -108,9 +160,12 @@ namespace ActiveProtect.Models
|
||||
return finalReceivedPower;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算制导加速度
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
protected override void CalculateGuidanceAcceleration(double deltaTime)
|
||||
{
|
||||
Console.WriteLine($"激光半主动导弹引导加速度计算: 位置: {Position}, 速度: {Velocity}, 目标位置: {TargetPosition}, 目标速度: {TargetVelocity}");
|
||||
// 计算比例导引加速度
|
||||
GuidanceAcceleration = CalculateProportionalNavigation(ProportionalNavigationCoefficient, Position, Velocity, TargetPosition, TargetVelocity);
|
||||
|
||||
@ -122,18 +177,12 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
}
|
||||
|
||||
private void PrintGuidanceInfo()
|
||||
/// <summary>
|
||||
/// 获取制导系统状态
|
||||
/// </summary>
|
||||
public override string GetStatus()
|
||||
{
|
||||
Console.WriteLine($"激光半主动导弹引导信息:");
|
||||
Console.WriteLine($" 位置: {Position}");
|
||||
Console.WriteLine($" 速度: {Velocity}");
|
||||
Console.WriteLine($" 速度大小: {Velocity.Magnitude():F2} m/s");
|
||||
Console.WriteLine($" 是否有引导: {HasGuidance}");
|
||||
Console.WriteLine($" 目标位置: {TargetPosition}");
|
||||
Console.WriteLine($" 制导加速度: {GuidanceAcceleration}");
|
||||
Console.WriteLine($" 接收到的激光功率: {CalculateReceivedLaserPower():E} W");
|
||||
Console.WriteLine($" 锁定阈值: {LockThreshold:E} W");
|
||||
Console.WriteLine();
|
||||
return base.GetStatus() + $" 接收到的激光功率: {CalculateReceivedLaserPower():E} W 锁定阈值: {LockThreshold:E} W";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,25 +18,22 @@ namespace ActiveProtect.Models
|
||||
Explode, // 爆炸阶段
|
||||
SelfDestruct // 自毁阶段
|
||||
}
|
||||
|
||||
private LSAGM_Stage currentStage;
|
||||
private LaserSemiActiveGuidanceSystem LaserGuidanceSystem;
|
||||
public string LaserDesignatorId { get; set; } = "";
|
||||
private MissileConfig missileConfig;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">导弹ID</param>
|
||||
/// <param name="laserDesignatorId">激光指示器ID</param>
|
||||
/// <param name="missileConfig">导弹配置</param>
|
||||
/// <param name="config">导弹配置</param>
|
||||
/// <param name="simulationManager">仿真管理器</param>
|
||||
public LaserSemiActiveGuidedMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig, simulationManager)
|
||||
public LaserSemiActiveGuidedMissile(MissileConfig config, ISimulationManager manager)
|
||||
: base(config, manager)
|
||||
{
|
||||
LaserGuidanceSystem = new LaserSemiActiveGuidanceSystem();
|
||||
currentStage = LSAGM_Stage.Launch;
|
||||
this.missileConfig = missileConfig;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -141,10 +138,15 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
LaserGuidanceSystem.Update(deltaTime, Position, Velocity);
|
||||
GuidanceAcceleration = LaserGuidanceSystem.GetGuidanceAcceleration();
|
||||
if (DistanceToTarget <= missileConfig.DistanceParams.ExplosionDistance)
|
||||
Console.WriteLine($"导弹ID: {Id}, 距离目标: {DistanceToTarget}, 爆炸半径: {ExplosionRadius}");
|
||||
if (DistanceToTarget <= ExplosionRadius)
|
||||
{
|
||||
currentStage = LSAGM_Stage.Explode;
|
||||
}
|
||||
if(ShouldSelfDestruct())
|
||||
{
|
||||
currentStage = LSAGM_Stage.SelfDestruct;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateExplodeStage(double deltaTime)
|
||||
|
||||
@ -43,8 +43,8 @@ namespace ActiveProtect.Models
|
||||
MonitoredEntityId = monitoredEntityId;
|
||||
IsAlarming = false;
|
||||
alarmDuration = config.AlarmDuration;
|
||||
SimulationManager.SubscribeToEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
|
||||
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||
base.SimulationManager.SubscribeToEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
|
||||
base.SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -56,9 +56,9 @@ namespace ActiveProtect.Models
|
||||
public double DistanceToTarget { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹距离参数
|
||||
/// 爆炸半径(米)
|
||||
/// </summary>
|
||||
public MissileDistanceParams DistanceParams { get; protected set; }
|
||||
public double ExplosionRadius { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上一帧目标位置
|
||||
@ -130,54 +130,55 @@ namespace ActiveProtect.Models
|
||||
/// </summary>
|
||||
protected Vector3D ThrustAcceleration { get; set; }
|
||||
|
||||
protected readonly MissileConfig MissileConfig;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public MissileBase(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, missileConfig.InitialSpeed, simulationManager)
|
||||
public MissileBase(MissileConfig config, ISimulationManager manager)
|
||||
: base(config.Id, config.InitialPosition, config.InitialOrientation, config.InitialSpeed, manager)
|
||||
{
|
||||
// 初始化导弹属性
|
||||
Speed = missileConfig.InitialSpeed;
|
||||
MaxSpeed = missileConfig.MaxSpeed;
|
||||
MaxFlightTime = missileConfig.MaxFlightTime;
|
||||
MaxFlightDistance = missileConfig.MaxFlightDistance;
|
||||
DistanceParams = missileConfig.DistanceParams;
|
||||
MissileConfig = config;
|
||||
SimulationManager = manager;
|
||||
InitializeFromConfig();
|
||||
|
||||
IsActive = false;
|
||||
FlightTime = 0;
|
||||
FlightDistance = 0;
|
||||
SimulationManager = simulationManager;
|
||||
LaunchAcceleration = missileConfig.LaunchAcceleration;
|
||||
EngineBurnTime = 0;
|
||||
MaxEngineBurnTime = missileConfig.MaxEngineBurnTime;
|
||||
MaxAcceleration = missileConfig.MaxAcceleration;
|
||||
ProportionalNavigationCoefficient = missileConfig.ProportionalNavigationCoefficient;
|
||||
TargetId = $"Tank_{missileConfig.TargetIndex + 1}";
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
ThrustAcceleration = Vector3D.Zero;
|
||||
LastTargetPosition = Vector3D.Zero;
|
||||
TargetId = $"Tank_{config.TargetIndex + 1}";
|
||||
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从配置初始化导弹
|
||||
/// </summary>
|
||||
private void InitializeFromConfig()
|
||||
{
|
||||
// 初始化导弹属性
|
||||
Speed = MissileConfig.InitialSpeed;
|
||||
MaxSpeed = MissileConfig.MaxSpeed;
|
||||
MaxFlightTime = MissileConfig.MaxFlightTime;
|
||||
MaxFlightDistance = MissileConfig.MaxFlightDistance;
|
||||
ExplosionRadius = MissileConfig.ExplosionRadius;
|
||||
LaunchAcceleration = MissileConfig.LaunchAcceleration;
|
||||
MaxEngineBurnTime = MissileConfig.MaxEngineBurnTime;
|
||||
MaxAcceleration = MissileConfig.MaxAcceleration;
|
||||
ProportionalNavigationCoefficient = MissileConfig.ProportionalNavigationCoefficient;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导弹状态
|
||||
/// </summary>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
if (ShouldSelfDestruct())
|
||||
if (IsActive)
|
||||
{
|
||||
SelfDestruct();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
UpdateMotionState(deltaTime);
|
||||
|
||||
if (CheckHit())
|
||||
{
|
||||
Explode();
|
||||
return;
|
||||
// 更新导弹运动状态
|
||||
UpdateMotionState(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,53 +210,10 @@ namespace ActiveProtect.Models
|
||||
/// </summary>
|
||||
private Vector3D CalculateAcceleration(Vector3D velocity)
|
||||
{
|
||||
// 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.05);
|
||||
// guidanceAcceleration = guidanceCommand * 1;
|
||||
// break;
|
||||
// case FlightStage.TerminalGuidance:
|
||||
// thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.05);
|
||||
// guidanceAcceleration = guidanceCommand * 1;
|
||||
// break;
|
||||
// case FlightStage.Attack:
|
||||
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration*0.05;
|
||||
// guidanceAcceleration = guidanceCommand * 1;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// if (!HasGuidance)
|
||||
// {
|
||||
// if (velocity.Magnitude() > 0)
|
||||
// {
|
||||
// ThrustAcceleration = LaunchAcceleration * velocity.Normalize();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ThrustAcceleration = LaunchAcceleration * velocity.Normalize();
|
||||
// }
|
||||
// }
|
||||
|
||||
//计算重力加速度(反坦克导弹一般升力很小, 主要依靠初始发射动能和持续的推力来维持飞行)
|
||||
//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;
|
||||
|
||||
Vector3D totalAcceleration = GuidanceAcceleration + ThrustAcceleration + dragAcceleration;
|
||||
|
||||
Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {GuidanceAcceleration}, 推力加速度: {ThrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
|
||||
if (totalAcceleration.Magnitude() > MaxAcceleration)
|
||||
@ -278,14 +236,6 @@ namespace ActiveProtect.Models
|
||||
return 0.5 * dragCoefficient * airDensity * referenceArea * speed * speed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否命中目标
|
||||
/// </summary>
|
||||
protected bool CheckHit()
|
||||
{
|
||||
return DistanceToTarget <= DistanceParams.ExplosionDistance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否应该自毁
|
||||
/// </summary>
|
||||
@ -320,20 +270,6 @@ namespace ActiveProtect.Models
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 计算比例导引加速度
|
||||
/// </summary>
|
||||
// private Vector3D CalculateProportionalNavigation(Vector3D position)
|
||||
// {
|
||||
// Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
||||
// Vector3D LOS = targetPosition - position;
|
||||
// Vector3D LOSRate = (targetPosition - LastTargetPosition) / FlightTime - Velocity;
|
||||
// LastTargetPosition = targetPosition;
|
||||
|
||||
// return Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), LOS).Normalize()
|
||||
// * ProportionalNavigationCoefficient * Velocity.Magnitude();
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹爆炸
|
||||
/// </summary>
|
||||
@ -375,7 +311,7 @@ namespace ActiveProtect.Models
|
||||
/// </summary>
|
||||
public override string GetStatus()
|
||||
{
|
||||
MissileRunningState missileRunningState = GetState();
|
||||
MissileRunningState missileRunningState = GetRunningState();
|
||||
return $"导弹 {missileRunningState.Id}:\n" +
|
||||
$" 位置: {missileRunningState.Position}\n" +
|
||||
$" 速度: {missileRunningState.Speed:F2} m/s\n" +
|
||||
@ -397,7 +333,7 @@ namespace ActiveProtect.Models
|
||||
// 基类中的默认实现
|
||||
}
|
||||
|
||||
public MissileRunningState GetState()
|
||||
public MissileRunningState GetRunningState()
|
||||
{
|
||||
return new MissileRunningState
|
||||
{
|
||||
@ -411,7 +347,6 @@ namespace ActiveProtect.Models
|
||||
FlightTime = FlightTime,
|
||||
FlightDistance = FlightDistance,
|
||||
DistanceToTarget = DistanceToTarget,
|
||||
//CurrentStage = CurrentStage,
|
||||
HasGuidance = HasGuidance,
|
||||
LostGuidanceTime = LostGuidanceTime,
|
||||
EngineBurnTime = EngineBurnTime,
|
||||
@ -475,11 +410,6 @@ namespace ActiveProtect.Models
|
||||
/// </summary>
|
||||
public double DistanceToTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前飞行阶段
|
||||
/// </summary>
|
||||
//public FlightStage CurrentStage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否有制导
|
||||
/// </summary>
|
||||
|
||||
@ -200,6 +200,10 @@ namespace ActiveProtect.Models
|
||||
/// </summary>
|
||||
public class MillimeterWaveAltimeter : Sensor
|
||||
{
|
||||
private double currentAltitude;
|
||||
|
||||
private TerminalSensitiveSubmunition submunition;
|
||||
|
||||
/// <summary>
|
||||
/// 最大测量高度
|
||||
/// </summary>
|
||||
@ -217,11 +221,13 @@ namespace ActiveProtect.Models
|
||||
/// <param name="orientation">测高雷达的朝向</param>
|
||||
/// <param name="maxAltitude">最大测量高度</param>
|
||||
/// <param name="accuracy">测量精度</param>
|
||||
public MillimeterWaveAltimeter(Vector3D position, Orientation orientation, double maxAltitude, double accuracy)
|
||||
: base(position, orientation)
|
||||
public MillimeterWaveAltimeter(TerminalSensitiveSubmunition submunition, double maxAltitude, double accuracy)
|
||||
: base(submunition.Position, submunition.Orientation)
|
||||
{
|
||||
MaxAltitude = maxAltitude;
|
||||
Accuracy = accuracy;
|
||||
currentAltitude = 0;
|
||||
this.submunition = submunition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -230,7 +236,8 @@ namespace ActiveProtect.Models
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 实现毫米波测高雷达的更新逻辑
|
||||
// 更新当前高度,考虑测量精度
|
||||
currentAltitude = submunition.Position.Y + Accuracy * new Random().NextDouble();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -240,7 +247,11 @@ namespace ActiveProtect.Models
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回毫米波测高雷达的数据
|
||||
return new AltimeterSensorData();
|
||||
AltimeterSensorData altimeterSensorData = new AltimeterSensorData
|
||||
{
|
||||
Altitude = currentAltitude
|
||||
};
|
||||
return altimeterSensorData;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -31,11 +31,10 @@ namespace ActiveProtect.Models
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="id">坦克ID</param>
|
||||
/// <param name="tankConfig">坦克配置</param>
|
||||
/// <param name="simulationManager">仿真管理器</param>
|
||||
public Tank(string id, TankConfig tankConfig, ISimulationManager simulationManager)
|
||||
: base(id, tankConfig.InitialPosition, tankConfig.InitialOrientation, tankConfig.InitialSpeed, simulationManager)
|
||||
public Tank(TankConfig tankConfig, ISimulationManager simulationManager)
|
||||
: base(tankConfig.Id, tankConfig.InitialPosition, tankConfig.InitialOrientation, tankConfig.InitialSpeed, simulationManager)
|
||||
{
|
||||
Speed = tankConfig.InitialSpeed;
|
||||
MaxSpeed = tankConfig.MaxSpeed;
|
||||
|
||||
@ -8,37 +8,32 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
// 分离高度 1000米,默认 1000 米
|
||||
private const double SeparationHeight = 1000;
|
||||
|
||||
// 分离点距离目标水平距离,默认 1000 米
|
||||
private const double SeparationDistance = 1000;
|
||||
|
||||
// 分离时距离分离点的距离阈值,默认 50米
|
||||
private const double SeparationRange = 50;
|
||||
|
||||
// 分离时距目标距离阈值,默认 1400 米
|
||||
private const double SeparationTargetDistance = 1400;
|
||||
|
||||
// 子弹数量, 155 口径母弹,默认 2 个
|
||||
private const int SubmunitionCount = 1;
|
||||
|
||||
// 子弹数组
|
||||
private TerminalSensitiveSubmunition[] submunitions;
|
||||
|
||||
// 分离点位置
|
||||
private Vector3D separationPoint;
|
||||
private readonly Vector3D separationPoint;
|
||||
|
||||
public MissileConfig missileConfig { get; set; }
|
||||
|
||||
public TerminalSensitiveMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig, simulationManager)
|
||||
public TerminalSensitiveMissile(MissileConfig config, ISimulationManager manager)
|
||||
: base(config, manager)
|
||||
{
|
||||
submunitions = new TerminalSensitiveSubmunition[SubmunitionCount];
|
||||
this.missileConfig = missileConfig;
|
||||
|
||||
|
||||
//计算分离点坐标,高度为SeparationHeight,距离目标的距离为SeparationDistance
|
||||
separationPoint = Vector3D.PointOnLine(SimulationManager.GetEntityById(TargetId).Position, Position, SeparationDistance) + new Vector3D(0, SeparationHeight, 0);
|
||||
separationPoint = Vector3D.PointOnLine(base.SimulationManager.GetEntityById(TargetId).Position, base.Position, SeparationDistance) + new Vector3D(0, SeparationHeight, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导弹
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间步长</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
@ -73,9 +68,10 @@ namespace ActiveProtect.Models
|
||||
Vector3D directionToTarget = (targetPosition - this.Position).Normalize();
|
||||
Orientation orientationToTarget = Orientation.FromVector(directionToTarget);
|
||||
|
||||
submunitions[i] = new TerminalSensitiveSubmunition($"{Id}_Sub_{i}",
|
||||
submunitions[i] = new TerminalSensitiveSubmunition(
|
||||
new MissileConfig
|
||||
{
|
||||
Id = $"{Id}_Sub_{i}",
|
||||
InitialPosition = this.Position,
|
||||
InitialOrientation = orientationToTarget, // 设置为朝向目标的方向
|
||||
InitialSpeed = 200, // 子弹初始速度
|
||||
@ -84,8 +80,9 @@ namespace ActiveProtect.Models
|
||||
MaxFlightTime = 50,
|
||||
MaxFlightDistance = 1000,
|
||||
MaxAcceleration = 50,
|
||||
ProportionalNavigationCoefficient = 0.1,
|
||||
Mass = 10
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
Mass = 10,
|
||||
ExplosionRadius = 10
|
||||
},
|
||||
SimulationManager);
|
||||
|
||||
@ -97,6 +94,10 @@ namespace ActiveProtect.Models
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取导弹状态
|
||||
/// </summary>
|
||||
/// <returns>导弹状态</returns>
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"{base.GetStatus()}\n母弹, 分离点: {separationPoint}";
|
||||
|
||||
@ -5,18 +5,25 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
public class TerminalSensitiveSubmunition : MissileBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 子弹阶段
|
||||
/// </summary>
|
||||
private enum SubmunitionStage
|
||||
{
|
||||
Separation,
|
||||
Deceleration,
|
||||
SpiralScan,
|
||||
Attack,
|
||||
Explode,
|
||||
SelfDestruct
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前阶段
|
||||
/// </summary>
|
||||
private SubmunitionStage currentStage;
|
||||
private double spiralAngle;
|
||||
private const double SpiralRotationSpeed = 4 * Math.PI; // 2 rotations per second
|
||||
|
||||
private const double SpiralRotationSpeed = 8 * Math.PI; // 4 rotations per second
|
||||
private const double VerticalDescentSpeed = 10; // 10 m/s
|
||||
private const double ScanAngle = 20 * Math.PI / 180; // 20 degrees in radians
|
||||
|
||||
@ -29,37 +36,50 @@ namespace ActiveProtect.Models
|
||||
// 自毁高度 20米
|
||||
private const double SelfDestructHeight = 20;
|
||||
|
||||
private const double AttackSpeed = 200;
|
||||
// 攻击速度 500 m/s
|
||||
private const double AttackSpeed = 500;
|
||||
|
||||
private Vector3D lastScanDirection;
|
||||
// 是否检测到目标
|
||||
private bool targetDetected;
|
||||
|
||||
/// <summary>
|
||||
/// 螺旋角度
|
||||
/// </summary>
|
||||
private double spiralAngle;
|
||||
|
||||
// 检测到目标的角度
|
||||
private double detectionAngle;
|
||||
|
||||
// 添加传感器
|
||||
private InfraredDetector infraredDetector;
|
||||
private MillimeterWaveRadiometer radiometer;
|
||||
private MillimeterWaveAltimeter altimeter;
|
||||
private LaserRangefinder rangefinder;
|
||||
// 弹载传感器
|
||||
private readonly InfraredDetector infraredDetector;
|
||||
private readonly MillimeterWaveRadiometer radiometer;
|
||||
private readonly MillimeterWaveAltimeter altimeter;
|
||||
private readonly LaserRangefinder rangefinder;
|
||||
|
||||
private MissileConfig missileConfig;
|
||||
|
||||
public TerminalSensitiveSubmunition(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig, simulationManager)
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="config">导弹配置</param>
|
||||
/// <param name="manager">模拟管理器</param>
|
||||
public TerminalSensitiveSubmunition(MissileConfig config, ISimulationManager manager)
|
||||
: base(config, manager)
|
||||
{
|
||||
currentStage = SubmunitionStage.Separation;
|
||||
spiralAngle = 0;
|
||||
lastScanDirection = Vector3D.Zero;
|
||||
targetDetected = false;
|
||||
detectionAngle = 0;
|
||||
this.missileConfig = missileConfig;
|
||||
|
||||
// 初始化传感器
|
||||
infraredDetector = new InfraredDetector(Position, Orientation, 1000, 30);
|
||||
infraredDetector = new InfraredDetector(Position, Orientation, 100, 30);
|
||||
radiometer = new MillimeterWaveRadiometer(Position, Orientation, 94e9, 1e-6);
|
||||
altimeter = new MillimeterWaveAltimeter(Position, Orientation, 1000, 0.1);
|
||||
rangefinder = new LaserRangefinder(Position, Orientation, 5000, 1000);
|
||||
altimeter = new MillimeterWaveAltimeter(this, 1000, 0.1); // 毫米波测高仪,测量精度0.1米
|
||||
rangefinder = new LaserRangefinder(Position, Orientation, 1000, 1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新子弹的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">时间增量</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
@ -84,53 +104,75 @@ namespace ActiveProtect.Models
|
||||
case SubmunitionStage.Attack:
|
||||
UpdateAttackStage(deltaTime);
|
||||
break;
|
||||
case SubmunitionStage.Explode:
|
||||
UpdateExplodeStage(deltaTime);
|
||||
break;
|
||||
case SubmunitionStage.SelfDestruct:
|
||||
SelfDestruct();
|
||||
UpdateSelfDestructStage(deltaTime);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分离阶段
|
||||
/// </summary>
|
||||
private void UpdateSeparationStage(double deltaTime)
|
||||
{
|
||||
Console.WriteLine("分离阶段");
|
||||
// 分离阶段
|
||||
Vector3D deceleration = new Vector3D(0, 9.8, 0);
|
||||
Vector3D deceleration = new(0, 9.8, 0);
|
||||
Velocity += deceleration * deltaTime;
|
||||
Position += Velocity * deltaTime;
|
||||
|
||||
if (Position.Y <= DecelerationHeight)
|
||||
if(!altimeter.IsActive)
|
||||
{
|
||||
currentStage = SubmunitionStage.Deceleration;
|
||||
// 激活毫米波测高雷达
|
||||
altimeter.Activate();
|
||||
}
|
||||
|
||||
// 检查高度是否小于等于减速高度
|
||||
if(((AltimeterSensorData)altimeter.GetSensorData()).Altitude <= DecelerationHeight)
|
||||
{
|
||||
// 如果是,则进入减速阶段
|
||||
currentStage = SubmunitionStage.Deceleration;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 减速阶段
|
||||
/// </summary>
|
||||
private void UpdateDecelerationStage(double deltaTime)
|
||||
{
|
||||
Console.WriteLine("减速阶段");
|
||||
// 减速减旋,垂直速度减小
|
||||
Vector3D deceleration = new Vector3D(0, 9.8, 0) - Velocity.Normalize() * 50; // 假设减速度为5m/s^2
|
||||
Console.WriteLine($"减速速度: {deceleration}");
|
||||
Console.WriteLine($"降落伞打开,减速速度: {deceleration}");
|
||||
Velocity += deceleration * deltaTime;
|
||||
|
||||
if (Velocity.Magnitude() <= VerticalDescentSpeed || Position.Y <= ScanningHeight)
|
||||
|
||||
if (Velocity.Magnitude() <= VerticalDescentSpeed)
|
||||
{
|
||||
Velocity = new Vector3D(0, -VerticalDescentSpeed, 0);
|
||||
if (Position.Y <= ScanningHeight)
|
||||
{
|
||||
currentStage = SubmunitionStage.SpiralScan;
|
||||
}
|
||||
}
|
||||
|
||||
if (((AltimeterSensorData)altimeter.GetSensorData()).Altitude <= ScanningHeight)
|
||||
{
|
||||
currentStage = SubmunitionStage.SpiralScan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 扫描阶段
|
||||
/// </summary>
|
||||
private void UpdateSpiralScanStage(double deltaTime)
|
||||
{
|
||||
Console.WriteLine("扫描阶段");
|
||||
spiralAngle = spiralAngle % (2 * Math.PI);
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
Velocity = new Vector3D(0, -VerticalDescentSpeed, 0);
|
||||
|
||||
// 螺旋扫描
|
||||
spiralAngle %= (2 * Math.PI);
|
||||
spiralAngle += SpiralRotationSpeed * deltaTime;
|
||||
|
||||
// 计算水平速度分量
|
||||
double horizontalSpeed = VerticalDescentSpeed * Math.Tan(ScanAngle);
|
||||
Vector3D horizontalVelocity = new Vector3D(
|
||||
Vector3D horizontalVelocity = new(
|
||||
Math.Cos(spiralAngle) * horizontalSpeed,
|
||||
0,
|
||||
Math.Sin(spiralAngle) * horizontalSpeed
|
||||
@ -140,7 +182,7 @@ namespace ActiveProtect.Models
|
||||
Velocity = new Vector3D(horizontalVelocity.X, -VerticalDescentSpeed, horizontalVelocity.Z);
|
||||
|
||||
// 计算扫描方向
|
||||
Vector3D scanDirection = new Vector3D(
|
||||
Vector3D scanDirection = new(
|
||||
Math.Cos(spiralAngle) * Math.Sin(ScanAngle),
|
||||
-Math.Cos(ScanAngle),
|
||||
Math.Sin(spiralAngle) * Math.Sin(ScanAngle)
|
||||
@ -148,6 +190,7 @@ namespace ActiveProtect.Models
|
||||
|
||||
if (DetectTarget(scanDirection))
|
||||
{
|
||||
Console.WriteLine("检测到目标");
|
||||
if (!targetDetected)
|
||||
{
|
||||
targetDetected = true;
|
||||
@ -159,14 +202,15 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
}
|
||||
|
||||
lastScanDirection = scanDirection;
|
||||
|
||||
if (Position.Y <= SelfDestructHeight)
|
||||
if (((AltimeterSensorData)altimeter.GetSensorData()).Altitude <= SelfDestructHeight)
|
||||
{
|
||||
currentStage = SubmunitionStage.SelfDestruct;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 攻击阶段
|
||||
/// </summary>
|
||||
private void UpdateAttackStage(double deltaTime)
|
||||
{
|
||||
Console.WriteLine("攻击阶段");
|
||||
@ -174,18 +218,34 @@ namespace ActiveProtect.Models
|
||||
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
||||
Vector3D direction = (targetPosition - Position).Normalize();
|
||||
Velocity = direction * AttackSpeed;
|
||||
|
||||
if (Vector3D.Distance(Position, targetPosition) < 5)
|
||||
Console.WriteLine($"导弹ID: {Id}, 距离目标: {DistanceToTarget}, 爆炸半径: {ExplosionRadius}");
|
||||
if (DistanceToTarget <= ExplosionRadius)
|
||||
{
|
||||
Explode();
|
||||
currentStage = SubmunitionStage.Explode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 爆炸阶段
|
||||
/// </summary>
|
||||
private void UpdateExplodeStage(double deltaTime)
|
||||
{
|
||||
Explode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自毁阶段
|
||||
/// </summary>
|
||||
private void UpdateSelfDestructStage(double deltaTime)
|
||||
{
|
||||
SelfDestruct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测目标
|
||||
/// </summary>
|
||||
/// <param name="scanDirection">扫描方向</param>
|
||||
/// <returns>是否检测到目标</returns>
|
||||
private bool DetectTarget(Vector3D scanDirection)
|
||||
{
|
||||
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
||||
@ -195,6 +255,22 @@ namespace ActiveProtect.Models
|
||||
return Vector3D.DotProduct(scanDirection, toTarget) > Math.Cos(5 * Math.PI / 180); // 允许5度的误差
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁子弹
|
||||
/// </summary>
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
infraredDetector.Deactivate();
|
||||
radiometer.Deactivate();
|
||||
altimeter.Deactivate();
|
||||
rangefinder.Deactivate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取子弹状态
|
||||
/// </summary>
|
||||
/// <returns>子弹状态</returns>
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"{base.GetStatus()}\nSubmunition Stage: {currentStage}\nDetection Angle: {detectionAngle * 180 / Math.PI:F2}°\nSpiral Angle: {spiralAngle * 180 / Math.PI:F2}°\nTarget Detected: {targetDetected}";
|
||||
|
||||
46
Program.cs
46
Program.cs
@ -3,31 +3,24 @@ using System.Threading;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
using ActiveProtect.Models;
|
||||
using Model;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ActiveProtect
|
||||
{
|
||||
/// <summary>
|
||||
/// 主程序
|
||||
/// </summary>
|
||||
class Program
|
||||
{
|
||||
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
|
||||
@ -35,10 +28,11 @@ namespace ActiveProtect
|
||||
// 配置坦克
|
||||
TankConfigs = new List<TankConfig>
|
||||
{
|
||||
new TankConfig(tankinfo)
|
||||
new(tankinfo)
|
||||
{
|
||||
Id = "Tank_1",
|
||||
InitialOrientation = new Orientation(Math.PI/4, 0, 0),
|
||||
InitialSpeed = 0,
|
||||
InitialSpeed = 10,
|
||||
MaxSpeed = 25,
|
||||
MaxArmor = 100,
|
||||
HasLaserWarner = false,
|
||||
@ -48,6 +42,7 @@ namespace ActiveProtect
|
||||
// 配置激光指示器
|
||||
LaserDesignatorConfig = new LaserDesignatorConfig
|
||||
{
|
||||
Id = "LD_1",
|
||||
InitialPosition = new Vector3D(2000, 150, 100),
|
||||
LaserPower = 1e6,
|
||||
LaserDivergenceAngle = 0.01
|
||||
@ -55,11 +50,13 @@ namespace ActiveProtect
|
||||
// 配置激光告警器
|
||||
LaserWarnerConfig = new LaserWarnerConfig
|
||||
{
|
||||
Id = "LW_1",
|
||||
AlarmDuration = 5.0
|
||||
},
|
||||
// 配置激光干扰器
|
||||
LaserJammerConfig = new LaserJammerConfig
|
||||
{
|
||||
Id = "LJ_1",
|
||||
MaxJammingCooldown = 5.0,
|
||||
MaxJammingPower = 10000.0,
|
||||
InitialJammingPower = 4000.0,
|
||||
@ -68,6 +65,7 @@ namespace ActiveProtect
|
||||
// 配置激光驾束仪
|
||||
LaserBeamRiderConfig = new LaserBeamRiderConfig
|
||||
{
|
||||
Id = "LBR_1",
|
||||
InitialPosition = new Vector3D(2000, 10, 100),
|
||||
LaserPower = 1000,
|
||||
ControlFieldDiameter = 6
|
||||
@ -76,8 +74,8 @@ namespace ActiveProtect
|
||||
MissileConfigs = new List<MissileConfig>
|
||||
{
|
||||
// 激光半主动制导导弹配置
|
||||
new MissileConfig
|
||||
{
|
||||
new() {
|
||||
Id = "LSGM_1",
|
||||
InitialPosition = new Vector3D(2000, 100, 100),
|
||||
InitialOrientation = new Orientation(Math.PI, -0.1, 0),
|
||||
InitialSpeed = 700,
|
||||
@ -89,14 +87,13 @@ namespace ActiveProtect
|
||||
MaxEngineBurnTime = 10,
|
||||
MaxAcceleration = 400,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
StageConfig = FlightStageConfig.LaserSemiActiveGuidedMissile,
|
||||
DistanceParams = new MissileDistanceParams(500, 200, 20),
|
||||
ExplosionRadius = 10,
|
||||
Mass = 50,
|
||||
Type = MissileType.LaserSemiActiveGuidance
|
||||
},
|
||||
// 激光驾束制导导弹配置
|
||||
new MissileConfig
|
||||
{
|
||||
new() {
|
||||
Id = "LBRM_1",
|
||||
InitialPosition = new Vector3D(2000, 10, 100),
|
||||
InitialOrientation = new Orientation(Math.PI, 0.0, 0.0),
|
||||
InitialSpeed = 300,
|
||||
@ -108,14 +105,13 @@ namespace ActiveProtect
|
||||
MaxEngineBurnTime = 10,
|
||||
MaxAcceleration = 400,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
StageConfig = FlightStageConfig.LaserBeamRiderGuidance,
|
||||
DistanceParams = new MissileDistanceParams(500, 200, 10),
|
||||
ExplosionRadius = 10,
|
||||
Mass = 50,
|
||||
Type = MissileType.LaserBeamRiderGuidance
|
||||
},
|
||||
// 末敏弹配置
|
||||
new MissileConfig
|
||||
{
|
||||
new() {
|
||||
Id = "TSM_1",
|
||||
InitialPosition = new Vector3D(4000, 0, 100), // 发射位置
|
||||
InitialOrientation = new Orientation(Math.PI, Math.PI/8, 0), // 使用计算得到的发射角度
|
||||
InitialSpeed = 800,
|
||||
@ -127,14 +123,12 @@ namespace ActiveProtect
|
||||
MaxEngineBurnTime = 0,
|
||||
MaxAcceleration = 1000,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
StageConfig = FlightStageConfig.TerminalSensitiveMissile,
|
||||
DistanceParams = new MissileDistanceParams(1000, 400, 20),
|
||||
Mass = 50,
|
||||
Type = MissileType.TerminalSensitiveMissile
|
||||
}
|
||||
},
|
||||
|
||||
SimulationTimeStep = 0.05 // 仿真时间步长, 激光驾束制导导弹需要更小的步长,< 0.025s
|
||||
SimulationTimeStep = 0.025 // 仿真时间步长, 激光驾束制导导弹需要更小的步长,< 0.025s
|
||||
};
|
||||
|
||||
// 创建仿真管理器
|
||||
|
||||
@ -65,6 +65,11 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public class TankConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 坦克ID
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始位置
|
||||
/// </summary>
|
||||
@ -106,7 +111,8 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
public TankConfig()
|
||||
{
|
||||
SetDefaultValues();
|
||||
|
||||
|
||||
Id = "";
|
||||
InitialPosition = new Vector3D(0, 0, 0);
|
||||
InitialOrientation = new Orientation(0, 0, 0);
|
||||
}
|
||||
@ -114,6 +120,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
public TankConfig(TankInfo tankInfo){
|
||||
SetDefaultValues();
|
||||
|
||||
Id = $"Tank_{tankInfo.TankID}";
|
||||
InitialPosition = new Vector3D(tankInfo.xp, tankInfo.yp, tankInfo.zp);
|
||||
InitialOrientation = new Orientation(0, 0, 0);
|
||||
}
|
||||
@ -125,6 +132,13 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
HasLaserWarner = false;
|
||||
HasLaserJammer = false;
|
||||
}
|
||||
|
||||
// 验证方法
|
||||
public bool Validate()
|
||||
{
|
||||
// 实现验证逻辑
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -132,6 +146,11 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public class MissileConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 导弹ID
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始位置
|
||||
/// </summary>
|
||||
@ -157,6 +176,8 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public int TargetIndex { get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 最大飞行时间(秒)
|
||||
/// </summary>
|
||||
@ -177,16 +198,6 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public double ProportionalNavigationCoefficient { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 飞行阶段配置
|
||||
/// </summary>
|
||||
public FlightStageConfig StageConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 距离参数
|
||||
/// </summary>
|
||||
public MissileDistanceParams DistanceParams { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发射推力加速度(米/秒²)
|
||||
/// </summary>
|
||||
@ -202,6 +213,11 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public double Mass { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 爆炸半径(米)
|
||||
/// </summary>
|
||||
public double ExplosionRadius { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹类型
|
||||
/// </summary>
|
||||
@ -214,29 +230,35 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
{
|
||||
SetDefaultValues();
|
||||
|
||||
Id = "";
|
||||
InitialPosition = new Vector3D(0, 0, 0);
|
||||
InitialOrientation = new Orientation(0, 0, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数,根据导弹初始信息初始化导弹配置
|
||||
/// </summary>
|
||||
/// <param name="mIniInfo">导弹初始信息</param>
|
||||
public MissileConfig(MIniInfo mIniInfo){
|
||||
SetDefaultValues();
|
||||
|
||||
Id = $"Missile_{mIniInfo.nMisID}";
|
||||
InitialPosition = new Vector3D(mIniInfo.xm, mIniInfo.ym, mIniInfo.zm);
|
||||
InitialOrientation = new Orientation(mIniInfo.psi_m, mIniInfo.theta_m, 0);
|
||||
InitialSpeed = mIniInfo.vm;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置默认值
|
||||
/// </summary>
|
||||
public void SetDefaultValues(){
|
||||
InitialSpeed = 0;
|
||||
MaxSpeed = 0;
|
||||
TargetIndex = 0;
|
||||
MaxFlightTime = 0;
|
||||
MaxFlightDistance = 0;
|
||||
StageConfig = FlightStageConfig.StandardMissile;
|
||||
LaunchAcceleration = 0;
|
||||
MaxEngineBurnTime = 0;
|
||||
MaxAcceleration = 0;
|
||||
DistanceParams = new MissileDistanceParams(0, 0, 0);
|
||||
ExplosionRadius = 0;
|
||||
ProportionalNavigationCoefficient = 0;
|
||||
Type = MissileType.StandardMissile;
|
||||
}
|
||||
@ -247,6 +269,11 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public class LaserDesignatorConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光指示器ID
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始位置
|
||||
/// </summary>
|
||||
@ -267,6 +294,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public LaserDesignatorConfig()
|
||||
{
|
||||
Id = "";
|
||||
InitialPosition = new Vector3D(0, 0, 0);
|
||||
LaserPower = 0;
|
||||
LaserDivergenceAngle = 0;
|
||||
@ -278,6 +306,11 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public class LaserBeamRiderConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光驾束仪ID
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始位置
|
||||
/// </summary>
|
||||
@ -304,6 +337,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public LaserBeamRiderConfig()
|
||||
{
|
||||
Id = "";
|
||||
InitialPosition = new Vector3D(0, 0, 0);
|
||||
LaserPower = 0;
|
||||
ControlFieldDiameter = 0;
|
||||
@ -324,109 +358,17 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
TerminalSensitiveMissile // 末敏弹
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导弹距离参数结构
|
||||
/// </summary>
|
||||
public struct MissileDistanceParams
|
||||
{
|
||||
/// <summary>
|
||||
/// 终端制导距离(米)
|
||||
/// </summary>
|
||||
public double TerminalGuidanceDistance;
|
||||
/// <summary>
|
||||
/// 攻击距离(米)
|
||||
/// </summary>
|
||||
public double AttackDistance;
|
||||
/// <summary>
|
||||
/// 爆炸距离(米)
|
||||
/// </summary>
|
||||
public double ExplosionDistance;
|
||||
|
||||
public MissileDistanceParams(double terminalGuidanceDistance, double attackDistance, double explosionDistance)
|
||||
{
|
||||
TerminalGuidanceDistance = terminalGuidanceDistance;
|
||||
AttackDistance = attackDistance;
|
||||
ExplosionDistance = explosionDistance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// 导弹飞行阶段配置结构
|
||||
/// </summary>
|
||||
public struct FlightStageConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 启用发射阶段
|
||||
/// </summary>
|
||||
public bool EnableLaunch;
|
||||
/// <summary>
|
||||
/// 启用加速阶段
|
||||
/// </summary>
|
||||
public bool EnableAcceleration;
|
||||
/// <summary>
|
||||
/// 启用巡航阶段
|
||||
/// </summary>
|
||||
public bool EnableCruise;
|
||||
/// <summary>
|
||||
/// 启用终端制导阶段
|
||||
/// </summary>
|
||||
public bool EnableTerminalGuidance;
|
||||
/// <summary>
|
||||
/// 启用攻击阶段
|
||||
/// </summary>
|
||||
public bool EnableAttack;
|
||||
|
||||
/// <summary>
|
||||
/// 标准导弹的预设配置, 所有阶段都启用
|
||||
/// </summary>
|
||||
public static FlightStageConfig StandardMissile => new(false, true, false, false, false);
|
||||
|
||||
/// <summary>
|
||||
/// 激光半主动制导导弹的预设配置, 没有加速阶段
|
||||
/// </summary>
|
||||
public static FlightStageConfig LaserSemiActiveGuidedMissile => new(true, false, true, true, true);
|
||||
|
||||
/// <summary>
|
||||
/// 激光驾束制导导弹的预设配置,没有巡航阶段
|
||||
/// </summary>
|
||||
public static FlightStageConfig LaserBeamRiderGuidance => new(true, true, false, true, true);
|
||||
|
||||
/// <summary>
|
||||
/// 红外指令制导导弹的预设配置,没有巡航阶段
|
||||
/// </summary>
|
||||
public static FlightStageConfig InfraredCommandGuidance => new(true, true, false, true, true);
|
||||
|
||||
/// <summary>
|
||||
/// 红外成像末制导导弹的预设配置
|
||||
/// </summary>
|
||||
public static FlightStageConfig InfraredImagingTerminalGuidance => new(true, true, true, true, true);
|
||||
|
||||
/// <summary>
|
||||
/// 毫米波末制导导弹的预设配置
|
||||
/// </summary>
|
||||
public static FlightStageConfig MillimeterWaveTerminalGuidance => new(true, true, true, true, true);
|
||||
|
||||
/// <summary>
|
||||
/// 末敏弹的预设配置
|
||||
/// </summary>
|
||||
public static FlightStageConfig TerminalSensitiveMissile => new(true, true, false, false, true);
|
||||
|
||||
public FlightStageConfig(bool enableLaunch, bool enableAcceleration, bool enableCruise, bool enableTerminalGuidance, bool enableAttack)
|
||||
{
|
||||
EnableLaunch = enableLaunch;
|
||||
EnableAcceleration = enableAcceleration;
|
||||
EnableCruise = enableCruise;
|
||||
EnableTerminalGuidance = enableTerminalGuidance;
|
||||
EnableAttack = enableAttack;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光告警器配置类
|
||||
/// </summary>
|
||||
public class LaserWarnerConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光告警器ID
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 警报持续时间(秒)
|
||||
/// </summary>
|
||||
@ -437,6 +379,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public LaserWarnerConfig()
|
||||
{
|
||||
Id = "";
|
||||
AlarmDuration = 5.0; // 默认警报持续5秒
|
||||
}
|
||||
}
|
||||
@ -446,6 +389,11 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public class LaserJammerConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光干扰器ID
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大干扰冷却时间(秒)
|
||||
/// </summary>
|
||||
@ -471,6 +419,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public LaserJammerConfig()
|
||||
{
|
||||
Id = "";
|
||||
MaxJammingCooldown = 5.0;
|
||||
MaxJammingPower = 10000.0;
|
||||
InitialJammingPower = 4000.0;
|
||||
|
||||
@ -36,7 +36,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// <summary>
|
||||
/// 仿真管理器的引用
|
||||
/// </summary>
|
||||
public ISimulationManager SimulationManager { get; set; }
|
||||
protected ISimulationManager SimulationManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
@ -51,7 +51,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
Position = position;
|
||||
Orientation = orientation;
|
||||
Velocity = orientation.ToVector() * speed;
|
||||
SimulationManager = simulationManager;
|
||||
this.SimulationManager = simulationManager;
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
|
||||
@ -98,8 +98,6 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
public string? DestroyedEntityId { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 激光告警器警报事件
|
||||
/// </summary>
|
||||
|
||||
@ -96,36 +96,36 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
for (int i = 0; i < config.TankConfigs.Count; i++)
|
||||
{
|
||||
var tankConfig = config.TankConfigs[i];
|
||||
var tank = new Tank($"Tank_{i + 1}", tankConfig, this);
|
||||
var tank = new Tank(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(
|
||||
$"LW_{i}",
|
||||
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(
|
||||
$"LJ_{i}",
|
||||
tank.Position,
|
||||
tank.Orientation,
|
||||
this,
|
||||
tank.Id,
|
||||
config.LaserJammerConfig
|
||||
);
|
||||
Elements.Add(laserJammer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -139,16 +139,16 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
switch (missileConfig.Type)
|
||||
{
|
||||
case MissileType.LaserSemiActiveGuidance:
|
||||
missile = new LaserSemiActiveGuidedMissile($"LSGM_{i + 1}", missileConfig, this);
|
||||
missile = new LaserSemiActiveGuidedMissile(missileConfig, this);
|
||||
break;
|
||||
case MissileType.LaserBeamRiderGuidance:
|
||||
missile = new LaserBeamRiderMissile($"LBRM_{i + 1}", missileConfig, this);
|
||||
missile = new LaserBeamRiderMissile(missileConfig, this);
|
||||
break;
|
||||
case MissileType.TerminalSensitiveMissile:
|
||||
missile = new TerminalSensitiveMissile($"TSM_{i + 1}", missileConfig, this);
|
||||
missile = new TerminalSensitiveMissile(missileConfig, this);
|
||||
break;
|
||||
default:
|
||||
missile = new MissileBase($"M_{i + 1}", missileConfig, this);
|
||||
missile = new MissileBase(missileConfig, this);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -175,7 +175,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
var laserBeamRiderConfig = config.LaserBeamRiderConfig;
|
||||
var laserBeamRider = new LaserBeamRider(
|
||||
"LBR_1",
|
||||
"LBRM_2",
|
||||
"LBRM_1",
|
||||
"Tank_1",
|
||||
0,
|
||||
laserBeamRiderConfig,
|
||||
@ -185,13 +185,13 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
|
||||
|
||||
// 激活所有元素
|
||||
// ActivateAllElements();
|
||||
ActivateAllElements();
|
||||
|
||||
// 激活部分元素
|
||||
ActivateSomeElements();
|
||||
//ActivateSomeElements();
|
||||
|
||||
// 启动激光驾束仪
|
||||
//laserBeamRider.StartBeamIllumination();
|
||||
// 激光驾束仪开始照射
|
||||
laserBeamRider.StartBeamIllumination();
|
||||
|
||||
}
|
||||
|
||||
@ -209,18 +209,24 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
// 激活坦克
|
||||
Elements.FindAll(e => e.Id == "Tank_1").ForEach(e => e.Activate());
|
||||
|
||||
// 激活激光告警器
|
||||
//Elements.FindAll(e => e.Id == "LW_1").ForEach(e => e.Activate());
|
||||
|
||||
// 激活激光干扰器
|
||||
//Elements.FindAll(e => e.Id == "LJ_1").ForEach(e => e.Activate());
|
||||
|
||||
// 激活激光半主动制导导弹
|
||||
//Elements.FindAll(e => e.Id == "LSGM_1").ForEach(e => e.Activate());
|
||||
// 激活激光目标指示器
|
||||
//Elements.FindAll(e => e.Id == "LD_1").ForEach(e => e.Activate());
|
||||
|
||||
// 激活激光驾束制导导弹
|
||||
//Elements.FindAll(e => e.Id == "LBRM_2").ForEach(e => e.Activate());
|
||||
//Elements.FindAll(e => e.Id == "LBRM_1").ForEach(e => e.Activate());
|
||||
// 激活激光驾束仪
|
||||
//Elements.FindAll(e => e.Id == "LBR_1").ForEach(e => e.Activate());
|
||||
|
||||
// 激活末敏弹
|
||||
Elements.FindAll(e => e.Id == "TSM_3").ForEach(e => e.Activate());
|
||||
Elements.FindAll(e => e.Id == "TSM_1").ForEach(e => e.Activate());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user