self_see_filter.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
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 
30 #ifndef FILTERS_SELF_SEE_H_
31 #define FILTERS_SELF_SEE_H_
32 
33 #include <filters/filter_base.h>
35 #include <ros/console.h>
36 
37 namespace filters
38 {
39 
44 template <typename PointT>
45 class SelfFilter: public FilterBase <pcl::PointCloud<PointT> >
46 {
47 
48 public:
49  typedef pcl::PointCloud<PointT> PointCloud;
52  {
53  nh_.param<double>("min_sensor_dist", min_sensor_dist_, 0.01);
54  double default_padding, default_scale;
55  nh_.param<double>("self_see_default_padding", default_padding, .01);
56  nh_.param<double>("self_see_default_scale", default_scale, 1.0);
57  nh_.param<bool>("keep_organized", keep_organized_, false);
58  std::vector<robot_self_filter::LinkInfo> links;
59  std::string link_names;
60 
61  if(!nh_.hasParam("self_see_links")) {
62  ROS_WARN("No links specified for self filtering.");
63  } else {
64 
65  XmlRpc::XmlRpcValue ssl_vals;;
66 
67  nh_.getParam("self_see_links", ssl_vals);
68  if(ssl_vals.getType() != XmlRpc::XmlRpcValue::TypeArray) {
69  ROS_WARN("Self see links need to be an array");
70 
71  } else {
72  if(ssl_vals.size() == 0) {
73  ROS_WARN("No values in self see links array");
74  } else {
75  for(int i = 0; i < ssl_vals.size(); i++) {
77 
78  if(ssl_vals[i].getType() != XmlRpc::XmlRpcValue::TypeStruct) {
79  ROS_WARN("Self see links entry %d is not a structure. Stopping processing of self see links",i);
80  break;
81  }
82  if(!ssl_vals[i].hasMember("name")) {
83  ROS_WARN("Self see links entry %d has no name. Stopping processing of self see links",i);
84  break;
85  }
86  li.name = std::string(ssl_vals[i]["name"]);
87  if(!ssl_vals[i].hasMember("padding")) {
88  ROS_DEBUG("Self see links entry %d has no padding. Assuming default padding of %g",i,default_padding);
89  li.padding = default_padding;
90  } else {
91  li.padding = ssl_vals[i]["padding"];
92  }
93  if(!ssl_vals[i].hasMember("scale")) {
94  ROS_DEBUG("Self see links entry %d has no scale. Assuming default scale of %g",i,default_scale);
95  li.scale = default_scale;
96  } else {
97  li.scale = ssl_vals[i]["scale"];
98  }
99  links.push_back(li);
100  }
101  }
102  }
103  }
105  if (!sensor_frame_.empty())
106  ROS_INFO("Self filter is removing shadow points for sensor in frame '%s'. Minimum distance to sensor is %f.", sensor_frame_.c_str(), min_sensor_dist_);
107  }
108 
111  virtual ~SelfFilter(void)
112  {
113  delete sm_;
114  }
115 
116  virtual bool configure(void)
117  {
118  // keep only the points that are outside of the robot
119  // for testing purposes this may be changed to true
120  nh_.param("invert", invert_, false);
121 
122  if (invert_)
123  ROS_INFO("Inverting filter output");
124 
125  return true;
126  }
127 
128  bool updateWithSensorFrame(const PointCloud& data_in, PointCloud& data_out, const std::string& sensor_frame)
129  {
130  sensor_frame_ = sensor_frame;
131  return update(data_in, data_out);
132  }
133 
138  virtual bool update(const PointCloud& data_in, PointCloud& data_out)
139  {
140  std::vector<int> keep(data_in.points.size());
141  if(sensor_frame_.empty()) {
142  sm_->maskContainment(data_in, keep);
143  } else {
144  sm_->maskIntersection(data_in, sensor_frame_, min_sensor_dist_, keep);
145  }
146  fillResult(data_in, keep, data_out);
147  return true;
148  }
149 
150  bool updateWithSensorFrame(const PointCloud& data_in, PointCloud& data_out, PointCloud& data_diff, const std::string& sensor_frame)
151  {
152  sensor_frame_ = sensor_frame;
153  return update(data_in, data_out, data_diff);
154  }
155 
160  virtual bool update(const PointCloud& data_in, PointCloud& data_out, PointCloud& data_diff)
161  {
162  std::vector<int> keep(data_in.points.size());
163  if(sensor_frame_.empty()) {
164  sm_->maskContainment(data_in, keep);
165  } else {
166  sm_->maskIntersection(data_in, sensor_frame_, min_sensor_dist_, keep);
167  }
168  fillResult(data_in, keep, data_out);
169  fillDiff(data_in,keep,data_diff);
170  return true;
171  }
172 
173  void fillDiff(const PointCloud& data_in, const std::vector<int> &keep, PointCloud& data_out)
174  {
175  const unsigned int np = data_in.points.size();
176 
177  // fill in output data
178  data_out.header = data_in.header;
179 
180  data_out.points.resize(0);
181  data_out.points.reserve(np);
182 
183  for (unsigned int i = 0 ; i < np ; ++i)
184  {
185  if ((keep[i] && invert_) || (!keep[i] && !invert_))
186  {
187  data_out.points.push_back(data_in.points[i]);
188  }
189  }
190  }
191 
192  void fillResult(const PointCloud& data_in, const std::vector<int> &keep, PointCloud& data_out)
193  {
194  const unsigned int np = data_in.points.size();
195 
196  // fill in output data with points that are NOT on the robot
197  data_out.header = data_in.header;
198 
199  data_out.points.resize(0);
200  data_out.points.reserve(np);
201  PointT nan_point;
202  nan_point.x = std::numeric_limits<float>::quiet_NaN();
203  nan_point.y = std::numeric_limits<float>::quiet_NaN();
204  nan_point.z = std::numeric_limits<float>::quiet_NaN();
205  for (unsigned int i = 0 ; i < np ; ++i)
206  {
207  if (keep[i] == robot_self_filter::OUTSIDE)
208  {
209  data_out.points.push_back(data_in.points[i]);
210  }
212  {
213  data_out.points.push_back(nan_point);
214  }
215  }
216  if (keep_organized_) {
217  data_out.width = data_in.width;
218  data_out.height = data_in.height;
219  }
220  }
221 
222  virtual bool updateWithSensorFrame(const std::vector<PointCloud> & data_in, std::vector<PointCloud>& data_out, const std::string& sensor_frame)
223  {
224  sensor_frame_ = sensor_frame;
225  return update(data_in, data_out);
226  }
227 
228  virtual bool update(const std::vector<PointCloud> & data_in, std::vector<PointCloud>& data_out)
229  {
230  bool result = true;
231  data_out.resize(data_in.size());
232  for (unsigned int i = 0 ; i < data_in.size() ; ++i)
233  if (!update(data_in[i], data_out[i]))
234  result = false;
235  return true;
236  }
237 
239  return sm_;
240  }
241 
242  void setSensorFrame(const std::string& frame) {
243  sensor_frame_ = frame;
244  }
245 
246 protected:
247 
250 
252  bool invert_;
253  std::string sensor_frame_;
256 
257 };
258 
259 }
260 
261 #endif //#ifndef FILTERS_SELF_SEE_H_
std::string sensor_frame_
tf::TransformListener tf_
virtual ~SelfFilter(void)
Destructor to clean up.
int size() const
virtual bool update(const PointCloud &data_in, PointCloud &data_out)
Update the filter and return the data seperately.
ros::NodeHandle nh_
virtual bool update(const PointCloud &data_in, PointCloud &data_out, PointCloud &data_diff)
Update the filter and return the data seperately.
void fillDiff(const PointCloud &data_in, const std::vector< int > &keep, PointCloud &data_out)
Type const & getType() const
virtual bool update(const std::vector< PointCloud > &data_in, std::vector< PointCloud > &data_out)
#define ROS_WARN(...)
pcl::PointCloud< PointT > PointCloud
virtual bool updateWithSensorFrame(const std::vector< PointCloud > &data_in, std::vector< PointCloud > &data_out, const std::string &sensor_frame)
robot_self_filter::SelfMask< PointT > * sm_
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void setSensorFrame(const std::string &frame)
bool updateWithSensorFrame(const PointCloud &data_in, PointCloud &data_out, PointCloud &data_diff, const std::string &sensor_frame)
SelfFilter(ros::NodeHandle nh)
Construct the filter.
robot_self_filter::SelfMask< PointT > * getSelfMask()
Computing a mask for a pointcloud that states which points are inside the robot.
Definition: self_mask.h:145
A filter to remove parts of the robot seen in a pointcloud.
bool getParam(const std::string &key, std::string &s) const
void fillResult(const PointCloud &data_in, const std::vector< int > &keep, PointCloud &data_out)
bool hasParam(const std::string &key) const
bool updateWithSensorFrame(const PointCloud &data_in, PointCloud &data_out, const std::string &sensor_frame)
virtual bool configure(void)
#define ROS_DEBUG(...)


pr2_navigation_self_filter
Author(s): Eitan Marder-Eppstein
autogenerated on Mon Jun 10 2019 14:28:54