【ROS书籍】ROSByExampleⅡ——第三章 使用ROS任务执行 (三)

3.8.5 SMACH Iterators

  在patrol_smach.py脚本,我们在一个while循环将机器执行重复巡逻。现在,我们将展示如何使用SMACH迭代器(Iterator)容器实现相同的结果。新的脚本叫做patrol_smach_iterator.py,可以在rbx2_tasks/nodes目录中找到。因为patrol_smach.py脚本的大多数是一样的,我们只会突出差异。


  程序中的关键代码如下:

# Initialize the top level state machine
self.sm = StateMachine(outcomes=['succeeded','aborted','preempted'])
with self.sm:
  # Initialize the iterator
  self.sm_patrol_iterator = Iterator(outcomes = ['succeeded','preempted','aborted'],
                            input_keys = [],
                            it = lambda: range(0, self.n_patrols),
                            output_keys = [],
                            it_label = 'index',
                            exhausted_outcome = 'succeeded')

with self.sm_patrol_iterator:
  # Initialize the patrol state machine
  self.sm_patrol = StateMachine(outcomes =
  ['succeeded','aborted','preempted','continue'])

# Add the states to the state machine with the appropriate transitions
with self.sm_patrol:
  StateMachine.add('NAV_STATE_0', nav_states[0],
  transitions={'succeeded':'NAV_STATE_1','aborted':'NAV_STATE_1','preempted':'NAV_STATE_1'})
  StateMachine.add('NAV_STATE_1', nav_states[1],
  transitions={'succeeded':'NAV_STATE_2','aborted':'NAV_STATE_2','preempted':'NAV_STATE_2'})
  StateMachine.add('NAV_STATE_2', nav_states[2],
  transitions={'succeeded':'NAV_STATE_3','aborted':'NAV_STATE_3','preempted':'NAV_STATE_3'})
  StateMachine.add('NAV_STATE_3', nav_states[3],
  transitions={'succeeded':'NAV_STATE_4','aborted':'NAV_STATE_4','preempted':'NAV_STATE_4'})
  StateMachine.add('NAV_STATE_4', nav_states[0],
  transitions={'succeeded':'continue','aborted':'continue','preempted':'continue'})
  # Close the sm_patrol machine and add it to the iterator
  Iterator.set_contained_state('PATROL_STATE', self.sm_patrol,
                               loop_outcomes=['continue'])
# Close the top level state machine
StateMachine.add('PATROL_ITERATOR', self.sm_patrol_iterator, {'succeeded':'succeeded', 'aborted':'aborted'})

现在,让我们分块解释。

# Initialize the top level state machine
self.sm = StateMachine(outcomes=['succeeded','aborted','preempted'])
with self.sm:
  # Initialize the iterator
  self.sm_patrol_iterator = Iterator(outcomes = ['succeeded','preempted','aborted'],
                            input_keys = [],
                            it = lambda: range(0, self.n_patrols),
                            output_keys = [],
                            it_label = 'index',
                            exhausted_outcome = 'succeeded')

在顶部初始化状态机后,我们构建一个迭代器(Iterator)循环的self.n_patrols时间。迭代器(Iterator)的核心是it参数,该参数将设置迭代对象的列表。在我们的例子中,我们使用Python的lambda函数定义列表创建一个整数列表通过range(0,self.n_patrols)。it_label参数(在我们的例子中设置为“index”)保持当前关键值,因为它遍历列表。exhausted_outcome参数设置发出结果,当迭代器(Iterator)已经到了列表的最后。


with self.sm_patrol_iterator:
  # Initialize the patrol state machine
  self.sm_patrol = StateMachine(outcomes =
  ['succeeded','aborted','preempted','continue'])

# Add the states to the state machine with the appropriate transitions
with self.sm_patrol:
  StateMachine.add('NAV_STATE_0', nav_states[0],
  transitions={'succeeded':'NAV_STATE_1','aborted':'NAV_STATE_1','preempted':'NAV_STATE_1'})
  StateMachine.add('NAV_STATE_1', nav_states[1],
  transitions={'succeeded':'NAV_STATE_2','aborted':'NAV_STATE_2','preempted':'NAV_STATE_2'})
  StateMachine.add('NAV_STATE_2', nav_states[2],
  transitions={'succeeded':'NAV_STATE_3','aborted':'NAV_STATE_3','preempted':'NAV_STATE_3'})
  StateMachine.add('NAV_STATE_3', nav_states[3],
  transitions={'succeeded':'NAV_STATE_4','aborted':'NAV_STATE_4','preempted':'NAV_STATE_4'})
  StateMachine.add('NAV_STATE_4', nav_states[0],
  transitions={'succeeded':'continue','aborted':'continue','preempted':'continue'})


  接下来我们创建巡逻状态机,比较之前的两个差异。首先,在”with self.sm_patrol_iterator”中声明状态机是阻塞的。第二,我们已经在整体巡逻机和最终状态:NAV_STATE_4中添加了一个新的结果标记为“continue”。为什么我们这样做在下面最后一行会解释。


  # Close the sm_patrol machine and add it to the iterator
  Iterator.set_contained_state('PATROL_STATE', self.sm_patrol,
                               loop_outcomes=['continue'])
