ROS smach-----状态之间传递用户数据

2023-11-04 07:30

本文主要是介绍ROS smach-----状态之间传递用户数据,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 定义用户数据

    有时可能需要给某个状态提供一些输入数据,而且该状态也可能需要输出一些数据给其它状态使用。这些输入和输出数据可以称为userdata

class Foo(smach.State):def __init__(self, outcomes=['outcome1', 'outcome2'],input_keys=['foo_input'],output_keys=['foo_output'])def execute(self, userdata):# Do something with userdataif userdata.foo_input == 1:return 'outcome1'else:userdata.foo_output = 3return 'outcome2'

  • input_keys  列表是该状态需要输入的数据。execute方法使用 userdata结构拷贝。该状态可以读取列举的 在input_keys列表的所有userdata数据字段, 但是不能向这些字段写东西

  • output_keys列表是该状态所有输出数据。该状态可以写output_keys中列举的任何userdata字段。

user_data_single.png

状态接口可以被定义,通过 outcomes,  input keys和output keys。


2 连接用户数据

    当向状态机添加状态时候,你可以映射userdata字段。例如,如果状态FOO输出数据 'foo_output', 而同时状态BAR 需要输入'bar_input', 那么你可将通过名字讲userdata相关字段连接到一起:

sm_top = smach.StateMachine(outcomes=['outcome4','outcome5'],input_keys=['sm_input'],output_keys=['sm_output'])with sm_top:smach.StateMachine.add('FOO', Foo(),transitions={'outcome1':'BAR','outcome2':'outcome4'},remapping={'foo_input':'sm_input','foo_output':'sm_data'})smach.StateMachine.add('BAR', Bar(),transitions={'outcome2':'FOO'},remapping={'bar_input':'sm_data','bar_output1':'sm_output'})


字段remapping映射状态的in/output_key到状态机的userdata字段。因此,当映射 'x':'y'时候:

  • x 是状态的一个input_key 或者一个output_key  ;
  • y 自动成为了状态机的userdata的部分 ;
注意:如果状态和状态机中userdata名字相同,这种remapping其实是不需要的,但是为了让这种数据连接看起来更加清洗,我们还是建议使用remapping字段,即使像"remapping={'a':'a'}"。

2.1 状态之间传递数据

我们可以使用remapping机制从状态FOO向状态BAR传递数据,为此当向状态机添加这两种状态时需要使用如下remapping:

  • FOO: remapping={'foo_output':'sm_user_data'}
  • BAR: remapping={'bar_input':'sm_user_data'}

2.2 状态和状态机之间传递数据

从状态BAR向包含BAR的状态机传递数据

BAR: remapping={'bar_output':'sm_output'}

从状态机向包含状态FOO的状态传递数据

FOO: remapping={'foo_input':'sm_input'}



3 实例解析

 

#!/usr/bin/env pythonimport roslib; roslib.load_manifest('smach_tutorials')
import rospy
import smach
import smach_ros# define state Foo
class Foo(smach.State):def __init__(self):smach.State.__init__(self, outcomes=['outcome1','outcome2'],input_keys=['foo_counter_in'],output_keys=['foo_counter_out'])def execute(self, userdata):rospy.loginfo('Executing state FOO')if userdata.foo_counter_in < 3:userdata.foo_counter_out = userdata.foo_counter_in + 1return 'outcome1'else:return 'outcome2'# define state Bar
class Bar(smach.State):def __init__(self):smach.State.__init__(self, outcomes=['outcome1'],input_keys=['bar_counter_in'])def execute(self, userdata):rospy.loginfo('Executing state BAR')rospy.loginfo('Counter = %f'%userdata.bar_counter_in)        return 'outcome1'def main():rospy.init_node('smach_example_state_machine')# Create a SMACH state machinesm = smach.StateMachine(outcomes=['outcome4'])sm.userdata.sm_counter = 0# Open the containerwith sm:# Add states to the containersmach.StateMachine.add('FOO', Foo(), transitions={'outcome1':'BAR', 'outcome2':'outcome4'},remapping={'foo_counter_in':'sm_counter', 'foo_counter_out':'sm_counter'})smach.StateMachine.add('BAR', Bar(), transitions={'outcome1':'FOO'},remapping={'bar_counter_in':'sm_counter'})# Execute SMACH planoutcome = sm.execute()if __name__ == '__main__':main()
运行结果如下:


[INFO] [WallTime: 1478505239.574543] State machine starting in initial state 'FOO' with userdata: ['sm_counter']
[INFO] [WallTime: 1478505239.575218] Executing state FOO
[INFO] [WallTime: 1478505239.575714] State machine transitioning 'FOO':'outcome1'-->'BAR'
[INFO] [WallTime: 1478505239.576135] Executing state BAR
[INFO] [WallTime: 1478505239.576547] Counter = 1.000000
[INFO] [WallTime: 1478505239.576917] State machine transitioning 'BAR':'outcome1'-->'FOO'
[INFO] [WallTime: 1478505239.577303] Executing state FOO
[INFO] [WallTime: 1478505239.577718] State machine transitioning 'FOO':'outcome1'-->'BAR'
[INFO] [WallTime: 1478505239.578095] Executing state BAR
[INFO] [WallTime: 1478505239.578463] Counter = 2.000000
[INFO] [WallTime: 1478505239.578850] State machine transitioning 'BAR':'outcome1'-->'FOO'
[INFO] [WallTime: 1478505239.579229] Executing state FOO
[INFO] [WallTime: 1478505239.579621] State machine transitioning 'FOO':'outcome1'-->'BAR'
[INFO] [WallTime: 1478505239.580049] Executing state BAR
[INFO] [WallTime: 1478505239.580421] Counter = 3.000000
[INFO] [WallTime: 1478505239.580770] State machine transitioning 'BAR':'outcome1'-->'FOO'
[INFO] [WallTime: 1478505239.581125] Executing state FOO
[INFO] [WallTime: 1478505239.581510] State machine terminating 'FOO':'outcome2':'outcome4'



这篇关于ROS smach-----状态之间传递用户数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

hdu1565(状态压缩)

本人第一道ac的状态压缩dp,这题的数据非常水,很容易过 题意:在n*n的矩阵中选数字使得不存在任意两个数字相邻,求最大值 解题思路: 一、因为在1<<20中有很多状态是无效的,所以第一步是选择有效状态,存到cnt[]数组中 二、dp[i][j]表示到第i行的状态cnt[j]所能得到的最大值,状态转移方程dp[i][j] = max(dp[i][j],dp[i-1][k]) ,其中k满足c

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca