| Directory: | ./ | 
|---|---|
| File: | include/pinocchio/collision/broadphase-callbacks.hpp | 
| Date: | 2025-02-12 21:03:38 | 
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 62 | 69 | 89.9% | 
| Branches: | 28 | 132 | 21.2% | 
| Line | Branch | Exec | Source | 
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2022 INRIA | ||
| 3 | // | ||
| 4 | |||
| 5 | #ifndef __pinocchio_collision_broadphase_callback_hpp__ | ||
| 6 | #define __pinocchio_collision_broadphase_callback_hpp__ | ||
| 7 | |||
| 8 | #include <hpp/fcl/broadphase/broadphase_callbacks.h> | ||
| 9 | |||
| 10 | #include "pinocchio/multibody/fcl.hpp" | ||
| 11 | #include "pinocchio/multibody/geometry.hpp" | ||
| 12 | |||
| 13 | #include "pinocchio/collision/collision.hpp" | ||
| 14 | |||
| 15 | namespace pinocchio | ||
| 16 | { | ||
| 17 | |||
| 18 | /// @brief Interface for Pinocchio collision callback functors | ||
| 19 | struct CollisionCallBackBase : hpp::fcl::CollisionCallBackBase | ||
| 20 | { | ||
| 21 | 2008 | CollisionCallBackBase(const GeometryModel & geometry_model, GeometryData & geometry_data) | |
| 22 | 4016 | : geometry_model_ptr(&geometry_model) | |
| 23 | 2008 | , geometry_data_ptr(&geometry_data) | |
| 24 | 2008 | , collision(false) | |
| 25 | 2008 | , accumulate(false) | |
| 26 | { | ||
| 27 | 2008 | } | |
| 28 | |||
| 29 | 34136 | const GeometryModel & getGeometryModel() const | |
| 30 | { | ||
| 31 | 34136 | return *geometry_model_ptr; | |
| 32 | } | ||
| 33 | const GeometryData & getGeometryData() const | ||
| 34 | { | ||
| 35 | return *geometry_data_ptr; | ||
| 36 | } | ||
| 37 | 34136 | GeometryData & getGeometryData() | |
| 38 | { | ||
| 39 | 34136 | return *geometry_data_ptr; | |
| 40 | } | ||
| 41 | |||
| 42 | /// \brief If true, the stopping criteria related to the collision callback has been met and one | ||
| 43 | /// can stop. | ||
| 44 | virtual bool stop() const = 0; | ||
| 45 | |||
| 46 | /// \brief Callback method called after the termination of a collisition detection algorithm. | ||
| 47 | /// The default implementation does nothing. | ||
| 48 | ✗ | virtual void done() {}; | |
| 49 | |||
| 50 | protected: | ||
| 51 | /// @brief Geometry model associated to the callback | ||
| 52 | const GeometryModel * geometry_model_ptr; | ||
| 53 | |||
| 54 | /// @brief Geometry data associated to the callback | ||
| 55 | GeometryData * geometry_data_ptr; | ||
| 56 | |||
| 57 | public: | ||
| 58 | /// @brief Whether there is a collision or not | ||
| 59 | bool collision; | ||
| 60 | |||
| 61 | /// @brief Whether the callback is used in an accumulate mode where several collide methods are | ||
| 62 | /// called successively. | ||
| 63 | bool accumulate; | ||
| 64 | }; | ||
| 65 | |||
| 66 | struct CollisionCallBackDefault : CollisionCallBackBase | ||
| 67 | { | ||
| 68 | 2008 | CollisionCallBackDefault( | |
| 69 | const GeometryModel & geometry_model, | ||
| 70 | GeometryData & geometry_data, | ||
| 71 | bool stopAtFirstCollision = false) | ||
| 72 | 2008 | : CollisionCallBackBase(geometry_model, geometry_data) | |
| 73 | 2008 | , stopAtFirstCollision(stopAtFirstCollision) | |
| 74 | 2008 | , count(0) | |
| 75 | // , visited(Eigen::MatrixXd::Zero(geometry_model.ngeoms,geometry_model.ngeoms)) | ||
| 76 | { | ||
| 77 | 2008 | } | |
| 78 | |||
| 79 | 532120 | void init() | |
| 80 | { | ||
| 81 | 
        2/2✓ Branch 0 taken 530112 times. 
          ✓ Branch 1 taken 2008 times. 
         | 
      532120 | if (accumulate) // skip reseting of the parameters | 
| 82 | 530112 | return; | |
| 83 | |||
| 84 | 2008 | count = 0; | |
| 85 | 2008 | collision = false; | |
| 86 | 2008 | collisionPairIndex = std::numeric_limits<PairIndex>::max(); | |
| 87 | // visited.setZero(); | ||
| 88 | } | ||
| 89 | |||
| 90 | 67826 | bool collide(hpp::fcl::CollisionObject * o1, hpp::fcl::CollisionObject * o2) | |
| 91 | { | ||
| 92 | |||
| 93 | 
        1/2✓ Branch 1 taken 67826 times. 
          ✗ Branch 2 not taken. 
         | 
      67826 | assert(!stop() && "must never happened"); | 
| 94 | |||
| 95 | 67826 | CollisionObject & co1 = reinterpret_cast<CollisionObject &>(*o1); | |
| 96 | 67826 | CollisionObject & co2 = reinterpret_cast<CollisionObject &>(*o2); | |
| 97 | |||
| 98 | 67826 | const Eigen::DenseIndex go1_index = (Eigen::DenseIndex)co1.geometryObjectIndex; | |
| 99 | 67826 | const Eigen::DenseIndex go2_index = (Eigen::DenseIndex)co2.geometryObjectIndex; | |
| 100 | |||
| 101 | 67826 | const GeometryModel & geometry_model = *geometry_model_ptr; | |
| 102 | |||
| 103 | 
        2/6✓ Branch 0 taken 67826 times. 
          ✗ Branch 1 not taken. 
          ✗ Branch 2 not taken. 
          ✓ Branch 3 taken 67826 times. 
          ✗ Branch 6 not taken. 
          ✗ Branch 7 not taken. 
         | 
      67826 | PINOCCHIO_CHECK_INPUT_ARGUMENT( | 
| 104 | go1_index < (Eigen::DenseIndex)geometry_model.ngeoms && go1_index >= 0); | ||
| 105 | 
        2/6✓ Branch 0 taken 67826 times. 
          ✗ Branch 1 not taken. 
          ✗ Branch 2 not taken. 
          ✓ Branch 3 taken 67826 times. 
          ✗ Branch 6 not taken. 
          ✗ Branch 7 not taken. 
         | 
      67826 | PINOCCHIO_CHECK_INPUT_ARGUMENT( | 
| 106 | go2_index < (Eigen::DenseIndex)geometry_model.ngeoms && go2_index >= 0); | ||
| 107 | |||
| 108 | 
        1/2✓ Branch 1 taken 67826 times. 
          ✗ Branch 2 not taken. 
         | 
      67826 | const int pair_index = geometry_model.collisionPairMapping(go1_index, go2_index); | 
| 109 | 
        2/2✓ Branch 0 taken 57516 times. 
          ✓ Branch 1 taken 10310 times. 
         | 
      67826 | if (pair_index == -1) | 
| 110 | 57516 | return false; | |
| 111 | |||
| 112 | 10310 | const GeometryData & geometry_data = *geometry_data_ptr; | |
| 113 | 10310 | const CollisionPair & cp = geometry_model.collisionPairs[(PairIndex)pair_index]; | |
| 114 | const bool do_collision_check = | ||
| 115 | 
        1/2✓ Branch 1 taken 10310 times. 
          ✗ Branch 2 not taken. 
         | 
      10310 | geometry_data.activeCollisionPairs[(PairIndex)pair_index] | 
| 116 | 
        1/2✓ Branch 0 taken 10310 times. 
          ✗ Branch 1 not taken. 
         | 
      20620 | && !( | 
| 117 | 
        1/2✓ Branch 1 taken 10310 times. 
          ✗ Branch 2 not taken. 
         | 
      10310 | geometry_model.geometryObjects[cp.first].disableCollision | 
| 118 | 
        1/2✓ Branch 1 taken 10310 times. 
          ✗ Branch 2 not taken. 
         | 
      10310 | || geometry_model.geometryObjects[cp.second].disableCollision); | 
| 119 | 
        1/2✗ Branch 0 not taken. 
          ✓ Branch 1 taken 10310 times. 
         | 
      10310 | if (!do_collision_check) | 
| 120 | ✗ | return false; | |
| 121 | |||
| 122 | 10310 | count++; | |
| 123 | |||
| 124 | fcl::CollisionRequest collision_request( | ||
| 125 | 
        1/2✓ Branch 2 taken 10310 times. 
          ✗ Branch 3 not taken. 
         | 
      10310 | geometry_data_ptr->collisionRequests[size_t(pair_index)]); | 
| 126 | 10310 | collision_request.gjk_variant = fcl::GJKVariant::NesterovAcceleration; | |
| 127 | // collision_request.gjk_initial_guess = fcl::GJKInitialGuess::BoundingVolumeGuess; | ||
| 128 | |||
| 129 | 10310 | if ( | |
| 130 | 10310 | co1.collisionGeometry().get() | |
| 131 | 10310 | != geometry_model.geometryObjects[size_t(go1_index)].geometry.get() | |
| 132 | 
        3/6✓ Branch 0 taken 10310 times. 
          ✗ Branch 1 not taken. 
          ✗ Branch 4 not taken. 
          ✓ Branch 5 taken 10310 times. 
          ✗ Branch 6 not taken. 
          ✓ Branch 7 taken 10310 times. 
         | 
      20620 | || co2.collisionGeometry().get() | 
| 133 | 10310 | != geometry_model.geometryObjects[size_t(go2_index)].geometry.get()) | |
| 134 | ✗ | PINOCCHIO_THROW_PRETTY( | |
| 135 | std::logic_error, "go1: " << go1_index << " or go2: " << go2_index | ||
| 136 | << " have not been updated and have missmatching pointers."); | ||
| 137 | // if(!(co1.collisionGeometry()->aabb_local.volume() < 0 || | ||
| 138 | // co2.collisionGeometry()->aabb_local.volume() <0)) { // TODO(jcarpent): check potential | ||
| 139 | // bug | ||
| 140 | // collision_request.gjk_initial_guess = fcl::GJKInitialGuess::BoundingVolumeGuess; | ||
| 141 | // } | ||
| 142 | |||
| 143 | bool res; | ||
| 144 | try | ||
| 145 | { | ||
| 146 | 20620 | res = computeCollision( | |
| 147 | 
        1/2✓ Branch 1 taken 10310 times. 
          ✗ Branch 2 not taken. 
         | 
      10310 | *geometry_model_ptr, *geometry_data_ptr, (PairIndex)pair_index, collision_request); | 
| 148 | } | ||
| 149 | ✗ | catch (std::logic_error & e) | |
| 150 | { | ||
| 151 | ✗ | PINOCCHIO_THROW_PRETTY( | |
| 152 | std::logic_error, "Geometries with index go1: " | ||
| 153 | << go1_index << " or go2: " << go2_index | ||
| 154 | << " have produced an internal error within HPP-FCL.\n what:\n" | ||
| 155 | << e.what()); | ||
| 156 | } | ||
| 157 | |||
| 158 | 
        4/4✓ Branch 0 taken 1004 times. 
          ✓ Branch 1 taken 9306 times. 
          ✓ Branch 2 taken 330 times. 
          ✓ Branch 3 taken 674 times. 
         | 
      10310 | if (res && !collision) | 
| 159 | { | ||
| 160 | 330 | collision = true; | |
| 161 | 330 | collisionPairIndex = (PairIndex)pair_index; | |
| 162 | } | ||
| 163 | |||
| 164 | 
        1/2✓ Branch 0 taken 10310 times. 
          ✗ Branch 1 not taken. 
         | 
      10310 | if (!stopAtFirstCollision) | 
| 165 | 10310 | return false; | |
| 166 | else | ||
| 167 | ✗ | return res; | |
| 168 | } | ||
| 169 | |||
| 170 | 597938 | bool stop() const final | |
| 171 | { | ||
| 172 | 
        1/4✗ Branch 0 not taken. 
          ✓ Branch 1 taken 597938 times. 
          ✗ Branch 2 not taken. 
          ✗ Branch 3 not taken. 
         | 
      597938 | if (stopAtFirstCollision && collision) | 
| 173 | ✗ | return true; | |
| 174 | |||
| 175 | 597938 | return false; | |
| 176 | } | ||
| 177 | |||
| 178 | 3012 | void done() final | |
| 179 | { | ||
| 180 | 
        2/2✓ Branch 0 taken 495 times. 
          ✓ Branch 1 taken 2517 times. 
         | 
      3012 | if (collision) | 
| 181 | 495 | geometry_data_ptr->collisionPairIndex = collisionPairIndex; | |
| 182 | 3012 | } | |
| 183 | |||
| 184 | /// @brief Whether to stop or not when localizing a first collision | ||
| 185 | bool stopAtFirstCollision; | ||
| 186 | |||
| 187 | /// @brief The collision index of the first pair in collision | ||
| 188 | PairIndex collisionPairIndex; | ||
| 189 | |||
| 190 | /// @brief Number of visits of the collide method | ||
| 191 | size_t count; | ||
| 192 | |||
| 193 | // Eigen::MatrixXd visited; | ||
| 194 | }; | ||
| 195 | |||
| 196 | } // namespace pinocchio | ||
| 197 | |||
| 198 | /* --- Details -------------------------------------------------------------------- */ | ||
| 199 | #include "pinocchio/collision/broadphase-callbacks.hxx" | ||
| 200 | |||
| 201 | #endif // ifndef __pinocchio_collision_broadphase_callback_hpp__ | ||
| 202 |