speckle_filter.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Robot Operating System code by Eurotec B.V.
5  * Copyright (c) 2020, Eurotec B.V.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  *
21  * 3. Neither the name of the copyright holder nor the names of its
22  * contributors may be used to endorse or promote products derived
23  * from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
29  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * speckle_filter.cpp
38  */
39 
41 #include <ros/node_handle.h>
42 
43 namespace laser_filters
44 {
46 {
47  validator_ = 0;
48 }
49 
51 {
52  if (!validator_)
53  {
54  delete validator_;
55  }
56 }
57 
59 {
60  ros::NodeHandle private_nh("~" + getName());
61  dyn_server_.reset(new dynamic_reconfigure::Server<laser_filters::SpeckleFilterConfig>(own_mutex_, private_nh));
62  dynamic_reconfigure::Server<laser_filters::SpeckleFilterConfig>::CallbackType f;
63  f = boost::bind(&laser_filters::LaserScanSpeckleFilter::reconfigureCB, this, _1, _2);
64  dyn_server_->setCallback(f);
65 
66  getParam("filter_type", config_.filter_type);
67  getParam("max_range", config_.max_range);
68  getParam("max_range_difference", config_.max_range_difference);
69  getParam("filter_window", config_.filter_window);
70  dyn_server_->updateConfig(config_);
71  return true;
72 }
73 
74 bool LaserScanSpeckleFilter::update(const sensor_msgs::LaserScan& input_scan, sensor_msgs::LaserScan& output_scan)
75 {
76  output_scan = input_scan;
77  std::vector<bool> valid_ranges(output_scan.ranges.size(), false);
78 
79  /*Check if range size is big enough to use the filter window */
80  if (output_scan.ranges.size() <= config_.filter_window + 1)
81  {
82  ROS_ERROR("Scan ranges size is too small: size = %i", output_scan.ranges.size());
83  return false;
84  }
85 
86  for (size_t idx = 0; idx < output_scan.ranges.size() - config_.filter_window + 1; ++idx)
87  {
88  bool window_valid = validator_->checkWindowValid(
89  output_scan, idx, config_.filter_window, config_.max_range_difference);
90 
91  // Actually set the valid ranges (do not set to false if it was already valid or out of range)
92  for (size_t neighbor_idx_or_self_nr = 0; neighbor_idx_or_self_nr < config_.filter_window; ++neighbor_idx_or_self_nr)
93  {
94  size_t neighbor_idx_or_self = idx + neighbor_idx_or_self_nr;
95  if (neighbor_idx_or_self < output_scan.ranges.size()) // Out of bound check
96  {
97  bool out_of_range = output_scan.ranges[neighbor_idx_or_self] > config_.max_range;
98  valid_ranges[neighbor_idx_or_self] = valid_ranges[neighbor_idx_or_self] || window_valid || out_of_range;
99  }
100  }
101  }
102 
103  for (size_t idx = 0; idx < valid_ranges.size(); ++idx)
104  {
105  if (!valid_ranges[idx])
106  {
107  output_scan.ranges[idx] = std::numeric_limits<float>::quiet_NaN();
108  }
109  }
110 
111  return true;
112 }
113 
114 void LaserScanSpeckleFilter::reconfigureCB(laser_filters::SpeckleFilterConfig& config, uint32_t level)
115 {
116  config_ = config;
117 
118  switch (config_.filter_type) {
119  case laser_filters::SpeckleFilter_RadiusOutlier:
120  if (validator_)
121  {
122  delete validator_;
123  }
125  break;
126 
127  case laser_filters::SpeckleFilter_Distance:
128  if (validator_)
129  {
130  delete validator_;
131  }
133  break;
134 
135  default:
136  break;
137  }
138 
139 }
140 }
virtual bool checkWindowValid(const sensor_msgs::LaserScan &scan, size_t idx, size_t window, double max_range_difference)=0
f
bool update(const sensor_msgs::LaserScan &input_scan, sensor_msgs::LaserScan &output_scan)
LaserScanMaskFilter removes points on directions defined in a mask from a laser scan.
std::shared_ptr< dynamic_reconfigure::Server< laser_filters::SpeckleFilterConfig > > dyn_server_
bool getParam(const std::string &name, std::string &value) const
void reconfigureCB(laser_filters::SpeckleFilterConfig &config, uint32_t level)
#define ROS_ERROR(...)


laser_filters
Author(s): Tully Foote
autogenerated on Mon Feb 28 2022 22:39:24