@@ -36,6 +36,7 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh)
3636 std::vector<std::string> pointcloud_topics;
3737 std::vector<std::string> map_topics;
3838 double recordableFps, updateVarianceFps, timeInterval, updatePoseFps, updateGridMapFps, publishStatisticsFps;
39+ bool enablePointCloudPublishing (false );
3940
4041 nh.param <std::vector<std::string>>(" pointcloud_topics" , pointcloud_topics, {" points" });
4142 nh.getParam (" publishers" , publishers);
@@ -55,10 +56,13 @@ ElevationMappingNode::ElevationMappingNode(ros::NodeHandle& nh)
5556 nh.param <double >(" initialize_tf_grid_size" , initializeTfGridSize_, 0.5 );
5657 nh.param <double >(" map_acquire_fps" , updateGridMapFps, 5.0 );
5758 nh.param <double >(" publish_statistics_fps" , publishStatisticsFps, 1.0 );
58- nh.param <bool >(" enable_pointcloud_publishing" , enablePointCloudPublishing_ , false );
59+ nh.param <bool >(" enable_pointcloud_publishing" , enablePointCloudPublishing , false );
5960 nh.param <bool >(" enable_normal_arrow_publishing" , enableNormalArrowPublishing_, false );
6061 nh.param <bool >(" enable_drift_corrected_TF_publishing" , enableDriftCorrectedTFPublishing_, false );
6162 nh.param <bool >(" use_initializer_at_start" , useInitializerAtStart_, false );
63+
64+ enablePointCloudPublishing_ = enablePointCloudPublishing;
65+
6266 for (const auto & pointcloud_topic : pointcloud_topics) {
6367 ros::Subscriber sub = nh_.subscribe (pointcloud_topic, 1 , &ElevationMappingNode::pointcloudCallback, this );
6468 pointcloudSubs_.push_back (sub);
@@ -184,25 +188,29 @@ void ElevationMappingNode::publishMapOfIndex(int index) {
184188 }
185189 grid_map_msgs::GridMap msg;
186190 std::vector<std::string> layers;
187- for (const auto & layer : map_layers_[index]) {
188- const bool is_layer_in_all = map_layers_all_.find (layer) != map_layers_all_.end ();
189- if (is_layer_in_all && gridMap_.exists (layer)) {
190- layers.push_back (layer);
191- } else if (map_.exists_layer (layer)) {
192- // if there are layers which is not in the syncing layer.
193- boost::recursive_mutex::scoped_lock scopedLockForGridMap (mapMutex_);
194- ElevationMappingWrapper::RowMatrixXf map_data;
195- map_.get_layer_data (layer, map_data);
196- gridMap_.add (layer, map_data);
197- layers.push_back (layer);
191+
192+ { // need continuous lock between adding layers and converting to message. Otherwise updateGridmap can reset the data not in
193+ // map_layers_all_
194+ std::lock_guard<std::mutex> lock (mapMutex_);
195+ for (const auto & layer : map_layers_[index]) {
196+ const bool is_layer_in_all = map_layers_all_.find (layer) != map_layers_all_.end ();
197+ if (is_layer_in_all && gridMap_.exists (layer)) {
198+ layers.push_back (layer);
199+ } else if (map_.exists_layer (layer)) {
200+ // if there are layers which is not in the syncing layer.
201+ ElevationMappingWrapper::RowMatrixXf map_data;
202+ map_.get_layer_data (layer, map_data);
203+ gridMap_.add (layer, map_data);
204+ layers.push_back (layer);
205+ }
198206 }
207+ if (layers.empty ()) {
208+ return ;
209+ }
210+
211+ grid_map::GridMapRosConverter::toMessage (gridMap_, layers, msg);
199212 }
200- if (layers.empty ()) {
201- return ;
202- }
203- boost::recursive_mutex::scoped_lock scopedLockForGridMap (mapMutex_);
204- grid_map::GridMapRosConverter::toMessage (gridMap_, layers, msg);
205- scopedLockForGridMap.unlock ();
213+
206214 msg.basic_layers = map_basic_layers_[index];
207215 mapPubs_[index].publish (msg);
208216}
@@ -226,16 +234,25 @@ void ElevationMappingNode::pointcloudCallback(const sensor_msgs::PointCloud2& cl
226234 ROS_ERROR (" %s" , ex.what ());
227235 return ;
228236 }
229- map_.input (pointCloud, transformationSensorToMap.rotation (), transformationSensorToMap.translation (), positionError_, orientationError_);
237+
238+ double positionError{0.0 };
239+ double orientationError{0.0 };
240+ {
241+ std::lock_guard<std::mutex> lock (errorMutex_);
242+ positionError = positionError_;
243+ orientationError = orientationError_;
244+ }
245+
246+ map_.input (pointCloud, transformationSensorToMap.rotation (), transformationSensorToMap.translation (), positionError, orientationError);
230247
231248 if (enableDriftCorrectedTFPublishing_) {
232249 publishMapToOdom (map_.get_additive_mean_error ());
233250 }
234251
235252 ROS_DEBUG_THROTTLE (1.0 , " ElevationMap processed a point cloud (%i points) in %f sec." , static_cast <int >(pointCloud->size ()),
236253 (ros::Time::now () - start).toSec ());
237- ROS_DEBUG_THROTTLE (1.0 , " positionError: %f " , positionError_ );
238- ROS_DEBUG_THROTTLE (1.0 , " orientationError: %f " , orientationError_ );
254+ ROS_DEBUG_THROTTLE (1.0 , " positionError: %f " , positionError );
255+ ROS_DEBUG_THROTTLE (1.0 , " orientationError: %f " , orientationError );
239256 // This is used for publishing as statistics.
240257 pointCloudProcessCounter_++;
241258}
@@ -259,18 +276,22 @@ void ElevationMappingNode::updatePose(const ros::TimerEvent&) {
259276 transformTf.getRotation ().w ());
260277 lowpassPosition_ = positionAlpha_ * position3 + (1 - positionAlpha_) * lowpassPosition_;
261278 lowpassOrientation_ = orientationAlpha_ * orientation + (1 - orientationAlpha_) * lowpassOrientation_;
262- positionError_ = (position3 - lowpassPosition_).norm ();
263- orientationError_ = (orientation - lowpassOrientation_).norm ();
279+ {
280+ std::lock_guard<std::mutex> lock (errorMutex_);
281+ positionError_ = (position3 - lowpassPosition_).norm ();
282+ orientationError_ = (orientation - lowpassOrientation_).norm ();
283+ }
284+
264285 if (useInitializerAtStart_) {
265286 ROS_INFO (" Clearing map with initializer." );
266287 initializeWithTF ();
267288 useInitializerAtStart_ = false ;
268289 }
269290}
270291
271- void ElevationMappingNode::publishAsPointCloud () {
292+ void ElevationMappingNode::publishAsPointCloud (const grid_map::GridMap& map) const {
272293 sensor_msgs::PointCloud2 msg;
273- grid_map::GridMapRosConverter::toPointCloud (gridMap_ , " elevation" , msg);
294+ grid_map::GridMapRosConverter::toPointCloud (map , " elevation" , msg);
274295 pointPub_.publish (msg);
275296}
276297
@@ -302,7 +323,7 @@ bool ElevationMappingNode::getSubmap(grid_map_msgs::GetGridMap::Request& request
302323 grid_map::Index index;
303324 grid_map::GridMap subMap;
304325 {
305- boost::recursive_mutex::scoped_lock scopedLockForGridMap (mapMutex_);
326+ std::lock_guard<std::mutex> lock (mapMutex_);
306327 subMap = gridMap_.getSubmap (requestedSubmapPosition, requestedSubmapLength, index, isSuccess);
307328 }
308329 const auto & length = subMap.getLength ();
@@ -453,14 +474,14 @@ void ElevationMappingNode::publishStatistics(const ros::TimerEvent&) {
453474
454475void ElevationMappingNode::updateGridMap (const ros::TimerEvent&) {
455476 std::vector<std::string> layers (map_layers_all_.begin (), map_layers_all_.end ());
456- boost::recursive_mutex::scoped_lock scopedLockForGridMap (mapMutex_);
477+ std::lock_guard<std::mutex> lock (mapMutex_);
457478 map_.get_grid_map (gridMap_, layers);
458479 gridMap_.setTimestamp (ros::Time::now ().toNSec ());
459480 alivePub_.publish (std_msgs::Empty ());
460481
461482 // Mostly debug purpose
462483 if (enablePointCloudPublishing_) {
463- publishAsPointCloud ();
484+ publishAsPointCloud (gridMap_ );
464485 }
465486 if (enableNormalArrowPublishing_) {
466487 publishNormalAsArrow (gridMap_);
@@ -515,7 +536,7 @@ bool ElevationMappingNode::initializeMap(elevation_map_msgs::Initialize::Request
515536 return true ;
516537}
517538
518- void ElevationMappingNode::publishNormalAsArrow (const grid_map::GridMap& map) {
539+ void ElevationMappingNode::publishNormalAsArrow (const grid_map::GridMap& map) const {
519540 auto startTime = ros::Time::now ();
520541
521542 const auto & normalX = map[" normal_x" ];
@@ -545,7 +566,7 @@ void ElevationMappingNode::publishNormalAsArrow(const grid_map::GridMap& map) {
545566}
546567
547568visualization_msgs::Marker ElevationMappingNode::vectorToArrowMarker (const Eigen::Vector3d& start, const Eigen::Vector3d& end,
548- const int id) {
569+ const int id) const {
549570 visualization_msgs::Marker marker;
550571 marker.header .frame_id = mapFrameId_;
551572 marker.header .stamp = ros::Time::now ();
@@ -576,13 +597,12 @@ visualization_msgs::Marker ElevationMappingNode::vectorToArrowMarker(const Eigen
576597}
577598
578599void ElevationMappingNode::publishMapToOdom (double error) {
579- static tf::TransformBroadcaster br;
580600 tf::Transform transform;
581601 transform.setOrigin (tf::Vector3 (0.0 , 0.0 , error));
582602 tf::Quaternion q;
583603 q.setRPY (0 , 0 , 0 );
584604 transform.setRotation (q);
585- br .sendTransform (tf::StampedTransform (transform, ros::Time::now (), mapFrameId_, correctedMapFrameId_));
605+ tfBroadcaster_ .sendTransform (tf::StampedTransform (transform, ros::Time::now (), mapFrameId_, correctedMapFrameId_));
586606}
587607
588608} // namespace elevation_mapping_cupy
0 commit comments