简化了导弹基类设计,将自毁和爆炸的状态判断,放到子类中处理。给所有文档加上注释

This commit is contained in:
Tian jianyong 2024-10-24 11:56:37 +08:00
parent 6e960f59b3
commit 6fca00b28c
27 changed files with 615 additions and 1698 deletions

4
.cursorignore Normal file
View File

@ -0,0 +1,4 @@
# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)
bin/
obj/
.DS_Store

View File

@ -148,3 +148,14 @@ public class FireMissileCommand : ICommand
#### 1.3 导弹行为
导弹行为包括导弹的飞行行为、攻击行为、躲避行为、跟踪行为、锁定行为、发射行为、爆炸行为等。
## 在激光驾束制导中, 为了实现更平滑的控制同时将加速度控制在25 m/s²以下并保持偏移在1.5米以内,我们可以采用以下几种方法
1. 使用PID控制器
PID比例-积分-微分)控制器可以提供更平滑和精确的控制。它考虑了误差的历史、当前值和变化率。
2. 非线性增益:
使用非线性函数来计算增益,使得在接近目标时增益减小,远离目标时增益增大。
3. 低通滤波:
对计算出的加速度进行低通滤波,以减少高频振荡。
4. 预测控制:
基于当前状态预测未来的位置,提前做出调整。

View File

@ -92,14 +92,3 @@ public class Missile : IProperties, IState
4. 符合单一职责原则:每个类都只负责一种类型的参数。
5. 便于测试:可以轻松地为每种参数类型创建模拟对象,便于单元测试。
6. 灵活性:可以为不同类型的导弹创建不同的参数实现,而保持相同的接口。
## 在激光驾束制导中, 为了实现更平滑的控制同时将加速度控制在25 m/s²以下并保持偏移在1.5米以内,我们可以采用以下几种方法
1. 使用PID控制器
PID比例-积分-微分)控制器可以提供更平滑和精确的控制。它考虑了误差的历史、当前值和变化率。
2. 非线性增益:
使用非线性函数来计算增益,使得在接近目标时增益减小,远离目标时增益增大。
3. 低通滤波:
对计算出的加速度进行低通滤波,以减少高频振荡。
4. 预测控制:
基于当前状态预测未来的位置,提前做出调整。

View File

@ -1,620 +0,0 @@
using System;
using System.Collections.Generic;
using ActiveProtect.SimulationEnvironment;
using Model;
namespace ActiveProtect.Models
{
/// <summary>
/// 表示仿真中的导弹
/// </summary>
public class MissileBase : SimulationElement
{
/// <summary>
/// 导弹类型
/// </summary>
public MissileType Type { get; protected set; }
/// <summary>
/// 当前速度(米/秒)
/// </summary>
public double Speed { get; protected set; }
/// <summary>
/// 最大速度(米/秒)
/// </summary>
public double MaxSpeed { get; protected set; }
/// <summary>
/// 目标ID
/// </summary>
public string TargetId { get; protected set; }
/// <summary>
/// 最大飞行时间(秒)
/// </summary>
public double MaxFlightTime { get; protected set; }
/// <summary>
/// 最大飞行距离(米)
/// </summary>
public double MaxFlightDistance { get; protected set; }
/// <summary>
/// 当前飞行时间(秒)
/// </summary>
public double FlightTime { get; protected set; }
/// <summary>
/// 当前飞行距离(米)
/// </summary>
public double FlightDistance { get; protected set; }
/// <summary>
/// 与目标的距离(米)
/// </summary>
public double DistanceToTarget { get; protected set; }
/// <summary>
/// 导弹距离参数
/// </summary>
public MissileDistanceParams DistanceParams { get; protected set; }
/// <summary>
/// 飞行阶段配置
/// </summary>
public FlightStageConfig StageConfig { get; protected set; }
/// <summary>
/// 当前飞行阶段
/// </summary>
public FlightStage InitialStage { get; protected set; }
/// <summary>
/// 上一帧目标位置
/// </summary>
private Vector3D LastTargetPosition;
/// <summary>
/// 比例导引系数
/// </summary>
private const double N = 3;
/// <summary>
/// 推力加速度(米/秒²)
/// </summary>
public double ThrustAcceleration { get; protected set; }
/// <summary>
/// 当前发动机燃烧时间(秒)
/// </summary>
public double EngineBurnTime { get; protected set; }
/// <summary>
/// 最大发动机燃烧时间(秒)
/// </summary>
public double MaxEngineBurnTime { get; protected set; }
/// <summary>
/// 最大加速度(米/秒²)
/// </summary>
public double MaxAcceleration { get; protected set; } = 10000;
/// <summary>
/// 比例导引系数
/// </summary>
public double ProportionalNavigationCoefficient { get; set; }
/// <summary>
/// 是否有制导
/// </summary>
public bool HasGuidance { get; protected set; } = false;
/// <summary>
/// 失去制导的时间(秒)
/// </summary>
protected double LostGuidanceTime { get; set; } = 0;
/// <summary>
/// 最后已知的速度向量
/// </summary>
protected Vector3D LastKnownVelocity = Vector3D.Zero;
/// <summary>
/// 发射速度(米/秒)
/// </summary>
public const double LAUNCH_SPEED = 10;
/// <summary>
/// 发射阶段持续时间(秒)
/// </summary>
public const double LAUNCH_DURATION = 0.5;
/// <summary>
/// 当前飞行阶段策略
/// </summary>
protected IMissileStageStrategy currentStageStrategy;
/// <summary>
/// 飞行阶段策略字典
/// </summary>
private Dictionary<FlightStage, IMissileStageStrategy> stageStrategies;
/// <summary>
/// 导弹质量(千克)
/// </summary>
public double Mass { get; protected set; } = 100;
/// <summary>
/// 构造函数
/// </summary>
public MissileBase(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
: base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, missileConfig.InitialSpeed, simulationManager)
{
// 初始化导弹属性
Speed = missileConfig.InitialSpeed;
MaxSpeed = missileConfig.MaxSpeed;
MaxFlightTime = missileConfig.MaxFlightTime;
MaxFlightDistance = missileConfig.MaxFlightDistance;
DistanceParams = missileConfig.DistanceParams;
StageConfig = missileConfig.StageConfig;
IsActive = false;
FlightTime = 0;
FlightDistance = 0;
SimulationManager = simulationManager;
ThrustAcceleration = missileConfig.ThrustAcceleration;
EngineBurnTime = 0;
MaxEngineBurnTime = missileConfig.MaxEngineBurnTime;
MaxAcceleration = missileConfig.MaxAcceleration;
ProportionalNavigationCoefficient = missileConfig.ProportionalNavigationCoefficient;
TargetId = $"Tank_{missileConfig.TargetIndex + 1}";
// 初始化策略字典
stageStrategies = new Dictionary<FlightStage, IMissileStageStrategy>
{
{ FlightStage.Launch, new LaunchStageStrategy(this) },
{ FlightStage.Acceleration, new AccelerationStageStrategy(this) },
{ FlightStage.Cruise, new CruiseStageStrategy(this) },
{ FlightStage.TerminalGuidance, new TerminalGuidanceStageStrategy(this) },
{ FlightStage.Attack, new AttackStageStrategy(this) }
};
// 设置初始阶段
SetInitialStage();
currentStageStrategy = stageStrategies[InitialStage];
LastTargetPosition = Vector3D.Zero;
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
}
/// <summary>
/// 设置导弹的初始飞行阶段
/// </summary>
private void SetInitialStage()
{
if (StageConfig.EnableLaunch) InitialStage = FlightStage.Launch;
else if (StageConfig.EnableAcceleration) InitialStage = FlightStage.Acceleration;
else if (StageConfig.EnableCruise) InitialStage = FlightStage.Cruise;
else if (StageConfig.EnableTerminalGuidance) InitialStage = FlightStage.TerminalGuidance;
else if (StageConfig.EnableAttack) InitialStage = FlightStage.Attack;
Console.WriteLine($"导弹 {Id} 的初始阶段: {InitialStage}");
}
/// <summary>
/// 更新导弹状态
/// </summary>
public override void Update(double deltaTime)
{
if (!IsActive) return;
if (ShouldSelfDestruct())
{
SelfDestruct();
return;
}
UpdateEngineBurnTime(deltaTime);
Vector3D guidanceCommand = GetGuidanceCommand();
UpdateMotionState(deltaTime, guidanceCommand);
if (CheckHit())
{
Explode();
return;
}
currentStageStrategy.Update(deltaTime);
}
protected virtual Vector3D GetGuidanceCommand()
{
throw new NotImplementedException();
}
protected virtual void UpdateMotionState(double deltaTime, Vector3D guidanceCommand)
{
Vector3D acceleration = CalculateAcceleration(Velocity, guidanceCommand);
// 使用四阶龙格-库塔方法更新导弹的位置和速度
(Position, Velocity) = BasicGuidanceSystem.RungeKutta4(deltaTime, Position, Velocity, acceleration);
// 限制速度不超过最大速度
if (Velocity.Magnitude() > MaxSpeed)
{
Velocity = Velocity.Normalize() * MaxSpeed;
}
UpdateMotionStatus(deltaTime);
}
protected virtual void UpdateMotionStatus(double deltaTime)
{
Speed = Velocity.Magnitude();
Orientation = Orientation.FromVector(Velocity);
FlightTime += deltaTime;
FlightDistance += Speed * deltaTime;
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
}
/// <summary>
/// 计算导弹的加速度
/// </summary>
private Vector3D CalculateAcceleration(Vector3D velocity, Vector3D guidanceCommand)
{
Vector3D thrustAcceleration = Vector3D.Zero;
Vector3D guidanceAcceleration = Vector3D.Zero;
switch (InitialStage)
{
case FlightStage.Launch:
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
break;
case FlightStage.Acceleration:
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
guidanceAcceleration = guidanceCommand;
break;
case FlightStage.Cruise:
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.05);
guidanceAcceleration = guidanceCommand * 1;
break;
case FlightStage.TerminalGuidance:
thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.05);
guidanceAcceleration = guidanceCommand * 1;
break;
case FlightStage.Attack:
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration*0.05;
guidanceAcceleration = guidanceCommand * 1;
break;
}
if (!HasGuidance)
{
if (velocity.Magnitude() > 0)
{
thrustAcceleration = velocity.Normalize() * ThrustAcceleration;
}
else
{
thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
}
}
//计算重力加速度(反坦克导弹一般升力很小, 主要依靠初始发射动能和持续的推力来维持飞行)
//Vector3D gravityCompensation = new(0, 9.81, 0);
Vector3D gravityAcceleration = new(0, -9.81, 0);
// 计算空气阻力的影响
Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / Mass;
Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration + gravityAcceleration +dragAcceleration;
//Vector3D totalAcceleration = guidanceAcceleration + thrustAcceleration +dragAcceleration;
Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {guidanceAcceleration}, 推力加速度: {thrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
if (totalAcceleration.Magnitude() > MaxAcceleration)
{
totalAcceleration = totalAcceleration.Normalize() * MaxAcceleration;
}
return totalAcceleration;
}
/// <summary>
/// 切换导弹飞行阶段
/// </summary>
public void ChangeStage(FlightStage newStage)
{
if (stageStrategies.TryGetValue(newStage, out var strategy))
{
if (IsStageEnabled(newStage))
{
InitialStage = newStage;
currentStageStrategy = strategy;
Console.WriteLine($"导弹 {Id} 切换到 {newStage} 阶段");
}
else
{
// 如果目标阶段不可用,尝试切换到下一个可用阶段
TryChangeToNextAvailableStage(newStage);
}
}
else
{
Console.WriteLine($"导弹 {Id} 无法切换到未知阶段 {newStage}");
}
}
/// <summary>
/// 检查指定飞行阶段是否启用
/// </summary>
private bool IsStageEnabled(FlightStage stage)
{
return stage switch
{
FlightStage.Launch => StageConfig.EnableLaunch,
FlightStage.Acceleration => StageConfig.EnableAcceleration,
FlightStage.Cruise => StageConfig.EnableCruise,
FlightStage.TerminalGuidance => StageConfig.EnableTerminalGuidance,
FlightStage.Attack => StageConfig.EnableAttack,
_ => false
};
}
/// <summary>
/// 尝试切换到下一个可用的飞行阶段
/// </summary>
private void TryChangeToNextAvailableStage(FlightStage startStage)
{
FlightStage[] stageOrder = new FlightStage[] {FlightStage.Launch, FlightStage.Acceleration, FlightStage.Cruise, FlightStage.TerminalGuidance, FlightStage.Attack};
int startIndex = Array.IndexOf(stageOrder, startStage);
for (int i = startIndex + 1; i < stageOrder.Length; i++)
{
if (IsStageEnabled(stageOrder[i]))
{
ChangeStage(stageOrder[i]);
return;
}
}
// 如果没有可用的下一个阶段,导弹自毁
Console.WriteLine($"导弹 {Id} 没有可用的下一个阶段,准备自毁");
SelfDestruct();
}
/// <summary>
/// 计算空气阻力
/// </summary>
private static double CalculateDrag(double speed)
{
const double dragCoefficient = 0.1; // 减小阻力系数
const double airDensity = 1.225; // 海平面空气密度kg/m^3
const double referenceArea = 0.01; // 减小导弹的参考面积m^2
return 0.5 * dragCoefficient * airDensity * referenceArea * speed * speed;
}
/// <summary>
/// 检查是否命中目标
/// </summary>
protected bool CheckHit()
{
return DistanceToTarget <= DistanceParams.ExplosionDistance;
}
/// <summary>
/// 检查是否应该自毁
/// </summary>
protected bool ShouldSelfDestruct()
{
if (FlightTime >= MaxFlightTime)
{
Console.WriteLine($"导弹 {Id} 超出最大飞行时间 ({FlightTime:F2}/{MaxFlightTime:F2}),准备自毁");
return true;
}
if (FlightDistance >= MaxFlightDistance)
{
Console.WriteLine($"导弹 {Id} 超出最大飞行距离 ({FlightDistance:F2}/{MaxFlightDistance:F2}),准备自毁");
return true;
}
if (Position.Y <= -1.0) // 数字略小于0
{
Console.WriteLine($"导弹 {Id} 高度小于等于0 ({Position.Y:F2}),准备自毁");
return true;
}
return false;
}
/// <summary>
/// 更新发动机燃烧时间
/// </summary>
private void UpdateEngineBurnTime(double deltaTime)
{
if (InitialStage == FlightStage.Acceleration && EngineBurnTime < MaxEngineBurnTime)
{
EngineBurnTime += deltaTime;
}
}
/// <summary>
/// 计算比例导引加速度
/// </summary>
private Vector3D CalculateProportionalNavigation(Vector3D position)
{
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
Vector3D LOS = targetPosition - position;
Vector3D LOSRate = (targetPosition - LastTargetPosition) / FlightTime - Velocity;
LastTargetPosition = targetPosition;
return Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), LOS).Normalize()
* ProportionalNavigationCoefficient * Velocity.Magnitude();
}
/// <summary>
/// 导弹爆炸
/// </summary>
public void Explode()
{
Deactivate();
SimulationManager.HandleTargetHit(TargetId, Id);
Console.WriteLine($"导弹 {Id} 在 {Position} 爆炸,命中目标!");
}
/// <summary>
/// 导弹自毁
/// </summary>
public void SelfDestruct()
{
if (IsActive)
{
string reason = FlightTime >= MaxFlightTime ? "超出最大飞行时间" :
FlightDistance >= MaxFlightDistance ? "超出最大飞行距离" :
Position.Y <= 0 ? "高度小于等于0" :
!HasGuidance ? "失去引导" : "未知原因";
Console.WriteLine($"导弹 {Id} 自毁。原因: {reason}");
Deactivate();
}
}
/// <summary>
/// 设置比例导引系数
/// </summary>
public void SetProportionalNavigationCoefficient(double newCoefficient)
{
ProportionalNavigationCoefficient = newCoefficient;
Console.WriteLine($"导弹 {Id} 的比例导引系数已更新为 {newCoefficient}");
}
/// <summary>
/// 获取导弹状态
/// </summary>
public override string GetStatus()
{
MissileRunningState missileRunningState = GetState();
return $"导弹 {missileRunningState.Id}:\n" +
$" 位置: {missileRunningState.Position}\n" +
$" 速度: {missileRunningState.Speed:F2} m/s\n" +
$" 速度分量: {missileRunningState.Velocity}\n" +
$" 朝向: {missileRunningState.Orientation}\n" +
$" 当前状态: {missileRunningState.CurrentStage}\n" +
$" 飞行时间: {missileRunningState.FlightTime:F2}/{MaxFlightTime:F2}\n" +
$" 飞行距离: {missileRunningState.FlightDistance:F2}/{MaxFlightDistance:F2}\n" +
$" 距离目标: {missileRunningState.DistanceToTarget:F2}\n" +
$" 发动机工作时间: {missileRunningState.EngineBurnTime:F2}/{MaxEngineBurnTime:F2}\n" +
$" 有引导: {(missileRunningState.HasGuidance ? "是" : "否")}\n" +
$" 失去引导时间: {missileRunningState.LostGuidanceTime:F2}";
}
/// <summary>
/// 更新导弹的制导状态
/// </summary>
protected virtual void UpdateGuidanceStatus()
{
// 基类中的默认实现
}
public MissileRunningState GetState()
{
return new MissileRunningState
{
Id = Id,
Type = Type,
Position = Position,
Velocity = Velocity,
Orientation = Orientation,
Speed = Speed,
TargetId = TargetId,
FlightTime = FlightTime,
FlightDistance = FlightDistance,
DistanceToTarget = DistanceToTarget,
CurrentStage = InitialStage,
HasGuidance = HasGuidance,
LostGuidanceTime = LostGuidanceTime,
EngineBurnTime = EngineBurnTime,
IsActive = IsActive
};
}
}
/// <summary>
/// 表示导弹的运行状态信息
/// </summary>
public struct MissileRunningState
{
/// <summary>
/// 导弹ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 导弹类型
/// </summary>
public MissileType Type { get; set; }
/// <summary>
/// 当前位置
/// </summary>
public Vector3D Position { get; set; }
/// <summary>
/// 当前速度向量
/// </summary>
public Vector3D Velocity { get; set; }
/// <summary>
/// 当前朝向
/// </summary>
public Orientation Orientation { get; set; }
/// <summary>
/// 当前速度(米/秒)
/// </summary>
public double Speed { get; set; }
/// <summary>
/// 目标ID
/// </summary>
public string TargetId { get; set; }
/// <summary>
/// 当前飞行时间(秒)
/// </summary>
public double FlightTime { get; set; }
/// <summary>
/// 当前飞行距离(米)
/// </summary>
public double FlightDistance { get; set; }
/// <summary>
/// 与目标的距离(米)
/// </summary>
public double DistanceToTarget { get; set; }
/// <summary>
/// 当前飞行阶段
/// </summary>
public FlightStage CurrentStage { get; set; }
/// <summary>
/// 是否有制导
/// </summary>
public bool HasGuidance { get; set; }
/// <summary>
/// 失去制导时间(秒)
/// </summary>
public double LostGuidanceTime { get; set; }
/// <summary>
/// 当前发动机燃烧时间(秒)
/// </summary>
public double EngineBurnTime { get; set; }
/// <summary>
/// 是否处于活动状态
/// </summary>
public bool IsActive { get; set; }
}
}

