38 #include <moveit_msgs/SaveMap.h>
39 #include <moveit_msgs/LoadMap.h>
46 static const std::string
LOGNAME =
"occupancy_map_monitor";
49 : map_resolution_(map_resolution), debug_info_(false), mesh_handle_count_(0), nh_(
"~"), active_(false)
54 OccupancyMapMonitor::OccupancyMapMonitor(
const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
55 const std::string& map_frame,
double map_resolution)
57 , map_frame_(map_frame)
58 , map_resolution_(map_resolution)
60 , mesh_handle_count_(0)
66 OccupancyMapMonitor::OccupancyMapMonitor(
const std::shared_ptr<tf2_ros::Buffer>& tf_buffer,
ros::NodeHandle& nh,
67 const std::string& map_frame,
double map_resolution)
69 , map_frame_(map_frame)
70 , map_resolution_(map_resolution)
72 , mesh_handle_count_(0)
78 void OccupancyMapMonitor::initialize()
81 if (map_resolution_ <= std::numeric_limits<double>::epsilon())
83 if (!nh_.getParam(
"octomap_resolution", map_resolution_))
85 map_resolution_ = 0.1;
86 ROS_WARN_NAMED(
LOGNAME,
"Resolution not specified for Octomap. Assuming resolution = %g instead", map_resolution_);
91 if (map_frame_.empty())
92 if (!nh_.getParam(
"octomap_frame", map_frame_))
95 "No transforms will be applied to received data.");
97 if (!tf_buffer_ && !map_frame_.empty())
99 <<
"\" specified but no TF instance (buffer) specified. "
100 "No transforms will be applied to received data.");
102 tree_ = std::make_shared<collision_detection::OccMapTree>(map_resolution_);
106 if (nh_.getParam(
"sensors", sensor_list))
111 for (int32_t i = 0; i < sensor_list.
size(); ++i)
119 if (!sensor_list[i].hasMember(
"sensor_plugin"))
125 std::string sensor_plugin = std::string(sensor_list[i][
"sensor_plugin"]);
126 if (sensor_plugin.empty() || sensor_plugin[0] ==
'~')
132 if (!updater_plugin_loader_)
136 updater_plugin_loader_ = std::make_unique<pluginlib::ClassLoader<OccupancyMapUpdater>>(
137 "moveit_ros_perception",
"occupancy_map_monitor::OccupancyMapUpdater");
145 OccupancyMapUpdaterPtr up;
148 up = updater_plugin_loader_->createUniqueInstance(sensor_plugin);
149 up->setMonitor(
this);
154 << sensor_plugin <<
"': " << ex.what() << std::endl);
159 if (!up->setParams(sensor_list[i]))
165 if (!up->initialize())
167 ROS_ERROR_NAMED(
LOGNAME,
"Unable to initialize map updater of type %s (plugin %s)", up->getType().c_str(),
168 sensor_plugin.c_str());
187 save_map_srv_ = nh_.advertiseService(
"save_map", &OccupancyMapMonitor::saveMapCallback,
this);
188 load_map_srv_ = nh_.advertiseService(
"load_map", &OccupancyMapMonitor::loadMapCallback,
this);
191 void OccupancyMapMonitor::addUpdater(
const OccupancyMapUpdaterPtr& updater)
195 map_updaters_.push_back(updater);
196 updater->publishDebugInformation(debug_info_);
197 if (map_updaters_.size() > 1)
199 mesh_handles_.resize(map_updaters_.size());
201 if (map_updaters_.size() == 2)
203 map_updaters_[0]->setTransformCacheCallback(
205 return getShapeTransformCache(0, frame, stamp, cache);
207 map_updaters_[1]->setTransformCacheCallback(
209 return getShapeTransformCache(1, frame, stamp, cache);
213 map_updaters_.back()->setTransformCacheCallback(
214 [
this, i = map_updaters_.size() - 1](
const std::string& frame,
const ros::Time& stamp,
216 return getShapeTransformCache(i, frame, stamp, cache);
220 updater->setTransformCacheCallback(transform_cache_callback_);
226 void OccupancyMapMonitor::publishDebugInformation(
bool flag)
229 for (OccupancyMapUpdaterPtr& map_updater : map_updaters_)
230 map_updater->publishDebugInformation(debug_info_);
233 void OccupancyMapMonitor::setMapFrame(
const std::string& frame)
235 boost::mutex::scoped_lock _(parameters_lock_);
242 if (map_updaters_.size() == 1)
243 return map_updaters_[0]->excludeShape(shape);
246 for (std::size_t i = 0; i < map_updaters_.size(); ++i)
248 ShapeHandle mh = map_updaters_[i]->excludeShape(shape);
252 h = ++mesh_handle_count_;
253 mesh_handles_[i][h] = mh;
259 void OccupancyMapMonitor::forgetShape(
ShapeHandle handle)
262 if (map_updaters_.size() == 1)
264 map_updaters_[0]->forgetShape(handle);
268 for (std::size_t i = 0; i < map_updaters_.size(); ++i)
270 std::map<ShapeHandle, ShapeHandle>::const_iterator it = mesh_handles_[i].find(handle);
271 if (it == mesh_handles_[i].end())
273 map_updaters_[i]->forgetShape(it->second);
280 if (map_updaters_.size() == 1)
281 map_updaters_[0]->setTransformCacheCallback(transform_callback);
283 transform_cache_callback_ = transform_callback;
286 bool OccupancyMapMonitor::getShapeTransformCache(std::size_t index,
const std::string& target_frame,
289 if (transform_cache_callback_)
292 if (transform_cache_callback_(target_frame, target_time, temp_cache))
294 for (std::pair<const ShapeHandle, Eigen::Isometry3d>& it : temp_cache)
296 std::map<ShapeHandle, ShapeHandle>::const_iterator jt = mesh_handles_[
index].find(it.first);
297 if (jt == mesh_handles_[
index].end())
303 cache[jt->second] = it.second;
314 bool OccupancyMapMonitor::saveMapCallback(moveit_msgs::SaveMap::Request& request,
315 moveit_msgs::SaveMap::Response& response)
321 response.success = tree_->writeBinary(request.filename);
331 bool OccupancyMapMonitor::loadMapCallback(moveit_msgs::LoadMap::Request& request,
332 moveit_msgs::LoadMap::Response& response)
340 response.success = tree_->readBinary(request.filename);
347 tree_->unlockWrite();
350 tree_->triggerUpdateCallback();
355 void OccupancyMapMonitor::startMonitor()
359 for (OccupancyMapUpdaterPtr& map_updater : map_updaters_)
360 map_updater->start();
363 void OccupancyMapMonitor::stopMonitor()
366 for (OccupancyMapUpdaterPtr& map_updater : map_updaters_)
370 OccupancyMapMonitor::~OccupancyMapMonitor()