开箱报告,Simulink Toolbox库模块使用指南(七)——S-Fuction Builder模块

本文主要是介绍开箱报告,Simulink Toolbox库模块使用指南(七)——S-Fuction Builder模块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

前言

S-Fuction Builder

模块配置

编写Update_wrapper()

编写Outputs_wrapper()

Build S-Fuction

仿真验证

生成代码

Tips

分析和应用

总结


前言

        见《开箱报告,Simulink Toolbox库模块使用指南(一)——powergui模块》

        见《开箱报告,Simulink Toolbox库模块使用指南(二)——MATLAB Fuction模块》

        见《开箱报告,Simulink Toolbox库模块使用指南(三)——Simscape 电路仿真模块》

        见《开箱报告,Simulink Toolbox库模块使用指南(四)——S-Fuction模块》

        见《开箱报告,Simulink Toolbox库模块使用指南(五)——S-Fuction模块(C MEX S-Function)》

        见《开箱报告,Simulink Toolbox库模块使用指南(六)——S-Fuction模块(TLC)》

S-Fuction Builder

        S-Fuction Builter模块Mathworks官方Help对该部分内容的说明如下所示。

        DFT算法的原理讲解和模块开发在前几篇文章中已经完成了,本文介绍如何使用S-Fuction Builter模块一步到位地自动开发DFT算法模块,包括建立C MEX S-Function文件、TLC文件和编译生成等工作。

模块配置

        第一步是模块配置,包括S-Fuction的名字、开发语言、输入输出端口、状态变量和固定参数等,如下图所示:

编写Update_wrapper()

         第二步是编写Update_wrapper()函数,沿用前期C MEX S-Function的代码,使用自动生成的函数接口,写出的Update_wrapper()函数如下:

void DFT_CMexSfuncBuilder_Update_wrapper(const real_T *u0,real_T *y0,real_T *xD,const real_T *Freq, const int_T p_width0)
{
/* Update_BEGIN */static real_T Fs = 10e3;static real_T L = 5e3;real_T Sr_cos;real_T Sr_sin;real_T T;if(xD[0]<=L){   Sr_cos = cos(2*3.14*xD[4]*xD[1]);Sr_sin = sin(2*3.14*xD[4]*xD[1]);xD[2] = xD[2] + u0[0]*Sr_cos;xD[3] = xD[3] + u0[0]*Sr_sin;xD[0] = xD[0] + 1;T = 1/Fs;xD[1] = xD[1] + T;}
/* Update_END */
}

编写Outputs_wrapper()

        第三步是编写Outputs_wrapper()函数,沿用前期C MEX S-Function的代码,使用自动生成的函数接口,写出的Outputs_wrapper()函数如下:

void DFT_CMexSfuncBuilder_Outputs_wrapper(const real_T *u0,real_T *y0,const real_T *xD,const real_T *Freq, const int_T p_width0)
{
/* Output_BEGIN */
/* This sample sets the output equal to the inputy0[0] = u0[0]; For complex signals use: y0[0].re = u0[0].re; y0[0].im = u0[0].im;y1[0].re = u1[0].re;y1[0].im = u1[0].im;*/static real_T L = 5e3;real_T real = 0;real_T imag = 0;real_T modl = 0;if(xD[0]==L+1){real = xD[2]/L*2;imag = xD[3]/L*2;modl = sqrt(real*real + imag*imag);y0[0] = modl;       }
/* Output_END */
}

Build S-Fuction

        上述配置和函数编写完成后,点击Build按钮,可以看到如下是信息:

        其中,DFT_CMexSfuncBuilder.c文件就是自动生成的C MEX文件,DFT_CMexSfuncBuilder_wrapper.c文件是C MEX文件中调用的wrapper函数,DFT_CMexSfuncBuilder.tlc是自动生成的TLC文件。

        与此同时,工程文件夹里边还会自动生成DFT_CMexSfuncBuilder.mexw64、rtwmakecfg.m和SFB__DFT_CMexSfuncBuilder__SFB.mat,都是S-Fuction的执行文件和代码生成和编译的相关文件。

