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_utils/polygon_flipper.h"
00038 #include "jsk_recognition_utils/pcl_conversion_util.h"
00039 #include <algorithm>
00040 #include <iterator>
00041 
00042 namespace jsk_pcl_ros_utils
00043 {
00044   void PolygonFlipper::onInit()
00045   {
00046     DiagnosticNodelet::onInit();
00047     if (!pnh_->getParam("sensor_frame", sensor_frame_)) {
00048       NODELET_FATAL("no ~sensor_frame is specified");
00049       return;
00050     }
00051 
00052     pnh_->param<int>("queue_size", queue_size_, 100);
00053     pnh_->param<bool>("use_indices", use_indices_, true);
00054 
00055     tf_listener_ = jsk_recognition_utils::TfListenerSingleton::getInstance();
00056     pub_polygons_ = advertise<jsk_recognition_msgs::PolygonArray>(
00057       *pnh_, "output/polygons", 1);
00058     pub_coefficients_ = advertise<jsk_recognition_msgs::ModelCoefficientsArray>(
00059       *pnh_, "output/coefficients", 1);
00060     if (use_indices_)
00061       pub_indices_ = advertise<jsk_recognition_msgs::ClusterPointIndices>(
00062         *pnh_, "output/indices", 1);
00063 
00064     onInitPostProcess();
00065   }
00066 
00067   void PolygonFlipper::subscribe()
00068   {
00069     sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(queue_size_);
00070     sub_polygons_.subscribe(*pnh_, "input/polygons", 1);
00071     sub_coefficients_.subscribe(*pnh_, "input/coefficients", 1);
00072     if (use_indices_) {
00073       sub_indices_.subscribe(*pnh_, "input/indices", 1);
00074       sync_->connectInput(sub_polygons_, sub_indices_, sub_coefficients_);
00075     } else {
00076       sub_polygons_.registerCallback(boost::bind(&PolygonFlipper::fillEmptyIndices, this, _1));
00077       sync_->connectInput(sub_polygons_, sub_indices_null_, sub_coefficients_);
00078     }
00079     sync_->registerCallback(boost::bind(&PolygonFlipper::flip, this, _1, _2, _3));
00080   }
00081 
00082   void PolygonFlipper::unsubscribe()
00083   {
00084     sub_polygons_.unsubscribe();
00085     sub_coefficients_.unsubscribe();
00086     if (use_indices_)
00087       sub_indices_.unsubscribe();
00088   }
00089 
00090   void PolygonFlipper::fillEmptyIndices(
00091     const jsk_recognition_msgs::PolygonArray::ConstPtr& polygons_msg)
00092   {
00093     jsk_recognition_msgs::ClusterPointIndices indices;
00094     indices.header.stamp = polygons_msg->header.stamp;
00095     indices.cluster_indices.resize(polygons_msg->polygons.size());
00096     sub_indices_null_.add(
00097       boost::make_shared<jsk_recognition_msgs::ClusterPointIndices>(indices));
00098   }
00099 
00100   void PolygonFlipper::flip(
00101     const jsk_recognition_msgs::PolygonArray::ConstPtr& polygons_msg,
00102     const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& indices_msg,
00103     const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& coefficients_msg)
00104   {
00105     vital_checker_->poke();
00106     if (polygons_msg->polygons.size() != coefficients_msg->coefficients.size()) {
00107       NODELET_ERROR("The size of polygons and coefficients are not same");
00108       return;
00109     }
00110     jsk_recognition_msgs::PolygonArray flipped_polygons = *polygons_msg;
00111     jsk_recognition_msgs::ModelCoefficientsArray flipped_coefficients;
00112     jsk_recognition_msgs::ClusterPointIndices flipped_indices;
00113     flipped_polygons.polygons.clear();
00114     flipped_coefficients.header = coefficients_msg->header;
00115     flipped_indices.header = indices_msg->header;
00116     try {
00117       for (size_t i = 0; i < polygons_msg->polygons.size(); i++) {
00118         geometry_msgs::PolygonStamped target_polygon = polygons_msg->polygons[i];
00119         PCLModelCoefficientMsg target_coefficients = coefficients_msg->coefficients[i];
00120         PCLIndicesMsg target_indices = indices_msg->cluster_indices[i];
00121         tf::StampedTransform tf_transform
00122           = jsk_recognition_utils::lookupTransformWithDuration(
00123             tf_listener_, target_coefficients.header.frame_id,
00124             sensor_frame_, target_coefficients.header.stamp,
00125             ros::Duration(1.0));
00126         Eigen::Affine3f sensor_transform;
00127         tf::transformTFToEigen(tf_transform, sensor_transform);
00128         {
00129           
00130           jsk_recognition_utils::ConvexPolygon convex = jsk_recognition_utils::ConvexPolygon::fromROSMsg(target_polygon.polygon);
00131           Eigen::Vector3f polygon_normal = convex.getNormal();
00132           if (polygon_normal.dot(Eigen::Vector3f(sensor_transform.translation()))
00133               < 0) {
00134             geometry_msgs::PolygonStamped flipped_polygon;
00135             std::reverse_copy(
00136               target_polygon.polygon.points.begin(),
00137               target_polygon.polygon.points.end(),
00138               std::back_inserter(flipped_polygon.polygon.points));
00139             flipped_polygon.header = target_polygon.header;
00140             flipped_polygons.polygons.push_back(flipped_polygon);
00141           }
00142           else {
00143             flipped_polygons.polygons.push_back(target_polygon);
00144           }
00145         }
00146         
00147         {
00148           
00149           Eigen::Vector3f local_normal(target_coefficients.values[0],
00150                                        target_coefficients.values[1],
00151                                        target_coefficients.values[2]);
00152           if (local_normal.dot(Eigen::Vector3f(sensor_transform.translation()))
00153               < 0) {
00154             PCLModelCoefficientMsg the_flipped_coefficients;
00155             PCLIndicesMsg the_flipped_indices;
00156             for (size_t j = 0; j < target_coefficients.values.size(); j++) {
00157               the_flipped_coefficients.values.push_back(
00158                 - target_coefficients.values[j]);
00159             }
00160             std::reverse_copy(target_indices.indices.begin(), target_indices.indices.end(),
00161                               std::back_inserter(the_flipped_indices.indices));
00162             the_flipped_coefficients.header = target_coefficients.header;
00163             the_flipped_indices.header = target_indices.header;
00164             flipped_coefficients.coefficients.push_back(the_flipped_coefficients);
00165             
00166             flipped_indices.cluster_indices.push_back(the_flipped_indices);
00167             
00168           }
00169           else {
00170             
00171             flipped_coefficients.coefficients.push_back(target_coefficients);
00172             flipped_indices.cluster_indices.push_back(target_indices);
00173           }
00174         }
00175       }
00176       pub_polygons_.publish(flipped_polygons);
00177       pub_coefficients_.publish(flipped_coefficients);
00178       if (use_indices_)
00179         pub_indices_.publish(flipped_indices);
00180     }
00181     catch (tf2::TransformException& e) {
00182       NODELET_ERROR("Failed to lookup transformation: %s", e.what());
00183     }
00184   }
00185 }
00186 
00187 #include <pluginlib/class_list_macros.h>
00188 PLUGINLIB_EXPORT_CLASS (jsk_pcl_ros_utils::PolygonFlipper, nodelet::Nodelet);