最近使用ROS进行任务(Task)执行,深切体会用传统的方法实现是极其繁杂的。比如人脸录入工作,包含人脸检测,识别,语音提示,运动控制,这些子部分基本都是通过订阅话题的回调函数中处理,之间的切换,如人脸识别,语音提示之间的切换,需要用信号量进行控制切换,当多数据融合的时候,逻辑是极其的混乱的,也容易导致冗余代码,后期的维护也是不易于维护的。深切体会到一个好的实现框架有多么的重要。正如自己的体会,PR2开发中,发现如果不用一套完整的框架去执行任务,会导致代码的维护特别的繁杂,所以大佬们才开发这套smach状态机功能包。而状态机的思想也正符合机器人的这种多数据融合,多子任务执行的问题。状态机的优点是:实现简单,易于维护,重构任务顺序容易。最近的实现证明,smach正是为任务执行量身定做的。经检索也发现,国内介绍关于smach状态机的介绍和比较少,从这篇开始,我们将连续的介绍在ROS-Indigo版本下的smach使用。

1、安装

  学习smach之前需要安装这个软件,安装smach有两种方式:

  a、使用apt-get直接安装(推荐),只需要执行如下代码:

$ sudo apt-get install ros-indigo-executive-smach

  b、使用源码安装,只需要在相应的工作空间的src下,通过git clone拉取下来,比如在catkin_ws/src的目录下执行如下代码:

$ git clone http://wiki.ros.org/smach/Tutorials

2、smach介绍

 smach[1]是ros中的一个实现有限状态机的开发包,在ROS任务执行中使用得比较多。一提到状态机,大家可能会想起图灵而望而生畏,别紧张,其实没那么的难。smach使用了python实现,所以要使用smach只能在python环境中使用,python使用起来很简单,如果有编程基础,看几个小时就可以上手,没编程基础的看几天也可以很容易上手。

  smach提供了actionlib整合和smach viewer两大组件。smach viewer可以实时地查看任务执行当前的状态节点位置,是调试开发的必备工具。smach还整合了动作状态,例如定点导航。可以把话题topic,服务service转化为状态,也可以把一个类转化为状态节点。smach可以实现状态的并发执行,任务的重复执行,层次嵌套复杂的状态机(状态机也可以作为一个状态)。

  学习smach需要有两个基础:状态机和python知识。

  a、状态机

  状态机就是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。参考资料[3],最简单的例子就是灯的开灯和关灯的例子。用开灯状态和关灯状态描述灯的状态,状态之间的转换,通过开灯动作和关灯的动作来完成,基于smach打实现如下:

#!/usr/bin/env python

import roslib; roslib.load_manifest('smach_sample_node')
import rospy
import smach
import smach_ros
import time
# define state Foo # define state Bar
class Open(smach.State):
def __init__(self):
smach.State.__init__(self, outcomes=['closed']) def execute(self, userdata):
rospy.loginfo('Opened')
time.sleep(2)
rospy.loginfo('Closeing')
return 'closed' #define state close light
class Close(smach.State):
def __init__(self):
smach.State.__init__(self, outcomes=['opened']) def execute(self, userdata):
rospy.loginfo('Closed')
time.sleep(2)
rospy.loginfo('Closing')
return 'opened' # main
def main():
rospy.init_node('smach_example_state_machine') # Create a SMACH state machine
sm_light = smach.StateMachine(outcomes=['stop', 'succee']) # Open the container
with sm_light:
# Add states to the container
smach.StateMachine.add('OPEN', Open(),
transitions={'closed':'CLOSE'})
smach.StateMachine.add('CLOSE', Close(),
transitions={'opened':'OPEN'}) # Execute SMACH plan
sis = smach_ros.IntrospectionServer('sm_light', sm_light, '/SM_ROOT')
sis.start()
# Execute SMACH plan
outcome = sm_light.execute() # Wait for ctrl-c to stop the application
rospy.spin()
sis.stop() if __name__ == '__main__':
main()

    输出结果:

[INFO] [WallTime: 1453689512.106141] Closed
[INFO] [WallTime: 1453689514.108995] Closing
[INFO] [WallTime: 1453689514.109447] State machine transitioning 'CLOSE':'opened'-->'OPEN'
[INFO] [WallTime: 1453689514.109942] Opened
[INFO] [WallTime: 1453689514.420038] Closeing
[INFO] [WallTime: 1453689514.420271] State machine transitioning 'OPEN':'closed'-->'CLOSE'

    相应的状态机实时状态,如下图所示:

    大家发现,基于smach实现状态机器是如此打简单,所以大胆打去弄熟它吧。

    下面贴出两张ros smach viewer生成的图,直观感受下状态机的魅力。

    简单有限状态机:

(来自:ros wiki)

    较为复杂的有限状态机:    

(来自ros wiki)

  b、python知识

   网上资源特别多,这里不展开介绍了。请参考[2]

参考资料

[1]. http://wiki.ros.org/smach/Tutorials

[2]. Python菜鸟教程

[3]. 有限状态机