View File

@ -1,168 +0,0 @@
using System;
namespace ActiveProtect.Models
{
/// <summary>
/// 导弹飞行阶段枚举
/// </summary>
public enum FlightStage
{
Launch, // 发射阶段
Acceleration, // 加速阶段
Cruise, // 巡航阶段
TerminalGuidance, // 终端制导阶段
Attack, // 攻击阶段
Explosion, // 爆炸阶段
}
/// <summary>
/// 导弹飞行阶段策略接口
/// </summary>
public interface IMissileStageStrategy
{
void Update(double deltaTime);
}
/// <summary>
/// 发射阶段策略
/// </summary>
public class LaunchStageStrategy : IMissileStageStrategy
{
private readonly MissileBase missile;
private double launchTime = 0;
public LaunchStageStrategy(MissileBase missile)
{
this.missile = missile;
}
public void Update(double deltaTime)
{
launchTime += deltaTime;
if (launchTime >= MissileBase.LAUNCH_DURATION || missile.Speed >= missile.MaxSpeed * 0.1)
{
missile.ChangeStage(FlightStage.Acceleration);
}
}
}
/// <summary>
/// <summary>
/// 加速阶段策略
/// </summary>
public class AccelerationStageStrategy : IMissileStageStrategy
{
private readonly MissileBase missile;
public AccelerationStageStrategy(MissileBase missile)
{
this.missile = missile;
}
public void Update(double deltaTime)
{
if (missile.EngineBurnTime >= missile.MaxEngineBurnTime || missile.Speed >= missile.MaxSpeed)
{
missile.ChangeStage(FlightStage.Cruise);
}
}
}
/// <summary>
/// 巡航阶段策略
/// </summary>
public class CruiseStageStrategy : IMissileStageStrategy
{
private readonly MissileBase missile;
public CruiseStageStrategy(MissileBase missile)
{
this.missile = missile;
}
public void Update(double deltaTime)
{
if (missile.DistanceToTarget <= missile.DistanceParams.TerminalGuidanceDistance)
{
missile.ChangeStage(FlightStage.TerminalGuidance);
}
}
}
/// <summary>
/// 终端制导阶段策略
/// </summary>
public class TerminalGuidanceStageStrategy : IMissileStageStrategy
{
private readonly MissileBase missile;
public TerminalGuidanceStageStrategy(MissileBase missile)
{
this.missile = missile;
}
public void Update(double deltaTime)
{
if (missile.DistanceToTarget <= missile.DistanceParams.AttackDistance)
{
missile.ChangeStage(FlightStage.Attack);
}
}
}
/// <summary>
/// 攻击阶段策略
/// </summary>
public class AttackStageStrategy : IMissileStageStrategy
{
private readonly MissileBase missile;
public AttackStageStrategy(MissileBase missile)
{
this.missile = missile;
}
public void Update(double deltaTime)
{
if (missile.DistanceToTarget <= missile.DistanceParams.ExplosionDistance)
{
missile.Explode();
}
}
}
/// <summary>
/// 无制导阶段策略
/// </summary>
public class UnguidedStageStrategy : IMissileStageStrategy
{
private readonly MissileBase missile;
public UnguidedStageStrategy(MissileBase missile)
{
this.missile = missile;
}
public void Update(double deltaTime)
{
// 检查是否重新获得引导
if (missile.HasGuidance)
{
Console.WriteLine($"导弹 {missile.Id} 重新获得引导,退出无制导阶段");
if (missile.DistanceToTarget <= missile.DistanceParams.AttackDistance)
{
missile.ChangeStage(FlightStage.Attack);
}
else if (missile.DistanceToTarget <= missile.DistanceParams.TerminalGuidanceDistance)
{
missile.ChangeStage(FlightStage.TerminalGuidance);
}
else
{
missile.ChangeStage(FlightStage.Cruise);
}
}
}
}
}

