lidar_measurement_model_beam.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/raycast.h>
00043 #include <mcl_3dl/vec3.h>
00044 
00045 #include <mcl_3dl/lidar_measurement_models/lidar_measurement_model_beam.h>
00046 
00047 namespace mcl_3dl
00048 {
00049 LidarMeasurementModelBeam::LidarMeasurementModelBeam(
00050     const float x, const float y, const float z)
00051 {
00052   // FIXME(at-wat): remove NOLINT after clang-format or roslint supports it
00053   map_grid_min_ = std::min({ x, y, z });  // NOLINT(whitespace/braces)
00054   map_grid_max_ = std::max({ x, y, z });  // NOLINT(whitespace/braces)
00055 }
00056 
00057 void LidarMeasurementModelBeam::loadConfig(
00058     const ros::NodeHandle& nh,
00059     const std::string& name)
00060 {
00061   ros::NodeHandle pnh(nh, name);
00062 
00063   int num_points, num_points_global;
00064   pnh.param("num_points", num_points, 3);
00065   pnh.param("num_points_global", num_points_global, 0);
00066   num_points_default_ = num_points_ = num_points;
00067   num_points_global_ = num_points_global;
00068 
00069   double clip_near, clip_far;
00070   pnh.param("clip_near", clip_near, 0.5);
00071   pnh.param("clip_far", clip_far, 4.0);
00072   clip_near_sq_ = clip_near * clip_near;
00073   clip_far_sq_ = clip_far * clip_far;
00074 
00075   double clip_z_min, clip_z_max;
00076   pnh.param("clip_z_min", clip_z_min, -2.0);
00077   pnh.param("clip_z_max", clip_z_max, 2.0);
00078   clip_z_min_ = clip_z_min;
00079   clip_z_max_ = clip_z_max;
00080 
00081   double beam_likelihood_min;
00082   pnh.param("beam_likelihood", beam_likelihood_min, 0.2);
00083   beam_likelihood_min_ = beam_likelihood_min;
00084   beam_likelihood_ = powf(beam_likelihood_min, 1.0 / static_cast<float>(num_points));
00085 
00086   double ang_total_ref;
00087   pnh.param("ang_total_ref", ang_total_ref, M_PI / 6.0);
00088   sin_total_ref_ = sinf(ang_total_ref);
00089 }
00090 
00091 void LidarMeasurementModelBeam::setGlobalLocalizationStatus(
00092     const size_t num_particles,
00093     const size_t current_num_particles)
00094 {
00095   if (current_num_particles <= num_particles)
00096   {
00097     num_points_ = num_points_default_;
00098     return;
00099   }
00100   size_t num = num_points_default_ * num_particles / current_num_particles;
00101   if (num < num_points_global_)
00102     num = num_points_global_;
00103 
00104   num_points_ = num;
00105 }
00106 
00107 typename pcl::PointCloud<LidarMeasurementModelBase::PointType>::Ptr
00108 LidarMeasurementModelBeam::filter(
00109     const typename pcl::PointCloud<LidarMeasurementModelBase::PointType>::ConstPtr& pc) const
00110 {
00111   const auto local_points_filter = [this](const LidarMeasurementModelBase::PointType& p)
00112   {
00113     if (p.x * p.x + p.y * p.y > clip_far_sq_)
00114       return true;
00115     if (p.x * p.x + p.y * p.y < clip_near_sq_)
00116       return true;
00117     if (p.z < clip_z_min_ || clip_z_max_ < p.z)
00118       return true;
00119     return false;
00120   };
00121   pcl::PointCloud<LidarMeasurementModelBase::PointType>::Ptr pc_filtered(
00122       new pcl::PointCloud<LidarMeasurementModelBase::PointType>);
00123   *pc_filtered = *pc;
00124   pc_filtered->erase(
00125       std::remove_if(pc_filtered->begin(), pc_filtered->end(), local_points_filter), pc_filtered->end());
00126   pc_filtered->width = 1;
00127   pc_filtered->height = pc_filtered->points.size();
00128 
00129   return sampler_.sample<LidarMeasurementModelBase::PointType>(pc_filtered, num_points_);
00130 }
00131 
00132 LidarMeasurementResult LidarMeasurementModelBeam::measure(
00133     typename ChunkedKdtree<LidarMeasurementModelBase::PointType>::Ptr& kdtree,
00134     const typename pcl::PointCloud<LidarMeasurementModelBase::PointType>::ConstPtr& pc,
00135     const std::vector<Vec3>& origins,
00136     const State6DOF& s) const
00137 {
00138   if (!pc)
00139     return LidarMeasurementResult(1, 0);
00140   if (pc->size() == 0)
00141     return LidarMeasurementResult(1, 0);
00142   pcl::PointCloud<LidarMeasurementModelBase::PointType>::Ptr pc_particle(
00143       new pcl::PointCloud<LidarMeasurementModelBase::PointType>);
00144   std::vector<int> id(1);
00145   std::vector<float> sqdist(1);
00146 
00147   float score_beam = 1.0;
00148   *pc_particle = *pc;
00149   s.transform(*pc_particle);
00150   for (auto& p : pc_particle->points)
00151   {
00152     const int beam_header_id = p.label;
00153     Raycast<LidarMeasurementModelBase::PointType> ray(
00154         kdtree,
00155         s.pos_ + s.rot_ * origins[beam_header_id],
00156         Vec3(p.x, p.y, p.z),
00157         map_grid_min_, map_grid_max_);
00158     for (auto point : ray)
00159     {
00160       if (point.collision_)
00161       {
00162         // reject total reflection
00163         if (point.sin_angle_ > sin_total_ref_)
00164         {
00165           score_beam *= beam_likelihood_;
00166         }
00167         break;
00168       }
00169     }
00170   }
00171   if (score_beam < beam_likelihood_min_)
00172     score_beam = beam_likelihood_min_;
00173 
00174   return LidarMeasurementResult(score_beam, 1.0);
00175 }
00176 }  // namespace mcl_3dl


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