29 #include "rtabmap_ros/MapData.h" 32 #include "rtabmap_ros/GetMap.h" 45 #include <nav_msgs/OccupancyGrid.h> 46 #include <std_srvs/Empty.h> 48 #ifdef WITH_OCTOMAP_MSGS 49 #ifdef RTABMAP_OCTOMAP 50 #include <octomap_msgs/GetOctomap.h> 63 localGridsRegenerated_(
false)
68 std::string configPath;
69 pnh.
param(
"config_path", configPath, configPath);
70 pnh.
param(
"regenerate_local_grids", localGridsRegenerated_, localGridsRegenerated_);
79 if(!configPath.empty())
87 for(ParametersMap::iterator iter=parameters.begin(); iter!=parameters.end(); ++iter)
89 ParametersMap::iterator jter = allParameters.find(iter->first);
90 if(jter!=allParameters.end())
92 iter->second = jter->second;
98 ROS_ERROR(
"Config file \"%s\" not found!", configPath.c_str());
101 for(rtabmap::ParametersMap::iterator iter=parameters.begin(); iter!=parameters.end(); ++iter)
112 else if(pnh.
getParam(iter->first, vBool))
117 else if(pnh.
getParam(iter->first, vDouble))
122 else if(pnh.
getParam(iter->first, vInt))
130 for(rtabmap::ParametersMap::iterator iter=argParameters.begin(); iter!=argParameters.end(); ++iter)
132 rtabmap::ParametersMap::iterator jter = parameters.find(iter->first);
133 if(jter!=parameters.end())
136 jter->second = iter->second;
148 if(iter->second.first && parameters.find(iter->second.second) != parameters.end())
151 parameters.at(iter->second.second)= vStr;
152 ROS_WARN(
"%s: Parameter name changed: \"%s\" -> \"%s\". Please update your launch file accordingly. Value \"%s\" is still set to the new parameter name.",
157 if(iter->second.second.empty())
159 ROS_ERROR(
"%s: Parameter \"%s\" doesn't exist anymore!",
164 ROS_ERROR(
"%s: Parameter \"%s\" doesn't exist anymore! You may look at this similar parameter: \"%s\"",
172 for(ParametersMap::iterator iter=parameters.begin(); iter!=parameters.end(); ++iter)
174 pnh.
setParam(iter->first, iter->second);
179 mapsManager_.backwardCompatibilityParameters(pnh, parameters);
180 mapsManager_.setParameters(parameters);
183 std::string rtabmapNs;
184 for(std::list<std::string>::iterator iter=splitName.begin(); iter!=splitName.end() && iter!=--splitName.end(); ++iter)
186 if(!rtabmapNs.empty())
192 ROS_INFO(
"Rtabmap namespace is \"%s\", deduced from topic \"%s\"", rtabmapNs.c_str(), nh.
resolveName(
"mapData").c_str());
193 if(rtabmapNs.empty())
195 rtabmapNs =
"get_map_data";
199 rtabmapNs +=
"/get_map_data";
203 getMapSrv.request.global =
false;
204 getMapSrv.request.optimized =
true;
205 getMapSrv.request.graphOnly =
false;
210 ROS_WARN(
"Cannot call \"%s\" service", rtabmapNs.c_str());
214 ROS_INFO(
"Called \"%s\" service, initializing cache...", rtabmapNs.c_str());
215 processMapData(getMapSrv.response.data);
216 ROS_INFO(
"Called \"%s\" service, initializing cache... done! The map" 217 " will be assembled on next subscriber connection.", rtabmapNs.c_str());
222 ROS_WARN(
"Service \"%s\" not available after waiting for 5 seconds, " 223 "may not be a problem if rtabmap is started afterwards. If rtabmap " 224 "is started after in localization mode, call /rtabmap/publish_maps " 225 "service with graph_only=false to make sure map_assembler has all the data.", rtabmapNs.c_str());
234 #ifdef WITH_OCTOMAP_MSGS 235 #ifdef RTABMAP_OCTOMAP 236 octomapBinarySrv_ = pnh.
advertiseService(
"octomap_binary", &MapAssembler::octomapBinaryCallback,
this);
237 octomapFullSrv_ = pnh.
advertiseService(
"octomap_full", &MapAssembler::octomapFullCallback,
this);
248 processMapData(*msg);
254 std::map<int, Transform> poses;
255 std::multimap<int, Link> constraints;
258 for(
unsigned int i=0; i<msg.nodes.size(); ++i)
260 if(msg.nodes[i].image.size() ||
261 msg.nodes[i].depth.size() ||
262 msg.nodes[i].laserScan.size())
265 if(localGridsRegenerated_)
269 uInsert(nodes_, std::make_pair(msg.nodes[i].id, data));
274 if(poses.size() && nodes_.find(poses.rbegin()->first) != nodes_.end())
276 Signature tmpS = nodes_.at(poses.rbegin()->first);
280 poses.insert(std::make_pair(0, poses.rbegin()->second));
286 poses = mapsManager_.updateMapCaches(
293 double updateTime = timer.
ticks();
295 mapFrameId_ = msg.header.frame_id;
296 optimizedPoses_ = poses;
298 mapsManager_.publishMaps(poses, msg.header.stamp, msg.header.frame_id);
300 ROS_INFO(
"map_assembler: Updating = %fs, Publishing data = %fs (subscribers=%s)", updateTime, timer.
ticks(), mapsManager_.hasSubscribers()?
"true":
"false");
303 bool reset(std_srvs::Empty::Request&, std_srvs::Empty::Response&)
306 mapsManager_.clear();
310 #ifdef WITH_OCTOMAP_MSGS 311 #ifdef RTABMAP_OCTOMAP 312 bool octomapBinaryCallback(
313 octomap_msgs::GetOctomap::Request &req,
314 octomap_msgs::GetOctomap::Response &
res)
316 ROS_INFO(
"Sending binary map data on service request");
317 res.map.header.frame_id = mapFrameId_;
320 mapsManager_.updateMapCaches(optimizedPoses_, 0,
false,
true, nodes_);
327 bool octomapFullCallback(
328 octomap_msgs::GetOctomap::Request &req,
329 octomap_msgs::GetOctomap::Response &res)
331 ROS_INFO(
"Sending full map data on service request");
332 res.map.header.frame_id = mapFrameId_;
335 mapsManager_.updateMapCaches(optimizedPoses_, 0,
false,
true, nodes_);
353 #ifdef WITH_OCTOMAP_MSGS 354 #ifdef RTABMAP_OCTOMAP 363 int main(
int argc,
char** argv)
371 for(
int i=1;i<argc;++i)
373 if(strcmp(argv[i],
"--params") == 0)
381 for(rtabmap::ParametersMap::iterator iter=parameters.begin(); iter!=parameters.end(); ++iter)
383 std::string str =
"Param: " + iter->first +
" = \"" + iter->second +
"\"";
386 std::setw(60 - str.size()) <<
392 ROS_WARN(
"Node will now exit after showing default parameters because " 393 "argument \"--params\" is detected!");
396 else if(strcmp(argv[i],
"--udebug") == 0)
400 else if(strcmp(argv[i],
"--uinfo") == 0)
ros::ServiceClient getMapSrv
static const std::map< std::string, std::pair< bool, std::string > > & getRemovedParameters()
static std::string getDescription(const std::string ¶mKey)
void setOccupancyGrid(const cv::Mat &ground, const cv::Mat &obstacles, const cv::Mat &empty, float cellSize, const cv::Point3f &viewPoint)
rtabmap::Signature nodeDataFromROS(const rtabmap_ros::NodeData &msg)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
std::pair< std::string, std::string > ParametersPair
bool call(const std::string &service_name, MReq &req, MRes &res)
static bool fullMapToMsg(const OctomapT &octomap, Octomap &msg)
static ParametersMap parseArguments(int argc, char *argv[], bool onlyParameters=false)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::map< std::string, std::string > ParametersMap
ROSCPP_DECL const std::string & getName()
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
static void setLevel(ULogger::Level level)
static bool binaryMapToMsg(const OctomapT &octomap, Octomap &msg)
std::string uBool2Str(bool boolean)
std::map< int, Transform > optimizedPoses_
bool reset(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
int main(int argc, char **argv)
std::list< std::string > uSplit(const std::string &str, char separator=' ')
std::map< int, Signature > nodes_
std::string uNumber2Str(unsigned int number)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
ros::ServiceServer resetService_
bool localGridsRegenerated_
bool getParam(const std::string &key, std::string &s) const
static void setType(Type type, const std::string &fileName=kDefaultLogFileName, bool append=true)
void mapGraphFromROS(const rtabmap_ros::MapGraph &msg, std::map< int, rtabmap::Transform > &poses, std::multimap< int, rtabmap::Link > &links, rtabmap::Transform &mapToOdom)
std::string resolveName(const std::string &name, bool remap=true) const
const RtabmapColorOcTree * octree() const
static const ParametersMap & getDefaultParameters()
void processMapData(const rtabmap_ros::MapData &msg)
SensorData & sensorData()
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
const Transform & getPose() const
MapAssembler(int &argc, char **argv)
static void readINI(const std::string &configFile, ParametersMap ¶meters, bool modifiedOnly=false)
void mapDataReceivedCallback(const rtabmap_ros::MapDataConstPtr &msg)
ros::Subscriber mapDataTopic_
ROSCPP_DECL bool waitForService(const std::string &service_name, int32_t timeout)
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)