3. 状态、转移与层次结构建模

Stateflow 的建模能力,本质上来自四个基本语义要素的组合:状态表示系统在某一时刻所处的模式;转移表示模式之间允许发生的切换;转移标签规定切换在什么事件、什么条件下、执行什么动作;层次结构则把大量状态组织成可复用、可维护的父子关系。理解这四者的语义,是后续处理复杂模式切换、故障降级、多工况调度的前提。

状态语义:激活、互斥与并行

一个状态被“激活”,意味着它当前正在参与执行。Stateflow 中状态分为两类:互斥(OR)状态与并行(AND)状态。互斥状态同一时刻只能有一个子状态处于激活;并行状态的所有子状态同时激活。例如一个电机控制器,顶层用互斥状态表达“停机 / 运行 / 故障”,而“运行”内部又用并行状态同时表达“转速控制”和“温度监控”,两者互不排斥、同时工作。

状态还可以携带 entry、during、exit 三类动作。entry 在进入状态瞬间执行一次,适合做初始化,如 speedRef = 0;;during 在状态保持激活的每个采样步执行,适合做持续控制;exit 在离开状态时执行一次,适合做清理,如 integral = 0;。把初始化放在 entry、把复位放在 exit,可以避免状态切换时残留旧值,这是工程上最常见的错误来源之一。

默认转移:确定初始激活路径

当父状态被首次激活时,它必须知道从哪个子状态开始。默认转移就是这条“入口路径”,用一条从默认转移点出发、不带事件和条件的短箭头表示。若父状态有多个子状态而没有默认转移,Stateflow 会报错或行为不确定。对于带历史节点的父状态,默认转移只在“从未进入过”时生效;一旦进入过,历史节点会记住上次激活的子状态。

默认转移的箭头必须从父状态边界上的默认转移点出发,不能从其它状态出发。若把默认转移误画成普通转移,会导致首次进入时无法确定初始子状态。

转移标签:事件、条件与动作

转移标签的完整语法为 event[condition]{action},三段均可省略,但顺序固定。事件是触发源,如 tick、faultDetected;条件是布尔表达式,如 [temp > 85];动作是转移发生时执行的语句,如 {mode = 2;}。只有条件没有事件时,表示该转移在每个采样步都评估条件,属于“条件转移”;只有事件没有条件时,表示事件一到就转移。

转移的评估遵循“从源状态向外、按优先级”的规则:同一层次内,靠左、靠上的转移优先。若多个转移同时满足,只有优先级最高的那条会执行。因此,在画故障转移时,通常把“故障”转移放在最靠前的位置,保证它优先于正常控制转移被评估。

% 转移标签示例
tick[temp > 85]{mode = FAULT;}      % 事件+条件+动作
[cmd == STOP]{mode = IDLE;}          % 纯条件转移
faultDetected{mode = FAULT;}         % 纯事件转移

父子状态与历史节点

层次结构的价值在于“封装”。父状态对外只暴露少量转移,内部细节被子状态隐藏。当父状态被重新进入时,默认行为是从默认转移指定的子状态重新开始;如果希望“回到上次离开的地方”,就需要在父状态内放置历史节点。历史节点分为浅历史(H)和深历史(H*):浅历史只记住父状态直接子层的激活状态,深历史则递归记住所有嵌套层的激活状态。

以“运行”父状态为例,其内部有“加速 / 稳态 / 减速”三个子状态。若使用浅历史,从“运行”退出再进入时,会回到上次激活的子状态;若内部还有嵌套的并行监控状态,则需要深历史才能完整恢复。历史节点用带 H 或 H* 的圆圈表示,并用默认转移指向“从未进入过”时的初始子状态。

复杂模式切换的层次化表达

面对多模式系统,推荐采用“顶层互斥 + 内部并行 + 历史恢复”的三层组织方式。顶层用互斥状态表达大模式,如“初始化 / 待机 / 运行 / 故障 / 停机”;“运行”内部用并行状态同时处理控制与监控;“运行”与“待机”之间用历史节点保存上次工况,实现快速恢复。这样,模式切换逻辑集中在顶层少量转移上,内部细节各自独立,修改一个模式不会波及其它模式。

复杂模式切换的层次化状态图 父状态:运行(互斥) 加速 entry: ref=+10 稳态 during: 闭环调节 减速 entry: ref=-10 [v≥vset] [cmd=down] H 浅历史节点 恢复上次子状态 并行监控(AND) 温度监控 [temp>85]→故障 电流监控 [I>Imax]→故障 故障 entry: 切断输出 待机 entry: ref=0 停机 exit: 保存状态 faultDetected [cmd=idle] [cmd=run] [reset] 默认转移 历史恢复 并行状态 故障转移(高优先级) 标签格式:event[condition]{action}

上图展示了一个典型的层次化模式切换结构:顶层“运行”是互斥父状态,内部“加速 / 稳态 / 减速”互斥切换,并通过浅历史节点保存上次工况;“运行”内部还嵌套了并行的温度与电流监控,一旦越限立即触发故障转移。故障转移使用橙色高亮,表示它在优先级上高于正常控制转移。待机与运行之间通过 [cmd=run] 条件转移切换,停机则通过 exit 动作保存状态。

在工程实现时,建议遵循以下检查顺序:先确认每个父状态都有默认转移或历史节点;再确认互斥子状态之间没有遗漏的转移路径;然后检查转移标签的事件与条件是否与外部输入一致;最后验证历史节点在“退出—重进”后是否恢复到预期子状态。可以用一个简单的测试序列验证:进入运行→切到减速→退出到待机→重新进入运行,观察是否回到“减速”而非“加速”。若回到“加速”,说明历史节点未生效或默认转移被误用。

历史节点只保存“激活状态”,不保存变量值。若需要恢复变量,必须在 entry 或历史恢复后的转移动作中显式赋值,否则会沿用退出前的旧值,可能造成控制量跳变。