修改了末敏弹分离阶段参数和对应逻辑;修改了综合导弹模拟器,添加了激光半主动制导导弹、激光驾束制导导弹、红外成像末制导导弹的模拟;
This commit is contained in:
parent
217f13bbc4
commit
bc73ce758c
@ -236,5 +236,146 @@ namespace ThreatSource.Tests.Missile
|
||||
_output.WriteLine($"修正后的水平方向: {horizontalCorrectedDirection}");
|
||||
_output.WriteLine($"修正后的水平夹角: {correctedHorizontalAngle:F2}°");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0, 0, 0, 44, 76.5, 0)] // 原点场景
|
||||
[InlineData(100, 0, 0, 144, 76.5, 0)] // X轴平移
|
||||
[InlineData(0, 0, 100, 44, 76.5, 100)] // Z轴平移
|
||||
[InlineData(100, 0, 100, 144, 76.5, 100)] // XZ平面平移
|
||||
public void TestTargetDetectionAtDifferentPositions(
|
||||
double targetX, double targetY, double targetZ,
|
||||
double submunitionX, double submunitionY, double submunitionZ)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 设置目标位置
|
||||
var targetPosition = new Vector3D(targetX, targetY, targetZ);
|
||||
_tank.Position = targetPosition;
|
||||
|
||||
// 设置子弹位置
|
||||
var submunitionPosition = new Vector3D(submunitionX, submunitionY, submunitionZ);
|
||||
_submunition.Position = submunitionPosition;
|
||||
|
||||
// 计算从子弹到目标的向量
|
||||
var toTarget = (targetPosition - submunitionPosition).Normalize();
|
||||
|
||||
// 设置子弹的扫描方向直接指向目标
|
||||
var scanDirection = toTarget;
|
||||
var field = typeof(TerminalSensitiveSubmunition)
|
||||
.GetField("scanDirection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
|
||||
if (field == null)
|
||||
{
|
||||
_output.WriteLine("无法找到scanDirection字段");
|
||||
Assert.Fail("无法找到scanDirection字段");
|
||||
return;
|
||||
}
|
||||
|
||||
field.SetValue(_submunition, scanDirection);
|
||||
|
||||
// 执行目标检测
|
||||
var detectionResult = _submunition.DetectTarget(30); // 30度视场角
|
||||
|
||||
// 输出测试信息
|
||||
_output.WriteLine($"\n=== 测试场景 ===");
|
||||
_output.WriteLine($"目标位置: ({targetX}, {targetY}, {targetZ})");
|
||||
_output.WriteLine($"子弹位置: ({submunitionX}, {submunitionY}, {submunitionZ})");
|
||||
_output.WriteLine($"相对位置向量: {toTarget}");
|
||||
_output.WriteLine($"扫描方向: {scanDirection}");
|
||||
_output.WriteLine($"检测结果: {(detectionResult.Target != null ? "已检测到目标" : "未检测到目标")}");
|
||||
|
||||
if (detectionResult.Target != null)
|
||||
{
|
||||
_output.WriteLine($"目标方位角: {detectionResult.Angle * 180 / Math.PI:F2}度");
|
||||
}
|
||||
else
|
||||
{
|
||||
_output.WriteLine("警告:未检测到目标!");
|
||||
}
|
||||
|
||||
// 验证检测结果
|
||||
Assert.True(detectionResult.Target != null, $"在位置({targetX}, {targetY}, {targetZ})处未能检测到目标");
|
||||
Assert.True(detectionResult.Angle.HasValue, "检测结果中没有方位角信息");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_output.WriteLine($"\n发生异常: {ex.Message}");
|
||||
_output.WriteLine($"堆栈跟踪: {ex.StackTrace}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0, 0, 0)] // 原点场景
|
||||
[InlineData(100, 0, 0)] // X轴平移
|
||||
[InlineData(0, 0, 100)] // Z轴平移
|
||||
[InlineData(100, 0, 100)] // XZ平面平移
|
||||
public void TestScanningAtFixedHeight(double targetX, double targetY, double targetZ)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 设置目标位置
|
||||
var targetPosition = new Vector3D(targetX, targetY, targetZ);
|
||||
_tank.Position = targetPosition;
|
||||
|
||||
// 设置子弹位置和速度(只有垂直下降速度-10m/s)
|
||||
_submunition.Position = new Vector3D(targetX + 44, 210, targetZ);
|
||||
_submunition.Velocity = new Vector3D(0, -10, 0); // 设置速度为(0,-10,0)
|
||||
|
||||
// 记录初始状态
|
||||
_output.WriteLine($"\n=== 初始状态 ===");
|
||||
_output.WriteLine($"目标位置: {targetPosition}");
|
||||
_output.WriteLine($"子弹位置: {_submunition.Position}");
|
||||
_output.WriteLine($"相对位置: {(targetPosition - _submunition.Position)}");
|
||||
_output.WriteLine($"子弹速度: {_submunition.Velocity}");
|
||||
|
||||
// 激活子弹
|
||||
_submunition.Activate();
|
||||
|
||||
// 运行1000步扫描,每步0.002秒
|
||||
const double deltaTime = 0.002;
|
||||
const int totalSteps = 1000;
|
||||
bool targetDetected = false;
|
||||
int firstDetectionStep = -1;
|
||||
|
||||
for (int i = 0; i < totalSteps; i++)
|
||||
{
|
||||
_submunition.Update(deltaTime);
|
||||
|
||||
// 检查是否进入制导
|
||||
if (_submunition.IsGuidance && !targetDetected)
|
||||
{
|
||||
targetDetected = true;
|
||||
firstDetectionStep = i;
|
||||
_output.WriteLine($"\n=== 首次检测到目标!===");
|
||||
_output.WriteLine($"检测步数: {i} (时间: {i * deltaTime:F3}秒)");
|
||||
_output.WriteLine($"当前子弹位置: {_submunition.Position}");
|
||||
_output.WriteLine($"当前子弹速度: {_submunition.Velocity}");
|
||||
}
|
||||
|
||||
if (i % 500 == 0) // 每1秒(500步)输出一次状态
|
||||
{
|
||||
_output.WriteLine($"\n=== 第{i}步扫描 (时间: {i * deltaTime:F3}秒) ===");
|
||||
_output.WriteLine(_submunition.GetStatus());
|
||||
}
|
||||
}
|
||||
|
||||
// 验证是否检测到目标
|
||||
Assert.True(targetDetected, $"在位置({targetX}, {targetY}, {targetZ})处未能检测到目标");
|
||||
|
||||
// 输出扫描统计信息
|
||||
_output.WriteLine($"\n=== 扫描统计 ===");
|
||||
_output.WriteLine($"总扫描步数: {totalSteps}");
|
||||
_output.WriteLine($"总扫描时间: {totalSteps * deltaTime:F3}秒");
|
||||
_output.WriteLine($"首次检测步数: {firstDetectionStep}");
|
||||
_output.WriteLine($"首次检测时间: {firstDetectionStep * deltaTime:F3}秒");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_output.WriteLine($"\n发生异常: {ex.Message}");
|
||||
_output.WriteLine($"堆栈跟踪: {ex.StackTrace}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -43,6 +43,16 @@ namespace ThreatSource.Missile
|
||||
/// </remarks>
|
||||
private const double SeparationDistance = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// 子弹分离角度(与地面的夹角)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 单位:度
|
||||
/// 子弹从母弹分离时与地面的夹角
|
||||
/// 默认设置为60度
|
||||
/// </remarks>
|
||||
private const double SubmunitionSeparationAngle = 45;
|
||||
|
||||
/// <summary>
|
||||
/// 触发分离的距离阈值
|
||||
/// </summary>
|
||||
@ -225,19 +235,32 @@ namespace ThreatSource.Missile
|
||||
Console.WriteLine($"开始分离,当前位置:{Position},分离点:{separationPoint}");
|
||||
Debug.WriteLine($"开始分离,当前位置:{Position},分离点:{separationPoint}");
|
||||
|
||||
// 获取目标位置
|
||||
SimulationElement target = SimulationManager.GetEntityById(TargetId) as SimulationElement ?? throw new Exception("目标不存在");
|
||||
Vector3D targetPosition = target.Position;
|
||||
Console.WriteLine($"目标位置:{targetPosition}");
|
||||
Debug.WriteLine($"目标位置:{targetPosition}");
|
||||
// 获取母弹当前的方向向量
|
||||
Vector3D currentDirection = Orientation.ToVector();
|
||||
|
||||
// 计算子弹朝向目标的方向
|
||||
Vector3D directionToTarget = (targetPosition - this.Position).Normalize();
|
||||
Orientation orientationToTarget = Orientation.FromVector(directionToTarget);
|
||||
Console.WriteLine($"子弹朝向:{directionToTarget}");
|
||||
Debug.WriteLine($"子弹朝向:{directionToTarget}");
|
||||
// 计算水平方向(保持母弹的水平方向分量)
|
||||
Vector3D horizontalDirection = new Vector3D(currentDirection.X, 0, currentDirection.Z).Normalize();
|
||||
|
||||
// 创建并释子弹
|
||||
// 计算分离角度(弧度)
|
||||
double separationAngleRad = SubmunitionSeparationAngle * Math.PI / 180.0;
|
||||
|
||||
// 计算子弹的初始方向(保持水平方向不变,设置垂直角度为-60度)
|
||||
Vector3D initialDirection = new Vector3D(
|
||||
horizontalDirection.X,
|
||||
-Math.Tan(separationAngleRad), // 负号表示向下的60度角
|
||||
horizontalDirection.Z
|
||||
).Normalize();
|
||||
|
||||
// 根据新方向创建朝向
|
||||
Orientation separationOrientation = Orientation.FromVector(initialDirection);
|
||||
Console.WriteLine($"母弹当前方向:{currentDirection}");
|
||||
Console.WriteLine($"子弹分离角度:{SubmunitionSeparationAngle}度(向下)");
|
||||
Console.WriteLine($"子弹初始方向:{initialDirection}");
|
||||
Debug.WriteLine($"母弹当前方向:{currentDirection}");
|
||||
Debug.WriteLine($"子弹分离角度:{SubmunitionSeparationAngle}度(向下)");
|
||||
Debug.WriteLine($"子弹初始方向:{initialDirection}");
|
||||
|
||||
// 创建并释放子弹
|
||||
for (int i = 0; i < SubmunitionCount; i++)
|
||||
{
|
||||
Console.WriteLine($"创建子弹 {i}");
|
||||
@ -248,7 +271,7 @@ namespace ThreatSource.Missile
|
||||
{
|
||||
Id = $"{Id}_Sub_{i}",
|
||||
InitialPosition = Position,
|
||||
InitialOrientation = Orientation, // 子弹初始方向等于母弹方向
|
||||
InitialOrientation = separationOrientation, // 使用新计算的分离方向
|
||||
InitialSpeed = Velocity.Magnitude(), // 子弹初始速度等于母弹速度
|
||||
MaxSpeed = 2000,
|
||||
MaxFlightTime = 100,
|
||||
|
||||
@ -75,13 +75,13 @@ namespace ThreatSource.Missile
|
||||
private SubmunitionStage currentStage;
|
||||
|
||||
/// <summary>
|
||||
/// 螺旋扫描旋转速度,单位:弧度/秒
|
||||
/// 减速加速度,单位:米/秒²
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 定义了螺旋扫描时的旋转角速度
|
||||
/// 4转/秒 = 8π弧度/秒
|
||||
/// 减速阶段的减速度大小
|
||||
/// 影响速度调整的快慢
|
||||
/// </remarks>
|
||||
private const double SpiralRotationSpeed = 8 * Math.PI;
|
||||
private const double DecelerationAcceleration = 250;
|
||||
|
||||
/// <summary>
|
||||
/// 减速阶段末速,单位:米/秒
|
||||
@ -89,15 +89,32 @@ namespace ThreatSource.Missile
|
||||
/// <remarks>
|
||||
/// 定义了减速阶段的垂直下降速度
|
||||
/// </remarks>
|
||||
private const double DecelerationEndSpeed = 40;
|
||||
private const double DecelerationEndSpeed = 50;
|
||||
|
||||
/// <summary>
|
||||
/// 开伞高度,单位:米
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 打开降落伞的高度阈值
|
||||
/// 影响降落伞打开阶段的触发时机
|
||||
/// </remarks>
|
||||
private const double ParachuteDeploymentHeight = 400;
|
||||
/// <summary>
|
||||
/// 降落伞减速加速度,单位:米/秒²
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 定义了降落伞减速加速度
|
||||
/// </remarks>
|
||||
private const double ParachuteDeceleration = 50;
|
||||
private const double ParachuteDeceleration = 140;
|
||||
|
||||
/// <summary>
|
||||
/// 稳定扫描高度,单位:米
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 开始螺旋扫描的高度阈值
|
||||
/// 影响扫描阶段的触发时机
|
||||
/// </remarks>
|
||||
private const double StableScanHeight = 200;
|
||||
|
||||
/// <summary>
|
||||
/// 垂直下降速度,单位:米/秒
|
||||
@ -107,6 +124,15 @@ namespace ThreatSource.Missile
|
||||
/// </remarks>
|
||||
private const double VerticalDeclineSpeed = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 螺旋扫描旋转速度,单位:弧度/秒
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 定义了螺旋扫描时的旋转角速度
|
||||
/// 4转/秒 = 8π弧度/秒
|
||||
/// </remarks>
|
||||
private const double SpiralRotationSpeed = 8 * Math.PI;
|
||||
|
||||
/// <summary>
|
||||
/// 扫描角度,单位:弧度
|
||||
/// </summary>
|
||||
@ -116,33 +142,6 @@ namespace ThreatSource.Missile
|
||||
/// </remarks>
|
||||
public const double ScanAngle = 30 * Math.PI / 180;
|
||||
|
||||
/// <summary>
|
||||
/// 开伞高度,单位:米
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 打开降落伞的高度阈值
|
||||
/// 影响降落伞打开阶段的触发时机
|
||||
/// </remarks>
|
||||
private const double ParachuteDeploymentHeight = 400;
|
||||
|
||||
/// <summary>
|
||||
/// 减速加速度,单位:米/秒²
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 减速阶段的减速度大小
|
||||
/// 影响速度调整的快慢
|
||||
/// </remarks>
|
||||
private const double DecelerationAcceleration = 50;
|
||||
|
||||
/// <summary>
|
||||
/// 稳定扫描高度,单位:米
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 开始螺旋扫描的高度阈值
|
||||
/// 影响扫描阶段的触发时机
|
||||
/// </remarks>
|
||||
private const double StableScanHeight = 200;
|
||||
|
||||
/// <summary>
|
||||
/// 目标探测距离,单位:米
|
||||
/// </summary>
|
||||
@ -386,7 +385,8 @@ namespace ThreatSource.Missile
|
||||
|
||||
if (Velocity.Magnitude() <= DecelerationEndSpeed)
|
||||
{
|
||||
Velocity = new Vector3D(0, -DecelerationEndSpeed, 0);
|
||||
//垂直速度设为减速阶段末速
|
||||
Velocity = new Vector3D(Velocity.X, -DecelerationEndSpeed, Velocity.Z);
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
}
|
||||
|
||||
@ -402,6 +402,10 @@ namespace ThreatSource.Missile
|
||||
{
|
||||
// 如果是,则进入降落伞打开阶段
|
||||
currentStage = SubmunitionStage.ParachuteDeployment;
|
||||
|
||||
//垂直速度设为减速阶段末速
|
||||
Velocity = new Vector3D(Velocity.X, -DecelerationEndSpeed, Velocity.Z);
|
||||
GuidanceAcceleration = Vector3D.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
@ -850,6 +854,7 @@ namespace ThreatSource.Missile
|
||||
$"运行状态: {currentStage}\n" +
|
||||
$"扫描角度: {spiralAngle * 180 / Math.PI:F2}°, 弧度值: {spiralAngle:F6}\n" +
|
||||
$"目标检测: {lastDetectionTime != null}\n" +
|
||||
$"目标位置: {target.Position}\n" +
|
||||
$"目标距离: {distanceToTarget:F2}米\n" +
|
||||
$"传感器状态: {(IsSensorsJammed() ? "传感器受到干扰" : "正常工作")}";
|
||||
|
||||
|
||||
546
tools/ComprehensiveMissileSimulator.cs
Normal file
546
tools/ComprehensiveMissileSimulator.cs
Normal file
@ -0,0 +1,546 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Linq;
|
||||
using ThreatSource.Missile;
|
||||
using ThreatSource.Simulation;
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Jamming;
|
||||
using ThreatSource.Sensor;
|
||||
using ThreatSource.Target;
|
||||
using ThreatSource.Guidance;
|
||||
using ThreatSource.Indicator;
|
||||
|
||||
namespace ThreatSource.Tools.MissileSimulation
|
||||
{
|
||||
/// <summary>
|
||||
/// 综合导弹模拟器 - 支持6种不同类型的导弹模拟
|
||||
/// </summary>
|
||||
public class ComprehensiveMissileSimulator
|
||||
{
|
||||
// 定义仿真结束事件
|
||||
public event EventHandler? SimulationEnded;
|
||||
|
||||
private readonly ISimulationManager simulationManager;
|
||||
private readonly Dictionary<string, SimulationElement> missiles;
|
||||
private readonly Dictionary<string, SimulationElement> targets;
|
||||
private readonly Dictionary<string, SimulationElement> sensors;
|
||||
private Dictionary<string, bool> missileActiveStatus;
|
||||
private bool isRunning;
|
||||
private readonly double timeStep = 0.002; // 时间步长,单位:秒
|
||||
|
||||
/// <summary>
|
||||
/// 初始化综合导弹模拟器
|
||||
/// </summary>
|
||||
public ComprehensiveMissileSimulator()
|
||||
{
|
||||
simulationManager = new SimulationManager();
|
||||
missiles = new Dictionary<string, SimulationElement>();
|
||||
targets = new Dictionary<string, SimulationElement>();
|
||||
sensors = new Dictionary<string, SimulationElement>();
|
||||
missileActiveStatus = new Dictionary<string, bool>();
|
||||
isRunning = false;
|
||||
InitializeSimulation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化仿真环境
|
||||
/// </summary>
|
||||
private void InitializeSimulation()
|
||||
{
|
||||
// 添加目标(坦克)
|
||||
AddTarget("Tank_1", new Vector3D(0, 0, 0));
|
||||
|
||||
// 添加各种类型的导弹
|
||||
AddLaserSemiActiveMissile();
|
||||
AddLaserBeamRiderMissile();
|
||||
AddTerminalSensitiveMissile();
|
||||
AddInfraredCommandMissile();
|
||||
AddInfraredImagingMissile();
|
||||
AddMillimeterWaveMissile();
|
||||
|
||||
// 添加各种传感器和指示器
|
||||
AddSensorsAndDesignators();
|
||||
|
||||
// 初始化所有导弹的激活状态为false
|
||||
foreach (var missile in missiles.Keys)
|
||||
{
|
||||
missileActiveStatus[missile] = false;
|
||||
missiles[missile].Activate(); // 激活导弹,但不会更新状态
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加目标
|
||||
/// </summary>
|
||||
private void AddTarget(string targetId, Vector3D position)
|
||||
{
|
||||
var target = new Tank(targetId, position, 0, simulationManager)
|
||||
{
|
||||
Position = position
|
||||
};
|
||||
targets[targetId] = target;
|
||||
simulationManager.RegisterEntity(targetId, target);
|
||||
Console.WriteLine($"添加目标 {targetId},位置:{position}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加激光半主动制导导弹
|
||||
/// </summary>
|
||||
private void AddLaserSemiActiveMissile()
|
||||
{
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "LSGM_1",
|
||||
Mass = 50,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 800,
|
||||
MaxFlightTime = 10,
|
||||
MaxFlightDistance = 5000,
|
||||
MaxAcceleration = 400,
|
||||
InitialPosition = new Vector3D(2000, 100, 100),
|
||||
InitialSpeed = 700,
|
||||
InitialOrientation = new Orientation(Math.PI, -0.1, 0),
|
||||
Type = MissileType.LaserSemiActiveGuidance
|
||||
};
|
||||
|
||||
var missile = new LaserSemiActiveGuidedMissile(properties, simulationManager);
|
||||
missiles["LSGM_1"] = missile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加激光驾束制导导弹
|
||||
/// </summary>
|
||||
private void AddLaserBeamRiderMissile()
|
||||
{
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "LBRM_1",
|
||||
Mass = 50,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 400,
|
||||
MaxFlightTime = 10,
|
||||
MaxFlightDistance = 3000,
|
||||
MaxAcceleration = 400,
|
||||
InitialPosition = new Vector3D(2000, 10, 100),
|
||||
InitialSpeed = 300,
|
||||
InitialOrientation = new Orientation(Math.PI, 0.0, 0.0),
|
||||
Type = MissileType.LaserBeamRiderGuidance
|
||||
};
|
||||
|
||||
var missile = new LaserBeamRiderMissile(properties, simulationManager);
|
||||
missiles["LBRM_1"] = missile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加末敏弹
|
||||
/// </summary>
|
||||
private void AddTerminalSensitiveMissile()
|
||||
{
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "TSM_1",
|
||||
Mass = 50,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 1000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 5000,
|
||||
MaxAcceleration = 200,
|
||||
InitialPosition = new Vector3D(3000, 0, 0),
|
||||
InitialSpeed = 800,
|
||||
InitialOrientation = new Orientation(Math.PI, 0, 0),
|
||||
Type = MissileType.TerminalSensitiveMissile
|
||||
};
|
||||
|
||||
var missile = new TerminalSensitiveMissile("Tank_1", properties, simulationManager);
|
||||
missiles["TSM_1"] = missile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加红外指令制导导弹
|
||||
/// </summary>
|
||||
private void AddInfraredCommandMissile()
|
||||
{
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "ICGM_1",
|
||||
Mass = 50,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 400,
|
||||
MaxFlightTime = 60,
|
||||
MaxFlightDistance = 5000,
|
||||
MaxAcceleration = 100,
|
||||
InitialPosition = new Vector3D(2000, 10, 100),
|
||||
InitialSpeed = 300,
|
||||
InitialOrientation = new Orientation(Math.PI, 0.0, 0),
|
||||
Type = MissileType.InfraredCommandGuidance
|
||||
};
|
||||
|
||||
var missile = new InfraredCommandGuidedMissile(properties, simulationManager);
|
||||
missiles["ICGM_1"] = missile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加红外成像末制导导弹
|
||||
/// </summary>
|
||||
private void AddInfraredImagingMissile()
|
||||
{
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "ITGM_1",
|
||||
Mass = 50,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 400,
|
||||
MaxFlightTime = 60,
|
||||
MaxFlightDistance = 5000,
|
||||
MaxAcceleration = 50,
|
||||
InitialPosition = new Vector3D(2000, 20, 100),
|
||||
InitialSpeed = 300,
|
||||
InitialOrientation = new Orientation(Math.PI, 0.0, 0),
|
||||
Type = MissileType.InfraredImagingTerminalGuidance
|
||||
};
|
||||
|
||||
var missile = new InfraredImagingTerminalGuidedMissile(properties, simulationManager);
|
||||
missiles["ITGM_1"] = missile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加毫米波末制导导弹
|
||||
/// </summary>
|
||||
private void AddMillimeterWaveMissile()
|
||||
{
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Id = "MMWG_1",
|
||||
Mass = 50,
|
||||
ExplosionRadius = 5,
|
||||
MaxSpeed = 400,
|
||||
MaxFlightTime = 60,
|
||||
MaxFlightDistance = 5000,
|
||||
MaxAcceleration = 50,
|
||||
InitialPosition = new Vector3D(2000, 200, 100),
|
||||
InitialSpeed = 300,
|
||||
InitialOrientation = new Orientation(Math.PI, 0.0, 0),
|
||||
Type = MissileType.MillimeterWaveTerminalGuidance
|
||||
};
|
||||
|
||||
var missile = new MillimeterWaveTerminalGuidedMissile(properties, simulationManager);
|
||||
missiles["MMWG_1"] = missile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加传感器和指示器
|
||||
/// </summary>
|
||||
private void AddSensorsAndDesignators()
|
||||
{
|
||||
// 添加激光目标指示器
|
||||
var laserDesignator = new LaserDesignator(
|
||||
"LD_1",
|
||||
"Tank_1",
|
||||
"LSGM_1",
|
||||
0,
|
||||
new LaserDesignatorConfig
|
||||
{
|
||||
Id = "LD_1",
|
||||
InitialPosition = new Vector3D(2000, 150, 100),
|
||||
LaserPower = 1e6,
|
||||
LaserDivergenceAngle = 0.01
|
||||
},
|
||||
simulationManager
|
||||
);
|
||||
sensors["LD_1"] = laserDesignator;
|
||||
|
||||
// 添加激光驾束仪
|
||||
var laserBeamRider = new LaserBeamRider(
|
||||
"LBR_1",
|
||||
"LBRM_1",
|
||||
"Tank_1",
|
||||
0,
|
||||
new LaserBeamRiderConfig
|
||||
{
|
||||
Id = "LBR_1",
|
||||
InitialPosition = new Vector3D(2000, 10, 100),
|
||||
LaserPower = 1000,
|
||||
ControlFieldDiameter = 6
|
||||
},
|
||||
simulationManager
|
||||
);
|
||||
sensors["LBR_1"] = laserBeamRider;
|
||||
|
||||
// 添加红外测角仪
|
||||
var infraredTracker = new InfraredTracker(
|
||||
"IT_1",
|
||||
"Tank_1",
|
||||
new InfraredTrackerConfig
|
||||
{
|
||||
Id = "IT_1",
|
||||
InitialPosition = new Vector3D(2000, 0, 100),
|
||||
InitialOrientation = new Orientation(Math.PI, 0, 0),
|
||||
MaxTrackingRange = 10000,
|
||||
FieldOfView = Math.PI / 4,
|
||||
AngleMeasurementAccuracy = 0.0005,
|
||||
UpdateFrequency = 100
|
||||
},
|
||||
simulationManager
|
||||
);
|
||||
sensors["IT_1"] = infraredTracker;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选择要激活的导弹
|
||||
/// </summary>
|
||||
public void SelectMissile(string missileId)
|
||||
{
|
||||
if (!missiles.ContainsKey(missileId))
|
||||
{
|
||||
Console.WriteLine($"错误:找不到导弹 {missileId}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 重置所有导弹的激活状态
|
||||
foreach (var id in missiles.Keys)
|
||||
{
|
||||
missileActiveStatus[id] = false;
|
||||
}
|
||||
|
||||
// 激活选中的导弹
|
||||
missileActiveStatus[missileId] = true;
|
||||
Console.WriteLine($"已选择导弹:{missileId}");
|
||||
|
||||
// 激活相关的传感器和指示器
|
||||
ActivateRelatedSensors(missileId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 激活与导弹相关的传感器和指示器
|
||||
/// </summary>
|
||||
private void ActivateRelatedSensors(string missileId)
|
||||
{
|
||||
// 停用所有传感器
|
||||
foreach (var sensor in sensors.Values)
|
||||
{
|
||||
sensor.Deactivate();
|
||||
}
|
||||
|
||||
// 根据导弹类型激活相应的传感器
|
||||
switch (missileId)
|
||||
{
|
||||
case "LSGM_1": // 激光半主动制导导弹
|
||||
if (sensors.ContainsKey("LD_1"))
|
||||
{
|
||||
sensors["LD_1"].Activate();
|
||||
}
|
||||
break;
|
||||
case "LBRM_1": // 激光驾束制导导弹
|
||||
if (sensors.ContainsKey("LBR_1"))
|
||||
{
|
||||
sensors["LBR_1"].Activate();
|
||||
}
|
||||
break;
|
||||
case "ICGM_1": // 红外指令制导导弹
|
||||
case "ITGM_1": // 红外成像末制导导弹
|
||||
if (sensors.ContainsKey("IT_1"))
|
||||
{
|
||||
sensors["IT_1"].Activate();
|
||||
}
|
||||
break;
|
||||
case "TSM_1": // 末敏弹
|
||||
case "MMWG_1": // 毫米波末制导导弹
|
||||
// 这些导弹使用自身的传感器系统
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用干扰
|
||||
/// </summary>
|
||||
public void ApplyJamming(JammingType type, double power, double duration, Vector3D position)
|
||||
{
|
||||
var jammingParams = new JammingParameters
|
||||
{
|
||||
Type = type,
|
||||
Power = power,
|
||||
Duration = duration,
|
||||
Direction = new Vector3D(1, 0, 0)
|
||||
};
|
||||
|
||||
foreach (var missile in missiles.Values)
|
||||
{
|
||||
if (missile is BaseMissile actualMissile)
|
||||
{
|
||||
// 获取导弹内部的传感器
|
||||
var infraredDetector = actualMissile.GetType().GetField("infraredDetector", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(actualMissile) as InfraredDetector;
|
||||
var radiometer = actualMissile.GetType().GetField("radiometer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(actualMissile) as MillimeterWaveRadiometer;
|
||||
var rangefinder = actualMissile.GetType().GetField("rangefinder", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(actualMissile) as LaserRangefinder;
|
||||
var altimeter = actualMissile.GetType().GetField("altimeter", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(actualMissile) as MillimeterWaveAltimeter;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case JammingType.Infrared:
|
||||
infraredDetector?.ApplyJamming(jammingParams);
|
||||
break;
|
||||
case JammingType.MillimeterWave:
|
||||
radiometer?.ApplyJamming(jammingParams);
|
||||
altimeter?.ApplyJamming(jammingParams);
|
||||
break;
|
||||
case JammingType.Laser:
|
||||
rangefinder?.ApplyJamming(jammingParams);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除干扰
|
||||
/// </summary>
|
||||
public void ClearJamming(JammingType type)
|
||||
{
|
||||
var jammingParams = new JammingParameters
|
||||
{
|
||||
Type = type,
|
||||
Power = 0,
|
||||
Duration = 0,
|
||||
Direction = new Vector3D(1, 0, 0)
|
||||
};
|
||||
|
||||
foreach (var missile in missiles.Values)
|
||||
{
|
||||
if (missile is BaseMissile actualMissile)
|
||||
{
|
||||
// 获取导弹内部的传感器
|
||||
var infraredDetector = actualMissile.GetType().GetField("infraredDetector", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(actualMissile) as InfraredDetector;
|
||||
var radiometer = actualMissile.GetType().GetField("radiometer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(actualMissile) as MillimeterWaveRadiometer;
|
||||
var rangefinder = actualMissile.GetType().GetField("rangefinder", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(actualMissile) as LaserRangefinder;
|
||||
var altimeter = actualMissile.GetType().GetField("altimeter", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(actualMissile) as MillimeterWaveAltimeter;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case JammingType.Infrared:
|
||||
infraredDetector?.ClearJamming(type);
|
||||
break;
|
||||
case JammingType.MillimeterWave:
|
||||
radiometer?.ClearJamming(type);
|
||||
altimeter?.ClearJamming(type);
|
||||
break;
|
||||
case JammingType.Laser:
|
||||
rangefinder?.ClearJamming(type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始模拟
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
isRunning = true;
|
||||
bool hasActiveEntities = true;
|
||||
Console.WriteLine("开始综合导弹模拟...");
|
||||
|
||||
while (isRunning)
|
||||
{
|
||||
hasActiveEntities = false;
|
||||
// 更新所有导弹
|
||||
foreach (var missile in missiles.Values)
|
||||
{
|
||||
if (missile.IsActive && missileActiveStatus[missile.Id])
|
||||
{
|
||||
hasActiveEntities = true;
|
||||
missile.Update(timeStep);
|
||||
Console.WriteLine($"\n导弹状态:\n{missile.GetStatus()}");
|
||||
}
|
||||
}
|
||||
|
||||
// 获取并更新所有子弹
|
||||
var allEntities = simulationManager.GetAllEntities();
|
||||
foreach (var entity in allEntities)
|
||||
{
|
||||
if (entity is TerminalSensitiveSubmunition submunition && submunition.IsActive)
|
||||
{
|
||||
hasActiveEntities = true;
|
||||
submunition.Update(timeStep);
|
||||
Console.WriteLine($"\n子弹状态:\n{submunition.GetStatus()}");
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有活动的导弹和子弹,退出模拟
|
||||
if (!hasActiveEntities)
|
||||
{
|
||||
isRunning = false;
|
||||
// 触发仿真结束事件
|
||||
SimulationEnded?.Invoke(this, EventArgs.Empty);
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (var target in targets.Values)
|
||||
{
|
||||
target.Update(timeStep);
|
||||
}
|
||||
|
||||
foreach (var sensor in sensors.Values)
|
||||
{
|
||||
if (sensor.IsActive)
|
||||
{
|
||||
sensor.Update(timeStep);
|
||||
}
|
||||
}
|
||||
|
||||
Thread.Sleep((int)(timeStep * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止模拟
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
isRunning = false;
|
||||
Console.WriteLine("模拟结束");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前活动的传感器列表
|
||||
/// </summary>
|
||||
public (string Id, string Name, bool IsActive)[] GetActiveSensors()
|
||||
{
|
||||
return sensors.Select(s => (
|
||||
s.Value.Id,
|
||||
GetSensorDisplayName(s.Value),
|
||||
s.Value.IsActive
|
||||
)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取传感器的显示名称
|
||||
/// </summary>
|
||||
private string GetSensorDisplayName(SimulationElement sensor)
|
||||
{
|
||||
return sensor switch
|
||||
{
|
||||
LaserDesignator _ => "激光目标指示器",
|
||||
LaserBeamRider _ => "激光驾束仪",
|
||||
InfraredTracker _ => "红外测角仪",
|
||||
_ => sensor.Id
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切换传感器的激活状态
|
||||
/// </summary>
|
||||
public void ToggleSensor(string sensorId)
|
||||
{
|
||||
if (sensors.TryGetValue(sensorId, out var sensor))
|
||||
{
|
||||
if (sensor.IsActive)
|
||||
sensor.Deactivate();
|
||||
else
|
||||
sensor.Activate();
|
||||
|
||||
Console.WriteLine($"传感器 {GetSensorDisplayName(sensor)} 已{(sensor.IsActive ? "激活" : "停用")}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,217 +0,0 @@
|
||||
using ThreatSource.Missile;
|
||||
using ThreatSource.Simulation;
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Jamming;
|
||||
using ThreatSource.Sensor;
|
||||
using ThreatSource.Target;
|
||||
namespace ThreatSource.Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// 导弹模拟程序
|
||||
/// </summary>
|
||||
public class MissileSimulator
|
||||
{
|
||||
private readonly ISimulationManager simulationManager;
|
||||
private readonly List<TerminalSensitiveSubmunition> missiles;
|
||||
private readonly List<SimulationElement> targets;
|
||||
private bool isRunning;
|
||||
private readonly double timeStep = 0.0025; // 时间步长,单位:秒
|
||||
|
||||
/// <summary>
|
||||
/// 初始化导弹模拟器
|
||||
/// </summary>
|
||||
public MissileSimulator()
|
||||
{
|
||||
simulationManager = new SimulationManager();
|
||||
missiles = new List<TerminalSensitiveSubmunition>();
|
||||
targets = new List<SimulationElement>();
|
||||
isRunning = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加目标
|
||||
/// </summary>
|
||||
/// <param name="position">目标位置</param>
|
||||
/// <returns>目标ID</returns>
|
||||
public string AddTarget(Vector3D position)
|
||||
{
|
||||
string targetId = $"target_{targets.Count + 1}";
|
||||
var target = new MockTarget(targetId, simulationManager)
|
||||
{
|
||||
Position = position
|
||||
};
|
||||
targets.Add(target);
|
||||
simulationManager.RegisterEntity(targetId, target);
|
||||
Console.WriteLine($"添加目标 {targetId},位置:{position}");
|
||||
return targetId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发射导弹
|
||||
/// </summary>
|
||||
/// <param name="targetId">目标ID</param>
|
||||
/// <param name="position">发射位置</param>
|
||||
public void LaunchMissile(string targetId, Vector3D position)
|
||||
{
|
||||
var properties = new MissileProperties
|
||||
{
|
||||
Mass = 10,
|
||||
ExplosionRadius = 0.1,
|
||||
MaxSpeed = 2000,
|
||||
MaxFlightTime = 100,
|
||||
MaxFlightDistance = 5000,
|
||||
MaxAcceleration = 200,
|
||||
InitialPosition = position,
|
||||
InitialSpeed = 80,
|
||||
InitialOrientation = new Orientation(0, -Math.PI/2, 0) // 垂直向下
|
||||
};
|
||||
|
||||
var missile = new TerminalSensitiveSubmunition(targetId, properties, simulationManager);
|
||||
missile.Activate();
|
||||
missiles.Add(missile);
|
||||
Console.WriteLine($"发射导弹,目标:{targetId},位置:{position}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 应用干扰
|
||||
/// </summary>
|
||||
/// <param name="type">干扰类型</param>
|
||||
/// <param name="power">干扰功率</param>
|
||||
/// <param name="duration">持续时间</param>
|
||||
/// <param name="position">干扰源位置</param>
|
||||
public void ApplyJamming(JammingType type, double power, double duration, Vector3D position)
|
||||
{
|
||||
var jammingParams = new JammingParameters
|
||||
{
|
||||
Type = type,
|
||||
Power = power,
|
||||
Duration = duration,
|
||||
Direction = new Vector3D(1, 0, 0)
|
||||
};
|
||||
|
||||
foreach (var missile in missiles)
|
||||
{
|
||||
// 获取导弹内部的传感器
|
||||
var infraredDetector = missile.GetType().GetField("infraredDetector", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(missile) as InfraredDetector;
|
||||
var radiometer = missile.GetType().GetField("radiometer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(missile) as MillimeterWaveRadiometer;
|
||||
var rangefinder = missile.GetType().GetField("rangefinder", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(missile) as LaserRangefinder;
|
||||
var altimeter = missile.GetType().GetField("altimeter", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(missile) as MillimeterWaveAltimeter;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case JammingType.Infrared:
|
||||
infraredDetector?.ApplyJamming(jammingParams);
|
||||
break;
|
||||
case JammingType.MillimeterWave:
|
||||
radiometer?.ApplyJamming(jammingParams);
|
||||
altimeter?.ApplyJamming(jammingParams);
|
||||
break;
|
||||
case JammingType.Laser:
|
||||
rangefinder?.ApplyJamming(jammingParams);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"应用{type}干扰,功率:{power}瓦特,持续时间:{duration}秒,位置:{position}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除干扰
|
||||
/// </summary>
|
||||
/// <param name="type">干扰类型</param>
|
||||
public void ClearJamming(JammingType type)
|
||||
{
|
||||
foreach (var missile in missiles)
|
||||
{
|
||||
// 获取导弹内部的传感器
|
||||
var infraredDetector = missile.GetType().GetField("infraredDetector", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(missile) as InfraredDetector;
|
||||
var radiometer = missile.GetType().GetField("radiometer", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(missile) as MillimeterWaveRadiometer;
|
||||
var rangefinder = missile.GetType().GetField("rangefinder", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(missile) as LaserRangefinder;
|
||||
var altimeter = missile.GetType().GetField("altimeter", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(missile) as MillimeterWaveAltimeter;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case JammingType.Infrared:
|
||||
infraredDetector?.ClearJamming(type);
|
||||
break;
|
||||
case JammingType.MillimeterWave:
|
||||
radiometer?.ClearJamming(type);
|
||||
altimeter?.ClearJamming(type);
|
||||
break;
|
||||
case JammingType.Laser:
|
||||
rangefinder?.ClearJamming(type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"清除{type}干扰");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始模拟
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
isRunning = true;
|
||||
Console.WriteLine("开始模拟...");
|
||||
|
||||
while (isRunning)
|
||||
{
|
||||
// 更新所有实体
|
||||
foreach (var missile in missiles.ToList())
|
||||
{
|
||||
missile.Update(timeStep);
|
||||
Console.WriteLine($"\n导弹状态:\n{missile.GetStatus()}");
|
||||
}
|
||||
|
||||
foreach (var target in targets)
|
||||
{
|
||||
target.Update(timeStep);
|
||||
}
|
||||
|
||||
// 移除已经爆炸或自毁的导弹
|
||||
missiles.RemoveAll(m => m.GetType().GetField("currentStage", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.GetValue(m)?.ToString() is "Explode" or "SelfDestruct");
|
||||
|
||||
// 如果所有导弹都已经结束,停止模拟
|
||||
if (!missiles.Any())
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
Thread.Sleep((int)(timeStep * 1000)); // 按照时间步长暂停
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止模拟
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
isRunning = false;
|
||||
Console.WriteLine("模拟结束");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模拟目标类
|
||||
/// </summary>
|
||||
public class MockTarget : SimulationElement, ITarget
|
||||
{
|
||||
public MockTarget(string id, ISimulationManager simulationManager) : base(id, new Vector3D(0, 0, 0), new Orientation(), 1000, simulationManager) { }
|
||||
|
||||
public override void Update(double deltaTime) { }
|
||||
|
||||
public string Type => "Tank";
|
||||
|
||||
// 设置目标的物理尺寸
|
||||
public double Length => 6.0; // 长度 6 米
|
||||
public double Width => 3.0; // 宽度 3 米
|
||||
public double Height => 2.5; // 高度 2.5 米
|
||||
|
||||
// 设置目标的特征参数
|
||||
public double RadarCrossSection => 10.0; // 雷达散射截面积(示例值)
|
||||
public double InfraredRadiationIntensity => 500.0; // 红外辐射强度(示例值)
|
||||
public double MillimeterWaveRadiationTemperature => 90.0; // 毫米波辐射温度(示例值)
|
||||
public double LaserReflectivity => 0.3; // 激光反射率(示例值)
|
||||
}
|
||||
}
|
||||
245
tools/Program.cs
245
tools/Program.cs
@ -1,75 +1,206 @@
|
||||
using ThreatSource.Utils;
|
||||
using ThreatSource.Jamming;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace ThreatSource.Tools
|
||||
namespace ThreatSource.Tools.MissileSimulation
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("末敏子弹模拟程序启动...");
|
||||
var simulator = new MissileSimulator();
|
||||
|
||||
// 添加目标
|
||||
var targetId = simulator.AddTarget(new Vector3D(0, 0, 0));
|
||||
|
||||
// 发射导弹
|
||||
simulator.LaunchMissile(targetId, new Vector3D(40, 450, 40));
|
||||
|
||||
// 启动模拟线程
|
||||
var simulationThread = new Thread(simulator.Start);
|
||||
simulationThread.Start();
|
||||
|
||||
// 等待用户输入命令
|
||||
Console.WriteLine("综合导弹模拟程序启动...");
|
||||
var simulator = new ComprehensiveMissileSimulator();
|
||||
|
||||
// 标记是否收到仿真结束事件
|
||||
var simulationEndedEvent = new ManualResetEvent(false);
|
||||
|
||||
// 订阅仿真结束事件
|
||||
simulator.SimulationEnded += (sender, e) => {
|
||||
simulationEndedEvent.Set();
|
||||
};
|
||||
|
||||
while (true)
|
||||
{
|
||||
Console.WriteLine("\n请输入命令(help查看帮助):");
|
||||
var command = Console.ReadLine()?.ToLower();
|
||||
|
||||
switch (command)
|
||||
// 显示主菜单,如果返回false则退出程序
|
||||
if (!ShowMainMenu(simulator))
|
||||
{
|
||||
case "help":
|
||||
ShowHelp();
|
||||
break;
|
||||
case "ir":
|
||||
simulator.ApplyJamming(JammingType.Infrared, 100, 5, new Vector3D(0, 0, 0));
|
||||
break;
|
||||
case "mw":
|
||||
simulator.ApplyJamming(JammingType.MillimeterWave, 200, 5, new Vector3D(0, 0, 0));
|
||||
break;
|
||||
case "laser":
|
||||
simulator.ApplyJamming(JammingType.Laser, 150, 5, new Vector3D(0, 0, 0));
|
||||
break;
|
||||
case "clear ir":
|
||||
simulator.ClearJamming(JammingType.Infrared);
|
||||
break;
|
||||
case "clear mw":
|
||||
simulator.ClearJamming(JammingType.MillimeterWave);
|
||||
break;
|
||||
case "clear laser":
|
||||
simulator.ClearJamming(JammingType.Laser);
|
||||
break;
|
||||
case "exit":
|
||||
simulator.Stop();
|
||||
return;
|
||||
default:
|
||||
Console.WriteLine("未知命令,请输入help查看帮助");
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
// 重置事件状态
|
||||
simulationEndedEvent.Reset();
|
||||
|
||||
// 开始仿真
|
||||
var simulationThread = new Thread(simulator.Start);
|
||||
simulationThread.Start();
|
||||
|
||||
// 等待退出命令
|
||||
Console.WriteLine("\n仿真已开始运行。输入 'exit' 退出程序。");
|
||||
bool exitProgram = false;
|
||||
while (true)
|
||||
{
|
||||
if (Console.KeyAvailable)
|
||||
{
|
||||
var input = Console.ReadLine()?.ToLower();
|
||||
if (input == "exit")
|
||||
{
|
||||
simulator.Stop();
|
||||
exitProgram = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查仿真是否结束
|
||||
if (simulationEndedEvent.WaitOne(100)) // 等待100ms
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (exitProgram)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// 等待仿真线程完全结束
|
||||
simulationThread.Join();
|
||||
|
||||
// 显示分隔线和新的仿真选项
|
||||
Console.WriteLine("\n" + new string('=', 50));
|
||||
Console.WriteLine("当前导弹仿真结束,准备开始新的仿真...");
|
||||
Console.WriteLine(new string('=', 50) + "\n");
|
||||
}
|
||||
|
||||
Console.WriteLine("\n程序已退出。");
|
||||
}
|
||||
|
||||
static bool ShowMainMenu(ComprehensiveMissileSimulator simulator)
|
||||
{
|
||||
Console.WriteLine("=== 导弹仿真系统主菜单 ===\n");
|
||||
|
||||
// 第一步:选择导弹
|
||||
if (!SelectMissile(simulator))
|
||||
return false;
|
||||
|
||||
// 第二步:配置传感器
|
||||
if (!ConfigureSensors(simulator))
|
||||
return false;
|
||||
|
||||
// 第三步:配置干扰
|
||||
if (!ConfigureJamming(simulator))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SelectMissile(ComprehensiveMissileSimulator simulator)
|
||||
{
|
||||
var missiles = new[]
|
||||
{
|
||||
("LSGM_1", "激光半主动制导导弹"),
|
||||
("LBRM_1", "激光驾束制导导弹"),
|
||||
("TSM_1", "末敏弹"),
|
||||
("ICGM_1", "红外指令制导导弹"),
|
||||
("ITGM_1", "红外成像末制导导弹"),
|
||||
("MMWG_1", "毫米波末制导导弹")
|
||||
};
|
||||
|
||||
while (true)
|
||||
{
|
||||
Console.WriteLine("\n第一步:请选择导弹类型:");
|
||||
for (int i = 0; i < missiles.Length; i++)
|
||||
{
|
||||
Console.WriteLine($" {i + 1}. {missiles[i].Item2}");
|
||||
}
|
||||
Console.WriteLine(" exit. 退出程序");
|
||||
|
||||
var input = Console.ReadLine()?.ToLower();
|
||||
if (input == "exit")
|
||||
return false;
|
||||
|
||||
if (int.TryParse(input, out int choice) &&
|
||||
choice >= 1 && choice <= missiles.Length)
|
||||
{
|
||||
simulator.SelectMissile(missiles[choice - 1].Item1);
|
||||
return true;
|
||||
}
|
||||
Console.WriteLine("无效选择,请重试");
|
||||
}
|
||||
}
|
||||
|
||||
static void ShowHelp()
|
||||
|
||||
static bool ConfigureSensors(ComprehensiveMissileSimulator simulator)
|
||||
{
|
||||
Console.WriteLine("可用命令:");
|
||||
Console.WriteLine(" help - 显示帮助信息");
|
||||
Console.WriteLine(" ir - 应用红外干扰");
|
||||
Console.WriteLine(" mw - 应用毫米波干扰");
|
||||
Console.WriteLine(" laser - 应用激光干扰");
|
||||
Console.WriteLine(" clear ir - 清除红外干扰");
|
||||
Console.WriteLine(" clear mw - 清除毫米波干扰");
|
||||
Console.WriteLine(" clear laser - 清除激光干扰");
|
||||
Console.WriteLine(" exit - 退出程序");
|
||||
while (true)
|
||||
{
|
||||
Console.WriteLine("\n第二步:配置传感器和指示器");
|
||||
Console.WriteLine("当前传感器状态:");
|
||||
var sensors = simulator.GetActiveSensors();
|
||||
for (int i = 0; i < sensors.Length; i++)
|
||||
{
|
||||
Console.WriteLine($" {i + 1}. {sensors[i].Name} [{(sensors[i].IsActive ? "激活" : "未激活")}]");
|
||||
}
|
||||
Console.WriteLine(" 0. 继续下一步");
|
||||
Console.WriteLine(" exit. 退出程序");
|
||||
|
||||
var input = Console.ReadLine()?.ToLower();
|
||||
if (input == "exit")
|
||||
return false;
|
||||
|
||||
if (int.TryParse(input, out int choice))
|
||||
{
|
||||
if (choice == 0) return true;
|
||||
if (choice >= 1 && choice <= sensors.Length)
|
||||
{
|
||||
simulator.ToggleSensor(sensors[choice - 1].Id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Console.WriteLine("无效选择,请重试");
|
||||
}
|
||||
}
|
||||
|
||||
static bool ConfigureJamming(ComprehensiveMissileSimulator simulator)
|
||||
{
|
||||
var jammingTypes = new[]
|
||||
{
|
||||
(JammingType.Infrared, "红外干扰"),
|
||||
(JammingType.MillimeterWave, "毫米波干扰"),
|
||||
(JammingType.Laser, "激光干扰")
|
||||
};
|
||||
|
||||
var jammingStatus = new bool[jammingTypes.Length];
|
||||
|
||||
while (true)
|
||||
{
|
||||
Console.WriteLine("\n第三步:配置干扰方式");
|
||||
Console.WriteLine("当前干扰状态:");
|
||||
for (int i = 0; i < jammingTypes.Length; i++)
|
||||
{
|
||||
Console.WriteLine($" {i + 1}. {jammingTypes[i].Item2} [{(jammingStatus[i] ? "激活" : "未激活")}]");
|
||||
}
|
||||
Console.WriteLine(" 0. 开始仿真");
|
||||
Console.WriteLine(" exit. 退出程序");
|
||||
|
||||
var input = Console.ReadLine()?.ToLower();
|
||||
if (input == "exit")
|
||||
return false;
|
||||
|
||||
if (int.TryParse(input, out int choice))
|
||||
{
|
||||
if (choice == 0) return true;
|
||||
if (choice >= 1 && choice <= jammingTypes.Length)
|
||||
{
|
||||
jammingStatus[choice - 1] = !jammingStatus[choice - 1];
|
||||
if (jammingStatus[choice - 1])
|
||||
simulator.ApplyJamming(jammingTypes[choice - 1].Item1, 100, 5, new Vector3D(0, 0, 0));
|
||||
else
|
||||
simulator.ClearJamming(jammingTypes[choice - 1].Item1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Console.WriteLine("无效选择,请重试");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user