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 
00035 
00036 #define BOOST_PARAMETER_MAX_ARITY 7
00037 #include "jsk_pcl_ros/octree_voxel_grid.h"
00038 #include <std_msgs/Float32.h>
00039 #include <jsk_topic_tools/color_utils.h>
00040 #include <pcl/common/common.h>
00041 #include <jsk_recognition_utils/pcl_ros_util.h>
00042 
00043 namespace jsk_pcl_ros
00044 {
00045   template <class PointT>
00046   void OctreeVoxelGrid::generateVoxelCloudImpl(const sensor_msgs::PointCloud2ConstPtr& input_msg)
00047   {
00048 
00049     typename pcl::PointCloud<PointT>::Ptr cloud (new pcl::PointCloud<PointT> ());
00050     typename pcl::PointCloud<PointT>::Ptr cloud_voxeled (new pcl::PointCloud<PointT> ());
00051     pcl::fromROSMsg(*input_msg, *cloud);
00052 
00053     
00054     typename pcl::octree::OctreePointCloud<PointT> octree(resolution_);
00055     
00056     octree.setInputCloud(cloud);
00057     octree.addPointsFromInputCloud();
00058     
00059     typename pcl::octree::OctreePointCloud<PointT>::AlignedPointTVector point_vec;
00060     octree.getOccupiedVoxelCenters(point_vec);
00061     
00062     cloud_voxeled->width = point_vec.size();
00063     cloud_voxeled->height = 1;
00064     for (int i = 0; i < point_vec.size(); i++) {
00065       cloud_voxeled->push_back(point_vec[i]);
00066     }
00067 
00068     
00069     sensor_msgs::PointCloud2 output_msg;
00070     toROSMsg(*cloud_voxeled, output_msg);
00071     output_msg.header = input_msg->header;
00072     pub_cloud_.publish(output_msg);
00073 
00074     
00075     if (publish_marker_flag_) {
00076       visualization_msgs::Marker marker_msg;
00077       marker_msg.type = visualization_msgs::Marker::CUBE_LIST;
00078       marker_msg.scale.x = resolution_;
00079       marker_msg.scale.y = resolution_;
00080       marker_msg.scale.z = resolution_;
00081       marker_msg.header = input_msg->header;
00082       marker_msg.pose.orientation.w = 1.0;
00083       if (marker_color_ == "flat") {
00084         marker_msg.color = jsk_topic_tools::colorCategory20(0);
00085         marker_msg.color.a = marker_color_alpha_;
00086       }
00087       
00088       
00089       Eigen::Vector4f minpt, maxpt;
00090       pcl::getMinMax3D<PointT>(*cloud_voxeled, minpt, maxpt);
00091       PointT p;
00092       for (size_t i = 0; i < cloud_voxeled->size(); i++) {
00093         p = cloud_voxeled->at(i);
00094         geometry_msgs::Point point_ros;
00095         point_ros.x = p.x;
00096         point_ros.y = p.y;
00097         point_ros.z = p.z;
00098         marker_msg.points.push_back(point_ros);
00099         if (marker_color_ == "flat") {
00100           marker_msg.colors.push_back(jsk_topic_tools::colorCategory20(0));
00101         }
00102         else if (marker_color_ == "z") {
00103           marker_msg.colors.push_back(jsk_topic_tools::heatColor((p.z - minpt[2]) / (maxpt[2] - minpt[2])));
00104         }
00105         else if (marker_color_ == "x") {
00106           marker_msg.colors.push_back(jsk_topic_tools::heatColor((p.x - minpt[0]) / (maxpt[0] - minpt[0])));
00107         }
00108         else if (marker_color_ == "y") {
00109           marker_msg.colors.push_back(jsk_topic_tools::heatColor((p.y - minpt[1]) / (maxpt[1] - minpt[1])));
00110         }
00111         marker_msg.colors[marker_msg.colors.size() - 1].a = marker_color_alpha_;
00112       }
00113       pub_marker_.publish(marker_msg);
00114 
00115       
00116       visualization_msgs::MarkerArray marker_array_msg;
00117       marker_array_msg.markers.push_back(marker_msg);
00118       pub_marker_array_.publish(marker_array_msg);
00119     }
00120   }
00121 
00122   void OctreeVoxelGrid::generateVoxelCloud(const sensor_msgs::PointCloud2ConstPtr& input_msg)
00123   {
00124     boost::mutex::scoped_lock lock(mutex_);
00125     if (resolution_ == 0.0) {
00126       pub_cloud_.publish(input_msg);
00127       
00128     }
00129     else {
00130       if (jsk_recognition_utils::hasField("rgb", *input_msg) &&
00131           jsk_recognition_utils::hasField("normal_x", *input_msg) &&
00132           jsk_recognition_utils::hasField("normal_y", *input_msg) &&
00133           jsk_recognition_utils::hasField("normal_z", *input_msg)) {
00134         generateVoxelCloudImpl<pcl::PointXYZRGBNormal>(input_msg);
00135       }
00136       else if (jsk_recognition_utils::hasField("rgb", *input_msg)) {
00137         generateVoxelCloudImpl<pcl::PointXYZRGB>(input_msg);
00138       }
00139       else if (jsk_recognition_utils::hasField("normal_x", *input_msg) &&
00140                jsk_recognition_utils::hasField("normal_y", *input_msg) &&
00141                jsk_recognition_utils::hasField("normal_z", *input_msg)) {
00142         generateVoxelCloudImpl<pcl::PointNormal>(input_msg);
00143       }
00144       else {
00145         generateVoxelCloudImpl<pcl::PointXYZ>(input_msg);
00146       }
00147     }
00148     std_msgs::Float32 resolution;
00149     resolution.data = resolution_;
00150     pub_octree_resolution_.publish(resolution);
00151   }
00152 
00153   void OctreeVoxelGrid::subscribe()
00154   {
00155     sub_input_ = pnh_->subscribe("input", 1, &OctreeVoxelGrid::generateVoxelCloud, this);
00156   }
00157 
00158   void OctreeVoxelGrid::unsubscribe()
00159   {
00160     sub_input_.shutdown();
00161   }
00162 
00163   void OctreeVoxelGrid::configCallback(Config &config, uint32_t level)
00164   {
00165     boost::mutex::scoped_lock lock(mutex_);
00166     resolution_ = config.resolution;
00167     publish_marker_flag_ = config.publish_marker;
00168     marker_color_ = config.marker_color;
00169     marker_color_alpha_ = config.marker_color_alpha;
00170   }
00171 
00172   void OctreeVoxelGrid::onInit(void)
00173   {
00174     DiagnosticNodelet::onInit();
00175     srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> > (*pnh_);
00176     dynamic_reconfigure::Server<Config>::CallbackType f =
00177       boost::bind (&OctreeVoxelGrid::configCallback, this, _1, _2);
00178     srv_->setCallback (f);
00179 
00180     pub_cloud_ = advertise<sensor_msgs::PointCloud2>(*pnh_, "output", 1);
00181     pub_marker_ = advertise<visualization_msgs::Marker>(*pnh_, "output_marker", 1);
00182     pub_marker_array_ = advertise<visualization_msgs::MarkerArray>(*pnh_, "output_marker_array", 1);
00183     pub_octree_resolution_ = advertise<std_msgs::Float32>(*pnh_, "output_resolution", 1);
00184 
00185     onInitPostProcess();
00186   }
00187 }
00188 
00189 #include <pluginlib/class_list_macros.h>
00190 PLUGINLIB_EXPORT_CLASS (jsk_pcl_ros::OctreeVoxelGrid, nodelet::Nodelet);