3. Stateflow实现车灯自动控制逻辑

任务说明

本案例使用Stateflow构建一个包含两个状态的状态机,演示状态进入动作(entry action)的触发机制。当状态机激活某个状态时,进入该状态的瞬间执行一次entry动作——本例中为设置输出值并调用一个自定义函数。通过仿真观察输出信号的变化时刻,验证entry动作仅在状态激活时执行一次。

模型设计

在Simulink中创建Stateflow Chart,内部包含两个状态:State_A和State_B。使用一个外部输入信号switch控制状态切换,输出信号out_val记录当前状态对应的输出值。

  • State_A:entry动作设置 out_val = 1,并调用函数 logEntry('A')
  • State_B:entry动作设置 out_val = 2,并调用函数 logEntry('B')
  • 状态转移:State_A 在 switch > 0 时转移到 State_B;State_B 在 switch <= 0 时转移回 State_A

完整实现

在MATLAB命令窗口执行以下命令创建Stateflow Chart并配置完整逻辑:

% 创建模型
model = 'sf_entry_demo';
new_system(model);
load_system(model);

% 添加Stateflow Chart
chartPath = [model '/Chart'];
add_block('sflib/Chart', chartPath);
sfChart = sfroot;
chartObj = sfChart.find('-isa','Stateflow.Chart','-and','Path',chartPath);

% 创建状态A
stateA = Stateflow.State(chartObj);
stateA.Name = 'State_A';
stateA.Position = [50 50 100 60];
stateA.EntryAction = 'out_val = 1; logEntry(''A'');';

% 创建状态B
stateB = Stateflow.State(chartObj);
stateB.Name = 'State_B';
stateB.Position = [250 50 100 60];
stateB.EntryAction = 'out_val = 2; logEntry(''B'');';

% 创建转移
transAB = Stateflow.Transition(chartObj);
transAB.Source = stateA;
transAB.Destination = stateB;
transAB.LabelString = 'switch > 0';

transBA = Stateflow.Transition(chartObj);
transBA.Source = stateB;
transBA.Destination = stateA;
transBA.LabelString = 'switch <= 0';

% 添加输入输出端口
chartObj.Inputs = 'switch';
chartObj.Outputs = 'out_val';

% 添加Simulink输入输出模块
add_block('simulink/Sources/Step', [model '/Switch']);
set_param([model '/Switch'], 'Time', '1', 'Before', '0', 'After', '1', 'SampleTime', '0.1');
add_block('simulink/Sinks/Scope', [model '/Scope']);

% 连线
add_line(model, 'Switch/1', 'Chart/1');
add_line(model, 'Chart/1', 'Scope/1');

% 保存并打开
save_system(model);
open_system(model);

在Chart内部双击进入编辑界面,在Chart Properties中勾选Execute (enter) Chart at initialization,确保仿真开始时Chart被激活并执行初始状态的entry动作。

函数定义

在Chart的图形化函数区域添加以下MATLAB函数,用于记录entry动作触发日志:

function logEntry(stateName)
    % 在MATLAB命令行显示entry动作触发信息
    disp(['Entry action triggered in state: ' stateName]);
end

运行与验证

  1. 在模型窗口中点击Run按钮启动仿真,仿真时长设为3秒。
  2. 观察MATLAB命令行输出:仿真开始时(t=0)应显示Entry action triggered in state: A;当t=1秒时Switch信号从0跳变为1,状态切换到B,命令行应显示Entry action triggered in state: B。
  3. 打开Scope查看out_val波形:0~1秒期间输出值恒为1,1秒后跳变为2并保持。

通过条件:命令行日志与Scope波形均显示entry动作只在状态激活瞬间执行一次,且输出值与当前状态对应。若在状态驻留期间输出值保持不变且无重复日志,则验证通过。

关键点说明

  • entry动作在状态激活的瞬时执行,与状态驻留时长无关;状态内部若存在during动作,则每个仿真步执行,与entry动作不同。
  • 初始状态的entry动作在仿真启动时执行一次,前提是Chart属性中启用了初始化执行选项。
  • 本案例使用Step信号源产生阶跃输入,便于精确控制状态切换时刻,从而清晰观察entry动作的触发时机。