164第十二章利用状态流Stateflow进行控制系统状态转换Statefolw是一种图形化的设计开发工具,是有限状态机的图形实现工具,有人称之为状态流。主要用于simulink中控制和检测逻辑关系的。用户可以在进行Simulink仿真时,使用这种图形化的工具实现各个状态之间的转换,解决复杂的监控逻辑问题。它和Simulink同时使用使得Simulink更具有事件驱动控制能力。利用状态流可以做以下事情:1)基于有限状态机理论的相对复杂系统进行图形化建模和仿真;2)设计开发确定的、检测的控制系统;3)更容易在设计的不同阶段修改设计、评估结果和验证系统的性能;4)自动直接地从设计中产生整数、浮点和定点代码(需要状态流编码器);5)更好地结合利用Matlab和Simulink的环境对系统进行建模、仿真和分析。在状态流图中利用状态机原理、流图概念和状态转化图,状态流能够对复杂系统的行为进行清晰、简洁的描述。Stateflow生成的监控逻辑可以直接嵌入到Simulink模型下,两者之间能够实现无缝连接。仿真初始化时,Simulink会自动启动编译程序,将Stateflow绘制的逻辑框图转换成C格式的S-函数(Mex-文件),产生的代码就是仿真目标,且在状态流内称作Sfun目标,这样在仿真过程中直接调用相应的动态连接库文件,将二者组成一个仿真整体。Sfun目标只能与Simulink一起使用。在产生代码前,如果还没有建立名为sfprj子目录,状态流会在Matlab的当前目录下产生一个sfprj子目录。状态流在产生代码的过程中使用sfprj子目录存贮产生的文件。12.1有限状态机简介Stateflow的仿真原理是有限状态机(finitestatemachine,简称FSM)理论。为了更快地掌握Stateflow的使用方法,用户有必要先了解FSM的一些基本知识。所谓有限状态机是指系统中存在可数的状态,在某些事件发生时,系统从一个状态转换成另一个状态,故有限状态机又称为事件驱动的系统。在有限状态机的描述中,可以设计出由一种状态转换至另一种状态的条件,并将每对可转换的状态均设计出状态迁移的事件,从而构造出状态迁移图。Simulink/Stateflow为用户提供了图形界面支持的设计有限状态机的方法。它允许用户建立有限的状态,用图形的形式绘制出状态迁移的条件,并使用其规定的命令设计状态迁移执行的任务,从而构造出整个有限状态机系统。在Stateflow中,状态和状态转换是最基本的元素,有限状态机的示意图如图12.1所示。图12.1中有三个(有限个)状态,这几个状态的转换是有条件的,其中有些状态之间是相互转换的,A状态是自行转换的。在有限状态机系统中,还表明了状态迁移的条件或事件。Stateflow模型一般是嵌在Simulink模型下运行的,Stateflow是事件驱动的,这些事件可以来自同一个Stateflow图中,也可以来自Simulink。12.2Stateflow应用基础图12.1有限状态机示意图165在MATLAB命令窗口键入stateflow命令,将打开如图12.2.1所示的界面。其中,sflib窗口中有许多Simulink给用户提供的仿真算例。如果用户在MATLAB命令窗口键入sfnew命令,将打开嵌入Stateflow模块Charts的Simulink窗口untitled*。如图12.2(b)所示。其中Charts是空白的Stateflow模块图标。双击untitled*窗口中的Stateflow模块打开如图12.3所示的Stateflow编辑界面,用户可以在此窗口中编辑所需的Stateflow模型。Stateflow提供了强大的图形编辑功能,用户可以使用它描述很复杂的逻辑关系式。Stateflow编辑界面中点击鼠标右键,可以看到图12.4(a)所示的快捷菜单,选择其中的Properties(属性)菜单,可以打开图12.4(b)所示的对话框,用户可以在此对话框中设置整个Stateflow模型的属性。用户可以利用Stateflow编辑界面左侧的个编辑工具绘制Stateflow图形,下面介绍常用的编辑工具。1、状态工具系统的状态是指系统运行的模态。在Stateflow下,状态有两种行为:活动的(active)和非活动的(inactive)。单击状态工具按钮并拖动到编辑界面的空白处,即可绘制出一个状态的示意模块。用户可以在该模块右上角的问号位置填写状态的名称及动作描述,如标记为On,本例中状态的动作描述为entry:speed=1,将speed的值赋为1。(事实上,状态动作有很多种,不止entry一种,为了使读者先掌握状态流的一般知识,复杂的状态流的状态动作类型及其应用我们在随后的部分再来阐述。)激活On模块,使用热键Ctrl+C和Ctrl+V或使用edit菜单下的复制及粘贴命令,即可再复制一个同样的模块,将复制的模块标记改为Off,动作描述改为entry:speed=0。使用该工具,可以绘制出所有需要的状态,如图12.5所示。如果右击建立的状态图标,并选择快捷菜单中的Properties菜单项,可打开图12.6所示的设置状态属性的对话框。用户也可以在Label栏填写状态的名称和动作描述。图12.2(a)sflib窗口图12.2(b)嵌入Stateflow模块的Simulink窗口图12.2Stateflow启动窗口166状态工具历史交汇工具缺省状态迁移工具交汇连接工具放大缩小工具图12.3Stateflow编辑界面真值表图形函数工具内嵌Matlab函数模型整理工具(a)Stateflow快捷菜单(b)Stateflow属性设置对话框图12.4Stateflow模型的属性设置1672、状态迁移关系设置在一个状态块的边界按下鼠标键并拖动至另一个状态的边界释放,可以绘制出从一个状态到另一个状态的连线。单击此连线,在该连线上会出现一个问号,用户可以在该问号出添加状态迁移标记。状态迁移标记可以含有触发事件、迁移条件、条件动作及迁移动作,或他们中的任意组合。状态迁移图12.6状态属性设置对话框图12.5Stateflow窗口的新建状态及其设置168标记的一般形式是触发事件[迁移条件关系式]{条件动作}/迁移动作图12.7中的状态迁移显示了状态迁移标记的一般形式。触发事件表示只要迁移关系式是真,该触发事件可以引发状态的迁移。缺省触发事件时,任何事件均可在条件关系式为真的情况下引发状态的迁移。图12.7的示例中,只要条件[off_count==0]为真,事件off_switch可以引发状态On至状态Off的迁移。条件关系式一般是布尔表达式,写在方括号中。该关系式为真时,使得对于特定的触发信号迁移有效。本例中,只要当条件关系式off_count==0为真时,发生的事件off_switch才可引发状态迁移。条件动作是指当条件关系式一旦成立(即为真),就执行的动作,通常发生在迁移终点被确定有效之前。如果没有规定条件关系式,则认为条件关系式为真,即刻执行条件动作。条件动作必须写字花括号中。图12.7的示例中,只要条件[off_count==0]为真,即可执行条件动作off_count++。迁移动作是指当迁移终点已经确定有效,才执行的动作。如果迁移包含很多阶段,迁移动作只有在整个迁移通道到终点确认为有效后方可执行。迁移动作写在斜线’/’之后。图12.7的示例中,当条件[off_count==0]为真,发生了off_switch事件,迁移终点状态Off确认为有效,此时执行迁移动作LED_off图12.8也给出了一个简单的状态迁移标记示例。在该例中,用户可以使用状态迁移属性设置对话框对状态迁移条件进行设置。右键状态迁移连线即可打开状态迁移属性设置对话框,在Label栏中设置即可。请读者自行点击问号,将图中未设置触发事件的迁移事件设置为on_switch,并保存此例。本例的两个状态迁移均采用的是事件触发,状态迁移也可以采用关系式触发,一旦状态迁移上所描述的关系式成立,则状态迁移开始启动。关系式触发的状态迁移上的关系式格式是[关系式],如[temp=120]等。3、缺省状态转移设置缺省状态转移设置的作用是告诉Stateflow图形,当它开始工作时,哪个状态先处于激活状态。点击Stateflow图形编辑界面中的图标,然后将鼠标移动需要设置的图12.8Stateflow状态迁移设置缺省状态迁移图12.7状态迁移标记的一般形式举例169状态即可。见图12.8。4、事件与数据设置前面我们为状态迁移规定了迁移触发事件的名称,也就是说状态的迁移仅在这些事件发生的时候才开始。为了利用这些事件触发,我们必须先定义这些事件。定义on_switch和off_switch事件需要一下几步:a)从stateflow编辑界面的add菜单选择Event,并在随后弹出的下拉菜单下选择InputfromSimulink,打开事件对话框,见图12.9;将事件对话框中的Name改为off_switch,trigger选择为Falling(即下降沿触发),点击OK保存off_switch事件的设置。b)重复上述步骤设置on_switch事件,触发事件仍选择InputfromSimulink,Name设置为on_switch,trigger选择为Rising(即上升沿触发)。注:事件的范围(Scope)有三种选项:Local是指利用本Stateflow图形界面产生的触发事件;InputfromSimulink是指从Simulink模型引入事件至Stateflow图形界面;OutputtoSimulink是指将Stateflow图形界图12.9Stateflow事件对话框事件对话框170面产生的事件输出到Simulink模型中。事件的触发方式亦有多种选择:Either、Rising、Falling和FunctionCall四种。其中选择Rising或Falling分别指利用事件的上升沿或下降沿触发,Either是指不管上升沿还是下降沿事件均可以触发,FunctionCall是一种函数调用的触发方式。前面我们还为状态设置了动作,如状态On的动作描述为entry:speed=1,是希望在状态On激活时将speed的值赋为1,这个数据是要在Simulink模型中使用的,所以要将数据传递到Simulink模型中。在能够被利用之前,这个数据必须先定义。数据的定义步骤如下从stateflow编辑界面的add菜单选择Data,并在随后弹出的下拉菜单下选择OutputtoSimulink,打开数据对话框,将图12.10;将数据名Name改为speed,点击OK保存设置即可。注意:数据范围可以设置为Local(局部数据)、InputfromSimulink(从Simulink模型中输入数据,但Stateflow图需要利用Simulink模型的数据时,需要将相应的数据输入到Stateflow图中)、OutputtoSimulink(向Simulink模型输出数据)和Constant(常数)四种形式。数据的类型可以是Double(双精度)、Single(单精度)、Int32(整数)及Boolean(布尔数)等,也可以设置为Inherited,即继承原来的设置。数据对话框图12.10Stateflow数据对话框171这样在Stateflow编辑界面中,选择Tools菜单中的Explore,将会打开模型管理器ModelExplorer,如图12.11所示。事件和数据的定义也均可以在模型管理器中进行。分别点击模型管理器工具栏上的图标和即可添加事件和数据,然后点击相应的内容修改事件的范围、触发方式或数据的范围及数据的类型等内容。设置了事件和数据后,就可以从Simulink模型中输入事件和数据,并将Stateflow图执行过程中产生的数据或事件输出至Simulink模型中。例12.1将前面叙述中已设置好数据和事件的Stateflow图存为Examp12.1,从Simulink中产生上升沿和下降沿的触发事件,将Stateflow图