当前位置:   article > 正文

ROS 2边学边练(48)-- 将URDF与robot_state_publisher一起使用_robotstatepublisher

robotstatepublisher

前言

        本篇将完成一个行走的机器人,并以tf2消息的方式实时发布机器人状态,以便我们在Rviz中同步查看。

        首先,我们创建描述机器人装配的URDF模型。接下来,我们编写一个节点,用于模拟运动并发布JointState和位姿变换。然后,我们使用robot_state_publisher将整个robot状态发布到/tf2。

动动手

创建新包

        执行如下命令创建新的工作空间second_ros2_ws,并在其下创建src文件夹:

$mkdir -p second_ros2_ws/src

        再在src下创建urdf_tutorial_r2d2包:

  1. $cd second_ros2_ws/src
  2. $ros2 pkg create --build-type ament_python --license Apache-2.0 urdf_tutorial_r2d2 --dependencies rclpy
  3. $cd urdf_tutorial_r2d2

创建URDF文件

        在urdf_tutorial_r2d2包根路径下,创建urdf文件夹,以放置保存一些组件:

$mkdir -p urdf

        分别下载URDF文件(r2d2.urdf.xml)和Rviz配置文件(r2d2.rviz)到second_ros2_ws/src/urdf_tutorial_r2d2/urdf/路径下。

发布状态

        现在我们需要一种方法来指定机器人的状态。要做到这一点,我们必须指定所有三个关节和整体里程计。

        创建second_ros2_ws/src/urdf_tutorial_r2d2/urdf_tutorial_r2d2/state_publisher.py文件,将下述内容复制其中:

  1. from math import sin, cos, pi
  2. import rclpy
  3. from rclpy.node import Node
  4. from rclpy.qos import QoSProfile
  5. from geometry_msgs.msg import Quaternion
  6. from sensor_msgs.msg import JointState
  7. from tf2_ros import TransformBroadcaster, TransformStamped
  8. class StatePublisher(Node):
  9. def __init__(self):
  10. rclpy.init()
  11. super().__init__('state_publisher')
  12. qos_profile = QoSProfile(depth=10)
  13. self.joint_pub = self.create_publisher(JointState, 'joint_states', qos_profile)
  14. self.broadcaster = TransformBroadcaster(self, qos=qos_profile)
  15. self.nodeName = self.get_name()
  16. self.get_logger().info("{0} started".format(self.nodeName))
  17. degree = pi / 180.0
  18. loop_rate = self.create_rate(30)
  19. # robot state
  20. tilt = 0.
  21. tinc = degree
  22. swivel = 0.
  23. angle = 0.
  24. height = 0.
  25. hinc = 0.005
  26. # message declarations
  27. odom_trans = TransformStamped()
  28. odom_trans.header.frame_id = 'odom'
  29. odom_trans.child_frame_id = 'axis'
  30. joint_state = JointState()
  31. try:
  32. while rclpy.ok():
  33. rclpy.spin_once(self)
  34. # update joint_state
  35. now = self.get_clock().now()
  36. joint_state.header.stamp = now.to_msg()
  37. joint_state.name = ['swivel', 'tilt', 'periscope']
  38. joint_state.position = [swivel, tilt, height]
  39. # update transform
  40. # (moving in a circle with radius=2)
  41. odom_trans.header.stamp = now.to_msg()
  42. odom_trans.transform.translation.x = cos(angle)*2
  43. odom_trans.transform.translation.y = sin(angle)*2
  44. odom_trans.transform.translation.z = 0.7
  45. odom_trans.transform.rotation = \
  46. euler_to_quaternion(0, 0, angle + pi/2) # roll,pitch,yaw
  47. # send the joint state and transform
  48. self.joint_pub.publish(joint_state)
  49. self.broadcaster.sendTransform(odom_trans)
  50. # Create new robot state
  51. tilt += tinc
  52. if tilt < -0.5 or tilt > 0.0:
  53. tinc *= -1
  54. height += hinc
  55. if height > 0.2 or height < 0.0:
  56. hinc *= -1
  57. swivel += degree
  58. angle += degree/4
  59. # This will adjust as needed per iteration
  60. loop_rate.sleep()
  61. except KeyboardInterrupt:
  62. pass
  63. def euler_to_quaternion(roll, pitch, yaw):
  64. qx = sin(roll/2) * cos(pitch/2) * cos(yaw/2) - cos(roll/2) * sin(pitch/2) * sin(yaw/2)
  65. qy = cos(roll/2) * sin(pitch/2) * cos(yaw/2) + sin(roll/2) * cos(pitch/2) * sin(yaw/2)
  66. qz = cos(roll/2) * cos(pitch/2) * sin(yaw/2) - sin(roll/2) * sin(pitch/2) * cos(yaw/2)
  67. qw = cos(roll/2) * cos(pitch/2) * cos(yaw/2) + sin(roll/2) * sin(pitch/2) * sin(yaw/2)
  68. return Quaternion(x=qx, y=qy, z=qz, w=qw)
  69. def main():
  70. node = StatePublisher()
  71. if __name__ == '__main__':
  72. main()

