浏览模型示例

打开模型示例 rtwdemo_roll。

open_system('rtwdemo_roll')

该模型包含不连接到根级别 Inport 或 Outport 模块的内部信号。某些信号具有名称,例如 phiCmd 信号。

该模型还包含一些维护状态数据的模块。例如,在 BasicRollMode 子系统中,标记为 Integrator 的 Discrete-Time Integrator 模块用于维护状态。

在模型中,将 Configuration Parameters > Code Generation > System target file 设置为 grt.tlc。

set_param('rtwdemo_roll','SystemTargetFile','grt.tlc')

检查 Configuration Parameters > Code Generation > Interface > Code interface packaging 的设置。设置 Nonreusable function 表示生成的代码不可重用(可重入)。

对于此示例,通过清除 Configuration Parameters > Code Generation > Interface > Advanced parameters > Mat-file logging 生成更简单的代码。

set_param('rtwdemo_roll','MatFileLogging','off')

生成不可重用的代码

设置以下配置参数:

将 Default parameter behavior 设置为 Tunable。

清除 Signal storage reuse。

set_param('rtwdemo_roll','DefaultParameterBehavior','Tunable',...

'OptimizeBlockIOStorage','off')

从模型中生成代码。

rtwbuild('rtwdemo_roll')

### Starting build procedure for: rtwdemo_roll

### Successful completion of build procedure for: rtwdemo_roll

文件 rtwdemo_roll.h 定义了几种表示内部数据的结构体类型。例如,模块输入和输出结构体为模型中的每个内部信号定义一个字段。每个字段名称都派生自生成该信号的模块的名称,或者派生自该信号的名称(如果您指定了信号名称)。

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.h');

rtwdemodbtype(file,...

'/* Block signals (default storage) */','} B_rtwdemo_roll_T;',1,1)

/* Block signals (default storage) */

typedef struct {

real32_T phiCmd; /* '/ModeSwitch' */

real32_T Abs; /* '/Abs' */

real32_T FixPtUnitDelay1; /* '/FixPt Unit Delay1' */

real32_T Xnew; /* '/Enable' */

real32_T TKSwitch; /* '/TKSwitch' */

real32_T RefSwitch; /* '/RefSwitch' */

real32_T Integrator; /* '/Integrator' */

real32_T DispLimit; /* '/DispLimit' */

real32_T Sum; /* '/Sum' */

real32_T DispGain; /* '/DispGain' */

real32_T RateLimit; /* '/RateLimit' */

real32_T Sum1; /* '/Sum1' */

real32_T RateGain; /* '/RateGain' */

real32_T Sum2; /* '/Sum2' */

real32_T CmdLimit; /* '/CmdLimit' */

real32_T IntGain; /* '/IntGain' */

real32_T hdgError; /* '/Sum' */

real32_T DispGain_a; /* '/DispGain' */

real32_T Product; /* '/Product' */

boolean_T NotEngaged; /* '/NotEngaged' */

boolean_T TKThreshold; /* '/TKThreshold' */

boolean_T RefThreshold2; /* '/RefThreshold2' */

boolean_T RefThreshold1; /* '/RefThreshold1' */

boolean_T Or; /* '/Or' */

boolean_T NotEngaged_e; /* '/NotEngaged' */

} B_rtwdemo_roll_T;

该文件定义一种 DWork 结构体类型,用于表示模块状态,例如 Discrete-Time Integrator 模块的状态。

rtwdemodbtype(file,...

'/* Block states (default storage) for system','} DW_rtwdemo_roll_T;',1,1)

/* Block states (default storage) for system '' */

typedef struct {

real32_T FixPtUnitDelay1_DSTATE; /* '/FixPt Unit Delay1' */

real32_T Integrator_DSTATE; /* '/Integrator' */

int8_T Integrator_PrevResetState; /* '/Integrator' */

} DW_rtwdemo_roll_T;

该文件定义一种表示参数数据的结构体类型。模型中的每个可调模块参数(例如 Gain 模块的 Gain 参数)显示为此结构体的一个字段。如果模块参数从 MATLAB 变量或 Simulink.Parameter 对象获取其参数值,则该变量或对象显示为字段,而不是模块参数。

该文件还定义一种结构体类型,即实时模型数据结构体,其单个字段表示一种运行时指示,用于指示生成的代码在执行期间是否遇到错误。

rtwdemodbtype(file,'/* Real-time Model Data Structure */',...

'/* Block parameters (default storage) */',1,0)

/* Real-time Model Data Structure */

