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
00033
00034
00035
00036
00037 #include <costmap_2d/costmap_2d_publisher.h>
00038 #include <geometry_msgs/PolygonStamped.h>
00039
00040 namespace costmap_2d {
00041 Costmap2DPublisher::Costmap2DPublisher(ros::NodeHandle ros_node, double publish_frequency, std::string global_frame)
00042 : global_frame_(global_frame), visualizer_thread_(NULL), active_(false), new_data_(false), resolution_(0.0), visualizer_thread_shutdown_(false){
00043
00044 obs_pub_ = ros_node.advertise<nav_msgs::GridCells>("obstacles", 1);
00045 inf_obs_pub_ = ros_node.advertise<nav_msgs::GridCells>("inflated_obstacles", 1);
00046 unknown_space_pub_ = ros_node.advertise<nav_msgs::GridCells>("unknown_space", 1);
00047 footprint_pub_ = ros_node.advertise<geometry_msgs::PolygonStamped>("robot_footprint", 1);
00048
00049 visualizer_thread_ = new boost::thread(boost::bind(&Costmap2DPublisher::mapPublishLoop, this, publish_frequency));
00050 }
00051
00052 Costmap2DPublisher::~Costmap2DPublisher(){
00053 visualizer_thread_shutdown_ = true;
00054 if(visualizer_thread_ != NULL){
00055 visualizer_thread_->join();
00056 delete visualizer_thread_;
00057 }
00058 }
00059
00060 void Costmap2DPublisher::mapPublishLoop(double frequency){
00061
00062 if(frequency == 0.0)
00063 return;
00064
00065 active_ = true;
00066 ros::NodeHandle n;
00067 ros::Rate r(frequency);
00068 while(n.ok() && !visualizer_thread_shutdown_){
00069 ROS_DEBUG("In publish loop new data is: %d", new_data_);
00070
00071 if(new_data_){
00072
00073 ROS_DEBUG("Publishing costmap");
00074 publishCostmap();
00075 new_data_ = false;
00076 ROS_DEBUG("Finished publishing map and set new_data_ to: %d", new_data_);
00077 }
00078
00079 r.sleep();
00080
00081 if(r.cycleTime() > ros::Duration(1 / frequency))
00082 ROS_WARN("Map update loop missed its desired rate of %.4fHz... the loop actually took %.4f seconds", frequency, r.cycleTime().toSec());
00083 }
00084 }
00085
00086 void Costmap2DPublisher::updateCostmapData(const Costmap2D& costmap, const std::vector<geometry_msgs::Point>& footprint, const tf::Stamped<tf::Pose>& global_pose){
00087 std::vector< std::pair<double, double> > raw_obstacles, inflated_obstacles, unknown_space;
00088 for(unsigned int i = 0; i < costmap.getSizeInCellsX(); i++){
00089 for(unsigned int j = 0; j < costmap.getSizeInCellsY(); j++){
00090 double wx, wy;
00091 costmap.mapToWorld(i, j, wx, wy);
00092 std::pair<double, double> p(wx, wy);
00093
00094
00095 if(costmap.getCost(i, j) == costmap_2d::LETHAL_OBSTACLE)
00096 raw_obstacles.push_back(p);
00097 else if(costmap.getCost(i, j) == costmap_2d::INSCRIBED_INFLATED_OBSTACLE)
00098 inflated_obstacles.push_back(p);
00099 else if(costmap.getCost(i, j) == costmap_2d::NO_INFORMATION)
00100 unknown_space.push_back(p);
00101 }
00102 }
00103 lock_.lock();
00104 resolution_ = costmap.getResolution();
00105 raw_obstacles_ = raw_obstacles;
00106 inflated_obstacles_ = inflated_obstacles;
00107 unknown_space_ = unknown_space;
00108 inscribed_radius_ = costmap.getInscribedRadius();
00109 footprint_ = footprint;
00110 global_pose_ = global_pose;
00111
00112
00113 new_data_ = true;
00114 ROS_DEBUG("Set new_data_ to: %d", new_data_);
00115
00116 lock_.unlock();
00117
00118
00119 publishFootprint();
00120 }
00121
00122 void Costmap2DPublisher::publishFootprint(){
00123 std::vector<geometry_msgs::Point> footprint;
00124
00125 lock_.lock();
00126 footprint = footprint_;
00127 lock_.unlock();
00128
00129
00130 geometry_msgs::PolygonStamped footprint_poly;
00131 footprint_poly.header.frame_id = global_frame_;
00132 footprint_poly.header.stamp = ros::Time::now();
00133
00134
00135 if(footprint.size() < 3){
00136 double angle = 0;
00137 double step = 2 * M_PI / 72;
00138 while(angle < 2 * M_PI){
00139 geometry_msgs::Point32 pt;
00140 pt.x = inscribed_radius_ * cos(angle) + global_pose_.getOrigin().x();
00141 pt.y = inscribed_radius_ * sin(angle) + global_pose_.getOrigin().y();
00142 pt.z = 0.0;
00143 footprint_poly.polygon.points.push_back(pt);
00144 angle += step;
00145 }
00146 }
00147 else{
00148 footprint_poly.polygon.points.resize(footprint.size());
00149
00150 for(unsigned int i = 0; i < footprint.size(); ++i){
00151 footprint_poly.polygon.points[i].x = footprint[i].x;
00152 footprint_poly.polygon.points[i].y = footprint[i].y;
00153 footprint_poly.polygon.points[i].z = footprint[i].z;
00154 }
00155 }
00156
00157 ROS_DEBUG("Publishing footprint");
00158 footprint_pub_.publish(footprint_poly);
00159 }
00160
00161 void Costmap2DPublisher::publishCostmap(){
00162 std::vector< std::pair<double, double> > raw_obstacles, inflated_obstacles, unknown_space;
00163 double resolution;
00164
00165 lock_.lock();
00166 raw_obstacles = raw_obstacles_;
00167 inflated_obstacles = inflated_obstacles_;
00168 unknown_space = unknown_space_;
00169 resolution = resolution_;
00170 lock_.unlock();
00171
00172 unsigned int point_count = raw_obstacles.size();
00173
00174
00175 nav_msgs::GridCells obstacle_cells;
00176 obstacle_cells.header.frame_id = global_frame_;
00177 obstacle_cells.header.stamp = ros::Time::now();
00178
00179
00180 obstacle_cells.cell_width = resolution;
00181 obstacle_cells.cell_height = resolution;
00182
00183
00184 obstacle_cells.cells.resize(point_count);
00185
00186 for(unsigned int i=0;i<point_count;i++){
00187 obstacle_cells.cells[i].x = raw_obstacles[i].first;
00188 obstacle_cells.cells[i].y = raw_obstacles[i].second;
00189 obstacle_cells.cells[i].z = 0;
00190 }
00191
00192 ROS_DEBUG("Publishing obstacles");
00193 obs_pub_.publish(obstacle_cells);
00194
00195
00196 point_count = inflated_obstacles.size();
00197 obstacle_cells.cells.resize(point_count);
00198
00199 for(unsigned int i=0;i<point_count;i++){
00200 obstacle_cells.cells[i].x = inflated_obstacles[i].first;
00201 obstacle_cells.cells[i].y = inflated_obstacles[i].second;
00202 obstacle_cells.cells[i].z = 0;
00203 }
00204
00205 ROS_DEBUG("Publishing inflated obstacles");
00206 inf_obs_pub_.publish(obstacle_cells);
00207
00208 point_count = unknown_space.size();
00209 obstacle_cells.cells.resize(point_count);
00210
00211 for(unsigned int i=0;i<point_count;i++){
00212 obstacle_cells.cells[i].x = unknown_space[i].first;
00213 obstacle_cells.cells[i].y = unknown_space[i].second;
00214 obstacle_cells.cells[i].z = 0;
00215 }
00216
00217 ROS_DEBUG("Publishing unknown space");
00218 unknown_space_pub_.publish(obstacle_cells);
00219
00220 }
00221
00222 };