combine_grids.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Willow Garage, Inc.
00003  * Copyright (c) 2015-2016, Jiri Horner
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  *     * Redistributions of source code must retain the above copyright
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * 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  *     * Neither the name of the Jiri Horner nor the names of its
00015  *       contributors may be used to endorse or promote products derived from
00016  *       this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028  * POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  */
00031 
00032 
00042 #include <occupancy_grid_utils/combine_grids.h>
00043 #include <boost/bind.hpp>
00044 #include <boost/ref.hpp>
00045 #include <boost/make_shared.hpp> /* used only in deprecated functions */
00046 
00047 namespace occupancy_grid_utils
00048 {
00049 
00050 namespace nm=nav_msgs;
00051 namespace gm=geometry_msgs;
00052 
00053 using boost::bind;
00054 using boost::ref;
00055 using std::vector;
00056 using std::multiset;
00057 using std::set;
00058 using std::min;
00059 using std::max;
00060 
00061 inline Cell point32Cell (const nm::MapMetaData& info, const gm::Point32& p)
00062 {
00063   gm::Point pt;
00064   pt.x = p.x;
00065   pt.y = p.y;
00066   pt.z = p.z;
00067   return pointCell(info, pt);
00068 }
00069 
00070 // Does this cell contain a vertex of this polygon?
00071 inline bool containsVertex (const nm::MapMetaData& info, const Cell& c, const gm::Polygon& poly)
00072 {
00073   BOOST_FOREACH (const gm::Point32& p, poly.points) {
00074     if (point32Cell(info, p)==c)
00075       return true;
00076   }
00077   return false;    
00078 }
00079 
00080 // Do the two cells (on different grids) intersect?
00081 inline bool cellsIntersect (const nm::MapMetaData& info1, const Cell& c1, const nm::MapMetaData& info2, const Cell& c2)
00082 {
00083   const gm::Polygon p1=cellPolygon(info1, c1);
00084   const gm::Polygon p2=cellPolygon(info2, c2);
00085   return containsVertex(info1, c1, p2) || containsVertex(info2, c2, p1);
00086 }
00087 
00088 inline gm::Polygon expandPolygon(const gm::Polygon& p, const double r)
00089 {
00090   double sx=0;
00091   double sy=0;
00092   double sz=0;
00093   const size_t n = p.points.size();
00094   for (unsigned i=0; i<n; i++) {
00095     sx += p.points[i].x;
00096     sy += p.points[i].y;
00097     sz += p.points[i].z;
00098   }
00099   sx /= n;
00100   sy /= n;
00101   sz /= n;
00102   gm::Polygon p2;
00103   p2.points.resize(n);
00104   for (unsigned i=0; i<n; i++) {
00105     p2.points[i].x = sx + r*(p.points[i].x-sx);
00106     p2.points[i].y = sy + r*(p.points[i].y-sy);
00107     p2.points[i].z = sz + r*(p.points[i].z-sz);
00108   }
00109   return p2;
00110 }
00111 
00112 // Return set of intersecting cells in grid info, of cell cell2 in info2
00113 set<Cell> intersectingCells (const nm::MapMetaData& info, const nm::MapMetaData& info2, const Cell& cell2)
00114 {
00115   // The expansion is to avoid weird effects due to rounding when intersecting parallel grids
00116   const gm::Polygon poly=expandPolygon(cellPolygon(info2, cell2), 1.0001);
00117 
00118   // Figure out the candidates
00119   vector<Cell> corners(4);
00120   transform(poly.points.begin(), poly.points.end(), corners.begin(), 
00121             bind(point32Cell, boost::ref(info), _1));
00122   const coord_t min_x=min(corners[0].x, min(corners[1].x, min(corners[2].x, corners[3].x)));
00123   const coord_t min_y=min(corners[0].y, min(corners[1].y, min(corners[2].y, corners[3].y)));
00124   const coord_t max_x=max(corners[0].x, max(corners[1].x, max(corners[2].x, corners[3].x)));
00125   const coord_t max_y=max(corners[0].y, max(corners[1].y, max(corners[2].y, corners[3].y)));
00126   
00127   set<Cell> cells;
00128   for (coord_t x=min_x; x<=max_x; x++) {
00129     for (coord_t y=min_y; y<=max_y; y++) {
00130       const Cell candidate(x, y);
00131       if (withinBounds(info, candidate) &&
00132           cellsIntersect(info, candidate, info2, cell2))
00133         cells.insert(candidate);
00134     }
00135   }
00136 
00137   return cells;
00138 }
00139 
00140 gm::Pose transformPose (const tf::Pose trans, const gm::Pose p)
00141 {
00142   tf::Pose pose;
00143   tf::poseMsgToTF(p, pose);
00144   gm::Pose transformed;
00145   tf::poseTFToMsg(trans*pose, transformed);
00146   return transformed;
00147 }
00148 
00149 /* deprecated functions */
00150 
00151 nav_msgs::OccupancyGrid::Ptr combineGrids(const std::vector<nav_msgs::OccupancyGrid::ConstPtr>& grids, double resolution) {
00152   vector<boost::reference_wrapper<nav_msgs::OccupancyGrid const> > grids_refs;
00153   grids_refs.reserve(grids.size());
00154   nav_msgs::OccupancyGrid::Ptr result = boost::make_shared<nm::OccupancyGrid>();
00155 
00156   BOOST_FOREACH (const nav_msgs::OccupancyGrid::ConstPtr& g, grids) {
00157     grids_refs.push_back(boost::cref(*(g.get())));
00158   }
00159 
00160   combineGrids(grids_refs.begin(), grids_refs.end(), resolution, *result);
00161 
00162   return result;
00163 }
00164 
00165 nav_msgs::OccupancyGrid::Ptr combineGrids(const std::vector<nav_msgs::OccupancyGrid::ConstPtr>& grids) {
00166   ROS_ASSERT (!grids.empty());
00167   return combineGrids(grids, grids[0]->info.resolution);
00168 }
00169 
00170 } // namespace occupancy_grid_utils
00171 
00172 
00173 
00174 


map_merge
Author(s): Jiri Horner
autogenerated on Sun Mar 26 2017 03:48:10