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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include <mongo_ros/message_collection.h>
00052 #include <ros/ros.h>
00053 #include <nav_msgs/OccupancyGrid.h>
00054 #include <map_store/ListMaps.h>
00055 #include <map_store/PublishMap.h>
00056 #include <map_store/DeleteMap.h>
00057 #include <map_store/RenameMap.h>
00058 #include <map_store/MapListEntry.h>
00059 #include <nav_msgs/GetMap.h>
00060
00061 #include <string>
00062 #include <sstream>
00063 #include <exception>
00064 namespace mr=mongo_ros;
00065
00066 mr::MessageCollection<nav_msgs::OccupancyGrid> *map_collection;
00067 ros::Publisher map_publisher;
00068 std::string last_map;
00069
00070 typedef std::vector<mr::MessageWithMetadata<nav_msgs::OccupancyGrid>::ConstPtr> MapVector;
00071
00072 bool listMaps(map_store::ListMaps::Request &request,
00073 map_store::ListMaps::Response &response)
00074 {
00075 rospy.logdebug("listMaps() service call");
00076
00077 MapVector all_maps;
00078 all_maps = map_collection->pullAllResults( mr::Query(), true, "creation_time", false );
00079
00080
00081 for(MapVector::const_iterator map_iter = all_maps.begin(); map_iter != all_maps.end(); map_iter++)
00082 {
00083 rospy.logdebug("listMaps() reading a map");
00084
00085 rospy.logdebug("listMaps() adding a map to the result list.");
00086 rospy.logdebug("listMaps() metadata is: '%s'", (*map_iter)->metadata.toString().c_str());
00087
00088
00089 map_store::MapListEntry new_entry;
00090 new_entry.name = (*map_iter)->lookupString("name");
00091 new_entry.date = (int64_t)(*map_iter)->lookupDouble("creation_time");
00092 new_entry.session_id = (*map_iter)->lookupString("session_id");
00093 new_entry.map_id = (*map_iter)->lookupString("uuid");
00094
00095 response.map_list.push_back(new_entry);
00096 }
00097
00098 rospy.logdebug("listMaps() service call done");
00099 return true;
00100 }
00101
00102 bool lookupMap(std::string name, nav_msgs::OccupancyGridConstPtr &ptr) {
00103 MapVector matching_maps;
00104 try
00105 {
00106 matching_maps = map_collection->pullAllResults(mr::Query("uuid", name), false );
00107 } catch(const std::exception &e) {
00108 rospy.logerr("Error during query: %s", e.what());
00109 return false;
00110 }
00111
00112 if (matching_maps.size() != 1)
00113 {
00114 rospy.logerr("publishMap() found %d matching maps instead of 1. Failing.", (int) matching_maps.size());
00115 return false;
00116 }
00117 ptr = nav_msgs::OccupancyGridConstPtr( matching_maps[0] );
00118 return true;
00119 }
00120
00121 bool publishMap(map_store::PublishMap::Request &request,
00122 map_store::PublishMap::Response &response)
00123 {
00124 rospy.logdebug("publishMap() service call");
00125 rospy.logdebug("Searching for '%s'", request.map_id.c_str());
00126
00127 last_map = request.map_id;
00128 ros::NodeHandle nh;
00129 nh.setParam("last_map_id", last_map);
00130 nav_msgs::OccupancyGridConstPtr map;
00131 if (lookupMap(request.map_id, map))
00132 {
00133 try {
00134 map_publisher.publish(map);
00135 } catch(...) {
00136 rospy.logerr("Error publishing map");
00137 }
00138 }
00139 else
00140 {
00141 return false;
00142 }
00143
00144 return true;
00145 }
00146
00147 bool deleteMap(map_store::DeleteMap::Request &request,
00148 map_store::DeleteMap::Response &response)
00149 {
00150 ros::NodeHandle nh;
00151 std::string param;
00152 if (nh.getParam("last_map_id", param))
00153 {
00154 if (param == request.map_id)
00155 {
00156 nh.deleteParam("last_map_id");
00157 }
00158 }
00159 if (last_map == request.map_id)
00160 {
00161 last_map = "";
00162 }
00163 return map_collection->removeMessages(mr::Query("uuid", request.map_id)) == 1;
00164 }
00165
00166 bool renameMap(map_store::RenameMap::Request &request,
00167 map_store::RenameMap::Response &response)
00168 {
00169 map_collection->modifyMetadata(mr::Query("uuid", request.map_id), mr::Metadata("name", request.new_name));
00170 return true;
00171 }
00172
00173
00174 bool dynamicMap(nav_msgs::GetMap::Request &request,
00175 nav_msgs::GetMap::Response &response) {
00176 if (last_map == "") {
00177 return false;
00178 }
00179 nav_msgs::OccupancyGridConstPtr map;
00180 if (lookupMap(last_map, map))
00181 {
00182 response.map = *map;
00183 }
00184 else
00185 {
00186 return false;
00187 }
00188 return true;
00189 }
00190
00191 int main (int argc, char** argv)
00192 {
00193 ros::init(argc, argv, "map_manager");
00194 ros::NodeHandle nh;
00195
00196 map_collection = new mr::MessageCollection<nav_msgs::OccupancyGrid>("map_store", "maps");
00197 map_collection->ensureIndex("uuid");
00198
00199 if (!nh.getParam("last_map_id", last_map))
00200 {
00201 last_map = "";
00202 }
00203
00204
00205 map_publisher = nh.advertise<nav_msgs::OccupancyGrid>("map", 1, true);
00206 if (last_map != "")
00207 {
00208 nav_msgs::OccupancyGridConstPtr map;
00209 if (lookupMap(last_map, map))
00210 {
00211 try {
00212 map_publisher.publish(map);
00213 } catch(...) {
00214 rospy.logerr("Error publishing map");
00215 }
00216 }
00217 else
00218 {
00219 rospy.logerr("Invalid last_map_id");
00220 }
00221 }
00222
00223 ros::ServiceServer list_maps_service = nh.advertiseService("list_maps", listMaps);
00224 ros::ServiceServer publish_map_service = nh.advertiseService("publish_map", publishMap);
00225 ros::ServiceServer delete_map_service = nh.advertiseService("delete_map", deleteMap);
00226 ros::ServiceServer rename_map_service = nh.advertiseService("rename_map", renameMap);
00227 ros::ServiceServer dynamic_map = nh.advertiseService("dynamic_map", dynamicMap);
00228
00229 rospy.logdebug("spinning.");
00230
00231 ros::spin();
00232
00233 delete map_collection;
00234
00235 return 0;
00236 }