polygon_array_transformer_nodelet.cpp
Go to the documentation of this file.
1 // -*- mode: C++ -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2014, JSK Lab
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/o2r other materials provided
17  * with the distribution.
18  * * Neither the name of the JSK Lab nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
40 
41 namespace jsk_pcl_ros_utils
42 {
43 
45  {
46  ConnectionBasedNodelet::onInit();
47  if (!pnh_->getParam("frame_id", frame_id_)) {
48  NODELET_FATAL("~frame_id is not specified");
49  return;
50  }
52  polygons_pub_ = advertise<jsk_recognition_msgs::PolygonArray>(*pnh_, "output_polygons", 1);
53  coefficients_pub_ = advertise<jsk_recognition_msgs::ModelCoefficientsArray>(
54  *pnh_, "output_coefficients", 1);
56  }
57 
59  {
60  sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(100);
61  sub_polygons_.subscribe(*pnh_, "input_polygons", 1);
62  sub_coefficients_.subscribe(*pnh_, "input_coefficients", 1);
63  sync_->connectInput(sub_polygons_, sub_coefficients_);
64  sync_->registerCallback(boost::bind(&PolygonArrayTransformer::transform, this, _1, _2));
65  }
66 
68  {
71  }
72 
73  void PolygonArrayTransformer::computeCoefficients(const geometry_msgs::PolygonStamped& polygon,
74  PCLModelCoefficientMsg& coefficient)
75  {
76  Eigen::Vector3d A, B, C;
77  A[0] = polygon.polygon.points[0].x;
78  A[1] = polygon.polygon.points[0].y;
79  A[2] = polygon.polygon.points[0].z;
80  B[0] = polygon.polygon.points[1].x;
81  B[1] = polygon.polygon.points[1].y;
82  B[2] = polygon.polygon.points[1].z;
83  C[0] = polygon.polygon.points[2].x;
84  C[1] = polygon.polygon.points[2].y;
85  C[2] = polygon.polygon.points[2].z;
86  Eigen::Vector3d n = (B - A).cross(C - A).normalized();
87  double a = n[0];
88  double b = n[1];
89  double c = n[2];
90  double d = -(a * A[0] + b * A[1] + c * A[2]);
91  coefficient.header = polygon.header;
92  coefficient.values.push_back(a);
93  coefficient.values.push_back(b);
94  coefficient.values.push_back(c);
95  coefficient.values.push_back(d);
96 
97  }
98 
100  const PCLModelCoefficientMsg& coefficient,
101  PCLModelCoefficientMsg& result)
102  {
103  jsk_recognition_utils::Plane plane(coefficient.values);
104  jsk_recognition_utils::Plane transformed_plane = plane.transform(transform);
105  result.header.stamp = coefficient.header.stamp;
106  result.header.frame_id = frame_id_;
107  transformed_plane.toCoefficients(result.values);
108  NODELET_DEBUG("[%f, %f, %f, %f] => [%f, %f, %f, %f]",
109  coefficient.values[0], coefficient.values[1], coefficient.values[2], coefficient.values[3],
110  result.values[0], result.values[1], result.values[2], result.values[3]);
111  }
112 
114  const geometry_msgs::PolygonStamped& polygon,
115  geometry_msgs::PolygonStamped& result)
116  {
117  result.header = polygon.header;
118  result.header.frame_id = frame_id_;
119  for (size_t i = 0; i < polygon.polygon.points.size(); i++) {
120  Eigen::Vector4d point;
121  point[0] = polygon.polygon.points[i].x;
122  point[1] = polygon.polygon.points[i].y;
123  point[2] = polygon.polygon.points[i].z;
124  point[3] = 1; // homogenious
125  Eigen::Vector4d transformed_point_eigen = transform.inverse() * point;
126  geometry_msgs::Point32 transformed_point;
127  transformed_point.x = transformed_point_eigen[0];
128  transformed_point.y = transformed_point_eigen[1];
129  transformed_point.z = transformed_point_eigen[2];
130  result.polygon.points.push_back(transformed_point);
131  }
132  }
133 
134  void PolygonArrayTransformer::transform(const jsk_recognition_msgs::PolygonArray::ConstPtr& polygons,
135  const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr& coefficients)
136  {
137  if (polygons->polygons.size() != coefficients->coefficients.size()) {
138  NODELET_ERROR("the size of polygons(%lu) does not match with the size of coefficients(%lu)",
139  polygons->polygons.size(),
140  coefficients->coefficients.size());
141  return;
142  }
143 
144  jsk_recognition_msgs::PolygonArray transformed_polygon_array;
145  jsk_recognition_msgs::ModelCoefficientsArray transformed_model_coefficients_array;
146  transformed_polygon_array.header = polygons->header;
147  transformed_model_coefficients_array.header = coefficients->header;
148  transformed_polygon_array.header.frame_id = frame_id_;
149  transformed_model_coefficients_array.header.frame_id = frame_id_;
150  for (size_t i = 0; i < polygons->polygons.size(); i++) {
151  geometry_msgs::PolygonStamped polygon = polygons->polygons[i];
152  PCLModelCoefficientMsg coefficient = coefficients->coefficients[i];
153 
154  if (polygon.header.frame_id != coefficient.header.frame_id) {
155  NODELET_ERROR("frame_id of polygon[%lu] is %s and frame_id of coefficient[%lu] is %s, they does not point to the same frame_id",
156  i, polygon.header.frame_id.c_str(),
157  i, coefficient.header.frame_id.c_str());
158  return;
159  }
160  listener_->waitForTransform(coefficient.header.frame_id,
161  frame_id_,
162  coefficient.header.stamp,
163  ros::Duration(1.0));
164  if (listener_->canTransform(coefficient.header.frame_id,
165  frame_id_,
166  coefficient.header.stamp)) {
167  tf::StampedTransform transform; // header -> frame_id_
168  listener_->lookupTransform(coefficient.header.frame_id, frame_id_,
169  //ros::Time(0.0), transform);
170  coefficient.header.stamp, transform);
171  Eigen::Affine3d eigen_transform;
172  tf::transformTFToEigen(transform, eigen_transform);
173  PCLModelCoefficientMsg transformed_coefficient;
174  //transformModelCoefficient(eigen_transform, coefficient, transformed_coefficient);
175 
176  geometry_msgs::PolygonStamped transformed_polygon;
177  if (polygon.polygon.points.size() == 0) {
178  transformed_polygon.header = polygon.header;
179  transformed_polygon.header.frame_id = frame_id_;
180  transformed_polygon_array.polygons.push_back(transformed_polygon);
181  transformed_coefficient.values = coefficient.values;
182  transformed_coefficient.header = polygon.header;
183  transformed_coefficient.header.frame_id = frame_id_;
184  transformed_model_coefficients_array.coefficients.push_back(transformed_coefficient);
185  }
186  else {
187  transformPolygon(eigen_transform, polygon, transformed_polygon);
188  //computeCoefficients(transformed_polygon, transformed_coefficient);
189  transformModelCoefficient(eigen_transform, coefficient,
190  transformed_coefficient);
191  if (isnan(transformed_coefficient.values[0]) ||
192  isnan(transformed_coefficient.values[1]) ||
193  isnan(transformed_coefficient.values[2]) ||
194  isnan(transformed_coefficient.values[3])) {
195  continue;
196  }
197  transformed_polygon_array.polygons.push_back(transformed_polygon);
198  transformed_model_coefficients_array.coefficients.push_back(transformed_coefficient);
199  }
200  }
201  else {
202  NODELET_ERROR("cannot lookup transform from %s to %s at %f",
203  frame_id_.c_str(), coefficient.header.frame_id.c_str(),
204  coefficient.header.stamp.toSec());
205  return;
206  }
207  }
208  polygons_pub_.publish(transformed_polygon_array);
209  coefficients_pub_.publish(transformed_model_coefficients_array);
210  }
211 
212 }
213 
d
virtual void computeCoefficients(const geometry_msgs::PolygonStamped &polygon, PCLModelCoefficientMsg &coefficient)
#define NODELET_ERROR(...)
void publish(const boost::shared_ptr< M > &message) const
void transformTFToEigen(const tf::Transform &t, Eigen::Affine3d &e)
virtual void transformModelCoefficient(const Eigen::Affine3d &transform, const PCLModelCoefficientMsg &coefficient, PCLModelCoefficientMsg &result)
message_filters::Subscriber< jsk_recognition_msgs::PolygonArray > sub_polygons_
TFSIMD_FORCE_INLINE Vector3 cross(const Vector3 &v) const
virtual Plane transform(const Eigen::Affine3d &transform)
virtual void toCoefficients(std::vector< float > &output)
bool canTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, std::string *error_msg=NULL) const
bool waitForTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration &timeout, const ros::Duration &polling_sleep_duration=ros::Duration(0.01), std::string *error_msg=NULL) const
boost::shared_ptr< message_filters::Synchronizer< SyncPolicy > > sync_
boost::shared_ptr< ros::NodeHandle > pnh_
virtual void transform(const jsk_recognition_msgs::PolygonArray::ConstPtr &polygons, const jsk_recognition_msgs::ModelCoefficientsArray::ConstPtr &coefficients)
void lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, StampedTransform &transform) const
double x
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros_utils::PolygonArrayTransformer, nodelet::Nodelet)
void subscribe(ros::NodeHandle &nh, const std::string &topic, uint32_t queue_size, const ros::TransportHints &transport_hints=ros::TransportHints(), ros::CallbackQueueInterface *callback_queue=0)
message_filters::Subscriber< jsk_recognition_msgs::ModelCoefficientsArray > sub_coefficients_
c
virtual void transformPolygon(const Eigen::Affine3d &transform, const geometry_msgs::PolygonStamped &polygon, geometry_msgs::PolygonStamped &result)
static tf::TransformListener * getInstance()
#define NODELET_FATAL(...)
#define NODELET_DEBUG(...)
pcl::ModelCoefficients PCLModelCoefficientMsg


jsk_pcl_ros_utils
Author(s): Yohei Kakiuchi
autogenerated on Mon May 3 2021 03:03:15