主要内容

使用金宝app而且Stateflow在建模

当使用Stateflow时®,仿金宝app真软件®是输入、输出和结构化所必需的。单独的状态流可以执行各种公式处理。在使用Simulink金宝app时,可以通过方法来实现复杂的状态变量,例如使用开关情况块。

无论是Simu金宝applink还是statflow都可以用来对控制的特定部分建模,然而,在开发工作流中的任何一种产品的应用都是基于用户对底层算法的理解,并最终由组织决定哪种工具最适合他们的需求。决定是使用Simulink还是statf金宝applow进行设计,应该由一组人根据任务来决定。还应该指定statflow中的实现是通过使用状态转换还是使用流程图完成的。

在大多数情况下,statflow在RAM方面效率较低。因此,Simulink金宝app在使用简单公式的计算中具有优势。此外,Simulink对于金宝app状态变量是通过简单的触发器和继电器块。在项目中评估是否使用Simulink或statflow时,应考金宝app虑以下主题:

  • 增加RAM:必须始终有一个RAM可用来可视化statflow输入、输出和内部变量。

  • 公式错误处理:当内部使用一般计算公式时,用户会设计防止溢出的方法。

  • 分裂和分离函数:当在Stateflow之外使用Simulink执行计算时,它们可能会分裂,从而降低可读性。金宝app有时可读性也会提高。这一点很难判断。

在某些情况下,Stateflow拥有比Simulink更高效的代码,可以获得接近代码的最佳表达式,但大多数情况下会导致难以金宝app理解的模型。如果代码已经存在,使用s函数而不是状态流建模更有利。状态流可以记录指定了特定安排的计算,或者使用for循环的计算,比Simulink更有效,但近年来使用MATLAB也变得更方便金宝app®描述语言。如有需要,可考虑使用MATLAB语言进行建模。

对于状态流模型,当处理如下所述的状态时,通过将它们描述为状态转换来提高可读性:

  • 相同的输入输出不同的输出值。

  • 存在多个状态(作为指导,三个或更多)。

  • 州有有意义的名字而不仅仅是数字。

  • 在一个状态中,初始化(第一次)和执行期间的区分(第二次之后)是必需的。

例如,在触发器电路中,不同的输入输出不同的值。状态变量被限制为0和1。但是,不能仅仅通过保留布尔类型数字来为每个状态添加有意义的名称。状态内的初始化和执行也没有区别。因此,上述四种触发器中只有一种适用,因此Simulink更有益。金宝app

在statflow中,可以表示为状态的情况被实现为状态转换,而不是状态的条件分支被实现为流程图。真值表被归类为一种条件分支实现方法。当使用状态流将状态设计为状态转换时,经典应选择作为状态机类型,以便将其作为软件实现到控制系统的嵌入式微控制器中。

HDL Coder™由sta金宝apptflow支持。当使用HDL Coder时,粉状的摩尔必须选中;摩尔当需要防止内部电泄漏时,模式更合适。

请注意

这些指南中没有描述HDL Coder用例。

金宝app功能

本节提供有关使用Simulink进行建模的信息。金宝app

带有状态变量的块

带有状态变量的块主要分为Simulink和离散类型。金宝app

对于大多数这样的块,用户可以使用块参数设置状态属性和初始值。条件子系统可以有状态变量,这取决于结构模式。

在本例中,单位延迟块具有状态属性。

单元延迟块参数对话框的屏幕截图。

在本例中,利用延迟块没有状态属性。

点击延迟块参数对话框的屏幕截图。

参见指南:jc_0640

带有状态变量的分支语法

开关块子系统和条件子系统在使用状态变量时表现不同。

根据配置设置,当存在任何状态变量时,开关block一般在满足控制端口条件时执行子系统A。如果不满足条件,则只执行子系统B,不计算子系统A。当子系统A中存在状态变量时,即使不满足控制端口的条件,也会对子系统A内部的状态变量进行计算。

带状态变量的条件子系统的计算工作流。

在条件子系统中,满足条件时计算子系统A。当不满足时,不管子系统A中是否存在状态变量,都计算子系统B而不是子系统A。

没有状态变量的条件子系统的计算工作流。

重新计算中的重置操作可以通过使用{action Port}设置指定。

子系统A在使用时的行为开关块和条件控制流在下表中列出。熟悉这些行为,以确定是哪个结构开关块或条件子系统最适合预期用途。