仿真验证

        将上述编写好的S-Fuction Buider模块,放入Simulink模型中进行验证,如下所示:

        运行上述模型,得到的电流和电压如上图所示,与前期C MEX S-Function的结果一致。

        至此,可以证明该S-Fuction Buider模块可以较好地实现,手动开发C MEX S-Function相同的功能。

生成代码

        点击代码生成按钮,可以看到如下过程提示:

        点击打开报告按钮,可以看到如下生成报告:

        点击左侧的sfucbuilder.c超链接,可以看到如下生成的代码,其中30行到117行是该模型主要功能的代码,47行到86行是与我们S-Fuction Buider模块直接相关的代码。

File: sfucbuilder.c
1	/*
2	 * sfucbuilder.c
3	 *
4	 * Code generation for model "sfucbuilder".
5	 *
6	 * Model version              : 1.52
7	 * Simulink Coder version : 9.4 (R2020b) 29-Jul-2020
8	 * C source code generated on : Thu Oct  5 22:12:11 2023
9	 *
10	 * Target selection: grt.tlc
11	 * Note: GRT includes extra infrastructure and instrumentation for prototyping
12	 * Embedded hardware selection: Intel->x86-64 (Windows64)
13	 * Code generation objectives: Unspecified
14	 * Validation result: Not run
15	 */
16	
17	#include "sfucbuilder.h"
18	#include "sfucbuilder_private.h"
19	
20	/* Block signals (default storage) */
21	B_sfucbuilder_T sfucbuilder_B;
22	
23	/* Block states (default storage) */
24	DW_sfucbuilder_T sfucbuilder_DW;
25	
26	/* Real-time model */
27	static RT_MODEL_sfucbuilder_T sfucbuilder_M_;
28	RT_MODEL_sfucbuilder_T *const sfucbuilder_M = &sfucbuilder_M_;
29	
30	/* Model step function */
31	void sfucbuilder_step(void)
32	{
33	  /* Selector: '<Root>/Selector5' incorporates:
34	   *  Constant: '<Root>/Constant6'
35	   *  UnitDelay: '<S1>/Output'
36	   */
37	  sfucbuilder_B.Selector5 =
38	    sfucbuilder_ConstP.Constant6_Value[sfucbuilder_DW.Output_DSTATE];
39	
40	  /* Selector: '<Root>/Selector4' incorporates:
41	   *  Constant: '<Root>/Constant5'
42	   *  UnitDelay: '<S1>/Output'
43	   */
44	  sfucbuilder_B.Selector4 =
45	    sfucbuilder_ConstP.Constant5_Value[sfucbuilder_DW.Output_DSTATE];
46	
47	  /* S-Function (DFT_CMexSfuncBuilder): '<Root>/S-Function Builder' */
48	  DFT_CMexSfuncBuilder_Outputs_wrapper(&sfucbuilder_B.Selector4,
49	    &sfucbuilder_B.SFunctionBuilder, &sfucbuilder_DW.SFunctionBuilder_DSTATE[0],
50	    &sfucbuilder_ConstP.pooled1, 1);
51	
52	  /* S-Function (DFT_CMexSfuncBuilder): '<Root>/S-Function Builder1' */
53	  DFT_CMexSfuncBuilder_Outputs_wrapper(&sfucbuilder_B.Selector5,
54	    &sfucbuilder_B.SFunctionBuilder1, &sfucbuilder_DW.SFunctionBuilder1_DSTATE[0],
55	    &sfucbuilder_ConstP.pooled1, 1);
56	
57	  /* Switch: '<S3>/FixPt Switch' incorporates:
58	   *  Constant: '<S2>/FixPt Constant'
59	   *  Sum: '<S2>/FixPt Sum1'
60	   *  UnitDelay: '<S1>/Output'
61	   */
62	  if ((uint16_T)(sfucbuilder_DW.Output_DSTATE + 1U) > 4999) {
63	    /* Update for UnitDelay: '<S1>/Output' incorporates:
64	     *  Constant: '<S3>/Constant'
65	     */
66	    sfucbuilder_DW.Output_DSTATE = 0U;
67	  } else {
68	    /* Update for UnitDelay: '<S1>/Output' */
69	    sfucbuilder_DW.Output_DSTATE++;
70	  }
71	
72	  /* End of Switch: '<S3>/FixPt Switch' */
73	
74	  /* Update for S-Function (DFT_CMexSfuncBuilder): '<Root>/S-Function Builder' */
75	
76	  /* S-Function "DFT_CMexSfuncBuilder_wrapper" Block: <Root>/S-Function Builder */
77	  DFT_CMexSfuncBuilder_Update_wrapper(&sfucbuilder_B.Selector4,
78	    &sfucbuilder_B.SFunctionBuilder, &sfucbuilder_DW.SFunctionBuilder_DSTATE[0],
79	    &sfucbuilder_ConstP.pooled1, 1);
80	
81	  /* Update for S-Function (DFT_CMexSfuncBuilder): '<Root>/S-Function Builder1' */
82	
83	  /* S-Function "DFT_CMexSfuncBuilder_wrapper" Block: <Root>/S-Function Builder1 */
84	  DFT_CMexSfuncBuilder_Update_wrapper(&sfucbuilder_B.Selector5,
85	    &sfucbuilder_B.SFunctionBuilder1, &sfucbuilder_DW.SFunctionBuilder1_DSTATE[0],
86	    &sfucbuilder_ConstP.pooled1, 1);
87	
88	  /* Matfile logging */
89	  rt_UpdateTXYLogVars(sfucbuilder_M->rtwLogInfo,
90	                      (&sfucbuilder_M->Timing.taskTime0));
91	
92	  /* signal main to stop simulation */
93	  {                                    /* Sample time: [0.001s, 0.0s] */
94	    if ((rtmGetTFinal(sfucbuilder_M)!=-1) &&
95	        !((rtmGetTFinal(sfucbuilder_M)-sfucbuilder_M->Timing.taskTime0) >
96	          sfucbuilder_M->Timing.taskTime0 * (DBL_EPSILON))) {
97	      rtmSetErrorStatus(sfucbuilder_M, "Simulation finished");
98	    }
99	  }
100	
101	  /* Update absolute time for base rate */
102	  /* The "clockTick0" counts the number of times the code of this task has
103	   * been executed. The absolute time is the multiplication of "clockTick0"
104	   * and "Timing.stepSize0". Size of "clockTick0" ensures timer will not
105	   * overflow during the application lifespan selected.
106	   * Timer of this task consists of two 32 bit unsigned integers.
107	   * The two integers represent the low bits Timing.clockTick0 and the high bits
108	   * Timing.clockTickH0. When the low bit overflows to 0, the high bits increment.
109	   */
110	  if (!(++sfucbuilder_M->Timing.clockTick0)) {
111	    ++sfucbuilder_M->Timing.clockTickH0;
112	  }
113	
114	  sfucbuilder_M->Timing.taskTime0 = sfucbuilder_M->Timing.clockTick0 *
115	    sfucbuilder_M->Timing.stepSize0 + sfucbuilder_M->Timing.clockTickH0 *
116	    sfucbuilder_M->Timing.stepSize0 * 4294967296.0;
117	}
118	
119	/* Model initialize function */
120	void sfucbuilder_initialize(void)
121	{
122	  /* Registration code */
123	
124	  /* initialize non-finites */
125	  rt_InitInfAndNaN(sizeof(real_T));
126	
127	  /* initialize real-time model */
128	  (void) memset((void *)sfucbuilder_M, 0,
129	                sizeof(RT_MODEL_sfucbuilder_T));
130	  rtmSetTFinal(sfucbuilder_M, 10.0);
131	  sfucbuilder_M->Timing.stepSize0 = 0.001;
132	
133	  /* Setup for data logging */
134	  {
135	    static RTWLogInfo rt_DataLoggingInfo;
136	    rt_DataLoggingInfo.loggingInterval = NULL;
137	    sfucbuilder_M->rtwLogInfo = &rt_DataLoggingInfo;
138	  }
139	
140	  /* Setup for data logging */
141	  {
142	    rtliSetLogXSignalInfo(sfucbuilder_M->rtwLogInfo, (NULL));
143	    rtliSetLogXSignalPtrs(sfucbuilder_M->rtwLogInfo, (NULL));
144	    rtliSetLogT(sfucbuilder_M->rtwLogInfo, "tout");
145	    rtliSetLogX(sfucbuilder_M->rtwLogInfo, "");
146	    rtliSetLogXFinal(sfucbuilder_M->rtwLogInfo, "");
147	    rtliSetLogVarNameModifier(sfucbuilder_M->rtwLogInfo, "rt_");
148	    rtliSetLogFormat(sfucbuilder_M->rtwLogInfo, 0);
149	    rtliSetLogMaxRows(sfucbuilder_M->rtwLogInfo, 0);
150	    rtliSetLogDecimation(sfucbuilder_M->rtwLogInfo, 1);
151	    rtliSetLogY(sfucbuilder_M->rtwLogInfo, "");
152	    rtliSetLogYSignalInfo(sfucbuilder_M->rtwLogInfo, (NULL));
153	    rtliSetLogYSignalPtrs(sfucbuilder_M->rtwLogInfo, (NULL));
154	  }
155	
156	  /* block I/O */
157	  (void) memset(((void *) &sfucbuilder_B), 0,
158	                sizeof(B_sfucbuilder_T));
159	
160	  /* states (dwork) */
161	  (void) memset((void *)&sfucbuilder_DW, 0,
162	                sizeof(DW_sfucbuilder_T));
163	
164	  /* Matfile logging */
165	  rt_StartDataLoggingWithStartTime(sfucbuilder_M->rtwLogInfo, 0.0, rtmGetTFinal
166	    (sfucbuilder_M), sfucbuilder_M->Timing.stepSize0, (&rtmGetErrorStatus
167	    (sfucbuilder_M)));
168	
169	  /* InitializeConditions for UnitDelay: '<S1>/Output' */
170	  sfucbuilder_DW.Output_DSTATE = 0U;
171	
172	  /* InitializeConditions for S-Function (DFT_CMexSfuncBuilder): '<Root>/S-Function Builder' */
173	
174	  /* S-Function Block: <Root>/S-Function Builder */
175	  {
176	    real_T initVector[5] = { 1, 0, 0, 0, 50.0 };
177	
178	    {
179	      int_T i1;
180	      real_T *dw_DSTATE = &sfucbuilder_DW.SFunctionBuilder_DSTATE[0];
181	      for (i1=0; i1 < 5; i1++) {
182	        dw_DSTATE[i1] = initVector[i1];
183	      }
184	    }
185	  }
186	
187	  /* InitializeConditions for S-Function (DFT_CMexSfuncBuilder): '<Root>/S-Function Builder1' */
188	
189	  /* S-Function Block: <Root>/S-Function Builder1 */
190	  {
191	    real_T initVector[5] = { 1, 0, 0, 0, 50.0 };
192	
193	    {
194	      int_T i1;
195	      real_T *dw_DSTATE = &sfucbuilder_DW.SFunctionBuilder1_DSTATE[0];
196	      for (i1=0; i1 < 5; i1++) {
197	        dw_DSTATE[i1] = initVector[i1];
198	      }
199	    }
200	  }
201	}
202	
203	/* Model terminate function */
204	void sfucbuilder_terminate(void)
205	{
206	  /* (no terminate code required) */
207	}
208	

        人工检查上述自动生成的C代码,可以实现该Simulink模型设计的功能。

        至此,可以证明该S-Fuction Buider模块可以较好地实现,手动开发TLC相同的功能。

