scan_footobject_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$
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_FOOTOBJECT_FILTER_H
38 #define LASER_SCAN_FOOTOBJECT_FILTER_H
39 
40 #include <set>
41 
42 #include "filters/filter_base.h"
43 #include <sensor_msgs/LaserScan.h>
44 #include "angles/angles.h"
45 
46 namespace laser_filters{
47 
51 class ScanFootObjectFilter : public filters::FilterBase<sensor_msgs::LaserScan>
52 {
53 public:
54 
55  double max_radius_; // Filter angle threshold
57 
58 
61  {
62 
63 
64  }
65 
67  bool configure()
68  {
69  max_radius_ = 0.1;//default value
70  if (!filters::FilterBase<sensor_msgs::LaserScan>::getParam(std::string("max_radius"), max_radius_))
71  {
72  ROS_ERROR("Error: FootObjectFilter was not given min_radius.\n");
73  return false;
74  }
75 
76  min_points_ = 5;//default value
77  if (!filters::FilterBase<sensor_msgs::LaserScan>::getParam(std::string("min_points"), min_points_))
78  {
79  ROS_INFO("Error: FootObjectFilter was not given min_points.\n");
80  return false;
81  }
82  return true;
83  }
84 
86  virtual ~ScanFootObjectFilter () { }
87 
89 
93  bool update(const sensor_msgs::LaserScan& scan_in, sensor_msgs::LaserScan& scan_out)
94  {
95  //copy across all data first
96  scan_out = scan_in;
97 
98  std::set<int> indices_to_publish;
99  // assume that all points is pass thorugh shadow filter, so each blob is separeted by invalide scan data
100  std::vector<std::vector<int> > range_blobs;
101  std::vector<int> range_blob;
102  for (unsigned int i = 0; i < scan_in.ranges.size (); i++)
103  {
104  scan_out.ranges[i] = -1.0 * fabs(scan_in.ranges[i]); // set all ranges to invalid (*)
105  if ( scan_in.ranges[i] < 0 || std::isnan(scan_in.ranges[i])) {
106  if ( range_blob.size() > min_points_ ) {
107  range_blobs.push_back(range_blob);
108  }
109  range_blob.clear();
110  }else{
111  range_blob.push_back(i);
112  }
113  }
114  if ( range_blob.size() > min_points_ ) {
115  range_blobs.push_back(range_blob);
116  }
117  // for each blob calculate center and radius
118  for (unsigned int i = 0; i < range_blobs.size(); i++) {
119  int size = range_blobs[i].size();
120  // check center of blob
121  double center_x = 0, center_y = 0;
122  for (unsigned int j = 0; j < size; j++) {
123  double x = scan_in.ranges[range_blobs[i][j]];
124  double y = scan_in.ranges[range_blobs[i][j]] * scan_in.angle_increment;
125  center_x += x;
126  center_y += y;
127  }
128  center_x /= size;
129  center_y /= size;
130 
131  // check range of blob
132  double radius = 0;
133  for (unsigned int j = 0; j < size; j++) {
134  double x = scan_in.ranges[range_blobs[i][j]];
135  double y = scan_in.ranges[range_blobs[i][j]] * scan_in.angle_increment;
136  if ( radius < fabs(center_x - x) ) radius = fabs(center_x - x) ;
137  if ( radius < fabs(center_y - y) ) radius = fabs(center_y - y) ;
138  }
139 
140  ROS_DEBUG_STREAM("blob center " << center_x << " " << center_y << ", radius " << radius << ", num of ponits " << size);
141  if ( radius < max_radius_ ) {
142  indices_to_publish.insert(range_blobs[i][0] + size/2);
143  }
144  }
145  ROS_DEBUG("ScanFootObjectFilter %d Points from scan with min radius: %.2f, num of pints: %d", (int)indices_to_publish.size(), max_radius_, min_points_);
146  for ( std::set<int>::iterator it = indices_to_publish.begin(); it != indices_to_publish.end(); ++it)
147  {
148  scan_out.ranges[*it] = fabs(scan_in.ranges[*it]); // valid only the ranges that passwd the test (*)
149  }
150  return true;
151  }
152 
154 
155 } ;
156 }
157 
158 #endif //LASER_SCAN_FOOTOBJECT_FILTER_H
TFSIMD_FORCE_INLINE const tfScalar & y() const
#define ROS_INFO(...)
TFSIMD_FORCE_INLINE const tfScalar & x() const
#define ROS_DEBUG_STREAM(args)
bool update(const sensor_msgs::LaserScan &scan_in, sensor_msgs::LaserScan &scan_out)
#define ROS_ERROR(...)
#define ROS_DEBUG(...)


laser_filters_jsk_patch
Author(s): k-okada
autogenerated on Tue May 11 2021 02:55:37