使用构型
If
、elseif
、else
构造的 Simulink 构型
应对 if
、elseif
、else
构造使用下面这些构型。
功能 | Simulink 构型 |
使用 Switch 模块时的 if (If_Condition) { output_signal = If_Value; } else if (Else_If_Condition) { output_signal = Else_If_Value; } else { output_signal = Else_Value; } | |
使用动作子系统时的 if (Fault_1_Active & Fault_2_Active) { ErrMsg = SaftyCrit; } else if (Fault_1_Active | Fault_2_Active) { ErrMsg = DriverWarn; } else { ErrMsg = NoFaults; | |
case
构造的 Simulink 构型
应对 case
构造使用下面这些构型。
功能 | Simulink 构型 |
使用动作子系统的 case 构造。 switch (PRNDL_Enum) { case 1 TqEstimate = ParkV; break; case 2 TqEstimate = RevV; break; default TqEstimate = NeutralV; break; } | |
使用 Multiport Switch 模块的 case 构造。 switch (Selection) { case 1: output_signal = look1_binlxpw(In2,y1,x1,3U); break; case 2: output_signal = look1_binlxpw(In3,y2,x2,3U); break; case 3: output_signal = look1_binlxpw(In4,y3,x3,3U); break; default: output_signal = look1_binlxpw(In5,y4,x4,3U); break; } | |
逻辑构造的 Simulink 构型
应对逻辑构造使用下面这些构型。
合取范式
析取范式
矢量信号的 Simulink 构型
应对矢量信号使用下面这些构型。
功能 | Simulink 构型 |
矢量信号与参数(标量)乘法 for (i=0; i>input_vector_size; i++) { output_vector[i] = input_vector[i] * tunable_parameter_value; } (参考:使用 R2013b 生成的代码) for (i = 0; i < input_vectorDim; i++) { output_vector[i] = tunable_parameter_value * input_vector[i]; } (由于代码是使用可变数量的维度生成的,因此普通循环的上限是直接值。) | |
矢量信号与参数(矢量)的乘法
for (i=0; i>input_vector_size; i++) { output_vector[i] = input_vector[i] * tunable_parameter_vector[i]; } | |
矢量信号元素乘法 output_signal = 1; for (i=0; i>input_vector_size; i++) { output_signal = output_signal * input_vector[i]; } | |
矢量信号元素除法
output_signal = 1; for (i=0; i>input_vector_size; i++) { output_signal = output_signal / input_vector[i]; } | |
矢量信号与参数(标量)加法
for (i=0; i>input_vector_size; i++) { output_vector[i] = input_vector[i] + tunable_parameter_value; } | |
矢量信号与参数(矢量)加法
Vector signal and parameter (vector) addition for (i=0; i>input_vector_size; i++) { output_vector[i] = input_vector[i] + tunable_parameter_vector[i]; } | |
| |
矢量信号元素减法
output_signal = 0; for (i=0; i>input_vector_size; i++) { output_signal = output_signal - input_vector[i]; } | |
保留最小值/最大值 | |
使用 Switch 和 If
、Elseif
、Else
动作子系统
当相关的 elseif
和 else
操作仅涉及常量值的分配时,应使用 Switch 模块来对简单的 if
、elseif
、else
结构进行建模。
示例 - 推荐
对于简单的 if
、elseif
、else
结构,使用 Switch 模块。
示例 - 不推荐
使用 If 和 If Action Subsystem 模块来实现简单的 if
、elseif
、else
结构。
示例 - 推荐
对于复杂的 if
、elseif
、else
结构,使用 If 和 If Action Subsystem模块。
示例 - 不推荐
使用 Switch 模块来实现复杂的 if
、elseif
、else
结构。
使用 If
、Elseif
、Else
动作子系统替换多个开关
应避免频繁使用 Switch 模块进行条件分叉。而应使用目标上限(例如最多三级)。当超过目标值时,应使用基于 if
、elseif
、else
动作子系统的条件控制流。
示例 - 不推荐
四层嵌套。
示例 - 推荐
通过将第四层设置为一个 if
动作子系统,嵌套被限制为单层。
示例 - 不推荐
没有使用 if
动作子系统进行划分。
当应用 C 代码限制时,使用原子子系统 + 函数设置。这种情况下不需要使用 if
、elseif
、else
动作子系统了,而是可以将 Switch 模块的配置拆分并封装到子系统中。
五层嵌套模型示例 - 不推荐
五层嵌套模型示例 - 推荐
使用了一种描述方法,避免了在 Switch 模块中的分层嵌套。
虽然作为示例提供,但 if
动作子系统通常不用于切换固定值。在这些推荐和不推荐的示例中,如果用户不添加函数转换设置,则生成的 C 代码将是相同的。(在 R2010b 至 R2013a 中确认)C 代码不受约束。
使用条件控制流时动作子系统的使用规则
示例 - 推荐
当相关动作没有状态变量时,不应使用 if
动作子系统。
示例 - 推荐
使用五层嵌套的模型示例。由于没有内部状态,因此不会使用子系统进行分层。
示例 - 推荐
使用原子子系统来分割 Switch 模块的两侧,而无需使用动作子系统。
示例 - 不推荐
通过使用不必要的动作子系统进行分层。
如果某个功能可以通过动作子系统实现,则不必再使用动作子系统执行进一步分层。
在“不推荐”的例子中,在初始化第三层最低级别的 Unit Delay 模块时,首先在上面的第一层执行一次条件子系统初始化,然后在第二层再次执行一次,共计两次初始值设置。为了防止生成不必要的代码,建议不要在状态变量不存在的层级的条件子系统中进行列出或声明。
这基于这样的概念:通过降低层级来减少模型的复杂度。该规则的目的是避免执行不必要的初始化。
对于分岔条件嵌套结构较深的系统分岔,采用函数转换进行拆分,以减少代码分岔嵌套。将 Switch 模块前后的功能划分为各自的子系统,并将功能设置应用于原子子系统+功能。需要注意的是,这可能会导致意外的实现和不必要的 RAM 要求。
测试错误信息
当 Stateflow®(图形函数、MATLAB® 函数等)中使用的函数出现错误时,应将错误信息转化为便于测试的模型结构。
不检查函数返回的错误信息可能会导致意外行为。
示例 - 推荐
错误信息被并入模型结构,允许用户审查并对错误做出响应。
示例 - 不推荐
错误信息未并入模型结构。
条件的流程图构型
应对 Stateflow 流程图中的条件使用下面这些构型。
功能 | 流程图构型 |
一个条件。
[condition] | |
最多三个条件,简短形式。 (这种形式不允许使用不同的逻辑运算符。请改用子条件。) [condition1 && condition2 && condition3] [condition1 || condition2 || condition3] | |
两个或更多条件,多行形式。 (这种形式不允许使用不同的逻辑运算符。请改用子条件。) [condition1 ... && condition2 ... && condition3] [condition1 ... || condition2 ... || condition3] | |
带子条件的条件。 (不允许使用不同的逻辑运算符连接子条件。必须使用括号。) [(condition1a || condition1b) ... && (condition2a || condition2b) ... && (condition3)] [(condition1a && condition1b) ... || (condition2a && condition2b) ... || (condition3)] | |
视觉上分隔的条件 (这种形式可与前面的构型结合使用) [condition1 && condition2] [condition1 || condition2] | |
条件动作的流程图构型
应对 Stateflow 流程图中的条件动作使用下面这些构型:
功能 | 流程图构型 |
一个条件动作。 action; | |
两个或更多条件动作,多行形式。 (不允许在一行中包含两个或更多条件动作) action1; ... action2; ... action3; ... | |
视觉上分隔的条件动作 (这种形式可与前面的构型结合使用) action1a; action1b; action2; action3; | |
If
、Elseif
、Else
构造的流程图构型
应对 Stateflow 流程图内的If
构造使用下面这些构型。
功能 | 流程图构型 |
if (condition){ action; } | |
if (condition) { action1; } else { action2; } | |
if (condition1) { action1; } else if (condition2) { action2; } else if (condition3) { action3; } else { action4; } | |
级联 if (condition1) { action1; if (condition2) { action2; if (condition3) { action3; } } } | |
case 构造的流程图构型
应对 Stateflow 流程图中的 case 构造使用下面这些构型。
功能 | 流程图构型 |
具有排他选择的 case 构造。
selection = u1; switch (selection) { case 1: y1 = 1; break; case 2: y1 = 2; break; case 3: y1 = 4; break; default: y1 = 8; } | |
具有排他条件的 case 构造。
c1 = u1; c2 = u2; c3 = u3; if (c1 && ! c2 && ! c3) { y1 = 1; } elseif (! c1 && c2 && ! c3) { y1 = 2; } elseif (! c1 && ! c2 && c3) { y1 = 4; } else { y1 = 8; } | |
循环构造的流程图构型
应使用下面这些构型在 Stateflow 流程图中创建循环构造。
功能 | 流程图构型 |
For 循环构造
for ( index = 0; index < number_of_loops; index++ ) { action; } | |
While 循环构造
while ( condition ) { action; } | |
Do While 循环构造 do { action; } while ( condition ) | |
条件的状态机构型
应对 Stateflow 状态机中的条件使用下面这些构型
功能 | 状态机构型 |
一个条件 (condition) | |
最多三个条件,简短形式 (这种形式不允许使用不同的逻辑运算符,而应使用子条件) (condition1 && condition2) (condition1 || condition2) | |
两个或更多条件,多行形式 子条件是一组逻辑运算,全部属于同一类型,用括号括起来。 (这种形式不允许使用不同的运算符,而应使用子条件。) (condition1 ... && condition2 ... && condition3) (condition1 ... || condition2 ... || condition3) | |
转移动作的状态机构型
应对 Stateflow 状态机中的转移动作使用下面这些构型。
功能 | 状态机构型 |
一个转移动作。 action; | |
两个或更多转移动作,多行形式 (一行中不允许出现两个或更多转移动作。) action1; action2; action3; | |
jc_0321 限制状态分层
在单个查看器(子查看器)内,应通过定义单个视图(子视图)的约束来限制多层分层。当超出定义的约束目标时,应使用子图来切换屏幕。
示例 - 推荐
第四层封装在子图中。
示例 - 不推荐
约束目标设置为三层,但是 Level_4_a 和 Level_4_b 的层级超过三层,而且是嵌套的。
每个 Stateflow 容器的状态数
每个 Stateflow 容器的状态数应由图中可查看的状态数决定。所有状态都应该可见且可读。
从 Stateflow 调用函数
如果调用目标的 Function-Call Subsystem 中存在一个状态,并且当调用方的状态变为非活动状态时需要“重置”该状态,则调用方应使用绑定操作。
Stateflow 中可用的函数类型
Stateflow 中使用的函数类型应取决于所需的处理。
对于图形函数,使用:
If
、elseif
、else
逻辑
对于 Simulink® 函数,使用:
传递函数
积分器
表查找
对于 MATLAB 函数,使用:
复杂方程
If
、elseif
、else
逻辑