ThreatSourceLibaray/tools/ComprehensiveMissileSimulator.cs

546 lines
20 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 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 ? "" : "")}");
}
}
}
}