scan_shadows_filter.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2008-2021 Radu Bogdan Rusu <rusu@cs.tum.edu> and other laser_filters authors
5  *
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 are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *********************************************************************/
29 
31 
32 #include <ros/node_handle.h>
33 #include <angles/angles.h>
34 
35 namespace laser_filters
36 {
37 
39 {
40 }
41 
43 {
44 }
45 
47 {
48  ros::NodeHandle private_nh("~" + getName());
49  dyn_server_.reset(new dynamic_reconfigure::Server<laser_filters::ScanShadowsFilterConfig>(own_mutex_, private_nh));
50  dynamic_reconfigure::Server<laser_filters::ScanShadowsFilterConfig>::CallbackType f;
51  f = [this](auto& config, auto level){ reconfigureCB(config, level); };
52  dyn_server_->setCallback(f);
53 
55  {
56  ROS_ERROR("Error: ShadowsFilter was not given min_angle.\n");
57  return false;
58  }
60  {
61  ROS_ERROR("Error: ShadowsFilter was not given min_angle.\n");
62  return false;
63  }
65  {
66  ROS_ERROR("Error: ShadowsFilter was not given window.\n");
67  return false;
68  }
69  neighbors_ = 0; // default value
71  {
72  ROS_INFO("Error: ShadowsFilter was not given neighbors.\n");
73  }
74  remove_shadow_start_point_ = false; // default value
76  ROS_INFO("Remove shadow start point: %s", remove_shadow_start_point_ ? "true" : "false");
77 
78  if (min_angle_ < 0)
79  {
80  ROS_ERROR("min_angle must be 0 <= min_angle. Forcing min_angle = 0.\n");
81  min_angle_ = 0.0;
82  }
83  if (90 < min_angle_)
84  {
85  ROS_ERROR("min_angle must be min_angle <= 90. Forcing min_angle = 90.\n");
86  min_angle_ = 90.0;
87  }
88  if (max_angle_ < 90)
89  {
90  ROS_ERROR("max_angle must be 90 <= max_angle. Forcing max_angle = 90.\n");
91  max_angle_ = 90.0;
92  }
93  if (180 < max_angle_)
94  {
95  ROS_ERROR("max_angle must be max_angle <= 180. Forcing max_angle = 180.\n");
96  max_angle_ = 180.0;
97  }
98 
102 
103  angle_increment_ = 0;
104  param_config.min_angle = min_angle_;
105  param_config.max_angle = max_angle_;
106  param_config.window = window_;
107  param_config.neighbors = neighbors_;
108  param_config.remove_shadow_start_point = remove_shadow_start_point_;
109  dyn_server_->updateConfig(param_config);
110 
111  return true;
112 }
113 
114 void ScanShadowsFilter::reconfigureCB(ScanShadowsFilterConfig& config, uint32_t level)
115 {
116  boost::recursive_mutex::scoped_lock lock(own_mutex_);
117 
118  min_angle_ = config.min_angle;
119  max_angle_ = config.max_angle;
123  neighbors_ = config.neighbors;
124  window_ = config.window;
125  angle_increment_ = 0;
126  remove_shadow_start_point_ = config.remove_shadow_start_point;
127 }
128 
129 bool ScanShadowsFilter::update(const sensor_msgs::LaserScan& scan_in, sensor_msgs::LaserScan& scan_out)
130 {
131  boost::recursive_mutex::scoped_lock lock(own_mutex_);
132 
133  // copy across all data first
134  scan_out = scan_in;
135 
136  int size = scan_in.ranges.size();
137  int max_y;
138  int max_neighbors;
139  prepareForInput(scan_in.angle_increment);
140  // For each point in the current line scan
141  for (int i = 0; i < size; i++)
142  {
143  max_y = std::min<int>(size - i, window_ + 1);
144  for (int y = std::max<int>(-i, -window_); y < max_y; y++)
145  {
146  if (y == 0)
147  {
148  continue;
149  }
150 
152  scan_in.ranges[i], scan_in.ranges[i + y], sin_map_[y + window_], cos_map_[y + window_]))
153  {
154  max_neighbors = std::min<int>(i + neighbors_, size - 1);
155  for (int index = std::max<int>(i - neighbors_, 0); index <= max_neighbors; index++)
156  {
157  if (scan_in.ranges[i] < scan_in.ranges[index])
158  { // delete neighbor if they are farther away (note not self)
159  scan_out.ranges[index] = std::numeric_limits<float>::quiet_NaN();
160  }
161  }
163  {
164  scan_out.ranges[i] = std::numeric_limits<float>::quiet_NaN();
165  }
166  break;
167  }
168  }
169  }
170 
171  return true;
172 }
173 
174 void ScanShadowsFilter::prepareForInput(const float angle_increment) {
175  if (angle_increment_ != angle_increment) {
176  ROS_DEBUG ("[ScanShadowsFilter] No precomputed map given. Computing one.");
177  angle_increment_ = angle_increment;
178  sin_map_.clear();
179  cos_map_.clear();
180 
181  float included_angle = -window_ * angle_increment;
182  for (int i = -window_; i <= window_; ++i) {
183  sin_map_.push_back(fabs(sinf(included_angle)));
184  cos_map_.push_back(cosf(included_angle));
185  included_angle += angle_increment;
186  }
187  }
188 }
189 }
filters::FilterBase
node_handle.h
laser_filters::ScanShadowsFilter::dyn_server_
std::shared_ptr< dynamic_reconfigure::Server< laser_filters::ScanShadowsFilterConfig > > dyn_server_
Definition: scan_shadows_filter.h:113
angles::from_degrees
static double from_degrees(double degrees)
laser_filters::ScanShadowsFilter::prepareForInput
void prepareForInput(const float angle_increment)
Definition: scan_shadows_filter.cpp:201
laser_filters::ScanShadowsFilter::min_angle_
double min_angle_
Definition: scan_shadows_filter.h:107
laser_filters::ScanShadowsFilter::~ScanShadowsFilter
virtual ~ScanShadowsFilter()
Definition: scan_shadows_filter.cpp:69
laser_filters::ScanShadowsFilter::angle_increment_
float angle_increment_
Definition: scan_shadows_filter.h:134
laser_filters::ScanShadowsFilter::remove_shadow_start_point_
bool remove_shadow_start_point_
Definition: scan_shadows_filter.h:109
laser_filters::ScanShadowsFilter::shadow_detector_
ScanShadowDetector shadow_detector_
Definition: scan_shadows_filter.h:111
f
f
laser_filters::ScanShadowsFilter::param_config
ScanShadowsFilterConfig param_config
Definition: scan_shadows_filter.h:115
laser_filters::ScanShadowDetector::isShadow
bool isShadow(const float r1, const float r2, const float included_angle)
Check if the point is a shadow of another point within one laser scan.
Definition: scan_shadow_detector.cpp:89
laser_filters::ScanShadowsFilter::update
bool update(const sensor_msgs::LaserScan &scan_in, sensor_msgs::LaserScan &scan_out)
Filter shadow points based on 3 global parameters: min_angle, max_angle and window....
Definition: scan_shadows_filter.cpp:156
filters::FilterBase::getParam
bool getParam(const std::string &name, bool &value) const
ROS_DEBUG
#define ROS_DEBUG(...)
laser_filters::ScanShadowsFilter::ScanShadowsFilter
ScanShadowsFilter()
Definition: scan_shadows_filter.cpp:65
laser_filters::ScanShadowDetector::configure
void configure(const float min_angle, const float max_angle)
Definition: scan_shadow_detector.cpp:77
laser_filters::ScanShadowsFilter::configure
bool configure()
Definition: scan_shadows_filter.cpp:73
laser_filters::ScanShadowsFilter::reconfigureCB
void reconfigureCB(ScanShadowsFilterConfig &config, uint32_t level)
Definition: scan_shadows_filter.cpp:141
laser_filters::ScanShadowsFilter::max_angle_
double max_angle_
Definition: scan_shadows_filter.h:107
laser_filters::ScanShadowsFilter::sin_map_
std::vector< float > sin_map_
Definition: scan_shadows_filter.h:135
laser_filters::ScanShadowsFilter::neighbors_
int neighbors_
Definition: scan_shadows_filter.h:108
laser_filters::ScanShadowsFilter::own_mutex_
boost::recursive_mutex own_mutex_
Definition: scan_shadows_filter.h:114
laser_filters::ScanShadowsFilter::window_
int window_
Definition: scan_shadows_filter.h:108
filters::FilterBase< sensor_msgs::LaserScan >::getName
const std::string & getName() const
ROS_ERROR
#define ROS_ERROR(...)
scan_shadows_filter.h
ROS_INFO
#define ROS_INFO(...)
laser_filters
LaserScanMaskFilter removes points on directions defined in a mask from a laser scan.
Definition: angular_bounds_filter.h:43
laser_filters::ScanShadowsFilter::cos_map_
std::vector< float > cos_map_
Definition: scan_shadows_filter.h:136
ros::NodeHandle
angles.h


laser_filters
Author(s): Tully Foote
autogenerated on Mon Apr 3 2023 02:51:57