Go to the documentation of this file.00001
00002 #include <ros/ros.h>
00003 #include <sensor_msgs/PointCloud.h>
00004 #include <tf/transform_listener.h>
00005
00006 #include "point_cloud_ros/occupancy_grid.h"
00007 #include "point_cloud_ros/OccupancyGrid.h"
00008
00009 using namespace std;
00010
00011 class PointCloudToOccupancyGrid
00012 {
00013 private:
00014
00015 ros::NodeHandle nh_;
00016 ros::Subscriber sub_points_;
00017 ros::Subscriber sub_og_params_;
00018 ros::Publisher pub_og_;
00019
00020 int queue_size_;
00021 string points_in_, og_out_;
00022
00023 string og_params_;
00024 geometry_msgs::Point32 center_;
00025 geometry_msgs::Point32 resolution_;
00026 geometry_msgs::Point32 size_;
00027 int occupancy_threshold_;
00028 string og_frame_id_;
00029
00030 tf::TransformListener tf_listener;
00031
00032 public:
00033
00034 PointCloudToOccupancyGrid () : nh_ ("~"), queue_size_ (1), points_in_ ("/points_in"), og_out_ ("/og_out"), og_params_ ("/og_params")
00035 {
00036 pub_og_ = nh_.advertise<point_cloud_ros::OccupancyGrid> (og_out_, queue_size_);
00037 sub_points_ = nh_.subscribe (points_in_, queue_size_, &PointCloudToOccupancyGrid::cloud_cb_points, this);
00038 sub_og_params_ = nh_.subscribe(og_params_, queue_size_, &PointCloudToOccupancyGrid::og_params_cb, this);
00039 ROS_INFO ("PointCloudToOccupancyGrid initialized to transform from PointCloud (%s) to OccupancyGrid (%s).", nh_.resolveName (points_in_).c_str (), nh_.resolveName (og_out_).c_str ());
00040
00041 resolution_.x = 0.01;
00042 resolution_.y = 0.01;
00043 resolution_.z = 0.01;
00044
00045 size_.x = 0.1;
00046 size_.y = 0.1;
00047 size_.z = 0.1;
00048
00049 occupancy_threshold_ = 1;
00050 og_frame_id_ = "/base_link";
00051 }
00052
00054 void cloud_cb_points (const sensor_msgs::PointCloudConstPtr &cloud)
00055 {
00056 if (pub_og_.getNumSubscribers () <= 0)
00057 {
00058 ROS_DEBUG ("[occupancy_grid_converter] Got a PointCloud with %d points on %s, but no subscribers.", (int)cloud->points.size(), nh_.resolveName(points_in_).c_str());
00059 return;
00060 }
00061
00062 sensor_msgs::PointCloud c;
00063 c.header = cloud->header;
00064 c.points.resize((cloud->points).size());
00065 for (unsigned int i=0; i<c.points.size(); i++)
00066 c.points[i] = cloud->points[i];
00067
00068 tf_listener.transformPointCloud(og_frame_id_, c, c);
00069
00070 float cx = center_.x;
00071 float cy = center_.y;
00072 float cz = center_.z;
00073
00074 float rx = resolution_.x;
00075 float ry = resolution_.y;
00076 float rz = resolution_.z;
00077
00078 float sx = size_.x;
00079 float sy = size_.y;
00080 float sz = size_.z;
00081
00082 occupancy_grid::OccupancyGrid *v = new
00083 occupancy_grid::OccupancyGrid(cx, cy, cz, sx, sy, sz, rx, ry, rz);
00084 v->fillOccupancyGrid(c);
00085
00086 point_cloud_ros::OccupancyGrid og_msg;
00087 uint32_t* d = v->getData();
00088 int nCells = v->nX() * v->nY() * v->nZ();
00089
00090 og_msg.data.resize(nCells);
00091 for (int i=0; i<nCells; i++)
00092 og_msg.data[i] = d[i];
00093
00094 og_msg.header = c.header;
00095 og_msg.center.x = cx;
00096 og_msg.center.y = cy;
00097 og_msg.center.z = cz;
00098
00099
00100 og_msg.resolution.x = rx;
00101 og_msg.resolution.y = ry;
00102 og_msg.resolution.z = rz;
00103
00104 og_msg.grid_size.x = sx;
00105 og_msg.grid_size.y = sy;
00106 og_msg.grid_size.z = sz;
00107
00108 og_msg.occupancy_threshold = occupancy_threshold_;
00109 pub_og_.publish(og_msg);
00110 delete v;
00111 }
00112
00113 void og_params_cb(const point_cloud_ros::OccupancyGrid &og_param)
00114 {
00115 center_ = og_param.center;
00116 size_ = og_param.grid_size;
00117 resolution_ = og_param.resolution;
00118 occupancy_threshold_ = og_param.occupancy_threshold;
00119 og_frame_id_ = og_param.header.frame_id;
00120 ROS_INFO("og_params_cb called");
00121 }
00122 };
00123
00124
00125 int main (int argc, char** argv)
00126 {
00127
00128 ros::init (argc, argv, "pc_to_og", ros::init_options::AnonymousName);
00129 PointCloudToOccupancyGrid p;
00130 ros::spin();
00131
00132 return (0);
00133 }
00134
00135