简化了导弹运行阶段处理机制,导弹基类不再负责导弹的运行阶段,改由各子类处理;完善了末敏弹运行过程
This commit is contained in:
parent
cabe390112
commit
2456d04c28
620
Docs/MissileBase.bak
Normal file
620
Docs/MissileBase.bak
Normal file
@ -0,0 +1,620 @@
|
||||
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,36 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public class TerminalSensitiveMissile : SimulationElement
|
||||
{
|
||||
private TerminalSensitiveMotherMissile motherMissile;
|
||||
private List<TerminalSensitiveSubmunition> submunitions;
|
||||
|
||||
public TerminalSensitiveMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, missileConfig.InitialSpeed, simulationManager)
|
||||
{
|
||||
motherMissile = new TerminalSensitiveMotherMissile($"{id}_Mother", missileConfig, simulationManager);
|
||||
submunitions = new List<TerminalSensitiveSubmunition>();
|
||||
SimulationManager.AddElement(motherMissile);
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 这个类现在主要用于管理和跟踪整个末敏弹系统的状态
|
||||
// 实际的更新逻辑由母弹和子弹各自处理
|
||||
}
|
||||
|
||||
public override string GetStatus()
|
||||
{
|
||||
string status = $"Terminal Sensitive Missile System {Id}:\n";
|
||||
status += motherMissile.GetStatus() + "\n";
|
||||
foreach (var submunition in submunitions)
|
||||
{
|
||||
status += submunition.GetStatus() + "\n";
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,19 +2,23 @@ using System;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public interface IGuidanceSystem
|
||||
{
|
||||
bool HasGuidance { get; }
|
||||
void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity);
|
||||
Vector3D GetGuidanceAcceleration();
|
||||
}
|
||||
public class BasicGuidanceSystem : IGuidanceSystem
|
||||
{
|
||||
public bool HasGuidance { get; protected set; }
|
||||
protected double ProportionalNavigationCoefficient { get; set; }
|
||||
protected Vector3D Position { get; set; }
|
||||
protected Vector3D Velocity { get; set; }
|
||||
protected Vector3D GuidanceCommand { get; set; }
|
||||
protected Vector3D GuidanceAcceleration { get; set; }
|
||||
|
||||
public BasicGuidanceSystem(double proportionalNavigationCoefficient)
|
||||
public BasicGuidanceSystem()
|
||||
{
|
||||
ProportionalNavigationCoefficient = proportionalNavigationCoefficient;
|
||||
HasGuidance = false;
|
||||
GuidanceCommand = Vector3D.Zero;
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
Position = Vector3D.Zero;
|
||||
Velocity = Vector3D.Zero;
|
||||
}
|
||||
@ -25,21 +29,29 @@ namespace ActiveProtect.Models
|
||||
Velocity = missileVelocity;
|
||||
}
|
||||
|
||||
public Vector3D GetGuidanceCommand()
|
||||
public Vector3D GetGuidanceAcceleration()
|
||||
{
|
||||
return GuidanceCommand;
|
||||
return GuidanceAcceleration;
|
||||
}
|
||||
|
||||
protected virtual void CalculateGuidanceCommand(double deltaTime)
|
||||
protected virtual void CalculateGuidanceAcceleration(double deltaTime)
|
||||
{
|
||||
// 基础制导系统不计算制导指令
|
||||
// 派生类应该重写这个方法来实现特定的制导逻辑
|
||||
}
|
||||
|
||||
protected Vector3D CalculateProportionalNavigation(Vector3D missilePosition, Vector3D missileVelocity, Vector3D targetPosition, Vector3D targetVelocity)
|
||||
/// <summary>
|
||||
/// 计算比例导引加速度
|
||||
/// </summary>
|
||||
/// <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)
|
||||
{
|
||||
// 预测时间(可以根据实际情况调整)
|
||||
double predictionTime = 2.0;
|
||||
// 预测时间(预测目标前进方向该时间后到达的位置,可以调整)
|
||||
double predictionTime = 0.01;
|
||||
|
||||
// 预测目标位置
|
||||
Vector3D predictedTargetPosition = targetPosition + targetVelocity * predictionTime;
|
||||
@ -50,7 +62,7 @@ namespace ActiveProtect.Models
|
||||
Vector3D LOS = r.Normalize();
|
||||
Vector3D LOSRate = (v - (LOS * Vector3D.DotProduct(v, LOS))) / r.Magnitude();
|
||||
|
||||
Vector3D acceleration = Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), missileVelocity.Normalize()) * ProportionalNavigationCoefficient * missileVelocity.Magnitude();
|
||||
Vector3D acceleration = Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), missileVelocity.Normalize()) * proportionalNavigationCoefficient * missileVelocity.Magnitude();
|
||||
|
||||
return acceleration;
|
||||
}
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public interface IGuidanceSystem
|
||||
{
|
||||
bool HasGuidance { get; }
|
||||
void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity);
|
||||
Vector3D GetGuidanceCommand();
|
||||
}
|
||||
}
|
||||
@ -13,31 +13,28 @@ namespace ActiveProtect.Models
|
||||
|
||||
private Vector3D LastError = Vector3D.Zero;
|
||||
|
||||
public Vector3D LastGuidanceCommand { get; private set; }
|
||||
public Vector3D LastGuidanceAcceleration { get; private set; }
|
||||
|
||||
private Vector3D IntegralError = Vector3D.Zero;
|
||||
|
||||
private double ProportionalNavigationCoefficient { get; set; }
|
||||
|
||||
public LaserBeamRiderGuidanceSystem(double proportionalNavigationCoefficient)
|
||||
: base(proportionalNavigationCoefficient)
|
||||
private bool LaserIlluminationOn { get; set; }
|
||||
|
||||
|
||||
public LaserBeamRiderGuidanceSystem()
|
||||
{
|
||||
LaserSourcePosition = Vector3D.Zero;
|
||||
LaserDirection = Vector3D.Zero;
|
||||
LaserPower = 0;
|
||||
HasGuidance = false;
|
||||
LastGuidanceCommand = Vector3D.Zero;
|
||||
}
|
||||
|
||||
public void ActivateLaserBeam(Vector3D sourcePosition, Vector3D direction, double laserPower)
|
||||
{
|
||||
LaserSourcePosition = sourcePosition;
|
||||
LaserDirection = direction.Normalize();
|
||||
LaserPower = laserPower;
|
||||
HasGuidance = true;
|
||||
LastGuidanceAcceleration = Vector3D.Zero;
|
||||
ProportionalNavigationCoefficient = 3;
|
||||
}
|
||||
|
||||
public void UpdateLaserBeamRider(Vector3D sourcePosition, Vector3D direction, double laserPower)
|
||||
{
|
||||
LaserIlluminationOn = true;
|
||||
LaserSourcePosition = sourcePosition;
|
||||
LaserDirection = direction.Normalize();
|
||||
LaserPower = laserPower;
|
||||
@ -55,15 +52,21 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
base.Update(deltaTime, missilePosition, missileVelocity);
|
||||
|
||||
UpdateGuidanceStatus();
|
||||
|
||||
if (HasGuidance)
|
||||
if (LaserIlluminationOn)
|
||||
{
|
||||
CalculateGuidanceCommand(deltaTime);
|
||||
UpdateGuidanceStatus();
|
||||
if (HasGuidance)
|
||||
{
|
||||
CalculateGuidanceAcceleration(deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GuidanceCommand = Vector3D.Zero;
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,11 +102,11 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
}
|
||||
|
||||
protected override void CalculateGuidanceCommand(double deltaTime)
|
||||
protected override void CalculateGuidanceAcceleration(double deltaTime)
|
||||
{
|
||||
if (!HasGuidance)
|
||||
{
|
||||
GuidanceCommand = Vector3D.Zero;
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -150,15 +153,15 @@ namespace ActiveProtect.Models
|
||||
Vector3D forwardAcceleration = Vector3D.CrossProduct(rotationAxis, Velocity) * rotationAngle * ProportionalNavigationCoefficient;
|
||||
|
||||
// 合并横向和前向加速度
|
||||
GuidanceCommand = lateralAcceleration + forwardAcceleration;
|
||||
GuidanceAcceleration = lateralAcceleration + forwardAcceleration;
|
||||
|
||||
// 低通滤波
|
||||
const double alpha = 0.2;
|
||||
GuidanceCommand = GuidanceCommand * alpha + LastGuidanceCommand * (1 - alpha);
|
||||
GuidanceAcceleration = GuidanceAcceleration * alpha + LastGuidanceAcceleration * (1 - alpha);
|
||||
|
||||
// 更新上一次的误差和制导命令
|
||||
// 更新上一次的误差和制导加速度
|
||||
LastError = error;
|
||||
LastGuidanceCommand = GuidanceCommand;
|
||||
LastGuidanceAcceleration = GuidanceAcceleration;
|
||||
|
||||
Console.WriteLine($"Current Position: {Position}");
|
||||
Console.WriteLine($"Laser Source Position: {LaserSourcePosition}");
|
||||
@ -170,7 +173,7 @@ namespace ActiveProtect.Models
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"LaserBeamRiderGuidanceSystem: HasGuidance={HasGuidance}, LaserSourcePosition={LaserSourcePosition}, LaserDirection={LaserDirection}, GuidanceCommand={GuidanceCommand}";
|
||||
return $"LaserBeamRiderGuidanceSystem: HasGuidance={HasGuidance}, LaserSourcePosition={LaserSourcePosition}, LaserDirection={LaserDirection}, GuidanceAcceleration={GuidanceAcceleration}";
|
||||
}
|
||||
|
||||
private Vector3D CalculateShortestDistanceToLaserBeam()
|
||||
|
||||
@ -4,25 +4,34 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
public class LaserBeamRiderMissile : MissileBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光驾束制导导弹阶段
|
||||
/// </summary>
|
||||
private enum LBRM_Stage
|
||||
{
|
||||
Launch, // 发射阶段
|
||||
Cruise, // 巡航阶段
|
||||
Explode, // 爆炸阶段
|
||||
SelfDestruct // 自毁阶段
|
||||
}
|
||||
private LBRM_Stage currentStage;
|
||||
private LaserBeamRiderGuidanceSystem LaserBeamRiderGuidanceSystem;
|
||||
private MissileConfig missileConfig;
|
||||
|
||||
|
||||
public LaserBeamRiderMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig, simulationManager)
|
||||
{
|
||||
LaserBeamRiderGuidanceSystem = new LaserBeamRiderGuidanceSystem(missileConfig.ProportionalNavigationCoefficient);
|
||||
}
|
||||
|
||||
protected override Vector3D GetGuidanceCommand()
|
||||
{
|
||||
return LaserBeamRiderGuidanceSystem.GetGuidanceCommand();
|
||||
LaserBeamRiderGuidanceSystem = new LaserBeamRiderGuidanceSystem();
|
||||
currentStage = LBRM_Stage.Launch;
|
||||
this.missileConfig = missileConfig;
|
||||
}
|
||||
|
||||
private void OnLaserBeamStart(LaserBeamStartEvent evt)
|
||||
{
|
||||
if (evt?.LaserBeamRider != null)
|
||||
{
|
||||
LaserBeamRiderGuidanceSystem?.ActivateLaserBeam(evt.LaserBeamRider.Position, evt.LaserBeamRider.LaserDirection, evt.LaserBeamRider.LaserPower);
|
||||
LaserBeamRiderGuidanceSystem?.UpdateLaserBeamRider(evt.LaserBeamRider.Position, evt.LaserBeamRider.LaserDirection, evt.LaserBeamRider.LaserPower);
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,19 +53,58 @@ namespace ActiveProtect.Models
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (LaserBeamRiderGuidanceSystem.HasGuidance)
|
||||
switch (currentStage)
|
||||
{
|
||||
LaserBeamRiderGuidanceSystem.Update(deltaTime, Position, Velocity);
|
||||
this.HasGuidance = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.HasGuidance = false;
|
||||
case LBRM_Stage.Launch:
|
||||
UpdateLaunchStage(deltaTime);
|
||||
break;
|
||||
case LBRM_Stage.Cruise:
|
||||
UpdateCruiseStage(deltaTime);
|
||||
break;
|
||||
case LBRM_Stage.Explode:
|
||||
UpdateExplodeStage(deltaTime);
|
||||
break;
|
||||
case LBRM_Stage.SelfDestruct:
|
||||
SelfDestruct();
|
||||
break;
|
||||
}
|
||||
|
||||
base.Update(deltaTime);
|
||||
}
|
||||
|
||||
private void UpdateLaunchStage(double deltaTime)
|
||||
{
|
||||
// 发射阶段
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
if (FlightTime >= 0.01)
|
||||
{
|
||||
currentStage = LBRM_Stage.Cruise;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCruiseStage(double deltaTime)
|
||||
{
|
||||
// 巡航阶段
|
||||
LaserBeamRiderGuidanceSystem.Update(deltaTime, Position, Velocity);
|
||||
GuidanceAcceleration = LaserBeamRiderGuidanceSystem.GetGuidanceAcceleration();
|
||||
if (DistanceToTarget <= missileConfig.DistanceParams.ExplosionDistance)
|
||||
{
|
||||
currentStage = LBRM_Stage.Explode;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateExplodeStage(double deltaTime)
|
||||
{
|
||||
// 爆炸阶段
|
||||
Explode();
|
||||
}
|
||||
|
||||
private void UpdateSelfDestructStage(double deltaTime)
|
||||
{
|
||||
// 自毁阶段
|
||||
SelfDestruct();
|
||||
}
|
||||
|
||||
public override string GetStatus()
|
||||
{
|
||||
string baseStatus = base.GetStatus().Replace("导弹", "激光驾束制导导弹");
|
||||
|
||||
@ -12,31 +12,27 @@ namespace ActiveProtect.Models
|
||||
private const double TargetReflectiveArea = 1.0; // 目标有效反射面积(平方米)
|
||||
private Vector3D TargetPosition { get; set; }
|
||||
private Vector3D TargetVelocity { get; set; }
|
||||
private bool LaserIlluminationOn { get; set; }
|
||||
private Vector3D LaserDesignatorPosition { get; set; }
|
||||
private double LaserPower { get; set; }
|
||||
private double LaserDivergenceAngle { get; set; }
|
||||
public LaserSemiActiveGuidanceSystem(double proportionalNavigationCoefficient, Vector3D initialMissilePosition, Vector3D initialTargetPosition, Vector3D initialTargetVelocity)
|
||||
: base(proportionalNavigationCoefficient)
|
||||
|
||||
private double ProportionalNavigationCoefficient { get; set; }
|
||||
|
||||
|
||||
public LaserSemiActiveGuidanceSystem()
|
||||
{
|
||||
Position = initialMissilePosition;
|
||||
TargetPosition = initialTargetPosition;
|
||||
TargetVelocity = initialTargetVelocity;
|
||||
TargetPosition = Vector3D.Zero;
|
||||
TargetVelocity = Vector3D.Zero;
|
||||
LaserIlluminationOn = false;
|
||||
LaserDesignatorPosition = Vector3D.Zero;
|
||||
LaserPower = 0;
|
||||
}
|
||||
|
||||
public void ActivateLaserDesignator(Vector3D sourcePosition, Vector3D targetPosition, Vector3D targetVelocity, double laserPower, double laserDivergenceAngle)
|
||||
{
|
||||
HasGuidance = true;
|
||||
LaserDesignatorPosition = sourcePosition;
|
||||
TargetPosition = targetPosition;
|
||||
TargetVelocity = targetVelocity;
|
||||
LaserPower = laserPower;
|
||||
LaserDivergenceAngle = laserDivergenceAngle;
|
||||
ProportionalNavigationCoefficient = 4;
|
||||
}
|
||||
|
||||
public void UpdateLaserDesignator(Vector3D sourcePosition, Vector3D targetPosition, Vector3D targetVelocity, double laserPower, double laserDivergenceAngle)
|
||||
{
|
||||
LaserIlluminationOn = true;
|
||||
LaserDesignatorPosition = sourcePosition;
|
||||
TargetPosition = targetPosition;
|
||||
TargetVelocity = targetVelocity;
|
||||
@ -46,7 +42,7 @@ namespace ActiveProtect.Models
|
||||
|
||||
public void DeactivateLaserDesignator()
|
||||
{
|
||||
HasGuidance = false;
|
||||
LaserIlluminationOn = false;
|
||||
LaserDesignatorPosition = Vector3D.Zero;
|
||||
TargetPosition = Vector3D.Zero;
|
||||
TargetVelocity = Vector3D.Zero;
|
||||
@ -57,15 +53,21 @@ namespace ActiveProtect.Models
|
||||
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
|
||||
{
|
||||
base.Update(deltaTime, missilePosition, missileVelocity);
|
||||
|
||||
HasGuidance = CalculateReceivedLaserPower() > LockThreshold;
|
||||
if (HasGuidance)
|
||||
if (LaserIlluminationOn)
|
||||
{
|
||||
CalculateGuidanceCommand(deltaTime);
|
||||
HasGuidance = CalculateReceivedLaserPower() > LockThreshold;
|
||||
if (HasGuidance)
|
||||
{
|
||||
CalculateGuidanceAcceleration(deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GuidanceCommand = Vector3D.Zero;
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
}
|
||||
|
||||
PrintGuidanceInfo();
|
||||
@ -73,11 +75,11 @@ namespace ActiveProtect.Models
|
||||
|
||||
private double CalculateReceivedLaserPower()
|
||||
{
|
||||
double distanceToTarget = (TargetPosition - LaserDesignatorPosition).Magnitude();
|
||||
double distanceToMissile = (Position - TargetPosition).Magnitude();
|
||||
double distanceDesignatorToTarget = (LaserDesignatorPosition - TargetPosition).Magnitude();
|
||||
double distanceMissileToTarget = (Position - TargetPosition).Magnitude();
|
||||
|
||||
// 计算目标处的光斑面积
|
||||
double spotAreaAtTarget = Math.PI * Math.Pow(distanceToTarget * Math.Tan(LaserDivergenceAngle), 2);
|
||||
double spotAreaAtTarget = Math.PI * Math.Pow(distanceDesignatorToTarget * Math.Tan(LaserDivergenceAngle), 2);
|
||||
|
||||
// 计算目标处的激光功率密度
|
||||
double powerDensityAtTarget = LaserPower / spotAreaAtTarget;
|
||||
@ -86,14 +88,14 @@ namespace ActiveProtect.Models
|
||||
double reflectedPower = powerDensityAtTarget * TargetReflectiveArea * ReflectionCoefficient;
|
||||
|
||||
// 计算反射光在导弹处的扩散面积(假设漫反射)
|
||||
double reflectedSpotArea = 2 * Math.PI * Math.Pow(distanceToMissile, 2);
|
||||
double reflectedSpotArea = 2 * Math.PI * Math.Pow(distanceMissileToTarget, 2);
|
||||
|
||||
// 计算导弹接收到的功率
|
||||
double receivedPower = reflectedPower / reflectedSpotArea;
|
||||
|
||||
// 计算探测器接收到的功率比例
|
||||
double detectorArea = Math.PI * Math.Pow(DetectorDiameter / 2, 2);
|
||||
double illuminatedArea = Math.PI * Math.Pow(distanceToMissile * Math.Tan(FieldOfViewAngle / 2), 2);
|
||||
double illuminatedArea = Math.PI * Math.Pow(distanceMissileToTarget * Math.Tan(FieldOfViewAngle / 2), 2);
|
||||
double powerRatio = Math.Min(1, detectorArea / illuminatedArea);
|
||||
|
||||
// 计算聚焦后的功率密度增加
|
||||
@ -106,22 +108,17 @@ namespace ActiveProtect.Models
|
||||
return finalReceivedPower;
|
||||
}
|
||||
|
||||
protected override void CalculateGuidanceCommand(double deltaTime)
|
||||
protected override void CalculateGuidanceAcceleration(double deltaTime)
|
||||
{
|
||||
if (!HasGuidance)
|
||||
{
|
||||
GuidanceCommand = Vector3D.Zero;
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"激光半主动导弹引导加速度计算: 位置: {Position}, 速度: {Velocity}, 目标位置: {TargetPosition}, 目标速度: {TargetVelocity}");
|
||||
// 计算比例导引加速度
|
||||
GuidanceCommand = CalculateProportionalNavigation(Position, Velocity, TargetPosition, TargetVelocity);
|
||||
GuidanceAcceleration = CalculateProportionalNavigation(ProportionalNavigationCoefficient, Position, Velocity, TargetPosition, TargetVelocity);
|
||||
|
||||
// 限制最大加速度
|
||||
double maxAcceleration = 100; // 根据实际情况调整
|
||||
if (GuidanceCommand.Magnitude() > maxAcceleration)
|
||||
if (GuidanceAcceleration.Magnitude() > maxAcceleration)
|
||||
{
|
||||
GuidanceCommand = GuidanceCommand.Normalize() * maxAcceleration;
|
||||
GuidanceAcceleration = GuidanceAcceleration.Normalize() * maxAcceleration;
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,7 +130,7 @@ namespace ActiveProtect.Models
|
||||
Console.WriteLine($" 速度大小: {Velocity.Magnitude():F2} m/s");
|
||||
Console.WriteLine($" 是否有引导: {HasGuidance}");
|
||||
Console.WriteLine($" 目标位置: {TargetPosition}");
|
||||
Console.WriteLine($" 制导指令: {GuidanceCommand}");
|
||||
Console.WriteLine($" 制导加速度: {GuidanceAcceleration}");
|
||||
Console.WriteLine($" 接收到的激光功率: {CalculateReceivedLaserPower():E} W");
|
||||
Console.WriteLine($" 锁定阈值: {LockThreshold:E} W");
|
||||
Console.WriteLine();
|
||||
|
||||
@ -8,8 +8,21 @@ namespace ActiveProtect.Models
|
||||
/// </summary>
|
||||
public class LaserSemiActiveGuidedMissile : MissileBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 激光半主动制导导弹阶段
|
||||
/// </summary>
|
||||
private enum LSAGM_Stage
|
||||
{
|
||||
Launch, // 发射阶段
|
||||
Cruise, // 巡航阶段
|
||||
Explode, // 爆炸阶段
|
||||
SelfDestruct // 自毁阶段
|
||||
}
|
||||
|
||||
private LSAGM_Stage currentStage;
|
||||
private LaserSemiActiveGuidanceSystem LaserGuidanceSystem;
|
||||
public string LaserDesignatorId { get; set; } = "";
|
||||
private MissileConfig missileConfig;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
@ -21,14 +34,9 @@ namespace ActiveProtect.Models
|
||||
public LaserSemiActiveGuidedMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig, simulationManager)
|
||||
{
|
||||
Vector3D initialTargetPosition = simulationManager.GetEntityById($"Tank_{missileConfig.TargetIndex + 1}").Position;
|
||||
Vector3D initialTargetVelocity = simulationManager.GetEntityById($"Tank_{missileConfig.TargetIndex + 1}").Velocity;
|
||||
LaserGuidanceSystem = new LaserSemiActiveGuidanceSystem(
|
||||
missileConfig.ProportionalNavigationCoefficient,
|
||||
missileConfig.InitialPosition,
|
||||
initialTargetPosition,
|
||||
initialTargetVelocity
|
||||
);
|
||||
LaserGuidanceSystem = new LaserSemiActiveGuidanceSystem();
|
||||
currentStage = LSAGM_Stage.Launch;
|
||||
this.missileConfig = missileConfig;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -39,7 +47,7 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
if (evt?.LaserDesignator != null && evt?.Target != null)
|
||||
{
|
||||
LaserGuidanceSystem.ActivateLaserDesignator(evt.LaserDesignator.Position, evt.Target.Position, evt.Target.Velocity,
|
||||
LaserGuidanceSystem.UpdateLaserDesignator(evt.LaserDesignator.Position, evt.Target.Position, evt.Target.Velocity,
|
||||
evt.LaserDesignator.LaserPower, evt.LaserDesignator.LaserDivergenceAngle);
|
||||
}
|
||||
}
|
||||
@ -101,25 +109,53 @@ namespace ActiveProtect.Models
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
if (LaserGuidanceSystem.HasGuidance)
|
||||
{
|
||||
LaserGuidanceSystem.Update(deltaTime, Position, Velocity);
|
||||
this.HasGuidance = true;
|
||||
}
|
||||
else
|
||||
switch (currentStage)
|
||||
{
|
||||
this.HasGuidance = false;
|
||||
case LSAGM_Stage.Launch:
|
||||
UpdateLaunchStage(deltaTime);
|
||||
break;
|
||||
case LSAGM_Stage.Cruise:
|
||||
UpdateCruiseStage(deltaTime);
|
||||
break;
|
||||
case LSAGM_Stage.Explode:
|
||||
UpdateExplodeStage(deltaTime);
|
||||
break;
|
||||
case LSAGM_Stage.SelfDestruct:
|
||||
UpdateSelfDestructStage(deltaTime);
|
||||
break;
|
||||
}
|
||||
base.Update(deltaTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取制导命令
|
||||
/// </summary>
|
||||
/// <returns>制导命令</returns>
|
||||
protected override Vector3D GetGuidanceCommand()
|
||||
{
|
||||
return LaserGuidanceSystem.GetGuidanceCommand();
|
||||
private void UpdateLaunchStage(double deltaTime)
|
||||
{
|
||||
// 发射阶段
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
if (FlightTime >= 0.1)
|
||||
{
|
||||
currentStage = LSAGM_Stage.Cruise;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCruiseStage(double deltaTime)
|
||||
{
|
||||
LaserGuidanceSystem.Update(deltaTime, Position, Velocity);
|
||||
GuidanceAcceleration = LaserGuidanceSystem.GetGuidanceAcceleration();
|
||||
if (DistanceToTarget <= missileConfig.DistanceParams.ExplosionDistance)
|
||||
{
|
||||
currentStage = LSAGM_Stage.Explode;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateExplodeStage(double deltaTime)
|
||||
{
|
||||
base.Explode();
|
||||
}
|
||||
|
||||
private void UpdateSelfDestructStage(double deltaTime)
|
||||
{
|
||||
SelfDestruct();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,16 +60,6 @@ namespace ActiveProtect.Models
|
||||
/// </summary>
|
||||
public MissileDistanceParams DistanceParams { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 飞行阶段配置
|
||||
/// </summary>
|
||||
public FlightStageConfig StageConfig { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前飞行阶段
|
||||
/// </summary>
|
||||
public FlightStage CurrentStage { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上一帧目标位置
|
||||
/// </summary>
|
||||
@ -83,7 +73,7 @@ namespace ActiveProtect.Models
|
||||
/// <summary>
|
||||
/// 推力加速度(米/秒²)
|
||||
/// </summary>
|
||||
public double ThrustAcceleration { get; protected set; }
|
||||
public double LaunchAcceleration { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前发动机燃烧时间(秒)
|
||||
@ -98,7 +88,7 @@ namespace ActiveProtect.Models
|
||||
/// <summary>
|
||||
/// 最大加速度(米/秒²)
|
||||
/// </summary>
|
||||
public double MaxAcceleration { get; protected set; } = 10000;
|
||||
public double MaxAcceleration { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 比例导引系数
|
||||
@ -124,20 +114,22 @@ namespace ActiveProtect.Models
|
||||
/// 发射速度(米/秒)
|
||||
/// </summary>
|
||||
public const double LAUNCH_SPEED = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 发射阶段持续时间(秒)
|
||||
/// </summary>
|
||||
public const double LAUNCH_DURATION = 0.5;
|
||||
|
||||
protected IMissileStageStrategy currentStage;
|
||||
private Dictionary<FlightStage, IMissileStageStrategy> stageStrategies;
|
||||
|
||||
/// <summary>
|
||||
/// 导弹质量(千克)
|
||||
/// </summary>
|
||||
public double Mass { get; protected set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// 制导加速度
|
||||
/// </summary>
|
||||
protected Vector3D GuidanceAcceleration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 推力加速度
|
||||
/// </summary>
|
||||
protected Vector3D ThrustAcceleration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
@ -150,52 +142,22 @@ namespace ActiveProtect.Models
|
||||
MaxFlightTime = missileConfig.MaxFlightTime;
|
||||
MaxFlightDistance = missileConfig.MaxFlightDistance;
|
||||
DistanceParams = missileConfig.DistanceParams;
|
||||
StageConfig = missileConfig.StageConfig;
|
||||
IsActive = true;
|
||||
IsActive = false;
|
||||
FlightTime = 0;
|
||||
FlightDistance = 0;
|
||||
SimulationManager = simulationManager;
|
||||
ThrustAcceleration = missileConfig.ThrustAcceleration;
|
||||
LaunchAcceleration = missileConfig.LaunchAcceleration;
|
||||
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();
|
||||
|
||||
currentStage = stageStrategies[CurrentStage];
|
||||
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
ThrustAcceleration = Vector3D.Zero;
|
||||
LastTargetPosition = Vector3D.Zero;
|
||||
|
||||
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置导弹的初始飞行阶段
|
||||
/// </summary>
|
||||
private void SetInitialStage()
|
||||
{
|
||||
if (StageConfig.EnableLaunch) CurrentStage = FlightStage.Launch;
|
||||
else if (StageConfig.EnableAcceleration) CurrentStage = FlightStage.Acceleration;
|
||||
else if (StageConfig.EnableCruise) CurrentStage = FlightStage.Cruise;
|
||||
else if (StageConfig.EnableTerminalGuidance) CurrentStage = FlightStage.TerminalGuidance;
|
||||
else if (StageConfig.EnableAttack) CurrentStage = FlightStage.Attack;
|
||||
|
||||
Console.WriteLine($"导弹 {Id} 的初始阶段: {CurrentStage}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新导弹状态
|
||||
/// </summary>
|
||||
@ -209,30 +171,22 @@ namespace ActiveProtect.Models
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateEngineBurnTime(deltaTime);
|
||||
|
||||
Vector3D guidanceCommand = GetGuidanceCommand();
|
||||
|
||||
UpdateMotionState(deltaTime, guidanceCommand);
|
||||
UpdateMotionState(deltaTime);
|
||||
|
||||
if (CheckHit())
|
||||
{
|
||||
Explode();
|
||||
return;
|
||||
}
|
||||
|
||||
currentStage.Update(deltaTime);
|
||||
}
|
||||
|
||||
protected virtual Vector3D GetGuidanceCommand()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected virtual void UpdateMotionState(double deltaTime, Vector3D guidanceCommand)
|
||||
protected virtual void UpdateMotionState(double deltaTime)
|
||||
{
|
||||
|
||||
Vector3D acceleration = CalculateAcceleration(Velocity, guidanceCommand);
|
||||
//Vector3D acceleration = CalculateAcceleration(Velocity);
|
||||
|
||||
Vector3D acceleration = GuidanceAcceleration;
|
||||
|
||||
// 使用四阶龙格-库塔方法更新导弹的位置和速度
|
||||
(Position, Velocity) = BasicGuidanceSystem.RungeKutta4(deltaTime, Position, Velocity, acceleration);
|
||||
@ -243,70 +197,67 @@ namespace ActiveProtect.Models
|
||||
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)
|
||||
private Vector3D CalculateAcceleration(Vector3D velocity)
|
||||
{
|
||||
Vector3D thrustAcceleration = Vector3D.Zero;
|
||||
Vector3D guidanceAcceleration = Vector3D.Zero;
|
||||
// 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;
|
||||
}
|
||||
// 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 = velocity.Normalize() * ThrustAcceleration;
|
||||
}
|
||||
else
|
||||
{
|
||||
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
|
||||
}
|
||||
}
|
||||
// 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 gravityAcceleration = new(0, -9.81, 0);
|
||||
|
||||
// 计算空气阻力的影响
|
||||
Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / Mass;
|
||||
Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration + gravityAcceleration +dragAcceleration;
|
||||
//Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration +dragAcceleration;
|
||||
//Vector3D totalAcceleration = GuidanceAcceleration + ThrustAcceleration + gravityAcceleration +dragAcceleration;
|
||||
//Vector3D totalAcceleration = GuidanceAcceleration + ThrustAcceleration + dragAcceleration;
|
||||
Vector3D totalAcceleration = GuidanceAcceleration;
|
||||
|
||||
Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {guidanceAcceleration}, 推力加速度: {thrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
|
||||
Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {GuidanceAcceleration}, 推力加速度: {ThrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
|
||||
if (totalAcceleration.Magnitude() > MaxAcceleration)
|
||||
{
|
||||
totalAcceleration = totalAcceleration.Normalize() * MaxAcceleration;
|
||||
@ -314,68 +265,6 @@ namespace ActiveProtect.Models
|
||||
|
||||
return totalAcceleration;
|
||||
}
|
||||
/// <summary>
|
||||
/// 切换导弹飞行阶段
|
||||
/// </summary>
|
||||
public void ChangeStage(FlightStage newStage)
|
||||
{
|
||||
if (stageStrategies.TryGetValue(newStage, out var strategy))
|
||||
{
|
||||
if (IsStageEnabled(newStage))
|
||||
{
|
||||
CurrentStage = newStage;
|
||||
currentStage = 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>
|
||||
/// 计算空气阻力
|
||||
@ -423,32 +312,32 @@ namespace ActiveProtect.Models
|
||||
/// <summary>
|
||||
/// 更新发动机燃烧时间
|
||||
/// </summary>
|
||||
private void UpdateEngineBurnTime(double deltaTime)
|
||||
{
|
||||
if (CurrentStage == FlightStage.Acceleration && EngineBurnTime < MaxEngineBurnTime)
|
||||
{
|
||||
EngineBurnTime += deltaTime;
|
||||
}
|
||||
}
|
||||
// private void UpdateEngineBurnTime(double deltaTime)
|
||||
// {
|
||||
// if (CurrentStage == 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;
|
||||
// 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();
|
||||
}
|
||||
// return Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), LOS).Normalize()
|
||||
// * ProportionalNavigationCoefficient * Velocity.Magnitude();
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 导弹爆炸
|
||||
/// </summary>
|
||||
public void Explode()
|
||||
protected virtual void Explode()
|
||||
{
|
||||
Deactivate();
|
||||
SimulationManager.HandleTargetHit(TargetId, Id);
|
||||
@ -492,7 +381,6 @@ namespace ActiveProtect.Models
|
||||
$" 速度: {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" +
|
||||
@ -523,7 +411,7 @@ namespace ActiveProtect.Models
|
||||
FlightTime = FlightTime,
|
||||
FlightDistance = FlightDistance,
|
||||
DistanceToTarget = DistanceToTarget,
|
||||
CurrentStage = CurrentStage,
|
||||
//CurrentStage = CurrentStage,
|
||||
HasGuidance = HasGuidance,
|
||||
LostGuidanceTime = LostGuidanceTime,
|
||||
EngineBurnTime = EngineBurnTime,
|
||||
@ -590,7 +478,7 @@ namespace ActiveProtect.Models
|
||||
/// <summary>
|
||||
/// 当前飞行阶段
|
||||
/// </summary>
|
||||
public FlightStage CurrentStage { get; set; }
|
||||
//public FlightStage CurrentStage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否有制导
|
||||
|
||||
@ -41,6 +41,7 @@ namespace ActiveProtect.Models
|
||||
MaxSpeed = tankConfig.MaxSpeed;
|
||||
MaxArmor = tankConfig.MaxArmor;
|
||||
CurrentArmor = tankConfig.MaxArmor;
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -6,25 +6,34 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
public class TerminalSensitiveMissile : MissileBase
|
||||
{
|
||||
private TerminalSensitiveSubmunition[] submunitions;
|
||||
|
||||
private Vector3D guidanceCommand;
|
||||
|
||||
// 分离高度 1000米
|
||||
// 分离高度 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 const int SubmunitionCount = 2;
|
||||
|
||||
public MissileConfig missileConfig { get; set; }
|
||||
|
||||
public TerminalSensitiveMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig, simulationManager)
|
||||
{
|
||||
submunitions = new TerminalSensitiveSubmunition[SubmunitionCount];
|
||||
guidanceCommand = Vector3D.Zero;
|
||||
this.missileConfig = missileConfig;
|
||||
|
||||
//计算分离点坐标,高度为SeparationHeight,距离目标的距离为SeparationDistance
|
||||
separationPoint = Vector3D.PointOnLine(SimulationManager.GetEntityById(TargetId).Position, Position, SeparationDistance) + new Vector3D(0, SeparationHeight, 0);
|
||||
@ -32,9 +41,9 @@ namespace ActiveProtect.Models
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
// 无动力抛物线飞行
|
||||
ApplyGravity(deltaTime);
|
||||
base.Update(deltaTime);
|
||||
|
||||
GuidanceAcceleration = new Vector3D(0, -9.8, 0);
|
||||
|
||||
Console.WriteLine($"分离点距离: {(separationPoint - Position).Magnitude()}");
|
||||
|
||||
@ -42,13 +51,16 @@ namespace ActiveProtect.Models
|
||||
double distanceToTarget = (SimulationManager.GetEntityById(TargetId).Position - Position).Magnitude();
|
||||
|
||||
//距离分离点距离小于50米,或者距离目标小于1400米,则分离
|
||||
if ((separationPoint - Position).Magnitude() <= 50 || distanceToTarget <= 1400)
|
||||
if ((separationPoint - Position).Magnitude() <= SeparationRange || distanceToTarget <= SeparationTargetDistance)
|
||||
{
|
||||
Console.WriteLine("分离");
|
||||
PerformSeparation();
|
||||
}
|
||||
}
|
||||
|
||||
// 分离动作,母弹抛出 2 个子弹,子弹朝向目标方向
|
||||
// 初始化子弹,设置子弹参数
|
||||
// 母弹完成任务,可以被移除
|
||||
private void PerformSeparation()
|
||||
{
|
||||
// 获取目标位置
|
||||
@ -67,37 +79,28 @@ namespace ActiveProtect.Models
|
||||
InitialPosition = this.Position,
|
||||
InitialOrientation = orientationToTarget, // 设置为朝向目标的方向
|
||||
InitialSpeed = 200, // 子弹初始速度
|
||||
MaxSpeed = 300,
|
||||
MaxSpeed = 2000,
|
||||
TargetIndex = 0,
|
||||
MaxFlightTime = 10,
|
||||
MaxFlightTime = 50,
|
||||
MaxFlightDistance = 1000,
|
||||
MaxAcceleration = 50,
|
||||
ProportionalNavigationCoefficient = 0.1,
|
||||
Mass = 10
|
||||
Mass = 10
|
||||
},
|
||||
SimulationManager);
|
||||
|
||||
SimulationManager.AddElement(submunitions[i]);
|
||||
submunitions[i].Activate();
|
||||
}
|
||||
|
||||
// 母弹完成任务,可以被移除
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
private void ApplyGravity(double deltaTime)
|
||||
{
|
||||
Velocity += new Vector3D(0, -9.8, 0) * deltaTime;
|
||||
}
|
||||
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"{base.GetStatus()}\nMother Missile Stage: {currentStage}, Separation Point: {separationPoint}";
|
||||
}
|
||||
|
||||
protected override Vector3D GetGuidanceCommand()
|
||||
{
|
||||
return guidanceCommand;
|
||||
return $"{base.GetStatus()}\n母弹, 分离点: {separationPoint}";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,14 +7,14 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
private enum SubmunitionStage
|
||||
{
|
||||
Separation,
|
||||
Deceleration,
|
||||
SpiralScan,
|
||||
Attack,
|
||||
SelfDestruct
|
||||
}
|
||||
|
||||
private SubmunitionStage runningStage;
|
||||
private Vector3D guidanceCommand;
|
||||
private SubmunitionStage currentStage;
|
||||
private double spiralAngle;
|
||||
private const double SpiralRotationSpeed = 4 * Math.PI; // 2 rotations per second
|
||||
private const double VerticalDescentSpeed = 10; // 10 m/s
|
||||
@ -29,6 +29,8 @@ namespace ActiveProtect.Models
|
||||
// 自毁高度 20米
|
||||
private const double SelfDestructHeight = 20;
|
||||
|
||||
private const double AttackSpeed = 200;
|
||||
|
||||
private Vector3D lastScanDirection;
|
||||
private bool targetDetected;
|
||||
private double detectionAngle;
|
||||
@ -39,15 +41,17 @@ namespace ActiveProtect.Models
|
||||
private MillimeterWaveAltimeter altimeter;
|
||||
private LaserRangefinder rangefinder;
|
||||
|
||||
private MissileConfig missileConfig;
|
||||
|
||||
public TerminalSensitiveSubmunition(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||
: base(id, missileConfig, simulationManager)
|
||||
{
|
||||
runningStage = SubmunitionStage.Deceleration;
|
||||
currentStage = SubmunitionStage.Separation;
|
||||
spiralAngle = 0;
|
||||
lastScanDirection = Vector3D.Zero;
|
||||
targetDetected = false;
|
||||
detectionAngle = 0;
|
||||
guidanceCommand = Vector3D.Zero;
|
||||
this.missileConfig = missileConfig;
|
||||
|
||||
// 初始化传感器
|
||||
infraredDetector = new InfraredDetector(Position, Orientation, 1000, 30);
|
||||
@ -66,8 +70,11 @@ namespace ActiveProtect.Models
|
||||
altimeter.Update(deltaTime);
|
||||
rangefinder.Update(deltaTime);
|
||||
|
||||
switch (runningStage)
|
||||
switch (currentStage)
|
||||
{
|
||||
case SubmunitionStage.Separation:
|
||||
UpdateSeparationStage(deltaTime);
|
||||
break;
|
||||
case SubmunitionStage.Deceleration:
|
||||
UpdateDecelerationStage(deltaTime);
|
||||
break;
|
||||
@ -83,28 +90,44 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSeparationStage(double deltaTime)
|
||||
{
|
||||
Console.WriteLine("分离阶段");
|
||||
// 分离阶段
|
||||
Vector3D deceleration = new Vector3D(0, 9.8, 0);
|
||||
Velocity += deceleration * deltaTime;
|
||||
Position += Velocity * deltaTime;
|
||||
|
||||
if (Position.Y <= DecelerationHeight)
|
||||
{
|
||||
currentStage = SubmunitionStage.Deceleration;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateDecelerationStage(double deltaTime)
|
||||
{
|
||||
// 减速下降
|
||||
Vector3D deceleration = new Vector3D(0, 9.8, 0) - Velocity.Normalize() * 5; // 假设减速度为5m/s^2
|
||||
Console.WriteLine("减速阶段");
|
||||
// 减速减旋,垂直速度减小
|
||||
Vector3D deceleration = new Vector3D(0, 9.8, 0) - Velocity.Normalize() * 50; // 假设减速度为5m/s^2
|
||||
Console.WriteLine($"减速速度: {deceleration}");
|
||||
Velocity += deceleration * deltaTime;
|
||||
|
||||
if (Velocity.Y >= -VerticalDescentSpeed)
|
||||
if (Velocity.Magnitude() <= VerticalDescentSpeed || Position.Y <= ScanningHeight)
|
||||
{
|
||||
Velocity = new Vector3D(0, -VerticalDescentSpeed, 0);
|
||||
}
|
||||
|
||||
if (Position.Y <= ScanningHeight)
|
||||
{
|
||||
runningStage = SubmunitionStage.SpiralScan;
|
||||
Velocity = new Vector3D(0, -VerticalDescentSpeed, 0);
|
||||
if (Position.Y <= ScanningHeight)
|
||||
{
|
||||
currentStage = SubmunitionStage.SpiralScan;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSpiralScanStage(double deltaTime)
|
||||
{
|
||||
Console.WriteLine("扫描阶段");
|
||||
spiralAngle = spiralAngle % (2 * Math.PI);
|
||||
spiralAngle += SpiralRotationSpeed * deltaTime;
|
||||
|
||||
|
||||
// 计算水平速度分量
|
||||
double horizontalSpeed = VerticalDescentSpeed * Math.Tan(ScanAngle);
|
||||
Vector3D horizontalVelocity = new Vector3D(
|
||||
@ -132,7 +155,7 @@ namespace ActiveProtect.Models
|
||||
}
|
||||
else if (Math.Abs(spiralAngle - detectionAngle) < 0.1) // 允许一定的误差
|
||||
{
|
||||
runningStage = SubmunitionStage.Attack;
|
||||
currentStage = SubmunitionStage.Attack;
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,40 +163,41 @@ namespace ActiveProtect.Models
|
||||
|
||||
if (Position.Y <= SelfDestructHeight)
|
||||
{
|
||||
runningStage = SubmunitionStage.SelfDestruct;
|
||||
currentStage = SubmunitionStage.SelfDestruct;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAttackStage(double deltaTime)
|
||||
{
|
||||
Console.WriteLine("攻击阶段");
|
||||
// 攻击逻辑
|
||||
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
||||
Vector3D direction = (targetPosition - Position).Normalize();
|
||||
Velocity = direction * MaxSpeed;
|
||||
Velocity = direction * AttackSpeed;
|
||||
|
||||
if (Vector3D.Distance(Position, targetPosition) < 1)
|
||||
if (Vector3D.Distance(Position, targetPosition) < 5)
|
||||
{
|
||||
Explode();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSelfDestructStage(double deltaTime)
|
||||
{
|
||||
SelfDestruct();
|
||||
}
|
||||
|
||||
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度的误差
|
||||
return Vector3D.DotProduct(scanDirection, toTarget) > Math.Cos(5 * Math.PI / 180); // 允许5度的误差
|
||||
}
|
||||
|
||||
public override string GetStatus()
|
||||
{
|
||||
return $"{base.GetStatus()}\nSubmunition Stage: {runningStage}\nSpiral Angle: {spiralAngle * 180 / Math.PI:F2}°\nTarget Detected: {targetDetected}";
|
||||
return $"{base.GetStatus()}\nSubmunition Stage: {currentStage}\nDetection Angle: {detectionAngle * 180 / Math.PI:F2}°\nSpiral Angle: {spiralAngle * 180 / Math.PI:F2}°\nTarget Detected: {targetDetected}";
|
||||
}
|
||||
|
||||
protected override Vector3D GetGuidanceCommand()
|
||||
{
|
||||
return guidanceCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
28
Program.cs
28
Program.cs
@ -38,8 +38,8 @@ namespace ActiveProtect
|
||||
new TankConfig(tankinfo)
|
||||
{
|
||||
InitialOrientation = new Orientation(Math.PI/4, 0, 0),
|
||||
InitialSpeed = 15,
|
||||
MaxSpeed = 20,
|
||||
InitialSpeed = 0,
|
||||
MaxSpeed = 25,
|
||||
MaxArmor = 100,
|
||||
HasLaserWarner = false,
|
||||
HasLaserJammer = true
|
||||
@ -83,9 +83,9 @@ namespace ActiveProtect
|
||||
InitialSpeed = 700,
|
||||
MaxSpeed = 800,
|
||||
TargetIndex = 0,
|
||||
MaxFlightTime = 0,
|
||||
MaxFlightTime = 10,
|
||||
MaxFlightDistance = 5000,
|
||||
ThrustAcceleration = 50,
|
||||
LaunchAcceleration = 50,
|
||||
MaxEngineBurnTime = 10,
|
||||
MaxAcceleration = 400,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
@ -98,13 +98,13 @@ namespace ActiveProtect
|
||||
new MissileConfig
|
||||
{
|
||||
InitialPosition = new Vector3D(2000, 10, 100),
|
||||
InitialOrientation = new Orientation(Math.PI, 0.1, 0.0),
|
||||
InitialOrientation = new Orientation(Math.PI, 0.0, 0.0),
|
||||
InitialSpeed = 300,
|
||||
MaxSpeed = 400,
|
||||
TargetIndex = 0,
|
||||
MaxFlightTime = 0,
|
||||
MaxFlightTime = 10,
|
||||
MaxFlightDistance = 3000,
|
||||
ThrustAcceleration = 50,
|
||||
LaunchAcceleration = 50,
|
||||
MaxEngineBurnTime = 10,
|
||||
MaxAcceleration = 400,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
@ -121,20 +121,20 @@ namespace ActiveProtect
|
||||
InitialSpeed = 800,
|
||||
MaxSpeed = 1000,
|
||||
TargetIndex = 0,
|
||||
MaxFlightTime = 30, // 增加最大飞行时间
|
||||
MaxFlightDistance = 5000, // 增加最大飞行距离
|
||||
ThrustAcceleration = 0, // 母弹的推力加速度
|
||||
MaxEngineBurnTime = 0, // 母弹的发动机燃烧时间
|
||||
MaxFlightTime = 30,
|
||||
MaxFlightDistance = 5000,
|
||||
LaunchAcceleration = 0,
|
||||
MaxEngineBurnTime = 0,
|
||||
MaxAcceleration = 1000,
|
||||
ProportionalNavigationCoefficient = 3,
|
||||
StageConfig = FlightStageConfig.TerminalSensitiveMissile, // 使用新的枚举值
|
||||
StageConfig = FlightStageConfig.TerminalSensitiveMissile,
|
||||
DistanceParams = new MissileDistanceParams(1000, 400, 20),
|
||||
Mass = 50, // 增加质量以反映母弹的重量
|
||||
Mass = 50,
|
||||
Type = MissileType.TerminalSensitiveMissile
|
||||
}
|
||||
},
|
||||
|
||||
SimulationTimeStep = 0.05
|
||||
SimulationTimeStep = 0.05 // 仿真时间步长, 激光驾束制导导弹需要更小的步长,< 0.025s
|
||||
};
|
||||
|
||||
// 创建仿真管理器
|
||||
|
||||
11
README.md
11
README.md
@ -169,3 +169,14 @@ ActiveProtect/
|
||||
6. **任务要求**:精确打击任务可能需要较大的 N 值,而区域防御任务可能使用较小的 N 值。
|
||||
|
||||
在我们的仿真系统中,用户可以通过调整 `ProportionalNavigationCoefficient` 参数来设置不同的 N 值,以模拟各种实际情况下的导弹行为。我们建议用户尝试不同的 N 值,观察其对导弹性能的影响,以找到最适合特定场景的设置。
|
||||
|
||||
## 仿真时间步长
|
||||
|
||||
仿真时间步长是仿真系统中的一个重要参数,它直接影响仿真结果的准确性和计算效率。在我们的仿真系统中,用户可以通过调整 `SimulationTimeStep` 参数来设置不同的仿真时间步长。
|
||||
|
||||
1. **SimulationTimeStep = 0.01**:这是最短的时间步长,仿真精确度最高,但计算成本也最高。
|
||||
2. **SimulationTimeStep = 0.025**:这是默认的时间步长,适用于大多数导弹和防御系统。(激光驾束制导导弹至少要用此步长)
|
||||
3. **SimulationTimeStep = 0.05**:这是另一个常用的步长,适用于一些需要较低精度的场景。
|
||||
4. **SimulationTimeStep = 0.1**:这是较低的时间步长,仿真精确度很低,用于快速验证。
|
||||
|
||||
用户可以根据具体需求选择合适的时间步长,以平衡仿真精度和计算效率。
|
||||
|
||||
@ -171,7 +171,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// 最大加速度(米/秒²)
|
||||
/// </summary>
|
||||
public double MaxAcceleration { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 比例导引系数
|
||||
/// </summary>
|
||||
@ -188,9 +188,9 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
public MissileDistanceParams DistanceParams { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 推力加速度(米/秒²)
|
||||
/// 发射推力加速度(米/秒²)
|
||||
/// </summary>
|
||||
public double ThrustAcceleration { get; set; }
|
||||
public double LaunchAcceleration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大发动机燃烧时间(秒)
|
||||
@ -233,7 +233,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
MaxFlightTime = 0;
|
||||
MaxFlightDistance = 0;
|
||||
StageConfig = FlightStageConfig.StandardMissile;
|
||||
ThrustAcceleration = 0;
|
||||
LaunchAcceleration = 0;
|
||||
MaxEngineBurnTime = 0;
|
||||
MaxAcceleration = 0;
|
||||
DistanceParams = new MissileDistanceParams(0, 0, 0);
|
||||
@ -410,7 +410,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// <summary>
|
||||
/// 末敏弹的预设配置
|
||||
/// </summary>
|
||||
public static FlightStageConfig TerminalSensitiveMissile => new(false, false, true, false, false);
|
||||
public static FlightStageConfig TerminalSensitiveMissile => new(true, true, false, false, true);
|
||||
|
||||
public FlightStageConfig(bool enableLaunch, bool enableAcceleration, bool enableCruise, bool enableTerminalGuidance, bool enableAttack)
|
||||
{
|
||||
|
||||
@ -52,7 +52,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
Orientation = orientation;
|
||||
Velocity = orientation.ToVector() * speed;
|
||||
SimulationManager = simulationManager;
|
||||
IsActive = true;
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -185,10 +185,14 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
|
||||
|
||||
// 激活所有元素
|
||||
ActivateAllElements();
|
||||
// ActivateAllElements();
|
||||
|
||||
// 激活部分元素
|
||||
ActivateSomeElements();
|
||||
|
||||
// 启动激光驾束仪
|
||||
laserBeamRider.StartBeamIllumination();
|
||||
//laserBeamRider.StartBeamIllumination();
|
||||
|
||||
}
|
||||
|
||||
//激活所有元素
|
||||
@ -199,6 +203,25 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
element.Activate();
|
||||
}
|
||||
}
|
||||
// 激活部分元素
|
||||
private void ActivateSomeElements()
|
||||
{
|
||||
// 激活坦克
|
||||
Elements.FindAll(e => e.Id == "Tank_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 == "LBR_1").ForEach(e => e.Activate());
|
||||
|
||||
// 激活末敏弹
|
||||
Elements.FindAll(e => e.Id == "TSM_3").ForEach(e => e.Activate());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发布仿真事件
|
||||
@ -216,7 +239,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"没<EFBFBD><EFBFBD>找到事件 {eventType.Name} 的处理程序");
|
||||
Console.WriteLine($"没找到事件 {eventType.Name} 的处理程序");
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,7 +344,7 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public void PrintStatus()
|
||||
{
|
||||
Console.WriteLine($"仿真时间: {CurrentTime:F2}");
|
||||
Console.WriteLine($"\n********** 仿真时间: {CurrentTime:F2}");
|
||||
foreach (var element in Elements)
|
||||
{
|
||||
Console.WriteLine(element.GetStatus());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user