View File

@ -1,162 +0,0 @@
# 末敏弹仿真设计
## 1. 末敏弹的结构和原理
### 1.1 末敏弹的结构
末敏弹是一种远程投放,顶部攻击目标的弹药,其结构包括母弹、子弹、战斗部、导引头。
### 1.2 末敏弹的制导系统
末敏弹的制导系统包括毫米波雷达和红外两部分。
### 1.3 末敏弹的运行阶段
末敏弹的运行阶段包括发射阶段、分离阶段、减速阶段、螺旋扫描阶段、攻击阶段、自毁阶段等。
## 2. 末敏弹的仿真
### 2.1 运动仿真
运动仿真包括母弹和子弹的运行过程和运动规律,按运行阶段进行仿真。
### 2.2 导引头仿真
导引头仿真包括导引头的工作原理、搜索、锁定、攻击过程。
## 3. 运动仿真
### 3.1 发射阶段
行为:母弹发射
参数:
发射位置:距离目标 20 公里
发射角度:俯仰角和方位角,需要根据目标的坐标计算,暂定 45 度
发射速度1000 米/秒
### 3.2 分离阶段
动作:子母弹分离
参数:
分离高度1000 米
分离距离:与目标水平距离 1000 米
### 3.3 减速阶段
动作:开伞、减速减旋、稳态扫描
参数:
减速高度400 米
减速距离:与目标水平距离 300 米
### 3.4 螺旋扫描阶段
动作:螺旋扫描
参数:
扫描高度200 米
扫描距离:与目标水平距离小于 100 米
扫描角度30 度
扫描线视场角15 度
扫描速度2 圈/秒
下降速度10 米/秒
### 3.5 攻击阶段
动作:攻击目标
参数:
攻击高度:小于 200 米,扫描发现目标之后的 0.5 秒
攻击距离:与目标水平距离小于 100 米
攻击速度2000 米/秒
### 3.6 自毁阶段
动作:自毁
参数:
自毁高度20 米
自毁条件:扫描未发现目标
## 4. 导引头仿真
### 4.1 毫米波雷达
毫米波雷达的仿真包括雷达的参数模型和行为模型。
#### 4.1.1 参数模型
波长3毫米
频率94GHz
脉冲宽度100ns
脉冲重复频率10kHz
天线增益30dB
噪声系数5dB
信噪比阈值100dB
#### 4.1.2 行为模型
测高:到达 20 米,发出自毁信号
### 4.2 红外导引头
红外导引头的仿真包括红外导引头的参数模型和行为模型。
#### 4.2.1 参数模型
波长3-5 微米
模数:单模、多模
信噪比阈值100dB
#### 4.2.2 行为模型
探测目标:探测到目标,发出攻击信号
## 5. 干扰方式
干扰方式包括烟幕干扰、毫米波补偿
### 5.1 烟幕干扰
坦克顶部烟幕弹装置,发射烟幕弹,形成烟幕,干扰毫米波雷达和红外导引头。
### 5.2 毫米波补偿
坦克顶部毫米波干扰机,发射毫米波补偿信号,干扰末敏弹毫米波雷达。
## 6. 仿真模型设计思路
基于上述末敏弹的仿真设计,我们可以设计一个末敏弹仿真模型,主要思路如下:
1. 类结构设计:
- 创建一个 `TerminalSensitiveMissile` 类,继承自 `MissileBase`
- 创建 `MillimeterWaveRadar``InfraredSeeker` 类来模拟导引头。
2. 飞行阶段管理:
- 定义一个枚举 `TerminalSensitiveStage` 来表示末敏弹的不同飞行阶段。
- 实现一个状态机来管理这些阶段的转换。
3. 运动模型:
- 为每个飞行阶段实现特定的运动模型。
- 使用物理公式计算弹道,考虑重力、空气阻力等因素。
4. 导引头模拟:
- 实现毫米波雷达和红外导引头的探测逻辑。
- 模拟信号处理、目标识别和跟踪。
5. 目标交互:
- 实现与目标(如坦克)的交互逻辑。
- 模拟目标探测、锁定和攻击过程。
6. 环境交互:
- 考虑环境因素对末敏弹性能的影响,如天气条件。
7. 干扰模拟:
- 实现烟幕干扰和毫米波补偿等干扰方式的影响。
8. 参数配置:
- 设计一个灵活的参数配置系统,允许调整各种性能参数。
9. 数据记录和分析:
- 实现数据记录功能,用于后续分析和可视化。
10. 集成到仿真系统:
- 确保末敏弹模型能够与整个仿真系统无缝集成。
这个设计应该能够全面模拟末敏弹的行为,包括其复杂的飞行阶段和导引系统。实现时,我们需要逐步完善每个组件,并进行充分的测试和调整。

View File

@ -1,347 +0,0 @@
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);
}
}
}

View File

@ -2,12 +2,19 @@ using System;
namespace ActiveProtect.Models
{
public interface IGuidanceSystem
/// <summary>
/// 制导系统接口
/// </summary>
public interface IGuidanceSystem
{
bool HasGuidance { get; }
void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity);
Vector3D GetGuidanceAcceleration();
}
/// <summary>
/// 基础制导系统
/// </summary>
public class BasicGuidanceSystem : IGuidanceSystem
{
public bool HasGuidance { get; protected set; }
@ -23,17 +30,31 @@ namespace ActiveProtect.Models
Velocity = Vector3D.Zero;
}
/// <summary>
/// 更新制导系统
/// </summary>
/// <param name="deltaTime">时间步长</param>
/// <param name="missilePosition">导弹位置</param>
/// <param name="missileVelocity">导弹速度</param>
public virtual void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
{
Position = missilePosition;
Velocity = missileVelocity;
}
/// <summary>
/// 获取制导加速度
/// </summary>
/// <returns>制导加速度</returns>
public Vector3D GetGuidanceAcceleration()
{
return GuidanceAcceleration;
}
/// <summary>
/// 计算制导加速度
/// </summary>
/// <param name="deltaTime">时间步长</param>
protected virtual void CalculateGuidanceAcceleration(double deltaTime)
{
// 基础制导系统不计算制导指令
@ -43,12 +64,13 @@ namespace ActiveProtect.Models
/// <summary>
/// 计算比例导引加速度
/// </summary>
/// <param name="proportionalNavigationCoefficient">比例导引系数</param>
/// <param name="missilePosition">导弹位置</param>
/// <param name="missileVelocity">导弹速度</param>
/// <param name="targetPosition">目标位置</param>
/// <param name="targetVelocity">目标速度</param>
/// <returns>比例导引加速度</returns>
protected Vector3D CalculateProportionalNavigation(double proportionalNavigationCoefficient, Vector3D missilePosition, Vector3D missileVelocity, Vector3D targetPosition, Vector3D targetVelocity)
protected static Vector3D CalculateProportionalNavigation(double proportionalNavigationCoefficient, Vector3D missilePosition, Vector3D missileVelocity, Vector3D targetPosition, Vector3D targetVelocity)
{
// 预测时间(预测目标前进方向该时间后到达的位置,可以调整)
double predictionTime = 0.01;
@ -67,6 +89,14 @@ namespace ActiveProtect.Models
return acceleration;
}
/// <summary>
/// 四阶龙格库塔法计算导弹运动状态
/// </summary>
/// <param name="deltaTime">时间步长</param>
/// <param name="position">导弹位置</param>
/// <param name="velocity">导弹速度</param>
/// <param name="acceleration">导弹加速度</param>
/// <returns>新的位置和速度</returns>
public static (Vector3D newPosition, Vector3D newVelocity) RungeKutta4(double deltaTime, Vector3D position, Vector3D velocity, Vector3D acceleration)
{
// 定义一个局部函数来计算加速度
@ -98,5 +128,14 @@ namespace ActiveProtect.Models
return (newPosition, newVelocity);
}
/// <summary>
/// 获取制导系统状态
/// </summary>
/// <returns>制导系统状态</returns>
public virtual string GetStatus()
{
return $"BasicGuidanceSystem: HasGuidance={HasGuidance}, Position={Position}, Velocity={Velocity}, GuidanceAcceleration={GuidanceAcceleration}";
}
}
}

View File

@ -99,16 +99,25 @@ namespace ActiveProtect.Models
return new Vector3D(-a.X, -a.Y, -a.Z);
}
/// <summary>
/// 向量相等运算符重载
/// </summary>
public static bool operator ==(Vector3D left, Vector3D right)
{
return left.X == right.X && left.Y == right.Y && left.Z == right.Z;
}
/// <summary>
/// 向量不相等运算符重载
/// </summary>
public static bool operator !=(Vector3D left, Vector3D right)
{
return !(left == right);
}
/// <summary>
/// 判断两个向量是否相等
/// </summary>
public override bool Equals(object? obj)
{
if (obj is Vector3D other)
@ -118,6 +127,10 @@ namespace ActiveProtect.Models
return false;
}
/// <summary>
/// 获取向量的哈希码
/// </summary>
/// <returns>向量的哈希码</returns>
public override int GetHashCode()
{
return HashCode.Combine(X, Y, Z);
@ -320,17 +333,28 @@ namespace ActiveProtect.Models
}
}
/// <summary>
/// 表示二维空间中的向量
/// </summary>
public struct Vector2D
{
public double X { get; set; }
public double Y { get; set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="x">X坐标</param>
/// <param name="y">Y坐标</param>
public Vector2D(double x, double y)
{
X = x;
Y = y;
}
/// <summary>
/// 零向量
/// </summary>
public static Vector2D Zero => new Vector2D(0, 0);
}
}

View File

