collision_detector_nodelet.cpp
Go to the documentation of this file.
1 // -*- mode: c++ -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2015, 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 
36 #define BOOST_PARAMETER_MAX_ARITY 7
38 #include <cmath>
39 
40 namespace jsk_pcl_ros
41 {
43  {
44  DiagnosticNodelet::onInit();
45  initSelfMask();
46  pnh_->param<std::string>("world_frame_id", world_frame_id_, "map");
47  sub_ = pnh_->subscribe("input", 1, &CollisionDetector::pointcloudCallback, this);
48  service_ = pnh_->advertiseService("check_collision", &CollisionDetector::serviceCallback, this);
50  }
51 
53  {
54  }
55 
57  {
58  }
59 
61  {
62  // genearte urdf model
63  std::string content;
64  urdf::Model urdf_model;
65  if (nh_->getParam("robot_description", content)) {
66  if (!urdf_model.initString(content)) {
67  NODELET_ERROR("Unable to parse URDF description!");
68  }
69  }
70 
71  std::string root_link_id;
72  std::string world_frame_id;
73  pnh_->param<std::string>("root_link_id", root_link_id, "BODY");
74  pnh_->param<std::string>("world_frame_id", world_frame_id, "map");
75 
76  double default_padding, default_scale;
77  pnh_->param("self_see_default_padding", default_padding, 0.01);
78  pnh_->param("self_see_default_scale", default_scale, 1.0);
79  std::vector<robot_self_filter::LinkInfo> links;
80  std::string link_names;
81 
82  if (!pnh_->hasParam("self_see_links")) {
83  NODELET_WARN("No links specified for self filtering.");
84  } else {
85  XmlRpc::XmlRpcValue ssl_vals;;
86  pnh_->getParam("self_see_links", ssl_vals);
87  if (ssl_vals.getType() != XmlRpc::XmlRpcValue::TypeArray) {
88  NODELET_WARN("Self see links need to be an array");
89  } else {
90  if (ssl_vals.size() == 0) {
91  NODELET_WARN("No values in self see links array");
92  } else {
93  for (int i = 0; i < ssl_vals.size(); i++) {
94  robot_self_filter::LinkInfo li;
95  if (ssl_vals[i].getType() != XmlRpc::XmlRpcValue::TypeStruct) {
96  NODELET_WARN("Self see links entry %d is not a structure. Stopping processing of self see links",i);
97  break;
98  }
99  if (!ssl_vals[i].hasMember("name")) {
100  NODELET_WARN("Self see links entry %d has no name. Stopping processing of self see links",i);
101  break;
102  }
103  li.name = std::string(ssl_vals[i]["name"]);
104  if (!ssl_vals[i].hasMember("padding")) {
105  NODELET_DEBUG("Self see links entry %d has no padding. Assuming default padding of %g",i,default_padding);
106  li.padding = default_padding;
107  } else {
108  li.padding = ssl_vals[i]["padding"];
109  }
110  if (!ssl_vals[i].hasMember("scale")) {
111  NODELET_DEBUG("Self see links entry %d has no scale. Assuming default scale of %g",i,default_scale);
112  li.scale = default_scale;
113  } else {
114  li.scale = ssl_vals[i]["scale"];
115  }
116  links.push_back(li);
117  }
118  }
119  }
120  }
122  }
123 
124  void CollisionDetector::pointcloudCallback(const sensor_msgs::PointCloud2::ConstPtr& msg)
125  {
126  boost::mutex::scoped_lock lock(mutex_);
127  NODELET_DEBUG("update pointcloud.");
128 
129  pcl::fromROSMsg(*msg, cloud_);
130  cloud_frame_id_ = msg->header.frame_id;
131  cloud_stamp_ = msg->header.stamp;
132  }
133 
134  bool CollisionDetector::serviceCallback(jsk_recognition_msgs::CheckCollision::Request &req,
135  jsk_recognition_msgs::CheckCollision::Response &res)
136  {
137  sensor_msgs::JointState joint = req.joint;
138  geometry_msgs::PoseStamped pose = req.pose;
139  res.result = checkCollision(joint, pose);
140  return true;
141  }
142 
143  bool CollisionDetector::checkCollision(const sensor_msgs::JointState& joint,
144  const geometry_msgs::PoseStamped& pose)
145  {
146  boost::mutex::scoped_lock lock(mutex_);
147  NODELET_DEBUG("checkCollision is called.");
148 
149  // calculate the sensor transformation
150  tf::StampedTransform sensor_to_world_tf;
151  try {
153  } catch (tf::TransformException& ex) {
154  NODELET_ERROR_STREAM( "Transform error of sensor data: " << ex.what() << ", quitting callback");
155  return false;
156  }
157 
158  // transform point cloud
159  Eigen::Matrix4f sensor_to_world;
160  pcl_ros::transformAsMatrix(sensor_to_world_tf, sensor_to_world);
161  pcl::transformPointCloud(cloud_, cloud_, sensor_to_world);
162 
163  self_mask_->assumeFrameFromJointAngle(joint, pose);
164 
165  // check containment for all point cloud
166  bool contain_flag = false;
167  pcl::PointXYZ p;
168  for (size_t i = 0; i < cloud_.size(); i++) {
169  p = cloud_.at(i);
170  if (finite(p.x) && finite(p.y) && finite(p.z) &&
171  self_mask_->getMaskContainment(p.x, p.y, p.z) == robot_self_filter::INSIDE) {
172  contain_flag = true;
173  break;
174  }
175  }
176 
177  if (contain_flag) {
178  NODELET_INFO("collision!");
179  } else {
180  NODELET_INFO("no collision!");
181  }
182  return contain_flag;
183  }
184 }
185 
link_names
#define NODELET_ERROR(...)
#define NODELET_WARN(...)
URDF_EXPORT bool initString(const std::string &xmlstring)
int size() const
void transformAsMatrix(const tf::Transform &bt, Eigen::Matrix4f &out_mat)
pcl::PointCloud< pcl::PointXYZ > cloud_
void fromROSMsg(const sensor_msgs::PointCloud2 &cloud, pcl::PointCloud< T > &pcl_cloud)
PLUGINLIB_EXPORT_CLASS(jsk_pcl_ros::CollisionDetector, nodelet::Nodelet)
Type const & getType() const
pose
tf::TransformBroadcaster tf_broadcaster_
#define NODELET_ERROR_STREAM(...)
tf::TransformListener tf_listener_
boost::shared_ptr< ros::NodeHandle > pnh_
boost::shared_ptr< robot_self_filter::SelfMaskUrdfRobot > self_mask_
void lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, StampedTransform &transform) const
#define NODELET_INFO(...)
p
virtual bool checkCollision(const sensor_msgs::JointState &joint, const geometry_msgs::PoseStamped &pose)
virtual void pointcloudCallback(const sensor_msgs::PointCloud2::ConstPtr &msg)
boost::shared_ptr< ros::NodeHandle > nh_
#define NODELET_DEBUG(...)
virtual bool serviceCallback(jsk_recognition_msgs::CheckCollision::Request &req, jsk_recognition_msgs::CheckCollision::Response &res)


jsk_pcl_ros
Author(s): Yohei Kakiuchi
autogenerated on Mon May 3 2021 03:03:46