## For instruction on writing tutorials ## http://www.ros.org/wiki/WritingTutorials #################################### ##FILL ME IN #################################### ## for a custom note with links: ## note = ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0= ## descriptive title for the tutorial ## title = SimpleActionState (ROS) ## multi-line description to be displayed in search ## description = 本教程展示如何使用!SimpleActionState直接调用SMACH的行为接口。 ## the next tutorial description (optional) ## next = ## links to next tutorial (optional) ## next.0.link= [[cn/smach/Tutorials/ServiceState|ServiceState]] ## next.1.link= ## what level user is this tutorial for ## level= BeginnerCategory ## keywords = #################################### <> <> ##actionstart {{{#!python from smach_ros import SimpleActionState }}} 你可以简单地从[[cn/smach/Tutorials/Generic State|通用状态]]调用任何Action,但是smach有特定的支持来调用Action,为你节省了大量代码,!SMACH提供了一个作为[[cn/actionlib|actionlib]]操作代理的状态类。状态的实例化采用主题名称(topic name)、动作类型(action type)和生成目标(goal)的一些策略。简单动作状态的可能结果是'成功(succeeded)', '抢占(preempted)' 和 '中止(aborted)'。 取决于你的目标,SimpleActionState的实现可以很简单,也可以很复杂 == 目标消息 == === 空目标消息 === 这是一种少见的情况,它将调用一个action服务器,而不需要填写目标信息。 {{{ #!python sm = StateMachine(['succeeded','aborted','preempted']) with sm: smach.StateMachine.add('TRIGGER_GRIPPER', SimpleActionState('action_server_namespace', GripperAction), transitions={'succeeded':'APPROACH_PLUG'}) }}} === 固定的目标信息 === 稍微高级一点的用法是,你指定一个硬编码的固定目标,它将被传递给行为服务器: {{{ #!python sm = StateMachine(['succeeded','aborted','preempted']) with sm: gripper_goal = Pr2GripperCommandGoal() gripper_goal.command.position = 0.07 gripper_goal.command.max_effort = 99999 StateMachine.add('TRIGGER_GRIPPER', SimpleActionState('action_server_namespace', GripperAction, goal=gripper_goal), transitions={'succeeded':'APPROACH_PLUG'}) }}} === 从用户数据获取目标=== 假设你在用户数据中有许多字段,这些字段已经包含了你的目标消息所需的所有结构。然后,你可以将用户数据直接连接到目标消息中的字段。因此,从上面的例子中我们了解到,抓取动作的目标有两个字段:max_effort和position。假设我们的用户数据包含了相应的字段user_data_max和user_data_position。下面的代码连接相应的字段。 {{{ #!python sm = StateMachine(['succeeded','aborted','preempted']) with sm: StateMachine.add('TRIGGER_GRIPPER', SimpleActionState('action_server_namespace', GripperAction, goal_slots=['max_effort', 'position']), transitions={'succeeded':'APPROACH_PLUG'}, remapping={'max_effort':'user_data_max', 'position':'user_data_position'}) }}} 同样的方法也适用于'result_slots':操作的结果字段可以自动地写入到你的用户数据中。还要注意,在'goal_slots'和'result_slots'中指定的所有字段都自动放入'input_keys'和'output_keys'。 === 目标回调 === 这是权力最大的版本:当Action需要一个Goal时,你可以得到一个回调,你可以根据需要,在回调函数中创建自己的目标消息(goal)。 {{{ #!python sm = StateMachine(['succeeded','aborted','preempted']) with sm: def gripper_goal_cb(userdata, goal): gripper_goal = GripperGoal() gripper_goal.position.x = 2.0 gripper_goal.max_effort = userdata.gripper_input return gripper_goal StateMachine.add('TRIGGER_GRIPPER', SimpleActionState('action_server_namespace', GripperAction, goal_cb=gripper_goal_cb, input_keys=['gripper_input']) transitions={'succeeded':'APPROACH_PLUG'}, remapping={'gripper_input':'userdata_input'}) }}} 在你的目标回调中,你可以使用userdata,只要你在构造函数中列出input_keys即可。回调的一个参数是默认目标。如果你在构造函数中指定了'goal=...',该对象将被传递到回调函数中。 对于更多高级回调使用方法查看 `@smach.cb_interface` [[http://docs.ros.org/jade/api/smach/html/python/smach.util.CBInterface-class.html|(ROS Jade的API)]]。 == 结果消息 == === 结果到userdata === 你可以将操作的结果直接写入你的状态的userdata。 {{{ #!python sm = StateMachine(['succeeded','aborted','preempted']) with sm: StateMachine.add('TRIGGER_GRIPPER', SimpleActionState('action_server_namespace', GripperAction, result_slots=['max_effort', 'position']), transitions={'succeeded':'APPROACH_PLUG'}, remapping={'max_effort':'user_data_max', 'position':'user_data_position'}) }}} === 结果回调 === 结果回调与目标回调非常类似。它允许你从操作结果字段中读取任何数据,甚至返回一个不同的结果,而不是默认的'成功(succeeded)', '抢占(preempted)', '中止(aborted)'。 {{{ #!python sm = StateMachine(['succeeded','aborted','preempted']) with sm: def gripper_result_cb(userdata, status, result): if status == GoalStatus.SUCCEEDED: userdata.gripper_output = result.num_iterations return 'my_outcome' StateMachine.add('TRIGGER_GRIPPER', SimpleActionState('action_server_namespace', GripperAction, result_cb=gripper_result_cb, output_keys=['gripper_output']) transitions={'succeeded':'APPROACH_PLUG'}, remapping={'gripper_output':'userdata_output'}) }}} 在结果回调中,你获得了动作的状态,它告诉你动作是否成功,中止或被抢占。此外,还可以访问用户数据,以及操作的结果。 可选地,你可以从结果回调中返回一个不同的结果。如果你不返回任何东西,状态将返回相应的操作结果。 对于更多高级回调使用方法, 查看[[http://www.ros.org/doc/api/smach/html/python/smach.util.CBInterface-class.html|@smach.cb_interface]]。 ##actionend ## AUTOGENERATED DO NOT DELETE ## TutorialCategory ## FILL IN THE STACK TUTORIAL CATEGORY HERE ## SMACHStatesCategory, SMACHROSStatesCategory