(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

用actionlib封装容器

Description: 本教程介绍如何通过actionlib使用SMACH作为行为分发任务。

Tutorial Level: INTERMEDIATE

封装SMACH状态

SMACH提供了一个名为ActionServerWrapper的顶级容器。这个类发布一个actionlib行为服务器。当行为服务器接收到一个目标时,它所包含的状态将被激活,而不是由父进程执行。因此,这个容器不会从smach继承。状态基类,不能放入另一个容器内。

行为服务器封装器可以通过行为服务器接收到的目标消息注入到所包含的状态中,并在它终止时从该状态提取结果消息。在构造行为服务器封装器时,用户指定哪个状态机结果对应于成功、中止或抢占的结果。

考虑这个例子,它将一个SMACH状态机封装成一个行为:

   1 import rospy
   2 
   3 from smach import StateMachine
   4 from smach_ros import ActionServerWrapper
   5 
   6 # Construct state machine
   7 sm = StateMachine(outcomes=['did_something',
   8                             'did_something_else',
   9                             'aborted',
  10                             'preempted'])
  11 with sm:
  12     ### Add states in here...
  13 
  14 # Construct action server wrapper
  15 asw = ActionServerWrapper(
  16     'my_action_server_name', MyAction,
  17     wrapped_container = sm,
  18     succeeded_outcomes = ['did_something','did_something_else'],
  19     aborted_outcomes = ['aborted'],
  20     preempted_outcomes = ['preempted'] )
  21 
  22 # Run the server in a background thread
  23 asw.run_server()
  24 
  25 # Wait for control-c
  26 rospy.spin()

从包含的状态的输入/输出中得到目标/结果消息

上面的代码将调用sm.execute(),但是它不会将目标加载到包含的状态机中,也不会提取结果。为了完成这些任务,你需要告诉行为服务器封装器在SMACH的上下文中应该调用目标和结果消息。你可以用以下方法替换行为服务器包装器构造调用:

   1 # Construct action server wrapper
   2 asw = ActionServerWrapper(
   3     'my_action_server_name', MyAction, sm,
   4     ['did_something','did_something_else'], ['aborted'], ['preempted'],
   5     goal_key = 'my_awesome_goal',
   6     result_key = 'egad_its_a_result' )

关键字参数goal_keyresult_keyActionServerWrapper上下文中的SMACH用户数据键。与任何其他容器一样,这意味着封装器的包含状态(在这种情况下,状态机sm)将在调用其execute()方法时接收到这个userdata结构的引用。类似地,在嵌套状态机中的作用域之间如何传递userdata,在这种情况下,你也需要在状态机sm中设置这些关键标识符。

为了在密钥中复制父类,你可以用这个替换状态机sm的构造调用:

   1 # Construct state machine
   2 sm = StateMachine(
   3         outcomes=['did_something','did_something_else','aborted','preempted'],
   4         input_keys = ['my_awesome_goal'],
   5         output_keys = ['egad_its_a_result'])

完成此操作后,可以从添加到sm的任何状态访问这些密钥。关于跟多目标/结果策略,看到ActionServerWrapper API 文档.

Wiki: cn/smach/Tutorials/Wrapping a SMACH Container With actionlib (last edited 2018-03-10 07:22:00 by Playfish)