当前位置:   article > 正文

ros机器人在navigation下导航costmap_2d动态层(障碍物层)障碍物无法及时消除的情况解决办法_ros如何及时清除人走过的动态障碍物

ros如何及时清除人走过的动态障碍物

设备

杉川-3a激光雷达

win10笔记本电脑

ubuntu18.04

ros-melodic

问题

ros机器人在move_base下导航,有静态图层与动态图层,静态图层显示之前已经建立好的地图,而动态层显示现在激光雷达实时扫描到的障碍物。

假设机器人雷达最大范围为8m,在某一时刻,以机器人为原点,在机器人前方5m有一障碍物,在障碍物后方,距离机器人10m远有一堵墙。

在导航中机器人可以识别并标记5m处的障碍物,并在动态层显示障碍物,此时将障碍物平行移动至距离机器人5m处的另一个位置。发现原来位置的动态层处的障碍物位置信息并没有被更新,此时出现了两个障碍物标记,实际只有一个障碍物,但却出现了两个标记。

如果此时人从机器人5m处经过,会留下一排标记且无法更新

原因

move_base导航时,动态图更新时需要可用的激光雷达数据,当障碍物在5m时程序接受到正确的5m的数据,更新了动态层,但当障碍物移动时,原方向上只有10m外的有一堵墙,此时激光雷达无法捕捉到墙的距离信息,因为激光雷达的范围是8m,所以在原方向输出的数据为inf,即无穷大这并不算程序能处理的数据,所以程序认为此方向没有数据,故无法更新该方向上的障碍物标记信息。

解决方法

先查看原激光雷达数据信息

rostopic echo -n 1 /scan

3add516a4e114c9c997b33b9e61aba7c.png

此处雷达信息有多个inf,无穷大

我们打开雷达的功能包,找到输出雷达数据的段落

  1. for (size_t i = 0; i < node_count; i++)
  2. {
  3. size_t current_angle = floor(nodes[i].angle);
  4. //printf("current_angle = %d\r\n", current_angle);
  5. if(current_angle >= 360.0)
  6. {
  7. //printf("lidar angle over rang\n");
  8. continue;
  9. }
  10. float read_value = (float) nodes[i].distance;
  11. if (read_value > scan_msg.range_max || read_value < scan_msg.range_min)
  12. //如果雷达数据比最大值大,比最小值小,即在雷达范围外
  13. scan_msg.ranges[360 - 1 - current_angle] = std::numeric_limits<float>::infinity();
  14. //将此方向上的数据输出为无限大,std::numeric_limits<float>::infinity()这句话可以理解为一个无限大的值,赋给/scan节点
  15. else
  16. scan_msg.ranges[360 - 1 - current_angle] = read_value;
  17. }

由于move_base程序无法处理无限大,则修改为

  1. for (size_t i = 0; i < node_count; i++)
  2. {
  3. size_t current_angle = floor(nodes[i].angle);
  4. //printf("current_angle = %d\r\n", current_angle);
  5. if(current_angle >= 360.0)
  6. {
  7. //printf("lidar angle over rang\n");
  8. continue;
  9. }
  10. float read_value = (float) nodes[i].distance;
  11. if (read_value > scan_msg.range_max || read_value < scan_msg.range_min)
  12. //如果雷达数据比最大值大,比最小值小,即在雷达范围外
  13. //scan_msg.ranges[360 - 1 - current_angle] = std::numeric_limits<float>::infinity();
  14. scan_msg.ranges[360 - 1 - current_angle] = 0.0;
  15. //0.0赋值给/scan节点
  16. else
  17. scan_msg.ranges[360 - 1 - current_angle] = read_value;
  18. }

在catkin_make后在运行激光雷达并监听

89f57f1b41fe4210a9521cf8a3776641.png

确保你的数据是0.0,便可以开始下一步

如果你之前用的是sudo apt install ros-melodic-navigation下载的navigotion请卸载他

sudo apt remove ros-melodic-navigation

然后下载源码版的navigation

新建工作空间,并下载源码

  1. mkdir ~/navigation/src
  2. cd ~/navigation/src
  3. git clone https://github.com/ros-planning/navigation.git 
  4. cd ~/navigation
  5. catkin_make
  6. cd
  7. gedit .bashrc
  8. source ~/navigation/devel/setup.bash加入

如果提示报错一般是缺少功能包,运行

sudo apt install ros-melodic-功能包名

注意功能包名的下划线改连字符 _ 号改成 - 号

打开~/navigation/src/navigation/costmap_2d/plugins/obstacle_layer.cpp

找到第272行

  1. void ObstacleLayer::laserScanValidInfCallback(const sensor_msgs::LaserScanConstPtr& raw_message,
  2. const boost::shared_ptr<ObservationBuffer>& buffer)
  3. {
  4. // Filter positive infinities ("Inf"s) to max_range.
  5. float epsilon = 0.0001; // a tenth of a millimeter
  6. sensor_msgs::LaserScan message = *raw_message;
  7. for (size_t i = 0; i < message.ranges.size(); i++)
  8. {
  9. float range = message.ranges[ i ];
  10. if (!std::isfinite(range) && range > 0)
  11. {
  12. message.ranges[ i ] = message.range_max - epsilon;
  13. }
  14. }

改成

  1. void ObstacleLayer::laserScanValidInfCallback(const sensor_msgs::LaserScanConstPtr& raw_message,
  2. const boost::shared_ptr<ObservationBuffer>& buffer)
  3. {
  4. // Filter positive infinities ("Inf"s) to max_range.
  5. float epsilon = 0.0001; // a tenth of a millimeter
  6. sensor_msgs::LaserScan message = *raw_message;
  7. for (size_t i = 0; i < message.ranges.size(); i++)
  8. {
  9. float range = message.ranges[ i ];
  10. if (!std::isfinite(range) && range > 0||(range == 0.0))
  11. // 当雷达数据等于0.0时,认为此时激光雷达为最大范围
  12. {
  13. message.ranges[ i ] = message.range_max - epsilon;
  14. }
  15. }

回到navigation目录下,catkin_make

打开你的导航配置功能包,找到costmap_common_params.yaml配置文件

  1. robot_radius: 0.2
  2. map_type: costmap
  3. static_layer:
  4. enabled: true
  5. unknown_cost_value: -1
  6. lethal_cost_threshold: 100
  7. obstacle_layer:
  8. enabled: true
  9. max_obstacle_height: 2.0
  10. origin_z: 0.0
  11. z_resolution: 0.2
  12. z_voxels: 10
  13. unknown_threshold: 10
  14. mark_threshold: 0
  15. combination_method: 1
  16. track_unknown_space: false
  17. publish_voxel_map: false
  18. observation_sources: scan
  19. scan:
  20. data_type: LaserScan
  21. topic: scan
  22. marking: true
  23. clearing: true
  24. min_obstacle_height: -0.1
  25. max_obstacle_height: 1.5
  26. obstacle_range: 4.0
  27. raytrace_range: 4.0
  28. inf_is_valid: true #scan的无穷远数据是否有效
  29. inflation_layer:
  30. enabled: true
  31. cost_scaling_factor: 10
  32. inflation_radius: 0.11

在obstacle_layer:  /    scan:  /  中添加 inf_is_valid: true使数据有有效

问题解决

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/390306
推荐阅读
相关标签
  

闽ICP备14008679号