GCC Code Coverage Report


Directory: ./
File: src/distance-between-bodies.cc
Date: 2025-05-05 12:19:30
Exec Total Coverage
Lines: 0 78 0.0%
Branches: 0 180 0.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2015 CNRS
3 // Authors: Florent Lamiraux
4 //
5 //
6
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met:
10 //
11 // 1. Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //
14 // 2. Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30
31 #include <hpp/constraints/distance-between-bodies.hh>
32 #include <hpp/pinocchio/body.hh>
33 #include <hpp/pinocchio/device.hh>
34 #include <hpp/pinocchio/joint-collection.hh>
35 #include <hpp/pinocchio/joint.hh>
36 #include <pinocchio/algorithm/geometry.hpp>
37
38 namespace hpp {
39 namespace constraints {
40 typedef std::vector<CollisionObjectPtr_t> CollisionObjects_t;
41
42 ✗ void initGeomData(const pinocchio::GeomModel& model, pinocchio::GeomData& data,
43 const pinocchio::BodyPtr_t& body,
44 const CollisionObjects_t& objects) {
45 // Deactivate all collision pairs.
46 ✗ for (std::size_t i = 0; i < model.collisionPairs.size(); ++i)
47 ✗ data.deactivateCollisionPair(i);
48 // Activate only the relevant ones.
49 ✗ for (size_type i = 0; i < body->nbInnerObjects(); ++i) {
50 ✗ CollisionObjectConstPtr_t obj1(body->innerObjectAt(i));
51 ✗ for (std::size_t j = 0; j < objects.size(); ++j) {
52 ✗ CollisionObjectConstPtr_t obj2(objects[j]);
53 ✗ std::size_t idx = model.findCollisionPair(::pinocchio::CollisionPair(
54 ✗ obj1->indexInModel(), obj2->indexInModel()));
55 ✗ if (idx < model.collisionPairs.size())
56 ✗ data.activateCollisionPair(idx);
57 else
58 ✗ throw std::invalid_argument("Collision pair not found");
59 }
60 }
61 }
62
63 ✗ DistanceBetweenBodiesPtr_t DistanceBetweenBodies::create(
64 const std::string& name, const DevicePtr_t& robot, const JointPtr_t& joint1,
65 const JointPtr_t& joint2) {
66 DistanceBetweenBodies* ptr =
67 ✗ new DistanceBetweenBodies(name, robot, joint1, joint2);
68 ✗ DistanceBetweenBodiesPtr_t shPtr(ptr);
69 ✗ return shPtr;
70 }
71
72 ✗ DistanceBetweenBodiesPtr_t DistanceBetweenBodies::create(
73 const std::string& name, const DevicePtr_t& robot, const JointPtr_t& joint,
74 const CollisionObjects_t& objects) {
75 DistanceBetweenBodies* ptr =
76 ✗ new DistanceBetweenBodies(name, robot, joint, objects);
77 ✗ DistanceBetweenBodiesPtr_t shPtr(ptr);
78 ✗ return shPtr;
79 }
80
81 ✗ DistanceBetweenBodies::DistanceBetweenBodies(const std::string& name,
82 const DevicePtr_t& robot,
83 const JointPtr_t& joint1,
84 ✗ const JointPtr_t& joint2)
85 : DifferentiableFunction(robot->configSize(), robot->numberDof(),
86 ✗ LiegroupSpace::R1(), name),
87 ✗ robot_(robot),
88 ✗ joint1_(joint1),
89 ✗ joint2_(joint2),
90 ✗ data_(robot->geomModel()),
91 ✗ latestResult_(outputSpace()) {
92 ✗ pinocchio::BodyPtr_t body2(joint2_->linkedBody());
93 ✗ CollisionObjects_t objects2(body2->nbInnerObjects());
94 ✗ for (std::size_t j = 0; j < objects2.size(); ++j)
95 ✗ objects2[j] = body2->innerObjectAt(j);
96 ✗ initGeomData(robot_->geomModel(), data_, joint1_->linkedBody(), objects2);
97 }
98
99 ✗ DistanceBetweenBodies::DistanceBetweenBodies(const std::string& name,
100 const DevicePtr_t& robot,
101 const JointPtr_t& joint,
102 ✗ const CollisionObjects_t& objects)
103 : DifferentiableFunction(robot->configSize(), robot->numberDof(),
104 ✗ LiegroupSpace::R1(), name),
105 ✗ robot_(robot),
106 ✗ joint1_(joint),
107 ✗ joint2_(),
108 ✗ data_(robot->geomModel()),
109 ✗ latestResult_(outputSpace()) {
110 ✗ initGeomData(robot_->geomModel(), data_, joint1_->linkedBody(), objects);
111 }
112
113 ✗ void DistanceBetweenBodies::impl_compute(LiegroupElementRef result,
114 ConfigurationIn_t argument) const {
115 ✗ if ((argument.rows() == latestArgument_.rows()) &&
116 ✗ (argument == latestArgument_)) {
117 ✗ result = latestResult_;
118 ✗ return;
119 }
120 ✗ robot_->currentConfiguration(argument);
121 ✗ robot_->computeForwardKinematics(pinocchio::JOINT_POSITION |
122 pinocchio::JACOBIAN);
123 ✗ ::pinocchio::updateGeometryPlacements(robot_->model(), robot_->data(),
124 ✗ robot_->geomModel(), data_);
125 ✗ minIndex_ = ::pinocchio::computeDistances(robot_->geomModel(), data_);
126 ✗ result.vector()[0] = data_.distanceResults[minIndex_].min_distance;
127 ✗ latestArgument_ = argument;
128 ✗ latestResult_ = result;
129 }
130
131 ✗ void DistanceBetweenBodies::impl_jacobian(matrixOut_t jacobian,
132 ConfigurationIn_t arg) const {
133 ✗ LiegroupElement dist(outputSpace());
134 ✗ impl_compute(dist, arg);
135 ✗ const JointJacobian_t& J1(joint1_->jacobian());
136 ✗ const Transform3s& M1(joint1_->currentTransformation());
137 ✗ const matrix3_t& R1(M1.rotation());
138 ✗ vector3_t point1(data_.distanceResults[minIndex_].nearest_points[0]);
139 ✗ vector3_t point2(data_.distanceResults[minIndex_].nearest_points[1]);
140 // P1 - P2
141 ✗ vector3_t P1_minus_P2(point1 - point2);
142 // P1 - t1
143 ✗ vector3_t P1_minus_t1(point1 - M1.translation());
144 // T ( )
145 // (P1-P2) ( J - [P1 - t1] J )
146 // ( 1 [0:3] x 1 [3:6] )
147 ✗ jacobian = (P1_minus_P2.transpose() * R1 * J1.topRows<3>() +
148 ✗ P1_minus_P2.transpose() * R1.colwise().cross(P1_minus_t1) *
149 ✗ J1.bottomRows<3>()) /
150 ✗ dist.vector()[0];
151 ✗ if (joint2_) {
152 ✗ const JointJacobian_t& J2(joint2_->jacobian());
153 ✗ const Transform3s& M2(joint2_->currentTransformation());
154 ✗ const matrix3_t& R2(M2.rotation());
155 // P2 - t2
156 ✗ vector3_t P2_minus_t2(point2 - M2.translation());
157 // T ( )
158 // (P1-P2) ( J - [P1 - t1] J )
159 // ( 2 [0:3] x 2 [3:6] )
160 ✗ matrix_t tmp2(P1_minus_P2.transpose() * R2 * J2.topRows<3>() +
161 ✗ P1_minus_P2.transpose() * R2.colwise().cross(P2_minus_t2) *
162 ✗ J2.bottomRows<3>());
163 ✗ jacobian.noalias() -= tmp2 / dist.vector()[0];
164 }
165 }
166 } // namespace constraints
167 } // namespace hpp
168