| Directory: | ./ |
|---|---|
| File: | include/pinocchio/collision/collision.hxx |
| Date: | 2025-02-12 21:03:38 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 64 | 69 | 92.8% |
| Branches: | 90 | 281 | 32.0% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2015-2021 CNRS INRIA | ||
| 3 | // | ||
| 4 | |||
| 5 | #ifndef __pinocchio_collision_collision_hxx__ | ||
| 6 | #define __pinocchio_collision_collision_hxx__ | ||
| 7 | |||
| 8 | #include "pinocchio/multibody/model.hpp" | ||
| 9 | #include "pinocchio/multibody/data.hpp" | ||
| 10 | |||
| 11 | #include "pinocchio/multibody/geometry.hpp" | ||
| 12 | #include "pinocchio/algorithm/geometry.hpp" | ||
| 13 | #include "pinocchio/collision/distance.hpp" | ||
| 14 | |||
| 15 | namespace pinocchio | ||
| 16 | { | ||
| 17 | |||
| 18 | 152721 | inline bool computeCollision( | |
| 19 | const GeometryModel & geom_model, | ||
| 20 | GeometryData & geom_data, | ||
| 21 | const PairIndex pair_id, | ||
| 22 | fcl::CollisionRequest & collision_request) | ||
| 23 | { | ||
| 24 |
1/4✗ Branch 2 not taken.
✓ Branch 3 taken 152721 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
152721 | PINOCCHIO_CHECK_INPUT_ARGUMENT( |
| 25 | geom_model.collisionPairs.size() == geom_data.collisionResults.size()); | ||
| 26 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 152721 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
152721 | PINOCCHIO_CHECK_INPUT_ARGUMENT(pair_id < geom_model.collisionPairs.size()); |
| 27 | |||
| 28 | 152721 | const CollisionPair & pair = geom_model.collisionPairs[pair_id]; | |
| 29 | |||
| 30 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 152721 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
152721 | PINOCCHIO_CHECK_INPUT_ARGUMENT(pair.first < geom_model.ngeoms); |
| 31 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 152721 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
152721 | PINOCCHIO_CHECK_INPUT_ARGUMENT(pair.second < geom_model.ngeoms); |
| 32 | |||
| 33 | 152721 | collision_request.distance_upper_bound = | |
| 34 | 152721 | collision_request.security_margin + 1e-6; // TODO: change the margin | |
| 35 | |||
| 36 | 152721 | fcl::CollisionResult & collision_result = geom_data.collisionResults[pair_id]; | |
| 37 |
1/2✓ Branch 1 taken 152721 times.
✗ Branch 2 not taken.
|
152721 | collision_result.clear(); |
| 38 | |||
| 39 |
1/2✓ Branch 2 taken 152721 times.
✗ Branch 3 not taken.
|
152721 | fcl::Transform3f oM1(toFclTransform3f(geom_data.oMg[pair.first])), |
| 40 |
1/2✓ Branch 2 taken 152721 times.
✗ Branch 3 not taken.
|
152721 | oM2(toFclTransform3f(geom_data.oMg[pair.second])); |
| 41 | |||
| 42 | try | ||
| 43 | { | ||
| 44 | 152721 | GeometryData::ComputeCollision & do_computations = geom_data.collision_functors[pair_id]; | |
| 45 |
1/2✓ Branch 1 taken 152721 times.
✗ Branch 2 not taken.
|
152721 | do_computations(oM1, oM2, collision_request, collision_result); |
| 46 | } | ||
| 47 | ✗ | catch (std::invalid_argument & e) | |
| 48 | { | ||
| 49 | ✗ | PINOCCHIO_THROW_PRETTY( | |
| 50 | std::invalid_argument, "Problem when trying to check the collision of collision pair #" | ||
| 51 | << pair_id << " (" << pair.first << "," << pair.second << ")" | ||
| 52 | << std::endl | ||
| 53 | << "hpp-fcl original error:\n" | ||
| 54 | << e.what() << std::endl); | ||
| 55 | } | ||
| 56 | ✗ | catch (std::logic_error & e) | |
| 57 | { | ||
| 58 | ✗ | PINOCCHIO_THROW_PRETTY( | |
| 59 | std::logic_error, "Problem when trying to check the collision of collision pair #" | ||
| 60 | << pair_id << " (" << pair.first << "," << pair.second << ")" | ||
| 61 | << std::endl | ||
| 62 | << "hpp-fcl original error:\n" | ||
| 63 | << e.what() << std::endl); | ||
| 64 | } | ||
| 65 | |||
| 66 | 305442 | return collision_result.isCollision(); | |
| 67 | } | ||
| 68 | |||
| 69 | 142411 | inline bool computeCollision( | |
| 70 | const GeometryModel & geom_model, GeometryData & geom_data, const PairIndex pair_id) | ||
| 71 | { | ||
| 72 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 142411 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
142411 | PINOCCHIO_CHECK_INPUT_ARGUMENT(pair_id < geom_model.collisionPairs.size()); |
| 73 | 142411 | fcl::CollisionRequest & collision_request = geom_data.collisionRequests[pair_id]; | |
| 74 | |||
| 75 | 142411 | return computeCollision(geom_model, geom_data, pair_id, collision_request); | |
| 76 | } | ||
| 77 | |||
| 78 | 2010 | inline bool computeCollisions( | |
| 79 | const GeometryModel & geom_model, GeometryData & geom_data, const bool stopAtFirstCollision) | ||
| 80 | { | ||
| 81 | 2010 | bool isColliding = false; | |
| 82 | |||
| 83 |
2/2✓ Branch 1 taken 142334 times.
✓ Branch 2 taken 2010 times.
|
144344 | for (std::size_t cp_index = 0; cp_index < geom_model.collisionPairs.size(); ++cp_index) |
| 84 | { | ||
| 85 | 142334 | const CollisionPair & cp = geom_model.collisionPairs[cp_index]; | |
| 86 | |||
| 87 | 142334 | if ( | |
| 88 |
1/2✓ Branch 1 taken 142334 times.
✗ Branch 2 not taken.
|
142334 | geom_data.activeCollisionPairs[cp_index] |
| 89 |
2/4✓ Branch 0 taken 142334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 142334 times.
✗ Branch 3 not taken.
|
284668 | && !( |
| 90 |
1/2✓ Branch 1 taken 142334 times.
✗ Branch 2 not taken.
|
142334 | geom_model.geometryObjects[cp.first].disableCollision |
| 91 |
1/2✓ Branch 2 taken 142334 times.
✗ Branch 3 not taken.
|
284668 | || geom_model.geometryObjects[cp.second].disableCollision)) |
| 92 | { | ||
| 93 | 142334 | bool res = computeCollision(geom_model, geom_data, cp_index); | |
| 94 |
4/4✓ Branch 0 taken 126380 times.
✓ Branch 1 taken 15954 times.
✓ Branch 2 taken 330 times.
✓ Branch 3 taken 126050 times.
|
142334 | if (!isColliding && res) |
| 95 | { | ||
| 96 | 330 | isColliding = true; | |
| 97 | 330 | geom_data.collisionPairIndex = cp_index; // first pair to be in collision | |
| 98 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 330 times.
|
330 | if (stopAtFirstCollision) |
| 99 | ✗ | return true; | |
| 100 | } | ||
| 101 | } | ||
| 102 | } | ||
| 103 | |||
| 104 | 2010 | return isColliding; | |
| 105 | } | ||
| 106 | |||
| 107 | /* --- COLLISIONS ----------------------------------------------------------------- */ | ||
| 108 | /* --- COLLISIONS ----------------------------------------------------------------- */ | ||
| 109 | /* --- COLLISIONS ----------------------------------------------------------------- */ | ||
| 110 | |||
| 111 | // WARNING, if stopAtFirstcollision = true, then the collisions vector will not be fulfilled. | ||
| 112 | template< | ||
| 113 | typename Scalar, | ||
| 114 | int Options, | ||
| 115 | template<typename, int> class JointCollectionTpl, | ||
| 116 | typename ConfigVectorType> | ||
| 117 | 2004 | inline bool computeCollisions( | |
| 118 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 119 | DataTpl<Scalar, Options, JointCollectionTpl> & data, | ||
| 120 | const GeometryModel & geom_model, | ||
| 121 | GeometryData & geom_data, | ||
| 122 | const Eigen::MatrixBase<ConfigVectorType> & q, | ||
| 123 | const bool stopAtFirstCollision) | ||
| 124 | { | ||
| 125 | 2004 | updateGeometryPlacements(model, data, geom_model, geom_data, q); | |
| 126 | 2004 | return computeCollisions(geom_model, geom_data, stopAtFirstCollision); | |
| 127 | } | ||
| 128 | |||
| 129 | /* --- RADIUS -------------------------------------------------------------------- */ | ||
| 130 | /* --- RADIUS -------------------------------------------------------------------- */ | ||
| 131 | /* --- RADIUS -------------------------------------------------------------------- */ | ||
| 132 | |||
| 133 | /// Given p1..3 being either "min" or "max", return one of the corners of the | ||
| 134 | /// AABB cub of the FCL object. | ||
| 135 | #define PINOCCHIO_GEOM_AABB(FCL, p1, p2, p3) \ | ||
| 136 | SE3::Vector3(FCL->aabb_local.p1##_[0], FCL->aabb_local.p2##_[1], FCL->aabb_local.p3##_[2]) | ||
| 137 | |||
| 138 | /// For all bodies of the model, compute the point of the geometry model | ||
| 139 | /// that is the further from the center of the joint. This quantity is used | ||
| 140 | /// in some continuous collision test. | ||
| 141 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
| 142 | 1 | inline void computeBodyRadius( | |
| 143 | const ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
| 144 | const GeometryModel & geom_model, | ||
| 145 | GeometryData & geom_data) | ||
| 146 | { | ||
| 147 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | geom_data.radius.resize(model.joints.size(), 0); |
| 148 |
18/30✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 20 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 20 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 20 times.
✓ Branch 25 taken 20 times.
✓ Branch 26 taken 20 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 20 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 21 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 21 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 20 times.
✓ Branch 37 taken 1 times.
✓ Branch 38 taken 20 times.
✓ Branch 39 taken 1 times.
|
41 | BOOST_FOREACH (const GeometryObject & geom_object, geom_model.geometryObjects) |
| 149 | { | ||
| 150 | 20 | const GeometryObject::CollisionGeometryPtr & geometry = geom_object.geometry; | |
| 151 | |||
| 152 | // Force computation of the Local AABB | ||
| 153 | // TODO: change for a more elegant solution | ||
| 154 |
1/2✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
|
20 | const_cast<hpp::fcl::CollisionGeometry &>(*geometry).computeLocalAABB(); |
| 155 | |||
| 156 | 20 | const GeometryModel::SE3 & jMb = geom_object.placement; // placement in joint. | |
| 157 | 20 | const Model::JointIndex i = geom_object.parentJoint; | |
| 158 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
|
20 | assert(i < geom_data.radius.size()); |
| 159 | |||
| 160 | 20 | Scalar radius = geom_data.radius[i] * geom_data.radius[i]; | |
| 161 | |||
| 162 | // The radius is simply the one of the 8 corners of the AABB cube, expressed | ||
| 163 | // in the joint frame, whose norm is the highest. | ||
| 164 | 20 | radius = | |
| 165 |
6/12✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 20 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 20 times.
✗ Branch 20 not taken.
|
20 | std::max(jMb.act(PINOCCHIO_GEOM_AABB(geometry, min, min, min)).squaredNorm(), radius); |
| 166 | 20 | radius = | |
| 167 |
6/12✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 20 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 20 times.
✗ Branch 20 not taken.
|
20 | std::max(jMb.act(PINOCCHIO_GEOM_AABB(geometry, min, min, max)).squaredNorm(), radius); |
| 168 | 20 | radius = | |
| 169 |
6/12✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 20 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 20 times.
✗ Branch 20 not taken.
|
20 | std::max(jMb.act(PINOCCHIO_GEOM_AABB(geometry, min, max, min)).squaredNorm(), radius); |
| 170 | 20 | radius = | |
| 171 |
6/12✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 20 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 20 times.
✗ Branch 20 not taken.
|
20 | std::max(jMb.act(PINOCCHIO_GEOM_AABB(geometry, min, max, max)).squaredNorm(), radius); |
| 172 | 20 | radius = | |
| 173 |
6/12✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 20 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 20 times.
✗ Branch 20 not taken.
|
20 | std::max(jMb.act(PINOCCHIO_GEOM_AABB(geometry, max, min, min)).squaredNorm(), radius); |
| 174 | 20 | radius = | |
| 175 |
6/12✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 20 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 20 times.
✗ Branch 20 not taken.
|
20 | std::max(jMb.act(PINOCCHIO_GEOM_AABB(geometry, max, min, max)).squaredNorm(), radius); |
| 176 | 20 | radius = | |
| 177 |
6/12✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 20 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 20 times.
✗ Branch 20 not taken.
|
20 | std::max(jMb.act(PINOCCHIO_GEOM_AABB(geometry, max, max, min)).squaredNorm(), radius); |
| 178 | 20 | radius = | |
| 179 |
6/12✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 20 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 20 times.
✗ Branch 20 not taken.
|
20 | std::max(jMb.act(PINOCCHIO_GEOM_AABB(geometry, max, max, max)).squaredNorm(), radius); |
| 180 | |||
| 181 | // Don't forget to sqroot the squared norm before storing it. | ||
| 182 | 20 | geom_data.radius[i] = sqrt(radius); | |
| 183 | } | ||
| 184 | 1 | } | |
| 185 | |||
| 186 | #undef PINOCCHIO_GEOM_AABB | ||
| 187 | |||
| 188 | } // namespace pinocchio | ||
| 189 | |||
| 190 | #endif // ifndef __pinocchio_collision_collision_hxx__ | ||
| 191 |