HectorMappingRos.cpp
Go to the documentation of this file.
00001 //=================================================================================================
00002 // Copyright (c) 2011, Stefan Kohlbrecher, TU Darmstadt
00003 // All rights reserved.
00004 
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions are met:
00007 //     * Redistributions of source code must retain the above copyright
00008 //       notice, this list of conditions and the following disclaimer.
00009 //     * Redistributions in binary form must reproduce the above copyright
00010 //       notice, this list of conditions and the following disclaimer in the
00011 //       documentation and/or other materials provided with the distribution.
00012 //     * Neither the name of the Simulation, Systems Optimization and Robotics
00013 //       group, TU Darmstadt nor the names of its contributors may be used to
00014 //       endorse or promote products derived from this software without
00015 //       specific prior written permission.
00016 
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00018 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //=================================================================================================
00028 
00029 #include "HectorMappingRos.h"
00030 
00031 #include "map/GridMap.h"
00032 
00033 #include <geometry_msgs/PoseWithCovarianceStamped.h>
00034 #include <nav_msgs/Odometry.h>
00035 
00036 #include "sensor_msgs/PointCloud2.h"
00037 
00038 #include "HectorDrawings.h"
00039 #include "HectorDebugInfoProvider.h"
00040 #include "HectorMapMutex.h"
00041 
00042 #ifndef TF_SCALAR_H
00043   typedef btScalar tfScalar;
00044 #endif
00045 
00046 HectorMappingRos::HectorMappingRos()
00047   : debugInfoProvider(0)
00048   , hectorDrawings(0)
00049   , lastGetMapUpdateIndex(-100)
00050   , tfB_(0)
00051   , map__publish_thread_(0)
00052   , initial_pose_set_(false)
00053 {
00054   ros::NodeHandle private_nh_("~");
00055 
00056   std::string mapTopic_ = "map";
00057 
00058   private_nh_.param("pub_drawings", p_pub_drawings, false);
00059   private_nh_.param("pub_debug_output", p_pub_debug_output_, false);
00060   private_nh_.param("pub_map_odom_transform", p_pub_map_odom_transform_,true);
00061   private_nh_.param("pub_odometry", p_pub_odometry_,false);
00062   private_nh_.param("advertise_map_service", p_advertise_map_service_,true);
00063   private_nh_.param("scan_subscriber_queue_size", p_scan_subscriber_queue_size_, 5);
00064 
00065   private_nh_.param("map_resolution", p_map_resolution_, 0.025);
00066   private_nh_.param("map_size", p_map_size_, 1024);
00067   private_nh_.param("map_start_x", p_map_start_x_, 0.5);
00068   private_nh_.param("map_start_y", p_map_start_y_, 0.5);
00069   private_nh_.param("map_multi_res_levels", p_map_multi_res_levels_, 3);
00070 
00071   private_nh_.param("update_factor_free", p_update_factor_free_, 0.4);
00072   private_nh_.param("update_factor_occupied", p_update_factor_occupied_, 0.9);
00073 
00074   private_nh_.param("map_update_distance_thresh", p_map_update_distance_threshold_, 0.4);
00075   private_nh_.param("map_update_angle_thresh", p_map_update_angle_threshold_, 0.9);
00076 
00077   private_nh_.param("scan_topic", p_scan_topic_, std::string("scan"));
00078   private_nh_.param("sys_msg_topic", p_sys_msg_topic_, std::string("syscommand"));
00079   private_nh_.param("pose_update_topic", p_pose_update_topic_, std::string("poseupdate"));
00080 
00081   private_nh_.param("use_tf_scan_transformation", p_use_tf_scan_transformation_,true);
00082   private_nh_.param("use_tf_pose_start_estimate", p_use_tf_pose_start_estimate_,false);
00083   private_nh_.param("map_with_known_poses", p_map_with_known_poses_, false);
00084 
00085   private_nh_.param("base_frame", p_base_frame_, std::string("base_link"));
00086   private_nh_.param("map_frame", p_map_frame_, std::string("map"));
00087   private_nh_.param("odom_frame", p_odom_frame_, std::string("odom"));
00088 
00089   private_nh_.param("pub_map_scanmatch_transform", p_pub_map_scanmatch_transform_,true);
00090   private_nh_.param("tf_map_scanmatch_transform_frame_name", p_tf_map_scanmatch_transform_frame_name_, std::string("scanmatcher_frame"));
00091 
00092   private_nh_.param("output_timing", p_timing_output_,false);
00093 
00094   private_nh_.param("map_pub_period", p_map_pub_period_, 2.0);
00095 
00096   double tmp = 0.0;
00097   private_nh_.param("laser_min_dist", tmp, 0.4);
00098   p_sqr_laser_min_dist_ = static_cast<float>(tmp*tmp);
00099 
00100   private_nh_.param("laser_max_dist", tmp, 30.0);
00101   p_sqr_laser_max_dist_ = static_cast<float>(tmp*tmp);
00102 
00103   private_nh_.param("laser_z_min_value", tmp, -1.0);
00104   p_laser_z_min_value_ = static_cast<float>(tmp);
00105 
00106   private_nh_.param("laser_z_max_value", tmp, 1.0);
00107   p_laser_z_max_value_ = static_cast<float>(tmp);
00108 
00109   if (p_pub_drawings)
00110   {
00111     ROS_INFO("HectorSM publishing debug drawings");
00112     hectorDrawings = new HectorDrawings();
00113   }
00114 
00115   if(p_pub_debug_output_)
00116   {
00117     ROS_INFO("HectorSM publishing debug info");
00118     debugInfoProvider = new HectorDebugInfoProvider();
00119   }
00120 
00121   if(p_pub_odometry_)
00122   {
00123     odometryPublisher_ = node_.advertise<nav_msgs::Odometry>("scanmatch_odom", 50);
00124   }
00125 
00126   slamProcessor = new hectorslam::HectorSlamProcessor(static_cast<float>(p_map_resolution_), p_map_size_, p_map_size_, Eigen::Vector2f(p_map_start_x_, p_map_start_y_), p_map_multi_res_levels_, hectorDrawings, debugInfoProvider);
00127   slamProcessor->setUpdateFactorFree(p_update_factor_free_);
00128   slamProcessor->setUpdateFactorOccupied(p_update_factor_occupied_);
00129   slamProcessor->setMapUpdateMinDistDiff(p_map_update_distance_threshold_);
00130   slamProcessor->setMapUpdateMinAngleDiff(p_map_update_angle_threshold_);
00131 
00132   int mapLevels = slamProcessor->getMapLevels();
00133   mapLevels = 1;
00134 
00135   for (int i = 0; i < mapLevels; ++i)
00136   {
00137     mapPubContainer.push_back(MapPublisherContainer());
00138     slamProcessor->addMapMutex(i, new HectorMapMutex());
00139 
00140     std::string mapTopicStr(mapTopic_);
00141 
00142     if (i != 0)
00143     {
00144       mapTopicStr.append("_" + boost::lexical_cast<std::string>(i));
00145     }
00146 
00147     std::string mapMetaTopicStr(mapTopicStr);
00148     mapMetaTopicStr.append("_metadata");
00149 
00150     MapPublisherContainer& tmp = mapPubContainer[i];
00151     tmp.mapPublisher_ = node_.advertise<nav_msgs::OccupancyGrid>(mapTopicStr, 1, true);
00152     tmp.mapMetadataPublisher_ = node_.advertise<nav_msgs::MapMetaData>(mapMetaTopicStr, 1, true);
00153 
00154     if ( (i == 0) && p_advertise_map_service_)
00155     {
00156       tmp.dynamicMapServiceServer_ = node_.advertiseService("dynamic_map", &HectorMappingRos::mapCallback, this);
00157     }
00158 
00159     setServiceGetMapData(tmp.map_, slamProcessor->getGridMap(i));
00160 
00161     if ( i== 0){
00162       mapPubContainer[i].mapMetadataPublisher_.publish(mapPubContainer[i].map_.map.info);
00163     }
00164   }
00165 
00166   ROS_INFO("HectorSM p_base_frame_: %s", p_base_frame_.c_str());
00167   ROS_INFO("HectorSM p_map_frame_: %s", p_map_frame_.c_str());
00168   ROS_INFO("HectorSM p_odom_frame_: %s", p_odom_frame_.c_str());
00169   ROS_INFO("HectorSM p_scan_topic_: %s", p_scan_topic_.c_str());
00170   ROS_INFO("HectorSM p_use_tf_scan_transformation_: %s", p_use_tf_scan_transformation_ ? ("true") : ("false"));
00171   ROS_INFO("HectorSM p_pub_map_odom_transform_: %s", p_pub_map_odom_transform_ ? ("true") : ("false"));
00172   ROS_INFO("HectorSM p_scan_subscriber_queue_size_: %d", p_scan_subscriber_queue_size_);
00173   ROS_INFO("HectorSM p_map_pub_period_: %f", p_map_pub_period_);
00174   ROS_INFO("HectorSM p_update_factor_free_: %f", p_update_factor_free_);
00175   ROS_INFO("HectorSM p_update_factor_occupied_: %f", p_update_factor_occupied_);
00176   ROS_INFO("HectorSM p_map_update_distance_threshold_: %f ", p_map_update_distance_threshold_);
00177   ROS_INFO("HectorSM p_map_update_angle_threshold_: %f", p_map_update_angle_threshold_);
00178   ROS_INFO("HectorSM p_laser_z_min_value_: %f", p_laser_z_min_value_);
00179   ROS_INFO("HectorSM p_laser_z_max_value_: %f", p_laser_z_max_value_);
00180 
00181   scanSubscriber_ = node_.subscribe(p_scan_topic_, p_scan_subscriber_queue_size_, &HectorMappingRos::scanCallback, this);
00182   sysMsgSubscriber_ = node_.subscribe(p_sys_msg_topic_, 2, &HectorMappingRos::sysMsgCallback, this);
00183 
00184   poseUpdatePublisher_ = node_.advertise<geometry_msgs::PoseWithCovarianceStamped>(p_pose_update_topic_, 1, false);
00185   posePublisher_ = node_.advertise<geometry_msgs::PoseStamped>("slam_out_pose", 1, false);
00186 
00187   scan_point_cloud_publisher_ = node_.advertise<sensor_msgs::PointCloud>("slam_cloud",1,false);
00188 
00189   tfB_ = new tf::TransformBroadcaster();
00190   ROS_ASSERT(tfB_);
00191 
00192   /*
00193   bool p_use_static_map_ = false;
00194 
00195   if (p_use_static_map_){
00196     mapSubscriber_ = node_.subscribe(mapTopic_, 1, &HectorMappingRos::staticMapCallback, this);
00197   }
00198   */
00199 
00200   initial_pose_sub_ = new message_filters::Subscriber<geometry_msgs::PoseWithCovarianceStamped>(node_, "initialpose", 2);
00201   initial_pose_filter_ = new tf::MessageFilter<geometry_msgs::PoseWithCovarianceStamped>(*initial_pose_sub_, tf_, p_map_frame_, 2);
00202   initial_pose_filter_->registerCallback(boost::bind(&HectorMappingRos::initialPoseCallback, this, _1));
00203 
00204 
00205   map__publish_thread_ = new boost::thread(boost::bind(&HectorMappingRos::publishMapLoop, this, p_map_pub_period_));
00206 
00207   map_to_odom_.setIdentity();
00208 
00209   lastMapPublishTime = ros::Time(0,0);
00210 }
00211 
00212 HectorMappingRos::~HectorMappingRos()
00213 {
00214   delete slamProcessor;
00215 
00216   if (hectorDrawings)
00217     delete hectorDrawings;
00218 
00219   if (debugInfoProvider)
00220     delete debugInfoProvider;
00221 
00222   if (tfB_)
00223     delete tfB_;
00224 
00225   if(map__publish_thread_)
00226     delete map__publish_thread_;
00227 }
00228 
00229 void HectorMappingRos::scanCallback(const sensor_msgs::LaserScan& scan)
00230 {
00231   if (hectorDrawings)
00232   {
00233     hectorDrawings->setTime(scan.header.stamp);
00234   }
00235 
00236   ros::WallTime startTime = ros::WallTime::now();
00237 
00238   if (!p_use_tf_scan_transformation_)
00239   {
00240     if (rosLaserScanToDataContainer(scan, laserScanContainer,slamProcessor->getScaleToMap()))
00241     {
00242       slamProcessor->update(laserScanContainer,slamProcessor->getLastScanMatchPose());
00243     }
00244   }
00245   else
00246   {
00247     ros::Duration dur (0.5);
00248 
00249     if (tf_.waitForTransform(p_base_frame_,scan.header.frame_id, scan.header.stamp,dur))
00250     {
00251       tf::StampedTransform laserTransform;
00252       tf_.lookupTransform(p_base_frame_,scan.header.frame_id, scan.header.stamp, laserTransform);
00253 
00254       //projector_.transformLaserScanToPointCloud(p_base_frame_ ,scan, pointCloud,tf_);
00255       projector_.projectLaser(scan, laser_point_cloud_,30.0);
00256 
00257       if (scan_point_cloud_publisher_.getNumSubscribers() > 0){
00258         scan_point_cloud_publisher_.publish(laser_point_cloud_);
00259       }
00260 
00261       Eigen::Vector3f startEstimate(Eigen::Vector3f::Zero());
00262 
00263       if(rosPointCloudToDataContainer(laser_point_cloud_, laserTransform, laserScanContainer, slamProcessor->getScaleToMap()))
00264       {
00265         if (initial_pose_set_){
00266           initial_pose_set_ = false;
00267           startEstimate = initial_pose_;
00268         }else if (p_use_tf_pose_start_estimate_){
00269 
00270           try
00271           {
00272             tf::StampedTransform stamped_pose;
00273 
00274             tf_.waitForTransform(p_map_frame_,p_base_frame_, scan.header.stamp, ros::Duration(0.5));
00275             tf_.lookupTransform(p_map_frame_, p_base_frame_,  scan.header.stamp, stamped_pose);
00276 
00277             tfScalar yaw, pitch, roll;
00278             stamped_pose.getBasis().getEulerYPR(yaw, pitch, roll);
00279 
00280             startEstimate = Eigen::Vector3f(stamped_pose.getOrigin().getX(),stamped_pose.getOrigin().getY(), yaw);
00281           }
00282           catch(tf::TransformException e)
00283           {
00284             ROS_ERROR("Transform from %s to %s failed\n", p_map_frame_.c_str(), p_base_frame_.c_str());
00285             startEstimate = slamProcessor->getLastScanMatchPose();
00286           }
00287 
00288         }else{
00289           startEstimate = slamProcessor->getLastScanMatchPose();
00290         }
00291 
00292 
00293         if (p_map_with_known_poses_){
00294           slamProcessor->update(laserScanContainer, startEstimate, true);
00295         }else{
00296           slamProcessor->update(laserScanContainer, startEstimate);
00297         }
00298       }
00299 
00300     }else{
00301       ROS_INFO("lookupTransform %s to %s timed out. Could not transform laser scan into base_frame.", p_base_frame_.c_str(), scan.header.frame_id.c_str());
00302       return;
00303     }
00304   }
00305 
00306   if (p_timing_output_)
00307   {
00308     ros::WallDuration duration = ros::WallTime::now() - startTime;
00309     ROS_INFO("HectorSLAM Iter took: %f milliseconds", duration.toSec()*1000.0f );
00310   }
00311 
00312   //If we're just building a map with known poses, we're finished now. Code below this point publishes the localization results.
00313   if (p_map_with_known_poses_)
00314   {
00315     return;
00316   }
00317 
00318   poseInfoContainer_.update(slamProcessor->getLastScanMatchPose(), slamProcessor->getLastScanMatchCovariance(), scan.header.stamp, p_map_frame_);
00319 
00320   poseUpdatePublisher_.publish(poseInfoContainer_.getPoseWithCovarianceStamped());
00321   posePublisher_.publish(poseInfoContainer_.getPoseStamped());
00322 
00323   if(p_pub_odometry_)
00324   {
00325     nav_msgs::Odometry tmp;
00326     tmp.pose = poseInfoContainer_.getPoseWithCovarianceStamped().pose;
00327 
00328     tmp.header = poseInfoContainer_.getPoseWithCovarianceStamped().header;
00329     tmp.child_frame_id = p_base_frame_;
00330     odometryPublisher_.publish(tmp);
00331   }
00332 
00333   if (p_pub_map_odom_transform_)
00334   {
00335     tf::StampedTransform odom_to_base;
00336 
00337     try
00338     {
00339       tf_.waitForTransform(p_odom_frame_, p_base_frame_, scan.header.stamp, ros::Duration(0.5));
00340       tf_.lookupTransform(p_odom_frame_, p_base_frame_, scan.header.stamp, odom_to_base);
00341     }
00342     catch(tf::TransformException e)
00343     {
00344       ROS_ERROR("Transform failed during publishing of map_odom transform: %s",e.what());
00345       odom_to_base.setIdentity();
00346     }
00347     map_to_odom_ = tf::Transform(poseInfoContainer_.getTfTransform() * odom_to_base.inverse());
00348     tfB_->sendTransform( tf::StampedTransform (map_to_odom_, scan.header.stamp, p_map_frame_, p_odom_frame_));
00349   }
00350 
00351   if (p_pub_map_scanmatch_transform_){
00352     tfB_->sendTransform( tf::StampedTransform(poseInfoContainer_.getTfTransform(), scan.header.stamp, p_map_frame_, p_tf_map_scanmatch_transform_frame_name_));
00353   }
00354 }
00355 
00356 void HectorMappingRos::sysMsgCallback(const std_msgs::String& string)
00357 {
00358   ROS_INFO("HectorSM sysMsgCallback, msg contents: %s", string.data.c_str());
00359 
00360   if (string.data == "reset")
00361   {
00362     ROS_INFO("HectorSM reset");
00363     slamProcessor->reset();
00364   }
00365 }
00366 
00367 bool HectorMappingRos::mapCallback(nav_msgs::GetMap::Request  &req,
00368                                    nav_msgs::GetMap::Response &res)
00369 {
00370   ROS_INFO("HectorSM Map service called");
00371   res = mapPubContainer[0].map_;
00372   return true;
00373 }
00374 
00375 void HectorMappingRos::publishMap(MapPublisherContainer& mapPublisher, const hectorslam::GridMap& gridMap, ros::Time timestamp, MapLockerInterface* mapMutex)
00376 {
00377   nav_msgs::GetMap::Response& map_ (mapPublisher.map_);
00378 
00379   //only update map if it changed
00380   if (lastGetMapUpdateIndex != gridMap.getUpdateIndex())
00381   {
00382 
00383     int sizeX = gridMap.getSizeX();
00384     int sizeY = gridMap.getSizeY();
00385 
00386     int size = sizeX * sizeY;
00387 
00388     std::vector<int8_t>& data = map_.map.data;
00389 
00390     //std::vector contents are guaranteed to be contiguous, use memset to set all to unknown to save time in loop
00391     memset(&data[0], -1, sizeof(int8_t) * size);
00392 
00393     if (mapMutex)
00394     {
00395       mapMutex->lockMap();
00396     }
00397 
00398     for(int i=0; i < size; ++i)
00399     {
00400       if(gridMap.isFree(i))
00401       {
00402         data[i] = 0;
00403       }
00404       else if (gridMap.isOccupied(i))
00405       {
00406         data[i] = 100;
00407       }
00408     }
00409 
00410     lastGetMapUpdateIndex = gridMap.getUpdateIndex();
00411 
00412     if (mapMutex)
00413     {
00414       mapMutex->unlockMap();
00415     }
00416   }
00417 
00418   map_.map.header.stamp = timestamp;
00419 
00420   mapPublisher.mapPublisher_.publish(map_.map);
00421 }
00422 
00423 bool HectorMappingRos::rosLaserScanToDataContainer(const sensor_msgs::LaserScan& scan, hectorslam::DataContainer& dataContainer, float scaleToMap)
00424 {
00425   size_t size = scan.ranges.size();
00426 
00427   float angle = scan.angle_min;
00428 
00429   dataContainer.clear();
00430 
00431   dataContainer.setOrigo(Eigen::Vector2f::Zero());
00432 
00433   float maxRangeForContainer = scan.range_max - 0.1f;
00434 
00435   for (size_t i = 0; i < size; ++i)
00436   {
00437     float dist = scan.ranges[i];
00438 
00439     if ( (dist > scan.range_min) && (dist < maxRangeForContainer))
00440     {
00441       dist *= scaleToMap;
00442       dataContainer.add(Eigen::Vector2f(cos(angle) * dist, sin(angle) * dist));
00443     }
00444 
00445     angle += scan.angle_increment;
00446   }
00447 
00448   return true;
00449 }
00450 
00451 bool HectorMappingRos::rosPointCloudToDataContainer(const sensor_msgs::PointCloud& pointCloud, const tf::StampedTransform& laserTransform, hectorslam::DataContainer& dataContainer, float scaleToMap)
00452 {
00453   size_t size = pointCloud.points.size();
00454   //ROS_INFO("size: %d", size);
00455 
00456   dataContainer.clear();
00457 
00458   tf::Vector3 laserPos (laserTransform.getOrigin());
00459   dataContainer.setOrigo(Eigen::Vector2f(laserPos.x(), laserPos.y())*scaleToMap);
00460 
00461   for (size_t i = 0; i < size; ++i)
00462   {
00463 
00464     const geometry_msgs::Point32& currPoint(pointCloud.points[i]);
00465 
00466     float dist_sqr = currPoint.x*currPoint.x + currPoint.y* currPoint.y;
00467 
00468     if ( (dist_sqr > p_sqr_laser_min_dist_) && (dist_sqr < p_sqr_laser_max_dist_) ){
00469 
00470       if ( (currPoint.x < 0.0f) && (dist_sqr < 0.50f)){
00471         continue;
00472       }
00473 
00474       tf::Vector3 pointPosBaseFrame(laserTransform * tf::Vector3(currPoint.x, currPoint.y, currPoint.z));
00475 
00476       float pointPosLaserFrameZ = pointPosBaseFrame.z() - laserPos.z();
00477 
00478       if (pointPosLaserFrameZ > p_laser_z_min_value_ && pointPosLaserFrameZ < p_laser_z_max_value_)
00479       {
00480         dataContainer.add(Eigen::Vector2f(pointPosBaseFrame.x(),pointPosBaseFrame.y())*scaleToMap);
00481       }
00482     }
00483   }
00484 
00485   return true;
00486 }
00487 
00488 void HectorMappingRos::setServiceGetMapData(nav_msgs::GetMap::Response& map_, const hectorslam::GridMap& gridMap)
00489 {
00490   Eigen::Vector2f mapOrigin (gridMap.getWorldCoords(Eigen::Vector2f::Zero()));
00491   mapOrigin.array() -= gridMap.getCellLength()*0.5f;
00492 
00493   map_.map.info.origin.position.x = mapOrigin.x();
00494   map_.map.info.origin.position.y = mapOrigin.y();
00495   map_.map.info.origin.orientation.w = 1.0;
00496 
00497   map_.map.info.resolution = gridMap.getCellLength();
00498 
00499   map_.map.info.width = gridMap.getSizeX();
00500   map_.map.info.height = gridMap.getSizeY();
00501 
00502   map_.map.header.frame_id = p_map_frame_;
00503   map_.map.data.resize(map_.map.info.width * map_.map.info.height);
00504 }
00505 
00506 /*
00507 void HectorMappingRos::setStaticMapData(const nav_msgs::OccupancyGrid& map)
00508 {
00509   float cell_length = map.info.resolution;
00510   Eigen::Vector2f mapOrigin (map.info.origin.position.x + cell_length*0.5f,
00511                              map.info.origin.position.y + cell_length*0.5f);
00512 
00513   int map_size_x = map.info.width;
00514   int map_size_y = map.info.height;
00515 
00516   slamProcessor = new hectorslam::HectorSlamProcessor(cell_length, map_size_x, map_size_y, Eigen::Vector2f(0.0f, 0.0f), 1, hectorDrawings, debugInfoProvider);
00517 }
00518 */
00519 
00520 
00521 void HectorMappingRos::publishMapLoop(double map_pub_period)
00522 {
00523   ros::Rate r(1.0 / map_pub_period);
00524   while(ros::ok())
00525   {
00526     //ros::WallTime t1 = ros::WallTime::now();
00527     ros::Time mapTime (ros::Time::now());
00528     //publishMap(mapPubContainer[2],slamProcessor->getGridMap(2), mapTime);
00529     //publishMap(mapPubContainer[1],slamProcessor->getGridMap(1), mapTime);
00530     publishMap(mapPubContainer[0],slamProcessor->getGridMap(0), mapTime, slamProcessor->getMapMutex(0));
00531 
00532     //ros::WallDuration t2 = ros::WallTime::now() - t1;
00533 
00534     //std::cout << "time s: " << t2.toSec();
00535     //ROS_INFO("HectorSM ms: %4.2f", t2.toSec()*1000.0f);
00536 
00537     r.sleep();
00538   }
00539 }
00540 
00541 void HectorMappingRos::staticMapCallback(const nav_msgs::OccupancyGrid& map)
00542 {
00543 
00544 }
00545 
00546 void HectorMappingRos::initialPoseCallback(const geometry_msgs::PoseWithCovarianceStampedConstPtr& msg)
00547 {
00548   initial_pose_set_ = true;
00549 
00550   tf::Pose pose;
00551   tf::poseMsgToTF(msg->pose.pose, pose);
00552   initial_pose_ = Eigen::Vector3f(msg->pose.pose.position.x, msg->pose.pose.position.y, tf::getYaw(pose.getRotation()));
00553   ROS_INFO("Setting initial pose with world coords x: %f y: %f yaw: %f", initial_pose_[0], initial_pose_[1], initial_pose_[2]);
00554 }
00555 
00556 


hector_mapping
Author(s): Stefan Kohlbrecher
autogenerated on Thu Jun 6 2019 20:12:30