修改了末敏弹,增加了子弹模型,增加了传感器模型
This commit is contained in:
parent
a292d0e03f
commit
2f692dffbd
347
Docs/TerminalSensitiveMissile.bak
Normal file
347
Docs/TerminalSensitiveMissile.bak
Normal file
@ -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<TerminalSensitiveStage, Action<double>> 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, Action<double>>
|
||||
{
|
||||
{ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Docs/TerminalSensitiveMissileold.bak
Normal file
36
Docs/TerminalSensitiveMissileold.bak
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
public class TerminalSensitiveMissile : SimulationElement
|
||||
{
|
||||
private TerminalSensitiveMotherMissile motherMissile;
|
||||
private List<TerminalSensitiveSubmunition> 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<TerminalSensitiveSubmunition>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算向量的模长
|
||||
/// </summary>
|
||||
@ -166,6 +176,20 @@ namespace ActiveProtect.Models
|
||||
{
|
||||
return new Vector3D(-a.X, -a.Y, -a.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算AB两点之间距离 A 点一定距离的点的坐标
|
||||
/// </summary>
|
||||
/// <param name="a">直线起点</param>
|
||||
/// <param name="b">直线终点</param>
|
||||
/// <param name="distance">距离起点距离</param>
|
||||
/// <returns>直线上的点</returns>
|
||||
public static Vector3D PointOnLine(Vector3D a, Vector3D b, double distance)
|
||||
{
|
||||
Vector3D direction = b - a;
|
||||
Vector3D unitDirection = direction.Normalize();
|
||||
return a + unitDirection * distance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -9,7 +9,7 @@ namespace ActiveProtect.Models
|
||||
public class LaserSemiActiveGuidedMissile : MissileBase
|
||||
{
|
||||
private LaserSemiActiveGuidanceSystem LaserGuidanceSystem;
|
||||
private string LaserDesignatorId;
|
||||
public string LaserDesignatorId { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
@ -18,7 +18,7 @@ namespace ActiveProtect.Models
|
||||
/// <param name="laserDesignatorId">激光指示器ID</param>
|
||||
/// <param name="missileConfig">导弹配置</param>
|
||||
/// <param name="simulationManager">仿真管理器</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
355
Models/Sensors.cs
Normal file
355
Models/Sensors.cs
Normal file
@ -0,0 +1,355 @@
|
||||
using System;
|
||||
using ActiveProtect.SimulationEnvironment;
|
||||
|
||||
namespace ActiveProtect.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义传感器的基本接口
|
||||
/// </summary>
|
||||
public interface ISensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置传感器是否处于激活状态
|
||||
/// </summary>
|
||||
bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 激活传感器
|
||||
/// </summary>
|
||||
void Activate();
|
||||
|
||||
/// <summary>
|
||||
/// 停用传感器
|
||||
/// </summary>
|
||||
void Deactivate();
|
||||
|
||||
/// <summary>
|
||||
/// 更新传感器状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
void Update(double deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// 获取传感器数据
|
||||
/// </summary>
|
||||
/// <returns>传感器采集的数据</returns>
|
||||
SensorData GetSensorData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 传感器的抽象基类,实现了ISensor接口的基本功能
|
||||
/// </summary>
|
||||
public abstract class Sensor : ISensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置传感器是否处于激活状态
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 传感器的位置
|
||||
/// </summary>
|
||||
protected Vector3D Position { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 传感器的朝向
|
||||
/// </summary>
|
||||
protected Orientation Orientation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">传感器的初始位置</param>
|
||||
/// <param name="orientation">传感器的初始朝向</param>
|
||||
protected Sensor(Vector3D position, Orientation orientation)
|
||||
{
|
||||
Position = position;
|
||||
Orientation = orientation;
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活传感器
|
||||
/// </summary>
|
||||
public virtual void Activate()
|
||||
{
|
||||
IsActive = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停用传感器
|
||||
/// </summary>
|
||||
public virtual void Deactivate()
|
||||
{
|
||||
IsActive = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新传感器状态(需要在子类中实现)
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public abstract void Update(double deltaTime);
|
||||
|
||||
/// <summary>
|
||||
/// 获取传感器数据(需要在子类中实现)
|
||||
/// </summary>
|
||||
/// <returns>传感器采集的数据</returns>
|
||||
public abstract SensorData GetSensorData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 红外探测器类
|
||||
/// </summary>
|
||||
public class InfraredDetector : Sensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 探测范围
|
||||
/// </summary>
|
||||
public double DetectionRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 视场角
|
||||
/// </summary>
|
||||
public double FieldOfView { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">探测器的位置</param>
|
||||
/// <param name="orientation">探测器的朝向</param>
|
||||
/// <param name="detectionRange">探测范围</param>
|
||||
/// <param name="fieldOfView">视场角</param>
|
||||
public InfraredDetector(Vector3D position, Orientation orientation, double detectionRange, double fieldOfView)
|
||||
: base(position, orientation)
|
||||
{
|
||||
DetectionRange = detectionRange;
|
||||
FieldOfView = fieldOfView;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新红外探测器的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 实现红外探测器的更新逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取红外探测器的数据
|
||||
/// </summary>
|
||||
/// <returns>红外探测器采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回红外探测器的数据
|
||||
return new InfraredSensorData();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 毫米波辐射计类
|
||||
/// </summary>
|
||||
public class MillimeterWaveRadiometer : Sensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 工作频率
|
||||
/// </summary>
|
||||
public double Frequency { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 灵敏度
|
||||
/// </summary>
|
||||
public double Sensitivity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">辐射计的位置</param>
|
||||
/// <param name="orientation">辐射计的朝向</param>
|
||||
/// <param name="frequency">工作频率</param>
|
||||
/// <param name="sensitivity">灵敏度</param>
|
||||
public MillimeterWaveRadiometer(Vector3D position, Orientation orientation, double frequency, double sensitivity)
|
||||
: base(position, orientation)
|
||||
{
|
||||
Frequency = frequency;
|
||||
Sensitivity = sensitivity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新毫米波辐射计的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 实现毫米波辐射计的更新逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取毫米波辐射计的数据
|
||||
/// </summary>
|
||||
/// <returns>毫米波辐射计采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回毫米波辐射计的数据
|
||||
return new RadiometerSensorData();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 毫米波测高雷达类
|
||||
/// </summary>
|
||||
public class MillimeterWaveAltimeter : Sensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 最大测量高度
|
||||
/// </summary>
|
||||
public double MaxAltitude { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 测量精度
|
||||
/// </summary>
|
||||
public double Accuracy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">测高雷达的位置</param>
|
||||
/// <param name="orientation">测高雷达的朝向</param>
|
||||
/// <param name="maxAltitude">最大测量高度</param>
|
||||
/// <param name="accuracy">测量精度</param>
|
||||
public MillimeterWaveAltimeter(Vector3D position, Orientation orientation, double maxAltitude, double accuracy)
|
||||
: base(position, orientation)
|
||||
{
|
||||
MaxAltitude = maxAltitude;
|
||||
Accuracy = accuracy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新毫米波测高雷达的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 实现毫米波测高雷达的更新逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取毫米波测高雷达的数据
|
||||
/// </summary>
|
||||
/// <returns>毫米波测高雷达采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回毫米波测高雷达的数据
|
||||
return new AltimeterSensorData();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激光测距仪类
|
||||
/// </summary>
|
||||
public class LaserRangefinder : Sensor
|
||||
{
|
||||
/// <summary>
|
||||
/// 最大测量距离
|
||||
/// </summary>
|
||||
public double MaxRange { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 脉冲频率
|
||||
/// </summary>
|
||||
public double PulseRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="position">测距仪的位置</param>
|
||||
/// <param name="orientation">测距仪的朝向</param>
|
||||
/// <param name="maxRange">最大测量距离</param>
|
||||
/// <param name="pulseRate">脉冲频率</param>
|
||||
public LaserRangefinder(Vector3D position, Orientation orientation, double maxRange, double pulseRate)
|
||||
: base(position, orientation)
|
||||
{
|
||||
MaxRange = maxRange;
|
||||
PulseRate = pulseRate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新激光测距仪的状态
|
||||
/// </summary>
|
||||
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
// 实现激光测距仪的更新逻辑
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取激光测距仪的数据
|
||||
/// </summary>
|
||||
/// <returns>激光测距仪采集的数据</returns>
|
||||
public override SensorData GetSensorData()
|
||||
{
|
||||
// 返回激光测距仪的数据
|
||||
return new RangefinderSensorData();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 传感器数据的抽象基类
|
||||
/// </summary>
|
||||
public abstract class SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据采集的时间戳
|
||||
/// </summary>
|
||||
public DateTime Timestamp { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 红外传感器数据类
|
||||
/// </summary>
|
||||
public class InfraredSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 探测到的温度
|
||||
/// </summary>
|
||||
public double Temperature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 目标方向(如果检测到目标)
|
||||
/// </summary>
|
||||
public Vector3D? TargetDirection { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 辐射计传感器数据类
|
||||
/// </summary>
|
||||
public class RadiometerSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 探测到的辐射强度
|
||||
/// </summary>
|
||||
public double RadiationIntensity { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测高仪传感器数据类
|
||||
/// </summary>
|
||||
public class AltimeterSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 测量的高度
|
||||
/// </summary>
|
||||
public double Altitude { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测距仪传感器数据类
|
||||
/// </summary>
|
||||
public class RangefinderSensorData : SensorData
|
||||
{
|
||||
/// <summary>
|
||||
/// 测量的距离
|
||||
/// </summary>
|
||||
public double Distance { get; set; }
|
||||
}
|
||||
}
|
||||
@ -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<TerminalSensitiveStage, Action<double>> 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, Action<double>>
|
||||
{
|
||||
{ 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<LaserBeamStartEvent>(OnLaserBeamStart);
|
||||
// SimulationManager.SubscribeToEvent<LaserBeamStopEvent>(OnLaserBeamStop);
|
||||
// SimulationManager.SubscribeToEvent<LaserBeamUpdateEvent>(OnLaserBeamUpdate);
|
||||
return guidanceCommand;
|
||||
}
|
||||
|
||||
public override void Deactivate()
|
||||
{
|
||||
base.Deactivate();
|
||||
// SimulationManager.UnsubscribeFromEvent<LaserBeamStartEvent>(OnLaserBeamStart);
|
||||
// SimulationManager.UnsubscribeFromEvent<LaserBeamStopEvent>(OnLaserBeamStop);
|
||||
// SimulationManager.UnsubscribeFromEvent<LaserBeamUpdateEvent>(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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
179
Models/TerminalSensitiveSubmunition.cs
Normal file
179
Models/TerminalSensitiveSubmunition.cs
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
Program.cs
14
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
|
||||
}
|
||||
},
|
||||
|
||||
@ -407,6 +407,11 @@ namespace ActiveProtect.SimulationEnvironment
|
||||
/// </summary>
|
||||
public static FlightStageConfig MillimeterWaveTerminalGuidance => new(true, true, true, true, true);
|
||||
|
||||
/// <summary>
|
||||
/// 末敏弹的预设配置
|
||||
/// </summary>
|
||||
public static FlightStageConfig TerminalSensitiveMissile => new(false, false, true, false, false);
|
||||
|
||||
public FlightStageConfig(bool enableLaunch, bool enableAcceleration, bool enableCruise, bool enableTerminalGuidance, bool enableAttack)
|
||||
{
|
||||
EnableLaunch = enableLaunch;
|
||||
|
||||
@ -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($"没<EFBFBD><EFBFBD>找到事件 {eventType.Name} 的处理程序");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user