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; } } }