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

2023-11-04 07:30

本文主要是介绍SMACH专题(二)----Concurrent状态机,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

1、简单例子

具体地,实现代码如下:

#!/usr/bin/env pythonimport roslib; roslib.load_manifest('smach_example')
import time
import rospy
import smach
import smach_ros# define state Foo
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')time.sleep(1)if self.counter < 5:self.counter += 1return 'outcome1'else:return 'outcome2'# define state Bar
class Bar(smach.State):def __init__(self):smach.State.__init__(self, outcomes=['outcome1'])def execute(self, userdata):time.sleep(1)rospy.loginfo('Executing state BAR')return 'outcome1'# define state Bas
class Bas(smach.State):def __init__(self):smach.State.__init__(self, outcomes=['outcome3'])def execute(self, userdata):rospy.loginfo('Executing state BAS')return 'outcome3'def main():rospy.init_node('smach_example_state_machine')# Create the top level SMACH state machinesm_top = smach.StateMachine(outcomes=['outcome6'])# Open the container
    with sm_top:smach.StateMachine.add('BAS', Bas(),transitions={'outcome3':'CON'})# Create the sub SMACH state machinesm_con = smach.Concurrence(outcomes=['outcome4','outcome5'],default_outcome='outcome4',outcome_map={'outcome5':{ 'FOO':'outcome2','BAR':'outcome1'}})# Open the container
        with sm_con:# Add states to the containersmach.Concurrence.add('FOO', Foo())smach.Concurrence.add('BAR', Bar())smach.StateMachine.add('CON', sm_con,transitions={'outcome4':'CON','outcome5':'outcome6'})# Create and start the introspection serversis = smach_ros.IntrospectionServer('server_name', sm_top, '/SM_ROOT')sis.start()# Execute SMACH planoutcome = sm_top.execute()rospy.spin()sis.stop()
if __name__ == '__main__':main()

 

2、复杂例子

  定义复杂的输出结果条件判断,需要实现两个回调函数,如下代码的156行child_term_cb,178行的out_cb两个回调函数,具体说明,请参考代码处的文字解释。

  实现代码如下:

  1 #!/usr/bin/env python
  2 
  3 import roslib;
  4 import time
  5 import rospy
  6 import smach
  7 import smach_ros
  8 from twisted.internet.defer import succeed
  9 
 10 
 11 # define state Bas
 12 class Bas(smach.State):
 13     def __init__(self):
 14         smach.State.__init__(self, outcomes=['succeeded'])
 15 
 16     def execute(self, userdata):
 17         time.sleep(4)
 18         rospy.loginfo('Executing state BAS')
 19         return 'succeeded'
 20     
 21 # define state Foo
 22 class Foo(smach.State):
 23     def __init__(self):
 24         smach.State.__init__(self, outcomes=['succeeded','preempted','aborted'])
 25         self.counter = 0
 26 
 27     def execute(self, userdata):
 28         rospy.loginfo('Executing state FOO')
 29         time.sleep(1)
 30         print "counter:%d"%(self.counter)
 31         if self.counter < 5:
 32             self.counter += 1
 33             time.sleep(3)
 34             return 'succeeded'
 35         else:
 36             return 'aborted'
 37 
 38 
 39 # define state Bar1
 40 class Bar1(smach.State):
 41     def __init__(self):
 42         smach.State.__init__(self, outcomes=['succeeded','preempted','aborted'])
 43         self.task_name = 'task_bar1'
 44     def execute(self, userdata):
 45         if self.preempt_requested():#如果暂停,则返回暂停状态
 46             rospy.loginfo("Preempting %s"%(self.task_name))
 47             self.recall_preempt()#唤醒,终止暂停
 48             return 'preempted'
 49         time.sleep(5)
 50         rospy.loginfo('Executing state BAR1')
 51         return 'succeeded'
 52     
 53 # define state Bar2
 54 class Bar2(smach.State):
 55     def __init__(self):
 56         smach.State.__init__(self, outcomes=['succeeded','preempted','aborted'])
 57         self.task_name ='bar2'
 58     def execute(self, userdata):
 59         if self.preempt_requested():#如果暂停,则返回暂停状态
 60             rospy.loginfo("Preempting %s"%(self.task_name))
 61             self.recall_preempt()#唤醒,终止暂停
 62             return 'preempted'
 63         time.sleep(5)
 64         rospy.loginfo('Executing state BAR2')
 65         return 'succeeded'
 66     
 67     
 68 # define state Bar3
 69 class Bar3(smach.State):
 70     def __init__(self):
 71         smach.State.__init__(self, outcomes=['succeeded','preempted','aborted'])
 72         self.task_name = 'task_bar3'
 73     def execute(self, userdata):
 74         if self.preempt_requested():#如果暂停,则返回暂停状态
 75             rospy.loginfo("Preempting %s"%(self.task_name))
 76             self.recall_preempt()#唤醒,终止暂停
 77             return 'preempted'
 78         time.sleep(5)
 79         rospy.loginfo('Executing state BAR3')
 80         return 'succeeded'
 81  
 82 # define state Charge
 83 class Charge(smach.State):
 84     def __init__(self):
 85         smach.State.__init__(self, outcomes=['succeeded'])
 86 
 87     def execute(self, userdata):
 88         time.sleep(5)
 89         rospy.loginfo('Executing state BAS')
 90         return 'succeeded'
 91 
 92 class ConcurrentExample:
 93     def __init__(self):
 94         rospy.init_node('smach_example_state_machine')
 95     
 96         self.last_bar_state = None
 97         # Create the top level SMACH state machine
 98         self.sm_top = smach.StateMachine(outcomes=['stop'])
 99         