# Close the top level state machine
StateMachine.add('PATROL_ITERATOR', self.sm_patrol_iterator, {'succeeded':'succeeded', 'aborted':'aborted'})

  上面的第一行中增加了巡逻状态机的迭代器(Iterator)所包含的状态和loop_outcomes参数设置为“continue”。这意味着当包含的状态机发出“continue”的结果时,迭代器(Iterator)将移动到列表的下一个值。正如你从我们的巡逻状态机所看到的,NAV_STATE_4映射所有结果到“continue”,所以一旦我们完成NAV_STATE_4,迭代器(Iterator)将开始下一个循环。如果迭代器(Iterator)到达最后的列表,它将通过一个设定的exhausted_outcomes参数终止结果,所以我们构建迭代器(Iterator)时设置为“succeeded”。


  最后一行在整个状态机中添加迭代器(Iterator)作为一个状态。


  测试脚本,确保你有在前面的章节中的虚拟TurtleBot启动并运行,以及有nav_tasks.rviz配置文件的RViz,然后运行脚本迭代器(Iterator):

$ rosrun rbx2_tasks patrol_smach_iterator.py

结果应该与以前一样:机器人应该完成两个广场巡逻。


3.8.6 在一个转换中运行命令


  虚拟设我们想让机器人执行一个或多个函数每次从一个状态转换到下一个。例如,也许我们想要巡逻机器人扫描每个房间的人如果看到某人,说你好,然后继续。


  这种类型的执行回调函数可以通过使用转换。我们的演示脚本叫做patrol_smach_callback.py位于目录rbx2_tasks /节点。大多数的脚本patrol_smach是一样的.py脚本前面描述的我们只会突出的差异


  首先我们设置转换回调状态机如下:

self.sm_patrol.register_transition_cb(self.transition_cb, cb_args=[])

  register_transition_cb()函数接受两个参数:我们想要执行的回调函数,回调参数的列表,可以是一个空列表,这里我们使用。我们的回调函数,self.transition_cb()是这样的:

def transition_cb(self, userdata, active_states, *cb_args): 
  if self.rand.randint(0, 3) == 0:
    rospy.loginfo("Greetings human!")
    rospy.sleep(1) 
    rospy.loginfo("Is everything OK?")
    rospy.sleep(1) else:
    rospy.loginfo("Nobody here.")

  这里我们只是虚拟装检查一个人的存在通过随机选择一个数字0和3之间。如果是0,我们发出问候,否则,我们报告,没有人存在。当然,在真实的应用程序中,你可能包括代码扫描房间淘洗机器人的摄像头和使用语音说话人聊天,如果他们发现。


  测试脚本,确保你有虚拟TurtleBot启动并运行,在前面的章节以及RViz nav_tasks。rviz配置文件,然后运行脚本迭代器:

$ rosrun rbx2_tasks patrol_smach_callback.py

  不同于之前的脚本,这一个将与ctrl - c运行下去,直到你中止它

3.8.7 使用ROS话题和服务交互

  虚拟设我们希望监视机器人的电池水平,如果低于某一阈值,机器人应该暂停或中止这是做什么,导航到停靠站和充电,然后在它停止的地方继续前面的任务。首先,我们需要知道如何使用SMACH监控电池的水平。早些时候我们用虚拟电池模拟器介绍来说明这个过程。


  SMACH提供了预定义的状态MonitorState和ServiceState与ROS话题和服务在一个状态机。我们将使用一个MonitorState跟踪模拟电池水平和ServiceState模拟充电。之前将电池检查集成到我们的巡逻机器人状态机,让我们看一个简单的状态机,监控电池水平,然后发出一个充电服务调用时水平低于阈值。


  被称为monitor_fake_battery演示脚本.py脚本rbx2_tasks /节点目录和看起来像下面的

连接到源代码:monitor_fake_battery.py

