环境准备

xacro建模教程中,我们费老大劲在宏文件中添加了碰撞、惯性等物理属性,但并没有在Rviz中表现出来。这是因为RViz2只是显示器,只负责把数据画出来。在ROS生态中,Gazebo才是负责物理这一块的插件。

通过pkg list命令,可以检查响应的库是否已经安装

ros2 pkg list | grep ros_gz
ros2 pkg list | grep tf2
ros2 pkg list | grep twist

其中ros_gz就是最新版的Gazebo引擎;tf2是ROS2的坐标系转换框架,后面细讲;wtist_keyboard用于键盘控制。

如果没装,需要装一下

sudo apt update
sudo apt install ros-lyrical-ros-gz
sudo apt install ros-lyrical-tf2-ros
sudo apt install ros-lyrical-teleop-twist-keyboard

修改xarco文件

xacro建模教程的示例中,仅完成了模型的创建。接下来,在robot.xacro中,在最后一段,即</robot>标签之前,添加下面的gazebo代码。

  <!-- ==================== 5. Gazebo 插件配置 ==================== -->
  
  <!-- 全局插件:差速驱动控制器 -->
  <gazebo>
    <plugin filename="gz-sim-diff-drive-system" name="gz::sim::systems::DiffDrive">
      <!-- 关节名称 -->
      <left_joint>left_wheel_joint</left_joint>
      <right_joint>right_wheel_joint</right_joint>
      <!-- 物理参数 -->
      <wheel_separation>${wheel_offset_y * 2}</wheel_separation>
      <wheel_radius>${wheel_radius}</wheel_radius>
      <!-- 话题配置 -->
      <topic>cmd_vel</topic>          <!-- 接收速度指令的话题 -->
      <odom_topic>odom</odom_topic>   <!-- 发布里程计的话题 -->
      <odom_publish_frequency>50</odom_publish_frequency>
      <frame_id>odom</frame_id>
      <child_frame_id>base_link</child_frame_id>
    </plugin>

    <!-- 全局插件:传感器系统(必须添加,否则雷达不工作) -->
    <plugin filename="gz-sim-sensors-system" name="gz::sim::systems::Sensors">
      <render_engine>ogre2</render_engine>
    </plugin>
  </gazebo>

  <!-- 激光雷达传感器配置 -->
  <gazebo reference="lidar_link">
    <sensor type="gpu_lidar" name="lidar_sensor">
      <topic>scan</topic>
      <update_rate>10</update_rate>
      <ray>
        <scan>
          <horizontal>
            <samples>360</samples>
            <resolution>1</resolution>
            <min_angle>-3.14159</min_angle>
            <max_angle>3.14159</max_angle>
          </horizontal>
        </scan>
        <range>
          <min>0.1</min>
          <max>10.0</max>
          <resolution>0.01</resolution>
        </range>
      </ray>
      <always_on>true</always_on>
      <visualize>true</visualize>
    </sensor>
  </gazebo>

Gazebo启动Launch文件

在robot_description/launch下,新建gazebo_launch.py,代码如下

import os
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.substitutions import Command
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory

def generate_launch_description():
    pkg_share = get_package_share_directory('robot_description')
    xacro_file = os.path.join(pkg_share, 'urdf', 'robot.xacro')
    
    # 1. 解析 Xacro
    robot_desc = Command(['xacro ', xacro_file])

    # 2. 启动 Gazebo 仿真器
    gz_sim = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(get_package_share_directory('ros_gz_sim'), 'launch', 'gz_sim.launch.py')
        ),
        launch_arguments={'gz_args': '-r empty.sdf'}.items()
        # gazebo黑屏设置如下
        # launch_arguments={'gz_args': '-r empty.sdf --render-engine ogre'}.items()
    )

    # 3. 启动 robot_state_publisher (必须!否则 create 拿不到模型)
    robot_state_publisher = Node(
        package='robot_state_publisher',
        executable='robot_state_publisher',
        parameters=[{'robot_description': robot_desc}],
        output='screen'
    )

    # 4. 将机器人 Spawn 到 Gazebo 中
    spawn_entity = Node(
        package='ros_gz_sim',
        executable='create',
        arguments=[
            '-name', 'simple_robot',
            '-topic', 'robot_description',
            '-x', '0', '-y', '0', '-z', '0.5' # 稍微高一点,防止卡在地里
        ],
        output='screen'
    )

    # 5. 启动 Bridge
    bridge = Node(
        package='ros_gz_bridge',
        executable='parameter_bridge',
        arguments=[
            '/cmd_vel@geometry_msgs/msg/Twist@gz.msgs.Twist',
            '/odom@nav_msgs/msg/Odometry@gz.msgs.Odometry',
            '/scan@sensor_msgs/msg/LaserScan@gz.msgs.LaserScan',
            '/clock@rosgraph_msgs/msg/Clock[gz.msgs.Clock'
        ],
        output='screen'
    )

    return LaunchDescription([
        gz_sim,
        robot_state_publisher,
        spawn_entity,
        bridge
    ])

编译与运行

接下来就是老三样,编译、连接环境变量、运行

colcon build
source install/setup.bash
ros2 launch robot_description gazebo_launch.py

在虚拟机中运行,需要开启3D加速。以Virtualbox为例,虚拟机关机后,右键Ubuntu点击设置,进入Expert选项卡,左侧栏点击显示,即可找到3D Acceleration的勾选框。如果开启加速后,Gazebo窗口内容是黑的,则修改launch中的gz_args参数,将其设为代码中被注释的那部分。

当 Gazebo 窗口出现,且机器人(蓝色长方体)稳稳地站在地面上后,打开一个新终端,在 source install/setup.bash后,启动键盘遥控

ros2 run teleop_twist_keyboard teleop_twist_keyboard

然后,就可以通过按键来遥控机器人了

  • 按下键盘上的 i 键(前进)。
  • 按下 j / l 键(左转/右转)。
  • 按下 , (逗号) 键(后退)。
  • 按下 k 键(停止)。

效果如下

在这里插入图片描述

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