GCC Code Coverage Report


Directory: ./
File: src/handle.cc
Date: 2025-03-07 11:10:46
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