container_occupancy_detector_nodelet.cpp
Go to the documentation of this file.
1 // -*- mode: C++ -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2022, 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/or 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 /*
36  * container_occupancy_detector_nodelet.cpp
37  * Author: Yoshiki Obinata <obinata@jsk.imi.i.u-tokyo.ac.jp>
38  */
39 
41 
42 namespace jsk_pcl_ros{
43 
45  jsk_topic_tools::DiagnosticNodelet::onInit();
46  pnh_->param("approximate_sync", approximate_sync_, false);
47  pnh_->param("queue_size", queue_size_, 100);
49  = advertise<jsk_recognition_msgs::BoundingBoxArray>(*pnh_, "container/occupancies", 1);
51  onInitPostProcess();
52  }
53 
55  // message_filters::Synchronizer needs to be called reset
56  // before message_filters::Subscriber is freed.
57  // Calling reset fixes the following error on shutdown of the nodelet:
58  // terminate called after throwing an instance of
59  // 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::lock_error> >'
60  // what(): boost: mutex lock failed in pthread_mutex_lock: Invalid argument
61  // Also see https://github.com/ros/ros_comm/issues/720 .
63  ap_sync_.reset();
64  }else{
65  sync_.reset();
66  }
67  }
68 
70  sub_boxes_.subscribe(*pnh_, "container/boxes", 1);
71  sub_points_.subscribe(*pnh_, "container/points", 1);
72  sub_point_indices_.subscribe(*pnh_, "container/point_indices", 1);
74  ap_sync_ = std::make_shared<message_filters::Synchronizer<ApproximateSyncPolicy> >(queue_size_);
76  ap_sync_ -> registerCallback(boost::bind(&ContainerOccupancyDetector::calculate, this, _1, _2, _3));
77  }else{
78  sync_ = std::make_shared<message_filters::Synchronizer<SyncPolicy> >(100);
80  sync_->registerCallback(boost::bind(&ContainerOccupancyDetector::calculate, this, _1, _2, _3));
81  }
82  }
83 
88  }
89 
91  const jsk_recognition_msgs::BoundingBoxArray::ConstPtr& boxes_msg,
92  const sensor_msgs::PointCloud2::ConstPtr& points_msg,
93  const jsk_recognition_msgs::ClusterPointIndices::ConstPtr& point_indices_msg
94  ){
95  boost::mutex::scoped_lock lock(mutex_);
96  if (!boxes_msg->boxes.empty()){
97  // if boxes exist
98  if(pointsTransform(boxes_msg, points_msg)){
99  // if succeeded in transforming pointclouds
100  jsk_recognition_msgs::BoundingBoxArray result_ = *boxes_msg;
102  pcl::fromPCLPointCloud2(*pcl_pc2_ptr_, *pcl_xyz_ptr_);
103  for(size_t i_box = 0; i_box < boxes_msg->boxes.size(); i_box++){
104  // each boxes
105  float sum_occupancy_ = 0.0;
106  int32_t n_points_ = 0;
107  Eigen::Vector3d t_(boxes_msg->boxes.at(i_box).pose.position.x,
108  boxes_msg->boxes.at(i_box).pose.position.y,
109  boxes_msg->boxes.at(i_box).pose.position.z);
110  Eigen::Quaterniond q_(boxes_msg->boxes.at(i_box).pose.orientation.w,
111  boxes_msg->boxes.at(i_box).pose.orientation.x,
112  boxes_msg->boxes.at(i_box).pose.orientation.y,
113  boxes_msg->boxes.at(i_box).pose.orientation.z);
114  q_.normalize();
115  Eigen::Vector3d top_(0.0, 0.0, boxes_msg->boxes.at(i_box).dimensions.z / 2.0);
116  Eigen::Vector3d buttom_(0.0, 0.0, -boxes_msg->boxes.at(i_box).dimensions.z / 2.0);
117 
118  for(auto index = point_indices_msg->cluster_indices.at(i_box).indices.begin();
119  index != point_indices_msg->cluster_indices.at(i_box).indices.end();
120  ++index){
121  // each points in the box
122  Eigen::Vector3d eigen_point_(pcl_xyz_ptr_->at(*index).x,
123  pcl_xyz_ptr_->at(*index).y,
124  pcl_xyz_ptr_->at(*index).z);
125  Eigen::Vector3d rotated_point_ = q_.conjugate() * (eigen_point_ - t_);
126  float rate_ = (rotated_point_.z() - buttom_.z()) / (top_.z() - buttom_.z()); // remove points under the box
127  if(rate_ > 0){
128  sum_occupancy_ += rate_;
129  n_points_++;
130  }
131  }
132  result_.boxes.at(i_box).value = sum_occupancy_ / float(n_points_);
133  }
134  vital_checker_->poke();
135  boxes_occupancy_pub_.publish(result_);
136  }else{
137  NODELET_WARN("Failed to transform point cloud\n");
138  }
139  }else{
140  NODELET_DEBUG("No containers subscribed\n");
141  }
142  }
143 
145  const jsk_recognition_msgs::BoundingBoxArray::ConstPtr& boxes_msg,
146  const sensor_msgs::PointCloud2::ConstPtr& points_msg
147  ){
148  // convert pc2's frame to bounding box's one
149  geometry_msgs::TransformStamped transform_stamped_;
150  Eigen::Matrix4f mat;
151  try{
152  transform_stamped_ = tf_buffer_.lookupTransform(
153  boxes_msg->header.frame_id,
154  points_msg->header.frame_id,
155  points_msg->header.stamp,
156  ros::Duration(10.0));
157  mat = tf2::transformToEigen(transform_stamped_.transform).matrix().cast<float>();
159  return true;
160  }catch(tf2::TransformException &ex){
161  NODELET_WARN("Failed to transform tf: %s\n", ex.what());
162  return false;
163  }
164  }
165 
168  if(vital_checker_ -> isAlive()){
169  stat.summary(diagnostic_msgs::DiagnosticStatus::OK,
170  "ContainerOccupancyDetector running\n");
171  }
172  DiagnosticNodelet::updateDiagnostic(stat);
173  }
174 }
175 
extract_top_polygon_likelihood.ex
ex
Definition: extract_top_polygon_likelihood.py:51
depth_error_calibration.lock
lock
Definition: depth_error_calibration.py:32
jsk_pcl_ros::ContainerOccupancyDetector::sub_point_indices_
message_filters::Subscriber< jsk_recognition_msgs::ClusterPointIndices > sub_point_indices_
Definition: container_occupancy_detector.h:165
jsk_pcl_ros::ContainerOccupancyDetector::ap_sync_
std::shared_ptr< message_filters::Synchronizer< ApproximateSyncPolicy > > ap_sync_
Definition: container_occupancy_detector.h:167
pcl_conversions::toPCL
void toPCL(const pcl_msgs::ModelCoefficients &mc, pcl::ModelCoefficients &pcl_mc)
jsk_pcl_ros::ContainerOccupancyDetector::pcl_xyz_ptr_
pcl::PointCloud< pcl::PointXYZ >::Ptr pcl_xyz_ptr_
Definition: container_occupancy_detector.h:182
NODELET_WARN
#define NODELET_WARN(...)
jsk_pcl_ros::ContainerOccupancyDetector::sub_boxes_
message_filters::Subscriber< jsk_recognition_msgs::BoundingBoxArray > sub_boxes_
Definition: container_occupancy_detector.h:163
jsk_pcl_ros::ContainerOccupancyDetector::transformed_points_msg_
sensor_msgs::PointCloud2::Ptr transformed_points_msg_
Definition: container_occupancy_detector.h:172
jsk_pcl_ros::ContainerOccupancyDetector::calculate
virtual void calculate(const jsk_recognition_msgs::BoundingBoxArray::ConstPtr &boxes_msg, const sensor_msgs::PointCloud2::ConstPtr &points_msg, const jsk_recognition_msgs::ClusterPointIndices::ConstPtr &point_indices_msg)
Definition: container_occupancy_detector_nodelet.cpp:122
jsk_pcl_ros::ContainerOccupancyDetector::mutex_
boost::mutex mutex_
Definition: container_occupancy_detector.h:169
ros::Publisher::publish
void publish(const boost::shared_ptr< M > &message) const
message_filters::Subscriber::unsubscribe
void unsubscribe()
tf2_ros::TransformListener
class_list_macros.h
container_occupancy_detector.h
jsk_pcl_ros::ContainerOccupancyDetector::queue_size_
int queue_size_
Definition: container_occupancy_detector.h:195
diagnostic_updater::DiagnosticStatusWrapper::summary
void summary(const diagnostic_msgs::DiagnosticStatus &src)
jsk_pcl_ros::ContainerOccupancyDetector::onInit
virtual void onInit()
Definition: container_occupancy_detector_nodelet.cpp:76
jsk_pcl_ros
Definition: add_color_from_image.h:51
jsk_pcl_ros::ContainerOccupancyDetector::tf_buffer_
tf2_ros::Buffer tf_buffer_
Definition: container_occupancy_detector.h:170
jsk_pcl_ros::ContainerOccupancyDetector::pcl_pc2_ptr_
pcl::PCLPointCloud2Ptr pcl_pc2_ptr_
Definition: container_occupancy_detector.h:180
jsk_pcl_ros::ContainerOccupancyDetector::updateDiagnostic
virtual void updateDiagnostic(diagnostic_updater::DiagnosticStatusWrapper &stat)
Definition: container_occupancy_detector_nodelet.cpp:198
jsk_pcl_ros::ContainerOccupancyDetector::pointsTransform
virtual bool pointsTransform(const jsk_recognition_msgs::BoundingBoxArray::ConstPtr &boxes_msg, const sensor_msgs::PointCloud2::ConstPtr &points_msg)
Definition: container_occupancy_detector_nodelet.cpp:176
tf2::transformToEigen
Eigen::Isometry3d transformToEigen(const geometry_msgs::Transform &t)
jsk_pcl_ros::ContainerOccupancyDetector::unsubscribe
virtual void unsubscribe()
Definition: container_occupancy_detector_nodelet.cpp:116
message_filters::Subscriber::subscribe
void subscribe()
pcl_ros::transformPointCloud
void transformPointCloud(const Eigen::Matrix4f &transform, const sensor_msgs::PointCloud2 &in, sensor_msgs::PointCloud2 &out)
nodelet::Nodelet
jsk_pcl_ros::ContainerOccupancyDetector::subscribe
virtual void subscribe()
Definition: container_occupancy_detector_nodelet.cpp:101
jsk_pcl_ros::ContainerOccupancyDetector::sub_points_
message_filters::Subscriber< sensor_msgs::PointCloud2 > sub_points_
Definition: container_occupancy_detector.h:164
jsk_pcl_ros::ContainerOccupancyDetector::tf_listener_
tf2_ros::TransformListener * tf_listener_
Definition: container_occupancy_detector.h:171
jsk_pcl_ros::ContainerOccupancyDetector::boxes_occupancy_pub_
ros::Publisher boxes_occupancy_pub_
Definition: container_occupancy_detector.h:168
jsk_pcl_ros::ContainerOccupancyDetector::~ContainerOccupancyDetector
virtual ~ContainerOccupancyDetector()
Definition: container_occupancy_detector_nodelet.cpp:86
jsk_pcl_ros::ContainerOccupancyDetector::approximate_sync_
bool approximate_sync_
Definition: container_occupancy_detector.h:196
diagnostic_updater::DiagnosticStatusWrapper
PLUGINLIB_EXPORT_CLASS
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros::ContainerOccupancyDetector, nodelet::Nodelet)
jsk_pcl_ros::ContainerOccupancyDetector
Definition: container_occupancy_detector.h:96
tf2::TransformException
jsk_pcl_ros::ContainerOccupancyDetector::sync_
std::shared_ptr< message_filters::Synchronizer< SyncPolicy > > sync_
Definition: container_occupancy_detector.h:166
ros::Duration
tf2_ros::Buffer::lookupTransform
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const ros::Time &target_time, const std::string &source_frame, const ros::Time &source_time, const std::string &fixed_frame, const ros::Duration timeout) const
NODELET_DEBUG
#define NODELET_DEBUG(...)


jsk_pcl_ros
Author(s): Yohei Kakiuchi
autogenerated on Tue Jan 7 2025 04:05:44