scan_to_cloud_filter_chain.cpp
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>
33 
34 
35  */
36 
37 #include <ros/ros.h>
38 #include <sensor_msgs/PointCloud2.h>
39 #include <sensor_msgs/LaserScan.h>
40 
41 #include <float.h>
42 
43 // Laser projection
45 
46 // TF
47 #include <tf/transform_listener.h>
48 #include "tf/message_filter.h"
50 
51 //Filters
52 #include <filters/filter_chain.hpp>
53 
54 #if BUILDING_NODELET
55 #include <nodelet/nodelet.h>
57 
58 #define LASER_INFO NODELET_INFO
59 #define LASER_WARN NODELET_WARN
60 #else
61 #define LASER_INFO ROS_INFO
62 #define LASER_WARN ROS_WARN
63 #endif
64 
65 
69 {
70 public:
71 
72  // ROS related
73  laser_geometry::LaserProjection projector_; // Used to project laser scans
74 
75  double laser_max_range_; // Used in laser scan projection
76  int window_;
77 
78  bool high_fidelity_; // High fidelity (interpolating time across scan)
79  std::string target_frame_; // Target frame for high fidelity result
80  std::string scan_topic_, cloud_topic_;
81 
84  std::string name_;
85 
86  // TF
88 
91 
92  double tf_tolerance_;
96  unsigned int channel_options_;
97 
98  // Timer for displaying deprecation warnings
110 
112  ScanToCloudFilterChain (ros::NodeHandle& nh_, ros::NodeHandle& pnh, const std::string& name) :
113  laser_max_range_ (DBL_MAX), nh(nh_), private_nh(pnh), name_(name), filter_(tf_, "", 50),
114  cloud_filter_chain_("sensor_msgs::PointCloud2"), scan_filter_chain_("sensor_msgs::LaserScan")
115  {
116  private_nh.param("high_fidelity", high_fidelity_, false);
117  private_nh.param("notifier_tolerance", tf_tolerance_, 0.03);
118  private_nh.param("target_frame", target_frame_, std::string ("base_link"));
119 
120  // DEPRECATED with default value
122 
123  // DEPRECATED
128  using_cloud_filters_deprecated_ = private_nh.hasParam("cloud_filters/filter_chain");
129  using_scan_filters_deprecated_ = private_nh.hasParam("scan_filters/filter_chain");
130  using_cloud_filters_wrong_deprecated_ = private_nh.hasParam("cloud_filters/cloud_filter_chain");
131  using_scan_filters_wrong_deprecated_ = private_nh.hasParam("scan_filters/scan_filter_chain");
132 
133 
134  private_nh.param("filter_window", window_, 2);
135  private_nh.param("laser_max_range", laser_max_range_, DBL_MAX);
136  private_nh.param("scan_topic", scan_topic_, std::string("tilt_scan"));
137  private_nh.param("cloud_topic", cloud_topic_, std::string("tilt_laser_cloud_filtered"));
138  private_nh.param("incident_angle_correction", incident_angle_correction_, true);
139 
141  bool hasChannel;
142  private_nh.param("cloud_channel_intensity", hasChannel, true);
143  if (hasChannel)
145  private_nh.param("cloud_channel_index", hasChannel, true);
146  if (hasChannel)
148  private_nh.param("cloud_channel_distance", hasChannel, true);
149  if (hasChannel)
151  private_nh.param("cloud_channel_timestamp", hasChannel, true);
152  if (hasChannel)
154  private_nh.param("cloud_channel_viewpoint", hasChannel, false);
155  if (hasChannel)
157 
159  filter_.registerCallback(boost::bind(&ScanToCloudFilterChain::scanCallback, this, boost::placeholders::_1));
161 
164  else
165  sub_.subscribe(nh, "scan", 50);
166 
168 
170  cloud_pub_ = nh.advertise<sensor_msgs::PointCloud2> (cloud_topic_, 10);
171  else
172  cloud_pub_ = nh.advertise<sensor_msgs::PointCloud2> ("cloud_filtered", 10);
173 
174  std::string cloud_filter_xml;
175 
177  cloud_filter_chain_.configure("cloud_filters/filter_chain", private_nh);
179  cloud_filter_chain_.configure("cloud_filters/cloud_filter_chain", private_nh);
180  else
181  cloud_filter_chain_.configure("cloud_filter_chain", private_nh);
182 
184  scan_filter_chain_.configure("scan_filter/filter_chain", private_nh);
186  scan_filter_chain_.configure("scan_filters/scan_filter_chain", private_nh);
187  else
188  scan_filter_chain_.configure("scan_filter_chain", private_nh);
189 
190  deprecation_timer_ = nh.createTimer(ros::Duration(5.0), [this](auto& event){ this->deprecation_warn(event); });
191 
192  LASER_INFO("Scan to cloud filter initialized.");
193  }
194 
195  // We use a deprecation warning on a timer to avoid warnings getting lost in the noise
197  {
199  LASER_WARN("Use of '~scan_topic' parameter in scan_to_cloud_filter_chain has been deprecated.");
200 
202  LASER_WARN("Use of '~cloud_topic' parameter in scan_to_cloud_filter_chain has been deprecated.");
203 
205  LASER_WARN("Use of '~laser_max_range' parameter in scan_to_cloud_filter_chain has been deprecated.");
206 
208  LASER_WARN("Use of '~filter_window' parameter in scan_to_cloud_filter_chain has been deprecated.");
209 
211  LASER_WARN("Use of default '~target_frame' parameter in scan_to_cloud_filter_chain has been deprecated. Default currently set to 'base_link' please set explicitly as appropriate.");
212 
214  LASER_WARN("Use of '~cloud_filters/filter_chain' parameter in scan_to_cloud_filter_chain has been deprecated. Replace with '~cloud_filter_chain'");
215 
217  LASER_WARN("Use of '~scan_filters/filter_chain' parameter in scan_to_cloud_filter_chain has been deprecated. Replace with '~scan_filter_chain'");
218 
220  LASER_WARN("Use of '~cloud_filters/cloud_filter_chain' parameter in scan_to_cloud_filter_chain is incorrect. Please Replace with '~cloud_filter_chain'");
221 
223  LASER_WARN("Use of '~scan_filters/scan_filter_chain' parameter in scan_to_scan_filter_chain is incorrect. Please Replace with '~scan_filter_chain'");
224 
225  }
226 
227  std::string getName() const {
228  return this->name_;
229  }
230 
231 
233  void
234  scanCallback (const sensor_msgs::LaserScan::ConstPtr& scan_msg)
235  {
236  // sensor_msgs::LaserScan scan_msg = *scan_in;
237 
238  sensor_msgs::LaserScan filtered_scan;
239  scan_filter_chain_.update (*scan_msg, filtered_scan);
240 
241  // Project laser into point cloud
242  sensor_msgs::PointCloud2 scan_cloud;
243 
244  //\TODO CLEAN UP HACK
245  // This is a trial at correcting for incident angles. It makes many assumptions that do not generalise
247  {
248  for (unsigned int i = 0; i < filtered_scan.ranges.size(); i++)
249  {
250  double angle = filtered_scan.angle_min + i * filtered_scan.angle_increment;
251  filtered_scan.ranges[i] = filtered_scan.ranges[i] + 0.03 * exp(-fabs(sin(angle)));
252  }
253  }
254 
255  // Transform into a PointCloud message
256 
257  if (high_fidelity_)
258  {
259  try
260  {
262  }
263  catch (tf::TransformException &ex)
264  {
265  LASER_WARN("High fidelity enabled, but TF returned a transform exception to frame %s: %s", target_frame_.c_str (), ex.what ());
266  return;
267  //projector_.projectLaser (filtered_scan, scan_cloud, laser_max_range_, preservative_, mask);
268  }
269  }
270  else
271  {
273  }
274 
275  sensor_msgs::PointCloud2 filtered_cloud;
276  cloud_filter_chain_.update (scan_cloud, filtered_cloud);
277 
278  cloud_pub_.publish(filtered_cloud);
279  }
280 
281 } ;
282 
283 #if BUILDING_NODELET
284 
285 class ScanToCloudFilterChainNodelet : public nodelet::Nodelet
286 {
287  std::unique_ptr<ScanToCloudFilterChain> chain_;
288 
289  void onInit() override {
290  chain_ = std::unique_ptr<ScanToCloudFilterChain>(new ScanToCloudFilterChain(getNodeHandle(), getPrivateNodeHandle(), getName()));
291  }
292 };
293 
294 PLUGINLIB_EXPORT_CLASS(ScanToCloudFilterChainNodelet, nodelet::Nodelet)
295 #else
296 int
297 main (int argc, char** argv)
298 {
299  ros::init (argc, argv, "scan_to_cloud_filter_chain");
300  ros::NodeHandle nh, pnh("~");
301  ScanToCloudFilterChain f(nh, pnh, "");
302 
303  ros::spin();
304 
305  return (0);
306 }
307 #endif
ScanToCloudFilterChain::getName
std::string getName() const
Definition: scan_to_cloud_filter_chain.cpp:227
ros::Publisher
nodelet::Nodelet::getNodeHandle
ros::NodeHandle & getNodeHandle() const
ScanToCloudFilterChain::tf_tolerance_
double tf_tolerance_
Definition: scan_to_cloud_filter_chain.cpp:92
angle
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
LASER_INFO
#define LASER_INFO
Definition: scan_to_cloud_filter_chain.cpp:61
ScanToCloudFilterChain::incident_angle_correction_
bool incident_angle_correction_
Definition: scan_to_cloud_filter_chain.cpp:109
ros::init
ROSCPP_DECL void init(const M_string &remappings, const std::string &name, uint32_t options=0)
ScanToCloudFilterChain::using_cloud_topic_deprecated_
bool using_cloud_topic_deprecated_
Definition: scan_to_cloud_filter_chain.cpp:101
tf::MessageFilter::setTolerance
void setTolerance(const ros::Duration &tolerance)
laser_geometry::LaserProjection
ScanToCloudFilterChain::using_scan_filters_wrong_deprecated_
bool using_scan_filters_wrong_deprecated_
Definition: scan_to_cloud_filter_chain.cpp:107
ros.h
ScanToCloudFilterChain::tf_
tf::TransformListener tf_
Definition: scan_to_cloud_filter_chain.cpp:87
ScanToCloudFilterChain::target_frame_
std::string target_frame_
Definition: scan_to_cloud_filter_chain.cpp:79
laser_geometry::channel_option::Index
Index
ScanToCloudFilterChain::using_cloud_filters_deprecated_
bool using_cloud_filters_deprecated_
Definition: scan_to_cloud_filter_chain.cpp:106
ScanToCloudFilterChain::cloud_pub_
ros::Publisher cloud_pub_
Definition: scan_to_cloud_filter_chain.cpp:95
laser_geometry::LaserProjection::transformLaserScanToPointCloud
void transformLaserScanToPointCloud(const std::string &target_frame, const sensor_msgs::LaserScan &scan_in, sensor_msgs::PointCloud &cloud_out, tf::Transformer &tf, double range_cutoff, int channel_options=channel_option::Default)
tf::MessageFilter::connectInput
void connectInput(F &f)
ScanToCloudFilterChain::sub_
message_filters::Subscriber< sensor_msgs::LaserScan > sub_
Definition: scan_to_cloud_filter_chain.cpp:89
ScanToCloudFilterChain::using_filter_window_deprecated_
bool using_filter_window_deprecated_
Definition: scan_to_cloud_filter_chain.cpp:104
ScanToCloudFilterChain::cloud_filter_chain_
filters::FilterChain< sensor_msgs::PointCloud2 > cloud_filter_chain_
Definition: scan_to_cloud_filter_chain.cpp:93
laser_geometry::channel_option::None
None
ScanToCloudFilterChain::using_laser_max_range_deprecated_
bool using_laser_max_range_deprecated_
Definition: scan_to_cloud_filter_chain.cpp:103
nodelet::Nodelet::getPrivateNodeHandle
ros::NodeHandle & getPrivateNodeHandle() const
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
ScanToCloudFilterChain::private_nh
ros::NodeHandle private_nh
Definition: scan_to_cloud_filter_chain.cpp:83
ros::NodeHandle::advertise
Publisher advertise(AdvertiseOptions &ops)
f
f
filters::FilterChain::configure
bool configure(std::string param_name, ros::NodeHandle node=ros::NodeHandle())
ScanToCloudFilterChain::using_scan_filters_deprecated_
bool using_scan_filters_deprecated_
Definition: scan_to_cloud_filter_chain.cpp:105
message_filters::Subscriber< sensor_msgs::LaserScan >
ScanToCloudFilterChain::cloud_topic_
std::string cloud_topic_
Definition: scan_to_cloud_filter_chain.cpp:80
nodelet::Nodelet::onInit
virtual void onInit()=0
filters::FilterChain< sensor_msgs::PointCloud2 >
laser_geometry.h
ScanToCloudFilterChain::scan_topic_
std::string scan_topic_
Definition: scan_to_cloud_filter_chain.cpp:80
ScanToCloudFilterChain::using_scan_topic_deprecated_
bool using_scan_topic_deprecated_
Definition: scan_to_cloud_filter_chain.cpp:100
ScanToCloudFilterChain::laser_max_range_
double laser_max_range_
Definition: scan_to_cloud_filter_chain.cpp:75
filters::FilterChain::update
bool update(const T &data_in, T &data_out)
PLUGINLIB_EXPORT_CLASS
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
message_filter.h
ScanToCloudFilterChain::deprecation_timer_
ros::Timer deprecation_timer_
Definition: scan_to_cloud_filter_chain.cpp:99
ScanToCloudFilterChain::filter_
tf::MessageFilter< sensor_msgs::LaserScan > filter_
Definition: scan_to_cloud_filter_chain.cpp:90
ScanToCloudFilterChain::using_default_target_frame_deprecated_
bool using_default_target_frame_deprecated_
Definition: scan_to_cloud_filter_chain.cpp:102
subscriber.h
ScanToCloudFilterChain::projector_
laser_geometry::LaserProjection projector_
Definition: scan_to_cloud_filter_chain.cpp:73
ScanToCloudFilterChain
Definition: scan_to_cloud_filter_chain.cpp:68
ros::NodeHandle::hasParam
bool hasParam(const std::string &key) const
main
int main(int argc, char **argv)
Definition: scan_to_cloud_filter_chain.cpp:297
ScanToCloudFilterChain::name_
std::string name_
Definition: scan_to_cloud_filter_chain.cpp:84
ros::TimerEvent
laser_geometry::channel_option::Viewpoint
Viewpoint
ScanToCloudFilterChain::channel_options_
unsigned int channel_options_
Definition: scan_to_cloud_filter_chain.cpp:96
ScanToCloudFilterChain::ScanToCloudFilterChain
ScanToCloudFilterChain(ros::NodeHandle &nh_, ros::NodeHandle &pnh, const std::string &name)
Definition: scan_to_cloud_filter_chain.cpp:112
message_filters::Subscriber::subscribe
void subscribe()
ScanToCloudFilterChain::high_fidelity_
bool high_fidelity_
Definition: scan_to_cloud_filter_chain.cpp:78
transform_listener.h
laser_geometry::channel_option::Distance
Distance
nodelet::Nodelet
laser_geometry::channel_option::Timestamp
Timestamp
ScanToCloudFilterChain::scanCallback
void scanCallback(const sensor_msgs::LaserScan::ConstPtr &scan_msg)
Definition: scan_to_cloud_filter_chain.cpp:234
tf::MessageFilter::setTargetFrame
void setTargetFrame(const std::string &target_frame)
nodelet.h
tf::MessageFilter< sensor_msgs::LaserScan >
class_list_macros.hpp
tf::TransformListener
nodelet::Nodelet::getName
const std::string & getName() const
ros::NodeHandle::param
T param(const std::string &param_name, const T &default_val) const
ScanToCloudFilterChain::nh
ros::NodeHandle nh
Definition: scan_to_cloud_filter_chain.cpp:82
ros::spin
ROSCPP_DECL void spin()
ScanToCloudFilterChain::window_
int window_
Definition: scan_to_cloud_filter_chain.cpp:76
filter_chain.hpp
tf2::TransformException
laser_geometry::channel_option::Intensity
Intensity
ros::NodeHandle::createTimer
Timer createTimer(Duration period, const TimerCallback &callback, bool oneshot=false, bool autostart=true) const
ros::Duration
ros::Timer
LASER_WARN
#define LASER_WARN
Definition: scan_to_cloud_filter_chain.cpp:62
ScanToCloudFilterChain::scan_filter_chain_
filters::FilterChain< sensor_msgs::LaserScan > scan_filter_chain_
Definition: scan_to_cloud_filter_chain.cpp:94
ScanToCloudFilterChain::using_cloud_filters_wrong_deprecated_
bool using_cloud_filters_wrong_deprecated_
Definition: scan_to_cloud_filter_chain.cpp:108
ScanToCloudFilterChain::deprecation_warn
void deprecation_warn(const ros::TimerEvent &e)
Definition: scan_to_cloud_filter_chain.cpp:196
ros::NodeHandle


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