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 
60 
63  {
64  }
65 
67  bool configure()
68  {
69  if (!filters::FilterBase<sensor_msgs::LaserScan>::getParam(std::string("min_angle"), min_angle_))
70  {
71  ROS_ERROR("Error: ShadowsFilter was not given min_angle.\n");
72  return false;
73  }
74  if (!filters::FilterBase<sensor_msgs::LaserScan>::getParam(std::string("max_angle"), max_angle_))
75  {
76  ROS_ERROR("Error: ShadowsFilter was not given min_angle.\n");
77  return false;
78  }
79  if (!filters::FilterBase<sensor_msgs::LaserScan>::getParam(std::string("window"), window_))
80  {
81  ROS_ERROR("Error: ShadowsFilter was not given window.\n");
82  return false;
83  }
84  neighbors_ = 0; // default value
85  if (!filters::FilterBase<sensor_msgs::LaserScan>::getParam(std::string("neighbors"), neighbors_))
86  {
87  ROS_INFO("Error: ShadowsFilter was not given neighbors.\n");
88  }
89 
90  if (min_angle_ < 0)
91  {
92  ROS_ERROR("min_angle must be 0 <= min_angle. Forcing min_angle = 0.\n");
93  min_angle_ = 0.0;
94  }
95  if (90 < min_angle_)
96  {
97  ROS_ERROR("min_angle must be min_angle <= 90. Forcing min_angle = 90.\n");
98  min_angle_ = 90.0;
99  }
100  if (max_angle_ < 90)
101  {
102  ROS_ERROR("max_angle must be 90 <= max_angle. Forcing max_angle = 90.\n");
103  max_angle_ = 90.0;
104  }
105  if (180 < min_angle_)
106  {
107  ROS_ERROR("max_angle must be max_angle <= 180. Forcing max_angle = 180.\n");
108  max_angle_ = 180.0;
109  }
110  shadow_detector_.configure(
111  angles::from_degrees(min_angle_),
112  angles::from_degrees(max_angle_));
113 
114  return true;
115  }
116 
119  {
120  }
121 
123 
130  bool update(const sensor_msgs::LaserScan& scan_in, sensor_msgs::LaserScan& scan_out)
131  {
132  // copy across all data first
133  scan_out = scan_in;
134 
135  std::set<int> indices_to_delete;
136  // For each point in the current line scan
137  for (unsigned int i = 0; i < scan_in.ranges.size(); i++)
138  {
139  for (int y = -window_; y < window_ + 1; y++)
140  {
141  int j = i + y;
142  if (j < 0 || j >= (int)scan_in.ranges.size() || (int)i == j)
143  { // Out of scan bounds or itself
144  continue;
145  }
146 
147  if (shadow_detector_.isShadow(
148  scan_in.ranges[i], scan_in.ranges[j], y * scan_in.angle_increment))
149  {
150  for (int index = std::max<int>(i - neighbors_, 0); index <= std::min<int>(i + neighbors_, (int)scan_in.ranges.size() - 1); index++)
151  {
152  if (scan_in.ranges[i] < scan_in.ranges[index])
153  { // delete neighbor if they are farther away (note not self)
154  indices_to_delete.insert(index);
155  }
156  }
157  }
158  }
159  }
160 
161  ROS_DEBUG("ScanShadowsFilter removing %d Points from scan with min angle: %.2f, max angle: %.2f, neighbors: %d, and window: %d",
162  (int)indices_to_delete.size(), min_angle_, max_angle_, neighbors_, window_);
163  for (std::set<int>::iterator it = indices_to_delete.begin(); it != indices_to_delete.end(); ++it)
164  {
165  scan_out.ranges[*it] = std::numeric_limits<float>::quiet_NaN(); // Failed test to set the ranges to invalid value
166  }
167  return true;
168  }
169 
171 };
172 }
173 
174 #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
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 Wed Jul 3 2019 19:33:47