ThreatSourceLibaray/tools/MissileSimulator.cs

203 lines
7.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using ThreatSource.Missile;
using ThreatSource.Simulation;
using ThreatSource.Utils;
using ThreatSource.Jamming;
using ThreatSource.Sensor;
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.005; // 时间步长,单位:秒
/// <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)
{
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 = 5,
MaxSpeed = 2000
};
var missile = new TerminalSensitiveSubmunition(targetId, properties, simulationManager)
{
Position = position,
Velocity = new Vector3D(0, -10, 0) // 初始垂直下降速度
};
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
{
public MockTarget(string id) : base(id, new Vector3D(0, 0, 0), new Orientation(), 1000, null) { }
public override void Update(double deltaTime) { }
}
}