struct tag_RTM_rtwdemo_roll_T {

const char_T *errorStatus;

};

对于表示实时模型数据结构体的结构体类型,文件 rtwdemo_roll_types.h 会创建一个别名,生成的代码稍后将使用该别名为结构体分配内存。

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll_types.h');

rtwdemodbtype(file,'/* Forward declaration for rtModel */',...

'RT_MODEL_rtwdemo_roll_T;',1,1)

/* Forward declaration for rtModel */

typedef struct tag_RTM_rtwdemo_roll_T RT_MODEL_rtwdemo_roll_T;

rtwdemo_roll.c 使用这些结构体类型来定义用于为生成的算法存储内部数据的全局结构体变量(为其分配内存)。该文件还定义表示实时模型数据结构体的变量和指向该结构体的指针。

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');

rtwdemodbtype(file,'/* Block signals (default storage) */',...

'= &rtwdemo_roll_M_;',1,1)

/* Block signals (default storage) */

B_rtwdemo_roll_T rtwdemo_roll_B;

/* Block states (default storage) */

DW_rtwdemo_roll_T rtwdemo_roll_DW;

/* External inputs (root inport signals with default storage) */

ExtU_rtwdemo_roll_T rtwdemo_roll_U;

/* External outputs (root outports fed by signals with default storage) */

ExtY_rtwdemo_roll_T rtwdemo_roll_Y;

/* Real-time model */

RT_MODEL_rtwdemo_roll_T rtwdemo_roll_M_;

RT_MODEL_rtwdemo_roll_T *const rtwdemo_roll_M = &rtwdemo_roll_M_;

模型 step 函数(表示主模型算法)使用 void void 接口(不带参数)。

rtwdemodbtype(file,...

'/* Model step function */','void rtwdemo_roll_step(void)',1,1)

/* Model step function */

void rtwdemo_roll_step(void)

在函数定义中,算法通过直接访问全局变量来执行计算并将中间结果存储在信号和状态结构体中。该算法还从对应的全局变量中读取参数数据。例如,在 BasicRollMode 子系统中,为 Integrator 模块生成的代码在结构体中读取和写入信号、状态和参数数据。

rtwdemodbtype(file,'/* DiscreteIntegrator: ''/Integrator'' *',...

'/* End of DiscreteIntegrator: ''/Integrator'' */',1,1)

/* DiscreteIntegrator: '/Integrator' */

if (rtwdemo_roll_B.NotEngaged_e || (rtwdemo_roll_DW.Integrator_PrevResetState

!= 0)) {

rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.Integrator_IC;

}

if (rtwdemo_roll_DW.Integrator_DSTATE >= rtwdemo_roll_P.intLim) {

rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.intLim;

} else {

if (rtwdemo_roll_DW.Integrator_DSTATE <= rtwdemo_roll_P.Integrator_LowerSat)

{

rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.Integrator_LowerSat;

}

}

rtwdemo_roll_B.Integrator = rtwdemo_roll_DW.Integrator_DSTATE;

由于存在 void void 接口和直接数据访问,该函数不可重入。如果在一个应用程序中多次调用该函数,则每次调用都会将数据写入全局结构体变量,后续调用可以读取该数据,从而导致各次调用之间出现意外的干扰。

模型初始化函数 rtwdemo_roll_initialize 将所有内部数据初始化为零。该函数还通过调用专用宏函数对错误状态进行初始化。初始化函数直接访问全局变量,这意味着该函数不可重入。

rtwdemodbtype(file,'/* Model initialize function */',...

'sizeof(DW_rtwdemo_roll_T));',1,1)

/* Model initialize function */

void rtwdemo_roll_initialize(void)

{

/* Registration code */

/* initialize error status */

rtmSetErrorStatus(rtwdemo_roll_M, (NULL));

/* block I/O */

(void) memset(((void *) &rtwdemo_roll_B), 0,

sizeof(B_rtwdemo_roll_T));

/* states (dwork) */

(void) memset((void *)&rtwdemo_roll_DW, 0,

sizeof(DW_rtwdemo_roll_T));

然后,该函数将 DWork 结构体中的模块状态初始化为模型中的模块参数指定的初始值。模型的三个状态中的两个具有可调初始值,因此代码通过从参数结构体中读取数据来初始化它们。

rtwdemodbtype(file,...

'/* SystemInitialize for Atomic SubSystem: ''/RollAngleReference'' */',...

'/* Model terminate function */',1,0)

/* SystemInitialize for Atomic SubSystem: '/RollAngleReference' */

/* InitializeConditions for UnitDelay: '/FixPt Unit Delay1' */

rtwdemo_roll_DW.FixPtUnitDelay1_DSTATE = rtwdemo_roll_P.LatchPhi_vinit;

/* End of SystemInitialize for SubSystem: '/RollAngleReference' */

/* SystemInitialize for Atomic SubSystem: '/BasicRollMode' */

/* InitializeConditions for DiscreteIntegrator: '/Integrator' */

rtwdemo_roll_DW.Integrator_DSTATE = rtwdemo_roll_P.Integrator_IC;

rtwdemo_roll_DW.Integrator_PrevResetState = 0;

/* End of SystemInitialize for SubSystem: '/BasicRollMode' */

}

