增加了 Matlab/Simulink 集成示例代码和说明
This commit is contained in:
parent
131ba3997c
commit
1017af871e
@ -8,10 +8,6 @@
|
||||
## [未发布]
|
||||
|
||||
### 计划功能
|
||||
- Matlab/Simulink 仿真环境适配器
|
||||
- 支持与 Simulink 模型的数据交互
|
||||
- 实现实时仿真数据同步
|
||||
- 处理不同时间步长的协调
|
||||
- dll 库的接口有效性验证
|
||||
- 所有威胁源的参数规范化,增加默认参数配置
|
||||
- 规范第三方仿真环境使用 dll 库的场景和事件类型
|
||||
@ -26,7 +22,8 @@
|
||||
- 增加了命中概率的计算和实现
|
||||
- 增加了导弹运动状态的随机噪声,并根据飞行阶段设置不同的噪声系数
|
||||
- 同步 dll 库的文档,api 文档、使用说明、工作原理
|
||||
- 增加了性能测试,优化了仿真管理器和红外成像制导的性能,并做了记录
|
||||
- 增加了性能测试,优化了仿真管理器、红外成像制导、毫米波制导的性能,并做了记录
|
||||
- 增加了 Matlab/Simulink集成示例代码和说明
|
||||
|
||||
## [1.1.21] - 2025-05-24
|
||||
- 增加了升力加速度的计算
|
||||
|
||||
@ -145,72 +145,7 @@ class Program
|
||||
|
||||
### C++版本
|
||||
|
||||
C++项目有两种使用方式:
|
||||
|
||||
#### 方式一:动态加载(推荐)
|
||||
|
||||
这种方式适合纯C++项目,不需要配置CLR支持。
|
||||
|
||||
1. 下载 ThreatSourceNative 包并解压
|
||||
2. 将 bin 目录下的所有 DLL 文件复制到程序目录
|
||||
3. 将 include/threat_source.h 添加到项目中
|
||||
4. 按照标准结构部署数据文件
|
||||
|
||||
示例代码:
|
||||
|
||||
```cpp
|
||||
#include "threat_source.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
// 初始化仿真
|
||||
if (TS_CreateSimulation() != THREATSOURCE_SUCCESS) {
|
||||
printf("Failed to create simulation\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 创建导弹(使用配置文件)
|
||||
const char* missile_id = "missile1";
|
||||
const char* missile_model = "lsgm_001"; // 激光半主动制导导弹
|
||||
const char* target_id = "target1";
|
||||
|
||||
int result = TS_CreateMissileFromConfig(
|
||||
missile_id,
|
||||
missile_model,
|
||||
target_id,
|
||||
0, 0, 0, // 初始位置
|
||||
0, 0, 0 // 初始朝向
|
||||
);
|
||||
|
||||
if (result != THREATSOURCE_SUCCESS) {
|
||||
char error[256];
|
||||
TS_GetLastError(error, sizeof(error));
|
||||
printf("Failed to create missile: %s\n", error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 激活并发射导弹
|
||||
TS_ActivateMissile(missile_id);
|
||||
TS_FireMissile(missile_id);
|
||||
|
||||
// 仿真主循环
|
||||
double deltaTime = 0.01;
|
||||
int is_active = 1;
|
||||
|
||||
while (is_active) {
|
||||
TS_UpdateSimulation(deltaTime);
|
||||
TS_IsMissileActive(missile_id, &is_active);
|
||||
}
|
||||
|
||||
// 清理
|
||||
TS_DestroySimulation();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
#### 方式二:CLR 集成
|
||||
|
||||
如果需要使用 .NET 的完整功能,可以选择 CLR 集成方式:
|
||||
C++项目的使用方式(CLR集成):
|
||||
|
||||
1. 配置项目属性:
|
||||
- C/C++ -> 常规 -> 公共语言运行时支持:/clr
|
||||
@ -473,11 +408,13 @@ var dataManager = new ThreatSourceDataManager();
|
||||
4. ✅ 确保应用程序有读取数据目录的权限
|
||||
5. ✅ 测试自动路径解析功能
|
||||
|
||||
## 更多示例
|
||||
## 第三方仿真环境集成
|
||||
- [集成示例](../examples/Integration/README.md)
|
||||
|
||||
## 更多示例
|
||||
更多详细示例和高级用法请参考:
|
||||
- [仿真示例](../examples/Simulation/README.md)
|
||||
- [集成示例](../examples/Integration/README.md)
|
||||
|
||||
|
||||
## 故障排除
|
||||
|
||||
|
||||
@ -7,9 +7,100 @@
|
||||
- .NET 8.0 或更高版本
|
||||
- ThreatSource.dll 库文件
|
||||
- 对应的第三方引擎开发环境
|
||||
- **Unity**:2020.3或更高版本
|
||||
- **Unreal Engine**:4.27或更高版本
|
||||
- **Matlab/Simulink**:R2019b或更高版本(需要.NET 8.0支持)
|
||||
|
||||
## 示例文件
|
||||
|
||||
### [SimulinkExample.cs](SimulinkExample.cs)
|
||||
|
||||
Matlab/Simulink集成示例,展示了:
|
||||
|
||||
- 基于.NET Assembly直接调用的Matlab/Simulink集成
|
||||
- 简化的API接口,便于Matlab调用
|
||||
- 实时仿真数据交换和时间同步
|
||||
- 与Simulink时间步长的协调
|
||||
|
||||
#### 核心功能
|
||||
|
||||
```csharp
|
||||
using ThreatSource.Simulation;
|
||||
using ThreatSource.Data;
|
||||
using ThreatSource.Missile;
|
||||
using ThreatSource.Equipment;
|
||||
using ThreatSource.Utils;
|
||||
|
||||
/// <summary>
|
||||
/// Matlab/Simulink适配器类,演示如何将威胁源库集成到Matlab/Simulink中
|
||||
/// </summary>
|
||||
public class MatlabSimulinkAdapter
|
||||
{
|
||||
private ISimulationManager _simulationManager;
|
||||
private ThreatSourceDataManager _dataManager;
|
||||
private Dictionary<string, object> _matlabEntities;
|
||||
|
||||
public bool StartSimulation(double timeStep = 0.01)
|
||||
{
|
||||
_simulationManager.StartSimulation(timeStep);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CreateTarget(string entityId, double posX, double posY, double posZ,
|
||||
double velX, double velY, double velZ)
|
||||
{
|
||||
var targetPos = new Vector3D(posX, posY, posZ);
|
||||
var targetVel = new Vector3D(velX, velY, velZ);
|
||||
|
||||
var tank = new Tank(entityId, tankProperties, tankInitialMotion, _simulationManager);
|
||||
_simulationManager.RegisterEntity(entityId, tank);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public double[] GetEntityState(string entityId)
|
||||
{
|
||||
// 返回 [x,y,z,vx,vy,vz,roll,pitch,yaw,isActive] 格式
|
||||
var entity = _simulationManager.GetEntityById(entityId);
|
||||
return ConvertToMatlabStateArray(entity);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Matlab调用示例
|
||||
|
||||
详见 [matlab_example.m](matlab_example.m) 文件,展示了完整的Matlab集成流程:
|
||||
|
||||
```matlab
|
||||
%% 加载威胁源库
|
||||
NET.addAssembly('ThreatSource.dll');
|
||||
|
||||
%% 创建适配器
|
||||
adapter = MatlabSimulinkAdapter();
|
||||
|
||||
%% 启动仿真
|
||||
success = adapter.StartSimulation(0.01); % 10ms时间步长
|
||||
|
||||
%% 创建目标和导弹
|
||||
adapter.CreateTarget('target_001', 5000, 0, 1000, -50, 0, 0);
|
||||
adapter.CreateIRMissile('missile_001', 0, 0, 100, 'target_001');
|
||||
|
||||
%% 仿真循环
|
||||
for i = 1:1000
|
||||
adapter.UpdateSimulation(0.01);
|
||||
missile_state = adapter.GetEntityState('missile_001');
|
||||
% 处理数据...
|
||||
end
|
||||
```
|
||||
|
||||
#### Simulink S-Function集成
|
||||
|
||||
详见本文档的"Matlab/Simulink集成"部分,获取完整的Simulink集成指南,包括:
|
||||
- S-Function封装
|
||||
- 实时数据可视化
|
||||
- 与Simulink Control System闭环仿真
|
||||
- 性能优化和故障排除
|
||||
|
||||
### [UEExample.cs](UEExample.cs)
|
||||
|
||||
虚幻引擎(Unreal Engine)集成示例,展示了:
|
||||
@ -698,3 +789,119 @@ public class CustomMissileRenderer
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Matlab/Simulink集成
|
||||
|
||||
### Matlab/Simulink特定注意事项
|
||||
|
||||
1. **版本兼容性**:确保Matlab版本支持.NET 8.0(R2019b或更高版本)
|
||||
2. **时间同步**:使用固定步长求解器确保时间同步准确性
|
||||
3. **数据类型转换**:注意.NET数组与Matlab数组之间的转换
|
||||
4. **S-Function集成**:在Simulink中使用S-Function封装威胁源库调用
|
||||
|
||||
### Matlab集成示例
|
||||
|
||||
#### 基本初始化
|
||||
```matlab
|
||||
%% 加载威胁源库
|
||||
NET.addAssembly('ThreatSource.dll');
|
||||
|
||||
%% 创建适配器
|
||||
adapter = MatlabSimulinkAdapter();
|
||||
adapter.StartSimulation(0.01);
|
||||
```
|
||||
|
||||
#### 实时仿真循环
|
||||
```matlab
|
||||
%% 仿真主循环
|
||||
for step = 1:1000
|
||||
% 更新仿真
|
||||
adapter.UpdateSimulation(0.01);
|
||||
|
||||
% 获取实体状态
|
||||
missile_state = adapter.GetEntityState('missile_001');
|
||||
target_state = adapter.GetEntityState('target_001');
|
||||
|
||||
% 数据处理和可视化
|
||||
if ~isempty(missile_state)
|
||||
updateVisualization(missile_state, target_state);
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
#### S-Function封装
|
||||
```matlab
|
||||
function [sys,x0,str,ts,simStateCompliance] = threat_source_sfun(t,x,u,flag)
|
||||
% 威胁源库S-Function包装器
|
||||
|
||||
switch flag,
|
||||
case 0,
|
||||
[sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes;
|
||||
case 3,
|
||||
sys = mdlOutputs(t,x,u);
|
||||
case 9,
|
||||
sys = mdlTerminate(t,x,u);
|
||||
end
|
||||
|
||||
function [sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes
|
||||
% 初始化S-Function
|
||||
global threat_adapter;
|
||||
if isempty(threat_adapter)
|
||||
NET.addAssembly('ThreatSource.dll');
|
||||
threat_adapter = MatlabSimulinkAdapter();
|
||||
threat_adapter.StartSimulation(0.01);
|
||||
end
|
||||
|
||||
function sys = mdlOutputs(t,x,u)
|
||||
% 输出实体状态数据
|
||||
global threat_adapter;
|
||||
threat_adapter.UpdateSimulation(0.01);
|
||||
missile_state = threat_adapter.GetEntityState('missile_001');
|
||||
sys = double(missile_state);
|
||||
```
|
||||
|
||||
### Simulink模型集成步骤
|
||||
|
||||
1. **添加S-Function块**:在Simulink模型中添加S-Function块
|
||||
2. **配置参数**:设置S-Function名称为`threat_source_sfun`
|
||||
3. **连接数据流**:将S-Function输出连接到显示或分析模块
|
||||
4. **配置求解器**:使用固定步长求解器,时间步长设为0.01秒
|
||||
|
||||
### 数据格式规范
|
||||
|
||||
#### 实体状态数组格式
|
||||
```
|
||||
索引 | 含义 | 单位
|
||||
-----|-------------------|------
|
||||
0-2 | 位置(x,y,z) | 米
|
||||
3-5 | 速度(vx,vy,vz) | 米/秒
|
||||
6-8 | 姿态(roll,pitch,yaw) | 弧度
|
||||
9 | 活动状态 | 0/1
|
||||
```
|
||||
|
||||
#### Matlab示例完整流程
|
||||
|
||||
参见 [matlab_example.m](matlab_example.m) 了解完整的集成流程,包括:
|
||||
- 系统初始化和库加载
|
||||
- 仿真场景创建
|
||||
- 实时数据获取和处理
|
||||
- 结果可视化和分析
|
||||
- 资源清理和异常处理
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
docs/examples/Integration/
|
||||
├── README.md # 本文档
|
||||
├── SimulinkExample.cs # Matlab/Simulink集成示例代码
|
||||
├── matlab_example.m # Matlab调用示例脚本
|
||||
├── UnityExample.cs # Unity集成示例代码(方法一)
|
||||
├── UnityPackageExample.cs # Unity Package集成示例代码(方法二)
|
||||
└── UEExample.cs # 虚幻引擎集成示例代码
|
||||
```
|
||||
|
||||
## 相关文档
|
||||
|
||||
- **威胁源库文档**:[../../README.md](../../README.md) - 库的基本使用说明
|
||||
- **API文档**:[../../api/](../../api/) - 详细的API参考文档
|
||||
- **变更日志**:[../../CHANGELOG.md](../../CHANGELOG.md) - 版本更新记录
|
||||
|
||||
599
docs/examples/Integration/SimulinkExample.cs
Normal file
599
docs/examples/Integration/SimulinkExample.cs
Normal file
@ -0,0 +1,599 @@
|
||||
#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 // 结束编译指令块
|
||||
277
docs/examples/Integration/matlab_example.m
Normal file
277
docs/examples/Integration/matlab_example.m
Normal file
@ -0,0 +1,277 @@
|
||||
%% Matlab/Simulink 威胁源库集成示例
|
||||
% 演示如何在Matlab中使用ThreatSource仿真库
|
||||
%
|
||||
% 前置条件:
|
||||
% 1. 将 ThreatSource.dll 复制到 Matlab 路径
|
||||
% 2. 将 data/ 目录复制到当前工作目录
|
||||
% 3. 确保 Matlab 支持 .NET 8.0
|
||||
|
||||
%% 清理环境
|
||||
clear; clc; close all;
|
||||
|
||||
%% 加载 .NET 程序集
|
||||
fprintf('正在加载 ThreatSource.dll...\n');
|
||||
try
|
||||
% 假设 dll 文件在当前目录或 Matlab 路径中
|
||||
dll_path = 'ThreatSource.dll';
|
||||
if ~exist(dll_path, 'file')
|
||||
dll_path = fullfile(pwd, 'ThreatSource.dll');
|
||||
end
|
||||
|
||||
if exist(dll_path, 'file')
|
||||
NET.addAssembly(dll_path);
|
||||
fprintf('成功加载威胁源库\n');
|
||||
else
|
||||
error('找不到 ThreatSource.dll 文件');
|
||||
end
|
||||
catch ME
|
||||
fprintf('加载失败: %s\n', ME.message);
|
||||
return;
|
||||
end
|
||||
|
||||
%% 创建适配器实例
|
||||
fprintf('创建 Matlab 适配器...\n');
|
||||
try
|
||||
% 注意:这里使用完整的命名空间路径
|
||||
adapter = NET.createGeneric('MatlabSimulinkAdapter', {});
|
||||
fprintf('适配器创建成功\n');
|
||||
catch ME
|
||||
fprintf('适配器创建失败: %s\n', ME.message);
|
||||
return;
|
||||
end
|
||||
|
||||
%% 初始化仿真
|
||||
fprintf('初始化仿真系统...\n');
|
||||
time_step = 0.01; % 10ms 时间步长
|
||||
success = adapter.StartSimulation(time_step);
|
||||
|
||||
if ~success
|
||||
fprintf('仿真初始化失败\n');
|
||||
return;
|
||||
end
|
||||
fprintf('仿真系统初始化成功,时间步长: %.3f 秒\n', time_step);
|
||||
|
||||
%% 创建仿真场景
|
||||
fprintf('\n=== 创建仿真场景 ===\n');
|
||||
|
||||
% 目标参数
|
||||
target_id = 'target_001';
|
||||
target_pos = [5000, 0, 1000]; % 位置: [x, y, z] 米
|
||||
target_vel = [-50, 0, 0]; % 速度: [vx, vy, vz] 米/秒
|
||||
|
||||
% 创建目标
|
||||
success = adapter.CreateTarget(target_id, ...
|
||||
target_pos(1), target_pos(2), target_pos(3), ...
|
||||
target_vel(1), target_vel(2), target_vel(3));
|
||||
|
||||
if success
|
||||
fprintf('成功创建目标: %s\n', target_id);
|
||||
fprintf(' 位置: [%.0f, %.0f, %.0f] 米\n', target_pos);
|
||||
fprintf(' 速度: [%.1f, %.1f, %.1f] 米/秒\n', target_vel);
|
||||
else
|
||||
fprintf('目标创建失败\n');
|
||||
return;
|
||||
end
|
||||
|
||||
% 导弹参数
|
||||
missile_id = 'missile_001';
|
||||
missile_pos = [0, 0, 100]; % 发射位置: [x, y, z] 米
|
||||
|
||||
% 创建红外制导导弹
|
||||
success = adapter.CreateIRMissile(missile_id, ...
|
||||
missile_pos(1), missile_pos(2), missile_pos(3), target_id);
|
||||
|
||||
if success
|
||||
fprintf('成功创建红外制导导弹: %s\n', missile_id);
|
||||
fprintf(' 发射位置: [%.0f, %.0f, %.0f] 米\n', missile_pos);
|
||||
fprintf(' 目标: %s\n', target_id);
|
||||
else
|
||||
fprintf('导弹创建失败\n');
|
||||
return;
|
||||
end
|
||||
|
||||
%% 运行仿真循环
|
||||
fprintf('\n=== 开始仿真 ===\n');
|
||||
|
||||
% 仿真参数
|
||||
sim_duration = 5.0; % 仿真持续时间(秒)
|
||||
num_steps = int32(sim_duration / time_step);
|
||||
update_interval = 50; % 每50步显示一次状态
|
||||
|
||||
% 存储仿真数据
|
||||
time_data = zeros(num_steps, 1);
|
||||
missile_data = zeros(num_steps, 10); % [x,y,z,vx,vy,vz,roll,pitch,yaw,active]
|
||||
target_data = zeros(num_steps, 10);
|
||||
|
||||
fprintf('仿真参数:\n');
|
||||
fprintf(' 持续时间: %.1f 秒\n', sim_duration);
|
||||
fprintf(' 时间步长: %.3f 秒\n', time_step);
|
||||
fprintf(' 总步数: %d\n', num_steps);
|
||||
|
||||
% 仿真主循环
|
||||
for step = 1:num_steps
|
||||
% 更新仿真
|
||||
success = adapter.UpdateSimulation(time_step);
|
||||
if ~success
|
||||
fprintf('第 %d 步仿真更新失败\n', step);
|
||||
break;
|
||||
end
|
||||
|
||||
% 记录时间
|
||||
current_time = adapter.GetCurrentTime();
|
||||
time_data(step) = current_time;
|
||||
|
||||
% 获取实体状态
|
||||
missile_state = adapter.GetEntityState(missile_id);
|
||||
target_state = adapter.GetEntityState(target_id);
|
||||
|
||||
% 转换 .NET 数组为 Matlab 数组
|
||||
if ~isempty(missile_state)
|
||||
missile_data(step, :) = double(missile_state);
|
||||
end
|
||||
if ~isempty(target_state)
|
||||
target_data(step, :) = double(target_state);
|
||||
end
|
||||
|
||||
% 定期显示状态
|
||||
if mod(step, update_interval) == 0 || step == 1
|
||||
fprintf('时间: %6.2f 秒 | ', current_time);
|
||||
if ~isempty(missile_state) && length(missile_state) >= 10
|
||||
fprintf('导弹位置: [%6.0f, %6.0f, %6.0f] | ', ...
|
||||
missile_state(1), missile_state(2), missile_state(3));
|
||||
fprintf('活动: %s\n', missile_state(10) > 0.5 ? '是' : '否');
|
||||
else
|
||||
fprintf('导弹状态获取失败\n');
|
||||
end
|
||||
end
|
||||
|
||||
% 检查导弹是否仍然活动
|
||||
if ~isempty(missile_state) && length(missile_state) >= 10
|
||||
if missile_state(10) < 0.5 % 导弹已失活
|
||||
fprintf('导弹在第 %.2f 秒失活\n', current_time);
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
%% 显示仿真结果
|
||||
fprintf('\n=== 仿真结果分析 ===\n');
|
||||
|
||||
% 获取所有实体ID
|
||||
entity_ids = adapter.GetAllEntityIds();
|
||||
fprintf('仿真中的实体数量: %d\n', length(entity_ids));
|
||||
for i = 1:length(entity_ids)
|
||||
fprintf(' - %s\n', char(entity_ids(i)));
|
||||
end
|
||||
|
||||
% 计算统计信息
|
||||
valid_steps = sum(time_data > 0);
|
||||
fprintf('有效仿真步数: %d / %d\n', valid_steps, num_steps);
|
||||
|
||||
if valid_steps > 0
|
||||
% 导弹轨迹分析
|
||||
missile_pos = missile_data(1:valid_steps, 1:3);
|
||||
target_pos_final = target_data(1:valid_steps, 1:3);
|
||||
|
||||
% 计算导弹飞行距离
|
||||
if size(missile_pos, 1) > 1
|
||||
distances = sqrt(sum(diff(missile_pos).^2, 2));
|
||||
total_distance = sum(distances);
|
||||
fprintf('导弹总飞行距离: %.1f 米\n', total_distance);
|
||||
end
|
||||
|
||||
% 计算最终距离
|
||||
if valid_steps > 1
|
||||
final_missile_pos = missile_pos(end, :);
|
||||
final_target_pos = target_pos_final(end, :);
|
||||
final_distance = norm(final_missile_pos - final_target_pos);
|
||||
fprintf('最终导弹-目标距离: %.1f 米\n', final_distance);
|
||||
end
|
||||
end
|
||||
|
||||
%% 绘制仿真结果
|
||||
if valid_steps > 10 % 确保有足够的数据点
|
||||
fprintf('\n绘制仿真轨迹...\n');
|
||||
|
||||
figure('Name', '威胁源仿真轨迹', 'Position', [100, 100, 1200, 800]);
|
||||
|
||||
% 3D轨迹图
|
||||
subplot(2, 2, 1);
|
||||
plot3(missile_data(1:valid_steps, 1), missile_data(1:valid_steps, 2), ...
|
||||
missile_data(1:valid_steps, 3), 'r-', 'LineWidth', 2);
|
||||
hold on;
|
||||
plot3(target_data(1:valid_steps, 1), target_data(1:valid_steps, 2), ...
|
||||
target_data(1:valid_steps, 3), 'b--', 'LineWidth', 2);
|
||||
xlabel('X (米)'); ylabel('Y (米)'); zlabel('Z (米)');
|
||||
title('3D 轨迹图');
|
||||
legend('导弹', '目标', 'Location', 'best');
|
||||
grid on; axis equal;
|
||||
|
||||
% 高度vs时间
|
||||
subplot(2, 2, 2);
|
||||
plot(time_data(1:valid_steps), missile_data(1:valid_steps, 3), 'r-', 'LineWidth', 2);
|
||||
hold on;
|
||||
plot(time_data(1:valid_steps), target_data(1:valid_steps, 3), 'b--', 'LineWidth', 2);
|
||||
xlabel('时间 (秒)'); ylabel('高度 (米)');
|
||||
title('高度变化');
|
||||
legend('导弹', '目标', 'Location', 'best');
|
||||
grid on;
|
||||
|
||||
% 速度vs时间
|
||||
subplot(2, 2, 3);
|
||||
missile_speed = sqrt(sum(missile_data(1:valid_steps, 4:6).^2, 2));
|
||||
target_speed = sqrt(sum(target_data(1:valid_steps, 4:6).^2, 2));
|
||||
plot(time_data(1:valid_steps), missile_speed, 'r-', 'LineWidth', 2);
|
||||
hold on;
|
||||
plot(time_data(1:valid_steps), target_speed, 'b--', 'LineWidth', 2);
|
||||
xlabel('时间 (秒)'); ylabel('速度 (米/秒)');
|
||||
title('速度变化');
|
||||
legend('导弹', '目标', 'Location', 'best');
|
||||
grid on;
|
||||
|
||||
% 导弹-目标距离vs时间
|
||||
subplot(2, 2, 4);
|
||||
distances = sqrt(sum((missile_data(1:valid_steps, 1:3) - target_data(1:valid_steps, 1:3)).^2, 2));
|
||||
plot(time_data(1:valid_steps), distances, 'g-', 'LineWidth', 2);
|
||||
xlabel('时间 (秒)'); ylabel('距离 (米)');
|
||||
title('导弹-目标距离');
|
||||
grid on;
|
||||
|
||||
% 保存图像
|
||||
saveas(gcf, 'threat_source_simulation_result.png');
|
||||
fprintf('仿真结果图已保存为: threat_source_simulation_result.png\n');
|
||||
end
|
||||
|
||||
%% 清理资源
|
||||
fprintf('\n=== 清理资源 ===\n');
|
||||
try
|
||||
adapter.StopSimulation();
|
||||
fprintf('仿真已停止\n');
|
||||
catch ME
|
||||
fprintf('停止仿真时出错: %s\n', ME.message);
|
||||
end
|
||||
|
||||
fprintf('Matlab 威胁源库集成示例完成\n');
|
||||
|
||||
%% 辅助函数:导出数据到文件
|
||||
function export_simulation_data(time_data, missile_data, target_data, filename)
|
||||
try
|
||||
% 创建数据表
|
||||
data_table = table(time_data, ...
|
||||
missile_data(:,1), missile_data(:,2), missile_data(:,3), ...
|
||||
missile_data(:,4), missile_data(:,5), missile_data(:,6), ...
|
||||
target_data(:,1), target_data(:,2), target_data(:,3), ...
|
||||
target_data(:,4), target_data(:,5), target_data(:,6), ...
|
||||
'VariableNames', {'Time', ...
|
||||
'Missile_X', 'Missile_Y', 'Missile_Z', ...
|
||||
'Missile_VX', 'Missile_VY', 'Missile_VZ', ...
|
||||
'Target_X', 'Target_Y', 'Target_Z', ...
|
||||
'Target_VX', 'Target_VY', 'Target_VZ'});
|
||||
|
||||
% 保存为CSV文件
|
||||
writetable(data_table, filename);
|
||||
fprintf('仿真数据已导出到: %s\n', filename);
|
||||
catch ME
|
||||
fprintf('导出数据失败: %s\n', ME.message);
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user