2. 状态机与Simulink信号交互
任务目标
在Simulink中建立一个包含Stateflow图表的状态机模型,实现以下功能:读取Simulink输入信号(阶跃信号),根据信号值的大小在“低电平”与“高电平”两个状态之间切换,并将当前状态编号(0或1)作为输出信号返回给Simulink,供Scope显示或后续模块使用。
环境依赖
- MATLAB R2020a或更高版本(含Stateflow许可证)
- Simulink与Stateflow工具箱
模型搭建步骤
- 新建Simulink模型,添加以下模块:
- Signal Editor或Step模块(作为输入信号源)
- Stateflow Chart模块(双击进入编辑状态机)
- Scope模块(显示输出)
- 在Stateflow编辑器中创建两个状态:
Low(低电平)与High(高电平)。 - 定义输入事件或使用默认的输入条件触发方式(本例采用函数调用式输入,即每个仿真步长读取一次输入)。
- 设置状态转移条件,并定义输出变量。
Stateflow内部实现
在Stateflow图表中,添加一个输入端口u(来自Simulink)和一个输出端口y(返回状态值)。使用以下逻辑:
- 初始状态为
Low,输出y = 0。 - 当
u >= 1时,从Low转移到High,输出y = 1。 - 当
u < 1时,从High转移回Low,输出y = 0。
关键完整代码(Stateflow图表定义)
以下为Stateflow图表的完整定义,可直接复制到Stateflow编辑器中(通过“编辑 > 添加 > 图表”后,在图表属性中粘贴或手动创建):
// Stateflow 图表内部定义
// 输入: u (double)
// 输出: y (double)
// 状态 Low:
// entry: y = 0;
// 转移条件: [u >= 1] → 状态 High
// 状态 High:
// entry: y = 1;
// 转移条件: [u < 1] → 状态 Low
// 默认转移: → 状态 Low
在Stateflow图形编辑器中,手动创建两个状态框并填写上述逻辑,或使用以下MATLAB脚本自动生成模型与图表:
% 创建模型与Stateflow图表(完整可运行)
modelName = 'sf_signal_interaction';
new_system(modelName);
open_system(modelName);
% 添加输入信号源(阶跃信号,在t=5时从0跳变到1)
add_block('simulink/Sources/Step', [modelName '/Input']);
set_param([modelName '/Input'], 'Time', '5', 'Before', '0', 'After', '1');
% 添加Stateflow Chart模块
add_block('sflib/Chart', [modelName '/StateMachine']);
% 添加Scope
add_block('simulink/Sinks/Scope', [modelName '/Output']);
% 连接信号
add_line(modelName, 'Input/1', 'StateMachine/1');
add_line(modelName, 'StateMachine/1', 'Output/1');
% 配置Stateflow图表输入输出
rt = sfroot;
chart = find(rt, '-isa', 'Stateflow.Chart', 'Path', [modelName '/StateMachine']);
if isempty(chart)
% 若图表不存在则创建
load_system('sflib');
add_block('sflib/Chart', [modelName '/StateMachine']);
chart = find(rt, '-isa', 'Stateflow.Chart', 'Path', [modelName '/StateMachine']);
end
% 添加输入和输出数据
inputData = Stateflow.Data(chart);
inputData.Name = 'u';
inputData.Scope = 'Input';
outputData = Stateflow.Data(chart);
outputData.Name = 'y';
outputData.Scope = 'Output';
% 创建状态
lowState = Stateflow.State(chart);
lowState.Name = 'Low';
lowState.Position = [50 50 100 60];
highState = Stateflow.State(chart);
highState.Name = 'High';
highState.Position = [200 50 100 60];
% 默认转移到Low
defaultTrans = Stateflow.Transition(chart);
defaultTrans.Source = [];
defaultTrans.Destination = lowState;
defaultTrans.LabelString = '';
% Low → High 转移
trans1 = Stateflow.Transition(chart);
trans1.Source = lowState;
trans1.Destination = highState;
trans1.LabelString = 'u >= 1';
% High → Low 转移
trans2 = Stateflow.Transition(chart);
trans2.Source = highState;
trans2.Destination = lowState;
trans2.LabelString = 'u < 1';
% 设置状态entry动作
lowState.LabelString = sprintf('Low:\nentry: y = 0;');
highState.LabelString = sprintf('High:\nentry: y = 1;');
% 保存模型
save_system(modelName);
disp('模型已创建并保存。');
运行与验证
- 将上述MATLAB脚本复制到命令窗口执行,自动生成完整模型。
- 点击Run按钮运行仿真(默认仿真时间10秒)。
- 双击Scope模块查看输出波形。
通过条件:Scope中显示输出信号y在0~5秒内保持为0,在5秒后跳变为1并保持到仿真结束。该结果与输入阶跃信号在t=5秒从0变为1的逻辑完全一致,证明状态机正确读取了Simulink输入信号并完成了状态切换与输出。
预期输出说明
由于输入信号为确定性阶跃(t=5前为0,t=5后为1),根据状态机逻辑可唯一推出:输出y在t=5前为0,t=5后为1。此预期结果由代码逻辑直接推导,非实测数据。