问题标签 [boost-msm]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
169 浏览

c++ - 如何将 boost msm 与 boost 信号结合使用?

我对“boost msm”真的很陌生,现在我遇到了一个问题,如何在boost msm中使用boost信号,我尝试了很多次但没有用。

我想要实现的是当机器改变状态时,动作操作员发出信号,我的外部实体捕捉到信号并继续执行其他功能,但现在我无法将信号发出机器,我无法连接与外部实体的信号。有没有例子?

0 投票
0 回答
158 浏览

c++ - 为什么 boost msm 两次呼叫警卫?

我正在实现一个状态机,如下图 状态机图

我向状态机触发“event1”和“event2”,当“event1”触发时,状态机退出“state1”状态,进入“state3”子状态机并停留在“state3-state1”状态。当“event2”触发时,“state3”子状态机进入退出指针,进入“state1”状态。进入“state1”状态后,我发现“守卫”被调用了两次。以下是我的代码

boost的版本是1.66,程序的输出是

我找到了一个更简单的圆顶来显示相同​​的问题,状态机图在这里,代码是

程序的输出是

0 投票
1 回答
290 浏览

c++ - 延迟来自子状态机的事件

在我的项目中,有一个使用 boost 元状态机实现的状态机。这个主状态机,有一个状态(为了简单起见,我们称之为SubMachineEntry),它代表一个子状态机的入口点:

这个子状态机执行一些处理,然后我们回到外部状态机,状态

,代表子机的退出状态。我的问题是,在子状态机退出之前,可能会调度某个事件(toProcessInOuter),并且应该在子状态机退出后在外部状态机中处理。将该事件作为延迟放在子状态机中的所有状态中不起作用,它不会传播到之后的状态SubMachineFinished。有没有办法使用 boost MSM 的某种机制来实现这种事件的转发,而不使用一些自定义的解决方法?

0 投票
1 回答
507 浏览

c++ - 处理 Boost MSM 中每个状态的错误

我正在使用 Boost MSM 来模拟机器人的行为。有多种状态,如“ManualMove”、“AutoMove”、“Work”、“Idle”等......但是我需要能够从任何状态强制停止机器人,使其处于无法移动的状态并且无法接收新命令,因此我创建了“紧急停止”状态。 当机器人被要求重新武装自己时,机器人应该回到“空闲”状态。

但是,Boost 不建议创建从所有状态到单个状态的转换,而是更喜欢使用正交状态。所以我可以例如做“AllOk”和interrupt_state“EmergencyStopped”正交状态。

问题是,虽然我可以轻松地将机器人置于“EmergencyStopped”状态,但我无法退出并让机器人从之前的状态进入“空闲”状态。例如,如果机器人这样做:

  • [工作,一切正常] -> 停止
  • [工作,紧急停止] -> 恢复

机器人将处于状态 [Work, AllOk],而我希望它进入状态 [Idle, AllOk]。

所以我的问题是:

  • 我可以而且应该在这个工作流程中使用正交状态吗?如果是,当我退出正交状态“EmergencyStopped”时,如何强制状态“空闲”?
  • 或者我应该使“紧急停止”非正交并声明从所有状态到它的过渡?
  • 还是有其他解决方案?
0 投票
0 回答
234 浏览

c++ - 如何使用 Boost MSM 检索包含状态机

我使用 Boost MSM,我必须在状态机周围传递数据/使用函数。为此,我使用操作或 on_entry 挂钩从事件get_state()中获取数据,或从先前的使用状态中获取数据。

但是,我无法使用这种技术访问底层状态机,当我处于子状态机中时,我根本无法访问主状态机。

例如(带有操场链接):

ProcessingState::on_entry中,我无法使用get_state来获取SubStateMachine,也无法使用MainStateMachine. 我知道FSM会解决SubStateMachine,但是有没有办法得到MainStateMachine呢?

0 投票
1 回答
238 浏览

c++ - Boost MSM:使用状态机本身作为隐式顶级状态

