GCC Code Coverage Report


Directory: ./
File: src/handle.cc
Date: 2025-05-07 11:07:45
Exec Total Coverage
Lines: 0 120 0.0%
Branches: 0 293 0.0%

Line Branch Exec Source
1 ///
2 /// Copyright (c) 2014 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/explicit/relative-pose.hh>
32 #include <hpp/constraints/generic-transformation.hh>
33 #include <hpp/constraints/implicit.hh>
34 #include <hpp/manipulation/device.hh>
35 #include <hpp/manipulation/handle.hh>
36 #include <hpp/pinocchio/gripper.hh>
37 #include <hpp/pinocchio/joint-collection.hh>
38 #include <hpp/pinocchio/joint.hh>
39 #include <hpp/util/debug.hh>
40 #include <pinocchio/multibody/joint/joint-generic.hpp>
41
42 namespace hpp {
43 namespace manipulation {
44 using constraints::DifferentiableFunction;
45 using constraints::Explicit;
46 using constraints::ExplicitPtr_t;
47 using constraints::Implicit;
48 using constraints::ImplicitPtr_t;
49
50 std::string Handle::className("Handle");
51 namespace {
52 static const matrix3_t I3 = matrix3_t::Identity();
53
54 struct ZeroDiffFunc : public DifferentiableFunction {
55 ✗ ZeroDiffFunc(size_type sIn, size_type sInD,
56 std::string name = std::string("Empty function"))
57 ✗ : DifferentiableFunction(sIn, sInD, LiegroupSpace::empty(), name) {
58 ✗ context("Grasp complement");
59 }
60
61 ✗ inline void impl_compute(pinocchio::LiegroupElementRef, vectorIn_t) const {}
62 ✗ inline void impl_jacobian(matrixOut_t, vectorIn_t) const {}
63 };
64 } // namespace
65
66 ✗ bool isHandleOnFreeflyer(const Handle& handle) {
67 ✗ const JointPtr_t& joint = handle.joint();
68 ✗ if (joint && !joint->parentJoint() &&
69 ✗ joint->jointModel().shortname() ==
70 ✗ ::pinocchio::JointModelFreeFlyer::classname()) {
71 ✗ return true;
72 }
73 ✗ return false;
74 }
75
76 ✗ inline int maskSize(const std::vector<bool>& mask) {
77 ✗ assert(mask.size() == 6);
78 ✗ std::size_t res(0);
79 ✗ for (std::size_t i = 0; i < 6; ++i) {
80 ✗ if (mask[i]) ++res;
81 }
82 ✗ return (int)res;
83 }
84
85 ✗ inline std::vector<bool> boolOr(std::vector<bool> mask1,
86 std::vector<bool> mask2) {
87 ✗ assert(mask1.size() == 6 && mask2.size() == 6);
88 ✗ std::vector<bool> res(mask1.size());
89 ✗ for (std::size_t i = 0; i < 6; ++i) {
90 ✗ res[i] = mask1[i] || mask2[i];
91 }
92 ✗ return res;
93 }
94
95 ✗ inline bool is6Dmask(const std::vector<bool>& mask) {
96 ✗ for (std::size_t i = 0; i < 6; ++i)
97 ✗ if (!mask[i]) return false;
98 ✗ return true;
99 }
100
101 ✗ inline std::vector<bool> complementMask(const std::vector<bool>& mask) {
102 ✗ assert(mask.size() == 6);
103 ✗ std::vector<bool> m(6);
104 ✗ for (std::size_t i = 0; i < 6; ++i) m[i] = !mask[i];
105 ✗ return m;
106 }
107
108 ✗ inline std::string maskToStr(const std::vector<bool>& mask) {
109 ✗ std::stringstream ss;
110 ✗ ss << "(";
111 ✗ for (std::size_t i = 0; i < 5; ++i) ss << mask[i] << ",";
112 ✗ ss << mask[5] << ")";
113 ✗ return ss.str();
114 }
115
116 ✗ void Handle::mask(const std::vector<bool>& mask) {
117 ✗ assert(mask.size() == 6);
118 ✗ std::size_t nRotFree = 3;
119 ✗ for (std::size_t i = 3; i < 6; ++i)
120 ✗ if (mask[i]) nRotFree--;
121 ✗ switch (nRotFree) {
122 ✗ case 1: // TODO we should check the axis are properly aligned.
123 ✗ break;
124 ✗ case 2: // This does not make sense.
125 ✗ throw std::logic_error(
126 ✗ "It is not allowed to constrain only one rotation");
127 break;
128 }
129 ✗ mask_ = mask;
130 ✗ maskComp_ = complementMask(mask);
131 }
132
133 ✗ void Handle::maskComp(const std::vector<bool>& mask) {
134 ✗ assert(maskComp_.size() == 6);
135 ✗ maskComp_ = mask;
136 }
137
138 ✗ ImplicitPtr_t Handle::createGrasp(const GripperPtr_t& gripper,
139 std::string n) const {
140 ✗ if (n.empty()) {
141 ✗ n = gripper->name() + "_grasps_" + name() + "_" + maskToStr(mask_);
142 }
143 // If handle is on a freeflying object, create an explicit constraint
144 ✗ if (is6Dmask(mask_) && isHandleOnFreeflyer(*this)) {
145 ✗ return constraints::explicit_::RelativePose::create(
146 ✗ n, robot(), gripper->joint(), joint(), gripper->objectPositionInJoint(),
147 ✗ localPosition(), 6 * constraints::EqualToZero);
148 }
149 return Implicit::create(
150 ✗ RelativeTransformationR3xSO3::create(
151 ✗ n, robot(), gripper->joint(), joint(),
152 ✗ gripper->objectPositionInJoint(), localPosition()),
153 ✗ 6 * constraints::EqualToZero, mask_);
154 }
155
156 ✗ ImplicitPtr_t Handle::createGraspComplement(const GripperPtr_t& gripper,
157 std::string n) const {
158 ✗ if (n.empty()) {
159 ✗ n = gripper->name() + "_grasps_" + name() + "/complement_" +
160 ✗ maskToStr(maskComp_);
161 }
162 ✗ core::DevicePtr_t r = robot();
163 ✗ if (maskSize(maskComp_) == 0) {
164 ✗ return Implicit::create(shared_ptr<ZeroDiffFunc>(new ZeroDiffFunc(
165 ✗ r->configSize(), r->numberDof(), n)),
166 ✗ ComparisonTypes_t());
167 } else {
168 return Implicit::create(
169 ✗ RelativeTransformationR3xSO3::create(n, r, gripper->joint(), joint(),
170 ✗ gripper->objectPositionInJoint(),
171 ✗ localPosition()),
172 ✗ 6 * constraints::Equality, maskComp_);
173 }
174 }
175
176 ✗ ImplicitPtr_t Handle::createGraspAndComplement(const GripperPtr_t& gripper,
177 std::string n) const {
178 ✗ if (n.empty()) {
179 ✗ n = gripper->name() + "_holds_" + name();
180 }
181 // Create the comparison operator
182 ✗ assert(mask_.size() == 6);
183 ✗ ComparisonTypes_t comp(6);
184 ✗ for (std::size_t i = 0; i < 6; ++i) {
185 ✗ if (mask_[i]) {
186 ✗ comp[i] = constraints::EqualToZero;
187 } else {
188 ✗ comp[i] = constraints::Equality;
189 }
190 }
191 // If handle is on a freeflying object, create an explicit constraint
192 ✗ if (isHandleOnFreeflyer(*this) && maskSize(boolOr(mask_, maskComp_)) == 6) {
193 ✗ return constraints::explicit_::RelativePose::create(
194 ✗ n, robot(), gripper->joint(), joint(), gripper->objectPositionInJoint(),
195 ✗ localPosition(), comp);
196 }
197 return Implicit::create(
198 ✗ RelativeTransformationR3xSO3::create(
199 ✗ n, robot(), gripper->joint(), joint(),
200 ✗ gripper->objectPositionInJoint(), localPosition()),
201 ✗ comp, boolOr(mask_, maskComp_));
202 }
203
204 ✗ ImplicitPtr_t Handle::createPreGrasp(const GripperPtr_t& gripper,
205 const value_type& shift,
206 std::string n) const {
207 ✗ Transform3s M = gripper->objectPositionInJoint() *
208 ✗ Transform3s(I3, vector3_t(shift, 0, 0));
209 ✗ if (n.empty())
210 ✗ n = "Pregrasp_ " + maskToStr(mask_) + "_" + name() + "_" + gripper->name();
211 ImplicitPtr_t result(Implicit::create(
212 ✗ RelativeTransformationR3xSO3::create(n, robot(), gripper->joint(),
213 ✗ joint(), M, localPosition()),
214 ✗ 6 * constraints::EqualToZero, mask_));
215 ✗ return result;
216 }
217
218 ✗ HandlePtr_t Handle::clone() const {
219 ✗ HandlePtr_t other = Handle::create(name(), localPosition(), robot(), joint());
220 ✗ other->mask(mask_);
221 ✗ other->mask(maskComp_);
222 ✗ other->clearance(clearance_);
223 ✗ return other;
224 }
225
226 ✗ std::ostream& Handle::print(std::ostream& os) const {
227 ✗ os << "name :" << name() << std::endl;
228 ✗ os << "local position :" << localPosition() << std::endl;
229 ✗ os << "joint :" << joint()->name() << std::endl;
230 ✗ os << "mask :" << maskToStr(mask()) << std::endl;
231 ✗ os << "mask complement:" << maskToStr(maskComp_) << std::endl;
232 ✗ return os;
233 }
234
235 ✗ std::ostream& operator<<(std::ostream& os, const Handle& handle) {
236 ✗ return handle.print(os);
237 }
238 } // namespace manipulation
239 } // namespace hpp
240