00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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>
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
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
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
00113 set<Cell> intersectingCells (const nm::MapMetaData& info, const nm::MapMetaData& info2, const Cell& cell2)
00114 {
00115
00116 const gm::Polygon poly=expandPolygon(cellPolygon(info2, cell2), 1.0001);
00117
00118
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
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 }
00171
00172
00173
00174