当前位置:   article > 正文

ROS障碍层的无法清除干净的处理办法_obstacle ros 配置 障碍物没有清除

obstacle ros 配置 障碍物没有清除


    使用DWA导航的时候,发现障碍层的地图无法清除干净,在网上找了许久也找不到解决的办法,最后通过查看源码解决了这个问题。查看这个链接的时候:http://answers.ros.org/question/30014/costmap-clearing-of-obstacles/时候大概发现了问题的原因。是因为当激光雷达的数据在达到最大的距离的时候,会出现无法清除障碍物的现象。

    于是自己仿真的时候果然出现了这个问题,当激光雷达达到最大的距离的时候,会出现返回的激光的数据变为最大值,这个链接回答后面其中也给出了一些解决方法,但是没有根本上解决。

    在Rviz中也看不到等于激光最大检测范围的点,应该是Rviz自动处理了激光距离等于最大范围的数据,不显示。我分析激光雷达的数据是在障碍层进行了处理,于是我查看了costmap_2d软件包中的obstacle_laer.cpp文件,发现下面这段代码:


  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. }
  15. // project the laser into a point cloud
  16. sensor_msgs::PointCloud2 cloud;
  17. cloud.header = message.header;
  18. // project the scan into a point cloud
  19. try
  20. {
  21. projector_.transformLaserScanToPointCloud(message.header.frame_id, message, cloud, *tf_);
  22. }
  23. catch (tf::TransformException &ex)
  24. {
  25. ROS_WARN("High fidelity enabled, but TF returned a transform exception to frame %s: %s",
  26. global_frame_.c_str(), ex.what());
  27. projector_.projectLaser(message, cloud);
  28. }
  29. // buffer the point cloud
  30. buffer->lock();
  31. buffer->bufferCloud(cloud);
  32. buffer->unlock();
  33. }


    上面那一段红色的代码处理了每一个激光的数据,如果是激光的点是最大的距离,那么将这个点设置为比最大距离小十分之一毫米。我猜想程序设计者也考虑到了这个问题,当激光的距离等于最大的距离的时候会出现障碍物无法清除的现象,因此做这样的处理,使得所有的激光数据的距离小于最大距离。

    那么既然有了这样的处理为什么还会出现障碍物无法清除的现象呢?于是我查看了/scan数据,我发现激光的/scan话题,这个节点出来的数据是当障碍物的距离

大于激光的检测距离时,激光的数据被自动设置为最大距离,而不是inf,因此这段程序并不起作用,因此将程序改为下面的:

  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 >= message.range_max))
  11. {
  12. message.ranges[ i ] = message.range_max - epsilon;
  13. }
  14. }
  15. // project the laser into a point cloud
  16. sensor_msgs::PointCloud2 cloud;
  17. cloud.header = message.header;
  18. // project the scan into a point cloud
  19. try
  20. {
  21. projector_.transformLaserScanToPointCloud(message.header.frame_id, message, cloud, *tf_);
  22. }
  23. catch (tf::TransformException &ex)
  24. {
  25. ROS_WARN("High fidelity enabled, but TF returned a transform exception to frame %s: %s",
  26. global_frame_.c_str(), ex.what());
  27. projector_.projectLaser(message, cloud);
  28. }
  29. // buffer the point cloud
  30. buffer->lock();
  31. buffer->bufferCloud(cloud);
  32. buffer->unlock();
  33. }


当激光的数据范围大于最大值的时候都会设置为比最大值小一点点。这样就能保证障碍层能够清除了。


然后重新编译costmap_2d软件包

  1. catkin_make
  2. catkin_make install
 

将工作空间中的instal文件夹下面lib中的costmap_2d文件夹,liblayers.so和libcostmap_2d.so文件覆盖/opt/ros/indigo/lib/下的对应的文件就好了


最后在costmap_common_params.yaml文件中添加inf_is_valid设置为true。

  1. observation_sources: scan
  2. scan:
  3. data_type: LaserScan
  4. topic: /scan
  5. marking: true
  6. clearing: true
  7. inf_is_valid: true
  8. min_obstacle_height: 0.0
  9. max_obstacle_height: 1.0






















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

闽ICP备14008679号