129 #include "nav_msgs/MapMetaData.h" 136 #include <boost/foreach.hpp> 137 #define foreach BOOST_FOREACH 140 #define MAP_IDX(sx, i, j) ((sx) * (j) + (i)) 143 map_to_odom_(
tf::Transform(
tf::createQuaternionFromRPY( 0, 0, 0 ),
tf::
Point(0, 0, 0 ))),
144 laser_count_(0), private_nh_(
"~"), scan_filter_sub_(NULL), scan_filter_(NULL), transform_thread_(NULL)
284 double transform_publish_period;
294 std::vector<std::string> topics;
295 topics.push_back(std::string(
"/tf"));
296 topics.push_back(scan_topic);
300 std::queue<std::pair<sensor_msgs::LaserScan::ConstPtr, std::string> > s_queue;
303 tf::tfMessage::ConstPtr cur_tf = m.
instantiate<tf::tfMessage>();
304 if (cur_tf != NULL) {
305 for (
size_t i = 0; i < cur_tf->transforms.size(); ++i)
307 geometry_msgs::TransformStamped transformStamped;
309 transformStamped = cur_tf->transforms[i];
315 sensor_msgs::LaserScan::ConstPtr
s = m.
instantiate<sensor_msgs::LaserScan>();
317 if (!(
ros::Time(s->header.stamp)).is_zero())
319 s_queue.push(std::make_pair(s,
""));
322 if (s_queue.size() > 5) {
330 while (!s_queue.empty())
343 s_queue.front().second = std::string(e.what());
353 if(transform_publish_period == 0)
356 ros::Rate r(1.0 / transform_publish_period);
394 ROS_WARN(
"Failed to compute odom pose, skipping scan (%s)", e.what());
414 ident.
stamp_ = scan.header.stamp;
421 ROS_WARN(
"Failed to compute laser pose, aborting initialization (%s)",
428 v.setValue(0, 0, 1 + laser_pose.
getOrigin().z());
434 ROS_DEBUG(
"Z-Axis in sensor frame: %.3f", up.z());
438 ROS_WARN(
"Unable to determine orientation of laser: %s",
444 if (fabs(fabs(up.z()) - 1) > 0.001)
446 ROS_WARN(
"Laser has to be mounted planar! Z-coordinate has to be 1 or -1, but gave: %.5f",
453 double angle_center = (scan.angle_min + scan.angle_max)/2;
460 ROS_INFO(
"Laser is mounted upwards.");
467 ROS_INFO(
"Laser is mounted upside down.");
473 double theta = - std::fabs(scan.angle_min - scan.angle_max)/2;
474 for(
unsigned int i=0; i<scan.ranges.size(); ++i)
477 theta += std::fabs(scan.angle_increment);
480 ROS_DEBUG(
"Laser angles in laser-frame: min: %.3f max: %.3f inc: %.3f", scan.angle_min, scan.angle_max,
481 scan.angle_increment);
482 ROS_DEBUG(
"Laser angles in top-down centered laser-frame: min: %.3f max: %.3f inc: %.3f",
laser_angles_.front(),
501 fabs(scan.angle_increment),
519 ROS_WARN(
"Unable to determine inital pose of laser! Starting point will be set to zero.");
530 gsp_->setgenerateMap(
false);
545 ROS_INFO(
"Initialization complete");
560 double* ranges_double =
new double[scan.ranges.size()];
565 int num_ranges = scan.ranges.size();
566 for(
int i=0; i < num_ranges; i++)
569 if(scan.ranges[num_ranges - i - 1] < scan.range_min)
570 ranges_double[i] = (double)scan.range_max;
572 ranges_double[i] = (
double)scan.ranges[num_ranges - i - 1];
576 for(
unsigned int i=0; i < scan.ranges.size(); i++)
579 if(scan.ranges[i] < scan.range_min)
580 ranges_double[i] = (double)scan.range_max;
582 ranges_double[i] = (
double)scan.ranges[i];
589 scan.header.stamp.toSec());
593 delete[] ranges_double;
633 ROS_DEBUG(
"new best pose: %.3f %.3f %.3f", mpose.x, mpose.y, mpose.
theta);
634 ROS_DEBUG(
"odom pose: %.3f %.3f %.3f", odom_pose.x, odom_pose.y, odom_pose.
theta);
635 ROS_DEBUG(
"correction: %.3f %.3f %.3f", mpose.x - odom_pose.x, mpose.y - odom_pose.y, mpose.
theta - odom_pose.
theta);
647 last_map_update = scan->header.stamp;
657 double weight_total=0.0;
658 for(std::vector<GMapping::GridSlamProcessor::Particle>::const_iterator it =
gsp_->
getParticles().begin();
662 weight_total += it->weight;
664 double entropy = 0.0;
665 for(std::vector<GMapping::GridSlamProcessor::Particle>::const_iterator it =
gsp_->
getParticles().begin();
669 if(it->weight/weight_total > 0.0)
670 entropy += it->weight/weight_total * log(it->weight/weight_total);
679 boost::mutex::scoped_lock map_lock (
map_mutex_);
687 matcher.setgenerateMap(
true);
691 std_msgs::Float64 entropy;
693 if(entropy.data > 0.0)
698 map_.map.info.origin.position.x = 0.0;
699 map_.map.info.origin.position.y = 0.0;
700 map_.map.info.origin.position.z = 0.0;
701 map_.map.info.origin.orientation.x = 0.0;
702 map_.map.info.origin.orientation.y = 0.0;
703 map_.map.info.origin.orientation.z = 0.0;
704 map_.map.info.origin.orientation.w = 1.0;
750 map_.map.data.resize(
map_.map.info.width *
map_.map.info.height);
752 ROS_DEBUG(
"map origin: (%f, %f)",
map_.map.info.origin.position.x,
map_.map.info.origin.position.y);
761 double occ=smap.
cell(p);
786 nav_msgs::GetMap::Response &res)
788 boost::mutex::scoped_lock map_lock (
map_mutex_);
bool mapCallback(nav_msgs::GetMap::Request &req, nav_msgs::GetMap::Response &res)
Point map2world(const IntPoint &p) const
void laserCallback(const sensor_msgs::LaserScan::ConstPtr &scan)
static tf::Quaternion createQuaternionFromRPY(double roll, double pitch, double yaw)
int getBestParticleIndex() const
double registerScan(ScanMatcherMap &map, const OrientedPoint &p, const double *readings)
message_filters::Subscriber< sensor_msgs::LaserScan > * scan_filter_sub_
Cell & cell(int x, int y)
bool initMapper(const sensor_msgs::LaserScan &scan)
void updateMap(const sensor_msgs::LaserScan &scan)
tf::TransformListener tf_
void open(std::string const &filename, uint32_t mode=bagmode::Read)
double computePoseEntropy()
void setMatchingParameters(double urange, double range, double sigma, int kernsize, double lopt, double aopt, int iterations, double likelihoodSigma=1, double likelihoodGain=1, unsigned int likelihoodSkip=0)
static double getYaw(const Quaternion &bt_q)
bool processScan(const RangeReading &reading, int adaptParticles=0)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
OrientedPoint getPose() const
double UTILS_EXPORT sampleGaussian(double sigma, unsigned long int S=0)
void publishLoop(double transform_publish_period)
bool getOdomPose(GMapping::OrientedPoint &gmap_pose, const ros::Time &t)
tf::Stamped< tf::Pose > centered_laser_pose_
unsigned int gsp_laser_beam_count_
const ParticleVector & getParticles() const
void setLaserParameters(unsigned int beams, double *angles, const OrientedPoint &lpose)
tf::TransformBroadcaster * tfB_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
void publish(const boost::shared_ptr< M > &message) const
void startReplay(const std::string &bag_fname, std::string scan_topic)
tf::Transform map_to_odom_
void setUpdateDistances(double linear, double angular, double resampleThreshold)
void invalidateActiveArea()
void setSensorMap(const SensorMap &smap)
Duration & fromSec(double t)
nav_msgs::GetMap::Response map_
bool getParam(const std::string &key, std::string &s) const
TFSIMD_FORCE_INLINE Quaternion inverse(const Quaternion &q)
boost::mutex map_to_odom_mutex_
boost::thread * transform_thread_
ros::Publisher entropy_publisher_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
#define ROS_WARN_STREAM(args)
std::map< std::string, Sensor *> SensorMap
boost::shared_ptr< T > instantiate() const
ros::Duration map_update_interval_
double transform_publish_period_
#define MAP_IDX(sx, i, j)
ros::NodeHandle private_nh_
void setPose(const OrientedPoint &pose)
std::string getName() const
GMapping::GridSlamProcessor * gsp_
double resampleThreshold_
void setUpdatePeriod(double p)
void setMotionModelParameters(double srr, double srt, double str, double stt)
void computeActiveArea(ScanMatcherMap &map, const OrientedPoint &p, const double *readings)
static void transformStampedMsgToTF(const geometry_msgs::TransformStamped &msg, StampedTransform &bt)
std::vector< double > laser_angles_
tf::MessageFilter< sensor_msgs::LaserScan > * scan_filter_
GMapping::OdometrySensor * gsp_odom_
orientedpoint< double, double > OrientedPoint
GMapping::RangeSensor * gsp_laser_
bool addScan(const sensor_msgs::LaserScan &scan, GMapping::OrientedPoint &gmap_pose)
Connection registerCallback(const C &callback)