pcdfilter_pa_node.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 * *
3 * pcdfilter_pa_node.cpp *
4 * ===================== *
5 * *
6 *******************************************************************************
7 * *
8 * github repository *
9 * https://github.com/TUC-ProAut/ros_pcdfilter *
10 * *
11 * Chair of Automation Technology, Technische Universität Chemnitz *
12 * https://www.tu-chemnitz.de/etit/proaut *
13 * *
14 *******************************************************************************
15 * *
16 * New BSD License *
17 * *
18 * Copyright (c) 2015-2018, Peter Weissig, Technische Universität Chemnitz *
19 * All rights reserved. *
20 * *
21 * Redistribution and use in source and binary forms, with or without *
22 * modification, are permitted provided that the following conditions are met: *
23 * * Redistributions of source code must retain the above copyright *
24 * notice, this list of conditions and the following disclaimer. *
25 * * Redistributions in binary form must reproduce the above copyright *
26 * notice, this list of conditions and the following disclaimer in the *
27 * documentation and/or other materials provided with the distribution. *
28 * * Neither the name of the Technische Universität Chemnitz nor the *
29 * names of its contributors may be used to endorse or promote products *
30 * derived from this software without specific prior written permission. *
31 * *
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" *
33 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *
35 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY *
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR *
38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
39 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
42 * DAMAGE. *
43 * *
44 ******************************************************************************/
45 
46 // local headers
48 
49 // ros headers
51 
52 // standard headers
53 #include <string>
54 #include <math.h>
55 
56 //**************************[main]*********************************************
57 int main(int argc, char **argv) {
58 
59  ros::init(argc, argv, "pcd_filter_pa_node");
60  cPcdFilterPaNode pcd_filter;
61 
62  ros::spin();
63 
64  return 0;
65 }
66 
67 //**************************[cPcdFilterPaNode]*********************************
69  cParameterPaRos paramloader;
70 
71  std::vector<std::string> temp_filter;
72  paramloader.load("~/filters" , temp_filter);
73 
74  paramloader.load("~/skip_count" , input_throttle_.skip_count_ );
75  paramloader.load("~/skip_time" , input_throttle_.skip_time_ );
76 
77  paramloader.load("~/tf_lookup_time" , filters_.tf_lookup_time_ );
78  paramloader.load("~/buffer_pointcloud", rosparams_.buffer_pointcloud_);
79  paramloader.load("~/debugging" , rosparams_.debugging_ );
80  paramloader.load("~/laser_nan_replacement_value",
82 
83  bool enabled = true;
84  paramloader.load("~/enabled" , enabled );
85 
86 
87  bool remapping = false;
88  remapping|= paramloader.loadTopic("~/topic_in_cloud" ,
90  remapping|= paramloader.loadTopic("~/topic_in_cloud_old",
92  remapping|= paramloader.loadTopic("~/topic_in_laser" ,
94 
95  paramloader.loadTopic("~/topic_out_cloud" ,
97 
98  // Publisher for filtered pointcloud
99  pub_pcd_ = nh_.advertise<sensor_msgs::PointCloud2>(
100  nodeparams_.topic_out_cloud_, 10, true);
101 
102  std::string str_service = paramloader.resolveRessourcename("~/");
103 
104  // Service for adding additional filters
105  ser_filter_ = nh_.advertiseService( str_service + "filter",
107 
108  // Service for adding additional filters
109  ser_add_filters_ = nh_.advertiseService( str_service + "add_filters",
111  // Service for changing all filters
112  ser_change_filters_ = nh_.advertiseService( str_service + "change_filters",
114 
115  // Service for enabling filter node
116  ser_enable_ = nh_.advertiseService( str_service + "enable",
118  // Service for disabling filter node
119  ser_disable_ = nh_.advertiseService( str_service + "disable",
121 
122  if (enabled) { enable();} else { disable();}
123 
124  if (! remapping) {
126  ": no input topic was remapped\n" <<
127  "this seems to be a mistake - try the following:\n" <<
128  " rosrun pcdfilter_pa pcdfilter_pa_node _topic_in_cloud:=" <<
129  "/new_in_topic _topic_out_cloud:=/new_out_topic");
130  }
131 
132  addFilters(temp_filter);
133 }
134 
135 //**************************[~cPcdFilterPaNode]********************************
137 }
138 
139 //**************************[setCloudCallbackSub]******************************
141  const sensor_msgs::PointCloud2ConstPtr &msg) {
142 
143  if (rosparams_.debugging_) {
144  int count = (msg->width > 1 ? msg->width : 1) * msg->height;
145  ROS_INFO("%s: #### received new pointcloud (%d)",
146  ros::this_node::getName().data(), count);
147  }
148  if (! input_throttle_.checkNewInput(msg->header.stamp)) {
149  if (rosparams_.debugging_) {
150  ROS_INFO("%s: skipped (input throttle)",
151  ros::this_node::getName().data());
152  }
153 
154  return;
155  }
156 
157  if (! updateTf(tf_listener_, msg->header.frame_id, msg->header.stamp)) {
158  return;
159  }
160 
161  sensor_msgs::PointCloud2Ptr result;
162  if (filterCloud(msg, result)) {
163  if (rosparams_.debugging_) {
164  ROS_INFO("%s: publishing filtered pointcloud",
165  ros::this_node::getName().data());
166  }
167  pub_pcd_.publish(result);
168  }
169 }
170 
171 //**************************[setCloudOldCallbackSub]***************************
173  const sensor_msgs::PointCloudConstPtr &msg) {
174 
176 }
177 
178 //**************************[setCloudLaserCallbackSub]*************************
180  const sensor_msgs::LaserScanConstPtr &msg) {
181 
183 }
184 
185 //**************************[addFiltersCallbackSrv]****************************
187  pcdfilter_pa::PcdFilterPaFilter::Request &req,
188  pcdfilter_pa::PcdFilterPaFilter::Response &res) {
189 
190  addFilters(req.new_filter);
191  res.current_filter = filters_.get();
192 
194  if (! updateTf(tf_listener_)) {
195  return true;
196  }
197  sensor_msgs::PointCloud2Ptr cloud;
198  if (filterCloud(cloud)){
199  pub_pcd_.publish(cloud);
200  }
201  }
202  return true;
203 }
204 
205 //**************************[filterCallbackSrv]********************************
207  pcdfilter_pa::PcdFilterPaCloud::Request &req,
208  pcdfilter_pa::PcdFilterPaCloud::Response &res) {
209 
210  res.ok = false;
211 
212  sensor_msgs::PointCloud2ConstPtr msg(&req.in_cloud);
213  sensor_msgs::PointCloud2Ptr result;
214 
215  if (! updateTf(tf_listener_, msg->header.frame_id,
216  msg->header.stamp)) {
217  return true;
218  }
219 
220  if (filterCloud(msg, result)) {
221  ROS_INFO("%s: service call for filtering",
222  ros::this_node::getName().data());
223 
224  sensor_msgs::PointCloud2_<std::allocator<void> >::_data_type temp;
225  temp.swap(result->data);
226  res.out_cloud = *result;
227  res.out_cloud.data.swap(temp);
228 
229  res.ok = true;
230  }
231  return true;
232 
233 }
234 
235 //**************************[addFilters]***************************************
237  const std::vector<std::string> &new_filters) {
238 
239  for (int i = 0; i < new_filters.size(); i++) {
240  if (filters_.add(new_filters[i])) {
241  ROS_INFO("%s: added new filter definition \"%s\"",
242  ros::this_node::getName().data(), filters_.getLast().data());
243  } else {
244  ROS_WARN("%s: error in filter definition \"%s\"",
245  ros::this_node::getName().data(), filters_.getLast().data());
246  }
247  }
248 }
249 
250 //**************************[changeFiltersCallbackSrv]*************************
252  pcdfilter_pa::PcdFilterPaFilter::Request &req,
253  pcdfilter_pa::PcdFilterPaFilter::Response &res) {
254 
255  int count = filters_.size();
256  filters_.clear();
257 
258  ROS_INFO("%s: removed all filters (%d)",
259  ros::this_node::getName().data(), count);
260  return addFiltersCallbackSrv(req, res);
261 }
262 
263 //**************************[enableCallbackSrv]********************************
264 bool cPcdFilterPaNode::enableCallbackSrv(std_srvs::Empty::Request &req,
265  std_srvs::Empty::Response &res) {
266 
267  enable();
268  return true;
269 }
270 
271 //**************************[disableCallbackSrv]*******************************
272 bool cPcdFilterPaNode::disableCallbackSrv(std_srvs::Empty::Request &req,
273  std_srvs::Empty::Response &res) {
274 
275  disable();
276  return true;
277 }
278 
279 //**************************[enable]*******************************************
281 
282  ROS_INFO("%s: node enabled :-)", ros::this_node::getName().data());
283 
284  // Subscriber for pointclouds
285  if (nodeparams_.topic_in_cloud_ != "") {
286  sub_pcd_ = nh_.subscribe<sensor_msgs::PointCloud2>(
289  }
290 
291  // Subscriber for pointclouds (old format)
292  if (nodeparams_.topic_in_cloud_old_ != "") {
293  sub_pcd_old_ = nh_.subscribe<sensor_msgs::PointCloud>(
296  }
297 
298  // Subscriber for laserscans
299  if (nodeparams_.topic_in_laser_ != "") {
300  sub_laser_ = nh_.subscribe<sensor_msgs::LaserScan>(
303  }
304 }
305 
306 //**************************[disable]******************************************
308 
309  ROS_INFO("%s: node disabled :-(", ros::this_node::getName().data());
310 
311  sub_pcd_.shutdown() ;
313  sub_laser_.shutdown() ;
314 }
std::string topic_in_laser_
name of the topic for subscribing a laserscan ("~in_laser")
void addFilters(const std::vector< std::string > &new_filters)
function for adding several filters and giving feedback
void disable(void)
function for deactivating this node (disabling inputs)
std::string getLast(void) const
ros::ServiceServer ser_add_filters_
service for adding additional filters
void publish(const boost::shared_ptr< M > &message) const
std::string topic_in_cloud_old_
name of the topic for subscribing a pointcloud ("~in_cloud_old")
cPcdFilterPaRosThrottle input_throttle_
object for input throttling - e.g. only every 5th pointcloud
ros::ServiceServer ser_filter_
service for filtering
bool enableCallbackSrv(std_srvs::Empty::Request &req, std_srvs::Empty::Response &res)
callback function for enabling filter node
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
int main(int argc, char **argv)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
tf::TransformListener tf_listener_
for getting all necessary tfs
ros::Subscriber sub_pcd_old_
subscriber for a pointcloud (old format)
ROSCPP_DECL const std::string & getName()
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
bool loadTopic(const std::string name, std::string &value, const bool print_default=true) const
#define ROS_WARN(...)
cPcdFilterPaRosParameter rosparams_
ros specific parameter
bool debugging_
flag for extended output
bool load(const std::string name, bool &value, const bool print_default=true) const
ROSCPP_DECL void spin(Spinner &spinner)
bool changeFiltersCallbackSrv(pcdfilter_pa::PcdFilterPaFilter::Request &req, pcdfilter_pa::PcdFilterPaFilter::Response &res)
callback function for changing filters
ros::ServiceServer ser_enable_
service for enabling node
std::string topic_in_cloud_
name of the topic for subscribing a pointcloud ("~in_cloud")
bool updateTf(const tf::TransformListener &tf_listener, const std::string base_frame, const ros::Time time=ros::Time::now())
bool addFiltersCallbackSrv(pcdfilter_pa::PcdFilterPaFilter::Request &req, pcdfilter_pa::PcdFilterPaFilter::Response &res)
callback function for adding additional filters
cPcdFilterPaNode()
default constructor
void enable(void)
function for activating this node (enabling inputs)
#define ROS_INFO(...)
sensor_msgs::PointCloud2Ptr convertCloud(const sensor_msgs::PointCloudConstPtr &msg) const
converts the given pointcloud to newer format
cPcdFilterPaRosFilters filters_
object for filter handling
ros::Subscriber sub_laser_
subscriber for a laserscan
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ros::Subscriber sub_pcd_
subscriber for a pointcloud
#define ROS_WARN_STREAM(args)
static std::string resolveRessourcename(const std::string name)
void setCloudLaserCallbackSub(const sensor_msgs::LaserScanConstPtr &msg)
callback function for receiving a laserscan
~cPcdFilterPaNode()
default destructor
bool filterCloud(const sensor_msgs::PointCloud2ConstPtr &msg, sensor_msgs::PointCloud2Ptr &result)
filters the given pointcloud
bool add(std::string filter)
ros::NodeHandle nh_
node handler for topic subscription and advertising
cPcdFilterPaNodeParameter nodeparams_
ros specific variables, which will be read from Parameterserver
bool disableCallbackSrv(std_srvs::Empty::Request &req, std_srvs::Empty::Response &res)
callback function for disabling filter node
bool checkNewInput(ros::Time time=ros::Time::now())
checks if the current data is accepted
void setCloudCallbackSub(const sensor_msgs::PointCloud2ConstPtr &msg)
callback function for receiving a pointcloud
ros::Publisher pub_pcd_
publisher for filtered pointcloud
bool filterCallbackSrv(pcdfilter_pa::PcdFilterPaCloud::Request &req, pcdfilter_pa::PcdFilterPaCloud::Response &res)
callback function for filtering via service
ros::ServiceServer ser_change_filters_
service for changing filters
ros::ServiceServer ser_disable_
service for disabling node
std::vector< std::string > get(void) const
void setCloudOldCallbackSub(const sensor_msgs::PointCloudConstPtr &msg)
callback function for receiving a pointcloud (old format)


pcdfilter_pa
Author(s):
autogenerated on Mon Dec 23 2019 03:56:23