costmap_layer.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  * Copyright (c) 2015, Michal Drwiega (drwiega.michal@gmail.com)
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions are met:
00009  *     1. Redistributions of source code must retain the above copyright
00010  *        notice, this list of conditions and the following disclaimer.
00011  *     2. Redistributions in binary form must reproduce the above copyright
00012  *        notice, this list of conditions and the following disclaimer in the
00013  *        documentation and/or other materials provided with the distribution.
00014  *     3. Neither the name of the copyright holder nor the names of its
00015  *        contributors may be used to endorse or promote products derived
00016  *        from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00019  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00021  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00022  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00023  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00024  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00025  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00026  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *****************************************************************************/
00037 #include <nav_layer_from_points/costmap_layer.h>
00038 
00039 #include <iostream>
00040 #include <fstream>
00041 
00042 using costmap_2d::NO_INFORMATION;
00043 using costmap_2d::LETHAL_OBSTACLE;
00044 using costmap_2d::FREE_SPACE;
00045 
00046 PLUGINLIB_EXPORT_CLASS(nav_layer_from_points::NavLayerFromPoints, costmap_2d::Layer)
00047 
00048 namespace nav_layer_from_points
00049 {
00050   //=================================================================================================
00051   void NavLayerFromPoints::onInitialize()
00052   {
00053     current_ = true;
00054     first_time_ = true;
00055 
00056     ros::NodeHandle nh("~/" + name_), g_nh;
00057     sub_points_ = nh.subscribe("/downstairs_detector/points", 1,
00058                                &NavLayerFromPoints::pointsCallback, this);
00059 
00060     rec_server_ = new dynamic_reconfigure::Server<NavLayerFromPointsConfig>(nh);
00061     f_ = boost::bind(&NavLayerFromPoints::configure, this, _1, _2);
00062     rec_server_->setCallback(f_);
00063   }
00064 
00065   //=================================================================================================
00066   void NavLayerFromPoints::configure(NavLayerFromPointsConfig &config, uint32_t level)
00067   {
00068     points_keep_time_ = ros::Duration(config.keep_time);
00069     enabled_ = config.enabled;
00070 
00071     point_radius_ = config.point_radius;
00072     robot_radius_ = config.robot_radius;
00073   }
00074 
00075   //=================================================================================================
00076   void NavLayerFromPoints::pointsCallback(const depth_nav_msgs::Point32List& points)
00077   {
00078     boost::recursive_mutex::scoped_lock lock(lock_);
00079     points_list_ = points;
00080   }
00081 
00082   //=================================================================================================
00083   void NavLayerFromPoints::clearTransformedPoints()
00084   {
00085     std::list<geometry_msgs::PointStamped>::iterator p_it;
00086     p_it = transformed_points_.begin();
00087 
00088     if (transformed_points_.size() > 10000)
00089       transformed_points_.clear();
00090 
00091     while(p_it != transformed_points_.end())
00092     {
00093       if(ros::Time::now() - (*p_it).header.stamp > points_keep_time_)
00094         p_it = transformed_points_.erase(p_it);
00095       else
00096         ++p_it;
00097     }
00098   }
00099 
00100   //=================================================================================================
00101   void NavLayerFromPoints::updateBounds(double origin_x, double origin_y, double origin_z,
00102                                     double* min_x, double* min_y, double* max_x, double* max_y)
00103   {
00104     boost::recursive_mutex::scoped_lock lock(lock_);
00105 
00106     std::string global_frame = layered_costmap_->getGlobalFrameID();
00107 
00108     // Check if there are points to remove in transformed_points list and if so, then remove it
00109     if(!transformed_points_.empty())
00110       clearTransformedPoints();
00111 
00112     // Add points to PointStamped list transformed_points_
00113     for(unsigned int i = 0; i < points_list_.points.size(); i++)
00114     {
00115       geometry_msgs::PointStamped tpt;
00116       geometry_msgs::PointStamped pt, out_pt;
00117 
00118       tpt.point = costmap_2d::toPoint(points_list_.points[i]);
00119 
00120       try
00121       {
00122         pt.point.x = tpt.point.x;
00123         pt.point.y = 0;
00124         pt.point.z =  tpt.point.z;
00125         pt.header.frame_id = points_list_.header.frame_id;
00126 
00127         tf_.transformPoint(global_frame, pt, out_pt);
00128         tpt.point.x = out_pt.point.x;
00129         tpt.point.y = out_pt.point.y;
00130         tpt.point.z = out_pt.point.z;
00131 
00132         tpt.header.stamp = pt.header.stamp;
00133         //s << " ( " << tpt.point.x << " , " << tpt.point.y << " , " << tpt.point.z << " ) ";
00134         transformed_points_.push_back(tpt);
00135       }
00136       catch(tf::LookupException& ex)
00137       {
00138         ROS_ERROR("No Transform available Error: %s\n", ex.what());
00139         continue;
00140       }
00141       catch(tf::ConnectivityException& ex)
00142       {
00143         ROS_ERROR("Connectivity Error: %s\n", ex.what());
00144         continue;
00145       }
00146       catch(tf::ExtrapolationException& ex)
00147       {
00148         ROS_ERROR("Extrapolation Error: %s\n", ex.what());
00149         continue;
00150       }
00151     }
00152 
00153     //ROS_INFO_STREAM_THROTTLE(2,"transformed_points = " << s.str());
00154 
00155     updateBoundsFromPoints(min_x, min_y, max_x, max_y);
00156 
00157     if(first_time_)
00158     {
00159       last_min_x_ = *min_x;
00160       last_min_y_ = *min_y;
00161       last_max_x_ = *max_x;
00162       last_max_y_ = *max_y;
00163       first_time_ = false;
00164     }
00165     else
00166     {
00167       double a = *min_x, b = *min_y, c = *max_x, d = *max_y;
00168       *min_x = std::min(last_min_x_, *min_x);
00169       *min_y = std::min(last_min_y_, *min_y);
00170       *max_x = std::max(last_max_x_, *max_x);
00171       *max_y = std::max(last_max_y_, *max_y);
00172       last_min_x_ = a;
00173       last_min_y_ = b;
00174       last_max_x_ = c;
00175       last_max_y_ = d;
00176     }
00177     std::ostringstream s;
00178     s << " list_size = " << transformed_points_.size() << "   ";
00179     s << " min_x = " << *min_x << " max_x = " << *max_x <<
00180          " min_y = " << *min_y << " max_y = " << *max_y << "      ";
00181     ROS_INFO_STREAM_THROTTLE(2,"transformed_points = " << s.str());
00182 
00183   }
00184 
00185   //=================================================================================================
00186   void NavLayerFromPoints::updateBoundsFromPoints(double* min_x, double* min_y, double* max_x, double* max_y)
00187   {
00188     std::list<geometry_msgs::PointStamped>::iterator p_it;
00189 
00190     double radius = point_radius_ + robot_radius_;
00191 
00192     for(p_it = transformed_points_.begin(); p_it != transformed_points_.end(); ++p_it)
00193     {
00194       geometry_msgs::PointStamped pt = *p_it;
00195 
00196       *min_x = std::min(*min_x, pt.point.x - radius);
00197       *min_y = std::min(*min_y, pt.point.y - radius);
00198       *max_x = std::max(*max_x, pt.point.x + radius);
00199       *max_y = std::max(*max_y, pt.point.y + radius);
00200     }
00201   }
00202 
00203   //=================================================================================================
00204   void NavLayerFromPoints::updateCosts(costmap_2d::Costmap2D& master_grid,
00205                                    int min_i, int min_j, int max_i, int max_j)
00206   {
00207     boost::recursive_mutex::scoped_lock lock(lock_);
00208 
00209     if(!enabled_)
00210       return;
00211 
00212     if( points_list_.points.size() == 0 )
00213       return;
00214 
00215     std::list<geometry_msgs::PointStamped>::iterator p_it;
00216 
00217     costmap_2d::Costmap2D* costmap = layered_costmap_->getCostmap();
00218     double res = costmap->getResolution();
00219 
00220     for(p_it = transformed_points_.begin(); p_it != transformed_points_.end(); ++p_it)
00221     {
00222       geometry_msgs::Point pt = (*p_it).point;
00223 
00224       unsigned int size = std::max(1, int( (point_radius_ + robot_radius_) / res ));
00225       unsigned int map_x, map_y;
00226       unsigned int size_x = size, size_y = size;
00227       unsigned int start_x, start_y, end_x, end_y;
00228 
00229       // Check if point is on map
00230       // Convert from world coordinates to map coordinates with checking for legal bounds
00231       if (costmap->worldToMap(pt.x, pt.y, map_x, map_y))
00232       {
00233         start_x = map_x - size_x / 2;
00234         start_y = map_y - size_y / 2;
00235         end_x = map_x + size_x / 2;
00236         end_y = map_y + size_y / 2;
00237 
00238         if (start_x < min_i)
00239           start_x = min_i;
00240         if (end_x > max_i)
00241           end_x = max_i;
00242         if (start_y < min_j)
00243           start_y = min_j;
00244         if (end_y > max_j)
00245           end_y = max_j;
00246 
00247         for(int j = start_y; j < end_y; j++)
00248         {
00249           for(int i = start_x; i < end_x; i++)
00250           {
00251             unsigned char old_cost = costmap->getCost(i, j);
00252 //            unsigned char old_cost = costmap->getCost(map_x, map_y);
00253 
00254             if(old_cost == costmap_2d::NO_INFORMATION)
00255               continue;
00256 
00257             costmap->setCost(i, j, costmap_2d::LETHAL_OBSTACLE);
00258           }
00259         }
00260 
00261         //=============================================================================================
00262         /* int map_x, map_y;
00263       costmap->worldToMapNoBounds(pt.x, pt.y, map_x, map_y);
00264 
00265       int start_x = 0, start_y = 0, end_x = size, end_y = size;
00266 
00267       if(map_x < 0)
00268         start_x = -map_x;
00269       else if(map_x + size > costmap->getSizeInCellsX())
00270         end_x = std::max(0, (int)costmap->getSizeInCellsX() - map_x);
00271 
00272       if((int)(start_x+map_x) < min_i)
00273         start_x = min_i - map_x;
00274 
00275       if((int)(end_x+map_x) > max_i)
00276         end_x = max_i - map_x;
00277 
00278       if(map_y < 0)
00279         start_y = -map_y;
00280       else if(map_y + size > costmap->getSizeInCellsY())
00281         end_y = std::max(0, (int) costmap->getSizeInCellsY() - map_y);
00282 
00283       if((int)(start_y+map_y) < min_j)
00284         start_y = min_j - map_y;
00285 
00286       if((int)(end_y+map_y) > max_j)
00287         end_y = max_j - map_y;
00288 
00289       // Set cost for costmap poles
00290       for(int i = start_x; i < end_x; i++)
00291       {
00292         for(int j = start_y; j < end_y; j++)
00293         {
00294           unsigned char old_cost = costmap->getCost(i + map_x, j + map_y);
00295 
00296           //if(old_cost == costmap_2d::NO_INFORMATION)
00297             //continue;
00298 
00299           costmap->setCost(i + map_x, j + map_y, costmap_2d::LETHAL_OBSTACLE);
00300         }
00301       }*/
00302       }
00303     }
00304   }
00305 } // end of namespace
00306 //=================================================================================================
00307 //=================================================================================================


nav_layer_from_points
Author(s): Michal Drwiega
autogenerated on Thu Jun 6 2019 22:10:55