001  #!/usr/bin/env python
002  
003  import rospy
004  from smach import State, StateMachine
005  from smach_ros import MonitorState, ServiceState, IntrospectionServer
006  from rbx2_msgs.srv import *
007  from std_msgs.msg import Float32
008  
009  class main():
010      def __init__(self):
011          rospy.init_node('monitor_fake_battery', anonymous=False)
012          
013          rospy.on_shutdown(self.shutdown)
014          
015          # Set the low battery threshold (between 0 and 100)
016          self.low_battery_threshold = rospy.get_param('~low_battery_threshold', 50)
017   
018          # Initialize the state machine
019          sm_battery_monitor = StateMachine(outcomes=[])
020  
021          with sm_battery_monitor:
022              # Add a MonitorState to subscribe to the battery level topic
023              StateMachine.add('MONITOR_BATTERY',
024                   MonitorState('battery_level', Float32, self.battery_cb), 
025                   transitions={'invalid':'RECHARGE_BATTERY',
026                                'valid':'MONITOR_BATTERY',
027                                'preempted':'MONITOR_BATTERY'},)
028  
029              # Add a ServiceState to simulate a recharge using the set_battery_level service
030              StateMachine.add('RECHARGE_BATTERY',
031                   ServiceState('battery_simulator/set_battery_level', SetBatteryLevel, request=100), 
032                   transitions={'succeeded':'MONITOR_BATTERY',
033                                'aborted':'MONITOR_BATTERY',
034                                'preempted':'MONITOR_BATTERY'})
035              
036          # Create and start the SMACH introspection server
037          intro_server = IntrospectionServer('monitor_battery', sm_battery_monitor, '/SM_ROOT')
038          intro_server.start()
039          
040          # Execute the state machine
041          sm_outcome = sm_battery_monitor.execute()
042                          
043          intro_server.stop()
044          
045      def battery_cb(self, userdata, msg):
046          rospy.loginfo("Battery Level: " + str(msg))
047          if msg.data < self.low_battery_threshold:
048              return False
049          else:
050              return True
051  
052      def shutdown(self):
053          rospy.loginfo("Stopping the battery monitor...")
054          rospy.sleep(1)
055  
056  if __name__ == '__main__':
057      try:
058          main()
059      except rospy.ROSInterruptException:
060        rospy.loginfo("Battery monitor finished.")

让我们分块解释代码。

004  from smach import State, StateMachine
005  from smach_ros import MonitorState, ServiceState, IntrospectionServer
006  from rbx2_msgs.srv import *
007  from std_msgs.msg import Float32

  除了通常的状态和StateMachine对象,我们也从smach_ros导入MonitorState和ServiceState。由于服务,我们将连接rbx2_msgs包中的(set_battery_level),将导入所有服务定义。最后,由于电池水平使用Float32消息类型发布,我们还需从ROS的std_msgs包导入这个类型。

016          self.low_battery_threshold = rospy.get_param('~low_battery_threshold', 50)

low_battery_threshold作为一个参数从ROS服务器中读取,默认虚拟设为50以下,100是完全充电。

019          sm_battery_monitor = StateMachine(outcomes=[])

我们创建一个名为sm_battery_monitor的顶级状态机并将其分配给一个空的结果,因为它不会自己产生结果。

021          with sm_battery_monitor:
022              # Add a MonitorState to subscribe to the battery level topic
023              StateMachine.add('MONITOR_BATTERY',
024                   MonitorState('battery_level', Float32, self.battery_cb), 
025                   transitions={'invalid':'RECHARGE_BATTERY',
026                                'valid':'MONITOR_BATTERY',
027                                'preempted':'MONITOR_BATTERY'},)

  我们增加状态机的第一个状态称为MONITOR_BATTERY,它使用SMACH MonitorState监视电池水平。MonitorState构造函数的参数是这个我们想监控的话题,该话题的消息类型和一个回调函数(这里称为self.battery_cb)描述如下。字典转换的关键名称来自预定义的结果,对于MonitorState类型是avalid、invalid和preempted,虽然avalid和invalid的结果实际上分别代表值True和False。在我们的例子中,我们的回调函数将使用invalid结果,这意味着电池水平低于阈值,所以我们映射这个键到一个转换到RECHARGE_BATTERY状态,如以下描述。

030              StateMachine.add('RECHARGE_BATTERY',
031                   ServiceState('battery_simulator/set_battery_level', SetBatteryLevel, request=100), 
032                   transitions={'succeeded':'MONITOR_BATTERY',
033                                'aborted':'MONITOR_BATTERY',
034                                'preempted':'MONITOR_BATTERY'})

  我们添加到状态机的第二个状态是RECHARGE_BATTERY状态,该状态使用SMACH ServiceState。ServiceState构造函数的参数是服务名称、服务类型和发送到服务请求的值。SetBatteryLevel服务类型在rbx2_msgs包中设置,这就是为什么我们在脚本的顶部导入rbx2_msgs.srv。设置请求值为100基本上是模拟电池的充电过程。ServiceState返回传统的成功(succeed)、崩溃(aborted)和抢占(preempted)结果。我们将所有的结果映射回MONITOR_BATTERY状态。


  脚本的最后一部分需要解释MonitorState的回调函数:


