过滤噪声引起的障碍物
概述
嘈杂的传感器测量可能导致“体素层”或“障碍层”出现错误。因此,代价地图上可能会出现椒盐噪声。这种噪声会产生虚假障碍,阻止机器人在地图上找到最佳路径。虽然上面的图片显示了椒盐噪声以及由于错误定位而导致的错误,但该层只会消除传感器噪声,而不会消除与静态地图错位的错误定位伪影。 本教程介绍如何配置由噪声引起的虚假障碍的过滤。此功能由“DenoiseLayer”代价地图层插件提供,该插件将在本文档中启用和使用。
要求
假设 ROS 2、Gazebo 和 TurtleBot3 软件包已在本地安装或构建。请确保 Nav2 项目也在本地构建,因为它是在 构建与安装 中创建的。
教程步骤
1. 启用降噪层
Denoise Layer 是 Costmap2D 插件。您可以通过将“denoise_layer”添加到“nav2_params.yaml”中的“plugins”参数来启用 Costmap2D 中的“DenoiseLayer”插件。您可以将其放置在“global_costmap”和(或)“local_costmap”中,以过滤全局或局部地图上的噪声。DenoiseLayer 插件应定义以下参数:
“plugin”:插件类型。在我们的例子中是“nav2_costmap_2d::DenoiseLayer”。
“DenoiseLayer”支持的完整参数列表列在 :ref:“denoise”页面。
需要注意的是,“DenoiseLayer”通常应放置在膨胀层之前。 这是防止因噪声引起的障碍物膨胀所必需的。 此外,“DenoiseLayer”仅处理代价地图中的障碍物信息。 值“INSCRIBED_INFLATED_OBSTACLE”、“LETHAL_OBSTACLE”和可选的“NO_INFORMATION” 将被解释为障碍物单元。具有任何其他值的单元在处理时将被解释为“FREE_SPACE”(不会在代价地图中扭曲)。 如果带有障碍物的单元被识别为噪声,则在处理后将被“FREE_SPACE”替换。
要为全局和局部代价地图启用“DenoiseLayer”,请使用以下配置:
global_costmap:
global_costmap:
ros__parameters:
...
plugins: ["static_layer", "obstacle_layer", "denoise_layer", "inflation_layer"]
...
denoise_layer:
plugin: "nav2_costmap_2d::DenoiseLayer"
enabled: True
...
local_costmap:
local_costmap:
ros__parameters:
...
plugins: ["voxel_layer", "denoise_layer", inflation_layer"]
...
keepout_filter:
plugin: "nav2_costmap_2d::DenoiseLayer"
enabled: True
Note
成功过滤噪声的关键在于了解噪声的类型并选择正确的“DenoiseLayer”参数。 默认参数侧重于快速移除独立障碍物。 更正式地说,如果相邻的八个单元之间没有障碍物,则丢弃障碍物。 在典型情况下,这应该足够了。
如果某个传感器产生相互关联的噪声引起的障碍物,并且世界上不太可能出现小障碍物,则可以移除小群障碍物。 要将“DenoiseLayer”配置为此类情况并了解其工作原理,请参阅“工作原理”部分。
Warning
谨慎使用此插件过滤全局成本地图。它会带来潜在的性能问题。 例如,对于通常为高范围的激光雷达(20 米以上),更新窗口可能非常大,导致处理时间长得令人无法接受。 作为应用程序设计者,这一点值得考虑。
工作原理
该插件基于两种算法。
当参数 minimal_group_size = 2 时,第一个算法开启。
它将 erosion 函数与下图中的内核(如果 group_connectivity_type = 4,则为左侧;如果 group_connectivity_type = 8,则为右侧)应用于成本图。
内核像素的白色表示使用该值,黑色表示忽略它。
侵蚀函数的结果是创建了邻居图像。核在代价地图上的每个可能位置都与邻居图像的一个像素相对应。此图像的像素值等于对应于掩码白色像素的 4/8 代价地图像素的最大值。 换句话说,如果附近有障碍物,则邻居图像的像素等于障碍物代码,否则等于自由空间代码。 之后,邻居图像上与自由空间代码相对应的障碍物将被移除。
此过程如下所示。图像左侧是成本地图,右侧是邻居图像。白色像素表示自由空间,黑色像素表示障碍物,“group_connectivity_type” = 4。 动画结束时标记的障碍物将被移除。
当参数“minimal_group_size”> 2 时,将执行第二种算法。 这是一个通用解决方案,如果相邻障碍物的总数小于“minimal_group_size”,则可以删除这些障碍物。 为了选择相邻障碍物的组,该算法会对其进行分割。 一个段中的单元连接类型由参数“group_connectivity_type”决定。 接下来,计算每个段的大小。 大小小于“minimal_group_size”的障碍物段将被空单元替换。 该算法比第一个算法慢 10 倍左右,因此请谨慎使用,并且仅在必要时使用。 其执行时间取决于处理的地图片段的大小(而不取决于“minimal_group_size”的值)。
下面的动画说明了此算法(“group_connectivity_type” = 8)。 动画结尾处标记的障碍物将被移除(大小小于 3 的组)。