From 2f692dffbdd0b2ae33df392065af5f28094e2d0e Mon Sep 17 00:00:00 2001 From: Tian jianyong <11429339@qq.com> Date: Mon, 21 Oct 2024 01:24:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E6=9C=AB=E6=95=8F?= =?UTF-8?q?=E5=BC=B9=EF=BC=8C=E5=A2=9E=E5=8A=A0=E4=BA=86=E5=AD=90=E5=BC=B9?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=EF=BC=8C=E5=A2=9E=E5=8A=A0=E4=BA=86=E4=BC=A0?= =?UTF-8?q?=E6=84=9F=E5=99=A8=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Docs/TerminalSensitiveMissile.bak | 347 ++++++++++++++++++++ Docs/TerminalSensitiveMissileold.bak | 36 +++ Models/Common.cs | 24 ++ Models/LaserBeamRiderMissile.cs | 3 +- Models/LaserSemiActiveGuidedMissile.cs | 5 +- Models/Sensors.cs | 355 +++++++++++++++++++++ Models/TerminalSensitiveMissile.cs | 322 +++---------------- Models/TerminalSensitiveSubmunition.cs | 179 +++++++++++ Program.cs | 14 +- SimulationEnvironment/SimulationConfig.cs | 5 + SimulationEnvironment/SimulationManager.cs | 12 +- 11 files changed, 1016 insertions(+), 286 deletions(-) create mode 100644 Docs/TerminalSensitiveMissile.bak create mode 100644 Docs/TerminalSensitiveMissileold.bak create mode 100644 Models/Sensors.cs create mode 100644 Models/TerminalSensitiveSubmunition.cs diff --git a/Docs/TerminalSensitiveMissile.bak b/Docs/TerminalSensitiveMissile.bak new file mode 100644 index 0000000..3cf9aa9 --- /dev/null +++ b/Docs/TerminalSensitiveMissile.bak @@ -0,0 +1,347 @@ +using System; +using System.Collections.Generic; +using ActiveProtect.SimulationEnvironment; + +namespace ActiveProtect.Models +{ + public class TerminalSensitiveMissile : MissileBase + { + // 定义末敏弹工作阶段的枚举 + private enum TerminalSensitiveStage + { + Launch, // 发射阶段 + Separation, // 分离阶段 + Deceleration, // 减速阶段 + SpiralScan, // 螺旋扫描阶段 + Attack, // 攻击阶段 + SelfDestruct // 自毁阶段 + } + + // 当前工作阶段 + private TerminalSensitiveStage currentWorkingStage; + + // 阶段策略字典,用于存储不同阶段的更新策略 + private Dictionary> stageStrategies; + + // 螺旋扫描相关参数 + private double spiralAngle; + private const double SpiralRotationSpeed = 4 * Math.PI; // 2 rotations per second + private const double VerticalDescentSpeed = 10; // 10 m/s + private const double ScanAngle = 30 * Math.PI / 180; // 30 degrees in radians + + // 各阶段的距离和高度参数 + private const double SeparationDistance = 1000; // 分离距离 1000米 + private const double SeparationHeight = 1000; // 分离高度 1000米 + private const double DecelerationHeight = 400; // 减速高度 400米 + private const double ScanningHeight = 200; // 扫描高度 200米 + private const double SelfDestructHeight = 20; // 自毁高度 20米 + + // 扫描和目标检测相关参数 + private Vector3D lastScanDirection; + private bool targetDetected; + private double detectionAngle; + + // 目标位置和分离位置 + private Vector3D TargetPosition; + private Vector3D SeparationPosition; + + // 制导指令 + public Vector3D GuidanceCommand { get; private set; } + + // 传感器 + private InfraredDetector infraredDetector; + private MillimeterWaveRadiometer radiometer; + private MillimeterWaveAltimeter altimeter; + private LaserRangefinder rangefinder; + + // 构造函数 + public TerminalSensitiveMissile(string id, MissileConfig missileConfig, string targetId, ISimulationManager simulationManager) + : base(id, missileConfig, simulationManager) + { + // 初始化参数 + spiralAngle = 0; + lastScanDirection = Vector3D.Zero; + targetDetected = false; + detectionAngle = 0; + GuidanceCommand = Vector3D.Zero; + + // 获取目标位置 + TargetPosition = SimulationManager.GetEntityById(targetId).Position; + + // 计算分离位置 + SeparationPosition = CalculatePointOnTrajectory(Position, TargetPosition, SeparationDistance, SeparationHeight); + + // 初始化阶段策略字典 + stageStrategies = new Dictionary> + { + { TerminalSensitiveStage.Launch, UpdateLaunchStage }, + { TerminalSensitiveStage.Separation, UpdateSeparationStage }, + { TerminalSensitiveStage.Deceleration, UpdateDecelerationStage }, + { TerminalSensitiveStage.SpiralScan, UpdateSpiralScanStage }, + { TerminalSensitiveStage.Attack, UpdateAttackStage }, + { TerminalSensitiveStage.SelfDestruct, UpdateSelfDestructStage } + }; + + // 设置初始阶段 + currentWorkingStage = TerminalSensitiveStage.Launch; + + // 初始化传感器 + infraredDetector = new InfraredDetector(Position, Orientation, 1000, 30); + radiometer = new MillimeterWaveRadiometer(Position, Orientation, 94e9, 1e-6); + altimeter = new MillimeterWaveAltimeter(Position, Orientation, 1000, 0.1); + rangefinder = new LaserRangefinder(Position, Orientation, 5000, 1000); + } + + // 更新方法,每帧调用 + public override void Update(double deltaTime) + { + if (!IsActive) return; + + if (ShouldSelfDestruct()) + { + SelfDestruct(); + return; + } + + Console.WriteLine($"末敏弹 {Id} 当前位置: {Position}"); + Console.WriteLine($"末敏弹 {Id} 分离位置: {SeparationPosition}"); + + // 更新传感器 + infraredDetector.Update(deltaTime); + radiometer.Update(deltaTime); + altimeter.Update(deltaTime); + rangefinder.Update(deltaTime); + + // 使用当前阶段的策略更新导弹状态 + if (stageStrategies.TryGetValue(currentWorkingStage, out var updateStrategy)) + { + updateStrategy(deltaTime); + } + } + + // 发射阶段更新方法 + private void UpdateLaunchStage(double deltaTime) + { + // 无动力抛物线飞行 + ApplyGravity(deltaTime); + + base.UpdateMotionState(deltaTime, GuidanceCommand); + + if (Vector3D.Distance(Position, SeparationPosition) <= 200) + { + currentWorkingStage = TerminalSensitiveStage.Separation; + } + } + + // 分离阶段更新方法 + private void UpdateSeparationStage(double deltaTime) + { + Console.WriteLine($"末敏弹 {Id} 进入分离"); + + // 根据速度大小调整制导指令 + switch(Velocity.Magnitude()) + { + case >= 200: + GuidanceCommand = new Vector3D(400, -400, 0); + break; + case >= 100: + GuidanceCommand = new Vector3D(30, -30, 0); + break; + case >= 50: + GuidanceCommand = new Vector3D(20, -20, 0); + break; + case >= 20: + GuidanceCommand = new Vector3D(5, -10, 0); + break; + default: + GuidanceCommand = new Vector3D(0, -10, 0); + break; + } + base.UpdateMotionState(deltaTime, GuidanceCommand); + + if (Position.Y <= DecelerationHeight) + { + currentWorkingStage = TerminalSensitiveStage.Deceleration; + } + } + + // 减速阶段更新方法 + private void UpdateDecelerationStage(double deltaTime) + { + Console.WriteLine($"末敏弹 {Id} 进入减速"); + // 减速下降 + Velocity = new Vector3D(0, -VerticalDescentSpeed, 0); + Position += Velocity * deltaTime; + + if (Position.Y <= ScanningHeight) + { + currentWorkingStage = TerminalSensitiveStage.SpiralScan; + } + } + + // 螺旋扫描阶段更新方法 + private void UpdateSpiralScanStage(double deltaTime) + { + Console.WriteLine($"末敏弹 {Id} 进入螺旋扫描"); + + spiralAngle += SpiralRotationSpeed * deltaTime; + + // 计算水平速度分量 + double horizontalSpeed = VerticalDescentSpeed * Math.Tan(ScanAngle); + Vector3D horizontalVelocity = new Vector3D( + Math.Cos(spiralAngle) * horizontalSpeed, + 0, + Math.Sin(spiralAngle) * horizontalSpeed + ); + + // 更新速度 + Velocity = new Vector3D(horizontalVelocity.X, -VerticalDescentSpeed, horizontalVelocity.Z); + + // 计算扫描方向 + Vector3D scanDirection = new Vector3D( + Math.Cos(spiralAngle) * Math.Sin(ScanAngle), + -Math.Cos(ScanAngle), + Math.Sin(spiralAngle) * Math.Sin(ScanAngle) + ); + + if (DetectTarget(scanDirection)) + { + if (!targetDetected) + { + targetDetected = true; + detectionAngle = spiralAngle; + } + else if (Math.Abs(spiralAngle - detectionAngle) < 0.1) // 允许一定的误差 + { + currentWorkingStage = TerminalSensitiveStage.Attack; + } + } + + lastScanDirection = scanDirection; + + if (Position.Y <= SelfDestructHeight) + { + currentWorkingStage = TerminalSensitiveStage.SelfDestruct; + } + } + + // 攻击阶段更新方法 + private void UpdateAttackStage(double deltaTime) + { + // 攻击逻辑 + Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position; + Vector3D direction = (targetPosition - Position).Normalize(); + Velocity = direction * MaxSpeed; + + if (Vector3D.Distance(Position, targetPosition) < 1) + { + Explode(); + } + } + + // 自毁阶段更新方法 + private void UpdateSelfDestructStage(double deltaTime) + { + // 实现自毁逻辑 + Explode(); + } + + // 目标检测方法 + 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度的误差 + } + + // 应用重力 + private void ApplyGravity(double deltaTime) + { + GuidanceCommand = new Vector3D(0, -9.81, 0); + } + + // 获取导弹状态 + public override string GetStatus() + { + string baseStatus = base.GetStatus().Replace("导弹", "末敏弹"); + string additionalStatus = $"\n 扫描阶段: {(currentWorkingStage == TerminalSensitiveStage.SpiralScan ? "有效" : "无效")} \n"; + return baseStatus + additionalStatus; + } + + // 激活导弹 + public override void Activate() + { + base.Activate(); + // 可以在这里添加订阅事件的代码 + } + + // 停用导弹 + public override void Deactivate() + { + base.Deactivate(); + // 可以在这里添加取消订阅事件的代码 + } + + // 静态方法:计算发射参数 + public static (double angle, double distance) CalculateLaunchParameters(double initialVelocity, double targetHeight, double targetDistance) + { + double g = 9.8; // 重力加速度 + double v = initialVelocity; + double y = targetHeight; + double x = targetDistance; + + // 计算发射角度(弧度) + double angle = Math.Atan((v * v + Math.Sqrt(Math.Pow(v, 4) - g * (g * x * x + 2 * y * v * v))) / (g * x)); + + // 计算水平飞行距离 + double t = x / (v * Math.Cos(angle)); + double totalDistance = v * Math.Cos(angle) * t; + + return (angle, totalDistance); + } + + // 静态方法:计算发射位置 + public static Vector3D CalculateLaunchPosition(Vector3D knownPoint, Vector3D velocity) + { + double g = 9.8; // 重力加速度 + double x = knownPoint.X; + double y = knownPoint.Y; + double vx = velocity.X; + double vy = velocity.Y; + + // 计算时间 t + double t = (-vy - Math.Sqrt(vy * vy + 2 * g * y)) / -g; + + // 计算发射点的 x 坐标 + double launchX = x - vx * t; + + // 发射点的 y 和 z 坐标为 0 + return new Vector3D(launchX, 0, 0); + } + + // 静态方法:计算轨迹上的点 + public static Vector3D CalculatePointOnTrajectory(Vector3D launchPosition, Vector3D targetPosition, double distanceFromTarget, double height) + { + // 确保发射位置和目标位置的y坐标为0 + launchPosition = new Vector3D(launchPosition.X, 0, launchPosition.Z); + targetPosition = new Vector3D(targetPosition.X, 0, targetPosition.Z); + + // 计算发射方向向量 + Vector3D direction = targetPosition - launchPosition; + + // 计算总距离 + double totalDistance = direction.Magnitude(); + + // 归一化方向向量 + direction = direction.Normalize(); + + // 计算所需点的位置 + Vector3D pointOnTrajectory = targetPosition - direction * distanceFromTarget; + + // 返回结果,y坐标设置为指定的高度 + return new Vector3D(pointOnTrajectory.X, height, pointOnTrajectory.Z); + } + } +} diff --git a/Docs/TerminalSensitiveMissileold.bak b/Docs/TerminalSensitiveMissileold.bak new file mode 100644 index 0000000..8c67302 --- /dev/null +++ b/Docs/TerminalSensitiveMissileold.bak @@ -0,0 +1,36 @@ +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/Common.cs b/Models/Common.cs index 01b946a..8476bac 100644 --- a/Models/Common.cs +++ b/Models/Common.cs @@ -99,6 +99,16 @@ namespace ActiveProtect.Models return new Vector3D(-a.X, -a.Y, -a.Z); } + public static bool operator ==(Vector3D left, Vector3D right) + { + return left.X == right.X && left.Y == right.Y && left.Z == right.Z; + } + + public static bool operator !=(Vector3D left, Vector3D right) + { + return !(left == right); + } + /// /// 计算向量的模长 /// @@ -166,6 +176,20 @@ namespace ActiveProtect.Models { return new Vector3D(-a.X, -a.Y, -a.Z); } + + /// + /// 计算AB两点之间距离 A 点一定距离的点的坐标 + /// + /// 直线起点 + /// 直线终点 + /// 距离起点距离 + /// 直线上的点 + public static Vector3D PointOnLine(Vector3D a, Vector3D b, double distance) + { + Vector3D direction = b - a; + Vector3D unitDirection = direction.Normalize(); + return a + unitDirection * distance; + } } /// diff --git a/Models/LaserBeamRiderMissile.cs b/Models/LaserBeamRiderMissile.cs index f2b4027..3ef431c 100644 --- a/Models/LaserBeamRiderMissile.cs +++ b/Models/LaserBeamRiderMissile.cs @@ -7,11 +7,10 @@ namespace ActiveProtect.Models private LaserBeamRiderGuidanceSystem LaserBeamRiderGuidanceSystem; - public LaserBeamRiderMissile(string id, string targetId, MissileConfig missileConfig, ISimulationManager simulationManager) + public LaserBeamRiderMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager) : base(id, missileConfig, simulationManager) { LaserBeamRiderGuidanceSystem = new LaserBeamRiderGuidanceSystem(missileConfig.ProportionalNavigationCoefficient); - TargetId = targetId; } protected override Vector3D GetGuidanceCommand() diff --git a/Models/LaserSemiActiveGuidedMissile.cs b/Models/LaserSemiActiveGuidedMissile.cs index 50036e2..8a0a53a 100644 --- a/Models/LaserSemiActiveGuidedMissile.cs +++ b/Models/LaserSemiActiveGuidedMissile.cs @@ -9,7 +9,7 @@ namespace ActiveProtect.Models public class LaserSemiActiveGuidedMissile : MissileBase { private LaserSemiActiveGuidanceSystem LaserGuidanceSystem; - private string LaserDesignatorId; + public string LaserDesignatorId { get; set; } = ""; /// /// 构造函数 @@ -18,7 +18,7 @@ namespace ActiveProtect.Models /// 激光指示器ID /// 导弹配置 /// 仿真管理器 - public LaserSemiActiveGuidedMissile(string id, MissileConfig missileConfig, string laserDesignatorId, ISimulationManager simulationManager) + public LaserSemiActiveGuidedMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager) : base(id, missileConfig, simulationManager) { Vector3D initialTargetPosition = simulationManager.GetEntityById($"Tank_{missileConfig.TargetIndex + 1}").Position; @@ -29,7 +29,6 @@ namespace ActiveProtect.Models initialTargetPosition, initialTargetVelocity ); - LaserDesignatorId = laserDesignatorId; } /// diff --git a/Models/Sensors.cs b/Models/Sensors.cs new file mode 100644 index 0000000..efc2b4b --- /dev/null +++ b/Models/Sensors.cs @@ -0,0 +1,355 @@ +using System; +using ActiveProtect.SimulationEnvironment; + +namespace ActiveProtect.Models +{ + /// + /// 定义传感器的基本接口 + /// + public interface ISensor + { + /// + /// 获取或设置传感器是否处于激活状态 + /// + bool IsActive { get; set; } + + /// + /// 激活传感器 + /// + void Activate(); + + /// + /// 停用传感器 + /// + void Deactivate(); + + /// + /// 更新传感器状态 + /// + /// 自上次更新以来的时间间隔 + void Update(double deltaTime); + + /// + /// 获取传感器数据 + /// + /// 传感器采集的数据 + SensorData GetSensorData(); + } + + /// + /// 传感器的抽象基类,实现了ISensor接口的基本功能 + /// + public abstract class Sensor : ISensor + { + /// + /// 获取或设置传感器是否处于激活状态 + /// + public bool IsActive { get; set; } + + /// + /// 传感器的位置 + /// + protected Vector3D Position { get; set; } + + /// + /// 传感器的朝向 + /// + protected Orientation Orientation { get; set; } + + /// + /// 构造函数 + /// + /// 传感器的初始位置 + /// 传感器的初始朝向 + protected Sensor(Vector3D position, Orientation orientation) + { + Position = position; + Orientation = orientation; + IsActive = false; + } + + /// + /// 激活传感器 + /// + public virtual void Activate() + { + IsActive = true; + } + + /// + /// 停用传感器 + /// + public virtual void Deactivate() + { + IsActive = false; + } + + /// + /// 更新传感器状态(需要在子类中实现) + /// + /// 自上次更新以来的时间间隔 + public abstract void Update(double deltaTime); + + /// + /// 获取传感器数据(需要在子类中实现) + /// + /// 传感器采集的数据 + public abstract SensorData GetSensorData(); + } + + /// + /// 红外探测器类 + /// + public class InfraredDetector : Sensor + { + /// + /// 探测范围 + /// + public double DetectionRange { get; set; } + + /// + /// 视场角 + /// + public double FieldOfView { get; set; } + + /// + /// 构造函数 + /// + /// 探测器的位置 + /// 探测器的朝向 + /// 探测范围 + /// 视场角 + public InfraredDetector(Vector3D position, Orientation orientation, double detectionRange, double fieldOfView) + : base(position, orientation) + { + DetectionRange = detectionRange; + FieldOfView = fieldOfView; + } + + /// + /// 更新红外探测器的状态 + /// + /// 自上次更新以来的时间间隔 + public override void Update(double deltaTime) + { + // 实现红外探测器的更新逻辑 + } + + /// + /// 获取红外探测器的数据 + /// + /// 红外探测器采集的数据 + public override SensorData GetSensorData() + { + // 返回红外探测器的数据 + return new InfraredSensorData(); + } + } + + /// + /// 毫米波辐射计类 + /// + public class MillimeterWaveRadiometer : Sensor + { + /// + /// 工作频率 + /// + public double Frequency { get; set; } + + /// + /// 灵敏度 + /// + public double Sensitivity { get; set; } + + /// + /// 构造函数 + /// + /// 辐射计的位置 + /// 辐射计的朝向 + /// 工作频率 + /// 灵敏度 + public MillimeterWaveRadiometer(Vector3D position, Orientation orientation, double frequency, double sensitivity) + : base(position, orientation) + { + Frequency = frequency; + Sensitivity = sensitivity; + } + + /// + /// 更新毫米波辐射计的状态 + /// + /// 自上次更新以来的时间间隔 + public override void Update(double deltaTime) + { + // 实现毫米波辐射计的更新逻辑 + } + + /// + /// 获取毫米波辐射计的数据 + /// + /// 毫米波辐射计采集的数据 + public override SensorData GetSensorData() + { + // 返回毫米波辐射计的数据 + return new RadiometerSensorData(); + } + } + + /// + /// 毫米波测高雷达类 + /// + public class MillimeterWaveAltimeter : Sensor + { + /// + /// 最大测量高度 + /// + public double MaxAltitude { get; set; } + + /// + /// 测量精度 + /// + public double Accuracy { get; set; } + + /// + /// 构造函数 + /// + /// 测高雷达的位置 + /// 测高雷达的朝向 + /// 最大测量高度 + /// 测量精度 + public MillimeterWaveAltimeter(Vector3D position, Orientation orientation, double maxAltitude, double accuracy) + : base(position, orientation) + { + MaxAltitude = maxAltitude; + Accuracy = accuracy; + } + + /// + /// 更新毫米波测高雷达的状态 + /// + /// 自上次更新以来的时间间隔 + public override void Update(double deltaTime) + { + // 实现毫米波测高雷达的更新逻辑 + } + + /// + /// 获取毫米波测高雷达的数据 + /// + /// 毫米波测高雷达采集的数据 + public override SensorData GetSensorData() + { + // 返回毫米波测高雷达的数据 + return new AltimeterSensorData(); + } + } + + /// + /// 激光测距仪类 + /// + public class LaserRangefinder : Sensor + { + /// + /// 最大测量距离 + /// + public double MaxRange { get; set; } + + /// + /// 脉冲频率 + /// + public double PulseRate { get; set; } + + /// + /// 构造函数 + /// + /// 测距仪的位置 + /// 测距仪的朝向 + /// 最大测量距离 + /// 脉冲频率 + public LaserRangefinder(Vector3D position, Orientation orientation, double maxRange, double pulseRate) + : base(position, orientation) + { + MaxRange = maxRange; + PulseRate = pulseRate; + } + + /// + /// 更新激光测距仪的状态 + /// + /// 自上次更新以来的时间间隔 + public override void Update(double deltaTime) + { + // 实现激光测距仪的更新逻辑 + } + + /// + /// 获取激光测距仪的数据 + /// + /// 激光测距仪采集的数据 + public override SensorData GetSensorData() + { + // 返回激光测距仪的数据 + return new RangefinderSensorData(); + } + } + + /// + /// 传感器数据的抽象基类 + /// + public abstract class SensorData + { + /// + /// 数据采集的时间戳 + /// + public DateTime Timestamp { get; set; } + } + + /// + /// 红外传感器数据类 + /// + public class InfraredSensorData : SensorData + { + /// + /// 探测到的温度 + /// + public double Temperature { get; set; } + + /// + /// 目标方向(如果检测到目标) + /// + public Vector3D? TargetDirection { get; set; } + } + + /// + /// 辐射计传感器数据类 + /// + public class RadiometerSensorData : SensorData + { + /// + /// 探测到的辐射强度 + /// + public double RadiationIntensity { get; set; } + } + + /// + /// 测高仪传感器数据类 + /// + public class AltimeterSensorData : SensorData + { + /// + /// 测量的高度 + /// + public double Altitude { get; set; } + } + + /// + /// 测距仪传感器数据类 + /// + public class RangefinderSensorData : SensorData + { + /// + /// 测量的距离 + /// + public double Distance { get; set; } + } +} diff --git a/Models/TerminalSensitiveMissile.cs b/Models/TerminalSensitiveMissile.cs index f52fc21..6b6bd74 100644 --- a/Models/TerminalSensitiveMissile.cs +++ b/Models/TerminalSensitiveMissile.cs @@ -6,316 +6,98 @@ namespace ActiveProtect.Models { public class TerminalSensitiveMissile : MissileBase { - private enum TerminalSensitiveStage - { - Launch, // 发射阶段 - Separation, // 分离阶段 - Deceleration, // 减速阶段 - SpiralScan, // 螺旋扫描阶段 - Attack, // 攻击阶段 - SelfDestruct // 自毁阶段 - } + private TerminalSensitiveSubmunition[] submunitions; - private TerminalSensitiveStage currentWorkingStage; - private Dictionary> stageStrategies; - - private double spiralAngle; - private const double SpiralRotationSpeed = 4 * Math.PI; // 2 rotations per second - private const double VerticalDescentSpeed = 10; // 10 m/s - private const double ScanAngle = 30 * Math.PI / 180; // 30 degrees in radians - - // 分离距离 1000米 - private const double SeparationDistance = 1000; + private Vector3D guidanceCommand; // 分离高度 1000米 private const double SeparationHeight = 1000; - // 减速高度 400米 - private const double DecelerationHeight = 400; + // 分离点距离目标水平距离 + private const double SeparationDistance = 1000; - // 扫描高度 200米 - private const double ScanningHeight = 200; + private Vector3D separationPoint; + // 子弹数量 + private const int SubmunitionCount = 2; - // 自毁高度 20米 - private const double SelfDestructHeight = 20; - - private Vector3D lastScanDirection; - private bool targetDetected; - private double detectionAngle; - - //目标位置 - private Vector3D TargetPosition; - - //末敏弹子母弹分离位置 - private Vector3D SeparationPosition; - - public Vector3D GuidanceCommand { get; private set; } - - public TerminalSensitiveMissile(string id, MissileConfig missileConfig, string targetId, ISimulationManager simulationManager) + public TerminalSensitiveMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager) : base(id, missileConfig, simulationManager) { - spiralAngle = 0; - lastScanDirection = Vector3D.Zero; - targetDetected = false; - detectionAngle = 0; - GuidanceCommand = Vector3D.Zero; + submunitions = new TerminalSensitiveSubmunition[SubmunitionCount]; + guidanceCommand = Vector3D.Zero; - TargetPosition = SimulationManager.GetEntityById(targetId).Position; - - SeparationPosition = CalculatePointOnTrajectory(Position, TargetPosition, SeparationDistance, SeparationHeight); - - // 初始化策略字典 - stageStrategies = new Dictionary> - { - { TerminalSensitiveStage.Launch, UpdateLaunchStage }, - { TerminalSensitiveStage.Separation, UpdateSeparationStage }, - { TerminalSensitiveStage.Deceleration, UpdateDecelerationStage }, - { TerminalSensitiveStage.SpiralScan, UpdateSpiralScanStage }, - { TerminalSensitiveStage.Attack, UpdateAttackStage }, - { TerminalSensitiveStage.SelfDestruct, UpdateSelfDestructStage } - }; - - currentWorkingStage = TerminalSensitiveStage.Launch; + //计算分离点坐标,高度为SeparationHeight,距离目标的距离为SeparationDistance + separationPoint = Vector3D.PointOnLine(SimulationManager.GetEntityById(TargetId).Position, Position, SeparationDistance) + new Vector3D(0, SeparationHeight, 0); } public override void Update(double deltaTime) { - //base.Update(deltaTime); - if (!IsActive) return; - - if (ShouldSelfDestruct()) - { - SelfDestruct(); - return; - } - - Console.WriteLine($"末敏弹 {Id} 当前位置: {Position}"); - Console.WriteLine($"末敏弹 {Id} 分离位置: {SeparationPosition}"); - - // 使用当前阶段的策略更新导弹状态 - if (stageStrategies.TryGetValue(currentWorkingStage, out var updateStrategy)) - { - updateStrategy(deltaTime); - } - - } - - private void UpdateLaunchStage(double deltaTime) - { + base.Update(deltaTime); // 无动力抛物线飞行 ApplyGravity(deltaTime); - base.UpdateMotionState(deltaTime, GuidanceCommand); + Console.WriteLine($"分离点距离: {(separationPoint - Position).Magnitude()}"); - if (Vector3D.Distance(Position, SeparationPosition) <= 200) + //计算到目标的距离 + double distanceToTarget = (SimulationManager.GetEntityById(TargetId).Position - Position).Magnitude(); + + //距离分离点距离小于50米,或者距离目标小于1400米,则分离 + if ((separationPoint - Position).Magnitude() <= 50 || distanceToTarget <= 1400) { - currentWorkingStage = TerminalSensitiveStage.Separation; + Console.WriteLine("分离"); + PerformSeparation(); } } - private void UpdateSeparationStage(double deltaTime) + private void PerformSeparation() { - // 子母弹分离逻辑 - // 这里可以添加分离的具体实现,比如创建子弹等 - Console.WriteLine($"末敏弹 {Id} 进入分离"); - - switch(Velocity.Magnitude()) - { - case >= 200: - GuidanceCommand = new Vector3D(400, -400, 0); - break; - case >= 100: - GuidanceCommand = new Vector3D(30, -30, 0); - break; - case >= 50: - GuidanceCommand = new Vector3D(20, -20, 0); - break; - case >= 20: - GuidanceCommand = new Vector3D(5, -10, 0); - break; - default: - GuidanceCommand = new Vector3D(0, -10, 0); - break; - } - base.UpdateMotionState(deltaTime, GuidanceCommand); - - if (Position.Y <= DecelerationHeight) - { - currentWorkingStage = TerminalSensitiveStage.Deceleration; - } - } - - private void UpdateDecelerationStage(double deltaTime) - { - Console.WriteLine($"末敏弹 {Id} 进入减速"); - // 减速下降 - Velocity = new Vector3D(0, -VerticalDescentSpeed, 0); - Position += Velocity * deltaTime; - - if (Position.Y <= ScanningHeight) - { - currentWorkingStage = TerminalSensitiveStage.SpiralScan; - } - } - - private void UpdateSpiralScanStage(double deltaTime) - { - Console.WriteLine($"末敏弹 {Id} 进入螺旋扫描"); - - spiralAngle += SpiralRotationSpeed * deltaTime; - - // 计算水平速度分量 - double horizontalSpeed = VerticalDescentSpeed * Math.Tan(ScanAngle); - Vector3D horizontalVelocity = new Vector3D( - Math.Cos(spiralAngle) * horizontalSpeed, - 0, - Math.Sin(spiralAngle) * horizontalSpeed - ); - - // 更新速度 - Velocity = new Vector3D(horizontalVelocity.X, -VerticalDescentSpeed, horizontalVelocity.Z); - - // 计算扫描方向 - Vector3D scanDirection = new Vector3D( - Math.Cos(spiralAngle) * Math.Sin(ScanAngle), - -Math.Cos(ScanAngle), - Math.Sin(spiralAngle) * Math.Sin(ScanAngle) - ); - - if (DetectTarget(scanDirection)) - { - if (!targetDetected) - { - targetDetected = true; - detectionAngle = spiralAngle; - } - else if (Math.Abs(spiralAngle - detectionAngle) < 0.1) // 允许一定的误差 - { - currentWorkingStage = TerminalSensitiveStage.Attack; - } - } - - lastScanDirection = scanDirection; - - if (Position.Y <= SelfDestructHeight) - { - currentWorkingStage = TerminalSensitiveStage.SelfDestruct; - } - } - - private void UpdateAttackStage(double deltaTime) - { - // 攻击逻辑 + // 获取目标位置 Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position; - Vector3D direction = (targetPosition - Position).Normalize(); - Velocity = direction * MaxSpeed; - if (Vector3D.Distance(Position, targetPosition) < 1) + // 创建并释放子弹 + for (int i = 0; i < SubmunitionCount; i++) { - Explode(); + // 计算子弹朝向目标的方向 + Vector3D directionToTarget = (targetPosition - this.Position).Normalize(); + Orientation orientationToTarget = Orientation.FromVector(directionToTarget); + + submunitions[i] = new TerminalSensitiveSubmunition($"{Id}_Sub_{i}", + new MissileConfig + { + InitialPosition = this.Position, + InitialOrientation = orientationToTarget, // 设置为朝向目标的方向 + InitialSpeed = 200, // 子弹初始速度 + MaxSpeed = 300, + TargetIndex = 0, + MaxFlightTime = 10, + MaxFlightDistance = 1000, + MaxAcceleration = 50, + ProportionalNavigationCoefficient = 0.1, + Mass = 10 + }, + SimulationManager); + + SimulationManager.AddElement(submunitions[i]); } - } - private void UpdateSelfDestructStage(double deltaTime) - { - // 实现自毁逻辑 - Explode(); - } - - 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度的误差 + // 母弹完成任务,可以被移除 + IsActive = false; } private void ApplyGravity(double deltaTime) { - GuidanceCommand = new Vector3D(0, -9.81, 0); + Velocity += new Vector3D(0, -9.8, 0) * deltaTime; } public override string GetStatus() { - string baseStatus = base.GetStatus().Replace("导弹", "末敏弹"); - string additionalStatus = $"\n 扫描阶段: {(currentWorkingStage == TerminalSensitiveStage.SpiralScan ? "有效" : "无效")} \n"; - return baseStatus + additionalStatus; + return $"{base.GetStatus()}\nMother Missile Stage: {currentStage}, Separation Point: {separationPoint}"; } - public override void Activate() + protected override Vector3D GetGuidanceCommand() { - base.Activate(); - // SimulationManager.SubscribeToEvent(OnLaserBeamStart); - // SimulationManager.SubscribeToEvent(OnLaserBeamStop); - // SimulationManager.SubscribeToEvent(OnLaserBeamUpdate); + return guidanceCommand; } - public override void Deactivate() - { - base.Deactivate(); - // SimulationManager.UnsubscribeFromEvent(OnLaserBeamStart); - // SimulationManager.UnsubscribeFromEvent(OnLaserBeamStop); - // SimulationManager.UnsubscribeFromEvent(OnLaserBeamUpdate); - } - - public static (double angle, double distance) CalculateLaunchParameters(double initialVelocity, double targetHeight, double targetDistance) - { - double g = 9.8; // 重力加速度 - double v = initialVelocity; - double y = targetHeight; - double x = targetDistance; - - // 计算发射角度(弧度) - double angle = Math.Atan((v * v + Math.Sqrt(Math.Pow(v, 4) - g * (g * x * x + 2 * y * v * v))) / (g * x)); - - // 计算水平飞行距离 - double t = x / (v * Math.Cos(angle)); - double totalDistance = v * Math.Cos(angle) * t; - - return (angle, totalDistance); - } - - public static Vector3D CalculateLaunchPosition(Vector3D knownPoint, Vector3D velocity) - { - double g = 9.8; // 重力加速度 - double x = knownPoint.X; - double y = knownPoint.Y; - double vx = velocity.X; - double vy = velocity.Y; - - // 计算时间 t - double t = (-vy - Math.Sqrt(vy * vy + 2 * g * y)) / -g; - - // 计算发射点的 x 坐标 - double launchX = x - vx * t; - - // 发射点的 y 和 z 坐标为 0 - return new Vector3D(launchX, 0, 0); - } - - public static Vector3D CalculatePointOnTrajectory(Vector3D launchPosition, Vector3D targetPosition, double distanceFromTarget, double height) - { - // 确保发射位置和目标位置的y坐标为0 - launchPosition = new Vector3D(launchPosition.X, 0, launchPosition.Z); - targetPosition = new Vector3D(targetPosition.X, 0, targetPosition.Z); - - // 计算发射方向向量 - Vector3D direction = targetPosition - launchPosition; - - // 计算总距离 - double totalDistance = direction.Magnitude(); - - // 归一化方向向量 - direction = direction.Normalize(); - - // 计算所需点的位置 - Vector3D pointOnTrajectory = targetPosition - direction * distanceFromTarget; - - // 返回结果,y坐标设置为指定的高度 - return new Vector3D(pointOnTrajectory.X, height, pointOnTrajectory.Z); - } - - } } diff --git a/Models/TerminalSensitiveSubmunition.cs b/Models/TerminalSensitiveSubmunition.cs new file mode 100644 index 0000000..91e4c0e --- /dev/null +++ b/Models/TerminalSensitiveSubmunition.cs @@ -0,0 +1,179 @@ +using System; +using ActiveProtect.SimulationEnvironment; + +namespace ActiveProtect.Models +{ + public class TerminalSensitiveSubmunition : MissileBase + { + private enum SubmunitionStage + { + Deceleration, + SpiralScan, + Attack, + SelfDestruct + } + + private SubmunitionStage runningStage; + private Vector3D guidanceCommand; + private double spiralAngle; + private const double SpiralRotationSpeed = 4 * Math.PI; // 2 rotations per second + private const double VerticalDescentSpeed = 10; // 10 m/s + private const double ScanAngle = 20 * Math.PI / 180; // 20 degrees in radians + + // 减速高度 400米 + private const double DecelerationHeight = 400; + + // 扫描高度 200米 + private const double ScanningHeight = 200; + + // 自毁高度 20米 + private const double SelfDestructHeight = 20; + + private Vector3D lastScanDirection; + private bool targetDetected; + private double detectionAngle; + + // 添加传感器 + private InfraredDetector infraredDetector; + private MillimeterWaveRadiometer radiometer; + private MillimeterWaveAltimeter altimeter; + private LaserRangefinder rangefinder; + + public TerminalSensitiveSubmunition(string id, MissileConfig missileConfig, ISimulationManager simulationManager) + : base(id, missileConfig, simulationManager) + { + runningStage = SubmunitionStage.Deceleration; + spiralAngle = 0; + lastScanDirection = Vector3D.Zero; + targetDetected = false; + detectionAngle = 0; + guidanceCommand = Vector3D.Zero; + + // 初始化传感器 + infraredDetector = new InfraredDetector(Position, Orientation, 1000, 30); + radiometer = new MillimeterWaveRadiometer(Position, Orientation, 94e9, 1e-6); + altimeter = new MillimeterWaveAltimeter(Position, Orientation, 1000, 0.1); + rangefinder = new LaserRangefinder(Position, Orientation, 5000, 1000); + } + + public override void Update(double deltaTime) + { + base.Update(deltaTime); + + // 更新传感器 + infraredDetector.Update(deltaTime); + radiometer.Update(deltaTime); + altimeter.Update(deltaTime); + rangefinder.Update(deltaTime); + + switch (runningStage) + { + case SubmunitionStage.Deceleration: + UpdateDecelerationStage(deltaTime); + break; + case SubmunitionStage.SpiralScan: + UpdateSpiralScanStage(deltaTime); + break; + case SubmunitionStage.Attack: + UpdateAttackStage(deltaTime); + break; + case SubmunitionStage.SelfDestruct: + SelfDestruct(); + break; + } + } + + private void UpdateDecelerationStage(double deltaTime) + { + // 减速下降 + Vector3D deceleration = new Vector3D(0, 9.8, 0) - Velocity.Normalize() * 5; // 假设减速度为5m/s^2 + Velocity += deceleration * deltaTime; + + if (Velocity.Y >= -VerticalDescentSpeed) + { + Velocity = new Vector3D(0, -VerticalDescentSpeed, 0); + } + + if (Position.Y <= ScanningHeight) + { + runningStage = SubmunitionStage.SpiralScan; + Velocity = new Vector3D(0, -VerticalDescentSpeed, 0); + } + } + + private void UpdateSpiralScanStage(double deltaTime) + { + spiralAngle += SpiralRotationSpeed * deltaTime; + + // 计算水平速度分量 + double horizontalSpeed = VerticalDescentSpeed * Math.Tan(ScanAngle); + Vector3D horizontalVelocity = new Vector3D( + Math.Cos(spiralAngle) * horizontalSpeed, + 0, + Math.Sin(spiralAngle) * horizontalSpeed + ); + + // 更新速度 + Velocity = new Vector3D(horizontalVelocity.X, -VerticalDescentSpeed, horizontalVelocity.Z); + + // 计算扫描方向 + Vector3D scanDirection = new Vector3D( + Math.Cos(spiralAngle) * Math.Sin(ScanAngle), + -Math.Cos(ScanAngle), + Math.Sin(spiralAngle) * Math.Sin(ScanAngle) + ); + + if (DetectTarget(scanDirection)) + { + if (!targetDetected) + { + targetDetected = true; + detectionAngle = spiralAngle; + } + else if (Math.Abs(spiralAngle - detectionAngle) < 0.1) // 允许一定的误差 + { + runningStage = SubmunitionStage.Attack; + } + } + + lastScanDirection = scanDirection; + + if (Position.Y <= SelfDestructHeight) + { + runningStage = SubmunitionStage.SelfDestruct; + } + } + + private void UpdateAttackStage(double deltaTime) + { + // 攻击逻辑 + Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position; + Vector3D direction = (targetPosition - Position).Normalize(); + Velocity = direction * MaxSpeed; + + if (Vector3D.Distance(Position, targetPosition) < 1) + { + Explode(); + } + } + + 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度的误差 + } + + public override string GetStatus() + { + return $"{base.GetStatus()}\nSubmunition Stage: {runningStage}\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 346b215..bf859d2 100644 --- a/Program.cs +++ b/Program.cs @@ -116,20 +116,20 @@ namespace ActiveProtect // 末敏弹配置 new MissileConfig { - InitialPosition = new Vector3D(3500, 0, 100), // 发射位置 + InitialPosition = new Vector3D(4000, 0, 100), // 发射位置 InitialOrientation = new Orientation(Math.PI, Math.PI/8, 0), // 使用计算得到的发射角度 InitialSpeed = 800, MaxSpeed = 1000, TargetIndex = 0, - MaxFlightTime = 10, // 增加最大飞行时间 - MaxFlightDistance = 5000, // 增加最大飞行距离 - ThrustAcceleration = 0, // 无推力加速度 - MaxEngineBurnTime = 0, // 无发动机燃烧时间 + MaxFlightTime = 30, // 增加最大飞行时间 + MaxFlightDistance = 5000, // 增加最大飞行距离 + ThrustAcceleration = 0, // 母弹的推力加速度 + MaxEngineBurnTime = 0, // 母弹的发动机燃烧时间 MaxAcceleration = 1000, ProportionalNavigationCoefficient = 3, - StageConfig = FlightStageConfig.StandardMissile, + StageConfig = FlightStageConfig.TerminalSensitiveMissile, // 使用新的枚举值 DistanceParams = new MissileDistanceParams(1000, 400, 20), - Mass = 100, + Mass = 50, // 增加质量以反映母弹的重量 Type = MissileType.TerminalSensitiveMissile } }, diff --git a/SimulationEnvironment/SimulationConfig.cs b/SimulationEnvironment/SimulationConfig.cs index cf44f70..51c8c0c 100644 --- a/SimulationEnvironment/SimulationConfig.cs +++ b/SimulationEnvironment/SimulationConfig.cs @@ -407,6 +407,11 @@ namespace ActiveProtect.SimulationEnvironment /// public static FlightStageConfig MillimeterWaveTerminalGuidance => new(true, true, true, true, true); + /// + /// 末敏弹的预设配置 + /// + public static FlightStageConfig TerminalSensitiveMissile => new(false, false, true, false, false); + public FlightStageConfig(bool enableLaunch, bool enableAcceleration, bool enableCruise, bool enableTerminalGuidance, bool enableAttack) { EnableLaunch = enableLaunch; diff --git a/SimulationEnvironment/SimulationManager.cs b/SimulationEnvironment/SimulationManager.cs index ca0ae94..7136700 100644 --- a/SimulationEnvironment/SimulationManager.cs +++ b/SimulationEnvironment/SimulationManager.cs @@ -139,13 +139,13 @@ namespace ActiveProtect.SimulationEnvironment switch (missileConfig.Type) { case MissileType.LaserSemiActiveGuidance: - missile = new LaserSemiActiveGuidedMissile($"LSGM_{i + 1}", missileConfig, "Tank_1", this); + missile = new LaserSemiActiveGuidedMissile($"LSGM_{i + 1}", missileConfig, this); break; case MissileType.LaserBeamRiderGuidance: - missile = new LaserBeamRiderMissile($"LBRM_{i + 1}", "LBR_1", missileConfig, this); + missile = new LaserBeamRiderMissile($"LBRM_{i + 1}", missileConfig, this); break; case MissileType.TerminalSensitiveMissile: - missile = new TerminalSensitiveMissile($"TSM_{i + 1}", missileConfig, "Tank_1", this); + missile = new TerminalSensitiveMissile($"TSM_{i + 1}", missileConfig, this); break; default: missile = new MissileBase($"M_{i + 1}", missileConfig, this); @@ -166,6 +166,10 @@ namespace ActiveProtect.SimulationEnvironment this ); Elements.Add(laserDesignator); + if (Elements.FirstOrDefault(e => e.Id == "LSGM_1") is LaserSemiActiveGuidedMissile lsGM) + { + lsGM.LaserDesignatorId = "LD_1"; + } // 创建激光驾束仪 var laserBeamRiderConfig = config.LaserBeamRiderConfig; @@ -212,7 +216,7 @@ namespace ActiveProtect.SimulationEnvironment } else { - Console.WriteLine($"没有找到事件 {eventType.Name} 的处理程序"); + Console.WriteLine($"没��找到事件 {eventType.Name} 的处理程序"); } }