599 lines
18 KiB
C#
599 lines
18 KiB
C#
#if NEVER // 使用编译指令确保此文件永远不会被编译
|
||
|
||
// Matlab/Simulink集成示例代码 - .NET Assembly直接调用方式
|
||
//
|
||
// 【适用场景】
|
||
// - Matlab R2019b或更高版本
|
||
// - 需要在Simulink模型中集成威胁源仿真
|
||
// - 实时仿真数据交换和时间同步
|
||
//
|
||
// 【前置条件】
|
||
// 1. 将 ThreatSource.dll 放入 Matlab 路径或指定目录
|
||
// 2. 将 data/ 目录复制到 Matlab 工作目录下
|
||
// 3. Matlab版本支持 .NET 8.0
|
||
//
|
||
// 展示如何将Matlab/Simulink与ThreatSource仿真系统集成
|
||
// 需要实现的核心功能: .NET Assembly加载、数据交换、时间同步
|
||
|
||
using ThreatSource.Simulation;
|
||
using ThreatSource.Data;
|
||
using ThreatSource.Missile;
|
||
using ThreatSource.Equipment;
|
||
using ThreatSource.Utils;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
|
||
/// <summary>
|
||
/// Matlab/Simulink适配器类,演示如何将威胁源库集成到Matlab/Simulink中
|
||
/// </summary>
|
||
/// <remarks>
|
||
/// 该类提供以下功能:
|
||
/// - .NET Assembly方式的Matlab集成
|
||
/// - 简化的API接口,便于Matlab调用
|
||
/// - 实时数据交换和状态同步
|
||
/// - 事件处理和回调机制
|
||
/// - 与Simulink时间步长的协调
|
||
/// 本示例代码作为集成参考,可根据具体需求进行修改
|
||
/// </remarks>
|
||
public class MatlabSimulinkAdapter
|
||
{
|
||
#region 私有字段
|
||
/// <summary>
|
||
/// 仿真管理器实例
|
||
/// </summary>
|
||
private ISimulationManager _simulationManager;
|
||
|
||
/// <summary>
|
||
/// 数据管理器实例
|
||
/// </summary>
|
||
private ThreatSourceDataManager _dataManager;
|
||
|
||
/// <summary>
|
||
/// Matlab创建的实体映射
|
||
/// </summary>
|
||
private Dictionary<string, object> _matlabEntities = new Dictionary<string, object>();
|
||
|
||
/// <summary>
|
||
/// 当前仿真时间
|
||
/// </summary>
|
||
private double _currentTime = 0.0;
|
||
|
||
/// <summary>
|
||
/// 仿真时间步长
|
||
/// </summary>
|
||
private double _timeStep = 0.01;
|
||
|
||
/// <summary>
|
||
/// 是否已初始化
|
||
/// </summary>
|
||
private bool _isInitialized = false;
|
||
#endregion
|
||
|
||
#region 构造函数
|
||
/// <summary>
|
||
/// 初始化Matlab/Simulink适配器的新实例
|
||
/// </summary>
|
||
public MatlabSimulinkAdapter()
|
||
{
|
||
InitializeSimulation();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化仿真系统
|
||
/// </summary>
|
||
private void InitializeSimulation()
|
||
{
|
||
try
|
||
{
|
||
// 创建仿真管理器
|
||
_simulationManager = new SimulationManager();
|
||
|
||
// 创建数据管理器
|
||
_dataManager = new ThreatSourceDataManager();
|
||
|
||
Console.WriteLine("[MatlabAdapter] 威胁源仿真系统初始化完成");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[MatlabAdapter] 初始化失败: {ex.Message}");
|
||
throw;
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region Matlab公共接口
|
||
/// <summary>
|
||
/// 启动仿真系统
|
||
/// </summary>
|
||
/// <param name="timeStep">仿真时间步长(秒)</param>
|
||
/// <returns>启动是否成功</returns>
|
||
public bool StartSimulation(double timeStep = 0.01)
|
||
{
|
||
try
|
||
{
|
||
if (!_isInitialized)
|
||
{
|
||
_timeStep = timeStep;
|
||
_simulationManager.StartSimulation(timeStep);
|
||
_isInitialized = true;
|
||
Console.WriteLine($"[MatlabAdapter] 仿真已启动,时间步长: {timeStep}s");
|
||
}
|
||
return true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[MatlabAdapter] 启动仿真失败: {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新仿真状态(在Simulink中每个时间步调用)
|
||
/// </summary>
|
||
/// <param name="deltaTime">时间步长</param>
|
||
/// <returns>更新是否成功</returns>
|
||
public bool UpdateSimulation(double deltaTime)
|
||
{
|
||
try
|
||
{
|
||
if (!_isInitialized) return false;
|
||
|
||
_simulationManager.Update(deltaTime);
|
||
_currentTime += deltaTime;
|
||
return true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[MatlabAdapter] 仿真更新失败: {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建目标实体(供Matlab调用)
|
||
/// </summary>
|
||
/// <param name="entityId">实体ID</param>
|
||
/// <param name="posX">X坐标</param>
|
||
/// <param name="posY">Y坐标</param>
|
||
/// <param name="posZ">Z坐标</param>
|
||
/// <param name="velX">X方向速度</param>
|
||
/// <param name="velY">Y方向速度</param>
|
||
/// <param name="velZ">Z方向速度</param>
|
||
/// <returns>创建是否成功</returns>
|
||
public bool CreateTarget(string entityId, double posX, double posY, double posZ,
|
||
double velX, double velY, double velZ)
|
||
{
|
||
try
|
||
{
|
||
var targetPos = new Vector3D(posX, posY, posZ);
|
||
var targetVel = new Vector3D(velX, velY, velZ);
|
||
|
||
var tankInitialMotion = new KinematicState
|
||
{
|
||
Position = targetPos,
|
||
Orientation = new Orientation(0, 0, Math.Atan2(velY, velX)),
|
||
Speed = targetVel.Magnitude()
|
||
};
|
||
|
||
var tankProperties = new EquipmentProperties
|
||
{
|
||
InfraredRadiationIntensity = 10.0,
|
||
UltravioletRadiationIntensity = 10.0,
|
||
MillimeterWaveRadiationIntensity = 10.0
|
||
};
|
||
|
||
var tank = new Tank(entityId, tankProperties, tankInitialMotion, _simulationManager);
|
||
_simulationManager.RegisterEntity(entityId, tank);
|
||
_matlabEntities[entityId] = tank;
|
||
|
||
Console.WriteLine($"[MatlabAdapter] 成功创建目标: {entityId}");
|
||
return true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[MatlabAdapter] 创建目标失败: {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建红外成像制导导弹
|
||
/// </summary>
|
||
/// <param name="entityId">导弹ID</param>
|
||
/// <param name="posX">发射位置X</param>
|
||
/// <param name="posY">发射位置Y</param>
|
||
/// <param name="posZ">发射位置Z</param>
|
||
/// <param name="targetId">目标ID</param>
|
||
/// <returns>创建是否成功</returns>
|
||
public bool CreateIRMissile(string entityId, double posX, double posY, double posZ, string targetId)
|
||
{
|
||
try
|
||
{
|
||
var launchPos = new Vector3D(posX, posY, posZ);
|
||
|
||
var missileInitialMotion = new KinematicState
|
||
{
|
||
Position = launchPos,
|
||
Orientation = new Orientation(0, 0, 0),
|
||
Speed = 100
|
||
};
|
||
|
||
var properties = new MissileProperties
|
||
{
|
||
MaxSpeed = 1000,
|
||
MaxFlightTime = 100,
|
||
MaxFlightDistance = 10000,
|
||
MaxAcceleration = 50,
|
||
ProportionalNavigationCoefficient = 3,
|
||
Mass = 100,
|
||
ExplosionRadius = 10,
|
||
HitProbability = 0.9,
|
||
Type = MissileType.InfraredImagingTerminalGuidance
|
||
};
|
||
|
||
var guidanceConfig = new InfraredImagingGuidanceConfig
|
||
{
|
||
JammingResistanceThreshold = 1e-3
|
||
};
|
||
|
||
var missile = new InfraredImagingTerminalGuidanceMissile(
|
||
entityId, properties, missileInitialMotion, guidanceConfig, _simulationManager);
|
||
|
||
if (!string.IsNullOrEmpty(targetId))
|
||
{
|
||
missile.SetTarget(targetId);
|
||
}
|
||
|
||
_simulationManager.RegisterEntity(entityId, missile);
|
||
_matlabEntities[entityId] = missile;
|
||
|
||
Console.WriteLine($"[MatlabAdapter] 成功创建红外导弹: {entityId}");
|
||
return true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[MatlabAdapter] 创建红外导弹失败: {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建毫米波制导导弹
|
||
/// </summary>
|
||
/// <param name="entityId">导弹ID</param>
|
||
/// <param name="posX">发射位置X</param>
|
||
/// <param name="posY">发射位置Y</param>
|
||
/// <param name="posZ">发射位置Z</param>
|
||
/// <param name="targetId">目标ID</param>
|
||
/// <returns>创建是否成功</returns>
|
||
public bool CreateMMWMissile(string entityId, double posX, double posY, double posZ, string targetId)
|
||
{
|
||
try
|
||
{
|
||
var launchPos = new Vector3D(posX, posY, posZ);
|
||
|
||
var missileInitialMotion = new KinematicState
|
||
{
|
||
Position = launchPos,
|
||
Orientation = new Orientation(0, 0, 0),
|
||
Speed = 100
|
||
};
|
||
|
||
var properties = new MissileProperties
|
||
{
|
||
MaxSpeed = 1000,
|
||
MaxFlightTime = 100,
|
||
MaxFlightDistance = 10000,
|
||
MaxAcceleration = 50,
|
||
ProportionalNavigationCoefficient = 3,
|
||
Mass = 100,
|
||
ExplosionRadius = 10,
|
||
HitProbability = 0.9,
|
||
Type = MissileType.MillimeterWaveTerminalGuidance
|
||
};
|
||
|
||
var guidanceConfig = new MillimeterWaveGuidanceConfig
|
||
{
|
||
FieldOfViewAngle = 30,
|
||
TransmitPower = 0.5,
|
||
AntennaGainDB = 25,
|
||
WaveFrequency = 94e9
|
||
};
|
||
|
||
var missile = new MillimeterWaveTerminalGuidedMissile(
|
||
entityId, properties, missileInitialMotion, guidanceConfig, _simulationManager);
|
||
|
||
if (!string.IsNullOrEmpty(targetId))
|
||
{
|
||
missile.SetTarget(targetId);
|
||
}
|
||
|
||
_simulationManager.RegisterEntity(entityId, missile);
|
||
_matlabEntities[entityId] = missile;
|
||
|
||
Console.WriteLine($"[MatlabAdapter] 成功创建毫米波导弹: {entityId}");
|
||
return true;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[MatlabAdapter] 创建毫米波导弹失败: {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取实体状态(供Matlab调用)
|
||
/// </summary>
|
||
/// <param name="entityId">实体ID</param>
|
||
/// <returns>状态数组 [x, y, z, vx, vy, vz, roll, pitch, yaw, isActive]</returns>
|
||
public double[] GetEntityState(string entityId)
|
||
{
|
||
try
|
||
{
|
||
var entity = _simulationManager.GetEntityById(entityId);
|
||
if (entity is ISimulationElement simElement)
|
||
{
|
||
return ConvertToMatlabStateArray(simElement);
|
||
}
|
||
return new double[10]; // 返回零数组
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[MatlabAdapter] 获取实体状态失败: {ex.Message}");
|
||
return new double[10];
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置实体位置(供Matlab调用)
|
||
/// </summary>
|
||
/// <param name="entityId">实体ID</param>
|
||
/// <param name="posX">X坐标</param>
|
||
/// <param name="posY">Y坐标</param>
|
||
/// <param name="posZ">Z坐标</param>
|
||
/// <returns>设置是否成功</returns>
|
||
public bool SetEntityPosition(string entityId, double posX, double posY, double posZ)
|
||
{
|
||
try
|
||
{
|
||
var entity = _simulationManager.GetEntityById(entityId);
|
||
if (entity is ISimulationElement simElement)
|
||
{
|
||
simElement.KState.Position = new Vector3D(posX, posY, posZ);
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[MatlabAdapter] 设置实体位置失败: {ex.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取所有实体ID列表(供Matlab调用)
|
||
/// </summary>
|
||
/// <returns>实体ID字符串数组</returns>
|
||
public string[] GetAllEntityIds()
|
||
{
|
||
try
|
||
{
|
||
var allEntities = _simulationManager.GetAllEntities();
|
||
var entityIds = new List<string>();
|
||
|
||
foreach (var entity in allEntities)
|
||
{
|
||
if (entity is ISimulationElement simElement)
|
||
{
|
||
entityIds.Add(simElement.Id);
|
||
}
|
||
}
|
||
|
||
return entityIds.ToArray();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[MatlabAdapter] 获取实体列表失败: {ex.Message}");
|
||
return new string[0];
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 停止仿真
|
||
/// </summary>
|
||
public void StopSimulation()
|
||
{
|
||
try
|
||
{
|
||
_simulationManager.StopSimulation();
|
||
_isInitialized = false;
|
||
_matlabEntities.Clear();
|
||
_currentTime = 0.0;
|
||
Console.WriteLine("[MatlabAdapter] 仿真已停止");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[MatlabAdapter] 停止仿真失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前仿真时间
|
||
/// </summary>
|
||
/// <returns>当前仿真时间(秒)</returns>
|
||
public double GetCurrentTime()
|
||
{
|
||
return _currentTime;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查实体是否存在
|
||
/// </summary>
|
||
/// <param name="entityId">实体ID</param>
|
||
/// <returns>实体是否存在</returns>
|
||
public bool EntityExists(string entityId)
|
||
{
|
||
var entity = _simulationManager.GetEntityById(entityId);
|
||
return entity != null;
|
||
}
|
||
#endregion
|
||
|
||
#region 私有辅助方法
|
||
/// <summary>
|
||
/// 将仿真元素转换为Matlab状态数组
|
||
/// </summary>
|
||
/// <param name="element">仿真元素</param>
|
||
/// <returns>状态数组 [x, y, z, vx, vy, vz, roll, pitch, yaw, isActive]</returns>
|
||
private double[] ConvertToMatlabStateArray(ISimulationElement element)
|
||
{
|
||
var pos = element.KState.Position;
|
||
var ori = element.KState.Orientation;
|
||
var speed = element.KState.Speed;
|
||
|
||
// 计算速度分量
|
||
var vx = speed * Math.Cos(ori.Yaw) * Math.Cos(ori.Pitch);
|
||
var vy = speed * Math.Sin(ori.Yaw) * Math.Cos(ori.Pitch);
|
||
var vz = speed * Math.Sin(ori.Pitch);
|
||
|
||
return new double[]
|
||
{
|
||
pos.X, pos.Y, pos.Z, // 位置 [0-2]
|
||
vx, vy, vz, // 速度 [3-5]
|
||
ori.Roll, ori.Pitch, ori.Yaw, // 姿态 [6-8]
|
||
element.IsActive ? 1.0 : 0.0 // 活动状态 [9]
|
||
};
|
||
}
|
||
#endregion
|
||
}
|
||
|
||
/// <summary>
|
||
/// Matlab/Simulink仿真示例类
|
||
/// </summary>
|
||
/// <remarks>
|
||
/// 该类演示了:
|
||
/// - Matlab/Simulink仿真系统的初始化
|
||
/// - 适配器的配置和使用
|
||
/// - 典型的导弹-目标仿真场景
|
||
/// 用于指导实际项目中的集成实现
|
||
/// </remarks>
|
||
public class MatlabSimulinkExample
|
||
{
|
||
private MatlabSimulinkAdapter _adapter;
|
||
|
||
/// <summary>
|
||
/// 初始化示例
|
||
/// </summary>
|
||
public void Initialize()
|
||
{
|
||
_adapter = new MatlabSimulinkAdapter();
|
||
Console.WriteLine("Matlab/Simulink ThreatSource集成示例初始化完成");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 运行基本仿真示例
|
||
/// </summary>
|
||
public void RunBasicSimulationExample()
|
||
{
|
||
try
|
||
{
|
||
// 启动仿真系统
|
||
if (!_adapter.StartSimulation(0.01))
|
||
{
|
||
Console.WriteLine("仿真启动失败");
|
||
return;
|
||
}
|
||
|
||
// 创建目标
|
||
bool targetCreated = _adapter.CreateTarget(
|
||
"target_001",
|
||
5000, 0, 1000, // 位置: 5km距离,1km高度
|
||
-50, 0, 0 // 速度: 50m/s向西移动
|
||
);
|
||
|
||
if (!targetCreated)
|
||
{
|
||
Console.WriteLine("目标创建失败");
|
||
return;
|
||
}
|
||
|
||
// 创建红外制导导弹
|
||
bool missileCreated = _adapter.CreateIRMissile(
|
||
"missile_001",
|
||
0, 0, 100, // 发射位置: 起始位置,100m高度
|
||
"target_001" // 目标ID
|
||
);
|
||
|
||
if (missileCreated)
|
||
{
|
||
Console.WriteLine("基本仿真示例场景创建成功");
|
||
|
||
// 运行仿真步骤示例
|
||
for (int i = 0; i < 10; i++)
|
||
{
|
||
_adapter.UpdateSimulation(0.01);
|
||
|
||
// 获取导弹状态
|
||
var missileState = _adapter.GetEntityState("missile_001");
|
||
Console.WriteLine($"时间: {_adapter.GetCurrentTime():F2}s, 导弹位置: [{missileState[0]:F1}, {missileState[1]:F1}, {missileState[2]:F1}]");
|
||
|
||
// 在实际Simulink中,这里会是Simulink的时间步进
|
||
System.Threading.Thread.Sleep(10);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine("导弹创建失败");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"运行仿真示例失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 运行多导弹仿真示例
|
||
/// </summary>
|
||
public void RunMultiMissileExample()
|
||
{
|
||
try
|
||
{
|
||
// 启动仿真
|
||
_adapter.StartSimulation(0.01);
|
||
|
||
// 创建多个目标
|
||
_adapter.CreateTarget("target_001", 3000, 1000, 800, -30, -10, 0);
|
||
_adapter.CreateTarget("target_002", 4000, -500, 1200, -40, 20, 0);
|
||
|
||
// 创建不同类型的导弹
|
||
_adapter.CreateIRMissile("ir_missile_001", 0, 0, 100, "target_001");
|
||
_adapter.CreateMMWMissile("mmw_missile_001", 100, 0, 100, "target_002");
|
||
|
||
Console.WriteLine("多导弹仿真示例场景创建成功");
|
||
|
||
// 显示所有实体
|
||
var entityIds = _adapter.GetAllEntityIds();
|
||
Console.WriteLine($"仿真中共有 {entityIds.Length} 个实体:");
|
||
foreach (var id in entityIds)
|
||
{
|
||
Console.WriteLine($" - {id}");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"运行多导弹示例失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清理资源
|
||
/// </summary>
|
||
public void Cleanup()
|
||
{
|
||
_adapter?.StopSimulation();
|
||
Console.WriteLine("Matlab/Simulink ThreatSource集成示例已清理");
|
||
}
|
||
}
|
||
|
||
#endif // 结束编译指令块 |