lidar_measurement_model_likelihood.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2018, the mcl_3dl authors
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  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the copyright holder nor the names of its 
00014  *       contributors may be used to endorse or promote products derived from 
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDEDNode BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <algorithm>
00031 #include <string>
00032 #include <vector>
00033 
00034 #include <ros/ros.h>
00035 
00036 #include <pcl/point_types.h>
00037 #include <pcl_ros/point_cloud.h>
00038 
00039 #include <mcl_3dl/pf.h>
00040 #include <mcl_3dl/point_cloud_random_sampler.h>
00041 #include <mcl_3dl/point_types.h>
00042 #include <mcl_3dl/vec3.h>
00043 
00044 #include <mcl_3dl/lidar_measurement_models/lidar_measurement_model_likelihood.h>
00045 
00046 namespace mcl_3dl
00047 {
00048 void LidarMeasurementModelLikelihood::loadConfig(
00049     const ros::NodeHandle& nh,
00050     const std::string& name)
00051 {
00052   ros::NodeHandle pnh(nh, name);
00053 
00054   int num_points, num_points_global;
00055   pnh.param("num_points", num_points, 96);
00056   pnh.param("num_points_global", num_points_global, 8);
00057   num_points_default_ = num_points_ = num_points;
00058   num_points_global_ = num_points_global;
00059 
00060   double clip_near, clip_far;
00061   pnh.param("clip_near", clip_near, 0.5);
00062   pnh.param("clip_far", clip_far, 10.0);
00063   clip_near_sq_ = clip_near * clip_near;
00064   clip_far_sq_ = clip_far * clip_far;
00065 
00066   double clip_z_min, clip_z_max;
00067   pnh.param("clip_z_min", clip_z_min, -2.0);
00068   pnh.param("clip_z_max", clip_z_max, 2.0);
00069   clip_z_min_ = clip_z_min;
00070   clip_z_max_ = clip_z_max;
00071 
00072   double match_weight;
00073   pnh.param("match_weight", match_weight, 5.0);
00074   match_weight_ = match_weight;
00075 
00076   double match_dist_min, match_dist_flat;
00077   pnh.param("match_dist_min", match_dist_min, 0.2);
00078   pnh.param("match_dist_flat", match_dist_flat, 0.05);
00079   match_dist_min_ = match_dist_min;
00080   match_dist_flat_ = match_dist_flat;
00081 }
00082 void LidarMeasurementModelLikelihood::setGlobalLocalizationStatus(
00083     const size_t num_particles,
00084     const size_t current_num_particles)
00085 {
00086   if (current_num_particles <= num_particles)
00087   {
00088     num_points_ = num_points_default_;
00089     return;
00090   }
00091   size_t num = num_points_default_ * num_particles / current_num_particles;
00092   if (num < num_points_global_)
00093     num = num_points_global_;
00094 
00095   num_points_ = num;
00096 }
00097 
00098 typename pcl::PointCloud<LidarMeasurementModelBase::PointType>::Ptr
00099 LidarMeasurementModelLikelihood::filter(
00100     const typename pcl::PointCloud<LidarMeasurementModelBase::PointType>::ConstPtr& pc) const
00101 {
00102   const auto local_points_filter = [this](const LidarMeasurementModelBase::PointType& p)
00103   {
00104     if (p.x * p.x + p.y * p.y > clip_far_sq_)
00105       return true;
00106     if (p.x * p.x + p.y * p.y < clip_near_sq_)
00107       return true;
00108     if (p.z < clip_z_min_ || clip_z_max_ < p.z)
00109       return true;
00110     return false;
00111   };
00112   pcl::PointCloud<LidarMeasurementModelBase::PointType>::Ptr pc_filtered(
00113       new pcl::PointCloud<LidarMeasurementModelBase::PointType>);
00114   *pc_filtered = *pc;
00115   pc_filtered->erase(
00116       std::remove_if(pc_filtered->begin(), pc_filtered->end(), local_points_filter), pc_filtered->end());
00117   pc_filtered->width = 1;
00118   pc_filtered->height = pc_filtered->points.size();
00119 
00120   return sampler_.sample<LidarMeasurementModelBase::PointType>(pc_filtered, num_points_);
00121 }
00122 
00123 LidarMeasurementResult LidarMeasurementModelLikelihood::measure(
00124     typename ChunkedKdtree<LidarMeasurementModelBase::PointType>::Ptr& kdtree,
00125     const typename pcl::PointCloud<LidarMeasurementModelBase::PointType>::ConstPtr& pc,
00126     const std::vector<Vec3>& origins,
00127     const State6DOF& s) const
00128 {
00129   if (!pc)
00130     return LidarMeasurementResult(1, 0);
00131   if (pc->size() == 0)
00132     return LidarMeasurementResult(1, 0);
00133   pcl::PointCloud<LidarMeasurementModelBase::PointType>::Ptr pc_particle(
00134       new pcl::PointCloud<LidarMeasurementModelBase::PointType>);
00135   std::vector<int> id(1);
00136   std::vector<float> sqdist(1);
00137 
00138   float score_like = 0;
00139   *pc_particle = *pc;
00140   s.transform(*pc_particle);
00141   size_t num = 0;
00142   for (auto& p : pc_particle->points)
00143   {
00144     if (kdtree->radiusSearch(p, match_dist_min_, id, sqdist, 1))
00145     {
00146       const float dist = match_dist_min_ - std::max(sqrtf(sqdist[0]), match_dist_flat_);
00147       if (dist < 0.0)
00148         continue;
00149 
00150       score_like += dist * match_weight_;
00151       num++;
00152     }
00153   }
00154   const float match_ratio = static_cast<float>(num) / pc_particle->points.size();
00155 
00156   return LidarMeasurementResult(score_like, match_ratio);
00157 }
00158 }  // namespace mcl_3dl


mcl_3dl
Author(s): Atsushi Watanabe
autogenerated on Thu Jun 20 2019 20:04:43