您的位置:

Stateflow基本语法详解

Stateflow是MATLAB工具箱中的一个重要组件,主要用于事件驱动系统的建模、仿真、验证和代码自动生成。Stateflow可以快速地建立可视化的状态图,用于描述离散状态和连续状态的动态行为。本文将从多个方面对Stateflow基本语法进行详细阐述,并给出相应的代码示例。

一、状态和事件

在Stateflow中,状态可以理解为系统的一个特定的状态,例如:假设我们建立了一个售货机的状态图,而状态可以是“等待投币”、“选择商品”、“支付”、“出货”等状态。用Stateflow图描述状态之间的转移,以及状态与事件之间的关系,其中事件是使系统从当前状态转移到下一个状态的触发源。

一个Stateflow图通常包含一个或多个state,以及它们之间的transition。一个state有如下的特征:

  • 拥有一个名字,表示当前状态。
  • 可以有一个或多个入口,表示进入当前状态的条件。
  • 可以有一个或多个出口,表示状态转移后的下一个状态。
  • 可以有一个或多个事件,表示触发状态转移的事件。
  • 可以有一个可选择的default transition,表示当没有任何条件满足时,状态转移到的下一个状态。

下面给出一个简单的状态机的示例,实现了一个红绿灯的控制,以及一个按钮等待信号并在按下后触发状态转移:

chart light_controller

state (Idle) //初始状态
entry / no_light();

state (Green)
entry / green_light();

state (Red)
entry / red_light();

state (Button_Pressed) //按下状态
entry / button_pressed();

transition (Idle, Green) / (green_light_on) //初始状态到绿灯状态
transition (Green, Red) / (time_out) //绿灯到红灯状态
transition (Red, Green) / (time_out) //红灯到绿灯状态
transition (Red, Button_Pressed) / (button_pressed) //红灯到按下状态
transition (Green, Button_Pressed) / (button_pressed) //绿灯到按下状态
transition (Button_Pressed, Green) / (time_out) //按下状态到绿灯状态
transition (Button_Pressed, Red) / (time_out) //按下状态到红灯状态

event green_light_on;
event time_out;
event button_pressed;

// 操作函数
function no_light()
clear light;
end

function green_light()
light = 1;
end

function red_light()
light = 2;
end

function button_pressed()
light = 0;
end

二、Truth Table 与 Decision Block

Truth Table 是 Stateflow 决策块(Decision Block)最常用的子块之一。Truth Table通常用于将输入信号映射到输出信号,以便在决策块中具有更清晰的逻辑表达式。常见的使用方式是给定一系列的输入值和对应的输出值,通过Truth Table来完成映射,并将她们嵌入到决策块中,组合成决策逻辑。

下面是一个更加实际的例子,假设我们要实现一个简单的闹铃系统,需要根据当前的时间和用户设定的闹铃时间来触发闹铃。特别的,如果设定了“重复”功能,则每天该时间点都会触发闹铃。

chart alarm_system

input int alarm_time; //用户设定的闹铃时间
input int current_time; //当前时间
input boolean repeat; //是否重复

output boolean alarm;//输出信号,用于触发闹铃

// 决策块
decision Alarm_Decision
truth_table
//TureTable中的输入,即映射规则
TC: alarm_time
DZ: current_time
CX: repeat
//TrueTable中的输出,即映射的结果
0	1	1	0;
0	1	0	0;
1	1	1	1;
1	1	0	1;
end_truth_table

//根据TruthTable的结果,判断是否响铃
if (Alarm_Decision) {
alarm = true;
} else {
alarm = false;
}

三、超时和计数器

超时和计数器可以帮助我们在Stateflow中实现更加复杂的逻辑,例如倒计时、时序控制等。超时通常可以理解为在经过一定等待时间后触发某个事件。计数器可以帮助我们记录某个事件在state中执行的次数。以下是两个相关的例子:

chart timeout_example

state Timer
timeout(TIME) / timer_out;

state End

transition (Timer, End) / timer_out;

entry / set_timer();

const int TIME = 1000; // 1s

function set_timer()
reset_timer(Timer, TIME);
end

在这个例子中,我们创建一个state,名为 “Timer ”。当进入 Timer 状态时,然后设定一个明确的超时事件,在指定时间后跳转到状态“End”。可以通过reset_time函数来设定超时时间。

下面给出一个计数器的例子,假设我们现在要对汽车的车速进行实时监控,如果车速大于某个阈值,则提示需要减速。我们将这个过程分为三个状态,将车速传感器的读数作为输入值,在“检查”状态中判断车速是否大于阈值,如果大于阈值,计数器计数,则跳转至“提示”状态,弹出提示信息,然后跳转回“检查”状态。

chart speed_monitoring

input int speed; //车速
output boolean prompt; //是否提示

state Check
entry / reset_counter();
on entry {if (speed > THRESHOLD) {counter ++;}}

state Prompt
entry / emit_prompt();
on entry {prompt = true;}

state End

transition (Check, Prompt) / counter > 0;

transition (Prompt, Check) / true;

const int THRESHOLD = 60; //判断阈值
int counter = 0; //计数器

function reset_counter()
counter = 0;
end

function emit_prompt()
prompt = false;
end

四、MATLAB函数的使用

Stateflow与MATLAB紧密集成,可以通过编写MATLAB函数来对Stateflow的状态,变量和事件进行更加灵活的操作。在这个部分,我们将学习如何在Stateflow中使用MATLAB函数。

首先,在Stateflow中必须定义所有的变量类型、输入和输出参数,以保证与MATLAB环境的交互。下面是一个简单的例子,其中使用了MATLAB内置的sin函数来生成一个简单的正弦波形:

chart sine_wave

output int y;

state SineWave {
entry / set_phase();
during / y = amplitude * sin( 2 * pi * frequency * time + phase_offset );
}

function set_phase()
time = 0;
phase_offset = pi/4; 
end

const double amplitude = 5.0;
const double frequency = 1.0;
double time = 0;
double phase_offset = 0;

在这个例子中,我们定义了一个SineWave状态,并在其中使用sin函数。而这个函数体内的变量(time,phase_offset)均为类似MATLAB脚本的变量。此外,我们还需要在Stateflow图的Parameter Viewer中针对输入和输出参数定义相应的类型和名称,以将它们与MATLAB代码进行对接。

五、测试和仿真

最后,我们需要进行测试和仿真以验证Stateflow图的正确性。Stateflow可以通过生成C代码进行桌面仿真,也可以通过Simulink进行实时仿真。通常情况下,我们可以先在桌面上进行仿真,当Stateflow图的行为被验证后,再通过Simulink进行硬件验证。

在Simulink中使用Stateflow特别简单。首先,我们需要将Stateflow模块向Simulink模型中添加,并将它与其他Simulink模块进行连接。然后,我们需要将Stateflow图编译成C代码,从而生成可执行文件。最后,我们可以在Simulink的软件仿真环境中,通过执行生成的可执行文件来计算状态转移到的结果,并进行相应的输出。下面是如何进行桌面仿真和硬件验证的一个简单例子:

% 桌面仿真代码
load_system("model.slx"); % 加载模型
configure(model); % 参数配置
sim(model); % 开始仿真

有关如何进行硬件验证的详细步骤,参见Simulink的相关文档。

结论

通过以上的介绍,我们详细了解了Stateflow的基本语法和使用,包括状态和事件、Truth Table和Decision Block、超时和计数器、MATLAB函数的使用和测试和仿真。 Stateflow是一个非常强大的建模和仿真工具,为许多关键系统提供可视化的状态转移模型,并实现了高效的代码自动生成和测试验证功能。在实际的软件开发过程中,我们可以灵活运用Stateflow来提高系统的可靠性和效率。