SMACH中,状态(State)是状态机器组成的重要部分,理解State的原理和实现,对使用SMACH很有帮助,特别是理解

__init__(),execute(),preempt是尤为关键。

__init__():初始化函数,状态初始化时,进行参数的初始化

execute():状态运行时执行的函数

preempt:暂停状态

详细的说明请参考例子:The principle of Passing User Data between States

下面对State类进行解释注释,代码如下:

 import threading
import traceback import smach __all__ = ['State','CBState'] class State(object):
"""SMACH的状态基类 SMACH状态和SMACH容器交互的方式有两种。第一种是它的输出标识符outcome。
第二种是运行(execute)时,用来读入和输出打用户数据(userdata)。在execute()
调用前,需要在构造函数(__init__())中声明outcome和userdata并做相应的校验。
"""
def __init__(self, outcomes=[], input_keys=[], output_keys=[], io_keys=[]):
"""状态构造函数
@type outcomes:字符串数组
@param outcomes: 为此状态定义输出(outcomes). @type input_keys: 字符串数组
@param input_keys: 在运行时,从外部输入的用户数据keys. @type output_keys: 字符串数组
@param output_keys: 在运行时,从外部输出的用户数据keys. @type io_keys: 字符串数组
@param io_keys: 在运行时,从外部输入/输出的用户数据keys.
"""
# 存储输出结果(outcomes)
self._outcomes = set(outcomes) # 存储用户数据接口的描述
self._input_keys = set(input_keys + io_keys)
self._output_keys = set(output_keys + io_keys) # 声明暂停的标识符
self._preempt_requested = False ### Meat
def execute(self, ud):
"""Called when executing a state.当执行状态时调用
在基类中该函数会抛出异常NotImplementedError. @type ud: 用户数据结构体
@param ud: 状态在执行时,传递的用户数据
"""
raise NotImplementedError() ### SMACH 接口 API
def register_outcomes(self, new_outcomes):
"""向结果集中添加结果标签."""
self._outcomes = self._outcomes.union(new_outcomes) def get_registered_outcomes(self):
"""获取已经注册打结果集.
@rtype: 字符串数组
@return: 已经注册打结果字符串的数组.
"""
return tuple(self._outcomes) ### 用户数据API
def register_io_keys(self, keys):
"""向io_keys集合中添加keys.
@type keys: 字符串数组
@param keys: 输入输出的keys.
"""
self._input_keys = self._input_keys.union(keys)
self._output_keys = self._output_keys.union(keys) def register_input_keys(self, keys):
"""向input_keys集合中添加keys.
@type keys: 字符串列表
@param keys: 输入的keys.
"""
self._input_keys = self._input_keys.union(keys) def get_registered_input_keys(self):
"""获得已经注册的input_keys数组."""
return tuple(self._input_keys) def register_output_keys(self, keys):
"""向output_keys集合中添加keys.
@type keys: 字符串列表
@param keys: 输出的keys.
"""
self._output_keys = self._output_keys.union(keys) def get_registered_output_keys(self):
"""获得已经注册打output keys的数组."""
return tuple(self._output_keys) ### 暂停的接口
def request_preempt(self):
"""设置暂停请求preempt_requested为True,状态机暂停的时候,就需要设置该状态为False,运行时
需要设置为True才行,否则运行到该状态就会停止了。
"""
self._preempt_requested = True def service_preempt(self):
"""设置暂停请求preempt_requested为False"""
self._preempt_requested = False def recall_preempt(self):
"""设置暂停请求preempt_requested为False"""
self._preempt_requested = False def preempt_requested(self):
"""如果暂停则返回True."""
return self._preempt_requested class CBState(State):
def __init__(self, cb, cb_args=[], cb_kwargs={}, outcomes=[], input_keys=[], output_keys=[], io_keys=[]):
"""从一个函数中创建一个状态. @type outcomes: 字符串数组
@param outcomes: 为该状态定义的outcomes. @type input_keys: 字符串数组
@param input_keys: 在运行时,从外部输入的用户数据keys. @type output_keys: 字符串数组
@param output_keys: 在运行时,从外部输出的用户数据keys. @type io_keys: 字符串数组
@param io_keys: 在运行时,从外部输入/输出的用户数据keys.
"""
State.__init__(self, outcomes, input_keys, output_keys, io_keys)
self._cb = cb
self._cb_args = cb_args
self._cb_kwargs = cb_kwargs if smach.util.has_smach_interface(cb):
self._cb_input_keys = cb.get_registered_input_keys()
self._cb_output_keys = cb.get_registered_output_keys()
self._cb_outcomes = cb.get_registered_outcomes() self.register_input_keys(self._cb_input_keys)
self.register_output_keys(self._cb_output_keys)
self.register_outcomes(self._cb_outcomes) def execute(self, ud):
return self._cb(ud, *self._cb_args, **self._cb_kwargs)