100         # Open the container
101         with self.sm_top:
102     
103             smach.StateMachine.add('BAS', Bas(),
104                                    transitions={'succeeded':'CON'})
105     
106             # Create the sub SMACH state machine
107             self.sm_con = smach.Concurrence(outcomes=['succeeded','preempted','aborted'],
108                                        default_outcome='aborted',
109                                        #outcome_map = {'succeeded':{'FOO':'succeeded'},
110                                        #                 'aborted':{'FOO':'aborted'}},
111                                        child_termination_cb = self.child_term_cb,
112                                        outcome_cb = self.out_cb
113                                        )
114     
115             # Open the container
116             with self.sm_con:
117                 # Add states to the container
118                 smach.Concurrence.add('FOO', Foo())
119                 
120                 self.sm_bar = smach.StateMachine(outcomes=['succeeded','preempted','aborted'])
121                 with self.sm_bar:
122                     smach.StateMachine.add('BAR1',Bar1(),
123                                            transitions={'succeeded':'BAR2','preempted':'preempted'})
124                     smach.StateMachine.add('BAR2',Bar2(),
125                                            transitions={'succeeded':'BAR3','preempted':'preempted'})
126                     smach.StateMachine.add('BAR3',Bar3(),
127                                            transitions={'succeeded':'succeeded','preempted':'preempted'})
128                 self.sm_bar.register_transition_cb(self.bar_transition_cb, cb_args=[])
129                 smach.Concurrence.add('BAR', self.sm_bar)
130     
131             smach.StateMachine.add('CON', self.sm_con,
132                                    transitions={'succeeded':'stop',
133                                                 'aborted':'stop',
134                                                 'preempted':'CHARGE'})
135             
136             smach.StateMachine.add('CHARGE', Charge(),
137                                    transitions={'succeeded':'CON'})
138             
139          # Create and start the introspection server
140         sis = smach_ros.IntrospectionServer('server_name', self.sm_top, '/SM_ROOT')
141         sis.start()
142     
143         # Execute SMACH plan
144         outcome = self.sm_top.execute()
145         rospy.spin()
146         sis.stop()
147     
148     #状态之间转换的时候会调用该函数。比如BAR1转换到BAR2(或者BAR2转换到BAR3)后,执行该回调函数,
149     #那么活动的状态 active_states 是‘BAR2‘(‘BAR3‘)
150     def bar_transition_cb(self, userdata, active_states, *cb_args):    
151         print active_states # 注意这里是字符串,活动状态的标识符例如‘BAR’
152         self.last_bar_state = active_states
153         
154     # gets called when ANY child state terminates,
155     # 只要Concurent下的其中一个状态完成,都会出发该回调函数
156     def child_term_cb(self, outcome_map):
157       
158       # terminate all running states if FOO preempted with outcome 'succeeded'
159       if outcome_map['FOO'] == 'succeeded':
160         print "child_term_cv:FOO finished"
161         if self.last_bar_state is not None:
162             
163             self.sm_bar.set_initial_state(self.last_bar_state, smach.UserData())     
164         return True
165           
166       # terminate all running states if BAR preempted
167       if outcome_map['BAR']=='succeeded' or outcome_map['BAR']=='preempted':
168         print "child_term_cv:SM_BAR finished"
169         
170         return True
171     
172       # in all other case, just keep running, don't terminate anything
173       return False
174     
175     
176     # gets called when ALL child states are terminated,只要Concurrent下的状态都结束了,
177     #调用该函数.注意不是BAR下面的BAR1,BAR2,BAR3的之一完成
178     def out_cb(self, outcome_map):
179        if outcome_map['FOO'] == 'aborted':
180           print "out_cb FOO aborted"
181           return 'aborted'
182        elif outcome_map['BAR'] == 'preempted':
183           
184           print "out_cb BAR preempted"
185           return 'preempted'
186        elif outcome_map['BAR'] == 'succeeded':
187            print "out_cb_BAR succeeded"
188            return 'succeeded'
189 if __name__ == '__main__':
190     ConcurrentExample()

 

  状态机器效果图,CON下的FOO和BAR同时执行,如下所示:

    CON进入暂停状态,切换到CHARGE状态下执行(绿色表示执行):

