2. Stateflow状态机建模基础

任务说明

本案例使用Simulink/Stateflow建立一个包含两个状态(启动与运行)的状态机,通过外部阶跃信号触发状态切换,并在Simulink中完成仿真验证。最终交付物为一个可直接打开的模型文件及对应的仿真测试方法。

状态机设计

状态机包含两个互斥状态:Idle(空闲)与Running(运行)。输入信号start_cmd为阶跃信号,上升沿触发状态由Idle切换至Running;输入信号stop_cmd为阶跃信号,上升沿触发状态由Running切换回Idle。输出信号status为状态编码:Idle时输出0,Running时输出1。

Idle entry: status = 0; during: status = 0; Running entry: status = 1; during: status = 1; start_cmd == 1 stop_cmd == 1 输入信号 start_cmd / stop_cmd(阶跃信号) 输出信号 status(0 或 1)

模型实现步骤

在MATLAB命令窗口执行以下命令创建模型(需Stateflow许可证):

% 创建新模型
model = 'sf_two_state_demo';
new_system(model);
open_system(model);

% 添加Stateflow Chart模块
add_block('sflib/Chart', [model '/Controller']);

% 添加输入端口(来自工作空间的阶跃信号)
add_block('simulink/Sources/In1', [model '/start_cmd']);
add_block('simulink/Sources/In1', [model '/stop_cmd']);

% 添加输出端口
add_block('simulink/Sinks/Out1', [model '/status']);

% 连接输入到Chart
add_line(model, 'start_cmd/1', 'Controller/1', 'autorouting', 'on');
add_line(model, 'stop_cmd/1', 'Controller/2', 'autorouting', 'on');

% 连接Chart输出
add_line(model, 'Controller/1', 'status/1', 'autorouting', 'on');

% 保存模型
save_system(model);

在Chart内部双击打开Stateflow编辑器,添加两个状态并设置转移条件:

% 在Chart中添加状态(需在Stateflow编辑器中手动操作)
% 1. 添加状态 Idle:entry动作 status = 0;
% 2. 添加状态 Running:entry动作 status = 1;
% 3. 添加默认转移指向 Idle
% 4. 添加转移 Idle -> Running,条件:start_cmd == 1
% 5. 添加转移 Running -> Idle,条件:stop_cmd == 1

Chart的输入输出定义:输入事件start_cmd和stop_cmd为double类型的外部输入;输出status为double类型。在Chart属性中设置触发类型为Function Call或Rising Edge均可,本案例采用默认的Function Call语义,即每个仿真步长评估一次转移条件。

仿真验证

使用以下脚本配置仿真输入并运行,观察状态切换是否符合预期:

% 仿真配置
set_param(model, 'StopTime', '10');
set_param(model, 'Solver', 'FixedStepDiscrete');
set_param(model, 'FixedStep', '0.1');

% 生成阶跃输入信号
t = (0:0.1:10)';
start_cmd = zeros(size(t));
stop_cmd = zeros(size(t));

% 第2秒时 start_cmd 置1(触发 Idle -> Running)
start_cmd(t >= 2 & t < 2.1) = 1;

% 第6秒时 stop_cmd 置1(触发 Running -> Idle)
stop_cmd(t >= 6 & t < 6.1) = 1;

% 写入工作空间
assignin('base', 'start_cmd', timeseries(start_cmd, t));
assignin('base', 'stop_cmd', timeseries(stop_cmd, t));

% 连接工作空间信号到模型输入
set_param([model '/start_cmd'], 'Port', '1');
set_param([model '/start_cmd'], 'Source', 'start_cmd');
set_param([model '/stop_cmd'], 'Port', '1');
set_param([model '/stop_cmd'], 'Source', 'stop_cmd');

% 运行仿真
simOut = sim(model);

% 获取输出
status_out = simOut.get('status');
fprintf('仿真完成,输出信号长度: %d\n', length(status_out));

预期输出与判定标准

根据上述输入信号,状态机的确定性行为如下:

  • 0~2秒:Idle状态,status输出为0;
  • 2~6秒:Running状态,status输出为1;
  • 6~10秒:Idle状态,status输出为0。

验证方法:在仿真结束后,使用plot(t, status_out)绘制输出曲线,观察status在2秒时从0跳变为1,在6秒时从1跳变为0,且其他时间段保持恒定,即可判定状态机逻辑正确。若输出波形与上述描述不符,检查Chart中的转移条件方向或输入信号连接是否错误。