该表显示了子系统A的行为

控制口状况

(子系统A)

状态变量

开关 有条件的子系统
持有 没有 执行 执行
是的
不以 没有 不执行 不执行
是的

微加工

*执行与状态变量相关的计算

该表提供了子系统A的初始化时间。

行动的港口 初始化
开关 仅限第一次
有条件的子系统 持有 仅限第一次
重置 At由条件返回

看到指南:

子系统

子系统用于编译各种块和子系统。

子系统也可以用于其他目的。非功能子系统的使用方法包括:

  • 掩码显示子系统用于描述大纲或显示固定形式的文档,如“分类”

  • 子系统的开放函数(块属性中的回调函数)用于运行几个工具或显示与模型分离的解释性文本

  • 设置已经更改为掩码子系统的子系统(简单地设置为NoReadOrWrite),由具有管理权限的用户进行更改,但其他用户无法看到内容。

这些非典型的子系统不在指导方针的范围之内,如果被排除在外,应该放在项目管理的排除列表中。

看到指南:

原子子系统和虚拟子系统。有两种类型的子系统,虚拟子系统和原子子系统。这些子系统之间的主要区别在于子系统是否被视为一个单独的执行单元。虚拟子系统是默认的子系统块。

在模型中,虚拟子系统的边界较薄,而原子子系统的边界较厚且粗体。

虚拟子系统和原子子系统的边界。

虚拟子系统

提供可视化表示的块称为“虚拟块”。例如,Mux块,它编译多条信号线Block传递信号,还有转到对应于虚拟块的块。由于默认设置中的子系统块只构成一个可视的层次结构,因此这些块被认为是虚拟块。子系统被称为虚拟子系统。

考虑一个子系统,该子系统在子系统内查询外部计算结果,如下面的示例所示。这个方程组是由这四个方程计算出来的。

  • Temp1 = in1 + in2

  • Temp2 = in3 + in4

  • Out1 = in1 + in2 + temp2

  • Out2 = temp1 + in3 + in4

虚拟子系统的示例。

原子子系统

原子子系统与外部系统分离,不受跨界优化的影响。原子子系统不使用每个子系统的内部计算结果。因此,中间输出值将使用被会话延迟的计算结果。

  • Temp1 = in1 + in2

  • Temp2 = in4 + in5

  • Out1 = in1+ in2 + in3

  • Out2 = in4+ in5 + in6

  • in3 = temp2

  • in6 = temp1

原子子系统禁止将临时计算结果直接引用到其他子系统。

原子子系统的示例。

关于原子子系统的说明:

  • 原子子系统可以选择c源函数设置。

  • 如上所述,原子子系统的内部部分将被封装(对象化)。

  • 根据前后的关系,应该在子系统内部为输出信号保护一个静态RAM部分。

  • 原子子系统(包括添加的函数设置)应该谨慎使用。因子设置不会简单地在C代码中插入因子名称。应该承认,它被描述为一个数学上独立的系统,并且应该审查可以使用原子子系统的条件。

  • 包括与结构层的关系;有必要确定每个项目的操作规则,并确定其与指导规则的关系。

信号的名字

信号可以被命名并称为信号名。当一个信号被命名时,该信号名称将显示为一个标签。对标签的更新将反映在信号名称中并显示出来。

信号名称可以通过分支信号线或端口块传播到信号线,并显示为信号名称。

看到指南:

代码可以通过将信号名称与信号对象(Simulink对象或金宝appmpt对象)。类型设置通过数据字典配置,存储类设置为可选。这些块的推荐数据类型设置包括:

  • 轮廓尺寸块,设置数据类型}汽车

  • 外港块,数据类型}汽车

  • 总和块,设置输出数据类型通过反向传播继承

看到指南jc_0644:类型设置

矢量信号/路径信号

组成向量的单个标量信号应具有共同的函数、数据类型和单位。

不满足作为矢量的条件的信号只能作为总线信号分组。的总线选择器仅用总线信号输入阻断应使用。它不得用于从矢量信号中提取标量信号。

下表是矢量信号的一个例子。

向量的类型 大小
行向量 n [1]
列向量 (n - 1)
轮速子系统 [1轮数]
圆柱矢量 [1个气缸号]
基于二维坐标点的定位向量 (1 2)
基于三维坐标点的定位向量 3 [1]

下表是总线信号的一个例子。

