最近使用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. python3 切换工作文件夹

    python3 默认的工作文件夹在Python安装路径下.如下为查看工作文件夹路径: >>> import os >>> os.getcwd() 'D:\\Work ...

  2. HDU 6196 happy happy happy 爆搜加剪枝

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6196 题意:给你长度为n的序列,爸爸和儿子玩一个游戏,儿子先手,儿子每次都选择最左边与最右边最大的那个 ...

  3. OR 连接查询注意

    用or 查询时, 取得是 每个or中条件的 查询的结果集union. select * from categorysecond t where ISNULL(null); ort.csid in (' ...

  4. activiti源码分析学习

    activiti源码分析学习导语 目前项目中用activiti来做工作流的相关工作,最近遇到一些情况下,公司二次开发的流程图渲染出现了问题,会造成流程图出不来的情况.初步分析数据库中记录以及简单的代码 ...

  5. 【笔记】jQuery插件开发指南

    原文链接:http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html (有部分增删和修改) jQuery插件开发模式 软件开发过程中是需要一定 ...

  6. JAVA复习笔记之多线程并发

    前言:多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域,还是值得深入研究一下 概念: 1 线程:进程中负责程序执行的执行单元线程本身依靠程序进行运行线程是程序中的顺序控制流,只能使用 ...

  7. class getConstructor newinstance

    public static void main(String[] args) throws Exception{ /**获取String对象指定的构造方法(通过方法的参数类型,传递 参数的 Class ...

  8. MySQL学习笔记:从一个表update到另外一个表

    # ---- 测试数据 ---- # 表1 CREATE TABLE temp_x AS AS c_id, 1.11 AS c_amount FROM DUAL UNION ALL AS c_id, ...

  9. 如何用python解析mysqldump文件

    一.前言 最近在做离线数据导入HBase项目,涉及将存储在Mysql中的历史数据通过bulkload的方式导入HBase.由于源数据已经不在DB中,而是以文件形式存储在机器磁盘,此文件是mysqldu ...

  10. 20165333实验三 敏捷开发与XP实践

    实验内容 一.参考 http://www.cnblogs.com/rocedu/p/6371315.html#SECCODESTANDARD 安装alibaba 插件,解决代码中的规范问题. 在IDE ...