Tips

        本文沿用的例子--DFT算法S-Fuction开发,涉及到一个参数Freq。按照前期C MEX S-Function开发的经验,是可以通过函数直接引用的Freq = (real_T) *mxGetPr(ssGetSFcnParam(S,0)),但是在S-Fuction Buider里边尝试直接应用参数Freq时,却出现了报错。查阅相关资料后,发现有人是先把参数作为初始值赋给一个状态变量,然后再拿这个状态变量作为参数使用。本文中的第5个状态变量xD[4]就是充当Freq的中转桥,经验证这种方法确实可行。虽然这种方法稍微有点绕弯,但是也不失是一种解决问题的办法。

分析和应用

        前面分析了那么多C MEX S-Function和TLC的特点和应用,本文S-Fuction Buider是集它们特点于一身的存在,并且把C MEX S-Function中复杂的接口函数和TLC中复杂的语法,都变成了Matlab后台自动执行的工作,开发者只需把注意力集中在C算法的移植上即可,大大提升了S-Function开发的工作效率。

总结

        以上就是本人在使用S-Fuction Buider时,一些个人理解和分析的总结,首先介绍了S-Fuction Buider的基本知识,然后展示它的使用方法,最后分析了该模块的特点和适用场景。

        后续还会分享另外几个最近总结的Simulink Toolbox库模块,欢迎评论区留言、点赞、收藏和关注,这些鼓励和支持都将成文本人持续分享的动力。

        另外,上述例程使用的Demo工程,可以到笔者的主页查找和下载。