045      def battery_cb(self, userdata, msg):
046          rospy.loginfo("Battery Level: " + str(msg))
047          if msg.data < self.low_battery_threshold:
048              return False
049          else:
050              return True

  分配的任何回调函数给MonitorState状态会自动接收发布的消息到订阅的话题,和该状态的userdata。在这个回调,我们只会使用话题的类型(传入的msg参数),而不是userdata参数。


  回想一下我们监测的消息是简单Float32数字,该数字代表的是模拟电池水平。上面的第一行battery_cb功能只显示到屏幕上。然后我们在脚本早些时候测试水平low_battery_threshold。如果当前水平低于low_battery_threshold,我们返回False,相当于到MonitorState时invalid。否则,我们返回True和valid的结果是一样的。正如我们前面看到的,当MONITOR_BATTERY状态通过回调函数生成一个invalid结果,它转换到RECHARGE_BATTERY状态。


  既然我们了解脚本的功能,让我们试试。首先确保虚拟电池运行。如果你运行之前小节中的fake_turtlebot.launch,本小节还运行。否则,你可以启动自己的虚拟电池:

$ roslaunch rbx2_utils battery_simulator.launch

然后启动monitor_fake_battery.py脚本:

$ rosrun rbx2_tasks monitor_fake_battery.py

你应该会看到一系列的消息类似如下:

[INFO] [WallTime:1379002809.494314] State machine starting in initial state
'MONITOR_BATTERY' with userdata:[]
[INFO] [WallTime: 1379002812.213581] Battery Level: data: 70.0
[INFO] [WallTime: 1379002813.213005] Battery Level: data: 66.6666641235
[INFO] [WallTime: 1379002814.213802] Battery Level: data: 63.3333320618
[INFO] [WallTime: 1379002815.213758] Battery Level: data: 60.0
[INFO] [WallTime: 1379002816.213793] Battery Level: data: 56.6666679382
[INFO] [WallTime: 1379002817.213799] Battery Level: data: 53.3333320618
[INFO] [WallTime: 1379002818.213819] Battery Level: data: 50.0
[INFO] [WallTime: 1379002819.213816] Battery Level: data: 46.6666679382
[INFO] [WallTime: 1379002819.219875] State machine transitioning
'MONITOR_BATTERY':'invalid'-->'RECHARGE_BATTERY'
[INFO] [WallTime: 1379002819.229251] State machine transitioning
'RECHARGE_BATTERY':'succeeded'-->'MONITOR_BATTERY'
[INFO] [WallTime: 1379002820.213889] Battery Level: data: 100.0
[INFO] [WallTime: 1379002821.213805] Battery Level: data: 96.6666641235
[INFO] [WallTime: 1379002822.213807] Battery Level: data: 93.3333358765 etc


  上面的第一个INFO消息表明MONITOR_STATE初始化状态机的状态。接下来的一系列行显示了一个倒计时的电池水平,这是我们在battery_cb函数描述rospy.loginfo()语句的结果。水平低于阈值时,我们看到了MONITOR_STATE返回一个invalid的结果,该结果触发状态转换到RECHARGE_BATTERY状态。回顾到RECHARGE_STATE状态来调用set_battery_level服务并设置电池回到100满水平。然后返回一个成功(succeed)的结果并触发状态转换回到MONITOR_STATE。这个过程会继续下去。


3.8.8 回调函数(Callbacks)和自省(Introspection)


  SMACH的优点之一是能够在任何给定的时间确定机器的状态和设置回调状态转换或终止。例如,如果一个给定的状态机被抢占(preempted),我们想知道在被中断前过去的状态。在下一节我们将使用这个特性来确定充电后继续回到路上巡逻。我们还可以使用自省(Introspection)来改善我们跟踪成功率:不是简单地保持记录到达中转地点次数,我们也可以记录路标ID。


  你可以从在线SMACH API找到所有可能的回调细节。我们将使用的回调通常是在一个给定的状态机向每个状态提供转换。回调函数本身设置使用register_transition_cb()方法在状态机对象上。例如,在我们的巡逻状态机上的patrol_smach.py脚本中注册一个转换回调,我们将使用的语法:

self.sm_patrol.register_transition_cb(self.patrol_transition_cb, cb_args=[])

  我们将定义函数self.patrol_transition_cb来在每个状态转换执行我们想要执行的任何代码:

def patrol_transition_cb(self, userdata, active_states, *cb_args):
  Do something awesome with userdata, active_states or cb_args

  在这里,我们看到一个转换回调总是访问userdata、active_states和任何传递的回调参数。特别是变量active_states保持状态机的当前状态,和下一节我们将使用这个来确定机器人位置当中断并充电。

