scan_shadows_filter.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 Radu Bogdan Rusu <rusu@cs.tum.edu>
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  *
27  * $Id: scan_shadows_filter.cpp,v 1.0 2008/12/04 12:00:00 rusu Exp $
28  *
29  */
30 
31 /*
32  \author Radu Bogdan Rusu <rusu@cs.tum.edu> Tully Foote <tfoote@willowgarage.com>
33 
34 
35 */
36 
37 #ifndef LASER_SCAN_SHADOWS_FILTER_H
38 #define LASER_SCAN_SHADOWS_FILTER_H
39 
40 #include <set>
41 
42 #include "filters/filter_base.h"
44 #include <sensor_msgs/LaserScan.h>
45 #include <angles/angles.h>
46 
47 namespace laser_filters
48 {
52 class ScanShadowsFilter : public filters::FilterBase<sensor_msgs::LaserScan>
53 {
54 public:
55  double laser_max_range_; // Used in laser scan projection
56  double min_angle_, max_angle_; // Filter angle threshold
58  bool remove_shadow_start_point_; // Whether to also remove the start point of the shadow
59 
61 
64  {
65  }
66 
68  bool configure()
69  {
70  if (!filters::FilterBase<sensor_msgs::LaserScan>::getParam(std::string("min_angle"), min_angle_))
71  {
72  ROS_ERROR("Error: ShadowsFilter was not given min_angle.\n");
73  return false;
74  }
75  if (!filters::FilterBase<sensor_msgs::LaserScan>::getParam(std::string("max_angle"), max_angle_))
76  {
77  ROS_ERROR("Error: ShadowsFilter was not given min_angle.\n");
78  return false;
79  }
80  if (!filters::FilterBase<sensor_msgs::LaserScan>::getParam(std::string("window"), window_))
81  {
82  ROS_ERROR("Error: ShadowsFilter was not given window.\n");
83  return false;
84  }
85  neighbors_ = 0; // default value
86  if (!filters::FilterBase<sensor_msgs::LaserScan>::getParam(std::string("neighbors"), neighbors_))
87  {
88  ROS_INFO("Error: ShadowsFilter was not given neighbors.\n");
89  }
90  remove_shadow_start_point_ = false; // default value
91  filters::FilterBase<sensor_msgs::LaserScan>::getParam(std::string("remove_shadow_start_point"), remove_shadow_start_point_);
92  ROS_INFO("Remove shadow start point: %s", remove_shadow_start_point_ ? "true" : "false");
93 
94  if (min_angle_ < 0)
95  {
96  ROS_ERROR("min_angle must be 0 <= min_angle. Forcing min_angle = 0.\n");
97  min_angle_ = 0.0;
98  }
99  if (90 < min_angle_)
100  {
101  ROS_ERROR("min_angle must be min_angle <= 90. Forcing min_angle = 90.\n");
102  min_angle_ = 90.0;
103  }
104  if (max_angle_ < 90)
105  {
106  ROS_ERROR("max_angle must be 90 <= max_angle. Forcing max_angle = 90.\n");
107  max_angle_ = 90.0;
108  }
109  if (180 < min_angle_)
110  {
111  ROS_ERROR("max_angle must be max_angle <= 180. Forcing max_angle = 180.\n");
112  max_angle_ = 180.0;
113  }
114  shadow_detector_.configure(
115  angles::from_degrees(min_angle_),
116  angles::from_degrees(max_angle_));
117 
118  return true;
119  }
120 
123  {
124  }
125 
127 
134  bool update(const sensor_msgs::LaserScan& scan_in, sensor_msgs::LaserScan& scan_out)
135  {
136  // copy across all data first
137  scan_out = scan_in;
138 
139  std::set<int> indices_to_delete;
140  // For each point in the current line scan
141  for (unsigned int i = 0; i < scan_in.ranges.size(); i++)
142  {
143  for (int y = -window_; y < window_ + 1; y++)
144  {
145  int j = i + y;
146  if (j < 0 || j >= (int)scan_in.ranges.size() || (int)i == j)
147  { // Out of scan bounds or itself
148  continue;
149  }
150 
151  if (shadow_detector_.isShadow(
152  scan_in.ranges[i], scan_in.ranges[j], y * scan_in.angle_increment))
153  {
154  for (int index = std::max<int>(i - neighbors_, 0); index <= std::min<int>(i + neighbors_, (int)scan_in.ranges.size() - 1); index++)
155  {
156  if (scan_in.ranges[i] < scan_in.ranges[index])
157  { // delete neighbor if they are farther away (note not self)
158  indices_to_delete.insert(index);
159  }
160  }
161  if (remove_shadow_start_point_)
162  {
163  indices_to_delete.insert(i);
164  }
165  }
166  }
167  }
168 
169  ROS_DEBUG("ScanShadowsFilter removing %d Points from scan with min angle: %.2f, max angle: %.2f, neighbors: %d, and window: %d",
170  (int)indices_to_delete.size(), min_angle_, max_angle_, neighbors_, window_);
171  for (std::set<int>::iterator it = indices_to_delete.begin(); it != indices_to_delete.end(); ++it)
172  {
173  scan_out.ranges[*it] = std::numeric_limits<float>::quiet_NaN(); // Failed test to set the ranges to invalid value
174  }
175  return true;
176  }
177 
179 };
180 }
181 
182 #endif // LASER_SCAN_SHADOWS_FILTER_H
void configure(const float min_angle, const float max_angle)
LaserScanMaskFilter removes points on directions defined in a mask from a laser scan.
TFSIMD_FORCE_INLINE const tfScalar & y() const
bool getParam(const std::string &name, std::string &value)
static double from_degrees(double degrees)
#define ROS_INFO(...)
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. {min,max}_angle specify the allowed angle interval (in degrees) between the created lines (see getAngleWithViewPoint). Window specifies how many consecutive measurements to take into account for one point.
bool isShadow(const float r1, const float r2, const float included_angle)
#define ROS_ERROR(...)
#define ROS_DEBUG(...)


laser_filters
Author(s): Tully Foote
autogenerated on Tue Mar 17 2020 03:40:02