2. 双状态交替控制

任务目标

使用Stateflow实现一个双状态交替控制逻辑:两个状态State_A和State_B互斥激活,通过外部输入信号switch_signal控制状态切换,并输出当前激活状态编号。该案例用于演示Stateflow中最基础的状态迁移与事件驱动机制。

环境依赖

  • MATLAB R2018b或更高版本(含Stateflow工具箱)
  • Simulink(用于搭建模型并调用Stateflow图表)

实现步骤

在Simulink中新建模型,添加Stateflow Chart模块,双击进入图表编辑器,按以下逻辑完成设计:

  1. 创建两个互斥状态:State_A(entry动作:current_state = 1;)和State_B(entry动作:current_state = 2;)。
  2. 默认迁移指向State_A(初始激活状态)。
  3. 从State_A到State_B的迁移条件:[switch_signal == 1]。
  4. 从State_B到State_A的迁移条件:[switch_signal == 0]。
  5. 定义输入事件或输入端口:使用输入信号方式,在图表属性中添加输入switch_signal(数据类型double),添加输出current_state(数据类型double)。

关键完整代码

以下为Stateflow图表的完整定义代码(可直接粘贴到Stateflow图表属性中,或通过MATLAB命令创建):

% 在MATLAB命令窗口执行以下命令创建Stateflow图表
modelName = 'dual_state_control';
new_system(modelName);
open_system(modelName);

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

% 设置输入输出端口
chartObj.Inputs = 'switch_signal';
chartObj.Outputs = 'current_state';

% 创建两个状态
stateA = Stateflow.State(chartObj);
stateA.Name = 'State_A';
stateA.Position = [100 100 80 50];
stateA.EntryAction = 'current_state = 1;';

stateB = Stateflow.State(chartObj);
stateB.Name = 'State_B';
stateB.Position = [300 100 80 50];
stateB.EntryAction = 'current_state = 2;';

% 设置默认迁移到State_A
defaultTrans = Stateflow.Transition(chartObj);
defaultTrans.Source = [];
defaultTrans.Destination = stateA;
defaultTrans.LabelString = '';

% 迁移:State_A -> State_B
transAB = Stateflow.Transition(chartObj);
transAB.Source = stateA;
transAB.Destination = stateB;
transAB.LabelString = '[switch_signal == 1]';

% 迁移:State_B -> State_A
transBA = Stateflow.Transition(chartObj);
transBA.Source = stateB;
transBA.Destination = stateA;
transBA.LabelString = '[switch_signal == 0]';

% 保存模型
save_system(modelName);

运行与验证

完成图表设计后,在Simulink模型中添加以下验证结构:

  • Signal Editor或Step模块:生成switch_signal测试信号(0→1→0的阶跃序列)。
  • Scope:连接current_state输出,观察状态值变化。

仿真设置:停止时间20秒,求解器选择discrete(固定步长0.1s)。

验证方法:

  1. 仿真开始后,current_state应保持为1(State_A激活)。
  2. 当switch_signal从0跳变为1时,current_state应变为2(State_B激活)。
  3. 当switch_signal从1跳变为0时,current_state应回到1。

预期输出:给定输入信号序列[0,0,1,1,0,0](每段持续3秒),对应输出current_state应为[1,1,2,2,1,1]。该结果由状态迁移逻辑直接唯一确定,可用于判定逻辑正确性。

常见问题

  • 状态不切换:检查迁移条件中的比较运算符是否为==(而非=),并确认输入信号数据类型与条件表达式兼容。
  • 初始状态错误:确认默认迁移箭头从图表左上角的空心圆点出发指向State_A。
  • 输出不更新:确保current_state赋值写在状态的entry动作中,而非during动作。