00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cstdio>
00024
00025 #include "ros/ros.h"
00026 #include "ros/console.h"
00027
00028 #include "tf/transform_listener.h"
00029
00030 #include "sensor_msgs/PointCloud.h"
00031 #include "sensor_msgs/ChannelFloat32.h"
00032 #include "geometry_msgs/Point32.h"
00033
00034 class Cropper
00035 {
00036 public:
00037 Cropper(double zmin, double zmax, const std::string& frame_id)
00038 {
00039 zmin_ = zmin;
00040 zmax_ = zmax;
00041 frame_id_ = frame_id;
00042
00043 sub_ = n.subscribe<sensor_msgs::PointCloud>("full_cloud", 50, &Cropper::cloudCallback, this);
00044 pub_ = n.advertise<sensor_msgs::PointCloud>("full_cloud_cropped", 1);
00045 }
00046
00047 ~Cropper()
00048 {
00049 }
00050 private:
00051 ros::NodeHandle n;
00052 tf::TransformListener tf_;
00053 ros::Subscriber sub_;
00054 ros::Publisher pub_;
00055
00056 double zmin_, zmax_;
00057 std::string frame_id_;
00058
00059 void cloudCallback(const sensor_msgs::PointCloudConstPtr& cloud_in)
00060 {
00061 ROS_INFO("Received message with %d points", (int)cloud_in->points.size());
00062 sensor_msgs::PointCloud cloud_transformed;
00063
00064
00065 if (!tf_.waitForTransform(frame_id_, cloud_in->header.frame_id, cloud_in->header.stamp, ros::Duration(2.0))) return
00066 tf_.transformPointCloud(frame_id_, *cloud_in, cloud_transformed);
00067
00068 sensor_msgs::PointCloud cloud_out;
00069 cloud_out.header = cloud_transformed.header;
00070 for(unsigned int j=0;j<cloud_transformed.channels.size();j++)
00071 {
00072 sensor_msgs::ChannelFloat32 c;
00073 c.name = cloud_transformed.channels[j].name;
00074 cloud_out.channels.push_back(c);
00075 }
00076 for(unsigned int i=0;i<cloud_transformed.points.size();i++)
00077 {
00078 if((cloud_transformed.points[i].z >= zmin_) &&
00079 (cloud_transformed.points[i].z <= zmax_))
00080 {
00081 cloud_out.points.push_back(cloud_transformed.points[i]);
00082 for(unsigned int j=0;j<cloud_transformed.channels.size();j++)
00083 {
00084 cloud_out.channels[j].values.push_back(cloud_transformed.channels[j].values[i]);
00085 }
00086 }
00087 }
00088
00089 pub_.publish(cloud_out);
00090 ROS_INFO("Published message with %d points", (int)cloud_out.points.size());
00091 }
00092 };
00093
00094 #define USAGE "USAGE point_cloud_cropper <zmin> <zmax> <frame>"
00095
00096 int
00097 main(int argc, char** argv)
00098 {
00099 ros::init(argc, argv, "cropper", ros::init_options::AnonymousName);
00100 if (argc != 4)
00101 {
00102 puts(USAGE);
00103 return 1;
00104 }
00105
00106 Cropper c(atof(argv[1]), atof(argv[2]), argv[3]);
00107 ros::spin();
00108 return 0;
00109 }