static_polygon_array_publisher_nodelet.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2014, JSK Lab
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the JSK Lab nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
37 #include <jsk_topic_tools/rosparam_utils.h>
38 
39 namespace jsk_pcl_ros_utils
40 {
41 
43  {
44  ConnectionBasedNodelet::onInit();
45  pnh_->param("use_periodic", use_periodic_, false);
46  pnh_->param("use_message", use_message_, false);
47  pnh_->param("use_trigger", use_trigger_, false);
48  pnh_->param("periodic_rate", periodic_rate_, 10.0);
49 
50  bool frame_id_read_p
51  = jsk_topic_tools::readVectorParameter(*pnh_, "frame_ids",
52  frame_ids_);
53  if (!frame_id_read_p) {
54  NODELET_FATAL("failed to read frame_ids from ~frame_ids");
55  return;
56  }
57 
58  bool polygon_read_p = readPolygonArray("polygon_array");
59  if (!polygon_read_p) {
60  NODELET_FATAL("failed to read polygons from ~polygon_array");
61  return;
62  }
63 
64  if (frame_ids_.size() != polygons_.polygons.size()) {
65  NODELET_FATAL("the size of frame_ids(%lu) does not match the size of polygons(%lu)",
66  frame_ids_.size(), polygons_.polygons.size());
67  return;
68  }
69  else {
70  for (size_t i = 0; i < frame_ids_.size(); i++) {
71  polygons_.polygons[i].header.frame_id = frame_ids_[i];
72  coefficients_.coefficients[i].header.frame_id = frame_ids_[i];
73  }
74  }
75 
77  NODELET_FATAL("~use_periodic, ~use_trigger nor ~use_message is not true");
78  return;
79  }
80  polygons_.header.frame_id = frame_ids_[0];
81  coefficients_.header.frame_id = frame_ids_[0];
82 
83  if (!use_periodic_) {
84  polygon_pub_ = advertise<jsk_recognition_msgs::PolygonArray>(
85  *pnh_, "output_polygons", 1);
86  coefficients_pub_ = advertise<jsk_recognition_msgs::ModelCoefficientsArray>(
87  *pnh_, "output_coefficients", 1);
88  }
89  else {
90  polygon_pub_ = pnh_->advertise<jsk_recognition_msgs::PolygonArray>(
91  "output_polygons", 1);
92  coefficients_pub_ = pnh_->advertise<jsk_recognition_msgs::ModelCoefficientsArray>(
93  "output_coefficients", 1);
94  subscribe();
96  }
97  onInitPostProcess();
98  }
99 
101  // message_filters::Synchronizer needs to be called reset
102  // before message_filters::Subscriber is freed.
103  // Calling reset fixes the following error on shutdown of the nodelet:
104  // terminate called after throwing an instance of
105  // 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::lock_error> >'
106  // what(): boost: mutex lock failed in pthread_mutex_lock: Invalid argument
107  // Also see https://github.com/ros/ros_comm/issues/720 .
108  sync_.reset();
109  }
110 
112  {
113  if (use_message_) {
114  sub_ = pnh_->subscribe("input", 1, &StaticPolygonArrayPublisher::inputCallback, this);
115  }
116  if (use_trigger_) {
117  sub_input_.subscribe(*pnh_, "input", 1);
118  sub_trigger_.subscribe(*pnh_, "trigger", 1);
119  sync_
120  = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(100);
121  sync_->connectInput(sub_input_, sub_trigger_);
122  sync_->registerCallback(boost::bind(
124  this, _1, _2));
125  }
126  }
127 
129  {
130  if (use_message_) {
131  sub_.shutdown();
132  }
133  if (use_trigger_) {
136  }
137  }
138 
140  const sensor_msgs::PointCloud2::ConstPtr& input,
141  const jsk_recognition_msgs::Int32Stamped::ConstPtr& trigger)
142  {
143  publishPolygon(input->header.stamp);
144  }
145 
146  PCLModelCoefficientMsg StaticPolygonArrayPublisher::polygonToModelCoefficients(const geometry_msgs::PolygonStamped& polygon)
147  {
148  Eigen::Vector3d A, B, C;
149  A[0] = polygon.polygon.points[0].x;
150  A[1] = polygon.polygon.points[0].y;
151  A[2] = polygon.polygon.points[0].z;
152  B[0] = polygon.polygon.points[1].x;
153  B[1] = polygon.polygon.points[1].y;
154  B[2] = polygon.polygon.points[1].z;
155  C[0] = polygon.polygon.points[2].x;
156  C[1] = polygon.polygon.points[2].y;
157  C[2] = polygon.polygon.points[2].z;
158  Eigen::Vector3d n = (B - A).cross(C - A).normalized();
159  double a = n[0];
160  double b = n[1];
161  double c = n[2];
162  double d = -(a * A[0] + b * A[1] + c * A[2]);
163  PCLModelCoefficientMsg coefficient;
164  coefficient.header = polygon.header;
165  coefficient.values.push_back(a);
166  coefficient.values.push_back(b);
167  coefficient.values.push_back(c);
168  coefficient.values.push_back(d);
169  return coefficient;
170  }
171 
172  /*
173  parameter format is:
174  polygon_array: [[[0, 0, 0], [0, 0, 1], [1, 0, 0]], ...]
175  */
176  bool StaticPolygonArrayPublisher::readPolygonArray(const std::string& param_name)
177  {
178  if (pnh_->hasParam(param_name)) {
180  pnh_->param(param_name, v, v);
182  for (size_t toplevel_i = 0; toplevel_i < v.size(); toplevel_i++) { // polygons
183  XmlRpc::XmlRpcValue polygon_v = v[toplevel_i];
184  geometry_msgs::PolygonStamped polygon;
185  if (polygon_v.getType() == XmlRpc::XmlRpcValue::TypeArray &&
186  polygon_v.size() >= 3) {
187  for (size_t secondlevel_i = 0; secondlevel_i < polygon_v.size(); secondlevel_i++) { // each polygon, vertices
188  XmlRpc::XmlRpcValue vertex_v = polygon_v[secondlevel_i];
189  if (vertex_v.getType() == XmlRpc::XmlRpcValue::TypeArray &&
190  vertex_v.size() == 3 ) { // vertex_v := [x, y, z]
191  double x = getXMLDoubleValue(vertex_v[0]);
192  double y = getXMLDoubleValue(vertex_v[1]);
193  double z = getXMLDoubleValue(vertex_v[2]);
194  geometry_msgs::Point32 point;
195  point.x = x;
196  point.y = y;
197  point.z = z;
198  polygon.polygon.points.push_back(point);
199  }
200  else {
201  NODELET_FATAL("%s[%lu][%lu] is not array or the length is not 3",
202  param_name.c_str(), toplevel_i, secondlevel_i);
203  return false;
204  }
205  }
206  polygons_.polygons.push_back(polygon);
207  // estimate model coefficients
208  coefficients_.coefficients.push_back(polygonToModelCoefficients(polygon));
209  }
210  else {
211  NODELET_FATAL("%s[%lu] is not array or not enough points", param_name.c_str(), toplevel_i);
212  return false;
213  }
214  }
215  return true;
216  }
217  else {
218  NODELET_FATAL("%s is not array", param_name.c_str());
219  return false;
220  }
221  }
222  else {
223  NODELET_FATAL("no %s is available on parameter server", param_name.c_str());
224  return false;
225  }
226  return true;
227  }
228 
230  switch(val.getType()) {
232  return (double)((int)val);
234  return (double)val;
235  default:
236  return 0;
237  }
238  }
239 
240 
241  void StaticPolygonArrayPublisher::inputCallback(const sensor_msgs::PointCloud2::ConstPtr& msg)
242  {
243  publishPolygon(msg->header.stamp);
244  }
245 
247  {
249  }
250 
252  {
253  polygons_.header.stamp = stamp;
254  for (size_t i = 0; i < polygons_.polygons.size(); i++) {
255  polygons_.polygons[i].header.stamp = stamp;
256  }
257 
258  coefficients_.header.stamp = stamp;
259  for (size_t i = 0; i < coefficients_.coefficients.size(); i++) {
260  coefficients_.coefficients[i].header.stamp = stamp;
261  }
262 
265  }
266 
267 }
268 
271 
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::~StaticPolygonArrayPublisher
virtual ~StaticPolygonArrayPublisher()
Definition: static_polygon_array_publisher_nodelet.cpp:132
XmlRpc::XmlRpcValue::size
int size() const
jsk_pcl_ros_utils
Definition: add_point_indices.h:51
NODELET_FATAL
#define NODELET_FATAL(...)
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::polygons_
jsk_recognition_msgs::PolygonArray polygons_
Definition: static_polygon_array_publisher.h:139
msg
msg
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::sub_trigger_
message_filters::Subscriber< jsk_recognition_msgs::Int32Stamped > sub_trigger_
Definition: static_polygon_array_publisher.h:149
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::unsubscribe
virtual void unsubscribe()
Definition: static_polygon_array_publisher_nodelet.cpp:160
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::inputCallback
virtual void inputCallback(const sensor_msgs::PointCloud2::ConstPtr &msg)
Definition: static_polygon_array_publisher_nodelet.cpp:273
i
int i
PLUGINLIB_EXPORT_CLASS
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros_utils::StaticPolygonArrayPublisher, nodelet::Nodelet)
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::getXMLDoubleValue
virtual double getXMLDoubleValue(XmlRpc::XmlRpcValue val)
Definition: static_polygon_array_publisher_nodelet.cpp:261
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::coefficients_pub_
ros::Publisher coefficients_pub_
Definition: static_polygon_array_publisher.h:137
jsk_pcl_ros_utils::StaticPolygonArrayPublisher
Definition: static_polygon_array_publisher.h:95
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::triggerCallback
virtual void triggerCallback(const sensor_msgs::PointCloud2::ConstPtr &input, const jsk_recognition_msgs::Int32Stamped::ConstPtr &trigger)
Definition: static_polygon_array_publisher_nodelet.cpp:171
XmlRpc::XmlRpcValue::TypeInt
TypeInt
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::sub_input_
message_filters::Subscriber< sensor_msgs::PointCloud2 > sub_input_
Definition: static_polygon_array_publisher.h:148
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::coefficients_
jsk_recognition_msgs::ModelCoefficientsArray coefficients_
Definition: static_polygon_array_publisher.h:140
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::sub_
ros::Subscriber sub_
Definition: static_polygon_array_publisher.h:138
ros::Subscriber::shutdown
void shutdown()
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::polygon_pub_
ros::Publisher polygon_pub_
Definition: static_polygon_array_publisher.h:137
static_polygon_array_publisher.h
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::onInit
virtual void onInit()
Definition: static_polygon_array_publisher_nodelet.cpp:74
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
message_filters::Subscriber::unsubscribe
void unsubscribe()
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::timer_
ros::Timer timer_
Definition: static_polygon_array_publisher.h:147
input
char input[LINE_MAX_LEN]
class_list_macros.h
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::timerCallback
virtual void timerCallback(const ros::TimerEvent &event)
Definition: static_polygon_array_publisher_nodelet.cpp:278
A
XmlRpc::XmlRpcValue::TypeDouble
TypeDouble
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::readPolygonArray
virtual bool readPolygonArray(const std::string &param)
Definition: static_polygon_array_publisher_nodelet.cpp:208
PCLModelCoefficientMsg
pcl::ModelCoefficients PCLModelCoefficientMsg
y
double y
sample_camera_info_and_pointcloud_publisher.stamp
stamp
Definition: sample_camera_info_and_pointcloud_publisher.py:13
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::use_message_
bool use_message_
Definition: static_polygon_array_publisher.h:143
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::subscribe
virtual void subscribe()
Definition: static_polygon_array_publisher_nodelet.cpp:143
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::publishPolygon
virtual void publishPolygon(const ros::Time &stamp)
Definition: static_polygon_array_publisher_nodelet.cpp:283
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::use_trigger_
bool use_trigger_
Definition: static_polygon_array_publisher.h:144
d
d
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::frame_ids_
std::vector< std::string > frame_ids_
Definition: static_polygon_array_publisher.h:146
cross
double3 cross(const double3 &a, const double3 &b)
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::polygonToModelCoefficients
virtual PCLModelCoefficientMsg polygonToModelCoefficients(const geometry_msgs::PolygonStamped &polygon)
Definition: static_polygon_array_publisher_nodelet.cpp:178
ros::TimerEvent
XmlRpc::XmlRpcValue::getType
const Type & getType() const
point
std::chrono::system_clock::time_point point
XmlRpc::XmlRpcValue::TypeArray
TypeArray
message_filters::Subscriber::subscribe
void subscribe()
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::sync_
boost::shared_ptr< message_filters::Synchronizer< SyncPolicy > > sync_
Definition: static_polygon_array_publisher.h:150
nodelet::Nodelet
ros::Time
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::use_periodic_
bool use_periodic_
Definition: static_polygon_array_publisher.h:142
ros::TimerEvent::current_expected
Time current_expected
x
double x
ros::Duration
z
double z
jsk_pcl_ros_utils::StaticPolygonArrayPublisher::periodic_rate_
double periodic_rate_
Definition: static_polygon_array_publisher.h:145
XmlRpc::XmlRpcValue


jsk_pcl_ros_utils
Author(s): Yohei Kakiuchi
autogenerated on Fri May 16 2025 03:11:43