diff --git a/Models/Common.cs b/Models/Common.cs index a2aaef0..f5ff502 100644 --- a/Models/Common.cs +++ b/Models/Common.cs @@ -1,4 +1,5 @@ using System; +using System.Numerics; namespace ActiveProtect.Models { @@ -218,6 +219,35 @@ namespace ActiveProtect.Models return a + unitDirection * distance; } + internal Vector3D Rotate(Orientation orientation, double misalignmentAngle) + { + // 首先,根据方向和失调角计算出旋转矩阵 + Matrix4x4 rotationMatrix = CalculateRotationMatrix(orientation, misalignmentAngle); + + // 然后,使用旋转矩阵对当前向量进行旋转 + Vector3D rotatedVector = ApplyRotationMatrix(this, rotationMatrix); + return rotatedVector; + } + + private static Matrix4x4 CalculateRotationMatrix(Orientation orientation, double misalignmentAngle) + { + // 创建旋转矩阵 + Matrix4x4 yawRotation = Matrix4x4.CreateRotationY((float)orientation.Yaw); + Matrix4x4 pitchRotation = Matrix4x4.CreateRotationX((float)orientation.Pitch); + Matrix4x4 rollRotation = Matrix4x4.CreateRotationZ((float)orientation.Roll); + Matrix4x4 misalignmentRotation = Matrix4x4.CreateRotationY((float)misalignmentAngle); + + // 组合旋转矩阵 + return misalignmentRotation * yawRotation * pitchRotation * rollRotation; + } + + private static Vector3D ApplyRotationMatrix(Vector3D vector, Matrix4x4 matrix) + { + double x = vector.X * matrix.M11 + vector.Y * matrix.M21 + vector.Z * matrix.M31 + matrix.M41; + double y = vector.X * matrix.M12 + vector.Y * matrix.M22 + vector.Z * matrix.M32 + matrix.M42; + double z = vector.X * matrix.M13 + vector.Y * matrix.M23 + vector.Z * matrix.M33 + matrix.M43; + return new Vector3D(x, y, z); + } } /// @@ -281,8 +311,13 @@ namespace ActiveProtect.Models return angle; } + internal Vector3D Rotate(Vector3D vector, double misalignmentAngle) + { + throw new NotImplementedException(); + } + /// - /// 根据给定的方向向量创建方向 + /// 根���给定的方向向量创建方向 /// /// 方向向量 /// 对应的方向 diff --git a/Models/InfraredCommandGuidanceSystem.cs b/Models/InfraredCommandGuidanceSystem.cs new file mode 100644 index 0000000..943819e --- /dev/null +++ b/Models/InfraredCommandGuidanceSystem.cs @@ -0,0 +1,124 @@ +using System; +using ActiveProtect.SimulationEnvironment; + +namespace ActiveProtect.Models +{ + /// + /// 红外指令导引系统类 + /// + public class InfraredCommandGuidanceSystem : BasicGuidanceSystem + { + private Vector3D lastTrackerToTargetVector; + private Vector3D lastTrackerToMissileVector; + private double timeSinceLastCommand; + private Vector3D previousLineOfSight; + private double timeSinceLastCalculation; + private Vector3D lastGuidanceAcceleration; + + /// + /// 比例导航系数 + /// + public double ProportionalNavigationCoefficient { get; set; } + + /// + /// 最大加速度 + /// + public double MaxAcceleration { get; set; } + + /// + /// 构造函数 + /// + public InfraredCommandGuidanceSystem(double maxAcceleration, double proportionalNavigationCoefficient) + : base() + { + lastTrackerToTargetVector = Vector3D.Zero; + lastTrackerToMissileVector = Vector3D.Zero; + timeSinceLastCommand = 0; + MaxAcceleration = maxAcceleration; + ProportionalNavigationCoefficient = proportionalNavigationCoefficient; + timeSinceLastCalculation = 0; + previousLineOfSight = Vector3D.Zero; + lastGuidanceAcceleration = Vector3D.Zero; + } + + /// + /// 更新制导系统 + /// + public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity) + { + base.Update(deltaTime, missilePosition, missileVelocity); + timeSinceLastCommand += deltaTime; + CalculateGuidanceAcceleration(deltaTime); + } + + /// + /// 接收制导指令 + /// + public void ReceiveGuidanceCommand(Vector3D trackerToTargetVector, Vector3D trackerToMissileVector) + { + HasGuidance = true; + lastTrackerToTargetVector = trackerToTargetVector; + lastTrackerToMissileVector = trackerToMissileVector; + timeSinceLastCommand = 0; + } + + /// + /// 计算制导加速度 + /// + protected override void CalculateGuidanceAcceleration(double deltaTime) + { + if (HasGuidance && lastTrackerToTargetVector.Magnitude() > 0 && lastTrackerToMissileVector.Magnitude() > 0) + { + // 计算当前视线向量(从导弹到目标) + Vector3D currentLineOfSight = (lastTrackerToTargetVector - lastTrackerToMissileVector).Normalize(); + + // 计算视线角速率 + Vector3D lineOfSightRate; + if (previousLineOfSight != Vector3D.Zero && timeSinceLastCalculation > 0) + { + lineOfSightRate = Vector3D.CrossProduct(previousLineOfSight, currentLineOfSight) / timeSinceLastCalculation; + } + else + { + lineOfSightRate = Vector3D.Zero; + } + + // 计算制导加速度 + Vector3D newGuidanceAcceleration = Vector3D.CrossProduct(lineOfSightRate, Velocity) * ProportionalNavigationCoefficient; + + // 应用低通滤波器来平滑加速度变化,alpha越大,平滑效果越强 + double alpha = 0.2; + GuidanceAcceleration = lastGuidanceAcceleration * (1 - alpha) + newGuidanceAcceleration * alpha; + + // 限制最大加速度 + if (GuidanceAcceleration.Magnitude() > MaxAcceleration) + { + GuidanceAcceleration = GuidanceAcceleration.Normalize() * MaxAcceleration; + } + + // 更新上一次的视线向量和计算时间 + previousLineOfSight = currentLineOfSight; + timeSinceLastCalculation = deltaTime; + lastGuidanceAcceleration = GuidanceAcceleration; + + Console.WriteLine($"Missile Guidance: Current Position: {Position}, Velocity: {Velocity}, " + + $"Acceleration: {GuidanceAcceleration}, " + + $"LOS Rate: {lineOfSightRate.Magnitude()}, LOS: {currentLineOfSight}, " + + $"Distance to Target: {(lastTrackerToTargetVector - lastTrackerToMissileVector).Magnitude()}\n"); + } + else + { + GuidanceAcceleration = Vector3D.Zero; + } + } + + /// + /// 获取制导系统状态 + /// + public override string GetStatus() + { + return base.GetStatus() + $", GuidanceAcceleration: {GuidanceAcceleration}, " + + $"Tracker to Target Vector: {lastTrackerToTargetVector}, Tracker to Missile Vector: {lastTrackerToMissileVector}"; + } + } +} diff --git a/Models/InfraredCommandGuidedMissile.cs b/Models/InfraredCommandGuidedMissile.cs new file mode 100644 index 0000000..758b618 --- /dev/null +++ b/Models/InfraredCommandGuidedMissile.cs @@ -0,0 +1,189 @@ +using System; +using ActiveProtect.SimulationEnvironment; + +namespace ActiveProtect.Models +{ + + + /// + /// 红外指令制导导弹类 + /// + public class InfraredCommandGuidedMissile : MissileBase + { + /// + /// 红外指令制导导弹阶段 + /// + private enum ICGM_Stage + { + Launch, // 发射阶段 + Cruise, // 巡航阶段 + Explode, // 爆炸阶段 + SelfDestruct // 自毁阶段 + } + + /// + /// 当前阶段 + /// + private ICGM_Stage currentStage; + + /// + /// 红外热源辐射功率(瓦特) + /// + public double RadiationPower { get; set; } + + /// + /// 红外指令导引系统 + /// + private readonly InfraredCommandGuidanceSystem guidanceSystem; + + /// + /// 红外测角仪 + /// + private InfraredTracker infraredTracker; + + /// + /// 构造函数 + /// + public InfraredCommandGuidedMissile(MissileConfig config, ISimulationManager manager) : base(config, manager) + { + infraredTracker = null!; + RadiationPower = 1000; + + // 初始化红外指令导引系统,包括自适应 PID 参数 + guidanceSystem = new InfraredCommandGuidanceSystem( + maxAcceleration: config.MaxAcceleration, + proportionalNavigationCoefficient: config.ProportionalNavigationCoefficient + ); + + } + + /// + /// 更新导弹状态 + /// + protected override void UpdateMotionState(double deltaTime) + { + // 点亮红外热源 + LightInfraredSource(); + + switch (currentStage) + { + case ICGM_Stage.Launch: + UpdateLaunchStage(deltaTime); + break; + case ICGM_Stage.Cruise: + UpdateCruiseStage(deltaTime); + break; + case ICGM_Stage.Explode: + UpdateExplodeStage(deltaTime); + break; + case ICGM_Stage.SelfDestruct: + UpdateSelfDestructStage(deltaTime); + break; + } + + base.UpdateMotionState(deltaTime); + + } + + /// + /// 更新发射阶段 + /// + /// 时间步长 + private void UpdateLaunchStage(double deltaTime) + { + // 发射阶段 + GuidanceAcceleration = Vector3D.Zero; + if (FlightTime >= 0.1) + { + currentStage = ICGM_Stage.Cruise; + } + } + /// + /// 更新巡航阶段 + /// + /// 时间步长 + private void UpdateCruiseStage(double deltaTime) + { + guidanceSystem.Update(deltaTime, Position, Velocity); + GuidanceAcceleration = guidanceSystem.GetGuidanceAcceleration(); + if (DistanceToTarget <= ExplosionRadius) + { + currentStage = ICGM_Stage.Explode; + } + if(ShouldSelfDestruct()) + { + currentStage = ICGM_Stage.SelfDestruct; + } + } + + /// + /// 更新爆炸阶段 + /// + /// 时间步长 + private void UpdateExplodeStage(double deltaTime) + { + // 爆炸阶段 + Explode(); + } + + /// + /// 更新自毁阶段 + /// + /// 时间步长 + private void UpdateSelfDestructStage(double deltaTime) + { + // 自毁阶段 + SelfDestruct(); + } + + + /// + /// 处理制导指令事件 + /// + private void HandleGuidanceCommand(InfraredGuidanceCommandEvent evt) + { + if (evt.TargetMissileId == Id) + { + if (infraredTracker == null && evt.SenderId != null) + { + if (SimulationManager.GetEntityById(evt.SenderId) is InfraredTracker infraredTracker) + { + this.infraredTracker = infraredTracker; + } + } + + guidanceSystem.ReceiveGuidanceCommand(evt.TrackerToTargetVector, evt.TrackerToMissileVector); + } + } + + /// + /// 点亮红外热源 + /// + public void LightInfraredSource() + { + SimulationManager.PublishEvent(new InfraredGuidanceMissileLightEvent { RadiationPower = this.RadiationPower, SenderId = this.Id }); + } + + public override void Activate() + { + base.Activate(); + // 订阅红外指令制导事件 + SimulationManager.SubscribeToEvent(HandleGuidanceCommand); + } + + public override void Deactivate() + { + base.Deactivate(); + // 取消订阅红外指令制导事件 + SimulationManager.UnsubscribeFromEvent(HandleGuidanceCommand); + } + + /// + /// 获取导弹状态 + /// + public override string GetStatus() + { + return base.GetStatus() + $"\n 当前阶段:{currentStage}\n 红外指令导引系统状态: {guidanceSystem.GetStatus()}"; + } + } +} diff --git a/Models/InfraredTracker.cs b/Models/InfraredTracker.cs new file mode 100644 index 0000000..ea9d1fc --- /dev/null +++ b/Models/InfraredTracker.cs @@ -0,0 +1,152 @@ +using System; +using ActiveProtect.SimulationEnvironment; + +namespace ActiveProtect.Models +{ + /// + /// 红外测角仪类 + /// + public class InfraredTracker : SimulationElement + { + /// + /// 当前跟踪的导弹ID + /// + public string? TrackedMissileId { get; private set; } + + /// + /// 目标ID + /// + public string? TargetId { get; private set; } + + + /// + /// 上次更新时间 + /// + private double timeSinceLastUpdate; + + private readonly InfraredTrackerConfig config; + + /// + /// 构造函数 + /// + public InfraredTracker(string id, string targetId, InfraredTrackerConfig config, ISimulationManager manager) + : base(id, config.InitialPosition, config.InitialOrientation, 0, manager) + { + timeSinceLastUpdate = 0; + TargetId = targetId; + this.config = config; + } + + /// + /// 更新红外测角仪状态 + /// + public override void Update(double deltaTime) + { + if (!IsActive) return; + + timeSinceLastUpdate += deltaTime; + + // 检查是否需要更新 + if (timeSinceLastUpdate >= 1 / config.UpdateFrequency) + { + UpdateTracking(); + timeSinceLastUpdate = 0; + } + } + + /// + /// 更新跟踪状态 + /// + private void UpdateTracking() + { + if (TrackedMissileId == null || TargetId == null) return; + + var target = SimulationManager.GetEntityById(TargetId); + var missile = SimulationManager.GetEntityById(TrackedMissileId) as InfraredCommandGuidedMissile; + + if (missile == null || target == null) return; + + // 计算导弹到测角仪的距离 + double distanceToMissile = Vector3D.Distance(Position, missile.Position); + + // 检查导弹是否在跟踪范围内 + if (distanceToMissile <= config.MaxTrackingRange) + { + // 计算测角仪到导弹的向量 + Vector3D trackerToMissile = (missile.Position - Position).Normalize(); + + // 计算测角仪到目标的向量 + Vector3D trackerToTarget = (target.Position - Position).Normalize(); + + // 发送制导指令事件 + PublishGuidanceCommandEvent(missile.Id, trackerToMissile, trackerToTarget, Id); + } + else + { + // 导弹超出跟踪范围,停止跟踪 + StopTracking(); + } + } + + /// + /// 停止跟踪 + /// + public void StopTracking() + { + TrackedMissileId = null; + TargetId = null; + } + + /// + /// 发布制导指令事件 + /// + private void PublishGuidanceCommandEvent(string missileId, Vector3D trackerToMissileVector, Vector3D trackerToTargetVector, string senderId) + { + var evt = new InfraredGuidanceCommandEvent + { + TargetMissileId = missileId, + TrackerToMissileVector = trackerToMissileVector, + TrackerToTargetVector = trackerToTargetVector, + SenderId = senderId + }; + SimulationManager.PublishEvent(evt); + } + + /// + /// 处理红外指令制导导弹点亮红外热源事件 + /// + private void OnInfraredGuidanceMissileLight(InfraredGuidanceMissileLightEvent evt) + { + // 处理导弹点亮红外热源事件 + TrackedMissileId ??= evt.SenderId; + } + + /// + /// 激活红外测角仪 + /// + public override void Activate() + { + base.Activate(); + SimulationManager.SubscribeToEvent(OnInfraredGuidanceMissileLight); + } + + /// + /// 销毁红外测角仪 + /// + public override void Deactivate() + { + base.Deactivate(); + SimulationManager.UnsubscribeFromEvent(OnInfraredGuidanceMissileLight); + } + + /// + /// 获取红外测角仪状态 + /// + public override string GetStatus() + { + return $"红外测角仪 {Id} 位置: {Position}, 朝向: {Orientation}, " + + $"跟踪导弹: {TrackedMissileId ?? "无"}, 目标: {TargetId ?? "无"}"; + } + + } +} diff --git a/Models/Sensors.cs b/Models/Sensors.cs index 82354ee..314f235 100644 --- a/Models/Sensors.cs +++ b/Models/Sensors.cs @@ -167,7 +167,7 @@ namespace ActiveProtect.Models /// 辐射计的位置 /// 辐射计的朝向 /// 工作频率 - /// 辐射检测阈值 + /// 辐射温差检测阈值 public MillimeterWaveRadiometer(Vector3D position, Orientation orientation, double frequency, double detectionTemperatureDifferenceThreshold) : base(position, orientation) { @@ -202,7 +202,7 @@ namespace ActiveProtect.Models { private double currentAltitude; - private TerminalSensitiveSubmunition submunition; + private readonly TerminalSensitiveSubmunition submunition; /// /// 最大测量高度 diff --git a/Program.cs b/Program.cs index d0dcf38..49362a6 100644 --- a/Program.cs +++ b/Program.cs @@ -125,10 +125,38 @@ namespace ActiveProtect ProportionalNavigationCoefficient = 3, Mass = 50, Type = MissileType.TerminalSensitiveMissile + }, + // 红外指令制导导弹配置 + new() { + Id = "ICGM_1", + InitialPosition = new Vector3D(2000, 100, 100), + InitialOrientation = new Orientation(Math.PI, 0.0, 0), + InitialSpeed = 300, + MaxSpeed = 400, + TargetIndex = 0, + MaxFlightTime = 60, + MaxFlightDistance = 5000, + LaunchAcceleration = 50, + MaxEngineBurnTime = 10, + MaxAcceleration = 1000, + ExplosionRadius = 10, + ProportionalNavigationCoefficient = 1, + Mass = 50, + Type = MissileType.InfraredCommandGuidance } }, - - SimulationTimeStep = 0.025 // 仿真时间步长, 激光驾束制导导弹需要更小的步长,< 0.025s + // 配置红外测角仪 + InfraredTrackerConfig = new InfraredTrackerConfig + { + Id = "IT_1", + InitialPosition = new Vector3D(2500, 0, 100), + InitialOrientation = new Orientation(Math.PI, 0, 0), + MaxTrackingRange = 10000, // 10公里 + FieldOfView = Math.PI / 4, // 45度 + AngleMeasurementAccuracy = 0.000005, // 0.0005弧度 (约0.029度) + UpdateFrequency = 10 // 20赫兹 + }, + SimulationTimeStep = 0.01 // 仿真时间步长, 激光驾束制导导弹需要更小的步长,< 0.025s }; // 创建仿真管理器 @@ -141,7 +169,7 @@ namespace ActiveProtect { simulationManager.Update(); simulationManager.PrintStatus(); - Thread.Sleep(100); // 暂停100毫秒,使输出更易读 + Thread.Sleep(50); // 暂停100毫秒,使输出更易读 iteration++; } diff --git a/SimulationEnvironment/SimulationConfig.cs b/SimulationEnvironment/SimulationConfig.cs index 974870d..e383573 100644 --- a/SimulationEnvironment/SimulationConfig.cs +++ b/SimulationEnvironment/SimulationConfig.cs @@ -1,5 +1,5 @@ +using System; using System.Collections.Generic; -using System.ComponentModel; using ActiveProtect.Models; using Model; @@ -45,6 +45,11 @@ namespace ActiveProtect.SimulationEnvironment /// public double SimulationTimeStep { get; set; } + /// + /// 红外测角仪配置 + /// + public InfraredTrackerConfig InfraredTrackerConfig { get; set; } + /// /// 构造函数,初始化默认配置 /// @@ -56,6 +61,7 @@ namespace ActiveProtect.SimulationEnvironment LaserBeamRiderConfig = new LaserBeamRiderConfig(); LaserWarnerConfig = new LaserWarnerConfig(); LaserJammerConfig = new LaserJammerConfig(); + InfraredTrackerConfig = new InfraredTrackerConfig(); SimulationTimeStep = 0.1; // 默认时间步长为0.1秒 } } @@ -76,7 +82,7 @@ namespace ActiveProtect.SimulationEnvironment public Vector3D InitialPosition { get; set; } /// - /// 初始朝向 + /// 初���向 /// public Orientation InitialOrientation { get; set; } @@ -223,6 +229,31 @@ namespace ActiveProtect.SimulationEnvironment /// public MissileType Type { get; set; } + /// + /// 比例增益 + /// + public double Kp { get; set; } + + /// + /// 积分增益 + /// + public double Ki { get; set; } + + /// + /// 微分增益 + /// + public double Kd { get; set; } + + /// + /// 自适应速率 + /// + public double AdaptiveRate { get; set; } + + /// + /// 期望性能指标 + /// + public double DesiredPerformance { get; set; } + /// /// 构造函数,设置默认值 /// @@ -426,4 +457,59 @@ namespace ActiveProtect.SimulationEnvironment PowerIncreaseRate = 2000.0; // 每秒增加的功率 } } + + /// + /// 红外测角仪配置类 + /// + public class InfraredTrackerConfig + { + /// + /// 红外测角仪ID + /// + public string Id { get; set; } + + /// + /// 初始位置 + /// + public Vector3D InitialPosition { get; set; } + + /// + /// 初始朝向 + /// + public Orientation InitialOrientation { get; set; } + + /// + /// 最大跟踪距离(米) + /// + public double MaxTrackingRange { get; set; } + + /// + /// 视场角(弧度) + /// + public double FieldOfView { get; set; } + + /// + /// 角度测量精度(弧度) + /// + public double AngleMeasurementAccuracy { get; set; } + + /// + /// 更新频率(赫兹) + /// + public double UpdateFrequency { get; set; } + + /// + /// 构造函数,设置默认值 + /// + public InfraredTrackerConfig() + { + Id = ""; + InitialPosition = new Vector3D(0, 0, 0); + InitialOrientation = new Orientation(0, 0, 0); + MaxTrackingRange = 10000; // 10公里 + FieldOfView = Math.PI / 3; // 60度 + AngleMeasurementAccuracy = 0.001; // 0.001弧度 (约0.057度) + UpdateFrequency = 10; // 10赫兹 + } + } } diff --git a/SimulationEnvironment/SimulationEvents.cs b/SimulationEnvironment/SimulationEvents.cs index 341e22c..53f9ba2 100644 --- a/SimulationEnvironment/SimulationEvents.cs +++ b/SimulationEnvironment/SimulationEvents.cs @@ -45,7 +45,6 @@ namespace ActiveProtect.SimulationEnvironment public SimulationElement? Target { get; set; } } - /// /// 激光照射更新事件 /// @@ -166,4 +165,36 @@ namespace ActiveProtect.SimulationEnvironment { public LaserBeamRider? LaserBeamRider { get; set; } } + + /// + /// 红外指令制导事件 + /// + public class InfraredGuidanceCommandEvent : SimulationEvent + { + /// + /// 目标导弹ID + /// + public string? TargetMissileId { get; set; } + + /// + /// 视线向量 + /// + public Vector3D TrackerToTargetVector { get; set; } = Vector3D.Zero; + + /// + /// 视线向量 + /// + public Vector3D TrackerToMissileVector { get; set; } = Vector3D.Zero; + } + + /// + /// 红外指令制导导弹点亮红外热源事件 + /// + public class InfraredGuidanceMissileLightEvent : SimulationEvent + { + /// + /// 红外热源辐射功率(瓦特) + /// + public double RadiationPower { get; set; } + } } diff --git a/SimulationEnvironment/SimulationManager.cs b/SimulationEnvironment/SimulationManager.cs index df55161..48db31b 100644 --- a/SimulationEnvironment/SimulationManager.cs +++ b/SimulationEnvironment/SimulationManager.cs @@ -147,6 +147,9 @@ namespace ActiveProtect.SimulationEnvironment case MissileType.TerminalSensitiveMissile: missile = new TerminalSensitiveMissile(missileConfig, this); break; + case MissileType.InfraredCommandGuidance: + missile = new InfraredCommandGuidedMissile(missileConfig, this); + break; default: missile = new MissileBase(missileConfig, this); break; @@ -182,16 +185,25 @@ namespace ActiveProtect.SimulationEnvironment this ); Elements.Add(laserBeamRider); - + + // 创建红外测角仪 + var infraredTrackerConfig = config.InfraredTrackerConfig; + var infraredTracker = new InfraredTracker( + "IT_1", + "Tank_1", + infraredTrackerConfig, + this + ); + Elements.Add(infraredTracker); // 激活所有元素 - ActivateAllElements(); + //ActivateAllElements(); // 激活部分元素 - //ActivateSomeElements(); + ActivateSomeElements(); // 激光驾束仪开始照射 - laserBeamRider.StartBeamIllumination(); + //laserBeamRider.StartBeamIllumination(); } @@ -225,8 +237,13 @@ namespace ActiveProtect.SimulationEnvironment // 激活激光驾束仪 //Elements.FindAll(e => e.Id == "LBR_1").ForEach(e => e.Activate()); + // 激活红外指令制导导弹 + Elements.FindAll(e => e.Id == "ICGM_1").ForEach(e => e.Activate()); + // 激活红外测角仪 + Elements.FindAll(e => e.Id == "IT_1").ForEach(e => e.Activate()); + // 激活末敏弹 - Elements.FindAll(e => e.Id == "TSM_1").ForEach(e => e.Activate()); + //Elements.FindAll(e => e.Id == "TSM_1").ForEach(e => e.Activate()); } ///