pinocchio  UNKNOWN
algorithm/geometry.hxx
1 //
2 // Copyright (c) 2015-2017 CNRS
3 //
4 // This file is part of Pinocchio
5 // Pinocchio is free software: you can redistribute it
6 // and/or modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation, either version
8 // 3 of the License, or (at your option) any later version.
9 //
10 // Pinocchio is distributed in the hope that it will be
11 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Lesser Public License for more details. You should have
14 // received a copy of the GNU Lesser General Public License along with
15 // Pinocchio If not, see
16 // <http://www.gnu.org/licenses/>.
17 
18 #ifndef __se3_algo_geometry_hxx__
19 #define __se3_algo_geometry_hxx__
20 
21 #include <boost/foreach.hpp>
22 
23 namespace se3
24 {
25  /* --- GEOMETRY PLACEMENTS -------------------------------------------------------- */
26  /* --- GEOMETRY PLACEMENTS -------------------------------------------------------- */
27  /* --- GEOMETRY PLACEMENTS -------------------------------------------------------- */
28  inline void updateGeometryPlacements(const Model & model,
29  Data & data,
30  const GeometryModel & geomModel,
31  GeometryData & geomData,
32  const Eigen::VectorXd & q
33  )
34  {
35  assert(model.check(data) && "data is not consistent with model.");
36 
37  forwardKinematics(model, data, q);
38  updateGeometryPlacements(model, data, geomModel, geomData);
39  }
40 
41  inline void updateGeometryPlacements(const Model & model,
42  const Data & data,
43  const GeometryModel & geomModel,
44  GeometryData & geomData
45  )
46  {
47  assert(model.check(data) && "data is not consistent with model.");
48 
49  for (GeomIndex i=0; i < (GeomIndex) geomModel.ngeoms; ++i)
50  {
51  const Model::JointIndex & joint = geomModel.geometryObjects[i].parentJoint;
52  if (joint>0) geomData.oMg[i] = (data.oMi[joint] * geomModel.geometryObjects[i].placement);
53  else geomData.oMg[i] = geomModel.geometryObjects[i].placement;
54 #ifdef WITH_HPP_FCL
55  geomData.collisionObjects[i].setTransform( toFclTransform3f(geomData.oMg[i]) );
56 #endif // WITH_HPP_FCL
57  }
58  }
59 #ifdef WITH_HPP_FCL
60 
61  /* --- COLLISIONS ----------------------------------------------------------------- */
62  /* --- COLLISIONS ----------------------------------------------------------------- */
63  /* --- COLLISIONS ----------------------------------------------------------------- */
64 
65  inline bool computeCollision(const GeometryModel & geomModel,
66  GeometryData & geomData,
67  const PairIndex& pairId)
68  {
69  assert( pairId < geomModel.collisionPairs.size() );
70  const CollisionPair & pair = geomModel.collisionPairs[pairId];
71 
72  assert( pairId < geomData.collisionResults.size() );
73  assert( pair.first < geomData.collisionObjects.size() );
74  assert( pair.second < geomData.collisionObjects.size() );
75 
76  fcl::CollisionResult& collisionResult = geomData.collisionResults[pairId];
77  collisionResult.clear();
78  fcl::collide (&geomData.collisionObjects[pair.first],
79  &geomData.collisionObjects[pair.second],
80  geomData.collisionRequest,
81  collisionResult);
82 
83  return collisionResult.isCollision();
84  }
85 
86  inline bool computeCollisions(const GeometryModel & geomModel,
87  GeometryData & geomData,
88  const bool stopAtFirstCollision = true)
89  {
90  bool isColliding = false;
91 
92  for (std::size_t cpt = 0; cpt < geomModel.collisionPairs.size(); ++cpt)
93  {
94  if(geomData.activeCollisionPairs[cpt])
95  {
96  computeCollision(geomModel,geomData,cpt);
97  isColliding |= geomData.collisionResults[cpt].isCollision();
98  if(isColliding && stopAtFirstCollision)
99  return true;
100  }
101  }
102 
103  return isColliding;
104  }
105 
106  // WARNING, if stopAtFirstcollision = true, then the collisions vector will not be fulfilled.
107  inline bool computeCollisions(const Model & model,
108  Data & data,
109  const GeometryModel & geomModel,
110  GeometryData & geomData,
111  const Eigen::VectorXd & q,
112  const bool stopAtFirstCollision
113  )
114  {
115  assert(model.check(data) && "data is not consistent with model.");
116 
117  updateGeometryPlacements (model, data, geomModel, geomData, q);
118 
119  return computeCollisions(geomModel,geomData, stopAtFirstCollision);
120  }
121 
122  /* --- DISTANCES ----------------------------------------------------------------- */
123  /* --- DISTANCES ----------------------------------------------------------------- */
124  /* --- DISTANCES ----------------------------------------------------------------- */
125 
126  inline fcl::DistanceResult & computeDistance(const GeometryModel & geomModel,
127  GeometryData & geomData,
128  const PairIndex & pairId )
129  {
130  assert( pairId < geomModel.collisionPairs.size() );
131  const CollisionPair & pair = geomModel.collisionPairs[pairId];
132 
133  assert( pairId < geomData.distanceResults.size() );
134  assert( pair.first < geomData.collisionObjects.size() );
135  assert( pair.second < geomData.collisionObjects.size() );
136 
137  geomData.distanceResults[pairId].clear();
138  fcl::distance ( &geomData.collisionObjects[pair.first],
139  &geomData.collisionObjects[pair.second],
140  geomData.distanceRequest,
141  geomData.distanceResults[pairId]);
142 
143  return geomData.distanceResults[pairId];
144  }
145 
146 
147  template <bool COMPUTE_SHORTEST>
148  inline std::size_t computeDistances(const GeometryModel & geomModel,
149  GeometryData & geomData)
150  {
151  std::size_t min_index = geomModel.collisionPairs.size();
152  double min_dist = std::numeric_limits<double>::infinity();
153  for (std::size_t cpt = 0; cpt < geomModel.collisionPairs.size(); ++cpt)
154  {
155  if(geomData.activeCollisionPairs[cpt])
156  {
157  computeDistance(geomModel,geomData,cpt);
158  if (COMPUTE_SHORTEST && geomData.distanceResults[cpt].min_distance < min_dist)
159  {
160  min_index = cpt;
161  min_dist = geomData.distanceResults[cpt].min_distance;
162  }
163  }
164  }
165  return min_index;
166  }
167 
168  // Required to have a default template argument on templated free function
169  inline std::size_t computeDistances(const GeometryModel& geomModel,
170  GeometryData & geomData)
171  {
172  return computeDistances<true>(geomModel,geomData);
173  }
174 
175  // Required to have a default template argument on templated free function
176  inline std::size_t computeDistances(const Model & model,
177  Data & data,
178  const GeometryModel & geomModel,
179  GeometryData & geomData,
180  const Eigen::VectorXd & q
181  )
182  {
183  return computeDistances<true>(model, data, geomModel, geomData, q);
184  }
185 
186  template <bool ComputeShortest>
187  inline std::size_t computeDistances(const Model & model,
188  Data & data,
189  const GeometryModel & geomModel,
190  GeometryData & geomData,
191  const Eigen::VectorXd & q
192  )
193  {
194  assert(model.check(data) && "data is not consistent with model.");
195  updateGeometryPlacements (model, data, geomModel, geomData, q);
196  return computeDistances<ComputeShortest>(geomModel,geomData);
197  }
198 
199  /* --- RADIUS -------------------------------------------------------------------- */
200  /* --- RADIUS -------------------------------------------------------------------- */
201  /* --- RADIUS -------------------------------------------------------------------- */
202 
205 #define SE3_GEOM_AABB(FCL,p1,p2,p3) \
206  SE3::Vector3( \
207  FCL->aabb_local.p1##_ [0], \
208  FCL->aabb_local.p2##_ [1], \
209  FCL->aabb_local.p3##_ [2])
210 
214  inline void computeBodyRadius(const Model & model,
215  const GeometryModel & geomModel,
216  GeometryData & geomData)
217  {
218  geomData.radius.resize(model.joints.size(),0);
219  BOOST_FOREACH(const GeometryObject & geom,geomModel.geometryObjects)
220  {
221  const boost::shared_ptr<const fcl::CollisionGeometry> & fcl
222  = geom.fcl;
223  const SE3 & jMb = geom.placement; // placement in joint.
224  const Model::JointIndex & i = geom.parentJoint;
225  assert (i<geomData.radius.size());
226 
227  double radius = geomData.radius[i] * geomData.radius[i];
228 
229  // The radius is simply the one of the 8 corners of the AABB cube, expressed
230  // in the joint frame, whose norm is the highest.
231  radius = std::max (jMb.act(SE3_GEOM_AABB(fcl,min,min,min)).squaredNorm(),radius);
232  radius = std::max (jMb.act(SE3_GEOM_AABB(fcl,min,min,max)).squaredNorm(),radius);
233  radius = std::max (jMb.act(SE3_GEOM_AABB(fcl,min,max,min)).squaredNorm(),radius);
234  radius = std::max (jMb.act(SE3_GEOM_AABB(fcl,min,max,max)).squaredNorm(),radius);
235  radius = std::max (jMb.act(SE3_GEOM_AABB(fcl,max,min,min)).squaredNorm(),radius);
236  radius = std::max (jMb.act(SE3_GEOM_AABB(fcl,max,min,max)).squaredNorm(),radius);
237  radius = std::max (jMb.act(SE3_GEOM_AABB(fcl,max,max,min)).squaredNorm(),radius);
238  radius = std::max (jMb.act(SE3_GEOM_AABB(fcl,max,max,max)).squaredNorm(),radius);
239 
240  // Don't forget to sqroot the squared norm before storing it.
241  geomData.radius[i] = sqrt(radius);
242  }
243  }
244 
245 #undef SE3_GEOM_AABB
246 #endif // WITH_HPP_FCL
247 
248  /* --- APPEND GEOMETRY MODEL ----------------------------------------------------------- */
249 
250  inline void appendGeometryModel(GeometryModel & geomModel1,
251  const GeometryModel & geomModel2)
252  {
253  assert (geomModel1.ngeoms == geomModel1.geometryObjects.size());
254  Index nGeom1 = geomModel1.geometryObjects.size();
255  Index nColPairs1 = geomModel1.collisionPairs.size();
256  assert (geomModel2.ngeoms == geomModel2.geometryObjects.size());
257  Index nGeom2 = geomModel2.geometryObjects.size();
258  Index nColPairs2 = geomModel2.collisionPairs.size();
259 
261  geomModel1.geometryObjects.insert(geomModel1.geometryObjects.end(),
262  geomModel2.geometryObjects.begin(), geomModel2.geometryObjects.end());
263  geomModel1.ngeoms += nGeom2;
264 
266  geomModel1.collisionPairs.reserve(nColPairs1 + nColPairs2 + nGeom1 * nGeom2);
267  for (Index i = 0; i < nColPairs2; ++i)
268  {
269  const CollisionPair& cp = geomModel2.collisionPairs[i];
270  geomModel1.collisionPairs.push_back(
271  CollisionPair (cp.first + nGeom1, cp.second + nGeom1)
272  );
273  }
274 
276  for (Index i = 0; i < nGeom1; ++i) {
277  for (Index j = 0; j < nGeom2; ++j) {
278  geomModel1.collisionPairs.push_back(CollisionPair(i, nGeom1 + j));
279  }
280  }
281  }
282 
283 } // namespace se3
284 
285 #endif // ifnded __se3_algo_geometry_hxx__
JointIndex parentJoint
Index of the parent joint.
Definition: fcl.hpp:102
container::aligned_vector< GeometryObject > geometryObjects
Vector of GeometryObjects used for collision computations.
boost::shared_ptr< fcl::CollisionGeometry > fcl
The actual cloud of points representing the collision mesh of the object after scaling.
Definition: fcl.hpp:105
std::vector< bool > activeCollisionPairs
Vector of collision pairs.
fcl::CollisionRequest collisionRequest
Defines what information should be computed by collision test.
JointModelVector joints
Model of joint i, encapsulated in a JointModelAccessor.
Definition: model.hpp:70
std::size_t computeDistances(const Model &model, Data &data, const GeometryModel &geomModel, GeometryData &geomData, const Eigen::VectorXd &q)
std::vector< fcl::CollisionResult > collisionResults
Vector gathering the result of the collision computation for all the collision pairs.
SE3 placement
Position of geometry object in parent joint frame.
Definition: fcl.hpp:108
std::vector< CollisionPair > collisionPairs
Vector of collision pairs.
void appendGeometryModel(GeometryModel &geomModel1, GeometryData &geomData1)
std::vector< fcl::DistanceResult > distanceResults
Vector gathering the result of the distance computation for all the collision pairs.
fcl::DistanceResult & computeDistance(const GeometryModel &geomModel, GeometryData &geomData, const PairIndex &pairId)
Compute the minimal distance between collision objects of a SINGLE collison pair. ...
fcl::DistanceRequest distanceRequest
Defines what information should be computed by distance computation.
std::vector< fcl::CollisionObject > collisionObjects
Collision objects (ie a fcl placed geometry).
void computeBodyRadius(const Model &model, const GeometryModel &geomModel, GeometryData &geomData)
bool computeCollision(const GeometryModel &geomModel, GeometryData &geomData, const PairIndex &pairId)
Compute the collision status between a SINGLE collision pair. The result is store in the collisionRes...
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Index ngeoms
The number of GeometryObjects.
std::vector< double > radius
Radius of the bodies, i.e. distance of the further point of the geometry model attached to the body f...
void forwardKinematics(const Model &model, Data &data, const Eigen::VectorXd &q)
Update the joint placements according to the current joint configuration.
Definition: kinematics.hxx:106
container::aligned_vector< SE3 > oMi
Vector of absolute joint placements (wrt the world).
Definition: data.hpp:87
EIGEN_MAKE_ALIGNED_OPERATOR_NEW container::aligned_vector< se3::SE3 > oMg
Vector gathering the SE3 placements of the geometry objects relative to the world. See updateGeometryPlacements to update the placements.
bool check(const AlgorithmCheckerBase< D > &checker=AlgorithmCheckerBase< D >()) const
Definition: model.hpp:331
internal::SE3GroupAction< D >::ReturnType act(const D &d) const
ay = aXb.act(by)
Definition: se3.hpp:94
bool computeCollisions(const Model &model, Data &data, const GeometryModel &geomModel, GeometryData &geomData, const Eigen::VectorXd &q, const bool stopAtFirstCollision=false)
void updateGeometryPlacements(const Model &model, Data &data, const GeometryModel &geomModel, GeometryData &geomData, const Eigen::VectorXd &q)
Apply a forward kinematics and update the placement of the geometry objects.