连接到 ROS 2


预计完成时间:15 分钟

3.9   激光扫描仪(Lidar)插件

到目前为止,你已经有了一台能够移动的机器人。为了让机器人能够在障碍物之间导航,并感知周围环境,你还需要一个近距离扫描传感器,也就是激光扫描仪。因此,接下来要加入 Laser Scanner Plugin

首先,创建一个新的连杆来表示扫描传感器。把下面的代码添加到机器人定义文件中。

把下面这段代码复制到你的 URDF 文件底部,也就是结束的 </robot> XML 标签之前。

  复制并粘贴

In [ ]:
<!-- Gazebo tags - Laser scan -->
<gazebo reference="joint_laser_scan_chassis">
    <preserveFixedJoint>true</preserveFixedJoint>
</gazebo>
<gazebo reference="link_laser_scan">
    <material>Gazebo/DarkGrey</material>
</gazebo>

<!-- Laser scan -->
<joint name="joint_laser_scan_chassis" type="fixed">
    <origin rpy="0 0 0" xyz="0.8 0 0.3" />
    <child link="link_laser_scan" />
    <parent link="link_chassis" />
    <joint_properties damping="1.0" friction="1.0" />
</joint>
<link name="link_laser_scan">
    <inertial>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <mass value="0.5" />
        <inertia ixx="0.000252666666667" ixy="0" ixz="0" iyy="0.000252666666667" iyz="0" izz="0.0005"/>
    </inertial>
    <visual>
        <origin xyz="0 0 0" rpy="0 0 0" />
        <geometry>
            <cylinder radius="0.15" length="0.20"/>
        </geometry>
        <material name="Red">
            <color rgba="0.7 0.1 0.1 1" />
        </material>
    </visual>
    <collision>
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <geometry>
            <cylinder radius="0.15" length="0.20"/>
        </geometry>
    </collision>
</link>

在上面的代码块之后,把 Laser Scanner Plugin 添加到 URDF 文件中。

再添加一个新的 Gazebo 标签,并把它关联到 link_laser_scan 连杆。这意味着传感器的读数会从该连杆的起始位置开始计算。

把下面这段代码复制到你的 URDF 文件底部,也就是放在激光扫描连杆定义之后、结束的 </robot> XML 标签之前。

  复制并粘贴

In [ ]:
<!-- Laser Scanner Plugin -->
<gazebo>
    <plugin
      filename="libignition-gazebo-sensors-system"
      name="ignition::gazebo::systems::Sensors">
      <!-- use ogre2 if ogre v2.x is installed, otherwise use ogre -->
      <render_engine>ogre2</render_engine>
    </plugin>
</gazebo>
<gazebo reference="link_laser_scan">
    <sensor type="gpu_lidar" name="head_hokuyo_sensor">
        <pose relative_to='lidar_frame'>0 0 0 0 0 0</pose>
        <always_on>1</always_on>
        <visualize>true</visualize>
        <update_rate>20</update_rate>
        <topic>/laser/scan</topic>
        <ray>
            <scan>
                <horizontal>
                    <samples>720</samples>
                    <resolution>1</resolution>
                    <min_angle>-1.570796</min_angle>
                    <max_angle>1.570796</max_angle>
                </horizontal>
            </scan>
            <range>
                <min>0.20</min>
                <max>10.0</max>
                <resolution>0.01</resolution>
            </range>
            <noise>
                <type>gaussian</type>
                <mean>0.0</mean>
                <stddev>0.01</stddev>
            </noise>
        </ray>
    </sensor>
</gazebo>
- 注释 -

对应的新 Gazebo Sim 写法:

In [ ]:
<!-- Laser Scanner Plugin -->
<gazebo>
    <plugin
      filename="libgz-sim-sensors-system"
      name="gz::sim::systems::Sensors">
      ...
    </plugin>
</gazebo>
- 注释结束 -

visualize 参数有助于你理解扫描射线在仿真中的表现方式;如果你愿意,后面也可以把它改成 false。另外,pose 用于设置这些射线相对于被引用连杆原点的位置。

update_rate 参数用于设置 Gazebo 发布数据的频率。

ray/scan/horizontal 配置中,你需要定义在 min_anglemax_angle 之间采样的数量以及分辨率。请特别留意这些参数,因为它们决定了扫描从哪里开始、以多大步长进行以及最终在何处结束。

Range 用于定义最小距离、最大距离以及分辨率

重要! 最小测距值不能小于安装传感器的那个连杆本体尺寸,否则读数会一直先撞到连杆自身的内部形状,这显然没有意义。在这个例子里,最小测距值设为 0.20,而表示传感器的圆柱半径是 0.15,因此扫描会从传感器几何体之外开始。

"Lidar Rays Zoomed"

你还可以通过官方文档进一步了解其他参数:https://gazebosim.org/api/gazebo/6.5/classignition_1_1gazebo_1_1Lidar.html

粘贴完成后,保存你的 URDF 文件。接下来需要重新构建 ROS2 功能包,并重新生成机器人。

在 Gazebo Sim 中可视化 Lidar

如果想把激光扫描仪的测距结果可视化出来,可以使用插件面板中内置的 Gazebo Sim 插件 Visualize Lidar

机器人生成后,启动这个插件,并点击橙色的 Refresh 按钮,让系统自动选择带有 LaserScan 消息的对应话题。

"Visualize Lidar Plugin"

插件启动并选中话题之后,机器人应该会呈现出下图所示的效果:

"Gazebo Lidar Visuals"

- 练习 3.7.2 -

编写一个简单的 Python 脚本,根据两个参数控制机器人运动:线速度角速度

在机器人运动过程中,程序需要显示激光扫描传感器读到的最小距离

**提示:** 你需要同时为 /cmd_vel/laser/scan 这两个话题创建桥接。你已经知道 /cmd_vel 需要使用双向桥接;而 /laser/scan 则应使用单向桥接,也就是 IGN 到 ROS 的桥接。可用命令如下:

ros2 run ros_gz_bridge parameter_bridge /cmd_vel@geometry_msgs/msg/Twist@ignition.msgs.Twist /laser/scan@sensor_msgs/msg/LaserScan[ignition.msgs.LaserScan

**注意:** 别忘了更新你的 setup.py 文件,这样你才能通过 ros2 run 命令运行自己的程序。

预期结果:

"Display Scan Result"

- 练习 3.7.2 结束 -
- 练习 3.7.2 参考答案 -

在你自己尝试完成练习之前,不要先看答案。完成后再回头查看参考答案,会更方便你对比自己的实现。

如果你在完成练习时遇到问题,可以到论坛寻求支持。

display_scan.py

- 练习 3.7.2 参考答案结束 -