生成可重用的代码

您可以将生成的代码配置为可重入代码,这意味着您可以在一个应用程序中多次调用入口函数。使用此配置时,入口函数并不直接访问全局变量,而是通过形参(指针参数)接受内部数据。通过使用这些指针参数,每次调用都可以在一组单独的全局变量中维护内部数据,从而防止各次调用之间出现意外的交互。

在模型中,将 Configuration Parameters > Code Generation > Interface > Code interface packaging 设置为 Reusable function。

set_param('rtwdemo_roll','CodeInterfacePackaging','Reusable function')

从模型中生成代码。

rtwbuild('rtwdemo_roll')

### Starting build procedure for: rtwdemo_roll

### Successful completion of build procedure for: rtwdemo_roll

现在,在 rtwdemo_roll.h 中,实时模型数据结构体包含指向错误指示的指针、内部数据以及 ExtU 和 ExtY 子结构体形式的主输入和输出数据(其字段表示模型根级别的 Inport 和 Outport 模块)。

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.h');

rtwdemodbtype(file,'/* Real-time Model Data Structure */',...

'/* External data declarations for dependent source files */',1,0)

/* Real-time Model Data Structure */

struct tag_RTM_rtwdemo_roll_T {

const char_T *errorStatus;

B_rtwdemo_roll_T *blockIO;

ExtU_rtwdemo_roll_T *inputs;

ExtY_rtwdemo_roll_T *outputs;

DW_rtwdemo_roll_T *dwork;

};

/* Block parameters (default storage) */

extern P_rtwdemo_roll_T rtwdemo_roll_P;

要在一个应用程序中多次调用生成的代码,您的代码必须在每次调用时为实时模型数据结构体分配内存。文件 rtwdemo_roll.c 定义一个专用函数,它为新实时模型数据结构体分配内存并返回指向该结构体的指针。该函数还为模型数据结构体中的字段指向的子结构体(例如 DWork 结构体)分配内存。

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');

rtwdemodbtype(file,'/* Model data allocation function */',...

'RT_MODEL_rtwdemo_roll_T *rtwdemo_roll(void)',1,1)

/* Model data allocation function */

RT_MODEL_rtwdemo_roll_T *rtwdemo_roll(void)

模型 step 函数接受表示实时模型数据结构体的参数。

rtwdemodbtype(file,'/* Model step function */','void rtwdemo_roll_step',1,1)

/* Model step function */

void rtwdemo_roll_step(RT_MODEL_rtwdemo_roll_T *const rtwdemo_roll_M)

在函数定义中,算法首先将每个指针从实时模型数据结构体中提取到局部变量中。

rtwdemodbtype(file,'*rtwdemo_roll_B =','rtwdemo_roll_M->outputs;',1,1)

B_rtwdemo_roll_T *rtwdemo_roll_B = ((B_rtwdemo_roll_T *)

rtwdemo_roll_M->blockIO);

DW_rtwdemo_roll_T *rtwdemo_roll_DW = ((DW_rtwdemo_roll_T *)

rtwdemo_roll_M->dwork);

ExtU_rtwdemo_roll_T *rtwdemo_roll_U = (ExtU_rtwdemo_roll_T *)

rtwdemo_roll_M->inputs;

ExtY_rtwdemo_roll_T *rtwdemo_roll_Y = (ExtY_rtwdemo_roll_T *)

rtwdemo_roll_M->outputs;

然后,为了访问存储在全局内存中的内部数据,该算法与这些局部变量交互。

rtwdemodbtype(file,'/* DiscreteIntegrator: ''/Integrator'' */',...

'/* End of DiscreteIntegrator: ''/Integrator'' */',1,1)

/* DiscreteIntegrator: '/Integrator' */

if (rtwdemo_roll_B->NotEngaged_e ||

(rtwdemo_roll_DW->Integrator_PrevResetState != 0)) {

rtwdemo_roll_DW->Integrator_DSTATE = rtwdemo_roll_P.Integrator_IC;

}

