3. 状态进入动作
任务说明
本案例使用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
运行与验证
- 在模型窗口中点击Run按钮启动仿真,仿真时长设为3秒。
- 观察MATLAB命令行输出:仿真开始时(t=0)应显示
Entry action triggered in state: A;当t=1秒时Switch信号从0跳变为1,状态切换到B,命令行应显示Entry action triggered in state: B。 - 打开Scope查看
out_val波形:0~1秒期间输出值恒为1,1秒后跳变为2并保持。
通过条件:命令行日志与Scope波形均显示entry动作只在状态激活瞬间执行一次,且输出值与当前状态对应。若在状态驻留期间输出值保持不变且无重复日志,则验证通过。
关键点说明
- entry动作在状态激活的瞬时执行,与状态驻留时长无关;状态内部若存在during动作,则每个仿真步执行,与entry动作不同。
- 初始状态的entry动作在仿真启动时执行一次,前提是Chart属性中启用了初始化执行选项。
- 本案例使用Step信号源产生阶跃输入,便于精确控制状态切换时刻,从而清晰观察entry动作的触发时机。