我有一个带有 states 的状态机AB并且C. C直接处理事件e,whileABdo not,但我想回退到事件的默认处理程序(Samek 称之为“终极钩子”模式) (当在 states和e中找不到处理程序时将调用该处理程序)。但是,使用 Boost MSM,我无法在状态机级别实现此处理程序,而必须引入包含,和的附加容器状态。ABSABC

有没有办法直接在状态机级别本身实现事件处理程序,而不需要这个容器状态?

0 投票
1 回答
143 浏览

c++ - 如何在使用 Boost MSM 编写的状态机中直接达到任何状态

我目前正在使用 Boost MSM 库来编写状态机,并且我想编写单元测试来检查其状态之间的转换。对于每个单元测试,我需要编写重复的代码行以达到我想要开始的状态。因此,我想知道它们是否是一种在给定状态而不是启动状态下启动状态机的方法。

例如,如果我有一个像这样通常从 StartingState 开始的简单状态机,我想直接访问 IdleState 进行测试:

  • --> 起始状态 --> 空闲状态 --> 错误状态
0 投票
1 回答
46 浏览

c++ - 如何防止正交区域转换以进行错误处理

我想使用 Boost MSM 创建以下状态机:

正交区域中具有错误状态的简化 FSM

如果正交状态为“B”,我希望能够阻止Error事件触发转换。AllOk + Error == InError例如,为所有正交状态指定转换会很好。就像是:

但是,我找不到使用 Boost MSM 的方法,也找不到常规的 UML 命名法,这让我觉得我走错了路。

是否有经典的“UML 惯用语”来处理这种行为?

我看到两种可能的解决方案:

  • 设置一个警卫AllOk + Error == InError,检查其他状态是否是B就像这个响应
  • 发送一个更具体的错误(在我的例子中,CouldNotComputePath,因为我正在编写一个机器人),Error如果它没有被处理,则以某种方式将其转换。我不确定该怎么做。
0 投票
1 回答
141 浏览

c++ - 启动状态机无法处理启动时的内部转换

我有以下状态机(抱歉,我找不到如何制作更小的 MRE):

  • SM,包含 MainSM,包含 SubSM。
  • SM 有一个内部转换表,上面写着“忽略事件触发器”。
  • 启动时,SM 的初始状态为 MainSM,而 MainSM 的 initial_state 为“Default”(因此它不是 SubSM)。
  • 只有 SubSM 处理“触发器”事件。

它完美地工作,状态机按预期忽略Trigger事件。但是,如果发送事件的on_entry方法然后启动状态机将不会处理事件和调用。MainSMTriggerno_transition

问题是什么?调用start时SM还没准备好?这是一个错误还是符合规范?

这是代码片段。删除 process_event 调用第 80 行,一切正常。

使用 GCC 5.5、Clang 8、Boost 1.58 和 1.73 以及 C++14 进行测试。

0 投票
0 回答
80 浏览

c++ - boost.msm 如何调用当前状态方法

我必须用公共接口(API)实现一些逻辑。

每个 API 调用的返回值和“含义”取决于某些状态。规则示例:如果您在成功调用 api_open() 之前进行了任何 api 调用,则应返回错误。我在这里看到两种状态:初始状态和打开状态。在初始状态下,所有 api 调用都应该返回错误,除了 api_open()。在打开状态 api_1() 和 api_2() 执行一些操作。

通常我会将其实现为具有公共接口和以具体类型实现的状态的状态模式。示例:https ://www.robertlarsononline.com/2017/05/11/state-pattern-using-cplusplus/

然后我想..如果每个 boost.msm 状态都是这样的

然后我需要做的就是从状态机访问当前状态......并调用 api 方法。

但是引用 fom doc: current_state 返回当前活动状态的 id。您通常仅将它用于调试或记录目的。

感觉就像我试图滥用 boost.msm 库......我想我正在尝试将经典的 oop 状态模式与 msm 混合。情况不妙....

可能我应该将每个 API 调用作为事件(带有数据,表示 API 调用参数)传递给状态机,并以某种方式从中获取返回值......如何?

感觉就像将数据发送到状态机并取回并不明显。或者我可能没有明白这一点?

所以主要问题是:用 boost.msm 解决我的问题的正确方法是什么?