if (rtwdemo_roll_DW->Integrator_DSTATE >= rtwdemo_roll_P.intLim) {

rtwdemo_roll_DW->Integrator_DSTATE = rtwdemo_roll_P.intLim;

} else {

if (rtwdemo_roll_DW->Integrator_DSTATE <= rtwdemo_roll_P.Integrator_LowerSat)

{

rtwdemo_roll_DW->Integrator_DSTATE = rtwdemo_roll_P.Integrator_LowerSat;

}

}

rtwdemo_roll_B->Integrator = rtwdemo_roll_DW->Integrator_DSTATE;

同样,模型初始化函数接受实时模型数据结构体作为参数。

rtwdemodbtype(file,...

'/* Model initialize function */','void rtwdemo_roll_initialize',1,1)

/* Model initialize function */

void rtwdemo_roll_initialize(RT_MODEL_rtwdemo_roll_T *const rtwdemo_roll_M)

由于您对入口函数的每次调用都与一个单独的实时模型数据结构体交互,因此可以避免各次调用之间发生意外交互。

使用代码生成优化消除内部数据

为了获得消耗更少内存的更高效代码,请选择优化,例如您在前面清除了的 Default parameter behavior。

set_param('rtwdemo_roll','DefaultParameterBehavior','Inlined',...

'OptimizeBlockIOStorage','on',...

'LocalBlockOutputs','on')

在此示例中,为了获得更简单的代码,请将 Code interface packaging 设置为 Nonreusable function。

set_param('rtwdemo_roll','CodeInterfacePackaging','Nonreusable function')

从模型中生成代码。

rtwbuild('rtwdemo_roll')

### Starting build procedure for: rtwdemo_roll

### Successful completion of build procedure for: rtwdemo_roll

现在,rtwdemo_roll.h 没有定义用于模块输入和输出的结构体。对于模型中的所有内部信号,优化要么已消除了存储,要么创建了局部函数变量而不是全局结构体字段。

优化未能消除三种模块状态的存储,因此文件继续定义 DWork 结构体类型。

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.h');

rtwdemodbtype(file,...

'/* Block states (default storage) for system','} DW_rtwdemo_roll_T;',1,1)

/* Block states (default storage) for system '' */

typedef struct {

real32_T FixPtUnitDelay1_DSTATE; /* '/FixPt Unit Delay1' */

real32_T Integrator_DSTATE; /* '/Integrator' */

int8_T Integrator_PrevResetState; /* '/Integrator' */

} DW_rtwdemo_roll_T;

现在,为 Discrete-Time Integrator 模块生成的代码仅在 DWork 结构体中存储状态和输出数据。

file = fullfile('rtwdemo_roll_grt_rtw','rtwdemo_roll.c');

rtwdemodbtype(file,'/* Update for DiscreteIntegrator: ''/Integrator''',...

'/* End of Update for DiscreteIntegrator: ''/Integrator'' */',1,1)

/* Update for DiscreteIntegrator: '/Integrator' incorporates:

* Gain: '/IntGain'

*/

rtwdemo_roll_DW.Integrator_DSTATE += 0.5F * rtb_TKSwitch * 0.025F;

if (rtwdemo_roll_DW.Integrator_DSTATE >= 5.0F) {

rtwdemo_roll_DW.Integrator_DSTATE = 5.0F;

} else {

if (rtwdemo_roll_DW.Integrator_DSTATE <= -5.0F) {

rtwdemo_roll_DW.Integrator_DSTATE = -5.0F;

}

}

rtwdemo_roll_DW.Integrator_PrevResetState = (int8_T)rtb_NotEngaged_f;

优化还消除了模型中模块参数的存储。例如,在 Discrete-Time Integrator 模块中,Upper saturation limit 和 Lower saturation limit 参数设置为 intLim 和 -intLim。intLim 是 Simulink.Parameter 对象,用于存储值 5。在为 Discrete-Time Integrator 生成的代码中,这些模块参数和 intLim 显示为内联字面数字 5.0F 和 -5.0F。

如果模型包含代码生成器不能直接内联的参数(例如数组参数),则代码会定义表示该数据的结构体类型。此常量参数结构体使用 const 存储类型限定符,因此某些编译工具链可以进一步优化程序集代码。

