ROS Smach-----状态创建和添加

2023-11-04 07:30
文章标签 创建 状态 ros smach

本文主要是介绍ROS Smach-----状态创建和添加,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    Smach是状态机的意思,是基于python实现的一个功能强大且易于扩展的库。 smach本质上并不依赖于ROS,可以用于任意python项目,不过在ROS中功能包集executive_smach将smach和ROS很好的集成在了一起,该功能包集还集成了actionlib和smach_viewer(用于可视监控状态机变化,不过目前对于Kinetic版本还没有支持)。

   
本文主要叙述smach的 1)状态创建和2)如何把状态加入到状态机


1 状态创建

   1   class Foo(smach.State):2      def __init__(self, outcomes=['outcome1', 'outcome2']):3        # Your state initialization goes here4 5      def execute(self, userdata):6         # Your state execution goes here7         if xxxx:8             return 'outcome1'9         else:10             return 'outcome2'

  • init用于初始化状态class,必须确保该函数不会block执行。

  • execute 用于定义该状态下要完成的任务,它可以允许block执行,一旦你从该方法返回也意味着当前状态结束。

  • 当状态结束时候会返回outcome。每个状态都可能会有几种可能的outcomes。用户可以自定义 outcome来描述该状态完成的如何(如['succeeded', 'failed', 'awesome'),outcome也是一个状态切换到下一个状态 的依据。

2 添加状态到状态机

    状态机可以看作是一个容器,用于放置不同的状态。当把一个状态加入到状态机时候,我们需要指定状态转换规则。

  1   sm = smach.StateMachine(outcomes=['outcome4','outcome5'])2   with sm:3      smach.StateMachine.add('FOO', Foo(),4                             transitions={'outcome1':'BAR',5                                          'outcome2':'outcome4'})6      smach.StateMachine.add('BAR', Bar(),7                             transitions={'outcome2':'FOO'})

注意:状态机也可以看做状态,这意味着我们可以把一个状态机看做状态加入到另一个状态机。


3 实例代码

说明:以下代码来源于ROS WiKi。

#!/usr/bin/env pythonimport roslib; roslib.load_manifest('smach_tutorials')
import rospy
import smach
import smach_ros
<strong>
# define state Foo</strong>
class Foo(smach.State):def __init__(self):smach.State.__init__(self, outcomes=['outcome1','outcome2'])self.counter = 0def execute(self, userdata):rospy.loginfo('Executing state FOO')if self.counter < 3:self.counter += 1return 'outcome1'else:return 'outcome2'<strong># define state Bar</strong>
class Bar(smach.State):def __init__(self):smach.State.__init__(self, outcomes=['outcome2'])def execute(self, userdata):rospy.loginfo('Executing state BAR')return 'outcome2'<strong># main</strong>
def main():rospy.init_node('smach_example_state_machine')# Create a SMACH state machinesm = smach.StateMachine(outcomes=['outcome4', 'outcome5'])# Open the containerwith sm:# Add states to the containersmach.StateMachine.add('FOO', Foo(), transitions={'outcome1':'BAR', 'outcome2':'outcome4'})smach.StateMachine.add('BAR', Bar(), transitions={'outcome2':'FOO'})
<strong>#<span class="line"><span class="Comment">Create and start the introspection server</span></span><span style="font-family:Microsoft YaHei;">(For debugging interface by smach_viewer )</span></strong>
<span style="font-family:Microsoft YaHei;">         </span> sis = smach_ros.IntrospectionServer('sm_server', sm, '/SM_ROOT')sis.start()<strong># Execute SMACH plan</strong>outcome = sm.execute()
<pre dir="ltr" id="CA-06a92aec5f65b340e778bf2c2ce007b12b82e73a" lang="en"><span class="line"><span class="Comment">    <strong>#Wait for ctrl-c to stop the application</strong></span></span><pre name="code" class="python"><pre dir="ltr" id="CA-06a92aec5f65b340e778bf2c2ce007b12b82e73a" lang="en"><span class="line"><span class="Comment"></span></span><pre name="code" class="python"><strong><span style="font-family:Microsoft YaHei;">             #(For debugging interface by smach_viewer )</span></strong>

 
 
 
 
 
 
 rospy.spin() sis.stop()if __name__ == '__main__': main() 
 

输出信息:

[INFO] [WallTime: 1478497355.866746] State machine starting in initial state 'FOO' with userdata: []
[INFO] [WallTime: 1478497355.867673] Executing state FOO
[INFO] [WallTime: 1478497355.868092] State machine transitioning 'FOO':'outcome1'-->'BAR'
[INFO] [WallTime: 1478497355.868703] Executing state BAR
[INFO] [WallTime: 1478497355.869094] State machine transitioning 'BAR':'outcome2'-->'FOO'
[INFO] [WallTime: 1478497355.869660] Executing state FOO
[INFO] [WallTime: 1478497355.870035] State machine transitioning 'FOO':'outcome1'-->'BAR'
[INFO] [WallTime: 1478497355.870590] Executing state BAR
[INFO] [WallTime: 1478497355.871010] State machine transitioning 'BAR':'outcome2'-->'FOO'
[INFO] [WallTime: 1478497355.871513] Executing state FOO
[INFO] [WallTime: 1478497355.871843] State machine transitioning 'FOO':'outcome1'-->'BAR'
[INFO] [WallTime: 1478497355.872400] Executing state BAR
[INFO] [WallTime: 1478497355.872766] State machine transitioning 'BAR':'outcome2'-->'FOO'
[INFO] [WallTime: 1478497355.873100] Executing state FOO
[INFO] [WallTime: 1478497355.873282] State machine terminating 'FOO':'outcome2':'outcome4'


4 预定义的状态和状态机容器

上面代码是用户自定义状态和状态机容器,其实smach自身已经包含预定义的状态库和容器库,能够支持一些常见的状态和状态机。

4.1 状态库

  • SimpleActionState: automatically call actionlib actions.

  • ServiceState: automatically call ROS services

  • MonitorState

4.2容器库

  • StateMachine: the generic state machine container

  • Concurrence: a state machine that can run multiple states in parallel.

  • Sequence: a state machine that makes it easy to execute a set of states in sequence. The 'Smach Containers' section on the tutorials page gives an overview of all available containers.


如果ROS支持smach_viewer,你能输出图:






 

这篇关于ROS Smach-----状态创建和添加的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/344219

相关文章

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

Java中实现线程的创建和启动的方法

《Java中实现线程的创建和启动的方法》在Java中,实现线程的创建和启动是两个不同但紧密相关的概念,理解为什么要启动线程(调用start()方法)而非直接调用run()方法,是掌握多线程编程的关键,... 目录1. 线程的生命周期2. start() vs run() 的本质区别3. 为什么必须通过 st

Macos创建python虚拟环境的详细步骤教学

《Macos创建python虚拟环境的详细步骤教学》在macOS上创建Python虚拟环境主要通过Python内置的venv模块实现,也可使用第三方工具如virtualenv,下面小编来和大家简单聊聊... 目录一、使用 python 内置 venv 模块(推荐)二、使用 virtualenv(兼容旧版 P

IIS 7.0 及更高版本中的 FTP 状态代码

《IIS7.0及更高版本中的FTP状态代码》本文介绍IIS7.0中的FTP状态代码,方便大家在使用iis中发现ftp的问题... 简介尝试使用 FTP 访问运行 Internet Information Services (IIS) 7.0 或更高版本的服务器上的内容时,IIS 将返回指示响应状态的数字代

Linux lvm实例之如何创建一个专用于MySQL数据存储的LVM卷组

《Linuxlvm实例之如何创建一个专用于MySQL数据存储的LVM卷组》:本文主要介绍使用Linux创建一个专用于MySQL数据存储的LVM卷组的实例,具有很好的参考价值,希望对大家有所帮助,... 目录在Centos 7上创建卷China编程组并配置mysql数据目录1. 检查现有磁盘2. 创建物理卷3. 创

Java 如何创建和使用ExecutorService

《Java如何创建和使用ExecutorService》ExecutorService是Java中用来管理和执行多线程任务的一种高级工具,可以有效地管理线程的生命周期和任务的执行过程,特别是在需要处... 目录一、什么是ExecutorService?二、ExecutorService的核心功能三、如何创建

使用Python创建一个功能完整的Windows风格计算器程序

《使用Python创建一个功能完整的Windows风格计算器程序》:本文主要介绍如何使用Python和Tkinter创建一个功能完整的Windows风格计算器程序,包括基本运算、高级科学计算(如三... 目录python实现Windows系统计算器程序(含高级功能)1. 使用Tkinter实现基础计算器2.

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

使用Python和Pyecharts创建交互式地图

《使用Python和Pyecharts创建交互式地图》在数据可视化领域,创建交互式地图是一种强大的方式,可以使受众能够以引人入胜且信息丰富的方式探索地理数据,下面我们看看如何使用Python和Pyec... 目录简介Pyecharts 简介创建上海地图代码说明运行结果总结简介在数据可视化领域,创建交互式地