38 #define USAGE "\nUSAGE: map_server <map.yaml>\n" \
39 " map.yaml: map description file\n" \
40 "DEPRECATED USAGE: map_server <map> <resolution>\n" \
41 " map: image file to load\n"\
42 " resolution: map resolution [meters/pixel]"
48 #include <boost/filesystem.hpp>
51 #include "ros/console.h"
53 #include "nav_msgs/MapMetaData.h"
54 #include "yaml-cpp/yaml.h"
55 #include "rapp_platform_ros_communications/MapServerGetMapRosSrv.h"
56 #include "rapp_platform_ros_communications/MapServerUploadMapRosSrv.h"
57 #include "std_srvs/Empty.h"
60 #include <sys/types.h>
64 #ifdef HAVE_NEW_YAMLCPP
68 void operator >> (
const YAML::Node& node, T& i)
80 if ((
homedir = getenv(
"HOME")) == NULL) {
81 homedir = getpwuid(getuid())->pw_dir;
83 map_pub =
n.advertise<nav_msgs::OccupancyGrid>(
"/map", 1,
true);
86 std::string node_name = ros::this_node::getName();
102 metadata_pub=
n.advertise<nav_msgs::MapMetaData>(
"map_metadata", 1,
true);
121 bool mapUploadCallback(rapp_platform_ros_communications::MapServerUploadMapRosSrv::Request &req,
122 rapp_platform_ros_communications::MapServerUploadMapRosSrv::Response &res)
125 YAML::Node yaml_node;
126 yaml_node[
"image"] = req.map_name+
".png";
127 yaml_node[
"resolution"] = req.resolution;
128 yaml_node[
"origin"] = req.origin;
129 yaml_node[
"negate"] = req.negate;
130 yaml_node[
"occupied_thresh"] = req.occupied_thresh;
133 std::ostringstream ss;
134 yaml_node[
"free_thresh"] = req.free_thresh;
136 std::string user = req.user_name;
137 std::string map = req.map_name;
138 std::string homedir_str =
homedir;
139 std::string map_path = homedir_str+
"/rapp_platform_files/maps/"+user;
141 boost::filesystem::create_directories(map_path);
142 std::string yaml_path = map_path+
"/"+map+
".yaml";
143 std::ofstream fout(yaml_path.c_str());
145 std::string png_path = map_path+
"/"+map+
".png";
147 std::ofstream outfile (png_path.c_str(),std::ofstream::binary);
149 char* buffer =
reinterpret_cast<char*
>(req.data.data());
150 long size = strlen(buffer);
152 ROS_INFO_STREAM (
"User: "<<user<<
" saved map: "<< png_path <<
"\n size of the map: " << req.file_size <<
" bytes" );
154 outfile.write (buffer,req.file_size);
162 bool mapCallback(rapp_platform_ros_communications::MapServerGetMapRosSrv::Request &req,
163 rapp_platform_ros_communications::MapServerGetMapRosSrv::Response &res )
166 std::string node_name = ros::this_node::getName();
167 std::string param_name = node_name+
"/setMap";
169 const char * param_name_char = param_name.c_str();
171 if (
n.hasParam(param_name_char)){
172 n.getParam(param_name_char,
fname);
179 std::string mapfname =
"";
182 double occ_th, free_th;
184 std::string frame_id;
185 ros::NodeHandle private_nh(
"~");
186 private_nh.param(
"frame_id", frame_id, std::string(
"map"));
189 std::ifstream fin(fname.c_str());
191 ROS_ERROR(
"Map_server could not open %s.", fname.c_str());
194 #ifdef HAVE_NEW_YAMLCPP
196 YAML::Node doc = YAML::Load(fin);
198 YAML::Parser parser(fin);
200 parser.GetNextDocument(doc);
203 doc[
"resolution"] >> res;
204 }
catch (YAML::InvalidScalar) {
205 ROS_ERROR(
"The map does not contain a resolution tag or it is invalid.");
209 doc[
"negate"] >> negate;
210 }
catch (YAML::InvalidScalar) {
211 ROS_ERROR(
"The map does not contain a negate tag or it is invalid.");
215 doc[
"occupied_thresh"] >> occ_th;
216 }
catch (YAML::InvalidScalar) {
217 ROS_ERROR(
"The map does not contain an occupied_thresh tag or it is invalid.");
221 doc[
"free_thresh"] >> free_th;
222 }
catch (YAML::InvalidScalar) {
223 ROS_ERROR(
"The map does not contain a free_thresh tag or it is invalid.");
227 doc[
"trinary"] >> trinary;
228 }
catch (YAML::Exception) {
229 ROS_DEBUG(
"The map does not contain a trinary tag or it is invalid... assuming true");
233 doc[
"origin"][0] >> origin[0];
234 doc[
"origin"][1] >> origin[1];
235 doc[
"origin"][2] >> origin[2];
236 }
catch (YAML::InvalidScalar) {
237 ROS_ERROR(
"The map does not contain an origin tag or it is invalid.");
241 doc[
"image"] >> mapfname;
243 if(mapfname.size() == 0)
245 ROS_ERROR(
"The image tag cannot be an empty string.");
248 if(mapfname[0] !=
'/')
251 char* fname_copy = strdup(fname.c_str());
252 mapfname = std::string(dirname(fname_copy)) +
'/' + mapfname;
255 }
catch (YAML::InvalidScalar) {
256 ROS_ERROR(
"The map does not contain an image tag or it is invalid.");
260 private_nh.param(
"negate", negate, 0);
261 private_nh.param(
"occupied_thresh", occ_th, 0.65);
262 private_nh.param(
"free_thresh", free_th, 0.196);
264 origin[0] = origin[1] = origin[2] = 0.0;
267 ROS_INFO(
"Loading map from image \"%s\"", mapfname.c_str());
270 map_resp_.map.info.map_load_time = ros::Time::now();
271 map_resp_.map.header.frame_id = frame_id;
272 map_resp_.map.header.stamp = ros::Time::now();
273 ROS_INFO(
"Read a %d X %d map @ %.3lf m/cell",
288 int main(
int argc,
char **argv)
290 ros::init(argc, argv,
"map_server");
291 if(argc != 3 && argc != 2)
293 ROS_ERROR(
"%s",
USAGE);
297 ROS_WARN(
"Using deprecated map server interface. Please switch to new interface.");
299 std::string fname(argv[1]);
300 double res = (argc == 2) ? 0.0 : atof(argv[2]);
308 catch(std::runtime_error& e)
310 ROS_ERROR(
"map_server exception: %s", e.what());
ros::Publisher metadata_pub
MapServer(std::string fname)
int main(int argc, char **argv)
bool updateMap(const std::string fname, double res)
nav_msgs::MapMetaData meta_data_message_
void loadMapFromFile(nav_msgs::GetMap::Response *resp, const char *fname, double res, bool negate, double occ_th, double free_th, double *origin, bool trinary=true)
nav_msgs::GetMap::Response map_resp_
bool mapUploadCallback(rapp_platform_ros_communications::MapServerUploadMapRosSrv::Request &req, rapp_platform_ros_communications::MapServerUploadMapRosSrv::Response &res)
ros::ServiceServer test_service
ros::ServiceServer upload_service
ros::ServiceServer get_service
std::string upload_map_trigger_name
bool mapCallback(rapp_platform_ros_communications::MapServerGetMapRosSrv::Request &req, rapp_platform_ros_communications::MapServerGetMapRosSrv::Response &res)