总线类型 因素
传感器总线 力向量
位置
轮速矢量[Θlf, Θrf, Θlr, Θrr]
加速度
压力
总线控制器 传感器总线
致动器总线
串行数据总线 循环水温度
发动机转速,前副驾驶舱门打开

看到指南:

枚举类型

枚举类型数据是指限制为确定数值的数据。

在Simulink中枚举类型中可以使用的块类型是有限的。金宝app

若要使用枚举类型,必须使用来定义枚举类型.mMATLAB文件。有关定义枚举数据类型的其他信息,请参见在Simulink模型中使用枚举数据金宝app

Stateflow功能

本节提供有关使用statflow进行建模的信息。

可供操作Stateflow

有关状态流操作的其他信息,请参见状态流数据的操作(Stateflow)

看到指南:

状态转换和流程图的区别

状态流既可以表示状态转换,也可以表示流程图。

状态流允许在状态转换图中设计流程图。

入口操作表示为状态中的流程图,从默认转换开始,通过转换线移动到节点,如下所示。从内部转换线开始允许要在流程图中表示的动作。

流程图不能在更新之间保持其活动状态。因此,流程图总是在终端结点(没有有效的传出转换的连接结点)处结束。

相反,状态转换图将其当前状态存储在内存中,以便在更新之间保存本地数据和活动状态。因此,状态转换图可以从它们在前一个时间步骤中停止的地方开始执行。这意味着状态转换适合于建模依赖于历史的反应性系统或监视系统。

该表定义了流程图和状态转换图的起点和终点。

起点 终点
流程图

缺省转换

来自状态的所有终止都连接到连接结。
状态转换图

缺省转换

任何一个终止都应该连接到状态

这个插图显示了一般流程图和状态转换图之间的区别

在状态内部和状态外部的流程图和状态转换图的示例工作流

流程图和带有自转换的状态转换图的混合具有更严格的约束。

在状态内部和状态外部具有自转换的状态转换图示例。

看到指南:

回溯

此示例显示带有连接的转换行为,这些连接强制流程图中的回溯行为。该图表使用隐式输出转换顺序。

演示转换条件的操作执行的工作流。

最初,状态A是主动的,转换条件c1, c2和c3为真。转换条件c4为假。

  1. 图表根检查是否存在从状态a的有效转换。

    存在一个有效的过渡段,标记着从状态a到连接结点的过渡条件c1,因此:

    1. 转换条件c1为真,因此执行操作a1。

    2. 转换条件c3为真,因此执行操作a3。

    3. 转换条件c4不为真,因此,控制流返回到状态A。

  2. 图表根检查从状态A是否有另一个有效的转换。

    存在一个有效的过渡段,标记着从状态a到连接结点的过渡条件c2,因此:。

    1. 转换条件c2为真,因此执行动作a2。

    2. 转换条件c3为真,因此执行操作a3。

    3. 转换条件c4不为真,因此,控制流返回到状态A。

  3. 图表休眠了。

    要解决此问题,可以考虑向终止连接添加无条件过渡行。如果c3或c4不为真,则终止连接允许流终止。这种设计使状态A处于活动状态,而不执行不必要的操作。

演示使用无条件转换线到终止连接的工作流,允许在转换不为真时终止操作。

看到指南:

州外流程图

与状态相关联的流程图可以写在状态的内部或外部;但是,要注意执行命令和回溯。

下面的流程图在执行状态之外的流程图之后评估从a到b的转换,它似乎在与更新的计算相同的时间内执行转换。但是,如果通过计算状态外的转换到达终点,则不会计算到b的转换线。这是一个状态转换图,总是在a处。

在状态外执行流程图后评估转换的流程图。

如果操作正确,如下所示,转换条件不会被定位在外部流程图的末端,从而允许在流程图执行之后评估从a到b的转换线。这使得外部流程图可以在转换之前执行,并且可以在转换的瞬间使用最新的值进行评估。请注意,此图表包含一个死路径,其中转换条件永远不会保持,这可能在将来更改规范时导致错误。请谨慎使用此图表结构。

流程图在转换之前执行,并在转换的瞬间使用最新的值进行评估。

相比之下,下面的流程图是在状态内部,这意味着内部流程图总是在执行状态a时计算,可以描述为一个容易理解的结构,没有死路径。然而,应该注意的是,作为一种性能特征,当执行状态a时,从a到b的转换在计算内部流程图之后的循环中进行评估。由于这一特性,外部流程图的计算和转换的执行时间可能是关闭的。请谨慎使用。