@ -40,9 +40,13 @@ namespace ActiveProtect.Models
IsBeamOn = false;
MissileId = missileId;
TargetId = targetId;
SimulationManager = simulationManager;
base.SimulationManager = simulationManager;
}
/// <summary>
/// 更新激光驾束仪
/// </summary>
/// <param name="deltaTime">时间步长</param>
public override void Update(double deltaTime)
{
if (IsActive && IsBeamOn)
@ -88,6 +92,9 @@ namespace ActiveProtect.Models
base.Deactivate();
}
/// <summary>
/// 开启激光束照射
/// </summary>
public void StartBeamIllumination()
{
if (!IsBeamOn)
@ -98,6 +105,9 @@ namespace ActiveProtect.Models
}
}
/// <summary>
/// 停止激光束照射
/// </summary>
public void StopBeamIllumination()
{
if (IsBeamOn)
@ -141,6 +151,10 @@ namespace ActiveProtect.Models
});
}
/// <summary>
/// 获取激光驾束仪状态
/// </summary>
/// <returns>激光驾束仪状态</returns>
public override string GetStatus()
{
return $"激光驾束仪 {Id}:\n" +

View File

@ -2,26 +2,59 @@ using System;
namespace ActiveProtect.Models
{
/// <summary>
/// 激光驾束制导系统
/// </summary>
public class LaserBeamRiderGuidanceSystem : BasicGuidanceSystem
{
/// <summary>
/// 激光源位置
/// </summary>
private Vector3D LaserSourcePosition { get; set; }
/// <summary>
/// 激光方向
/// </summary>
private Vector3D LaserDirection { get; set; }
/// <summary>
/// 激光功率
/// </summary>
public double LaserPower { get; set; }
private const double MinDetectablePower = 1e-3; // 假设最小可探测功率为1毫瓦
private const double DetectorDiameter = 0.1; // 假设探测器直径为10厘米
private const double ControlFieldDiameter = 20.0; // 控制场直径(米)
/// <summary>
/// 上一次的误差
/// </summary>
private Vector3D LastError = Vector3D.Zero;
/// <summary>
/// 上一次的制导加速度
/// </summary>
public Vector3D LastGuidanceAcceleration { get; private set; }
/// <summary>
/// 积分误差
/// </summary>
private Vector3D IntegralError = Vector3D.Zero;
/// <summary>
/// 比例导引系数
/// </summary>
private double ProportionalNavigationCoefficient { get; set; }
/// <summary>
/// 激光照射是否开启
/// </summary>
private bool LaserIlluminationOn { get; set; }
/// <summary>
/// 构造函数
/// </summary>
public LaserBeamRiderGuidanceSystem()
{
LaserSourcePosition = Vector3D.Zero;
@ -32,6 +65,12 @@ namespace ActiveProtect.Models
ProportionalNavigationCoefficient = 3;
}
/// <summary>
/// 更新激光驾束仪
/// </summary>
/// <param name="sourcePosition">激光源位置</param>
/// <param name="direction">激光方向</param>
/// <param name="laserPower">激光功率</param>
public void UpdateLaserBeamRider(Vector3D sourcePosition, Vector3D direction, double laserPower)
{
LaserIlluminationOn = true;
@ -40,7 +79,10 @@ namespace ActiveProtect.Models
LaserPower = laserPower;
}
public void DeactivateLaserBeam(Vector3D sourcePosition, Vector3D direction)
/// <summary>
/// 关闭激光照射
/// </summary>
public void DeactivateLaserBeam()
{
LaserSourcePosition = Vector3D.Zero;
LaserDirection = Vector3D.Zero;
@ -48,6 +90,12 @@ namespace ActiveProtect.Models
HasGuidance = false;
}
/// <summary>
/// 更新制导系统
/// </summary>
/// <param name="deltaTime">时间步长</param>
/// <param name="missilePosition">导弹位置</param>
/// <param name="missileVelocity">导弹速度</param>
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
{
base.Update(deltaTime, missilePosition, missileVelocity);
@ -70,6 +118,9 @@ namespace ActiveProtect.Models
}
}
/// <summary>
/// 更新制导状态
/// </summary>
private void UpdateGuidanceStatus()
{
// 计算导弹到激光束的最短距离
@ -102,6 +153,10 @@ namespace ActiveProtect.Models
}
}
/// <summary>
/// 计算制导加速度
/// </summary>
/// <param name="deltaTime">时间步长</param>
protected override void CalculateGuidanceAcceleration(double deltaTime)
{
if (!HasGuidance)
@ -171,11 +226,19 @@ namespace ActiveProtect.Models
//Console.WriteLine($"Guidance Command: {GuidanceCommand.Magnitude()}, Lateral Error: {shortestDistanceVector.Magnitude()}, Lateral Acceleration: {lateralAcceleration.Magnitude()}, Forward Acceleration: {forwardAcceleration.Magnitude()}");
}
public override string ToString()
/// <summary>
/// 获取制导系统状态
/// </summary>
/// <returns>制导系统状态</returns>
public override string GetStatus()
{
return $"LaserBeamRiderGuidanceSystem: HasGuidance={HasGuidance}, LaserSourcePosition={LaserSourcePosition}, LaserDirection={LaserDirection}, GuidanceAcceleration={GuidanceAcceleration}";
}
/// <summary>
/// 计算导弹到激光束的最短距离
/// </summary>
/// <returns>最短距离向量</returns>
private Vector3D CalculateShortestDistanceToLaserBeam()
{
// 计算导弹到激光源的向量

View File

@ -14,19 +14,33 @@ namespace ActiveProtect.Models
Explode, // 爆炸阶段
SelfDestruct // 自毁阶段
}
/// <summary>
/// 当前阶段
/// </summary>
private LBRM_Stage currentStage;
private LaserBeamRiderGuidanceSystem LaserBeamRiderGuidanceSystem;
private MissileConfig missileConfig;
/// <summary>
/// 激光驾束制导系统
/// </summary>
private readonly LaserBeamRiderGuidanceSystem LaserBeamRiderGuidanceSystem;
public LaserBeamRiderMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
: base(id, missileConfig, simulationManager)
/// <summary>
/// 构造函数
/// </summary>
/// <param name="config">导弹配置</param>
/// <param name="manager">模拟管理器</param>
public LaserBeamRiderMissile(MissileConfig config, ISimulationManager manager)
: base(config, manager)
{
LaserBeamRiderGuidanceSystem = new LaserBeamRiderGuidanceSystem();
currentStage = LBRM_Stage.Launch;
this.missileConfig = missileConfig;
}
/// <summary>
/// 激光束开启事件
/// </summary>
/// <param name="evt">激光束开启事件</param>
private void OnLaserBeamStart(LaserBeamStartEvent evt)
{
if (evt?.LaserBeamRider != null)
@ -35,6 +49,10 @@ namespace ActiveProtect.Models
}
}
/// <summary>
/// 激光束更新事件
/// </summary>
/// <param name="evt">激光束更新事件</param>
private void OnLaserBeamUpdate(LaserBeamUpdateEvent evt)
{
if (evt?.LaserBeamRider != null)
@ -43,14 +61,22 @@ namespace ActiveProtect.Models
}
}
/// <summary>
/// 激光束停止事件
/// </summary>
/// <param name="evt">激光束停止事件</param>
private void OnLaserBeamStop(LaserBeamStopEvent evt)
{
if (evt?.LaserBeamRider != null)
{
LaserBeamRiderGuidanceSystem?.DeactivateLaserBeam(evt.LaserBeamRider.Position, evt.LaserBeamRider.LaserDirection);
LaserBeamRiderGuidanceSystem?.DeactivateLaserBeam();
}
}
/// <summary>
/// 更新导弹
/// </summary>
/// <param name="deltaTime">时间步长</param>
public override void Update(double deltaTime)
{
switch (currentStage)
@ -65,13 +91,17 @@ namespace ActiveProtect.Models
UpdateExplodeStage(deltaTime);
break;
case LBRM_Stage.SelfDestruct:
SelfDestruct();
UpdateSelfDestructStage(deltaTime);
break;
}
base.Update(deltaTime);
}
/// <summary>
/// 更新发射阶段
/// </summary>
/// <param name="deltaTime">时间步长</param>
private void UpdateLaunchStage(double deltaTime)
{
// 发射阶段
@ -82,29 +112,49 @@ namespace ActiveProtect.Models
}
}
/// <summary>
/// 更新巡航阶段
/// </summary>
/// <param name="deltaTime">时间步长</param>
private void UpdateCruiseStage(double deltaTime)
{
// 巡航阶段
LaserBeamRiderGuidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = LaserBeamRiderGuidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= missileConfig.DistanceParams.ExplosionDistance)
if (DistanceToTarget <= ExplosionRadius)
{
currentStage = LBRM_Stage.Explode;
}
if(ShouldSelfDestruct())
{
currentStage = LBRM_Stage.SelfDestruct;
}
}
/// <summary>
/// 更新爆炸阶段
/// </summary>
/// <param name="deltaTime">时间步长</param>
private void UpdateExplodeStage(double deltaTime)
{
// 爆炸阶段
Explode();
}
/// <summary>
/// 更新自毁阶段
/// </summary>
/// <param name="deltaTime">时间步长</param>
private void UpdateSelfDestructStage(double deltaTime)
{
// 自毁阶段
SelfDestruct();
}
/// <summary>
/// 获取导弹状态
/// </summary>
/// <returns>导弹状态</returns>
public override string GetStatus()
{
string baseStatus = base.GetStatus().Replace("导弹", "激光驾束制导导弹");
@ -112,6 +162,9 @@ namespace ActiveProtect.Models
return baseStatus + additionalStatus;
}
/// <summary>
/// 激活导弹
/// </summary>
public override void Activate()
{
base.Activate();
@ -120,6 +173,9 @@ namespace ActiveProtect.Models
SimulationManager.SubscribeToEvent<LaserBeamUpdateEvent>(OnLaserBeamUpdate);
}
/// <summary>
/// 关闭导弹
/// </summary>
public override void Deactivate()
{
base.Deactivate();

View File

@ -112,8 +112,7 @@ namespace ActiveProtect.Models
{
if (evt.TargetId == TargetId)
{
var tank = SimulationManager.GetEntityById(TargetId) as Tank;
if (tank != null)
if (SimulationManager.GetEntityById(TargetId) is Tank tank)
{
double distanceToTarget = Vector3D.Distance(Position, tank.Position);
double jammingEffectiveness = 20 * Math.Log10(evt.JammingPower) - 20 * Math.Log10(distanceToTarget) - 20 * Math.Log10(4 * Math.PI);

View File

@ -67,8 +67,8 @@ namespace ActiveProtect.Models
maxJammingPower = config.MaxJammingPower;
initialJammingPower = config.InitialJammingPower;
powerIncreaseRate = config.PowerIncreaseRate;
SimulationManager.SubscribeToEvent<LaserWarnerAlarmEvent>(OnLaserWarnerAlarmEvent);
SimulationManager.SubscribeToEvent<LaserWarnerAlarmStopEvent>(OnLaserWarnerAlarmStopEvent);
base.SimulationManager.SubscribeToEvent<LaserWarnerAlarmEvent>(OnLaserWarnerAlarmEvent);
base.SimulationManager.SubscribeToEvent<LaserWarnerAlarmStopEvent>(OnLaserWarnerAlarmStopEvent);
}
/// <summary>

View File

@ -2,6 +2,9 @@ using System;
namespace ActiveProtect.Models
{
/// <summary>
/// 激光半主动制导系统
/// </summary>
public class LaserSemiActiveGuidanceSystem : BasicGuidanceSystem
{
private const double FieldOfViewAngle = Math.PI / 6; // 30度视场角
@ -10,16 +13,46 @@ namespace ActiveProtect.Models
private const double ReflectionCoefficient = 0.2; // 反射系数
private const double LockThreshold = 1e-12; // 锁定阈值(瓦特)
private const double TargetReflectiveArea = 1.0; // 目标有效反射面积(平方米)
/// <summary>
/// 目标位置
/// </summary>
private Vector3D TargetPosition { get; set; }
/// <summary>
/// 目标速度
/// </summary>
private Vector3D TargetVelocity { get; set; }
/// <summary>
/// 激光照射是否开启
/// </summary>
private bool LaserIlluminationOn { get; set; }
/// <summary>
/// 激光指示器位置
/// </summary>
private Vector3D LaserDesignatorPosition { get; set; }
/// <summary>
/// 激光功率
/// </summary>
private double LaserPower { get; set; }
/// <summary>
/// 激光发散角
/// </summary>
private double LaserDivergenceAngle { get; set; }
/// <summary>
/// 比例导航系数
/// </summary>
private double ProportionalNavigationCoefficient { get; set; }
/// <summary>
/// 构造函数
/// </summary>
public LaserSemiActiveGuidanceSystem()
{
TargetPosition = Vector3D.Zero;
@ -30,6 +63,14 @@ namespace ActiveProtect.Models
ProportionalNavigationCoefficient = 4;
}
/// <summary>
/// 更新激光指示器
/// </summary>
/// <param name="sourcePosition">激光源位置</param>
/// <param name="targetPosition">目标位置</param>
/// <param name="targetVelocity">目标速度</param>
/// <param name="laserPower">激光功率</param>
/// <param name="laserDivergenceAngle">激光发散角</param>
public void UpdateLaserDesignator(Vector3D sourcePosition, Vector3D targetPosition, Vector3D targetVelocity, double laserPower, double laserDivergenceAngle)
{
LaserIlluminationOn = true;
@ -40,6 +81,9 @@ namespace ActiveProtect.Models
LaserDivergenceAngle = laserDivergenceAngle;
}
/// <summary>
/// 关闭激光照射
/// </summary>
public void DeactivateLaserDesignator()
{
LaserIlluminationOn = false;
@ -50,6 +94,12 @@ namespace ActiveProtect.Models
LaserDivergenceAngle = 0;
}
/// <summary>
/// 更新制导系统
/// </summary>
/// <param name="deltaTime">时间步长</param>
/// <param name="missilePosition">导弹位置</param>
/// <param name="missileVelocity">导弹速度</param>
public override void Update(double deltaTime, Vector3D missilePosition, Vector3D missileVelocity)
{
base.Update(deltaTime, missilePosition, missileVelocity);
@ -69,10 +119,12 @@ namespace ActiveProtect.Models
{
GuidanceAcceleration = Vector3D.Zero;
}
PrintGuidanceInfo();
}
/// <summary>
/// 计算接收到的激光功率
/// </summary>
/// <returns>接收到的激光功率</returns>
private double CalculateReceivedLaserPower()
{
double distanceDesignatorToTarget = (LaserDesignatorPosition - TargetPosition).Magnitude();
@ -108,9 +160,12 @@ namespace ActiveProtect.Models
return finalReceivedPower;
}
/// <summary>
/// 计算制导加速度
/// </summary>
/// <param name="deltaTime">时间步长</param>
protected override void CalculateGuidanceAcceleration(double deltaTime)
{
Console.WriteLine($"激光半主动导弹引导加速度计算: 位置: {Position}, 速度: {Velocity}, 目标位置: {TargetPosition}, 目标速度: {TargetVelocity}");
// 计算比例导引加速度
GuidanceAcceleration = CalculateProportionalNavigation(ProportionalNavigationCoefficient, Position, Velocity, TargetPosition, TargetVelocity);
@ -122,18 +177,12 @@ namespace ActiveProtect.Models
}
}
private void PrintGuidanceInfo()
/// <summary>
/// 获取制导系统状态
/// </summary>
public override string GetStatus()
{
Console.WriteLine($"激光半主动导弹引导信息:");
Console.WriteLine($" 位置: {Position}");
Console.WriteLine($" 速度: {Velocity}");
Console.WriteLine($" 速度大小: {Velocity.Magnitude():F2} m/s");
Console.WriteLine($" 是否有引导: {HasGuidance}");
Console.WriteLine($" 目标位置: {TargetPosition}");
Console.WriteLine($" 制导加速度: {GuidanceAcceleration}");
Console.WriteLine($" 接收到的激光功率: {CalculateReceivedLaserPower():E} W");
Console.WriteLine($" 锁定阈值: {LockThreshold:E} W");
Console.WriteLine();
return base.GetStatus() + $" 接收到的激光功率: {CalculateReceivedLaserPower():E} W 锁定阈值: {LockThreshold:E} W";
}
}
}

View File

@ -18,25 +18,22 @@ namespace ActiveProtect.Models
Explode, // 爆炸阶段
SelfDestruct // 自毁阶段
}
private LSAGM_Stage currentStage;
private LaserSemiActiveGuidanceSystem LaserGuidanceSystem;
public string LaserDesignatorId { get; set; } = "";
private MissileConfig missileConfig;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="id">导弹ID</param>
/// <param name="laserDesignatorId">激光指示器ID</param>
/// <param name="missileConfig">导弹配置</param>
/// <param name="config">导弹配置</param>
/// <param name="simulationManager">仿真管理器</param>
public LaserSemiActiveGuidedMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
: base(id, missileConfig, simulationManager)
public LaserSemiActiveGuidedMissile(MissileConfig config, ISimulationManager manager)
: base(config, manager)
{
LaserGuidanceSystem = new LaserSemiActiveGuidanceSystem();
currentStage = LSAGM_Stage.Launch;
this.missileConfig = missileConfig;
}
/// <summary>
@ -141,10 +138,15 @@ namespace ActiveProtect.Models
{
LaserGuidanceSystem.Update(deltaTime, Position, Velocity);
GuidanceAcceleration = LaserGuidanceSystem.GetGuidanceAcceleration();
if (DistanceToTarget <= missileConfig.DistanceParams.ExplosionDistance)
Console.WriteLine($"导弹ID: {Id}, 距离目标: {DistanceToTarget}, 爆炸半径: {ExplosionRadius}");
if (DistanceToTarget <= ExplosionRadius)
{
currentStage = LSAGM_Stage.Explode;
}
if(ShouldSelfDestruct())
{
currentStage = LSAGM_Stage.SelfDestruct;
}
}
private void UpdateExplodeStage(double deltaTime)

View File

@ -43,8 +43,8 @@ namespace ActiveProtect.Models
MonitoredEntityId = monitoredEntityId;
IsAlarming = false;
alarmDuration = config.AlarmDuration;
SimulationManager.SubscribeToEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
base.SimulationManager.SubscribeToEvent<LaserIlluminationStartEvent>(OnLaserIlluminationStart);
base.SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
}
/// <summary>

