作者:Sanjula Thiranjaya 编译:McGL
机器人自主探索,主要会遇到两类障碍物,即正障碍物和负障碍物。因为地平面缺失必须作为一个障碍物来检测,所以悬崖被认为是负的障碍物。悬崖检测在自主导航和探索中具有重要意义,可以探测和避开楼梯和凹坑等障碍物。
在自主移动机器人中,实现悬崖检测和躲避的一种方法是使用距离传感器(range sensor)检测悬崖,并将检测到的悬崖数据添加到现有的 ROS 导航栈中。ROS 分层 costmap 模型中的距离传感器层可以用来完成这项任务,因为它允许使用从距离传感器接收到的数据在 costmap 中标记障碍物。
在这里,指向地面的距离传感器被用来检测地平面的缺失。由于距离传感器层将更近的距离值标记为障碍物,如果我们将距离传感器的原始数据输入到距离传感器层,那么地板将被标记为障碍物。因此我们的想法是在将数据输入到距离传感器层之前将距离传感器接收到的数据反转。可以在 ROS 中实现一个中间节点(node),以快捷的计算这个反转(inversion)。
如图所示,距离 d2 应该转换成一个较小的值,这样它就会被标记为障碍物,距离 d1 应该转换成一个较大的值,这样它就不会被标记为障碍物。
利用倾斜距离传感器探测悬崖
本文是根据上述的思路将悬崖检测集成到 ROS 导航栈的分步教程。
这可以通过改变与红外传感器接合处的倾斜度来实现。在这种情况下,倾斜度设置为0.15弧度。
<!--Cliff Sensor Joints-->
<joint name="cliff_front_joint" type="fixed">
<axis xyz="0 1 0" />
<origin rpy="0 0.15 0" xyz=".291 0 0.15" />
<parent link="base_footprint"/>
<child link="cliff_ir_front"/>
</joint>
现在红外传感器信息将包含检测到的到地板的距离。(注意,这个距离根据红外传感器接合处的倾斜度而变化。)
Cliff_data 包的功能块图
初始化一个名为 'cliff_data' 的包,并在这个新的包中创建 src/cliff_data_node.cpp 文件。
节点应该订阅由距离传感器发布的主题,并且发布反转的(inverted)距离传感器读数。因此,节点既是订阅者又作为发布者。详细的 ROS 节点的代码在下面地址:https://github.com/jula97/myrobot/blob/main/src/cliff_data/src/cliff_data_node.cpp
数据的反转是使用以下方法在 ROS 节点内实现的。
//IR range data to cliff data conversion
float ir_to_cliff(double range){
if (range>cliff_mark_threshold)
{
return cliff_mark_distance;
}
else
{
return 10;
}
}
需要调优的参数可以使用 .yaml 文件导入到 ROS 参数服务器。这非常有用,因为这样每次更改参数时就不需要再重新编译 workspace 了。
在 cliff_data 包中创建 param/cliff_param.yaml 文件。
#Cliff data configuration parameters
#cliff_mark_threshold -> Threshold for IR ranges above which to be considered as cliffs
#cliff_mark_distance -> Range that should be published if a cliff is detected
cliff_mark_threshold: 1.1
cliff_mark_distance: 0.8
Launch 文件指定要设置的参数以及要在 ROS 包中启动的节点。
在 cliff_data 包中创建 launch/ir_to_cliff.launch 文件。
<!-- ir_to_cliff-->
<launch>
<node pkg="cliff_data" type="cliff_data_node" name="cliff_data_node">
</node>
<rosparam file="$(find cliff_data)/param/cliff_param.yaml" />
</launch>
现在负责悬崖检测的包已经完成。最终的包结构应该如下。
cliff_data
│ CMakeLists.txt
│ package.xml
└───launch
│ │ ir_to_cliff.launch
└───param
│ │ cliff_param.yaml
└───src
│ │ cliff_data_node.cpp
通过向 ROS 导航栈中的 costmap_common_parameter.yaml 文件添加以下代码块,可以创建一个新的距离传感器层。这个新层应该订阅上述节点发布的反转距离消息。
range_sensor_layer:
clear_threshold: 0.40
mark_threshold: 0.95
inflate_cone: 0.0
clear_on_max_reading: false
topics: ["/sensor/cliff_range_front","/sensor/cliff_range_back","/sensor/cliff_range_left_1","/sensor/cliff_range_right_1","/sensor/cliff_range_left_2","/sensor/cliff_range_right_2"]
新创建的距离传感器层可以作为插件添加到本地和全局 costmap 中。
global_costmap_params.yaml:
plugins:
- {name: static_layer, type: "costmap_2d::StaticLayer"}
- {name: obstacle_layer, type: "costmap_2d::ObstacleLayer"}
- {name: range_sensor_layer, type: "range_sensor_layer::RangeSensorLayer"}
- {name: inflation_layer, type: "costmap_2d::InflationLayer"}
local_costmap_params.yaml:
plugins:
- {name: obstacle_layer, type: "costmap_2d::ObstacleLayer"}
- {name: range_sensor_layer, type: "range_sensor_layer::RangeSensorLayer"}
- {name: inflation_layer, type: "costmap_2d::InflationLayer"}
现在悬崖检测和避开集成到 ROS 导航栈的工作已经完成。记住要保存所有修改过的文件,并在启动节点之前编译 workspace。ROS 导航栈启动后,可以使用以下命令启动负责数据反转的节点。
$ roslaunch cliff_data ir_to_cliff.launch
以下是使用 Gazebo 实现这种悬崖检测和避开方法后得到的一些结果。用于生成结果的完整 workspace 可以从以下地址 clone:https://github.com/jula97/myrobot
悬崖检测和避开
原文: https://medium.com/teamarimac/cliff-detection-and-avoidance-using-range-sensor-layer-5bba653f0d27