3.8.9并行任务:将电池检查添加到日常巡逻


  现在,我们知道如何广场巡逻和检查电池,是时候把这两个在一起。我们想要一个低电池信号得到高优先级,这样机器人会停止巡逻并导航到充电桩。一旦充电完成,我们想机器人继续巡逻,巡逻位置为中断的最后一个路标。


  SMACH提供Concurrence容器用于一致的运行任务,当条件满足时,使一个任务抢占(preempted)其他任务。我们用Concurrence容器设立新的状态机来保持导航状态机和电池检查状态机。然后我们将设置容器,这样当电池电量低于阈值时,电池检查可以抢占(preempted)导航。


  在看代码之前,让我们试一试。从早先的章节中终止monitor_battery.py节点,如果仍在运行。(在杀死节点之前可能需要一段时间响应Ctrl-C。)


  如果fake_turtlebot.launch文件没有运行,现在运行。回想一下,这个文件还启动了虚拟电池模拟器并运行60秒电池:

$ roslaunch rbx2_tasks fake_turtlebot.launch
 

  如果你还没有运行,使用命令启动SMACH查看器:

$ rosrun smach_viewer smach_viewer.py

  启动有nav_task配置文件的RViz,如果尚未运行:

$ rosrun rviz rviz -d `rospack find rbx2_tasks`/nav_tasks.rviz

  最后,确保你可以在前台看到RViz窗口,然后运行patrol_smach_concurrence.py脚本:

$ rosrun rbx2_tasks patrol_smach_concurrence.py

  你应该看到机器人围绕广场移动两次,然后停止。当电池低于阈值(task_setup.py文件默认设置为50),机器人将中断其巡逻并到充电桩充电。一旦充电完成,它将继续到离开的地方巡逻。


  脚本运行时,你还可以查看SMACH查看器的状态机。图像看起来应该像下面这样:


  (如果你没有在SMACH查看器中看到这张图片,关闭它然后重新启动。)图像在屏幕上应该比在这里重现更清晰。较大的灰色框左边代表Concurrence容器包含导航状态机SM_NAV和电池监控状态机MONITOR_BATTERY订阅的电池话题。右边的这个绿色的小盒子代表RECHARGE状态机和包含NAV_DOCKING_STATION以及RECHARGE_BATTERY状态。两者之间的转换状态机可以看到更清晰的放大,如下图:


  灭弧箭头从左边的红色recharge结果到右边的绿色RECHARGE盒,显示从concurrence容器到RECHARGE状态机当concurrence提供“recharge”的结果。


  现在让我们来研究一下代码,使这项工作。以下是总结的步骤:

  • l  创建一个名为sm_nav的状态机,负责移动机器人从一个路标导航到下一个路标
  • l  创建一个名为sm_recharge的第二状态机,移动机器人到充电桩并执行充电
  • l  创建一个名为sm_patrol的第三状态机定义为一个concurrence容器对sm_nav状态机与MonitorState电池状态订阅主题,可以抢占sm_nav机而停止sm_recharge状态机
  • l  最后,创建一个名为sm_top的第四状态机,包括sm_patrolsm_recharge机器以及停止状态,允许我们一旦我们完成指定数量的循环终止整个巡逻。


  状态机的树形图看起来像这样:

  • sm_top
    • sm_patrol
      • monitor_battery
      • sm_nav
    • sm_recharge


  完整的脚本文件中可以在rbx2_tasks/nodes目录下找到patrol_smach_concurrence.py。


  链接到源码:patrol_smach_concurrence.py


