shape_mask.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2008, Willow Garage, Inc.
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 Willow Garage 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 
35 /* Author: Ioan Sucan */
36 
39 #include <ros/console.h>
41 
42 static const std::string LOGNAME = "shape_mask";
43 
45  : transform_callback_(transform_callback), next_handle_(1), min_handle_(1)
46 {
47 }
48 
50 {
51  freeMemory();
52 }
53 
55 {
56  for (const SeeShape& body : bodies_)
57  delete body.body;
58  bodies_.clear();
59 }
60 
62 {
63  boost::mutex::scoped_lock _(shapes_lock_);
64  transform_callback_ = transform_callback;
65 }
66 
68  double scale, double padding)
69 {
70  boost::mutex::scoped_lock _(shapes_lock_);
71  SeeShape ss;
73  if (ss.body)
74  {
75  ss.body->setDimensionsDirty(shape.get());
76  ss.body->setScaleDirty(scale);
77  ss.body->setPaddingDirty(padding);
79  ss.volume = ss.body->computeVolume();
80  ss.handle = next_handle_;
81  std::pair<std::set<SeeShape, SortBodies>::iterator, bool> insert_op = bodies_.insert(ss);
82  if (!insert_op.second)
83  ROS_ERROR_NAMED(LOGNAME, "Internal error in management of bodies in ShapeMask. This is a serious error.");
84  used_handles_[next_handle_] = insert_op.first;
85  }
86  else
87  return 0;
88 
89  ShapeHandle ret = next_handle_;
90  const std::size_t sz = min_handle_ + bodies_.size() + 1;
91  for (std::size_t i = min_handle_; i < sz; ++i)
92  if (used_handles_.find(i) == used_handles_.end())
93  {
94  next_handle_ = i;
95  break;
96  }
97  min_handle_ = next_handle_;
98 
99  return ret;
100 }
101 
103 {
104  boost::mutex::scoped_lock _(shapes_lock_);
105  std::map<ShapeHandle, std::set<SeeShape, SortBodies>::iterator>::iterator it = used_handles_.find(handle);
106  if (it != used_handles_.end())
107  {
108  delete it->second->body;
109  bodies_.erase(it->second);
110  used_handles_.erase(it);
111  min_handle_ = handle;
112  }
113  else
114  ROS_ERROR_NAMED(LOGNAME, "Unable to remove shape handle %u", handle);
115 }
116 
117 void point_containment_filter::ShapeMask::maskContainment(const sensor_msgs::PointCloud2& data_in,
118  const Eigen::Vector3d& /*sensor_origin*/,
119  const double min_sensor_dist, const double max_sensor_dist,
120  std::vector<int>& mask)
121 {
122  boost::mutex::scoped_lock _(shapes_lock_);
123  const unsigned int np = data_in.data.size() / data_in.point_step;
124  mask.resize(np);
125 
126  if (bodies_.empty())
127  std::fill(mask.begin(), mask.end(), (int)OUTSIDE);
128  else
129  {
130  Eigen::Isometry3d tmp;
131  bspheres_.resize(bodies_.size());
132  std::size_t j = 0;
133  for (std::set<SeeShape>::const_iterator it = bodies_.begin(); it != bodies_.end(); ++it)
134  {
135  if (!transform_callback_(it->handle, tmp))
136  {
137  if (!it->body)
138  ROS_ERROR_STREAM_NAMED(LOGNAME, "Missing transform for shape with handle " << it->handle << " without a body");
139  else
140  ROS_ERROR_STREAM_NAMED(LOGNAME, "Missing transform for shape " << it->body->getType() << " with handle "
141  << it->handle);
142  }
143  else
144  {
145  it->body->setPose(tmp);
146  it->body->computeBoundingSphere(bspheres_[j++]);
147  }
148  }
149 
150  // compute a sphere that bounds the entire robot
153  const double radius_squared = bound.radius * bound.radius;
154 
155  // we now decide which points we keep
159 
160  // Cloud iterators are not incremented in the for loop, because of the pragma
161  // Comment out below parallelization as it can result in very high CPU consumption
162  //#pragma omp parallel for schedule(dynamic)
163  for (int i = 0; i < (int)np; ++i)
164  {
165  Eigen::Vector3d pt = Eigen::Vector3d(*(iter_x + i), *(iter_y + i), *(iter_z + i));
166  double d = pt.norm();
167  int out = OUTSIDE;
168  if (d < min_sensor_dist || d > max_sensor_dist)
169  out = CLIP;
170  else if ((bound.center - pt).squaredNorm() < radius_squared)
171  for (std::set<SeeShape>::const_iterator it = bodies_.begin(); it != bodies_.end() && out == OUTSIDE; ++it)
172  if (it->body->containsPoint(pt))
173  out = INSIDE;
174  mask[i] = out;
175  }
176  }
177 }
178 
180 {
181  boost::mutex::scoped_lock _(shapes_lock_);
182 
183  int out = OUTSIDE;
184  for (std::set<SeeShape>::const_iterator it = bodies_.begin(); it != bodies_.end() && out == OUTSIDE; ++it)
185  if (it->body->containsPoint(pt))
186  out = INSIDE;
187  return out;
188 }
189 
190 int point_containment_filter::ShapeMask::getMaskContainment(double x, double y, double z) const
191 {
192  return getMaskContainment(Eigen::Vector3d(x, y, z));
193 }
point_cloud2_iterator.h
point_containment_filter::ShapeHandle
unsigned int ShapeHandle
Definition: shape_mask.h:82
bodies::Body::computeVolume
virtual double computeVolume() const=0
bodies::Body::setDimensionsDirty
void setDimensionsDirty(const shapes::Shape *shape)
point_containment_filter::ShapeMask::TransformCallback
boost::function< bool(ShapeHandle, Eigen::Isometry3d &)> TransformCallback
Definition: shape_mask.h:96
ROS_ERROR_NAMED
#define ROS_ERROR_NAMED(name,...)
LOGNAME
static const std::string LOGNAME
Definition: shape_mask.cpp:42
sensor_msgs::PointCloud2ConstIterator
bodies::BoundingSphere
console.h
point_containment_filter::ShapeMask::~ShapeMask
virtual ~ShapeMask()
Destructor to clean up.
Definition: shape_mask.cpp:49
point_containment_filter::ShapeMask::maskContainment
void maskContainment(const sensor_msgs::PointCloud2 &data_in, const Eigen::Vector3d &sensor_pos, const double min_sensor_dist, const double max_sensor_dist, std::vector< int > &mask)
Compute the containment mask (INSIDE or OUTSIDE) for a given pointcloud. If a mask element is INSIDE,...
Definition: shape_mask.cpp:117
bodies::Body::setScaleDirty
void setScaleDirty(double scale)
bound
template Interval< double > bound(const Interval< double > &i, const Interval< double > &other)
y
double y
bodies::createEmptyBodyFromShapeType
Body * createEmptyBodyFromShapeType(const shapes::ShapeType &shapeType)
ROS_ERROR_STREAM_NAMED
#define ROS_ERROR_STREAM_NAMED(name, args)
point_containment_filter::ShapeMask::SeeShape
Definition: shape_mask.h:125
point_containment_filter::ShapeMask::freeMemory
void freeMemory()
Free memory.
Definition: shape_mask.cpp:54
point_containment_filter::ShapeMask::SeeShape::body
bodies::Body * body
Definition: shape_mask.h:132
d
d
body_operations.h
bodies::Body::updateInternalData
virtual void updateInternalData()=0
point_containment_filter::ShapeMask::SeeShape::handle
ShapeHandle handle
Definition: shape_mask.h:133
point_containment_filter::ShapeMask::removeShape
void removeShape(ShapeHandle handle)
Definition: shape_mask.cpp:102
point_containment_filter::ShapeMask::ShapeMask
ShapeMask(const TransformCallback &transform_callback=TransformCallback())
Construct the filter.
Definition: shape_mask.cpp:44
point_containment_filter::ShapeMask::setTransformCallback
void setTransformCallback(const TransformCallback &transform_callback)
Definition: shape_mask.cpp:61
bodies::Body::setPaddingDirty
void setPaddingDirty(double padd)
bodies::mergeBoundingSpheres
void mergeBoundingSpheres(const std::vector< BoundingSphere > &spheres, BoundingSphere &mergedSphere)
shapes::ShapeConstPtr
std::shared_ptr< const Shape > ShapeConstPtr
x
double x
shape_mask.h
point_containment_filter::ShapeMask::SeeShape::volume
double volume
Definition: shape_mask.h:134
point_containment_filter::ShapeMask::addShape
ShapeHandle addShape(const shapes::ShapeConstPtr &shape, double scale=1.0, double padding=0.0)
Definition: shape_mask.cpp:67
point_containment_filter::ShapeMask::getMaskContainment
int getMaskContainment(double x, double y, double z) const
Get the containment mask (INSIDE or OUTSIDE) value for an individual point. It is assumed the point i...
Definition: shape_mask.cpp:190
z
double z


perception
Author(s): Ioan Sucan , Jon Binney , Suat Gedikli
autogenerated on Fri Jun 21 2024 02:26:30