From 2456d04c2836b80accfe54da4e7984b846427bab Mon Sep 17 00:00:00 2001
From: Tian jianyong <11429339@qq.com>
Date: Mon, 21 Oct 2024 22:51:58 +0800
Subject: [PATCH] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BA=86=E5=AF=BC=E5=BC=B9?=
=?UTF-8?q?=E8=BF=90=E8=A1=8C=E9=98=B6=E6=AE=B5=E5=A4=84=E7=90=86=E6=9C=BA?=
=?UTF-8?q?=E5=88=B6=EF=BC=8C=E5=AF=BC=E5=BC=B9=E5=9F=BA=E7=B1=BB=E4=B8=8D?=
=?UTF-8?q?=E5=86=8D=E8=B4=9F=E8=B4=A3=E5=AF=BC=E5=BC=B9=E7=9A=84=E8=BF=90?=
=?UTF-8?q?=E8=A1=8C=E9=98=B6=E6=AE=B5=EF=BC=8C=E6=94=B9=E7=94=B1=E5=90=84?=
=?UTF-8?q?=E5=AD=90=E7=B1=BB=E5=A4=84=E7=90=86=EF=BC=9B=E5=AE=8C=E5=96=84?=
=?UTF-8?q?=E4=BA=86=E6=9C=AB=E6=95=8F=E5=BC=B9=E8=BF=90=E8=A1=8C=E8=BF=87?=
=?UTF-8?q?=E7=A8=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Docs/MissileBase.bak | 620 ++++++++++++++++++
.../MissileStageStrategy.bak | 0
Docs/TerminalSensitiveMissileold.bak | 36 -
Models/BasicGuidanceSystem.cs | 36 +-
Models/IGuidanceSystem.cs | 9 -
Models/LaserBeamRiderGuidanceSystem.cs | 51 +-
Models/LaserBeamRiderMissile.cs | 76 ++-
Models/LaserSemiActiveGuidanceSystem.cs | 71 +-
Models/LaserSemiActiveGuidedMissile.cs | 82 ++-
Models/MissileBase.cs | 276 +++-----
Models/Tank.cs | 1 +
Models/TerminalSensitiveMissile.cs | 59 +-
Models/TerminalSensitiveSubmunition.cs | 76 ++-
Program.cs | 28 +-
README.md | 11 +
SimulationEnvironment/SimulationConfig.cs | 10 +-
SimulationEnvironment/SimulationElement.cs | 2 +-
SimulationEnvironment/SimulationManager.cs | 31 +-
18 files changed, 1048 insertions(+), 427 deletions(-)
create mode 100644 Docs/MissileBase.bak
rename Models/MissileStageStrategy.cs => Docs/MissileStageStrategy.bak (100%)
delete mode 100644 Docs/TerminalSensitiveMissileold.bak
delete mode 100644 Models/IGuidanceSystem.cs
diff --git a/Docs/MissileBase.bak b/Docs/MissileBase.bak
new file mode 100644
index 0000000..9cf89c5
--- /dev/null
+++ b/Docs/MissileBase.bak
@@ -0,0 +1,620 @@
+using System;
+using System.Collections.Generic;
+using ActiveProtect.SimulationEnvironment;
+using Model;
+
+namespace ActiveProtect.Models
+{
+ ///
+ /// 表示仿真中的导弹
+ ///
+ public class MissileBase : SimulationElement
+ {
+ ///
+ /// 导弹类型
+ ///
+ public MissileType Type { get; protected set; }
+
+ ///
+ /// 当前速度(米/秒)
+ ///
+ public double Speed { get; protected set; }
+
+ ///
+ /// 最大速度(米/秒)
+ ///
+ public double MaxSpeed { get; protected set; }
+
+ ///
+ /// 目标ID
+ ///
+ public string TargetId { get; protected set; }
+
+ ///
+ /// 最大飞行时间(秒)
+ ///
+ public double MaxFlightTime { get; protected set; }
+
+ ///
+ /// 最大飞行距离(米)
+ ///
+ public double MaxFlightDistance { get; protected set; }
+
+ ///
+ /// 当前飞行时间(秒)
+ ///
+ public double FlightTime { get; protected set; }
+
+ ///
+ /// 当前飞行距离(米)
+ ///
+ public double FlightDistance { get; protected set; }
+
+ ///
+ /// 与目标的距离(米)
+ ///
+ public double DistanceToTarget { get; protected set; }
+
+ ///
+ /// 导弹距离参数
+ ///
+ public MissileDistanceParams DistanceParams { get; protected set; }
+
+ ///
+ /// 飞行阶段配置
+ ///
+ public FlightStageConfig StageConfig { get; protected set; }
+
+ ///
+ /// 当前飞行阶段
+ ///
+ public FlightStage InitialStage { get; protected set; }
+
+ ///
+ /// 上一帧目标位置
+ ///
+ private Vector3D LastTargetPosition;
+
+ ///
+ /// 比例导引系数
+ ///
+ private const double N = 3;
+
+ ///
+ /// 推力加速度(米/秒²)
+ ///
+ public double ThrustAcceleration { get; protected set; }
+
+ ///
+ /// 当前发动机燃烧时间(秒)
+ ///
+ public double EngineBurnTime { get; protected set; }
+
+ ///
+ /// 最大发动机燃烧时间(秒)
+ ///
+ public double MaxEngineBurnTime { get; protected set; }
+
+ ///
+ /// 最大加速度(米/秒²)
+ ///
+ public double MaxAcceleration { get; protected set; } = 10000;
+
+ ///
+ /// 比例导引系数
+ ///
+ public double ProportionalNavigationCoefficient { get; set; }
+
+ ///
+ /// 是否有制导
+ ///
+ public bool HasGuidance { get; protected set; } = false;
+
+ ///
+ /// 失去制导的时间(秒)
+ ///
+ protected double LostGuidanceTime { get; set; } = 0;
+
+ ///
+ /// 最后已知的速度向量
+ ///
+ protected Vector3D LastKnownVelocity = Vector3D.Zero;
+
+ ///
+ /// 发射速度(米/秒)
+ ///
+ public const double LAUNCH_SPEED = 10;
+
+ ///
+ /// 发射阶段持续时间(秒)
+ ///
+ public const double LAUNCH_DURATION = 0.5;
+ ///
+ /// 当前飞行阶段策略
+ ///
+ protected IMissileStageStrategy currentStageStrategy;
+ ///
+ /// 飞行阶段策略字典
+ ///
+ private Dictionary stageStrategies;
+
+ ///
+ /// 导弹质量(千克)
+ ///
+ public double Mass { get; protected set; } = 100;
+
+ ///
+ /// 构造函数
+ ///
+ 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.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);
+ }
+
+ ///
+ /// 设置导弹的初始飞行阶段
+ ///
+ 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}");
+ }
+
+ ///
+ /// 更新导弹状态
+ ///
+ 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);
+ }
+ ///
+ /// 计算导弹的加速度
+ ///
+ 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;
+ }
+ ///
+ /// 切换导弹飞行阶段
+ ///
+ 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}");
+ }
+ }
+
+ ///
+ /// 检查指定飞行阶段是否启用
+ ///
+ 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
+ };
+ }
+
+ ///
+ /// 尝试切换到下一个可用的飞行阶段
+ ///
+ 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();
+ }
+
+ ///
+ /// 计算空气阻力
+ ///
+ 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;
+ }
+
+ ///
+ /// 检查是否命中目标
+ ///
+ protected bool CheckHit()
+ {
+ return DistanceToTarget <= DistanceParams.ExplosionDistance;
+ }
+
+ ///
+ /// 检查是否应该自毁
+ ///
+ 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;
+ }
+
+ ///
+ /// 更新发动机燃烧时间
+ ///
+ private void UpdateEngineBurnTime(double deltaTime)
+ {
+ if (InitialStage == FlightStage.Acceleration && EngineBurnTime < MaxEngineBurnTime)
+ {
+ EngineBurnTime += deltaTime;
+ }
+ }
+
+ ///
+ /// 计算比例导引加速度
+ ///
+ 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();
+ }
+
+ ///
+ /// 导弹爆炸
+ ///
+ public void Explode()
+ {
+ Deactivate();
+ SimulationManager.HandleTargetHit(TargetId, Id);
+ Console.WriteLine($"导弹 {Id} 在 {Position} 爆炸,命中目标!");
+ }
+
+ ///
+ /// 导弹自毁
+ ///
+ public void SelfDestruct()
+ {
+ if (IsActive)
+ {
+ string reason = FlightTime >= MaxFlightTime ? "超出最大飞行时间" :
+ FlightDistance >= MaxFlightDistance ? "超出最大飞行距离" :
+ Position.Y <= 0 ? "高度小于等于0" :
+ !HasGuidance ? "失去引导" : "未知原因";
+
+ Console.WriteLine($"导弹 {Id} 自毁。原因: {reason}");
+ Deactivate();
+ }
+ }
+
+ ///
+ /// 设置比例导引系数
+ ///
+ public void SetProportionalNavigationCoefficient(double newCoefficient)
+ {
+ ProportionalNavigationCoefficient = newCoefficient;
+ Console.WriteLine($"导弹 {Id} 的比例导引系数已更新为 {newCoefficient}");
+ }
+
+ ///
+ /// 获取导弹状态
+ ///
+ 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}";
+ }
+
+ ///
+ /// 更新导弹的制导状态
+ ///
+ 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
+ };
+ }
+ }
+
+ ///
+ /// 表示导弹的运行状态信息
+ ///
+ public struct MissileRunningState
+ {
+ ///
+ /// 导弹ID
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// 导弹类型
+ ///
+ public MissileType Type { get; set; }
+
+ ///
+ /// 当前位置
+ ///
+ public Vector3D Position { get; set; }
+
+ ///
+ /// 当前速度向量
+ ///
+ public Vector3D Velocity { get; set; }
+
+ ///
+ /// 当前朝向
+ ///
+ public Orientation Orientation { get; set; }
+
+ ///
+ /// 当前速度(米/秒)
+ ///
+ public double Speed { get; set; }
+
+ ///
+ /// 目标ID
+ ///
+ public string TargetId { get; set; }
+
+ ///
+ /// 当前飞行时间(秒)
+ ///
+ public double FlightTime { get; set; }
+
+ ///
+ /// 当前飞行距离(米)
+ ///
+ public double FlightDistance { get; set; }
+
+ ///
+ /// 与目标的距离(米)
+ ///
+ public double DistanceToTarget { get; set; }
+
+ ///
+ /// 当前飞行阶段
+ ///
+ public FlightStage CurrentStage { get; set; }
+
+ ///
+ /// 是否有制导
+ ///
+ public bool HasGuidance { get; set; }
+
+ ///
+ /// 失去制导时间(秒)
+ ///
+ public double LostGuidanceTime { get; set; }
+
+ ///
+ /// 当前发动机燃烧时间(秒)
+ ///
+ public double EngineBurnTime { get; set; }
+
+ ///
+ /// 是否处于活动状态
+ ///
+ public bool IsActive { get; set; }
+ }
+}
diff --git a/Models/MissileStageStrategy.cs b/Docs/MissileStageStrategy.bak
similarity index 100%
rename from Models/MissileStageStrategy.cs
rename to Docs/MissileStageStrategy.bak
diff --git a/Docs/TerminalSensitiveMissileold.bak b/Docs/TerminalSensitiveMissileold.bak
deleted file mode 100644
index 8c67302..0000000
--- a/Docs/TerminalSensitiveMissileold.bak
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Collections.Generic;
-using ActiveProtect.SimulationEnvironment;
-
-namespace ActiveProtect.Models
-{
- public class TerminalSensitiveMissile : SimulationElement
- {
- private TerminalSensitiveMotherMissile motherMissile;
- private List 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();
- 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;
- }
- }
-}
diff --git a/Models/BasicGuidanceSystem.cs b/Models/BasicGuidanceSystem.cs
index 5f1e147..824c107 100644
--- a/Models/BasicGuidanceSystem.cs
+++ b/Models/BasicGuidanceSystem.cs
@@ -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)
+ ///
+ /// 计算比例导引加速度
+ ///
+ /// 导弹位置
+ /// 导弹速度
+ /// 目标位置
+ /// 目标速度
+ /// 比例导引加速度
+ 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;
}
diff --git a/Models/IGuidanceSystem.cs b/Models/IGuidanceSystem.cs
deleted file mode 100644
index 171ac22..0000000
--- a/Models/IGuidanceSystem.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace ActiveProtect.Models
-{
- public interface IGuidanceSystem
- {
- bool HasGuidance { get; }
- void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity);
- Vector3D GetGuidanceCommand();
- }
-}
diff --git a/Models/LaserBeamRiderGuidanceSystem.cs b/Models/LaserBeamRiderGuidanceSystem.cs
index 155f984..b3a44e9 100644
--- a/Models/LaserBeamRiderGuidanceSystem.cs
+++ b/Models/LaserBeamRiderGuidanceSystem.cs
@@ -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()
diff --git a/Models/LaserBeamRiderMissile.cs b/Models/LaserBeamRiderMissile.cs
index 3ef431c..69594de 100644
--- a/Models/LaserBeamRiderMissile.cs
+++ b/Models/LaserBeamRiderMissile.cs
@@ -4,25 +4,34 @@ namespace ActiveProtect.Models
{
public class LaserBeamRiderMissile : MissileBase
{
+ ///
+ /// 激光驾束制导导弹阶段
+ ///
+ 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("导弹", "激光驾束制导导弹");
diff --git a/Models/LaserSemiActiveGuidanceSystem.cs b/Models/LaserSemiActiveGuidanceSystem.cs
index e7a040d..15a9b95 100644
--- a/Models/LaserSemiActiveGuidanceSystem.cs
+++ b/Models/LaserSemiActiveGuidanceSystem.cs
@@ -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();
diff --git a/Models/LaserSemiActiveGuidedMissile.cs b/Models/LaserSemiActiveGuidedMissile.cs
index 8a0a53a..6d726a9 100644
--- a/Models/LaserSemiActiveGuidedMissile.cs
+++ b/Models/LaserSemiActiveGuidedMissile.cs
@@ -8,8 +8,21 @@ namespace ActiveProtect.Models
///
public class LaserSemiActiveGuidedMissile : MissileBase
{
+ ///
+ /// 激光半主动制导导弹阶段
+ ///
+ private enum LSAGM_Stage
+ {
+ Launch, // 发射阶段
+ Cruise, // 巡航阶段
+ Explode, // 爆炸阶段
+ SelfDestruct // 自毁阶段
+ }
+
+ private LSAGM_Stage currentStage;
private LaserSemiActiveGuidanceSystem LaserGuidanceSystem;
public string LaserDesignatorId { get; set; } = "";
+ private MissileConfig missileConfig;
///
/// 构造函数
@@ -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;
}
///
@@ -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);
}
- ///
- /// 获取制导命令
- ///
- /// 制导命令
- 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();
+ }
+
}
}
diff --git a/Models/MissileBase.cs b/Models/MissileBase.cs
index 3bd8f20..67ee32e 100644
--- a/Models/MissileBase.cs
+++ b/Models/MissileBase.cs
@@ -60,16 +60,6 @@ namespace ActiveProtect.Models
///
public MissileDistanceParams DistanceParams { get; protected set; }
- ///
- /// 飞行阶段配置
- ///
- public FlightStageConfig StageConfig { get; protected set; }
-
- ///
- /// 当前飞行阶段
- ///
- public FlightStage CurrentStage { get; protected set; }
-
///
/// 上一帧目标位置
///
@@ -83,7 +73,7 @@ namespace ActiveProtect.Models
///
/// 推力加速度(米/秒²)
///
- public double ThrustAcceleration { get; protected set; }
+ public double LaunchAcceleration { get; protected set; }
///
/// 当前发动机燃烧时间(秒)
@@ -98,7 +88,7 @@ namespace ActiveProtect.Models
///
/// 最大加速度(米/秒²)
///
- public double MaxAcceleration { get; protected set; } = 10000;
+ public double MaxAcceleration { get; protected set; }
///
/// 比例导引系数
@@ -124,20 +114,22 @@ namespace ActiveProtect.Models
/// 发射速度(米/秒)
///
public const double LAUNCH_SPEED = 10;
-
- ///
- /// 发射阶段持续时间(秒)
- ///
- public const double LAUNCH_DURATION = 0.5;
-
- protected IMissileStageStrategy currentStage;
- private Dictionary stageStrategies;
///
/// 导弹质量(千克)
///
public double Mass { get; protected set; } = 100;
+ ///
+ /// 制导加速度
+ ///
+ protected Vector3D GuidanceAcceleration { get; set; }
+
+ ///
+ /// 推力加速度
+ ///
+ protected Vector3D ThrustAcceleration { get; set; }
+
///
/// 构造函数
///
@@ -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.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);
}
- ///
- /// 设置导弹的初始飞行阶段
- ///
- 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}");
- }
-
///
/// 更新导弹状态
///
@@ -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);
}
+
///
/// 计算导弹的加速度
///
- 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;
}
- ///
- /// 切换导弹飞行阶段
- ///
- 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}");
- }
- }
-
- ///
- /// 检查指定飞行阶段是否启用
- ///
- 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
- };
- }
-
- ///
- /// 尝试切换到下一个可用的飞行阶段
- ///
- 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();
- }
///
/// 计算空气阻力
@@ -423,32 +312,32 @@ namespace ActiveProtect.Models
///
/// 更新发动机燃烧时间
///
- 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;
+ // }
+ // }
///
/// 计算比例导引加速度
///
- 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();
+ // }
///
/// 导弹爆炸
///
- 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
///
/// 当前飞行阶段
///
- public FlightStage CurrentStage { get; set; }
+ //public FlightStage CurrentStage { get; set; }
///
/// 是否有制导
diff --git a/Models/Tank.cs b/Models/Tank.cs
index 36ebb01..fb7fc86 100644
--- a/Models/Tank.cs
+++ b/Models/Tank.cs
@@ -41,6 +41,7 @@ namespace ActiveProtect.Models
MaxSpeed = tankConfig.MaxSpeed;
MaxArmor = tankConfig.MaxArmor;
CurrentArmor = tankConfig.MaxArmor;
+ IsActive = false;
}
///
diff --git a/Models/TerminalSensitiveMissile.cs b/Models/TerminalSensitiveMissile.cs
index 6b6bd74..e0770ab 100644
--- a/Models/TerminalSensitiveMissile.cs
+++ b/Models/TerminalSensitiveMissile.cs
@@ -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}";
}
}
-}
+}
\ No newline at end of file
diff --git a/Models/TerminalSensitiveSubmunition.cs b/Models/TerminalSensitiveSubmunition.cs
index 91e4c0e..08e7883 100644
--- a/Models/TerminalSensitiveSubmunition.cs
+++ b/Models/TerminalSensitiveSubmunition.cs
@@ -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;
- }
}
}
diff --git a/Program.cs b/Program.cs
index bf859d2..09b2bf5 100644
--- a/Program.cs
+++ b/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
};
// 创建仿真管理器
diff --git a/README.md b/README.md
index 97da885..d02ca2c 100644
--- a/README.md
+++ b/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**:这是较低的时间步长,仿真精确度很低,用于快速验证。
+
+用户可以根据具体需求选择合适的时间步长,以平衡仿真精度和计算效率。
diff --git a/SimulationEnvironment/SimulationConfig.cs b/SimulationEnvironment/SimulationConfig.cs
index 51c8c0c..9bbb27f 100644
--- a/SimulationEnvironment/SimulationConfig.cs
+++ b/SimulationEnvironment/SimulationConfig.cs
@@ -171,7 +171,7 @@ namespace ActiveProtect.SimulationEnvironment
/// 最大加速度(米/秒²)
///
public double MaxAcceleration { get; set; }
-
+
///
/// 比例导引系数
///
@@ -188,9 +188,9 @@ namespace ActiveProtect.SimulationEnvironment
public MissileDistanceParams DistanceParams { get; set; }
///
- /// 推力加速度(米/秒²)
+ /// 发射推力加速度(米/秒²)
///
- public double ThrustAcceleration { get; set; }
+ public double LaunchAcceleration { get; set; }
///
/// 最大发动机燃烧时间(秒)
@@ -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
///
/// 末敏弹的预设配置
///
- 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)
{
diff --git a/SimulationEnvironment/SimulationElement.cs b/SimulationEnvironment/SimulationElement.cs
index ab834a7..b88ff9c 100644
--- a/SimulationEnvironment/SimulationElement.cs
+++ b/SimulationEnvironment/SimulationElement.cs
@@ -52,7 +52,7 @@ namespace ActiveProtect.SimulationEnvironment
Orientation = orientation;
Velocity = orientation.ToVector() * speed;
SimulationManager = simulationManager;
- IsActive = true;
+ IsActive = false;
}
///
diff --git a/SimulationEnvironment/SimulationManager.cs b/SimulationEnvironment/SimulationManager.cs
index 7136700..c441169 100644
--- a/SimulationEnvironment/SimulationManager.cs
+++ b/SimulationEnvironment/SimulationManager.cs
@@ -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());
+ }
///
/// 发布仿真事件
@@ -216,7 +239,7 @@ namespace ActiveProtect.SimulationEnvironment
}
else
{
- Console.WriteLine($"没��找到事件 {eventType.Name} 的处理程序");
+ Console.WriteLine($"没找到事件 {eventType.Name} 的处理程序");
}
}
@@ -321,7 +344,7 @@ namespace ActiveProtect.SimulationEnvironment
///
public void PrintStatus()
{
- Console.WriteLine($"仿真时间: {CurrentTime:F2}");
+ Console.WriteLine($"\n********** 仿真时间: {CurrentTime:F2}");
foreach (var element in Elements)
{
Console.WriteLine(element.GetStatus());