546 lines
20 KiB
C#
546 lines
20 KiB
C#
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 ? "激活" : "停用")}");
|
||
}
|
||
}
|
||
}
|
||
} |