状态机设计处理数据输入

时间:2018-12-15 18:04:20

标签: c++ events state-machine

我正在实时机器控制系统上工作,该系统执行一系列任务,并且应对大量输入做出反应。我决定使用状态机来实现该系统。

过去,我曾经使用过基于简单开关/案例的状态机,并且希望过渡到更易于维护的解决方案。目前,我对如何处理输入和转换有些困惑。

例如,我有一个AnalogInput类,可为我提供应监视的测量值。假设我有一个状态 WaitForThreshold ,该状态应读取AnalogInput,然后在达到阈值时进行转换。

我要 a)将对AnalogInput类的引用传递给 WaitForThreshold 类,并允许其监视输入本身,并向StateMachine类发出希望转换的信号。

b)创建专用事件 LaserMeasurementAtThreshold 和状态转换图:StateMachine.addTransition(State A,Event e,State B)

c)创建更多通用事件 AnalogInputChanged 并为每个事件实现事件处理程序,这再次向StateMachine发出信号,表明需要进行过渡

选项a本质上是简单的开关/案例状态机的较大版本,可能会随着时间的推移而变得混乱,但提供了极大的灵活性,并且b / c似乎更加结构化和整洁,但似乎我可能不得不跳过很多由于事件数量可能非常大,因此无法实现相对简单的任务。

有人能提供一些关于状态机设计的见识吗,其中必须监视大量的输入源和类型,并且事件很大程度上是特定于状态的(大多数事件仅涉及单个状态)?

状态机设计可能还有其他选择来控制必须执行一系列步骤的系统(必须可以进行非线性,循环和转移)

语言:C ++

谢谢

1 个答案:

答案 0 :(得分:0)

我相信将其作为过渡表来实现会更清晰:

typedef (void)((*Pointer_To_Transition_Function)());
struct Table_Entry
{
  Input_Type input_value;
  Pointer_To_Transisiton_Function p_trans_function;
};

static const Table_Entry Transition_Table[] = 
{
  {4, Read_Sensor},
};
static const size_t transition_quantity =  
    sizeof(Transition_Table) / sizeof(Transition_Table[0]);

//...
for (size_t index = 0; index < transition_quantity; ++index)
{
  if (input_value = Transition_Table[index].input_value)
  {
    Pointer_To_Transition_Function p_function = Transition_Table[index].p_trans_function;
    // Call the function:
    p_function();
    break;
  }
}

您可以使用std::map,但必须在运行时初始化std::map。该表(数组)是静态且恒定的,因此可以将其放置在只读内存段中(对于嵌入式系统很方便);并且不使用动态内存分配。

编辑1:表格的ASCII图

+-------------+--------------------------------+  
| Input value | Pointer to transition function |  
+-------------+--------------------------------+  
|     4       |   Read sensor                  |
+-------------+--------------------------------+  
|     2       |   Start motor                  |
+-------------+--------------------------------+