流程图位于状态内部,这意味着在执行状态时始终计算内部流程图

看到指南:

指针变量

此代码示例来自模型sf_custom.要打开模型,在MATLAB命令行中输入以下命令:

openExample(“sf_custom”)
在模型sf_custom,点击打开my_header.h
#include "tmwtypes.h" extern real_T my_function(real_T x);/*定义自定义类型*/ typedef struct {real_T a;int8_T b [10];} MyStruct;/*全局struct变量的外部声明MyStruct *gMyStructPointerVar;
在模型sf_custom,点击打开my_function.c
#include  /*全局结构变量的定义*/ MyStruct gMyStructVar;MyStruct * gMyStructPointerVar =零;real_T my_function(real_T x) {real_T y;y = 2 * x;返回(y);}

gMyStructVar状态流中没有定义。典型地,函数my_function在状态流中调用C源。但是,从Stateflow中也可以直接引用C源代码公开的全局变量。

statflow中的指针变量。

初始化

本节提供有关使用初始化值的信息。

初始化中的初始值设置

当信号需要初始化时,应正确设置初始值。

在块内设置初始值时,请使用包含注释的初始值列表,以便可以直观地确认输入的初始值。

需要初始值的情况包括:

  • 当定义状态变量并且使用具有状态变量的块时。

    • 使用内部块设置。

    • 使用外部输入值。

  • 当定义状态变量并且在执行特定配置时为块启用初始值时。

    • 在合并块中设置初始值。

    • 使用在数据字典中注册的信号。

  • 当信号设置(与RAM)已经定义,可以从外部引用。

    • 使用在数据字典中注册的信号。

在数据字典中注册的信号的初始值

为数据字典中注册的信号设置初始值。

  • 离散块组,例如单位延迟而且数据存储内存,有状态变量。

    在自动代码生成的情况下,可以通过将信号与数据字典中的信号(与Simulink信号对象相关联)匹配来为状态变量设置信号名称、类型和初始值。金宝app当使用数据字典中定义的信号作为状态变量时,各自的初始值应符合相同的值。

  • 当使用数据字典中定义的信号作为状态变量时

    对于离散块,例如单位延迟而且数据存储内存,当使用数据字典中为块输出行定义的信号时执行设置,而是对块内的状态变量执行设置。即使将数据字典的信号名称分配给信号线,RAM也会以副本的形式保留,这是对RAM的浪费。

示例-正确

信号是为块内的状态变量定义的。信号名称定义和块参数状态名必须解析为Simulink信号对象金宝app被选中。

接口为块内的状态变量定义信号。

示例-不正确

信号为具有状态变量的块的输出信号定义。信号名称定义和块参数状态名必须解析为Simulink信号对象金宝app未选中。

接口,用于定义具有状态变量的块的输出信号。

通过使用,工作区中定义的信号对象可以自动与相同名称的信号对象和信号名称相关联disableimplicitsignalresolution (modelname).然而,对于块内的状态变量,它们与块内的状态变量和同名的信号名称相关联。如果一个全局设置的信号同时与两个变量相关联,最好进行设置,使块内的状态变量与信号线上的信号标签具有不同的名称,否则无法模拟模型。

外部输入值为初始值的块

在初始化过程中设置初始值时,初始化函数将信号设置为块内部的值或数据字典中定义的初始值。接下来,执行步骤函数(数据流执行函数)。这里,外部输入值被设置为初始值。建模时,要注意初始化的执行函数和执行时间。下图演示了这一点。

下面的图片

初始化解释和代码行为的差异。

接口指定初始条件的输入。

系统配置中的初始值设置将启用初始化参数

在某些系统配置中,根据它们的设置,为条件子系统和的组合启用初始化参数合并块。当这些组合需要初始值时,采用以下建模方法之一:

  • 外港

  • 在值中设置合并

  • 当一个mpt信号定义在合并块中设置的值mpt信号

例外情况是,当有具有初始值的连续块时,不需要对每个块进行设置以清楚地显示信号的初始值。

示例-正确

中设置的初始值合并块。

接口,通过使用“合并”块参数初始输出指定初始值。

示例-正确

中设置的初始值mpt对象。

初始值在.mpt信号中设置。

示例-不正确

尽管有初始值设置的要求,但它没有显示在任何地方。

Merge块参数的接口。未定义初始输出值。