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