SMACH专题(四)----状态State类的实现和中文注释的更多相关文章

  1. Html飞机大战(四):状态的切换(界面加载类的编辑)

    好家伙,接着写   既然我们涉及到状态了,那么我们也会涉及到状态的切换   那么我们怎样切换状态呢? 想象一下,如果我玩的游戏暂停了,那么我们肯定是通过点击或者按下某个按键来让游戏继续   这里我们选 ...

  2. a链接四种伪类状态切换实现人机交互

    常见的color, font-family, background 等css属性都能够设置链接的样式,a链接的特殊性在于能够根据它们所处的状态来设置它们的样式.a标签与人交互的4个状态属于伪类状态切换 ...

  3. 状态(State)模式

    状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式.状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它的 ...

  4. SMACH专题(一)----安装与初探

    最近使用ROS进行任务(Task)执行,深切体会用传统的方法实现是极其繁杂的.比如人脸录入工作,包含人脸检测,识别,语音提示,运动控制,这些子部分基本都是通过订阅话题的回调函数中处理,之间的切换,如人 ...

  5. <a>链接的四个伪类顺序

    <a>元素的作用是可以创建一个链接,链接对应4个状态:未访问,已访问,鼠标悬停,鼠标点击瞬间. 为了给链接的4个状态应用样式,引入伪类的概念. 什么是伪类呢?简单点说,就是你没定义这个类, ...

  6. css 为元素选择器,css目标状态伪类,结构化选择器,多媒体选择器,清除表默认样式、属性选择器

    伪元素选择器 :before 和 :after 添加的位置 :before --- 第一个子节点 :after --- 最后一个子节点 特点 1.默认是 inline 元素 2.必须包含 conten ...

  7. React-本地状态(state)

    在类组件中添加本地状态(state): 1.创建一个继承自 React.Component 类的 ES6 class 同名类: 2.添加一个 类构造函数(class constructor) 初始化 ...

  8. SMACH专题(二)----Concurrent状态机

    Concurrent状态机是一种同时执行多个状态的状态机.如下图所示.状态FOO和BAR同时执行,当两个状态输出的结果同时满足一个组合条件时(FOO输出outcome2,BAR输出outcome1)才 ...

  9. Java 实现状态(State)模式

    /** * @author stone */ public class WindowState { private String stateValue; public WindowState(Stri ...

随机推荐

  1. js数据绑定(模板引擎原理)

    <div> <ul id="list"> <li>11111111111</li> <li>22222222222< ...

  2. 微信 JS API 支付教程

    最近一个项目中用到了微信开发,之前没有做过支付相关的东西,算是拿这个来练练手,刚开始接触支付时候很懵逼,加上微信支付开发文档本来就讲得不清楚,我是彻底蒙圈了,参考了很多代码之后,算是有一点思路了. 用 ...

  3. Ubuntu Touch On Nexus4 Manual Install (手动安装) under Gentoo

    Table of Contents 1. 准备工作: 2. Saucy Salamander 3. 刷入 最新 版Touch 最近手里的 Nexus 4 手机一直闲置,它的配置要比我六年前买的笔记本还 ...

  4. Kotlin尝试

    Kotlin 是一种静态类型的编程语言,可在 Java 虚拟机上运行,也可以编译为 JavaScript 源代码.其主要发展来自位于俄罗斯圣彼得堡的 JetBrains 程序员团队.虽然语法与 Jav ...

  5. hdu 4559 涂色游戏(SG)

    在一个2*N的格子上,Alice和Bob又开始了新游戏之旅. 这些格子中的一些已经被涂过色,Alice和Bob轮流在这些格子里进行涂色操作,使用两种涂色工具,第一种可以涂色任意一个格子,第二种可以涂色 ...

  6. #define const typedef

    #define用法 1. 定义简单的常数:定义常量,便于修改 #define N 1000 2. 定义简单的函数:注意多使用括号 define可以像函数那样接受一些参数,如下: #define max ...

  7. 【LOJ】 #2540. 「PKUWC2018」随机算法

    题解 感觉极其神奇的状压dp \(dp[i][S]\)表示答案为i,然后不可选的点集为S 我们每次往答案里加一个点,然后方案数是,设原来可以选的点数是y,新加入一个点后导致了除了新加的点之外x个点不能 ...

  8. openfire 部署后报错: java.lang.IllegalArgumentException: interface xx is not visible from class loader

    该异常是创建代理时加载接口的类加载器与创建时传入的不一致. 在本地eclipse做openfire二次开发,本地运行没错,部署到服务器上后报异常:  java.lang.IllegalArgument ...

  9. bzoj 1925 dp

    思路:dp[ i ][ 0 ]表示第一个是山谷的方案,dp[ i ][ 1 ]表示第一个是山峰的方案, 我们算dp[ x ][ state ]的时候枚举 x 的位置 x 肯定是山峰, 然后就用组合数算 ...

  10. bzoj 1271

    思路:因为被占奇数次的点只有一个, 那么我们可以将数轴分成两部分,奇数次点之前的前缀和为偶数,之后的前缀和为奇数, 然后就可以二分了. #include<bits/stdc++.h> #d ...