View File

@ -56,9 +56,9 @@ namespace ActiveProtect.Models
public double DistanceToTarget { get; protected set; }
/// <summary>
/// 导弹距离参数
/// 爆炸半径(米)
/// </summary>
public MissileDistanceParams DistanceParams { get; protected set; }
public double ExplosionRadius { get; protected set; }
/// <summary>
/// 上一帧目标位置
@ -130,54 +130,55 @@ namespace ActiveProtect.Models
/// </summary>
protected Vector3D ThrustAcceleration { get; set; }
protected readonly MissileConfig MissileConfig;
/// <summary>
/// 构造函数
/// </summary>
public MissileBase(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
: base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, missileConfig.InitialSpeed, simulationManager)
public MissileBase(MissileConfig config, ISimulationManager manager)
: base(config.Id, config.InitialPosition, config.InitialOrientation, config.InitialSpeed, manager)
{
// 初始化导弹属性
Speed = missileConfig.InitialSpeed;
MaxSpeed = missileConfig.MaxSpeed;
MaxFlightTime = missileConfig.MaxFlightTime;
MaxFlightDistance = missileConfig.MaxFlightDistance;
DistanceParams = missileConfig.DistanceParams;
MissileConfig = config;
SimulationManager = manager;
InitializeFromConfig();
IsActive = false;
FlightTime = 0;
FlightDistance = 0;
SimulationManager = simulationManager;
LaunchAcceleration = missileConfig.LaunchAcceleration;
EngineBurnTime = 0;
MaxEngineBurnTime = missileConfig.MaxEngineBurnTime;
MaxAcceleration = missileConfig.MaxAcceleration;
ProportionalNavigationCoefficient = missileConfig.ProportionalNavigationCoefficient;
TargetId = $"Tank_{missileConfig.TargetIndex + 1}";
GuidanceAcceleration = Vector3D.Zero;
ThrustAcceleration = Vector3D.Zero;
LastTargetPosition = Vector3D.Zero;
TargetId = $"Tank_{config.TargetIndex + 1}";
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
}
/// <summary>
/// 从配置初始化导弹
/// </summary>
private void InitializeFromConfig()
{
// 初始化导弹属性
Speed = MissileConfig.InitialSpeed;
MaxSpeed = MissileConfig.MaxSpeed;
MaxFlightTime = MissileConfig.MaxFlightTime;
MaxFlightDistance = MissileConfig.MaxFlightDistance;
ExplosionRadius = MissileConfig.ExplosionRadius;
LaunchAcceleration = MissileConfig.LaunchAcceleration;
MaxEngineBurnTime = MissileConfig.MaxEngineBurnTime;
MaxAcceleration = MissileConfig.MaxAcceleration;
ProportionalNavigationCoefficient = MissileConfig.ProportionalNavigationCoefficient;
}
/// <summary>
/// 更新导弹状态
/// </summary>
public override void Update(double deltaTime)
{
if (!IsActive) return;
if (ShouldSelfDestruct())
if (IsActive)
{
SelfDestruct();
return;
}
UpdateMotionState(deltaTime);
if (CheckHit())
{
Explode();
return;
// 更新导弹运动状态
UpdateMotionState(deltaTime);
}
}
@ -209,53 +210,10 @@ namespace ActiveProtect.Models
/// </summary>
private Vector3D CalculateAcceleration(Vector3D velocity)
{
// Vector3D thrustAcceleration = Vector3D.Zero;
// Vector3D guidanceAcceleration = Vector3D.Zero;
// switch (CurrentStage)
// {
// case FlightStage.Launch:
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
// break;
// case FlightStage.Acceleration:
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration;
// guidanceAcceleration = guidanceCommand;
// break;
// case FlightStage.Cruise:
// thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.05);
// guidanceAcceleration = guidanceCommand * 1;
// break;
// case FlightStage.TerminalGuidance:
// thrustAcceleration = Orientation.ToVector() * (ThrustAcceleration * 0.05);
// guidanceAcceleration = guidanceCommand * 1;
// break;
// case FlightStage.Attack:
// thrustAcceleration = Orientation.ToVector() * ThrustAcceleration*0.05;
// guidanceAcceleration = guidanceCommand * 1;
// break;
// }
// if (!HasGuidance)
// {
// if (velocity.Magnitude() > 0)
// {
// ThrustAcceleration = LaunchAcceleration * velocity.Normalize();
// }
// else
// {
// ThrustAcceleration = LaunchAcceleration * velocity.Normalize();
// }
// }
//计算重力加速度(反坦克导弹一般升力很小, 主要依靠初始发射动能和持续的推力来维持飞行)
//Vector3D gravityCompensation = new(0, 9.81, 0);
//Vector3D gravityAcceleration = new(0, -9.81, 0);
// 计算空气阻力的影响
Vector3D dragAcceleration = velocity.Normalize() * -1 * CalculateDrag(velocity.Magnitude()) / Mass;
//Vector3D totalAcceleration = GuidanceAcceleration + ThrustAcceleration + gravityAcceleration +dragAcceleration;
//Vector3D totalAcceleration = GuidanceAcceleration + ThrustAcceleration + dragAcceleration;
Vector3D totalAcceleration = GuidanceAcceleration;
Vector3D totalAcceleration = GuidanceAcceleration + ThrustAcceleration + dragAcceleration;
Console.WriteLine($"导弹 {Id} 的加速度: {totalAcceleration}, 制导加速度: {GuidanceAcceleration}, 推力加速度: {ThrustAcceleration}, 空气阻力加速度: {dragAcceleration}");
if (totalAcceleration.Magnitude() > MaxAcceleration)
@ -278,14 +236,6 @@ namespace ActiveProtect.Models
return 0.5 * dragCoefficient * airDensity * referenceArea * speed * speed;
}
/// <summary>
/// 检查是否命中目标
/// </summary>
protected bool CheckHit()
{
return DistanceToTarget <= DistanceParams.ExplosionDistance;
}
/// <summary>
/// 检查是否应该自毁
/// </summary>
@ -320,20 +270,6 @@ namespace ActiveProtect.Models
// }
// }
/// <summary>
/// 计算比例导引加速度
/// </summary>
// private Vector3D CalculateProportionalNavigation(Vector3D position)
// {
// Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
// Vector3D LOS = targetPosition - position;
// Vector3D LOSRate = (targetPosition - LastTargetPosition) / FlightTime - Velocity;
// LastTargetPosition = targetPosition;
// return Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), LOS).Normalize()
// * ProportionalNavigationCoefficient * Velocity.Magnitude();
// }
/// <summary>
/// 导弹爆炸
/// </summary>
@ -375,7 +311,7 @@ namespace ActiveProtect.Models
/// </summary>
public override string GetStatus()
{
MissileRunningState missileRunningState = GetState();
MissileRunningState missileRunningState = GetRunningState();
return $"导弹 {missileRunningState.Id}:\n" +
$" 位置: {missileRunningState.Position}\n" +
$" 速度: {missileRunningState.Speed:F2} m/s\n" +
@ -397,7 +333,7 @@ namespace ActiveProtect.Models
// 基类中的默认实现
}
public MissileRunningState GetState()
public MissileRunningState GetRunningState()
{
return new MissileRunningState
{
@ -411,7 +347,6 @@ namespace ActiveProtect.Models
FlightTime = FlightTime,
FlightDistance = FlightDistance,
DistanceToTarget = DistanceToTarget,
//CurrentStage = CurrentStage,
HasGuidance = HasGuidance,
LostGuidanceTime = LostGuidanceTime,
EngineBurnTime = EngineBurnTime,
@ -475,11 +410,6 @@ namespace ActiveProtect.Models
/// </summary>
public double DistanceToTarget { get; set; }
/// <summary>
/// 当前飞行阶段
/// </summary>
//public FlightStage CurrentStage { get; set; }
/// <summary>
/// 是否有制导
/// </summary>

View File

@ -200,6 +200,10 @@ namespace ActiveProtect.Models
/// </summary>
public class MillimeterWaveAltimeter : Sensor
{
private double currentAltitude;
private TerminalSensitiveSubmunition submunition;
/// <summary>
/// 最大测量高度
/// </summary>
@ -217,11 +221,13 @@ namespace ActiveProtect.Models
/// <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)
public MillimeterWaveAltimeter(TerminalSensitiveSubmunition submunition, double maxAltitude, double accuracy)
: base(submunition.Position, submunition.Orientation)
{
MaxAltitude = maxAltitude;
Accuracy = accuracy;
currentAltitude = 0;
this.submunition = submunition;
}
/// <summary>
@ -230,7 +236,8 @@ namespace ActiveProtect.Models
/// <param name="deltaTime">自上次更新以来的时间间隔</param>
public override void Update(double deltaTime)
{
// 实现毫米波测高雷达的更新逻辑
// 更新当前高度,考虑测量精度
currentAltitude = submunition.Position.Y + Accuracy * new Random().NextDouble();
}
/// <summary>
@ -240,7 +247,11 @@ namespace ActiveProtect.Models
public override SensorData GetSensorData()
{
// 返回毫米波测高雷达的数据
return new AltimeterSensorData();
AltimeterSensorData altimeterSensorData = new AltimeterSensorData
{
Altitude = currentAltitude
};
return altimeterSensorData;
}
}

View File

@ -31,11 +31,10 @@ namespace ActiveProtect.Models
/// <summary>
/// 构造函数
/// </summary>
/// <param name="id">坦克ID</param>
/// <param name="tankConfig">坦克配置</param>
/// <param name="simulationManager">仿真管理器</param>
public Tank(string id, TankConfig tankConfig, ISimulationManager simulationManager)
: base(id, tankConfig.InitialPosition, tankConfig.InitialOrientation, tankConfig.InitialSpeed, simulationManager)
public Tank(TankConfig tankConfig, ISimulationManager simulationManager)
: base(tankConfig.Id, tankConfig.InitialPosition, tankConfig.InitialOrientation, tankConfig.InitialSpeed, simulationManager)
{
Speed = tankConfig.InitialSpeed;
MaxSpeed = tankConfig.MaxSpeed;

View File

@ -8,37 +8,32 @@ namespace ActiveProtect.Models
{
// 分离高度 1000米默认 1000 米
private const double SeparationHeight = 1000;
// 分离点距离目标水平距离,默认 1000 米
private const double SeparationDistance = 1000;
// 分离时距离分离点的距离阈值,默认 50米
private const double SeparationRange = 50;
// 分离时距目标距离阈值,默认 1400 米
private const double SeparationTargetDistance = 1400;
// 子弹数量, 155 口径母弹,默认 2 个
private const int SubmunitionCount = 1;
// 子弹数组
private TerminalSensitiveSubmunition[] submunitions;
// 分离点位置
private Vector3D separationPoint;
private readonly Vector3D separationPoint;
public MissileConfig missileConfig { get; set; }
public TerminalSensitiveMissile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
: base(id, missileConfig, simulationManager)
public TerminalSensitiveMissile(MissileConfig config, ISimulationManager manager)
: base(config, manager)
{
submunitions = new TerminalSensitiveSubmunition[SubmunitionCount];
this.missileConfig = missileConfig;
//计算分离点坐标高度为SeparationHeight距离目标的距离为SeparationDistance
separationPoint = Vector3D.PointOnLine(SimulationManager.GetEntityById(TargetId).Position, Position, SeparationDistance) + new Vector3D(0, SeparationHeight, 0);
separationPoint = Vector3D.PointOnLine(base.SimulationManager.GetEntityById(TargetId).Position, base.Position, SeparationDistance) + new Vector3D(0, SeparationHeight, 0);
}
/// <summary>
/// 更新导弹
/// </summary>
/// <param name="deltaTime">时间步长</param>
public override void Update(double deltaTime)
{
base.Update(deltaTime);
@ -73,9 +68,10 @@ namespace ActiveProtect.Models
Vector3D directionToTarget = (targetPosition - this.Position).Normalize();
Orientation orientationToTarget = Orientation.FromVector(directionToTarget);
submunitions[i] = new TerminalSensitiveSubmunition($"{Id}_Sub_{i}",
submunitions[i] = new TerminalSensitiveSubmunition(
new MissileConfig
{
Id = $"{Id}_Sub_{i}",
InitialPosition = this.Position,
InitialOrientation = orientationToTarget, // 设置为朝向目标的方向
InitialSpeed = 200, // 子弹初始速度
@ -84,8 +80,9 @@ namespace ActiveProtect.Models
MaxFlightTime = 50,
MaxFlightDistance = 1000,
MaxAcceleration = 50,
ProportionalNavigationCoefficient = 0.1,
Mass = 10
ProportionalNavigationCoefficient = 3,
Mass = 10,
ExplosionRadius = 10
},
SimulationManager);
@ -97,6 +94,10 @@ namespace ActiveProtect.Models
IsActive = false;
}
/// <summary>
/// 获取导弹状态
/// </summary>
/// <returns>导弹状态</returns>
public override string GetStatus()
{
return $"{base.GetStatus()}\n母弹, 分离点: {separationPoint}";

View File

@ -5,18 +5,25 @@ namespace ActiveProtect.Models
{
public class TerminalSensitiveSubmunition : MissileBase
{
/// <summary>
/// 子弹阶段
/// </summary>
private enum SubmunitionStage
{
Separation,
Deceleration,
SpiralScan,
Attack,
Explode,
SelfDestruct
}
/// <summary>
/// 当前阶段
/// </summary>
private SubmunitionStage currentStage;
private double spiralAngle;
private const double SpiralRotationSpeed = 4 * Math.PI; // 2 rotations per second
private const double SpiralRotationSpeed = 8 * Math.PI; // 4 rotations per second
private const double VerticalDescentSpeed = 10; // 10 m/s
private const double ScanAngle = 20 * Math.PI / 180; // 20 degrees in radians
@ -29,37 +36,50 @@ namespace ActiveProtect.Models
// 自毁高度 20米
private const double SelfDestructHeight = 20;
private const double AttackSpeed = 200;
// 攻击速度 500 m/s
private const double AttackSpeed = 500;
private Vector3D lastScanDirection;
// 是否检测到目标
private bool targetDetected;
/// <summary>
/// 螺旋角度
/// </summary>
private double spiralAngle;
// 检测到目标的角度
private double detectionAngle;
// 添加传感器
private InfraredDetector infraredDetector;
private MillimeterWaveRadiometer radiometer;
private MillimeterWaveAltimeter altimeter;
private LaserRangefinder rangefinder;
// 弹载传感器
private readonly InfraredDetector infraredDetector;
private readonly MillimeterWaveRadiometer radiometer;
private readonly MillimeterWaveAltimeter altimeter;
private readonly LaserRangefinder rangefinder;
private MissileConfig missileConfig;
public TerminalSensitiveSubmunition(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
: base(id, missileConfig, simulationManager)
/// <summary>
/// 构造函数
/// </summary>
/// <param name="config">导弹配置</param>
/// <param name="manager">模拟管理器</param>
public TerminalSensitiveSubmunition(MissileConfig config, ISimulationManager manager)
: base(config, manager)
{
currentStage = SubmunitionStage.Separation;
spiralAngle = 0;
lastScanDirection = Vector3D.Zero;
targetDetected = false;
detectionAngle = 0;
this.missileConfig = missileConfig;
// 初始化传感器
infraredDetector = new InfraredDetector(Position, Orientation, 1000, 30);
infraredDetector = new InfraredDetector(Position, Orientation, 100, 30);
radiometer = new MillimeterWaveRadiometer(Position, Orientation, 94e9, 1e-6);
altimeter = new MillimeterWaveAltimeter(Position, Orientation, 1000, 0.1);
rangefinder = new LaserRangefinder(Position, Orientation, 5000, 1000);
altimeter = new MillimeterWaveAltimeter(this, 1000, 0.1); // 毫米波测高仪测量精度0.1米
rangefinder = new LaserRangefinder(Position, Orientation, 1000, 1000);
}
/// <summary>
/// 更新子弹的状态
/// </summary>
/// <param name="deltaTime">时间增量</param>
public override void Update(double deltaTime)
{
base.Update(deltaTime);
@ -84,53 +104,75 @@ namespace ActiveProtect.Models
case SubmunitionStage.Attack:
UpdateAttackStage(deltaTime);
break;
case SubmunitionStage.Explode:
UpdateExplodeStage(deltaTime);
break;
case SubmunitionStage.SelfDestruct:
SelfDestruct();
UpdateSelfDestructStage(deltaTime);
break;
}
}
/// <summary>
/// 分离阶段
/// </summary>
private void UpdateSeparationStage(double deltaTime)
{
Console.WriteLine("分离阶段");
// 分离阶段
Vector3D deceleration = new Vector3D(0, 9.8, 0);
Vector3D deceleration = new(0, 9.8, 0);
Velocity += deceleration * deltaTime;
Position += Velocity * deltaTime;
if (Position.Y <= DecelerationHeight)
if(!altimeter.IsActive)
{
currentStage = SubmunitionStage.Deceleration;
// 激活毫米波测高雷达
altimeter.Activate();
}
// 检查高度是否小于等于减速高度
if(((AltimeterSensorData)altimeter.GetSensorData()).Altitude <= DecelerationHeight)
{
// 如果是,则进入减速阶段
currentStage = SubmunitionStage.Deceleration;
}
}
/// <summary>
/// 减速阶段
/// </summary>
private void UpdateDecelerationStage(double deltaTime)
{
Console.WriteLine("减速阶段");
// 减速减旋,垂直速度减小
Vector3D deceleration = new Vector3D(0, 9.8, 0) - Velocity.Normalize() * 50; // 假设减速度为5m/s^2
Console.WriteLine($"减速速度: {deceleration}");
Console.WriteLine($"降落伞打开,减速速度: {deceleration}");
Velocity += deceleration * deltaTime;
if (Velocity.Magnitude() <= VerticalDescentSpeed || Position.Y <= ScanningHeight)
if (Velocity.Magnitude() <= VerticalDescentSpeed)
{
Velocity = new Vector3D(0, -VerticalDescentSpeed, 0);
if (Position.Y <= ScanningHeight)
{
currentStage = SubmunitionStage.SpiralScan;
}
}
if (((AltimeterSensorData)altimeter.GetSensorData()).Altitude <= ScanningHeight)
{
currentStage = SubmunitionStage.SpiralScan;
}
}
/// <summary>
/// 扫描阶段
/// </summary>
private void UpdateSpiralScanStage(double deltaTime)
{
Console.WriteLine("扫描阶段");
spiralAngle = spiralAngle % (2 * Math.PI);
GuidanceAcceleration = Vector3D.Zero;
Velocity = new Vector3D(0, -VerticalDescentSpeed, 0);
// 螺旋扫描
spiralAngle %= (2 * Math.PI);
spiralAngle += SpiralRotationSpeed * deltaTime;
// 计算水平速度分量
double horizontalSpeed = VerticalDescentSpeed * Math.Tan(ScanAngle);
Vector3D horizontalVelocity = new Vector3D(
Vector3D horizontalVelocity = new(
Math.Cos(spiralAngle) * horizontalSpeed,
0,
Math.Sin(spiralAngle) * horizontalSpeed
@ -140,7 +182,7 @@ namespace ActiveProtect.Models
Velocity = new Vector3D(horizontalVelocity.X, -VerticalDescentSpeed, horizontalVelocity.Z);
// 计算扫描方向
Vector3D scanDirection = new Vector3D(
Vector3D scanDirection = new(
Math.Cos(spiralAngle) * Math.Sin(ScanAngle),
-Math.Cos(ScanAngle),
Math.Sin(spiralAngle) * Math.Sin(ScanAngle)
@ -148,6 +190,7 @@ namespace ActiveProtect.Models
if (DetectTarget(scanDirection))
{
Console.WriteLine("检测到目标");
if (!targetDetected)
{
targetDetected = true;
@ -159,14 +202,15 @@ namespace ActiveProtect.Models
}
}
lastScanDirection = scanDirection;
if (Position.Y <= SelfDestructHeight)
if (((AltimeterSensorData)altimeter.GetSensorData()).Altitude <= SelfDestructHeight)
{
currentStage = SubmunitionStage.SelfDestruct;
}
}
/// <summary>
/// 攻击阶段
/// </summary>
private void UpdateAttackStage(double deltaTime)
{
Console.WriteLine("攻击阶段");
@ -174,18 +218,34 @@ namespace ActiveProtect.Models
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
Vector3D direction = (targetPosition - Position).Normalize();
Velocity = direction * AttackSpeed;
if (Vector3D.Distance(Position, targetPosition) < 5)
Console.WriteLine($"导弹ID: {Id}, 距离目标: {DistanceToTarget}, 爆炸半径: {ExplosionRadius}");
if (DistanceToTarget <= ExplosionRadius)
{
Explode();
currentStage = SubmunitionStage.Explode;
}
}
/// <summary>
/// 爆炸阶段
/// </summary>
private void UpdateExplodeStage(double deltaTime)
{
Explode();
}
/// <summary>
/// 自毁阶段
/// </summary>
private void UpdateSelfDestructStage(double deltaTime)
{
SelfDestruct();
}
/// <summary>
/// 检测目标
/// </summary>
/// <param name="scanDirection">扫描方向</param>
/// <returns>是否检测到目标</returns>
private bool DetectTarget(Vector3D scanDirection)
{
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
@ -195,6 +255,22 @@ namespace ActiveProtect.Models
return Vector3D.DotProduct(scanDirection, toTarget) > Math.Cos(5 * Math.PI / 180); // 允许5度的误差
}
/// <summary>
/// 销毁子弹
/// </summary>
public override void Deactivate()
{
base.Deactivate();
infraredDetector.Deactivate();
radiometer.Deactivate();
altimeter.Deactivate();
rangefinder.Deactivate();
}
/// <summary>
/// 获取子弹状态
/// </summary>
/// <returns>子弹状态</returns>
public override string GetStatus()
{
return $"{base.GetStatus()}\nSubmunition Stage: {currentStage}\nDetection Angle: {detectionAngle * 180 / Math.PI:F2}°\nSpiral Angle: {spiralAngle * 180 / Math.PI:F2}°\nTarget Detected: {targetDetected}";

View File

@ -3,31 +3,24 @@ using System.Threading;
using ActiveProtect.SimulationEnvironment;
using ActiveProtect.Models;
using Model;
using System.Security.Cryptography.X509Certificates;
using System.Collections.Generic;
namespace ActiveProtect
{
/// <summary>
/// 主程序
/// </summary>
class Program
{
static void Main(string[] args)
{
// 初始化坦克信息
TankInfo tankinfo = new()
{
xp = 100,
yp = 0,
zp = 100
};
MIniInfo mIniInfo = new()
{
xm = 1500,
ym = 200,
zm = 100,
psi_m = Math.PI,
theta_m = -0.1,
vm = 0
};
// 创建仿真配置
var config = new SimulationConfig
@ -35,10 +28,11 @@ namespace ActiveProtect
// 配置坦克
TankConfigs = new List<TankConfig>
{
new TankConfig(tankinfo)
new(tankinfo)
{
Id = "Tank_1",
InitialOrientation = new Orientation(Math.PI/4, 0, 0),
InitialSpeed = 0,
InitialSpeed = 10,
MaxSpeed = 25,
MaxArmor = 100,
HasLaserWarner = false,
@ -48,6 +42,7 @@ namespace ActiveProtect
// 配置激光指示器
LaserDesignatorConfig = new LaserDesignatorConfig
{
Id = "LD_1",
InitialPosition = new Vector3D(2000, 150, 100),
LaserPower = 1e6,
LaserDivergenceAngle = 0.01
@ -55,11 +50,13 @@ namespace ActiveProtect
// 配置激光告警器
LaserWarnerConfig = new LaserWarnerConfig
{
Id = "LW_1",
AlarmDuration = 5.0
},
// 配置激光干扰器
LaserJammerConfig = new LaserJammerConfig
{
Id = "LJ_1",
MaxJammingCooldown = 5.0,
MaxJammingPower = 10000.0,
InitialJammingPower = 4000.0,
@ -68,6 +65,7 @@ namespace ActiveProtect
// 配置激光驾束仪
LaserBeamRiderConfig = new LaserBeamRiderConfig
{
Id = "LBR_1",
InitialPosition = new Vector3D(2000, 10, 100),
LaserPower = 1000,
ControlFieldDiameter = 6
@ -76,8 +74,8 @@ namespace ActiveProtect
MissileConfigs = new List<MissileConfig>
{
// 激光半主动制导导弹配置
new MissileConfig
{
new() {
Id = "LSGM_1",
InitialPosition = new Vector3D(2000, 100, 100),
InitialOrientation = new Orientation(Math.PI, -0.1, 0),
InitialSpeed = 700,
@ -89,14 +87,13 @@ namespace ActiveProtect
MaxEngineBurnTime = 10,
MaxAcceleration = 400,
ProportionalNavigationCoefficient = 3,
StageConfig = FlightStageConfig.LaserSemiActiveGuidedMissile,
DistanceParams = new MissileDistanceParams(500, 200, 20),
ExplosionRadius = 10,
Mass = 50,
Type = MissileType.LaserSemiActiveGuidance
},
// 激光驾束制导导弹配置
new MissileConfig
{
new() {
Id = "LBRM_1",
InitialPosition = new Vector3D(2000, 10, 100),
InitialOrientation = new Orientation(Math.PI, 0.0, 0.0),
InitialSpeed = 300,
@ -108,14 +105,13 @@ namespace ActiveProtect
MaxEngineBurnTime = 10,
MaxAcceleration = 400,
ProportionalNavigationCoefficient = 3,
StageConfig = FlightStageConfig.LaserBeamRiderGuidance,
DistanceParams = new MissileDistanceParams(500, 200, 10),
ExplosionRadius = 10,
Mass = 50,
Type = MissileType.LaserBeamRiderGuidance
},
// 末敏弹配置
new MissileConfig
{
new() {
Id = "TSM_1",
InitialPosition = new Vector3D(4000, 0, 100), // 发射位置
InitialOrientation = new Orientation(Math.PI, Math.PI/8, 0), // 使用计算得到的发射角度
InitialSpeed = 800,
@ -127,14 +123,12 @@ namespace ActiveProtect
MaxEngineBurnTime = 0,
MaxAcceleration = 1000,
ProportionalNavigationCoefficient = 3,
StageConfig = FlightStageConfig.TerminalSensitiveMissile,
DistanceParams = new MissileDistanceParams(1000, 400, 20),
Mass = 50,
Type = MissileType.TerminalSensitiveMissile
}
},
SimulationTimeStep = 0.05 // 仿真时间步长, 激光驾束制导导弹需要更小的步长,< 0.025s
SimulationTimeStep = 0.025 // 仿真时间步长, 激光驾束制导导弹需要更小的步长,< 0.025s
};
// 创建仿真管理器

View File

@ -65,6 +65,11 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public class TankConfig
{
/// <summary>
/// 坦克ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 初始位置
/// </summary>
@ -106,7 +111,8 @@ namespace ActiveProtect.SimulationEnvironment
public TankConfig()
{
SetDefaultValues();
Id = "";
InitialPosition = new Vector3D(0, 0, 0);
InitialOrientation = new Orientation(0, 0, 0);
}
@ -114,6 +120,7 @@ namespace ActiveProtect.SimulationEnvironment
public TankConfig(TankInfo tankInfo){
SetDefaultValues();
Id = $"Tank_{tankInfo.TankID}";
InitialPosition = new Vector3D(tankInfo.xp, tankInfo.yp, tankInfo.zp);
InitialOrientation = new Orientation(0, 0, 0);
}
@ -125,6 +132,13 @@ namespace ActiveProtect.SimulationEnvironment
HasLaserWarner = false;
HasLaserJammer = false;
}
// 验证方法
public bool Validate()
{
// 实现验证逻辑
return true;
}
}
/// <summary>
@ -132,6 +146,11 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public class MissileConfig
{
/// <summary>
/// 导弹ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 初始位置
/// </summary>
@ -157,6 +176,8 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public int TargetIndex { get; set; }
/// <summary>
/// 最大飞行时间(秒)
/// </summary>
@ -177,16 +198,6 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public double ProportionalNavigationCoefficient { get; set; }
/// <summary>
/// 飞行阶段配置
/// </summary>
public FlightStageConfig StageConfig { get; set; }
/// <summary>
/// 距离参数
/// </summary>
public MissileDistanceParams DistanceParams { get; set; }
/// <summary>
/// 发射推力加速度(米/秒²)
/// </summary>
@ -202,6 +213,11 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public double Mass { get; set; }
/// <summary>
/// 爆炸半径(米)
/// </summary>
public double ExplosionRadius { get; set; }
/// <summary>
/// 导弹类型
/// </summary>
@ -214,29 +230,35 @@ namespace ActiveProtect.SimulationEnvironment
{
SetDefaultValues();
Id = "";
InitialPosition = new Vector3D(0, 0, 0);
InitialOrientation = new Orientation(0, 0, 0);
}
/// <summary>
/// 构造函数,根据导弹初始信息初始化导弹配置
/// </summary>
/// <param name="mIniInfo">导弹初始信息</param>
public MissileConfig(MIniInfo mIniInfo){
SetDefaultValues();
Id = $"Missile_{mIniInfo.nMisID}";
InitialPosition = new Vector3D(mIniInfo.xm, mIniInfo.ym, mIniInfo.zm);
InitialOrientation = new Orientation(mIniInfo.psi_m, mIniInfo.theta_m, 0);
InitialSpeed = mIniInfo.vm;
}
/// <summary>
/// 设置默认值
/// </summary>
public void SetDefaultValues(){
InitialSpeed = 0;
MaxSpeed = 0;
TargetIndex = 0;
MaxFlightTime = 0;
MaxFlightDistance = 0;
StageConfig = FlightStageConfig.StandardMissile;
LaunchAcceleration = 0;
MaxEngineBurnTime = 0;
MaxAcceleration = 0;
DistanceParams = new MissileDistanceParams(0, 0, 0);
ExplosionRadius = 0;
ProportionalNavigationCoefficient = 0;
Type = MissileType.StandardMissile;
}
@ -247,6 +269,11 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public class LaserDesignatorConfig
{
/// <summary>
/// 激光指示器ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 初始位置
/// </summary>
@ -267,6 +294,7 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public LaserDesignatorConfig()
{
Id = "";
InitialPosition = new Vector3D(0, 0, 0);
LaserPower = 0;
LaserDivergenceAngle = 0;
@ -278,6 +306,11 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public class LaserBeamRiderConfig
{
/// <summary>
/// 激光驾束仪ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 初始位置
/// </summary>
@ -304,6 +337,7 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public LaserBeamRiderConfig()
{
Id = "";
InitialPosition = new Vector3D(0, 0, 0);
LaserPower = 0;
ControlFieldDiameter = 0;
@ -324,109 +358,17 @@ namespace ActiveProtect.SimulationEnvironment
TerminalSensitiveMissile // 末敏弹
}
/// <summary>
/// 导弹距离参数结构
/// </summary>
public struct MissileDistanceParams
{
/// <summary>
/// 终端制导距离(米)
/// </summary>
public double TerminalGuidanceDistance;
/// <summary>
/// 攻击距离(米)
/// </summary>
public double AttackDistance;
/// <summary>
/// 爆炸距离(米)
/// </summary>
public double ExplosionDistance;
public MissileDistanceParams(double terminalGuidanceDistance, double attackDistance, double explosionDistance)
{
TerminalGuidanceDistance = terminalGuidanceDistance;
AttackDistance = attackDistance;
ExplosionDistance = explosionDistance;
}
}
/// <summary>
/// <summary>
/// 导弹飞行阶段配置结构
/// </summary>
public struct FlightStageConfig
{
/// <summary>
/// 启用发射阶段
/// </summary>
public bool EnableLaunch;
/// <summary>
/// 启用加速阶段
/// </summary>
public bool EnableAcceleration;
/// <summary>
/// 启用巡航阶段
/// </summary>
public bool EnableCruise;
/// <summary>
/// 启用终端制导阶段
/// </summary>
public bool EnableTerminalGuidance;
/// <summary>
/// 启用攻击阶段
/// </summary>
public bool EnableAttack;
/// <summary>
/// 标准导弹的预设配置, 所有阶段都启用
/// </summary>
public static FlightStageConfig StandardMissile => new(false, true, false, false, false);
/// <summary>
/// 激光半主动制导导弹的预设配置, 没有加速阶段
/// </summary>
public static FlightStageConfig LaserSemiActiveGuidedMissile => new(true, false, true, true, true);
/// <summary>
/// 激光驾束制导导弹的预设配置,没有巡航阶段
/// </summary>
public static FlightStageConfig LaserBeamRiderGuidance => new(true, true, false, true, true);
/// <summary>
/// 红外指令制导导弹的预设配置,没有巡航阶段
/// </summary>
public static FlightStageConfig InfraredCommandGuidance => new(true, true, false, true, true);
/// <summary>
/// 红外成像末制导导弹的预设配置
/// </summary>
public static FlightStageConfig InfraredImagingTerminalGuidance => new(true, true, true, true, true);
/// <summary>
/// 毫米波末制导导弹的预设配置
/// </summary>
public static FlightStageConfig MillimeterWaveTerminalGuidance => new(true, true, true, true, true);
/// <summary>
/// 末敏弹的预设配置
/// </summary>
public static FlightStageConfig TerminalSensitiveMissile => new(true, true, false, false, true);
public FlightStageConfig(bool enableLaunch, bool enableAcceleration, bool enableCruise, bool enableTerminalGuidance, bool enableAttack)
{
EnableLaunch = enableLaunch;
EnableAcceleration = enableAcceleration;
EnableCruise = enableCruise;
EnableTerminalGuidance = enableTerminalGuidance;
EnableAttack = enableAttack;
}
}
/// <summary>
/// 激光告警器配置类
/// </summary>
public class LaserWarnerConfig
{
/// <summary>
/// 激光告警器ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 警报持续时间(秒)
/// </summary>
@ -437,6 +379,7 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public LaserWarnerConfig()
{
Id = "";
AlarmDuration = 5.0; // 默认警报持续5秒
}
}
@ -446,6 +389,11 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public class LaserJammerConfig
{
/// <summary>
/// 激光干扰器ID
/// </summary>
public string Id { get; set; }
/// <summary>
/// 最大干扰冷却时间(秒)
/// </summary>
@ -471,6 +419,7 @@ namespace ActiveProtect.SimulationEnvironment
/// </summary>
public LaserJammerConfig()
{
Id = "";
MaxJammingCooldown = 5.0;
MaxJammingPower = 10000.0;
InitialJammingPower = 4000.0;

View File

@ -36,7 +36,7 @@ namespace ActiveProtect.SimulationEnvironment
/// <summary>
/// 仿真管理器的引用
/// </summary>
public ISimulationManager SimulationManager { get; set; }
protected ISimulationManager SimulationManager { get; set; }
/// <summary>
/// 构造函数
@ -51,7 +51,7 @@ namespace ActiveProtect.SimulationEnvironment
Position = position;
Orientation = orientation;
Velocity = orientation.ToVector() * speed;
SimulationManager = simulationManager;
this.SimulationManager = simulationManager;
IsActive = false;
}

View File

@ -98,8 +98,6 @@ namespace ActiveProtect.SimulationEnvironment
public string? DestroyedEntityId { get; set; }
}
/// <summary>
/// 激光告警器警报事件
/// </summary>

View File

@ -96,36 +96,36 @@ namespace ActiveProtect.SimulationEnvironment
for (int i = 0; i < config.TankConfigs.Count; i++)
{
var tankConfig = config.TankConfigs[i];
var tank = new Tank($"Tank_{i + 1}", tankConfig, this);
var tank = new Tank(tankConfig, this);
Elements.Add(tank);
// // 为坦克创建激光告警器
// if (tankConfig.HasLaserWarner)
// {
// var laserWarner = new LaserWarner(
// $"LaserWarner_{tank.Id}",
// tank.Position,
// tank.Orientation,
// this,
// tank.Id,
// config.LaserWarnerConfig
// );
// Elements.Add(laserWarner);
// }
// 为坦克创建激光告警器
if (tankConfig.HasLaserWarner)
{
var laserWarner = new LaserWarner(
$"LW_{i}",
tank.Position,
tank.Orientation,
this,
tank.Id,
config.LaserWarnerConfig
);
Elements.Add(laserWarner);
}
// // 为坦克创建激光干扰机
// if (tankConfig.HasLaserJammer)
// {
// var laserJammer = new LaserJammer(
// $"LaserJammer_{tank.Id}",
// tank.Position,
// tank.Orientation,
// this,
// tank.Id,
// config.LaserJammerConfig
// );
// Elements.Add(laserJammer);
// }
// 为坦克创建激光干扰机
if (tankConfig.HasLaserJammer)
{
var laserJammer = new LaserJammer(
$"LJ_{i}",
tank.Position,
tank.Orientation,
this,
tank.Id,
config.LaserJammerConfig
);
Elements.Add(laserJammer);
}
}
@ -139,16 +139,16 @@ namespace ActiveProtect.SimulationEnvironment
switch (missileConfig.Type)
{
case MissileType.LaserSemiActiveGuidance:
missile = new LaserSemiActiveGuidedMissile($"LSGM_{i + 1}", missileConfig, this);
missile = new LaserSemiActiveGuidedMissile(missileConfig, this);
break;
case MissileType.LaserBeamRiderGuidance:
missile = new LaserBeamRiderMissile($"LBRM_{i + 1}", missileConfig, this);
missile = new LaserBeamRiderMissile(missileConfig, this);
break;
case MissileType.TerminalSensitiveMissile:
missile = new TerminalSensitiveMissile($"TSM_{i + 1}", missileConfig, this);
missile = new TerminalSensitiveMissile(missileConfig, this);
break;
default:
missile = new MissileBase($"M_{i + 1}", missileConfig, this);
missile = new MissileBase(missileConfig, this);
break;
}
@ -175,7 +175,7 @@ namespace ActiveProtect.SimulationEnvironment
var laserBeamRiderConfig = config.LaserBeamRiderConfig;
var laserBeamRider = new LaserBeamRider(
"LBR_1",
"LBRM_2",
"LBRM_1",
"Tank_1",
0,
laserBeamRiderConfig,
@ -185,13 +185,13 @@ namespace ActiveProtect.SimulationEnvironment
// 激活所有元素
// ActivateAllElements();
ActivateAllElements();
// 激活部分元素
ActivateSomeElements();
//ActivateSomeElements();
// 启动激光驾束仪
//laserBeamRider.StartBeamIllumination();
// 激光驾束仪开始照射
laserBeamRider.StartBeamIllumination();
}
@ -209,18 +209,24 @@ namespace ActiveProtect.SimulationEnvironment
// 激活坦克
Elements.FindAll(e => e.Id == "Tank_1").ForEach(e => e.Activate());
// 激活激光告警器
//Elements.FindAll(e => e.Id == "LW_1").ForEach(e => e.Activate());
// 激活激光干扰器
//Elements.FindAll(e => e.Id == "LJ_1").ForEach(e => e.Activate());
// 激活激光半主动制导导弹
//Elements.FindAll(e => e.Id == "LSGM_1").ForEach(e => e.Activate());
// 激活激光目标指示器
//Elements.FindAll(e => e.Id == "LD_1").ForEach(e => e.Activate());
// 激活激光驾束制导导弹
//Elements.FindAll(e => e.Id == "LBRM_2").ForEach(e => e.Activate());
//Elements.FindAll(e => e.Id == "LBRM_1").ForEach(e => e.Activate());
// 激活激光驾束仪
//Elements.FindAll(e => e.Id == "LBR_1").ForEach(e => e.Activate());
// 激活末敏弹
Elements.FindAll(e => e.Id == "TSM_3").ForEach(e => e.Activate());
Elements.FindAll(e => e.Id == "TSM_1").ForEach(e => e.Activate());
}
/// <summary>