Simulink部署
这里介绍了如何在Simulink中调用生成的代码.
这里以Windows系统为例, 介绍如何在Simulink中调用生成的代码. 其他平台 的使用方法类似, 只需在Simulink中设置正确的编译器与链接库即可.
我们以轨迹跟踪控制问题为例, 该示例的文件结构如下:
working_dir/
├── traj_tracking/
│ ├── traj_tracking_prob.c
│ ├── traj_tracking_prob.h
│ ├── traj_tracking_solver.h
│ ├── libtraj_tracking_solver_static.lib
├── traj_tracking.py
├── traj_tracking_sim.slx
.
其中:
traj_tracking.py
是模型文件, 该文件中定义了轨迹跟踪控制问题的模型, 以及代码生成的相关设置 (其中platform
选择'windows-x86_64-mingw'
(Windows平台) ,lib_type
选择'static'
(静态链接库))traj_tracking/
是代码生成的目录traj_tracking_sim.slx
是Simulink模型文件
前置工作
在Matlab中选择MinGW编译器, 以便生成的代码可以在Simulink中运行:
>> mex -setup
MEX configured to use 'MinGW64 Compiler (C)' for C language compilation.
Matlab中选择的编译器需要兼容生成的求解器库, 否则会导致编译错误.
例如, 'windows-x86_64-mingw'
对应生成的求解器库, 在Matlab中需要选择MinGW编译器.
其他编译器 (如Visual Studio) 会导致编译错误.
使用S-Function调用生成的代码
这里我们使用S-Function Builder来调用生成的代码. 具体步骤如下:
- 打开Simulink, 新建一个模型
- 在Simulink中添加一个S-Function Builder模块, 双击打开
- 在S-Function Builder的Editor中包含求解器的头文件
#include "traj_tracking_prob.h"
#include "traj_tracking_solver.h" - 在S-Function Builder的Libraries中添加求解器的库文件
- 将
traj_tracking/
加入到include path中 - 将
libtraj_tracking_solver_static.lib
加入到libraries中 - 将
traj_tracking_prob.c
加入到source files中
- 将
到这里, S-Function Builder中引入求解器的头文件与库文件已经完成, 下面轨迹跟踪控制问题相关的具体的设置:
-
在S-Function Builder的Ports and Parameters中定义该模块的输入输出端口, 这里我们定义了3个输入端口 (x0, xref_traj, yref) 和3个输出端口 (u, iter, solve_time):
-
在S-Function Builder的Editor中实现轨迹跟踪控制器的初始化, 求解与终止函数
-
点击Build按钮, 生成S-Function模块:
下面是S-Function Builder的Editor中填入的完整代码:
/* Includes_BEGIN */
#include "traj_tracking_prob.h"
#include "traj_tracking_solver.h"
#include <math.h>
/* Includes_END */
/* Externs_BEGIN */
static Traj_tracking_Problem prob;
static Traj_tracking_Option option;
static Traj_tracking_WorkSpace ws;
static Traj_tracking_Output output;
/* Externs_END */
void traj_tracking_controller_Start_wrapper(void)
{
/* Start_BEGIN */
traj_tracking_init(&prob, &option, &ws);
option.print_level = 0;
option.try_warm_start_barrier = 1;
/* Start_END */
}
void traj_tracking_controller_Outputs_wrapper(const real_T *x0,
const real_T *xref_traj,
const real_T *yref,
real_T *u,
int32_T *iter,
real_T *solve_time)
{
/* Output_BEGIN */
const double vref = 1.0;
const double ts_discretization = 0.2;
/* params */
prob.param[TRAJ_TRACKING_PARAM_XWEIGHT] = 1.0;
prob.param[TRAJ_TRACKING_PARAM_YWEIGHT] = 1.0;
prob.param[TRAJ_TRACKING_PARAM_VWEIGHT] = 1.0;
// initial state
prob.param[TRAJ_TRACKING_PARAM_X0] = x0[0];
prob.param[TRAJ_TRACKING_PARAM_Y0] = x0[1];
prob.param[TRAJ_TRACKING_PARAM_PHI0] = x0[2];
prob.param[TRAJ_TRACKING_PARAM_V0] = x0[3];
// reference trajectory
prob.param[TRAJ_TRACKING_PARAM_VREF] = vref;
for (size_t i = 0; i < TRAJ_TRACKING_DIM_N; i++) {
prob.param_stage[i][TRAJ_TRACKING_PARAM_STAGE_XREF] = xref_traj[i];
}
prob.param[TRAJ_TRACKING_PARAM_YREF] = yref[0];
// solve
traj_tracking_solve(&prob, &option, &ws, &output);
u[0] = output.primal.var[0][TRAJ_TRACKING_VAR_A];
u[1] = output.primal.var[0][TRAJ_TRACKING_VAR_DELTA];
iter[0] = output.iter;
solve_time[0] = output.solve_time;
/* Output_END */
}
void traj_tracking_controller_Terminate_wrapper(void)
{
/* Terminate_BEGIN */
/* Terminate_END */
}
运行Simulink模型
完成S-Function设置, 并且完成轨迹跟踪控制问题的闭环仿真搭建后, 运行Simulink模型即可.
整体闭环仿真框图如下图所示:
闭环仿真轨迹如下图所示:
附录
以下是本节中用到的文件:
需要运行traj_tracking.py
生成代码, 然后在Simulink中打开traj_tracking_sim_2017a.slx
文件, 运行仿真.