创建启动文件

        创建second_ros2_ws/src/urdf_tutorial_r2d2/launch文件夹,在其中新建demo_launch.py文件,将下面内容复制其中:

  1. import os
  2. from ament_index_python.packages import get_package_share_directory
  3. from launch import LaunchDescription
  4. from launch.actions import DeclareLaunchArgument
  5. from launch.substitutions import LaunchConfiguration
  6. from launch_ros.actions import Node
  7. def generate_launch_description():
  8. use_sim_time = LaunchConfiguration('use_sim_time', default='false')
  9. urdf_file_name = 'r2d2.urdf.xml'
  10. urdf = os.path.join(
  11. get_package_share_directory('urdf_tutorial_r2d2'),
  12. urdf_file_name)
  13. with open(urdf, 'r') as infp:
  14. robot_desc = infp.read()
  15. return LaunchDescription([
  16. DeclareLaunchArgument(
  17. 'use_sim_time',
  18. default_value='false',
  19. description='Use simulation (Gazebo) clock if true'),
  20. Node(
  21. package='robot_state_publisher',
  22. executable='robot_state_publisher',
  23. name='robot_state_publisher',
  24. output='screen',
  25. parameters=[{'use_sim_time': use_sim_time, 'robot_description': robot_desc}],
  26. arguments=[urdf]),
  27. Node(
  28. package='urdf_tutorial_r2d2',
  29. executable='state_publisher',
  30. name='state_publisher',
  31. output='screen'),
  32. ])

编辑setup.py文件

        我们必须告诉colcon build工具如何安装指定的python包。这可以通过修改python包根路径下的setup.py文件实现。

        包含如下内容

  1. import os
  2. from glob import glob
  3. from setuptools import setup
  4. from setuptools import find_packages
'
运行
  1. data_files=[
  2. ...
  3. (os.path.join('share', package_name, 'launch'), glob(os.path.join('launch', '*launch.[pxy][yma]*'))),
  4. (os.path.join('share', package_name), glob('urdf/*')),
  5. ],

        修改入口点(entry_points),使得可以通过控制台启动'state_publisher'.

  1. 'console_scripts': [
  2. 'state_publisher = urdf_tutorial_r2d2.state_publisher:main'
  3. ],

安装python包

  1. $cd second_ros2_ws
  2. $colcon build --symlink-install --packages-select urdf_tutorial_r2d2

        最后配置下环境变量:

$source install/setup.bash

查看结果

$ros2 launch urdf_tutorial_r2d2 demo_launch.py

        打开另外一个终端,运行rviz2进行查看(rviz使用参考)。

  1. $source /opt/ros/iron/setup.bash
  2. $rviz2 -d second_ros2_ws/install/urdf_tutorial_r2d2/share/urdf_tutorial_r2d2/r2d2.rviz

        不出大意外的话,大家运行后的结果应该像下面这样(需要手动点击左下角的Add按钮添加TF及机器人模型),机器人“隐身”了。 

 

        如果我们换个命令,则一切正常了(其实前面的命令最后调用的还是下面这个路径的rviz文件)

$rviz2 -d src/urdf_tutorial_r2d2/urdf/r2d2.rviz

或加上绝对路径,

$rviz2 -d ~/Desktop/second_ros2_ws/install/urdf_tutorial_r2d2/share/urdf_tutorial_r2d2/r2d2.rviz

 

        此例原始代码工程在(只不过编译运行后会报错误,需要增加dummpy link来解决)。

本篇完。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/979148
推荐阅读
相关标签
  

闽ICP备14008679号