Go to the documentation of this file.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 <fstream>
00038
00039 #include <youbot_overhead_localization/plannerMapServer.h>
00040
00041
00042 #include <opencv2/imgproc/imgproc.hpp>
00043
00044 using namespace std;
00045
00046 plannerMapServer::plannerMapServer()
00047 {
00048 mapfname = "";
00049 std::string fname;
00050 n.getParam("/planner_map_server/map_file_yaml", fname);
00051 n.param("frameID", frameID, std::string("map"));
00052
00053 std::ifstream fin(fname.c_str());
00054 if (fin.fail())
00055 {
00056 ROS_ERROR("Map_server could not open %s.", fname.c_str());
00057 exit(-1);
00058 }
00059 YAML::Parser parser(fin);
00060 YAML::Node doc;
00061 parser.GetNextDocument(doc);
00062 try
00063 {
00064 doc["resolution"] >> resolution;
00065 }
00066 catch (YAML::InvalidScalar &)
00067 {
00068 ROS_ERROR("The map does not contain a resolution tag or it is invalid.");
00069 exit(-1);
00070 }
00071 try
00072 {
00073 doc["negate"] >> negate;
00074 }
00075 catch (YAML::InvalidScalar &)
00076 {
00077 ROS_ERROR("The map does not contain a negate tag or it is invalid.");
00078 exit(-1);
00079 }
00080 try
00081 {
00082 doc["occupied_thresh"] >> occThresh;
00083 }
00084 catch (YAML::InvalidScalar &)
00085 {
00086 ROS_ERROR("The map does not contain an occupied_thresh tag or it is invalid.");
00087 exit(-1);
00088 }
00089 try
00090 {
00091 doc["free_thresh"] >> freeThresh;
00092 }
00093 catch (YAML::InvalidScalar &)
00094 {
00095 ROS_ERROR("The map does not contain a free_thresh tag or it is invalid.");
00096 exit(-1);
00097 }
00098 try
00099 {
00100 doc["origin"][0] >> origin[0];
00101 doc["origin"][1] >> origin[1];
00102 doc["origin"][2] >> origin[2];
00103 }
00104 catch (YAML::InvalidScalar &)
00105 {
00106 ROS_ERROR("The map does not contain an origin tag or it is invalid.");
00107 exit(-1);
00108 }
00109
00110 service = n.advertiseService("static_map", &plannerMapServer::mapCallback, this);
00111
00112
00113 metadataPublisher = n.advertise<nav_msgs::MapMetaData>("map_metadata", 1, true);
00114 metadataPublisher.publish(metaDataMessage);
00115
00116
00117 mapPublisher = n.advertise<nav_msgs::OccupancyGrid>("/map", 1, true);
00118
00119
00120 mapImageSubscriber = n.subscribe("/image_calibration/image_cal", 1, &plannerMapServer::mapUpdateCallback, this);
00121 }
00122
00123 void plannerMapServer::mapUpdateCallback(const sensor_msgs::Image& mapImg)
00124 {
00125 cv_bridge::CvImagePtr cvPtr = cv_bridge::toCvCopy(mapImg, "bgr8");
00126 cv::flip(cvPtr->image, cvPtr->image, 0);
00127 loadMapFromMat(&mapResponse, &cvPtr->image, resolution, negate, occThresh, freeThresh, origin);
00128
00129 mapResponse.map.info.map_load_time = ros::Time::now();
00130 mapResponse.map.header.frame_id = frameID;
00131 mapResponse.map.header.stamp = ros::Time::now();
00132 metaDataMessage = mapResponse.map.info;
00133
00134 metadataPublisher.publish(metaDataMessage);
00135 mapPublisher.publish(mapResponse.map);
00136 }
00137
00138 bool plannerMapServer::mapCallback(nav_msgs::GetMap::Request &req, nav_msgs::GetMap::Response &res)
00139 {
00140
00141 res = mapResponse;
00142 ROS_INFO("Sending map");
00143
00144 return true;
00145 }
00146
00147 void plannerMapServer::loadMapFromMat(nav_msgs::GetMap::Response* resp, cv::Mat *opencvimg, double res, bool negate,
00148 double occThresh, double freeThresh, double* origin)
00149 {
00150 unsigned char* pixels;
00151 unsigned char* p;
00152 int rowstride, n_channels;
00153 unsigned int i, j;
00154 int k;
00155 double occ;
00156 int color_sum;
00157 double color_avg;
00158
00159
00160 resp->map.info.width = opencvimg->cols;
00161 resp->map.info.height = opencvimg->rows;
00162 resp->map.info.resolution = res;
00163 resp->map.info.origin.position.x = *(origin);
00164 resp->map.info.origin.position.y = *(origin + 1);
00165 resp->map.info.origin.position.z = 0.0;
00166 tf::Quaternion q;
00167 q.setRPY(0, 0, *(origin + 2));
00168 resp->map.info.origin.orientation.x = q.x();
00169 resp->map.info.origin.orientation.y = q.y();
00170 resp->map.info.origin.orientation.z = q.z();
00171 resp->map.info.origin.orientation.w = q.w();
00172
00173
00174 resp->map.data.resize(resp->map.info.width * resp->map.info.height);
00175
00176
00177 rowstride = opencvimg->step;
00178 n_channels = opencvimg->channels();
00179
00180
00181 pixels = (unsigned char*)(opencvimg->data);
00182 for (j = 0; j < resp->map.info.height; j++)
00183 {
00184 for (i = 0; i < resp->map.info.width; i++)
00185 {
00186
00187 p = pixels + j * rowstride + i * n_channels;
00188 color_sum = 0;
00189 for (k = 0; k < n_channels; k++)
00190 color_sum += *(p + (k));
00191 color_avg = color_sum / (double)n_channels;
00192
00193
00194
00195 if (negate)
00196 occ = color_avg / 255.0;
00197 else
00198 occ = (255 - color_avg) / 255.0;
00199
00200
00201
00202
00203 if (occ > occThresh)
00204 resp->map.data[MAP_IDX(resp->map.info.width,i,resp->map.info.height - j - 1)] = +100;
00205 else if (occ < freeThresh)
00206 resp->map.data[MAP_IDX(resp->map.info.width,i,resp->map.info.height - j - 1)] = 0;
00207 else
00208 resp->map.data[MAP_IDX(resp->map.info.width,i,resp->map.info.height - j - 1)] = -1;
00209 }
00210 }
00211 }
00212
00216 int main(int argc, char **argv)
00217 {
00218 ros::init(argc, argv, "planner_map_server");
00219
00220 plannerMapServer ms;
00221
00222 ros::Rate loopRate(30);
00223 while (ros::ok())
00224 {
00225 ros::spinOnce();
00226 loopRate.sleep();
00227 }
00228
00229 return 0;
00230 }
00231