最近使用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. 【转载】ajaxFileUpload 报这错jQuery.handleError is not a function

    今天刚打个一个技术群,里面有人问标题上的问题,嘿,我恰好遇过,现在大家至少也在用jquery1.9以上的版本,ajaxfileupload的版本早就不更新了,大家可以下载看:地址这里,它例子里使用的J ...

  2. 缓存数据库-redis数据类型和操作(set)

    一:Redis 集合(Set) Redis的Set是string类型的无序集合.集合成员是唯一的,这就意味着集合中不能出现重复的数据. Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复 ...

  3. Graham求凸包模板

    struct P { double x, y; P(, ):x(x), y(y) {} double add(double a, double b){ ; return a+b; } P operat ...

  4. Centos之关机和重启命令

    shutdown命令 shutdown [选项] 时间 -c:取消前一个关机命令 -h:关机 -r:重启 [root@localhost ~]# date 2017年 06月 21日 星期三 15:4 ...

  5. xcode7 调用相册权限无提示

    1) 打开工程的Info.pilst: 2) 把 Bundle name 和 Bundle display name 的 value值 ,改成跟项目app名一致: 这样系统才能正确地接收到调用请求

  6. MICROSOFT SQLSERVER 总结

    --语 句 功 能--数据操作Select --从数据库表中检索数据行和列Insert --向数据库表添加新数据行Delete --从数据库表中删除数据行Update --更新数据库表中的数据--数据 ...

  7. set IDENTITY_INSERT on 和 off 的设置

    qlserver 批量插入记录时,对有标识列的字段要设置 set IDENTITY_INSERT 表名 on,然后再执行插入记录操作;插入完毕后恢复为 off 设置 格式:  set IDENTITY ...

  8. php中的单引号与双引号详解

    一.引号定义字符串 在Php中,通常一个字符串被定义在一对引号中,如: 'I am a string in single quotes'"I am a string in double qu ...

  9. django-suit的使用

    1.django-suit 是Django admin美化插件 django-suit官方文档 2.django-suit安装 #python pip install django-suit #pyt ...

  10. vue-cli中如何集成UEditor 富文本编辑器?

    1.根据后台语言下载对应的editor插件版本 地址:https://ueditor.baidu.com/website/download.html 2.将下载好的资源放在/static/uedito ...