参考资料:

[1]. http://wiki.ros.org/smach/Tutorials/Concurrent%20States

[2]. ros_by_example_vol2_indigo.pdf

 

问题:只要BAR或FOO之一结束,就输出相应打结果,这个如何做到?还没找到方法

转载于:https://www.cnblogs.com/cv-pr/p/5165004.html

这篇关于SMACH专题(二)----Concurrent状态机的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

专题二_滑动窗口_算法专题详细总结

目录 滑动窗口,引入: 滑动窗口,本质:就是同向双指针; 1.⻓度最⼩的⼦数组(medium) 1.解析:给我们一个数组nums,要我们找出最小子数组的和==target,首先想到的就是暴力解法 1)暴力: 2)优化,滑动窗口: 1.进窗口 2.出窗口 3.更新值 2.⽆重复字符的最⻓⼦串(medium) 1)仍然是暴力解法: 2)优化: 进窗口:hash[s[rig

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis

数字电路专题:verilog 阻塞赋值和非阻塞赋值

verilog 阻塞赋值 和 非阻塞赋值 “=”阻塞赋值, ”<=”非阻塞赋值。阻塞赋值为执行完一条赋值语句,再执行下一条,可理解为顺序执行,而且赋值是立即执行; 非阻塞赋值可理解为并行执行,不考虑顺序,在 always 块语句执行完成后,才进行赋值。 如下面的阻塞赋值: //代码如下:module top(din,a,b,c,clk);input din;input clk;out

算法专题一: 双指针

目录 前言1. 移动零(easy)2. 复写零(easy)3. 快乐数(medium)4. 盛水最多的容器(medium)5. 有效三角形的个数(medium)6. 和为 s 的两个数字(easy)7. 三数之和(medium)8. 四数之和(medium) 前言 常见的双指针有两种形式,一种是对撞指针,一种是左右指针。 1. 对撞指针: ⼀般用于顺序结构中,也称左右指针。

Python 中考虑 concurrent.futures 实现真正的并行计算

Python 中考虑 concurrent.futures 实现真正的并行计算 思考,如何将代码所要执行的计算任务划分成多个独立的部分并在各自的核心上面平行地运行。 Python 的全局解释器锁(global interpreter lock,GIL)导致没办法用线程来实现真正的并行​,所以先把这种方案排除掉。另一种常见的方案,是把那些对性能要求比较高的(performance-critica

《黑神话:悟空》专题合集MOD/修改器/壁纸/音乐/CG剧情

《黑神话:悟空》专题合集」 链接:https://pan.quark.cn/s/d67857f4e308 包含内容: 《黑神话:悟空》MOD合集 《黑神话:悟空》修改器(风灵月影) 《黑神话:悟空》壁纸合集 《黑神话:悟空》3小时CG完整剧情合集 4K120帧最高画质!国语 简中字幕 附:4K 结尾动画合集 ​​​国语 简中字幕 《黑神话:悟空》主题曲 《黑神话

2014暑假集训搜索专题

A - 漫步校园 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Description LL最近沉迷于AC不能自拔,每天寝室、机房两点一线。由于长时间坐在电脑边,缺乏运动。他决定充分利用每次从寝室到机房的时间,在校园里散散步。整个HDU校园呈方形布局,可划

2014级寒假特训之并查集专题

Problem A: Double和XXZ的生日宴请 Time Limit: 1 Sec   Memory Limit: 128 MB Submit: 9   Solved: 7 [ Submit][ Status][ Web Board] [ Edit] [ TestData] Description Double 和 XXZ同一天生日,他们俩30岁生日那天,当年