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());