SMACH专题(一)----安装与初探的更多相关文章

  1. freeswitch编译安装,初探, 以及联合sipgateway, webrtc server的使用场景。

    本文主要记录freeswitch学习过程. 一 安装freeswitch NOTE 以下两种安装方式,再安装的过程中遇到了不少问题,印象比较深刻的就是lua库找到不到这个问题.这个问题发生在make ...

  2. bbed的使用--安装及初探

    bbed是oracle内部一款用来直接查看和修改数据文件数据的工具,可以直接修改Oracle数据文件块的内容,在一些特殊恢复场景下比较有用. 1.bbed 的安装 在9i/10g中连接生成bbed: ...

  3. SMACH专题(三)----几种State类型

    状态机提供了若干种状态,包括了Generic State,CBState,SimpleActionState (ROS),ServiceState (ROS),MonitorState (ROS).下 ...

  4. SMACH专题(四)----状态State类的实现和中文注释

    SMACH中,状态(State)是状态机器组成的重要部分,理解State的原理和实现,对使用SMACH很有帮助,特别是理解 __init__(),execute(),preempt是尤为关键. __i ...

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

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

  6. 虚拟机安装&Linux初探

    学习基于VirtualBox虚拟机安装Ubuntu图文教程在自己笔记本上安装Linux操作系统 安装虚拟机的过程还算顺利.除了在安装增强设备功能时需要将之前的硬盘弹出之外,没有遇到其他的问题. 通过实 ...

  7. Python模块安装路径初探

    在调用MySQL第三方工具mysqlrplsync是报错 mysqlrplsync --master=checksum:checksum@master_ip:3306 --slave=checksum ...

  8. 安装archlinux的另辟蹊径的命令及心得

    先说说我为什么开始入坑archlinux的吧,我最喜欢这个系统的一点就是简洁,DIY程度高,可以定制真正属于自己的专用系统.(像gentoo的话,就为了日常使用也没必要那么折腾,除非你是想在折腾的过程 ...

  9. [知识库分享系列] 四、ASP.NET MVC and Winform

    知识库分享系列: [知识库分享系列] 三.Web(高性能Web站点建设) [知识库分享系列] 二..NET(ASP.NET) [知识库分享系列] 一.开篇 分享介绍本篇分享两个知识库节点,分别为“AS ...

随机推荐

  1. 利用github pages五分钟建好个人网站+个人博客

    笔者自己在建个人网站/个人博客的时候其实遇到了不少麻烦,但是都一一解决了,这里教给大家最简单的方式. 首先你需要一个GitHub账号,访问https://github.com创建新账号即可. 然后访问 ...

  2. tf.metrics.accuracy ==>坑货

    tf.metrics.accuracy输出两个值,第一个值为上几步的平均精度,第二值是上几步与该步的精度的平均值. 正常的计算单个batch正确率的代码 self.correct_prediction ...

  3. 洛谷P2812校园网络

    传送门啦 其实这个题只要读懂分析好题意就不是很难. 就是将一个有向图进行缩点操作,把一个强连通分量看成一个点,求入度为 0 的点和出度为 0 的点各有多少. 在这里先向大家推荐两个题目,建议大家先去看 ...

  4. Java 容器的打印

    Java容器类库中的两种主要类型,它们的区别在于容器中每个"槽"保存的元素个数 Clollection容器只能在保存一个元素,此类容器包括: List,它以特定顺序保存一组元素 S ...

  5. CVE-2013-1347Microsoft Internet Explorer 8 远程执行代码漏洞

    [CNNVD]Microsoft Internet Explorer 8 远程执行代码漏洞(CNNVD-201305-092) Microsoft Internet Explorer是美国微软(Mic ...

  6. 【58沈剑架构系列】RPC-client异步收发核心细节?

    第一章聊了[“为什么要进行服务化,服务化究竟解决什么问题”] 第二章聊了[“微服务的服务粒度选型”] 第三章聊了[“为什么说要搞定微服务架构,先搞定RPC框架?”] 上一章聊了[“微服务架构之RPC- ...

  7. Linux 中 &、jobs、fg、bg 等命令

    参考  Unix 或 Linux 中 &.jobs.fg.bg 等命令的使用方法 对之前文章的一个补充: linux 命令后台运行 这篇还是比较简单的,稍微一带而过 fg.bg.jobs.&a ...

  8. centos6编译安装zabbix3.0和中文支持整理文档

    编者按: 最近公司部分业务迁移机房,为了更方便的监控管理主机资源,决定上线zabbix监控平台.运维人员使用2.4版本的进行部署,个人在业余时间尝鲜,使用zabbix3.0进行部署,整理文档如下,仅供 ...

  9. codeforces 603 A

    题目大意:给你一个0,1串, 你可以反转一段连续的区间,问你最长的合法子串是多长, 合法字串相邻的两个不能相同. 思路:dp[ i ][ k ][ j ] 表示到第 i 个字符, 处于k这种状态, k ...

  10. vue 父子间组件传值

    1.父组件向子组件传值: 实例截图: 实例代码: /*子组件代码*/ //child.vue <template> <div style="border: 1px soli ...