54 m_enable_publish_ros_map =
false;
55 m_enable_subscribe_ros_map =
false;
72 if (Property::copyPortable(b, the_map))
75 auto it = m_maps_storage.find(map_name);
76 if (it == m_maps_storage.end())
79 m_maps_storage[map_name] = the_map;
86 m_maps_storage[map_name] = the_map;
95 yCError(MAP2DSERVER) <<
"Error in copyPortable";
101 auto it = m_maps_storage.find(name);
102 if (it != m_maps_storage.end())
107 Property::copyPortable(it->second, mapbot);
113 yCError(MAP2DSERVER) <<
"Map" << name <<
"not found";
121 for (
auto& it : m_maps_storage)
129 size_t rem = m_maps_storage.erase(name);
132 yCError(MAP2DSERVER) <<
"Map not found";
144 m_maps_storage.clear();
151 if (saveMaps(mapfile))
158 yCError(MAP2DSERVER,
"Unable to save collection");
166 if (loadMaps(mapfile))
173 yCError(MAP2DSERVER,
"Unable to load collection");
180 yCError(MAP2DSERVER,
"Invalid vocab received in Map2DServer");
195 std::map<std::string, Map2DLocation>::iterator it;
196 for (it = m_locations_storage.begin(); it != m_locations_storage.end(); ++it)
200 yCInfo(MAP2DSERVER) <<
"The following locations are currently stored in the server:" << l.
toString();
210 std::map<std::string, Map2DArea>::iterator it;
211 for (it = m_areas_storage.begin(); it != m_areas_storage.end(); ++it)
215 yCInfo(MAP2DSERVER) <<
"The following areas are currently stored in the server:" << l.
toString();
225 std::map<std::string, Map2DPath>::iterator it;
226 for (it = m_paths_storage.begin(); it != m_paths_storage.end(); ++it)
230 yCInfo(MAP2DSERVER) <<
"The following paths are currently stored in the server: " << l.
toString();
235 m_locations_storage.clear();
236 yCInfo(MAP2DSERVER) <<
"All locations deleted";
242 m_areas_storage.clear();
243 yCInfo(MAP2DSERVER) <<
"All areas deleted";
249 m_paths_storage.clear();
250 yCInfo(MAP2DSERVER) <<
"All paths deleted";
258 std::map<std::string, Map2DLocation>::iterator it;
259 it = m_locations_storage.find(name);
260 if (it != m_locations_storage.end())
262 yCInfo(MAP2DSERVER) <<
"Deleted location" << name;
263 m_locations_storage.erase(it);
268 yCError(MAP2DSERVER,
"User requested an invalid location name");
278 std::map<std::string, Map2DPath>::iterator it;
279 it = m_paths_storage.find(name);
280 if (it != m_paths_storage.end())
282 yCInfo(MAP2DSERVER) <<
"Deleted path" << name;
283 m_paths_storage.erase(it);
288 yCError(MAP2DSERVER,
"User requested an invalid location name");
299 std::map<std::string, Map2DLocation>::iterator orig_it;
300 orig_it = m_locations_storage.find(orig_name);
301 std::map<std::string, Map2DLocation>::iterator new_it;
302 new_it = m_locations_storage.find(new_name);
304 if (orig_it != m_locations_storage.end() &&
305 new_it == m_locations_storage.end())
307 yCInfo(MAP2DSERVER) <<
"Location:" << orig_name <<
"renamed to:" << new_name;
308 auto loc = orig_it->second;
309 m_locations_storage.erase(orig_it);
310 m_locations_storage.insert(std::pair<std::string, Map2DLocation>(new_name, loc));
315 yCError(MAP2DSERVER,
"User requested an invalid rename operation");
325 std::map<std::string, Map2DArea>::iterator orig_it;
326 orig_it = m_areas_storage.find(orig_name);
327 std::map<std::string, Map2DArea>::iterator new_it;
328 new_it = m_areas_storage.find(new_name);
330 if (orig_it != m_areas_storage.end() &&
331 new_it == m_areas_storage.end())
333 yCInfo(MAP2DSERVER) <<
"Area:" << orig_name <<
"renamed to:" << new_name;
334 auto area = orig_it->second;
335 m_areas_storage.erase(orig_it);
336 m_areas_storage.insert(std::pair<std::string, Map2DArea>(new_name,area));
341 yCError(MAP2DSERVER,
"User requested an invalid rename operation");
351 std::map<std::string, Map2DPath>::iterator orig_it;
352 orig_it = m_paths_storage.find(orig_name);
353 std::map<std::string, Map2DPath>::iterator new_it;
354 new_it = m_paths_storage.find(new_name);
356 if (orig_it != m_paths_storage.end() &&
357 new_it == m_paths_storage.end())
359 yCInfo(MAP2DSERVER) <<
"Path:" << orig_name <<
"renamed to:" << new_name;
360 auto area = orig_it->second;
361 m_paths_storage.erase(orig_it);
362 m_paths_storage.insert(std::pair<std::string, Map2DPath>(new_name, area));
367 yCError(MAP2DSERVER,
"User requested an invalid rename operation");
376 std::map<std::string, Map2DArea>::iterator it;
377 it = m_areas_storage.find(name);
378 if (it != m_areas_storage.end())
380 yCInfo(MAP2DSERVER) <<
"Deleted area" << name;
381 m_areas_storage.erase(it);
386 yCError(MAP2DSERVER,
"User requested an invalid area name");
396 std::map<std::string, Map2DLocation>::iterator it;
397 it = m_locations_storage.find(name);
398 if (it != m_locations_storage.end())
402 yCInfo(MAP2DSERVER) <<
"Retrieved location" << name <<
"at" << loc.
toString();
411 yCError(MAP2DSERVER,
"User requested an invalid location name");
419 std::map<std::string, Map2DArea>::iterator it;
420 it = m_areas_storage.find(area_name);
421 if (it != m_areas_storage.end())
426 if (Property::copyPortable(areatemp, areabot) ==
false)
428 yCError(MAP2DSERVER) <<
"VOCAB_NAV_GET_X VOCAB_NAV_AREA failed copyPortable()";
433 yCInfo(MAP2DSERVER) <<
"Retrieved area" << area_name <<
"at" << area.
toString();
437 Property::copyPortable(areatemp, areabot);
443 yCError(MAP2DSERVER,
"User requested an invalid area name");
451 std::map<std::string, Map2DPath>::iterator it;
452 it = m_paths_storage.find(path_name);
453 if (it != m_paths_storage.end())
458 if (Property::copyPortable(pathtemp, pathbot) ==
false)
460 yCError(MAP2DSERVER) <<
"VOCAB_NAV_GET_X VOCAB_NAV_PATH failed copyPortable()";
465 yCInfo(MAP2DSERVER) <<
"Retrieved path" << path_name <<
"at" << path.
toString();
469 Property::copyPortable(pathtemp, pathbot);
475 yCError(MAP2DSERVER,
"User requested an invalid path name");
489 m_locations_storage.insert(std::pair<std::string, Map2DLocation>(name, location));
490 yCInfo(MAP2DSERVER) <<
"Added location" << name <<
"at" << location.
toString();
500 if (Property::copyPortable(b, area))
502 m_areas_storage.insert(std::pair<std::string, Map2DArea>(area_name, area));
503 yCInfo(MAP2DSERVER) <<
"Added area" << area_name <<
"at" << area.
toString();
508 yCError(MAP2DSERVER) <<
"VOCAB_NAV_STORE_X VOCAB_NAV_AREA failed copyPortable()";
519 if (Property::copyPortable(b, path))
521 m_paths_storage.insert(std::pair<std::string, Map2DPath>(path_name, path));
522 yCInfo(MAP2DSERVER) <<
"Added path" << path_name <<
"at" << path.
toString();
527 yCError(MAP2DSERVER) <<
"VOCAB_NAV_STORE_X VOCAB_NAV_PATH failed copyPortable()";
557 out.
addString(
"save_locations&areas failed");
568 out.
addString(
"load_locations&areas failed");
573 std::map<std::string, Map2DLocation>::iterator it;
574 for (it = m_locations_storage.begin(); it != m_locations_storage.end(); ++it)
581 std::map<std::string, Map2DArea>::iterator it;
582 for (it = m_areas_storage.begin(); it != m_areas_storage.end(); ++it)
589 std::map<std::string, Map2DPath>::iterator it;
590 for (it = m_paths_storage.begin(); it != m_paths_storage.end(); ++it)
620 std::string map_file = in.
get(2).
asString() +
".map";
621 auto p = m_maps_storage.find(map_name);
622 if (p == m_maps_storage.end())
624 out.
addString(
"save_map failed: map " + map_name +
" not found");
628 bool b = p->second.saveToFile(map_file);
631 out.
addString(map_file +
" successfully saved");
635 out.
addString(
"save_map failed: unable to save " + map_name +
" to "+ map_file);
646 auto p = m_maps_storage.find(map_name);
647 if (p == m_maps_storage.end())
649 m_maps_storage[map_name] = map;
664 std::map<std::string, MapGrid2D>::iterator it;
665 for (it = m_maps_storage.begin(); it != m_maps_storage.end(); ++it)
670 else if(in.
get(0).
asString() ==
"clear_all_locations")
672 m_locations_storage.clear();
675 else if (in.
get(0).
asString() ==
"clear_all_areas")
677 m_areas_storage.clear();
680 else if (in.
get(0).
asString() ==
"clear_all_paths")
682 m_paths_storage.clear();
687 m_maps_storage.clear();
693 out.
addString(
"'save_locations&areas <full path filename>' to save locations and areas on a file");
694 out.
addString(
"'load_locations&areas <full path filename>' to load locations and areas from a file");
695 out.
addString(
"'list_locations' to view a list of all stored locations");
696 out.
addString(
"'list_areas' to view a list of all stored areas");
697 out.
addString(
"'list_paths' to view a list of all stored paths");
698 out.
addString(
"'clear_all_locations' to clear all stored locations");
699 out.
addString(
"'clear_all_areas' to clear all stored areas");
700 out.
addString(
"'clear_all_paths' to clear all stored paths");
701 out.
addString(
"'save_maps <full path>' to save a map collection to a folder");
702 out.
addString(
"'load_maps <full path>' to load a map collection from a folder");
703 out.
addString(
"'save_map <map_name> <full path>' to save a single map");
704 out.
addString(
"'load_map <full path>' to load a single map");
705 out.
addString(
"'list_maps' to view a list of all stored maps");
706 out.
addString(
"'clear_all_maps' to clear all stored maps");
710 out.
addString(
"request not understood, call 'help' to see a list of available commands");
718 std::lock_guard<std::mutex> lock(m_mutex);
721 bool ok = in.
read(connection);
722 if (!ok)
return false;
727 parse_string_command(in, out);
732 parse_vocab_command(in, out);
736 if (returnToSender !=
nullptr)
738 out.
write(*returnToSender);
742 yCError(MAP2DSERVER) <<
"Invalid return to sender";
749 if (m_maps_storage.size() == 0)
751 yCError(MAP2DSERVER) <<
"Map storage is empty";
755 file.open(mapsfile.c_str());
758 yCError(MAP2DSERVER) <<
"Sorry unable to open" << mapsfile;
762 for (
auto& it : m_maps_storage)
764 string map_filename = it.first +
".map";
766 file << map_filename;
768 ret &= it.second.saveToFile(map_filename);
778 file.open(mapsfile.c_str());
781 yCError(MAP2DSERVER) <<
"loadMaps() Unable to open:" << mapsfile;
788 std::getline(file,
buffer);
789 std::istringstream iss(
buffer);
791 if (dummy ==
"")
break;
792 if (dummy ==
"mapfile:")
798 string mapfilenameWithPath = m_rf_mapCollection.findFile(mapfilename);
804 auto p = m_maps_storage.find(map_name);
805 if (p == m_maps_storage.end())
807 if (option ==
"crop")
808 map.
crop(-1,-1,-1,-1);
809 m_maps_storage[map_name] = map;
813 yCError(MAP2DSERVER) <<
"A map with the same name '" << map_name <<
"'was found, skipping...";
819 yCError(MAP2DSERVER) <<
"Problems opening map file" << mapfilenameWithPath;
825 yCError(MAP2DSERVER) <<
"Invalid syntax, missing mapfile tag";
838 string collection_file_name=
"maps_collection.ini";
839 string locations_file_name=
"locations.ini";
840 if (config.
check(
"mapCollectionFile"))
842 collection_file_name= config.
find(
"mapCollectionFile").
asString();
845 if (config.
check(
"mapCollectionContext"))
847 string collection_context_name= config.
find(
"mapCollectionContext").
asString();
848 m_rf_mapCollection.setDefaultContext(collection_context_name.c_str());
849 string collection_file_with_path = m_rf_mapCollection.findFile(collection_file_name);
850 string locations_file_with_path = m_rf_mapCollection.findFile(locations_file_name);
852 if (collection_file_with_path==
"")
854 yCInfo(MAP2DSERVER) <<
"No locations loaded";
858 bool ret = load_locations_and_areas(locations_file_with_path);
859 if (
ret) {
yCInfo(MAP2DSERVER) <<
"Location file" << locations_file_with_path <<
"successfully loaded."; }
860 else {
yCError(MAP2DSERVER) <<
"Problems opening file" << locations_file_with_path; }
863 if (collection_file_with_path==
"")
865 yCError(MAP2DSERVER) <<
"Unable to find file" << collection_file_name <<
"within the specified context:" << collection_context_name;
868 if (loadMaps(collection_file_with_path))
870 yCInfo(MAP2DSERVER) <<
"Map collection file:" << collection_file_with_path <<
"successfully loaded.";
871 if (m_maps_storage.size() > 0)
873 yCInfo(MAP2DSERVER) <<
"Available maps are:";
874 for (
auto& it : m_maps_storage)
876 yCInfo(MAP2DSERVER) << it.first;
881 yCInfo(MAP2DSERVER) <<
"No maps available";
883 if (m_locations_storage.size() > 0)
885 yCInfo(MAP2DSERVER) <<
"Available Locations are:";
886 for (
auto& it : m_locations_storage)
888 yCInfo(MAP2DSERVER) << it.first;
893 yCInfo(MAP2DSERVER) <<
"No locations available";
896 if (m_areas_storage.size() > 0)
898 yCInfo(MAP2DSERVER) <<
"Available areas are:";
899 for (
auto& it : m_areas_storage)
901 yCInfo(MAP2DSERVER) << it.first;
906 yCInfo(MAP2DSERVER) <<
"No areas available";
911 yCError(MAP2DSERVER) <<
"Unable to load map collection file:" << collection_file_with_path;
916 if (!config.
check(
"name"))
918 m_rpcPortName =
"/mapServer/rpc";
926 if (!m_rpcPort.open(m_rpcPortName))
928 yCError(MAP2DSERVER,
"Failed to open port %s", m_rpcPortName.c_str());
931 m_rpcPort.setReader(*
this);
934 if (config.
check(
"ROS"))
936 yCInfo(MAP2DSERVER,
"Configuring ROS params");
938 if (ROS_config.
check(
"enable_ros_publisher") ==
false)
940 yCError(MAP2DSERVER) <<
"Missing 'enable_ros_publisher' in ROS group";
943 if (ROS_config.
find(
"enable_ros_publisher").
asInt32() == 1 || ROS_config.
find(
"enable_ros_publisher").
asString() ==
"true")
945 m_enable_publish_ros_map =
true;
946 yCInfo(MAP2DSERVER) <<
"Enabled ROS publisher";
948 if (ROS_config.
check(
"enable_ros_subscriber") ==
false)
950 yCError(MAP2DSERVER) <<
"Missing 'enable_ros_subscriber' in ROS group";
953 if (ROS_config.
find(
"enable_ros_subscriber").
asInt32() == 1 || ROS_config.
find(
"enable_ros_subscriber").
asString() ==
"true")
955 m_enable_subscribe_ros_map =
true;
956 yCInfo(MAP2DSERVER) <<
"Enabled ROS subscriber";
959 if (m_enable_subscribe_ros_map || m_enable_publish_ros_map)
961 if (m_rosNode ==
nullptr)
965 if (m_enable_publish_ros_map && !m_rosPublisherPort_map.topic(
ROSTOPICNAME_MAP))
967 yCError(MAP2DSERVER) <<
"Unable to publish to" <<
ROSTOPICNAME_MAP <<
"topic, check your YARP-ROS network configuration";
976 if (m_enable_subscribe_ros_map && !m_rosSubscriberPort_map.topic(
ROSTOPICNAME_MAP))
978 yCError(MAP2DSERVER) <<
"Unable to subscribe to " <<
ROSTOPICNAME_MAP <<
" topic, check your YARP-ROS network configuration";
986 m_rosSubscriberPort_map.setStrict();
987 m_rosSubscriberPort_metamap.setStrict();
1000 map_ros = m_rosSubscriberPort_map.
read(
true);
1001 metamap_ros = m_rosSubscriberPort_metamap.
read(
true);
1002 if (map_ros!=
nullptr && metamap_ros!=
nullptr)
1004 yCInfo(MAP2DSERVER) <<
"Received map for ROS";
1005 string map_name =
"ros_map";
1016 double orig_angle = vec[2];
1018 for (
size_t y=0; y< map_ros->
info.
height; y++)
1019 for (
size_t x=0; x< map_ros->
info.
width; x++)
1025 if (occ >= 0 && occ <= 70) map.
setMapFlag(cell, MapGrid2D::MAP_CELL_FREE);
1026 else if (occ >= 71 && occ <= 100) map.
setMapFlag(cell, MapGrid2D::MAP_CELL_WALL);
1027 else map.
setMapFlag(cell, MapGrid2D::MAP_CELL_UNKNOWN);
1029 auto p = m_maps_storage.find(map_name);
1030 if (p == m_maps_storage.end())
1032 yCInfo(MAP2DSERVER) <<
"Added map "<< map_name <<
" to mapServer";
1033 m_maps_storage[map_name] = map;
1041 yCTrace(MAP2DSERVER,
"Close");
1042 if (m_enable_publish_ros_map)
1044 m_rosPublisherPort_map.interrupt();
1045 m_rosPublisherPort_metamap.interrupt();
1046 m_rosPublisherPort_map.close();
1047 m_rosPublisherPort_metamap.close();
1049 if (m_enable_subscribe_ros_map)
1051 m_rosSubscriberPort_map.interrupt();
1052 m_rosSubscriberPort_metamap.interrupt();
1053 m_rosSubscriberPort_map.close();
1054 m_rosSubscriberPort_metamap.close();
1059 bool Map2DServer::priv_load_locations_and_areas_v1(std::ifstream& file)
1062 std::getline(file,
buffer);
1063 if (
buffer !=
"Locations:")
1065 yCError(MAP2DSERVER) <<
"Unable to parse Locations section!";
1071 std::getline(file,
buffer);
1072 if (
buffer ==
"Areas:")
break;
1075 yCError(MAP2DSERVER) <<
"Unexpected End Of File";
1080 size_t bot_size = b.
size();
1083 yCError(MAP2DSERVER) <<
"Unable to parse contents of Areas section!";
1092 m_locations_storage[name] = location;
1097 yCError(MAP2DSERVER) <<
"Unable to parse Areas section!";
1104 std::getline(file,
buffer);
1105 if (file.eof())
break;
1109 size_t bot_size = b.
size();
1113 if (area_size <= 0 || bot_size != area_size * 2 + 3)
1115 yCError(MAP2DSERVER) <<
"Unable to parse contents of Areas section!";
1118 for (
size_t ai = 3; ai < bot_size; ai += 2)
1124 m_areas_storage[name] = area;
1129 bool Map2DServer::priv_load_locations_and_areas_v2(std::ifstream& file)
1132 std::getline(file,
buffer);
1133 if (
buffer !=
"Locations:")
1135 yCError(MAP2DSERVER) <<
"Unable to parse Locations section!";
1141 std::getline(file,
buffer);
1142 if (
buffer ==
"Areas:")
break;
1145 yCError(MAP2DSERVER) <<
"Unexpected End Of File";
1150 size_t bot_size = b.
size();
1153 yCError(MAP2DSERVER) <<
"Unable to parse contents of Areas section!";
1162 m_locations_storage[name] = location;
1167 yCError(MAP2DSERVER) <<
"Unable to parse Areas section!";
1174 std::getline(file,
buffer);
1175 if (file.eof())
break;
1179 size_t bot_size = b.
size();
1183 if (area_size <= 0 || bot_size != area_size * 2 + 3)
1185 yCError(MAP2DSERVER) <<
"Unable to parse contents of Areas section!";
1188 for (
size_t ai = 3; ai < bot_size; ai += 2)
1194 m_areas_storage[name] = area;
1202 file.open (locations_file.c_str());
1206 yCError(MAP2DSERVER) <<
"Unable to open" << locations_file <<
"locations file.";
1212 std::getline(file,
buffer);
1213 if (
buffer !=
"Version:")
1215 yCError(MAP2DSERVER) <<
"Unable to parse Version section!";
1219 std::getline(file,
buffer);
1220 int version = atoi(
buffer.c_str());
1224 if (!priv_load_locations_and_areas_v1(file))
1226 yCError(MAP2DSERVER) <<
"Call to load_locations_and_areas_v1 failed";
1231 else if (version == 2)
1233 if (!priv_load_locations_and_areas_v2(file))
1235 yCError(MAP2DSERVER) <<
"Call to load_locations_and_areas_v2 failed";
1242 yCError(MAP2DSERVER) <<
"Only versions 1,2 supported!";
1249 yCDebug(MAP2DSERVER) <<
"Locations file" << locations_file <<
"loaded, " << m_locations_storage.size() <<
"locations and "<< m_areas_storage.size() <<
" areas available";
1256 file.open (locations_file.c_str());
1260 yCError(MAP2DSERVER) <<
"Unable to open" << locations_file <<
"locations file.";
1269 file <<
"Version: \n";
1273 file <<
"Locations: \n";
1274 std::map<std::string, Map2DLocation>::iterator it;
1275 for (it = m_locations_storage.begin(); it != m_locations_storage.end(); ++it)
1278 file << it->first << s << loc.
map_id << s << loc.
x << s << loc.
y << s << loc.
theta <<
"\n";
1283 file <<
"Areas: \n";
1284 std::map<std::string, Map2DArea>::iterator it2;
1285 for (it2 = m_areas_storage.begin(); it2 != m_areas_storage.end(); ++it2)
1288 file << it2->first << s << area.
map_id << s << area.
points.size() << s;
1289 for (
size_t i = 0; i < area.
points.size(); i++)
1291 file << area.
points[i].x << s;
1292 file << area.
points[i].y << s;
1299 file <<
"Paths: \n";
1300 std::map<std::string, Map2DPath>::iterator it3;
1301 for (it3 = m_paths_storage.begin(); it3 != m_paths_storage.end(); ++it3)
1304 for (
size_t i=0; i<it3->second.size(); i++)
1306 loc = it3->second[i];
1307 file <<
"( " <<loc.
map_id << s << loc.
x << s << loc.
y << s << loc.
theta <<
") ";
1314 yCDebug(MAP2DSERVER) <<
"Locations file" << locations_file <<
"saved.";
1318 bool Map2DServer::updateVizMarkers()
1326 time = (uint64_t)(yarpTimeStamp * 1000000000UL);
1327 nsec_part = (time % 1000000000UL);
1328 sec_part = (time / 1000000000UL);
1329 if (sec_part > std::numeric_limits<unsigned int>::max())
1331 yCWarning(MAP2DSERVER) <<
"Timestamp exceeded the 64 bit representation, resetting it to 0";
1343 std::map<std::string, Map2DLocation>::iterator it;
1345 for (it = m_locations_storage.begin(); it != m_locations_storage.end(); ++it, ++count)
1349 rpy[2] = it->second.theta / 180 * 3.14159265359;
1357 marker.
ns =
"my_namespace";
1376 marker.
text = it->first;
1377 markers.
markers.push_back(marker);
1380 m_rosPublisherPort_markers.write();