当前大多数搞机器人开发的用户所装的ROS是indigo版本,而且是基于Ubuntu14.04的。如果你跑别的版本的rbx代码老出错,不用怀疑,就是代码版本问题!ros by example for indigo volume 1很多地方(包括CSDN)都可以下载,而volume 2则只此一家哦!下面是本书的目录: Contents Preface................................................................................................................vii Printed vs PDF Versions of the Book...............................................................ix 1. Scope of this Volume.......................................................................................1 2. Installing the ros-by-example Code...............................................................3 3. Task Execution using ROS.............................................................................7 3.1 A Fake Battery Simulator.....................................................................................8 3.2 A Common Setup for Running the Examples.....................................................10 3.3 A Brief Review of ROS Actions........................................................................11 3.4 A Patrol Bot Example.........................................................................................12 3.5 The Patrol Bot using a Standard Script...............................................................13 3.6 Problems with the Script Approach....................................................................16 3.7 SMACH or Behavior Trees?..............................................................................17 3.8 SMACH: Tasks as State Machines.....................................................................17 3.8.1 SMACH review.......................................................................................................18 3.8.2 Patrolling a square using SMACH..........................................................................19 3.8.3 Testing SMACH navigation in the ArbotiX simulator............................................23 3.8.4 Accessing results from a SimpleActionState...........................................................26 3.8.5 SMACH Iterators.....................................................................................................27 3.8.6 Executing commands on each transition.................................................................30 3.8.7 Interacting with ROS topics and services................................................................31 3.8.8 Callbacks and Introspection.....................................................................................36 3.8.9 Concurrent tasks: Adding the battery check to the patrol routine...........................36 3.8.10 Comments on the battery checking Patrol Bot......................................................44 3.8.11 Passing user data between states and state machines............................................44 3.8.12 Subtasks and hierarchical state machines..............................................................48 3.8.13 Adding the battery check to the house cleaning robot...........................................54 3.8.14 Drawbacks of state machines................................................................................54 3.9 Behavior Trees...................................................................................................55 3.9.1 Behavior Trees versus Hierarchical State Machines...............................................56 3.1.2 Key properties of behavior trees..............................................................................57 3.9.3 Building a behavior tree..........................................................................................58 3.9.4 Selectors and sequences...........................................................................................60 3.9.5 Customizing behaviors using decorators (meta-behaviors).....................................61 3.10 Programming with Behavior Trees and ROS....................................................63 3.10.1 Installing the pi_trees library.................................................................................63 3.10.2 Basic components of the pi_trees library..............................................................63 3.10.3 ROS-specific behavior tree classes........................................................................68 3.10.4 A Patrol Bot example using behavior trees..........................................................72 3.10.5 A housing cleaning robot using behavior trees.....................................................79 3.10.6 Parallel tasks..........................................................................................................85 3.10.7 Adding and removing tasks...................................................................................87 4. Creating a URDF Model for your Robot....................................................89 4.1 Start with the Base and Wheels..........................................................................90 4.1.1 The robot_state_publisher and joint_state_publisher nodes....................................91 4.1.2 The base URDF/Xacro file......................................................................................92 4.1.3 Alternatives to using the /base_footprint frame......................................................97 4.1.4 Adding the base to the robot model.........................................................................97 4.1.5 Viewing the robot's transform tree..........................................................................98 4.1.6 Using a mesh for the base........................................................................................99 4.2 Simplifying Your Meshes.................................................................................104 4.3 Adding a Torso.................................................................................................104 4.3.1 Modeling the torso.................................................................................................105 4.3.2 Attaching the torso to the base..............................................................................106 4.3.3 Using a mesh for the torso.....................................................................................107 4.3.4 Adding the mesh torso to the mesh base...............................................................108 4.4 Measure, Calculate and Tweak.........................................................................110 4.5 Adding a Camera..............................................................................................110 4.5.1 Placement of the camera........................................................................................111 4.5.2 Modeling the camera.............................................................................................112 4.5.3 Adding the camera to the torso and base...............................................................114 4.5.4 Viewing the transform tree with torso and camera................................................115 4.5.5 Using a mesh for the camera.................................................................................116 4.5.6 Using an Asus Xtion Pro instead of a Kinect........................................................118 4.6 Adding a Laser Scanner (or other Sensors)......................................................119 4.6.1 Modeling the laser scanner....................................................................................119 4.6.2 Attaching a laser scanner (or other sensor) to a mesh base...................................120 4.6.3 Configuring the laser node launch file..................................................................121 4.7 Adding a Pan and Tilt Head..............................................................................122 4.7.1 Using an Asus Xtion Pro instead of a Kinect........................................................124 4.7.2 Modeling the pan-and-tilt head..............................................................................124 4.7.3 Figuring out rotation axes......................................................................................127 4.7.4 A pan and tilt head using meshes on Pi Robot......................................................128 4.7.5 Using an Asus Xtion Pro mesh instead of a Kinect on Pi Robot...........................129 4.8 Adding One or Two Arms................................................................................129 4.8.1 Placement of the arm(s).........................................................................................130 4.8.2 Modeling the arm...................................................................................................130 4.8.3 Adding a gripper frame for planning.....................................................................133 4.8.4 Adding a second arm.............................................................................................134 4.8.5 Using meshes for the arm servos and brackets......................................................136 4.9 Adding a Telescoping Torso to the Box Robot.................................................138 4.10 Adding a Telescoping Torso to Pi Robot........................................................139 4.11 A Tabletop One-Arm Pi Robot.......................................................................140 4.12 Testing your Model with the ArbotiX Simulator............................................142 4.12.1 A fake Box Robot................................................................................................142 4.12.2 A fake Pi Robot...................................................................................................145 4.13 Creating your own Robot Description Package..............................................145 4.13.1 Using rosbuild......................................................................................................145 4.13.2 Using catkin.........................................................................................................146 4.13.3 Copying files from the rbx2_description package...............................................147 4.13.4 Creating a test launch file....................................................................................147 5. Controlling Dynamixel Servos: Take 2......................................................149 5.1 Installing the ArbotiX Packages.......................................................................149 5.2 Launching the ArbotiX Nodes..........................................................................150 5.3 The ArbotiX Configuration File.......................................................................154 5.4 Testing the ArbotiX Joint Controllers in Fake Mode........................................160 5.5 Testing the Arbotix Joint Controllers with Real Servos....................................162 5.6 Relaxing All Servos..........................................................................................165 5.7 Enabling or Disabling All Servos.....................................................................168 6. Robot Diagnostics........................................................................................169 6.1 The DiagnosticStatus Message.........................................................................170 6.2 The Analyzer Configuration File......................................................................171 6.3 Monitoring Dynamixel Servo Temperatures....................................................172 6.3.1 Monitoring the servos for a pan-and-tilt head.......................................................172 6.3.2 Viewing messages on the /diagnostics topic.........................................................175 6.3.3 Protecting servos by monitoring the /diagnostics topic.........................................177 6.4 Monitoring a Laptop Battery............................................................................181 6.5 Creating your Own Diagnostics Messages.......................................................182 6.6 Monitoring Other Hardware States...................................................................188 7. Dynamic Reconfigure..................................................................................191 7.1 Adding Dynamic Parameters to your own Nodes.............................................192 7.1.1 Creating the .cfg file..............................................................................................192 7.1.2 Making the .cfg file executable.............................................................................193 7.1.3 Configuring the CMakeLists.txt file......................................................................194 7.1.4 Building the package.............................................................................................194 7.2 Adding Dynamic Reconfigure Capability to the Battery Simulator Node........194 7.3 Adding Dynamic Reconfigure Client Support to a ROS Node.........................198 7.4 Dynamic Reconfigure from the Command Line...............................................201 8. Multiplexing Topics with mux & yocs.......................................................203 8.1 Configuring Launch Files to Use mux Topics..................................................204 8.2 Testing mux with the Fake TurtleBot...............................................................205 8.3 Switching Inputs using mux Services...............................................................206 8.4 A ROS Node to Prioritize mux Inputs..............................................................207 8.5 The YOCS Controller from Yujin Robot..........................................................210 8.5.1 Adding input sources.............................................................................................213 9. Head Tracking in 3D...................................................................................215 9.1 Tracking a Fictional 3D Target.........................................................................216 9.2 Tracking a Point on the Robot..........................................................................217 9.3 The 3D Head Tracking Node............................................................................220 9.3.1 Real or fake head tracking.....................................................................................220 9.1.2 Projecting the target onto the camera plane...........................................................221 9.4 Head Tracking with Real Servos......................................................................224 9.4.1 Real servos and fake target....................................................................................225 9.4.2 Real servos, real target...........................................................................................226 9.4.3 The nearest_cloud.py node and launch file...........................................................228 10. Detecting and Tracking AR Tags.............................................................233 10.1 Installing and Testing the ar_track_alvar Package..........................................234 10.1.1 Creating your own AR Tags................................................................................234 10.1.2 Generating and printing the AR tags...................................................................236 10.1.3 Launching the camera driver and ar_track_alvar node.......................................236 10.1.4 Testing marker detection.....................................................................................238 10.1.5 Understanding the /ar_pose_marker topic...........................................................238 10.1.6 Viewing the markers in RViz..............................................................................240 10.2 Accessing AR Tag Poses in your Programs....................................................240 10.2.1 The ar_tags_cog.py script....................................................................................240 10.2.2 Tracking the tags with a pan-and-tilt head..........................................................244 10.3 Tracking Multiple Tags using Marker Bundles..............................................245 10.4 Following an AR Tag with a Mobile Robot....................................................245 10.4.1 Running the AR follower script on a TurtleBot .................................................248 10.5 Exercise: Localization using AR Tags............................................................249 11. Arm Navigation using MoveIt!.................................................................251 11.1 Do I Need a Real Robot with a Real Arm?.....................................................252 11.2 Degrees of Freedom.......................................................................................252 11.3 Joint Types.....................................................................................................253 11.4 Joint Trajectories and the Joint Trajectory Action Controller.........................254 11.5 Forward and Inverse Arm Kinematics............................................................257 11.6 Numerical versus Analytic Inverse Kinematics..............................................258 11.7 The MoveIt! Architecture...............................................................................258 11.8 Installing MoveIt!...........................................................................................260 11.9 Creating a Static URDF Model for your Robot .............................................261 11.10 Running the MoveIt! Setup Assistant...........................................................262 11.10.1 Load the robot's URDF model...........................................................................263 11.2.2 Generate the collision matrix.............................................................................264 11.10.3 Add the base_odom virtual joint.......................................................................264 11.10.4 Adding the right arm planning group................................................................265 11.10.5 Adding the right gripper planning group...........................................................269 11.10.6 Defining robot poses..........................................................................................271 11.10.7 Defining end effectors.......................................................................................273 11.10.8 Defining passive joints......................................................................................273 11.10.9 Generating the configuration files.....................................................................273 11.11 Configuration Files Created by the MoveIt! Setup Assistant........................275 11.11.1 The SRDF file (robot_name.srdf)......................................................................275 11.11.2 The fake_controllers.yaml file...........................................................................276 11.11.3 The joint_limits.yaml file..................................................................................277 11.11.4 The kinematics.yaml file...................................................................................278 11.12 The move_group Node and Launch File.......................................................280 11.13 Testing MoveIt! in Demo Mode...................................................................280 11.13.1 Exploring additional features of the Motion Planning plugin...........................284 11.13.2 Re-running the Setup Assistant at a later time..................................................285 11.14 Testing MoveIt! from the Command Line....................................................286 11.15 Determining Joint Configurations and End Effector Poses...........................289 11.16 Using the ArbotiX Joint Trajectory Action Controllers................................292 11.16.1 Testing the ArbotiX joint trajectory action controllers in simulation...............292 11.16.2 Testing the ArbotiX joint trajectory controllers with real servos......................300 11.17 Configuring MoveIt! Joint Controllers.........................................................301 11.17.1 Creating the controllers.yaml file......................................................................302 11.17.2 Creating the controller manager launch file......................................................304 11.18 The MoveIt! API..........................................................................................305 11.19 Forward Kinematics: Planning in Joint Space..............................................306 11.20 Inverse Kinematics: Planning in Cartesian Space.........................................314 11.21 Pointing at or Reaching for a Visual Target..................................................322 11.22 Setting Constraints on Planned Trajectories.................................................324 11.22.1 Executing Cartesian Paths.................................................................................324 11.22.2 Setting other path constraints............................................................................330 11.23 Adjusting Trajectory Speed..........................................................................333 11.24 Adding Obstacles to the Planning Scene......................................................337 11.25 Attaching Objects and Tools to the Robot....................................................346 11.26 Pick and Place..............................................................................................348 11.27 Adding a Sensor Controller..........................................................................360 11.28 Running MoveIt! on a Real Arm..................................................................363 11.28.1 Creating your own launch files and scripts.......................................................364 11.28.2 Running the robot's launch files........................................................................364 11.2.3 Forward kinematics on a real arm.....................................................................365 11.28.4 Inverse kinematics on a real arm.......................................................................366 11.28.5 Cartesian paths on a real arm.............................................................................367 11.28.6 Pick-and-place on a real arm.............................................................................367 11.28.7 Pointing at or reaching for a visual target..........................................................367 11.29 Creating a Custom Fast IK Plugin................................................................368 12. Gazebo: Simulating Worlds and Robots.................................................375 12.1 Installing Gazebo............................................................................................376 12.2 Hardware Graphics Acceleration....................................................................377 12.3 Installing the ROS Gazebo Packages..............................................................378 12.4 Installing the Kobuki ROS Packages..............................................................379 12.5 Installing the UBR-1 Files..............................................................................379 12.6 Using the Gazebo GUI...................................................................................379 12.7 Missing Model Bug in Gazebo 1.9.................................................................381 12.8 Testing the Kobuki Robot in Gazebo..............................................................383 12.8.1 Accessing simulated sensor data.........................................................................385 12.8.2 Adding safety control to the Kobuki...................................................................389 12.8.3 Running the nav_square.py script from Volume 1..............................................391 12.9 Loading Other Worlds and Objects................................................................392 12.10 Testing the UBR-1 Robot in Gazebo............................................................393 12.10.1 UBR-1 joint trajectories.....................................................................................394 12.1.2 The UBR-1 and MoveIt!....................................................................................395 12.11 Real Pick-and-Place using the UBR-1 Perception Pipeline..........................397 12.11.1 Limitations of depth cameras............................................................................398 12.11.2 Running the demo..............................................................................................399 12.11.3 Understanding the real_pick_and_place.py script.............................................404 12.12 Running Gazebo Headless + RViz...............................................................407 13. Rosbridge: Building a Web GUI for your Robot...................................411 13.1 Installing the rosbridge Packages...................................................................411 13.2 Installing the mjpeg_sever Package................................................................412 13.3 Installing a Simple Web Server (mini-httpd)..................................................415 13.4 Starting mini-httpd, rosbridge and mjpeg_server............................................416 13.5 A Simple rosbridge HTML/Javascript GUI....................................................417 13.6 Testing the GUI with a Fake TurtleBot..........................................................420 13.7 Testing the GUI with a Real Robot.................................................................420 13.8 Viewing the Web GUI on another Device on your Network..........................421 13.9 Using the Browser Debug Console.................................................................421 13.10 Understanding the Simple GUI.....................................................................423 13.10.1 The HTML layout: simple_gui.html.................................................................423 13.1.2 The JavaScript code: simple_gui.js...................................................................428 13.11 A More Advanced GUI using jQuery, jqWidgets and KineticJS..................438 13.12 Rosbridge Summary.....................................................................................443 Appendix: Plug and Play USB Devices for ROS: Creating udev Rules......445 13.13 Adding yourself to the dialout Group...........................................................445 13.14 Determining the Serial Number of a Device.................................................446 13.15 UDEV Rules.................................................................................................447 13.16 Testing a UDEV Rule...................................................................................448 13.17 Using a UDEV Device Name in a ROS Configuration File..........................448
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值