版权声明,原创文章,转载和引用请注明出处和链接,侵权必究!

这篇关于开箱报告,Simulink Toolbox库模块使用指南(七)——S-Fuction Builder模块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/210409

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

Python:豆瓣电影商业数据分析-爬取全数据【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】

**爬取豆瓣电影信息,分析近年电影行业的发展情况** 本文是完整的数据分析展现,代码有完整版,包含豆瓣电影爬取的具体方式【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】   最近MBA在学习《商业数据分析》,大实训作业给了数据要进行数据分析,所以先拿豆瓣电影练练手,网络上爬取豆瓣电影TOP250较多,但对于豆瓣电影全数据的爬取教程很少,所以我自己做一版。 目

开题报告中的研究方法设计:AI能帮你做什么?

AIPaperGPT,论文写作神器~ https://www.aipapergpt.com/ 大家都准备开题报告了吗?研究方法部分是不是已经让你头疼到抓狂? 别急,这可是大多数人都会遇到的难题!尤其是研究方法设计这一块,选定性还是定量,怎么搞才能符合老师的要求? 每次到这儿,头脑一片空白。 好消息是,现在AI工具火得一塌糊涂,比如ChatGPT,居然能帮你在研究方法这块儿上出点主意。是不

【干货分享】基于SSM的体育场管理系统的开题报告(附源码下载地址)

中秋送好礼 中秋佳节将至,祝福大家中秋快乐,阖家幸福。本期免费分享毕业设计作品:《基于SSM的体育场管理系统》。 基于SSM的体育场管理系统的开题报告 一、课题背景与意义 随着全民健身理念的深入人心,体育场已成为广大师生和社区居民进行体育锻炼的重要场所。然而,传统的体育场管理方式存在诸多问题,如资源分配不均、预约流程繁琐、数据统计不准确等,严重影响了体育场的使用效率和用户体验。

python内置模块datetime.time类详细介绍

​​​​​​​Python的datetime模块是一个强大的日期和时间处理库,它提供了多个类来处理日期和时间。主要包括几个功能类datetime.date、datetime.time、datetime.datetime、datetime.timedelta,datetime.timezone等。 ----------动动小手,非常感谢各位的点赞收藏和关注。----------- 使用datet