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
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
00109 if(!transformed_points_.empty())
00110 clearTransformedPoints();
00111
00112
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
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
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
00230
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
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
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 }
00303 }
00304 }
00305 }
00306
00307