matlab 生成信号文件,生成的代码如何存储内部信号、状态和参数数据相关推荐

  1. [MATLAB]将.m文件生成dll文件

    环境:VS2017+MATLAB R2017a ①配置编译环境 在命令行窗口中输入"mbuild -setup"(横线前有一个空格),如果出现如下图所示的提示信息即为成功. 如果提 ...

  2. java jdom 设置第1行_Java通过jdom操作生成XML文件的实例代码下载

    工作需要,要生成xml文件,所以做了个小demo分享一下. 看代码吧~ main()里面没什么好说的 该写的都写了public static void main(String[] args) { // ...

  3. java代码查询索引文件实例_关于使用pdfbox的对PDF文件通过lucene生成索引文件IndexPDFFiles类代码示例...

    一.前言 下面通过pdfbox的pdfbox-2.0.9源码中org.apache.pdfbox.examples.lucene.IndexPDFFiles索引PDF文件生成类,基于apache的lu ...

  4. MATLAB通过txt文件生成图像

    今天学习<计算机视觉基础>,作者的没给1.7的素材,然后自己造了个数据.分享一下. % 创建一幅图像 a=imread('landscape.jpg'); % 读取landscape.jp ...

  5. 用JS生成MIDI文件(附代码)

    用JS生成MIDI文件 大家好,近期我们的课程需要我们做一个应用,我的的小组打算做一个在线的伴奏制作平台,这意味着我们需要知道如何在线制作音乐以及如何用浏览器播放. 小编我这一节就跟大家讲解下如何用J ...

  6. FPGA:生成固化文件(将代码固化到板子上面)

    题目概述: 为了能够让工程上电就能运行,则需要生成固化文件,将文件固化到板载flash中去,这样上电就可以启动. 在生成固化文件之前我们先打开工程时序约束文件,在时序约束文件里添加下面的一段原语: s ...

  7. linux makefile文件怎么生成,Makefile文件生成

    所必须的软件:autoconf (generate configuration script [configuration]) automake( aclocal:automatically gene ...

  8. 【OFF三维显示】通过MATLAB读取off文件生成三视图 提取轮廓线

    1.软件版本 MATLAB2021a 2.本算法理论知识 里共提供了100个OFF文件,用来验证不同三维物体的效果. 整个系统分为两个部分:off文件的获取以及不同视角的物体显示和轮廓显示. 其中OF ...

  9. matlab产生mif 文件,生成.mif文件的matlab程序

    天气: 晴朗 心情: 高兴 function mif_Gen(filename,var,width,depth) %       function miffile(filename,var,width ...

最新文章

  1. java夯实基础:final脑图
  2. CMake添加-g编译选项
  3. Google Chrome Source Code 源码下载
  4. SpringBoot:spring-boot-starter-parent
  5. git版本管理工具学习
  6. SQL2005 DDL触发器
  7. php 抓取天气情况 www.weather.com.cn
  8. android扫码支付宝ofo,ofo等六大单车接入支付宝扫码,一半共享单车可分享支付宝流量...
  9. 中国软件服务业政策和形势_赵小凡
  10. 一个关于var函数计算方差 / 标准差的问题
  11. 基于BCNN的汽车车型识别研究
  12. Laravel的ORM模型的find(),findOrFail(),first(),firstOrFail(),get(),list(),toArray()之间的区别是什么?
  13. 入门学习UI设计有哪些就业方向?
  14. 学计算机做纸质笔记,电脑诞生这么久,为什么你还是喜欢在纸上做笔记
  15. 计算机科学与技术专业导论3500,计算机科学与技术专业导论.docx
  16. 航班信息查询和检索系统
  17. 吴恩达老师DeepLearning系列课程最详细学习笔记之23—Jupyter Ipython笔记本的快速指南
  18. 黑客入侵万象服务器的方法
  19. 我酸了,蚂蚁上市,财富自由都是他们的4、蚂蚁金服上市,算算你离财富自由还有多远?...
  20. 【数据结构与算法】初识二叉树(下)

热门文章

  1. Java StreamTokenizer quoteChar()方法与示例
  2. 干货!操作系统基础知识汇总!转给要面试的同学吧
  3. NBear简介与使用图解
  4. 转:ORA-01126: 数据库必须已装载到此实例并且不在任何实例中打开
  5. 算法复习第六章第七章
  6. Ubuntu16.04 Caffe 编译安装步骤记录
  7. Tensorflow中查看gpu是否可用
  8. mariadb与mysql的兼容_「MySQL架构」MariaDB versus MySQL: Compatibility
  9. iphone双卡_单卡 iPhone 变双卡,3分钟搞定安卓备用机短信——IFTTT妙用
  10. php页面不断弹出值_电脑自动弹出网页怎么办