纠正了遥控避障的bug, 由于teleop_twist_keyboard输出的速度话题与避障代码输出的更新后的速度控制话题相同。会导致代码进入死循环,从而导致避障失效。

teleop_twist_keyboard
        │
        ▼
     /cmd_vel
        │
        ▼
  tele_obs_avoid
        │
        ▼
     /cmd_vel
        ▲
        │
        └───── 自己又订阅了自己发布的话题
进入死循环的原因:
键盘输入

cmd.linear.x = 0.5

第一次进入 人工势场法修正速度(APF):

输入 0.5
↓
APF修正
↓
输出 0.3

发布到:/cmd_vel

但是下一次循环又订阅到了:0.3

于是:

输入 0.3
↓
APF修正
↓
输出 0.1

下一次:

输入 0.1
↓
APF修正
↓
输出 0

下一次:

输入 0
↓
APF修正
↓
输出 0

机器人彻底停住。

解决:

通过一下命令,将teleop_twist_keyboard输出的速度话题变更为/tele_cmd_vel。

ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args -r cmd_vel:=/tele_cmd_vel

问题2:当机器人离障碍物过近,停障后,无法通过遥控器倒退,走出停障区。

  //禁止前进,但是允许遥控后退脱困
  if (min_obstacle_dist < config_.apf_emergency_dist)
{
    if (cmd.linear.x > 0.0)
    {
        cmd.linear.x = 0.0;
    }

    cmd.linear.y = 0.0;

    return;
}

nav2的调参过程

一、 nav2的导航过程中,若局部地图出现空白,则未接收到局部的点云话题。

若接收到局部点云话题,则会生成如下图所示的局部栅格地图。

二、我想扩大nav2局部地图的范围,和局部路径的长度应该在这里改:

1.nav2局部地图的范围

obstacle_max_range: 5.0 — 代表标记障碍物范围,就是检测障碍物的最大距离。激光在此范围内命中的点,对应体素标记为 occupied(障碍)。

注意:里面大部分的数值,都要是浮点型,要有小数点,否则会启动不了。

2. 调节代价地图的膨胀区

调参建议

inflation_radius — 膨胀半径

障碍物周围多大范围内生成代价,单位米。

cost_scaling_factor — 衰减速率

控制代价从障碍物边缘到膨胀半径边缘衰减的快慢

场景 inflation_radius cost_scaling_factor
机器人贴墙走(紧凑环境) 小 (0.3~0.4) 大 (5~10)
机器人远离障碍物(安全优先) 大 (0.6~1.0) 小 (1~3)
大型机器人 robot_radius + 0.3 以上 2~5

三、局部栅格地图更新太慢,导致转向时,点云抖动或者移动障碍物导致的局部占据栅格会长时间停留,导致周围没有通路,无法路径规划。

原因:局部地图的障碍物栅格的处理方案是,voxel_layer的3D体素处理,计算开销很大,会产生更新延迟。

解决:将voxel_layer的插件换成obstacle_layer ,obstacle_layer是纯 2D 射线投射,计算极快,匹配传感器实时帧率。

场景适用性: voxel_layer 适用:需要区分高低障碍物、台阶、悬空杂物的场景(室内高差复杂、巡检机器人);代价是计算慢、动态转向易留拖影。 obstacle_layer 适用:地面移动机器狗 / AGV 仅检测地面障碍、以局部实时避障为核心的场景;更新速度快,彻底解决转向点云抖动残留的栅格导致的路径规划失效问题。

1. voxel_layer的配置代码。

plugins: ["voxel_layer", "inflation_layer"]
      inflation_layer:
        plugin: "nav2_costmap_2d::InflationLayer"
        cost_scaling_factor: 2.0
        inflation_radius: 0.55
      voxel_layer:
        plugin: "nav2_costmap_2d::VoxelLayer"
        enabled: True
        publish_voxel_map: True
        origin_z: 0.0
        z_resolution: 0.05
        z_voxels: 16
        max_obstacle_height: 2.0
        mark_threshold: 0   #当一个栅格内障碍物的点数大于mark_threshold时,认为该点是障碍物,二维点云一个点就算一个障碍物点只能设为0,三维点云一个体素内的点数大于mark_threshold时,认为该体素是障碍物
        observation_sources: scan
        scan:
          topic: /laser_scan
          max_obstacle_height: 2.0
          clearing: True
          marking: True
          data_type: "LaserScan"
          raytrace_max_range: 5.0
          raytrace_min_range: 0.1
          obstacle_max_range: 5.0
          obstacle_min_range: 0.0
      static_layer:
        plugin: "nav2_costmap_2d::StaticLayer"
        map_subscribe_transient_local: True
      always_send_full_costmap: True

2. obstacle_layer的配置代码。

 plugins: ["obstacle_layer", "inflation_layer"]
      obstacle_layer:
        plugin: "nav2_costmap_2d::ObstacleLayer"
        enabled: True
        observation_sources: "scan"

        scan:
          topic: /laser_scan
          max_obstacle_height: 2.0
          clearing: True
          marking: True
          data_type: "LaserScan"

          # 没打到障碍物的 inf 射线参与清除
          inf_is_valid: true

          # 不保留历史观测
          observation_persistence: 0.0

          # 清除距离建议略大于标记距离
          raytrace_max_range: 8.0
          raytrace_min_range: 0.1
          obstacle_max_range: 7.5
          obstacle_min_range: 0.0

      inflation_layer:
        plugin: "nav2_costmap_2d::InflationLayer"
        cost_scaling_factor: 2.0
        inflation_radius: 0.55

      always_send_full_costmap: True

Logo

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

更多推荐