预计完成时间:15 分钟
到目前为止,你已经有了一台能够移动的机器人。为了让机器人能够在障碍物之间导航,并感知周围环境,你还需要一个近距离扫描传感器,也就是激光扫描仪。因此,接下来要加入 Laser Scanner Plugin。
首先,创建一个新的连杆来表示扫描传感器。把下面的代码添加到机器人定义文件中。
把下面这段代码复制到你的 URDF 文件底部,也就是结束的 </robot> XML 标签之前。
复制并粘贴
<!-- 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 标签之前。
复制并粘贴
<!-- 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>
 Plugin_files/Gazebo_Ignition.jpg)
对应的新 Gazebo Sim 写法:
<!-- 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_angle 和 max_angle 之间采样的数量以及分辨率。请特别留意这些参数,因为它们决定了扫描从哪里开始、以多大步长进行以及最终在何处结束。
Range 用于定义最小距离、最大距离以及分辨率。
重要! 最小测距值不能小于安装传感器的那个连杆本体尺寸,否则读数会一直先撞到连杆自身的内部形状,这显然没有意义。在这个例子里,最小测距值设为 0.20,而表示传感器的圆柱半径是 0.15,因此扫描会从传感器几何体之外开始。
 Plugin_files/lidar_rays_zoomed.png)
你还可以通过官方文档进一步了解其他参数:https://gazebosim.org/api/gazebo/6.5/classignition_1_1gazebo_1_1Lidar.html。
粘贴完成后,保存你的 URDF 文件。接下来需要重新构建 ROS2 功能包,并重新生成机器人。
如果想把激光扫描仪的测距结果可视化出来,可以使用插件面板中内置的 Gazebo Sim 插件 Visualize Lidar。
机器人生成后,启动这个插件,并点击橙色的 Refresh 按钮,让系统自动选择带有 LaserScan 消息的对应话题。
 Plugin_files/visualize_lidar_plugin.png)
插件启动并选中话题之后,机器人应该会呈现出下图所示的效果:
 Plugin_files/gazebo_lidar_visuals.png)
编写一个简单的 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 命令运行自己的程序。
预期结果:
 Plugin_files/display_scan_result.gif)
 Plugin_files/english-proofread-ok.png)