Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00037 #include <ros/ros.h>
00038 #include <sstream>
00039 #include "robot_self_filter/self_see_filter.h"
00040 #include <tf/message_filter.h>
00041 #include <message_filters/subscriber.h>
00042 #include <pcl_conversions/pcl_conversions.h>
00043 #include <pcl/filters/voxel_grid.h>
00044
00045 class SelfFilter
00046 {
00047 public:
00048 SelfFilter (void): nh_ ("~")
00049 {
00050 nh_.param<std::string> ("sensor_frame", sensor_frame_, std::string ());
00051 nh_.param<double> ("subsample_value", subsample_param_, 0.01);
00052 self_filter_ = new filters::SelfFilter<pcl::PointCloud<pcl::PointXYZ> > (nh_);
00053
00054 sub_ = new message_filters::Subscriber<sensor_msgs::PointCloud2> (root_handle_, "cloud_in", 1);
00055 mn_ = new tf::MessageFilter<sensor_msgs::PointCloud2> (*sub_, tf_, "", 1);
00056
00057
00058 pointCloudPublisher_ = root_handle_.advertise<sensor_msgs::PointCloud2>("cloud_out", 1);
00059 std::vector<std::string> frames;
00060 self_filter_->getSelfMask()->getLinkNames(frames);
00061 if (frames.empty())
00062 {
00063 ROS_DEBUG ("No valid frames have been passed into the self filter. Using a callback that will just forward scans on.");
00064 no_filter_sub_ = root_handle_.subscribe<sensor_msgs::PointCloud2> ("cloud_in", 1, boost::bind(&SelfFilter::noFilterCallback, this, _1));
00065 }
00066 else
00067 {
00068 ROS_DEBUG ("Valid frames were passed in. We'll filter them.");
00069 mn_->setTargetFrames (frames);
00070 mn_->registerCallback (boost::bind (&SelfFilter::cloudCallback, this, _1));
00071 }
00072 }
00073
00074 ~SelfFilter (void)
00075 {
00076 delete self_filter_;
00077 delete mn_;
00078 delete sub_;
00079 }
00080
00081 private:
00082 void
00083 noFilterCallback (const sensor_msgs::PointCloud2ConstPtr &cloud)
00084 {
00085 pointCloudPublisher_.publish (cloud);
00086 ROS_DEBUG ("Self filter publishing unfiltered frame");
00087 }
00088
00089 void cloudCallback (const sensor_msgs::PointCloud2ConstPtr &cloud2)
00090 {
00091 ROS_DEBUG ("Got pointcloud that is %f seconds old", (ros::Time::now() - cloud2->header.stamp).toSec ());
00092 std::vector<int> mask;
00093 ros::WallTime tm = ros::WallTime::now ();
00094
00095 pcl::PointCloud<pcl::PointXYZ> cloud, cloud_filtered;
00096 pcl::fromROSMsg (*cloud2, cloud);
00097
00098 if (subsample_param_ != 0)
00099 {
00100 pcl::PointCloud<pcl::PointXYZ> cloud_downsampled;
00101
00102 grid_.setLeafSize (subsample_param_, subsample_param_, subsample_param_);
00103 grid_.setInputCloud (boost::make_shared <pcl::PointCloud<pcl::PointXYZ> > (cloud));
00104 grid_.filter (cloud_downsampled);
00105
00106 self_filter_->updateWithSensorFrame (cloud_downsampled, cloud_filtered, sensor_frame_);
00107 }
00108 else
00109 {
00110 self_filter_->updateWithSensorFrame (cloud, cloud_filtered, sensor_frame_);
00111 }
00112
00113 double sec = (ros::WallTime::now() - tm).toSec ();
00114
00115 ROS_DEBUG ("Self filter: reduced %d points to %d points in %f seconds", (int)cloud.points.size(), (int)cloud_filtered.points.size (), sec);
00116
00117 sensor_msgs::PointCloud2 out;
00118 pcl::toROSMsg (cloud_filtered, out);
00119 pointCloudPublisher_.publish (out);
00120 }
00121
00122 tf::TransformListener tf_;
00123
00124 ros::NodeHandle nh_, root_handle_;
00125
00126 tf::MessageFilter<sensor_msgs::PointCloud2> *mn_;
00127 message_filters::Subscriber<sensor_msgs::PointCloud2> *sub_;
00128
00129 filters::SelfFilter<pcl::PointCloud<pcl::PointXYZ> > *self_filter_;
00130 std::string sensor_frame_;
00131 double subsample_param_;
00132
00133 ros::Publisher pointCloudPublisher_;
00134 ros::Subscriber no_filter_sub_;
00135
00136 pcl::VoxelGrid<pcl::PointXYZ> grid_;
00137 };
00138
00139 int
00140 main (int argc, char **argv)
00141 {
00142 ros::init (argc, argv, "self_filter");
00143
00144 SelfFilter s;
00145 ros::spin ();
00146
00147 return (0);
00148 }