Directory: | ./ |
---|---|
File: | src/convex-shape-contact.cc |
Date: | 2025-05-05 12:19:30 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 221 | 296 | 74.7% |
Branches: | 234 | 581 | 40.3% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2014, LAAS-CNRS | ||
2 | // Authors: Joseph Mirabel (joseph.mirabel@laas.fr) | ||
3 | // | ||
4 | |||
5 | // Redistribution and use in source and binary forms, with or without | ||
6 | // modification, are permitted provided that the following conditions are | ||
7 | // met: | ||
8 | // | ||
9 | // 1. Redistributions of source code must retain the above copyright | ||
10 | // notice, this list of conditions and the following disclaimer. | ||
11 | // | ||
12 | // 2. Redistributions in binary form must reproduce the above copyright | ||
13 | // notice, this list of conditions and the following disclaimer in the | ||
14 | // documentation and/or other materials provided with the distribution. | ||
15 | // | ||
16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
20 | // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
27 | // DAMAGE. | ||
28 | |||
29 | #include "hpp/constraints/convex-shape-contact.hh" | ||
30 | |||
31 | #include <../src/generic-transformation/helper.hh> | ||
32 | #include <hpp/constraints/matrix-view.hh> | ||
33 | #include <hpp/pinocchio/device.hh> | ||
34 | #include <hpp/pinocchio/joint.hh> | ||
35 | #include <hpp/pinocchio/liegroup-element.hh> | ||
36 | #include <limits> | ||
37 | |||
38 | namespace hpp { | ||
39 | namespace constraints { | ||
40 | |||
41 | 7 | ConvexShapeContact::ConvexShapeContact(const std::string& name, | |
42 | DevicePtr_t robot, | ||
43 | const JointAndShapes_t& floorSurfaces, | ||
44 | 7 | const JointAndShapes_t& objectSurfaces) | |
45 | : DifferentiableFunction(robot->configSize(), robot->numberDof(), | ||
46 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
14 | LiegroupSpace::Rn(5), name), |
47 | 7 | robot_(robot), | |
48 |
2/4✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 7 times.
✗ Branch 6 not taken.
|
14 | relativeTransformationModel_(robot->numberDof() - |
49 | 7 | robot->extraConfigSpace().dimension()), | |
50 | 7 | normalMargin_(0), | |
51 |
3/6✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7 times.
✗ Branch 11 not taken.
|
28 | M_(0) { |
52 | 7 | relativeTransformationModel_.fullPos = true; | |
53 | 7 | relativeTransformationModel_.fullOri = true; | |
54 | 7 | relativeTransformationModel_.rowOri = 3; | |
55 | |||
56 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | activeParameters_.setConstant(false); |
57 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | activeDerivativeParameters_.setConstant(false); |
58 | // Register convex polygons into constraint | ||
59 | 7 | for (JointAndShapes_t::const_iterator it(floorSurfaces.begin()); | |
60 |
2/2✓ Branch 2 taken 14 times.
✓ Branch 3 taken 7 times.
|
21 | it != floorSurfaces.end(); ++it) { |
61 |
2/4✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 14 times.
✗ Branch 8 not taken.
|
14 | addFloor(ConvexShape(it->second, it->first)); |
62 | } | ||
63 | 7 | for (JointAndShapes_t::const_iterator it(objectSurfaces.begin()); | |
64 |
2/2✓ Branch 2 taken 8 times.
✓ Branch 3 taken 7 times.
|
15 | it != objectSurfaces.end(); ++it) { |
65 |
2/4✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
|
8 | addObject(ConvexShape(it->second, it->first)); |
66 | } | ||
67 |
1/2✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
|
7 | computeRadius(); |
68 | 7 | } | |
69 | |||
70 | ✗ | bool ConvexShapeContact::isEqual(const DifferentiableFunction& other) const { | |
71 | const ConvexShapeContact& castother = | ||
72 | ✗ | dynamic_cast<const ConvexShapeContact&>(other); | |
73 | ✗ | if (!DifferentiableFunction::isEqual(other)) return false; | |
74 | ✗ | if (robot_ != castother.robot_) return false; | |
75 | ✗ | if (objectConvexShapes_.size() != castother.objectConvexShapes_.size()) | |
76 | ✗ | return false; | |
77 | ✗ | for (std::size_t i = 0; i < objectConvexShapes_.size(); i++) | |
78 | ✗ | if (floorConvexShapes_[i] != castother.floorConvexShapes_[i]) return false; | |
79 | ✗ | return true; | |
80 | } | ||
81 | |||
82 | 7 | ConvexShapeContactPtr_t ConvexShapeContact::create( | |
83 | const std::string& name, DevicePtr_t robot, | ||
84 | const JointAndShapes_t& floorSurfaces, | ||
85 | const JointAndShapes_t& objectSurfaces) { | ||
86 | return ConvexShapeContactPtr_t( | ||
87 |
3/6✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 7 times.
✗ Branch 9 not taken.
|
7 | new ConvexShapeContact(name, robot, floorSurfaces, objectSurfaces)); |
88 | } | ||
89 | |||
90 | 8 | void ConvexShapeContact::addObject(const ConvexShape& t) { | |
91 | 8 | objectConvexShapes_.push_back(t); | |
92 | |||
93 | 8 | for (ConvexShapes_t::const_iterator f_it = floorConvexShapes_.begin(); | |
94 |
2/2✓ Branch 2 taken 16 times.
✓ Branch 3 taken 8 times.
|
24 | f_it != floorConvexShapes_.end(); ++f_it) { |
95 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | setActiveParameters(robot_, f_it->joint_, t.joint_, activeParameters_, |
96 | 16 | activeDerivativeParameters_); | |
97 | } | ||
98 | 8 | } | |
99 | |||
100 | 14 | void ConvexShapeContact::addFloor(const ConvexShape& t) { | |
101 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | ConvexShape tt(t); |
102 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | tt.reverse(); |
103 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | floorConvexShapes_.push_back(tt); |
104 | |||
105 | 14 | for (ConvexShapes_t::const_iterator o_it = objectConvexShapes_.begin(); | |
106 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
|
14 | o_it != objectConvexShapes_.end(); ++o_it) { |
107 | ✗ | setActiveParameters(robot_, tt.joint_, o_it->joint_, activeParameters_, | |
108 | ✗ | activeDerivativeParameters_); | |
109 | } | ||
110 | 14 | } | |
111 | |||
112 | 7 | void ConvexShapeContact::computeRadius() { | |
113 | // Compute upper bound of distance between center of polygon and | ||
114 | // vectices for all floor polygons. | ||
115 | 7 | for (ConvexShapes_t::const_iterator shape(floorConvexShapes_.begin()); | |
116 |
2/2✓ Branch 3 taken 14 times.
✓ Branch 4 taken 7 times.
|
21 | shape != floorConvexShapes_.end(); ++shape) { |
117 | 14 | for (std::vector<vector3_t>::const_iterator itv(shape->Pts_.begin()); | |
118 |
2/2✓ Branch 4 taken 62 times.
✓ Branch 5 taken 14 times.
|
76 | itv != shape->Pts_.end(); ++itv) { |
119 |
2/4✓ Branch 3 taken 62 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 62 times.
✗ Branch 7 not taken.
|
62 | value_type r((*itv - shape->C_).norm()); |
120 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 49 times.
|
62 | if (r > M_) { |
121 | 13 | M_ = r; | |
122 | } | ||
123 | } | ||
124 | } | ||
125 | 7 | M_ += 1; | |
126 | 7 | } | |
127 | |||
128 | 1 | void ConvexShapeContact::setNormalMargin(const value_type& margin) { | |
129 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | assert(margin >= 0); |
130 | 1 | normalMargin_ = margin; | |
131 | 1 | } | |
132 | |||
133 | std::vector<ConvexShapeContact::ForceData> | ||
134 | ✗ | ConvexShapeContact::computeContactPoints(ConfigurationIn_t q, | |
135 | const value_type& normalMargin) const { | ||
136 | ✗ | pinocchio::DeviceSync device(robot_); | |
137 | ✗ | device.currentConfiguration(q); | |
138 | ✗ | device.computeForwardKinematics(pinocchio::JOINT_POSITION); | |
139 | |||
140 | ✗ | std::vector<ForceData> forceDatas; | |
141 | ✗ | ForceData forceData; | |
142 | ✗ | ConvexShapeData od, fd; | |
143 | ✗ | for (ConvexShapes_t::const_iterator o_it = objectConvexShapes_.begin(); | |
144 | ✗ | o_it != objectConvexShapes_.end(); ++o_it) { | |
145 | ✗ | od.updateToCurrentTransform(*o_it, device.d()); | |
146 | ✗ | for (ConvexShapes_t::const_iterator f_it = floorConvexShapes_.begin(); | |
147 | ✗ | f_it != floorConvexShapes_.end(); ++f_it) { | |
148 | ✗ | fd.updateToCurrentTransform(*f_it, device.d()); | |
149 | ✗ | if (fd.isInside(*f_it, od.center_, fd.normal_)) { | |
150 | ✗ | value_type dn = fd.normal_.dot(od.center_ - fd.center_); | |
151 | ✗ | if (dn < normalMargin) { | |
152 | // TODO: compute which points of the object are inside the floor | ||
153 | // shape. | ||
154 | ✗ | forceData.joint = o_it->joint_; | |
155 | ✗ | forceData.points = o_it->Pts_; | |
156 | ✗ | forceData.normal = f_it->N_; | |
157 | ✗ | forceData.supportJoint = f_it->joint_; | |
158 | ✗ | forceDatas.push_back(forceData); | |
159 | } | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | ✗ | return forceDatas; | |
164 | } | ||
165 | |||
166 | 20995 | void ConvexShapeContact::computeInternalValue(const ConfigurationIn_t& argument, | |
167 | bool& isInside, ContactType& type, | ||
168 | vector6_t& value, | ||
169 | std::size_t& iobject, | ||
170 | std::size_t& ifloor) const { | ||
171 |
1/2✓ Branch 1 taken 21037 times.
✗ Branch 2 not taken.
|
20995 | GTDataV<true, true, true, false> data(relativeTransformationModel_, robot_); |
172 | |||
173 |
2/4✓ Branch 1 taken 21038 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21038 times.
✗ Branch 5 not taken.
|
21037 | data.device.currentConfiguration(argument); |
174 |
1/2✓ Branch 1 taken 21038 times.
✗ Branch 2 not taken.
|
21038 | data.device.computeForwardKinematics(pinocchio::JOINT_POSITION); |
175 | |||
176 |
2/4✓ Branch 1 taken 21038 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21035 times.
✗ Branch 5 not taken.
|
21038 | isInside = selectConvexShapes(data.device.d(), iobject, ifloor); |
177 | 21035 | const ConvexShape &object(objectConvexShapes_[iobject]), | |
178 |
1/2✓ Branch 2 taken 21037 times.
✗ Branch 3 not taken.
|
21035 | floor(floorConvexShapes_[ifloor]); |
179 |
1/2✓ Branch 1 taken 21036 times.
✗ Branch 2 not taken.
|
21037 | type = contactType(object, floor); |
180 | |||
181 | 21036 | relativeTransformationModel_.joint1 = floor.joint_; | |
182 | 21032 | relativeTransformationModel_.joint2 = object.joint_; | |
183 |
1/2✓ Branch 2 taken 21038 times.
✗ Branch 3 not taken.
|
21032 | relativeTransformationModel_.F1inJ1 = floor.positionInJoint(); |
184 |
1/2✓ Branch 2 taken 21038 times.
✗ Branch 3 not taken.
|
21038 | relativeTransformationModel_.F2inJ2 = object.positionInJoint(); |
185 |
1/2✓ Branch 1 taken 21036 times.
✗ Branch 2 not taken.
|
21038 | relativeTransformationModel_.checkIsIdentity1(); |
186 |
1/2✓ Branch 1 taken 21038 times.
✗ Branch 2 not taken.
|
21036 | relativeTransformationModel_.checkIsIdentity2(); |
187 | |||
188 |
1/2✓ Branch 1 taken 21037 times.
✗ Branch 2 not taken.
|
21038 | compute<true, true, true, false>::error(data); |
189 |
1/2✓ Branch 1 taken 21035 times.
✗ Branch 2 not taken.
|
21037 | value = data.value; |
190 | 21035 | } | |
191 | |||
192 | 10822 | void ConvexShapeContact::impl_compute(LiegroupElementRef result, | |
193 | ConfigurationIn_t argument) const { | ||
194 | bool isInside; | ||
195 | ContactType type; | ||
196 |
1/2✓ Branch 1 taken 10794 times.
✗ Branch 2 not taken.
|
10822 | vector6_t value; |
197 | std::size_t iobject, ifloor; | ||
198 |
1/2✓ Branch 1 taken 10834 times.
✗ Branch 2 not taken.
|
10794 | computeInternalValue(argument, isInside, type, value, iobject, ifloor); |
199 | |||
200 |
2/2✓ Branch 0 taken 5648 times.
✓ Branch 1 taken 5186 times.
|
10834 | if (isInside) { |
201 |
2/4✓ Branch 1 taken 5648 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 5648 times.
✗ Branch 6 not taken.
|
5648 | result.vector()[0] = value[0] + normalMargin_; |
202 |
2/4✓ Branch 2 taken 5648 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5648 times.
✗ Branch 6 not taken.
|
5648 | result.vector().segment<2>(1).setZero(); |
203 | } else { | ||
204 |
3/6✓ Branch 1 taken 5186 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 5186 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 5186 times.
✗ Branch 9 not taken.
|
5186 | result.vector().segment<3>(0) = value.head<3>(); |
205 |
1/2✓ Branch 2 taken 5186 times.
✗ Branch 3 not taken.
|
5186 | result.vector()[0] += normalMargin_; |
206 | } | ||
207 |
2/3✓ Branch 0 taken 210 times.
✓ Branch 1 taken 10624 times.
✗ Branch 2 not taken.
|
10834 | switch (type) { |
208 | 210 | case POINT_ON_PLANE: | |
209 |
2/4✓ Branch 2 taken 210 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 210 times.
✗ Branch 6 not taken.
|
210 | result.vector().segment<2>(3).setZero(); |
210 | 210 | break; | |
211 | 10624 | case LINE_ON_PLANE: | |
212 | // FIXME: only one rotation should be constrained in that case but | ||
213 | // the relative transformation is not aligned properly. The Y-axis | ||
214 | // of the reference of "object" should be aligned with the | ||
215 | // "floor" line axis (Y-axis) projection onto the plane plane. | ||
216 | // result [3] = 0; | ||
217 | // result [4] = rt_res_lge[5]; | ||
218 | case PLANE_ON_PLANE: | ||
219 |
3/6✓ Branch 1 taken 10624 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 10624 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 10624 times.
✗ Branch 9 not taken.
|
10624 | result.vector().segment<2>(3) = value.tail<2>(); |
220 | 10624 | break; | |
221 | } | ||
222 | hppDout(info, "result = " << result); | ||
223 | 10834 | } | |
224 | |||
225 | 17518 | void ConvexShapeContact::computeInternalJacobian( | |
226 | const ConfigurationIn_t& argument, bool& isInside, ContactType& type, | ||
227 | matrix_t& jacobian) const { | ||
228 |
4/8✓ Branch 0 taken 3 times.
✓ Branch 1 taken 17515 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
17518 | static std::vector<bool> mask(6, true); |
229 | |||
230 |
1/2✓ Branch 1 taken 17519 times.
✗ Branch 2 not taken.
|
17518 | GTDataJ<true, true, true, false> data(relativeTransformationModel_, robot_); |
231 | |||
232 |
2/4✓ Branch 1 taken 17519 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17519 times.
✗ Branch 5 not taken.
|
17519 | data.device.currentConfiguration(argument); |
233 |
1/2✓ Branch 1 taken 17519 times.
✗ Branch 2 not taken.
|
17519 | data.device.computeForwardKinematics(pinocchio::JOINT_POSITION | |
234 | pinocchio::JACOBIAN); | ||
235 | |||
236 | std::size_t ifloor, iobject; | ||
237 |
2/4✓ Branch 1 taken 17519 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17517 times.
✗ Branch 5 not taken.
|
17519 | isInside = selectConvexShapes(data.device.d(), iobject, ifloor); |
238 | 17517 | const ConvexShape &object(objectConvexShapes_[iobject]), | |
239 |
1/2✓ Branch 2 taken 17519 times.
✗ Branch 3 not taken.
|
17517 | floor(floorConvexShapes_[ifloor]); |
240 |
1/2✓ Branch 1 taken 17519 times.
✗ Branch 2 not taken.
|
17519 | type = contactType(object, floor); |
241 | |||
242 | 17519 | relativeTransformationModel_.joint1 = floor.joint_; | |
243 | 17518 | relativeTransformationModel_.joint2 = object.joint_; | |
244 |
1/2✓ Branch 2 taken 17519 times.
✗ Branch 3 not taken.
|
17518 | relativeTransformationModel_.F1inJ1 = floor.positionInJoint(); |
245 |
1/2✓ Branch 2 taken 17519 times.
✗ Branch 3 not taken.
|
17519 | relativeTransformationModel_.F2inJ2 = object.positionInJoint(); |
246 |
1/2✓ Branch 1 taken 17519 times.
✗ Branch 2 not taken.
|
17519 | relativeTransformationModel_.checkIsIdentity1(); |
247 |
1/2✓ Branch 1 taken 17519 times.
✗ Branch 2 not taken.
|
17519 | relativeTransformationModel_.checkIsIdentity2(); |
248 |
1/2✓ Branch 1 taken 17519 times.
✗ Branch 2 not taken.
|
17519 | data.cross2.setZero(); |
249 | |||
250 |
1/2✓ Branch 1 taken 17519 times.
✗ Branch 2 not taken.
|
17519 | compute<true, true, true, false>::error(data); |
251 |
2/4✓ Branch 1 taken 17519 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17517 times.
✗ Branch 5 not taken.
|
17519 | compute<true, true, true, false>::jacobian(data, jacobian, mask); |
252 | 17517 | } | |
253 | |||
254 | 8917 | void ConvexShapeContact::impl_jacobian(matrixOut_t jacobian, | |
255 | ConfigurationIn_t argument) const { | ||
256 | bool isInside; | ||
257 | ContactType type; | ||
258 |
2/4✓ Branch 2 taken 8917 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8917 times.
✗ Branch 6 not taken.
|
8917 | matrix_t tmpJac(6, robot_->numberDof()); |
259 |
1/2✓ Branch 1 taken 8917 times.
✗ Branch 2 not taken.
|
8917 | computeInternalJacobian(argument, isInside, type, tmpJac); |
260 | |||
261 |
2/2✓ Branch 0 taken 3881 times.
✓ Branch 1 taken 5036 times.
|
8917 | if (isInside) { |
262 |
3/6✓ Branch 1 taken 3881 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3881 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3881 times.
✗ Branch 8 not taken.
|
3881 | jacobian.row(0) = tmpJac.row(0); |
263 |
2/4✓ Branch 1 taken 3881 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3880 times.
✗ Branch 5 not taken.
|
3881 | jacobian.row(1).setZero(); |
264 |
2/4✓ Branch 1 taken 3881 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3881 times.
✗ Branch 5 not taken.
|
3880 | jacobian.row(2).setZero(); |
265 | } else { | ||
266 |
3/6✓ Branch 1 taken 5036 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5036 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5036 times.
✗ Branch 8 not taken.
|
5036 | jacobian.topRows<3>() = tmpJac.topRows<3>(); |
267 | } | ||
268 |
3/4✓ Branch 0 taken 105 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8811 times.
✓ Branch 3 taken 1 times.
|
8917 | switch (type) { |
269 | 105 | case POINT_ON_PLANE: | |
270 |
2/4✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 104 times.
✗ Branch 5 not taken.
|
105 | jacobian.bottomRows<2>().setZero(); |
271 | 104 | break; | |
272 | ✗ | case LINE_ON_PLANE: | |
273 | // FIXME: See FIXME of impl_compute | ||
274 | // jacobian.row (3).setZero (); | ||
275 | // jacobian.row (4) = tmpJac.row (5); | ||
276 | ✗ | throw std::logic_error("Contact LINE_ON_PLANE: Unimplement feature"); | |
277 | 8811 | case PLANE_ON_PLANE: | |
278 | // Row: 3 4 Row: 4 5 | ||
279 |
3/6✓ Branch 1 taken 8811 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8812 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8812 times.
✗ Branch 8 not taken.
|
8811 | jacobian.bottomRows<2>() = tmpJac.bottomRows<2>(); |
280 | 8812 | break; | |
281 | } | ||
282 | 8917 | } | |
283 | |||
284 | 38550 | bool ConvexShapeContact::selectConvexShapes(const pinocchio::DeviceData& data, | |
285 | std::size_t& iobject, | ||
286 | std::size_t& ifloor) const { | ||
287 |
2/4✓ Branch 1 taken 38557 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38557 times.
✗ Branch 5 not taken.
|
38550 | ConvexShapeData od, fd; |
288 | 38557 | bool isInside = false; // Initialized only to remove compiler warning. | |
289 | |||
290 | 38557 | value_type dist, minDist = +std::numeric_limits<value_type>::infinity(); | |
291 |
2/2✓ Branch 1 taken 77107 times.
✓ Branch 2 taken 38551 times.
|
115660 | for (std::size_t j = 0; j < floorConvexShapes_.size(); ++j) { |
292 |
1/2✓ Branch 2 taken 77107 times.
✗ Branch 3 not taken.
|
77107 | fd.updateToCurrentTransform(floorConvexShapes_[j], data); |
293 | |||
294 |
2/2✓ Branch 1 taken 152329 times.
✓ Branch 2 taken 77103 times.
|
229436 | for (std::size_t i = 0; i < objectConvexShapes_.size(); ++i) { |
295 |
1/2✓ Branch 2 taken 152325 times.
✗ Branch 3 not taken.
|
152329 | od.updateToCurrentTransform(objectConvexShapes_[i], data); |
296 |
1/2✓ Branch 2 taken 152328 times.
✗ Branch 3 not taken.
|
152325 | value_type dp = fd.distance(floorConvexShapes_[j], |
297 |
1/2✓ Branch 1 taken 152325 times.
✗ Branch 2 not taken.
|
152325 | fd.intersection(od.center_, fd.normal_)), |
298 |
2/4✓ Branch 1 taken 152337 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 152329 times.
✗ Branch 5 not taken.
|
152328 | dn = fd.normal_.dot(od.center_ - fd.center_); |
299 |
2/2✓ Branch 0 taken 65935 times.
✓ Branch 1 taken 86394 times.
|
152329 | if (dp < 0) |
300 | 65935 | dist = dn * dn; | |
301 | else | ||
302 | 86394 | dist = dp * dp + dn * dn; | |
303 | |||
304 |
2/2✓ Branch 0 taken 81751 times.
✓ Branch 1 taken 70578 times.
|
152329 | if (dist < minDist) { |
305 | 81751 | minDist = dist; | |
306 | 81751 | iobject = i; | |
307 | 81751 | ifloor = j; | |
308 | 81751 | isInside = (dp < 0); | |
309 | } | ||
310 | } | ||
311 | } | ||
312 | |||
313 | 38551 | return isInside; | |
314 | } | ||
315 | |||
316 | 38554 | ConvexShapeContact::ContactType ConvexShapeContact::contactType( | |
317 | const ConvexShape& object, const ConvexShape& floor) const { | ||
318 |
2/4✓ Branch 0 taken 38554 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38555 times.
✗ Branch 3 not taken.
|
38554 | assert(floor.shapeDimension_ > 0 && object.shapeDimension_); |
319 |
1/3✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 38555 times.
|
38555 | switch (floor.shapeDimension_) { |
320 | ✗ | case 1: | |
321 | ✗ | throw std::logic_error("Contact on points is currently unimplemented"); | |
322 | break; | ||
323 | ✗ | case 2: | |
324 | ✗ | throw std::logic_error("Contact on lines is currently unimplemented"); | |
325 | break; | ||
326 | 38555 | default: | |
327 |
2/3✓ Branch 0 taken 313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38242 times.
|
38555 | switch (object.shapeDimension_) { |
328 | 313 | case 1: | |
329 | 313 | return POINT_ON_PLANE; | |
330 | break; | ||
331 | ✗ | case 2: | |
332 | ✗ | return LINE_ON_PLANE; | |
333 | break; | ||
334 | 38242 | default: | |
335 | 38242 | return PLANE_ON_PLANE; | |
336 | break; | ||
337 | } | ||
338 | break; | ||
339 | } | ||
340 | } | ||
341 | |||
342 | 1 | ConvexShapeContactComplement::ConvexShapeContactComplement( | |
343 | const std::string& name, DevicePtr_t robot, | ||
344 | const JointAndShapes_t& floorSurfaces, | ||
345 | 1 | const JointAndShapes_t& objectSurfaces) | |
346 | : DifferentiableFunction(robot->configSize(), robot->numberDof(), | ||
347 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | LiegroupSpace::Rn(3), |
348 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2 | name + std::string("/complement")), |
349 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | sibling_(ConvexShapeContact::create(name, robot, floorSurfaces, |
350 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
|
4 | objectSurfaces)) {} |
351 | |||
352 | ✗ | bool ConvexShapeContactComplement::isEqual( | |
353 | const DifferentiableFunction& other) const { | ||
354 | const ConvexShapeContactComplement& castother = | ||
355 | ✗ | dynamic_cast<const ConvexShapeContactComplement&>(other); | |
356 | ✗ | if (!DifferentiableFunction::isEqual(other)) return false; | |
357 | ✗ | if (sibling_ == castother.sibling_) return true; | |
358 | ✗ | return (*sibling_ == *(castother.sibling_)); | |
359 | } | ||
360 | |||
361 | std::pair<ConvexShapeContactPtr_t, ConvexShapeContactComplementPtr_t> | ||
362 | 1 | ConvexShapeContactComplement::createPair( | |
363 | const std::string& name, DevicePtr_t robot, | ||
364 | const JointAndShapes_t& floorSurfaces, | ||
365 | const JointAndShapes_t& objectSurfaces) { | ||
366 | ConvexShapeContactComplement* ptr = new ConvexShapeContactComplement( | ||
367 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | name, robot, floorSurfaces, objectSurfaces); |
368 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | ConvexShapeContactComplementPtr_t shPtr(ptr); |
369 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | return std::make_pair(ptr->sibling_, shPtr); |
370 | 1 | } | |
371 | |||
372 | 400 | void ConvexShapeContactComplement::computeRelativePoseRightHandSide( | |
373 | LiegroupElementConstRef rhs, std::size_t& ifloor, std::size_t& iobject, | ||
374 | LiegroupElementRef relativePoseRhs) const { | ||
375 |
3/6✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 400 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 400 times.
|
400 | assert(*(rhs.space()) == *LiegroupSpace::Rn(8)); |
376 | 400 | value_type M(sibling_->radius()); | |
377 |
2/4✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 400 times.
✗ Branch 5 not taken.
|
400 | vector8_t logRhs(log(rhs)); |
378 |
1/2✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
|
400 | vector6_t logRelativePoseRhs; |
379 |
1/2✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
|
400 | logRelativePoseRhs.fill(sqrt(-1)); |
380 | // x | ||
381 |
2/4✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 400 times.
✗ Branch 5 not taken.
|
400 | logRelativePoseRhs[0] = logRhs[0]; |
382 | // ry, rz | ||
383 |
3/6✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 400 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 400 times.
✗ Branch 8 not taken.
|
400 | logRelativePoseRhs.segment<2>(4) = logRhs.segment<2>(3); |
384 | // rx | ||
385 |
2/4✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 400 times.
✗ Branch 5 not taken.
|
400 | logRelativePoseRhs[3] = logRhs[7]; |
386 |
1/2✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
|
400 | value_type Y(logRhs[5]); |
387 |
1/2✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
|
400 | value_type Z(logRhs[6]); |
388 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 400 times.
|
400 | assert(floor(Y / (2 * M) + .5) >= 0); |
389 | 400 | ifloor = (std::size_t)(floor(Y / (2 * M) + .5)); | |
390 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 400 times.
|
400 | assert(floor(Z / (2 * M) + .5) >= 0); |
391 | 400 | iobject = (std::size_t)(floor(Z / (2 * M) + .5)); | |
392 |
5/10✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 400 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 400 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 400 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 400 times.
✗ Branch 11 not taken.
|
400 | if ((logRhs[1] == 0) && (logRhs[2] == 0)) { |
393 | // inside | ||
394 |
1/2✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
|
400 | logRelativePoseRhs[1] = Y - (value_type)(2 * ifloor) * M; |
395 |
1/2✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
|
400 | logRelativePoseRhs[2] = Z - (value_type)(2 * iobject) * M; |
396 | } else { | ||
397 | // outside | ||
398 | ✗ | logRelativePoseRhs.segment<2>(1) = logRhs.segment<2>(1); | |
399 | } | ||
400 |
2/4✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 400 times.
|
400 | assert(!logRelativePoseRhs.hasNaN()); |
401 |
4/8✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 400 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 400 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 400 times.
✗ Branch 12 not taken.
|
400 | relativePoseRhs = LiegroupSpace::R3xSO3()->exp(logRelativePoseRhs); |
402 |
3/6✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 400 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 400 times.
|
400 | assert(*(relativePoseRhs.space()) == *LiegroupSpace::R3xSO3()); |
403 | 400 | } | |
404 | |||
405 | 10204 | void ConvexShapeContactComplement::impl_compute( | |
406 | LiegroupElementRef result, ConfigurationIn_t argument) const { | ||
407 | 10204 | value_type M(sibling_->radius()); | |
408 | bool isInside; | ||
409 | ConvexShapeContact::ContactType type; | ||
410 |
1/2✓ Branch 1 taken 10204 times.
✗ Branch 2 not taken.
|
10204 | vector6_t value; |
411 | std::size_t iobject, ifloor; | ||
412 |
1/2✓ Branch 2 taken 10204 times.
✗ Branch 3 not taken.
|
10204 | sibling_->computeInternalValue(argument, isInside, type, value, iobject, |
413 | ifloor); | ||
414 |
1/2✓ Branch 1 taken 10204 times.
✗ Branch 2 not taken.
|
10204 | vector3_t offset; |
415 |
3/6✓ Branch 1 taken 10204 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10204 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 10204 times.
✗ Branch 8 not taken.
|
10204 | offset << (value_type)(2 * ifloor) * M, (value_type)(2 * iobject) * M, 0; |
416 |
2/4✓ Branch 1 taken 10204 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 10204 times.
✗ Branch 6 not taken.
|
10204 | result.vector()[2] = value[3]; |
417 |
2/2✓ Branch 0 taken 5018 times.
✓ Branch 1 taken 5186 times.
|
10204 | if (isInside) |
418 |
3/6✓ Branch 1 taken 5018 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 5018 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 5018 times.
✗ Branch 9 not taken.
|
5018 | result.vector().head<2>() = value.segment<2>(1); |
419 | else | ||
420 |
2/4✓ Branch 2 taken 5186 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 5186 times.
✗ Branch 6 not taken.
|
5186 | result.vector().head<2>().setZero(); |
421 |
1/2✓ Branch 2 taken 10204 times.
✗ Branch 3 not taken.
|
10204 | result.vector() += offset; |
422 | hppDout(info, "result = " << result); | ||
423 | 10204 | } | |
424 | |||
425 | 8602 | void ConvexShapeContactComplement::impl_jacobian( | |
426 | matrixOut_t jacobian, ConfigurationIn_t argument) const { | ||
427 | bool isInside; | ||
428 | ConvexShapeContact::ContactType type; | ||
429 |
2/4✓ Branch 3 taken 8602 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8602 times.
✗ Branch 7 not taken.
|
8602 | matrix_t tmpJac(6, sibling_->robot_->numberDof()); |
430 |
1/2✓ Branch 2 taken 8602 times.
✗ Branch 3 not taken.
|
8602 | sibling_->computeInternalJacobian(argument, isInside, type, tmpJac); |
431 | |||
432 |
2/2✓ Branch 0 taken 3566 times.
✓ Branch 1 taken 5036 times.
|
8602 | if (isInside) |
433 |
3/6✓ Branch 1 taken 3566 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3566 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3566 times.
✗ Branch 8 not taken.
|
3566 | jacobian.topRows<2>() = tmpJac.middleRows<2>(1); |
434 | else | ||
435 |
2/4✓ Branch 1 taken 5036 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5036 times.
✗ Branch 5 not taken.
|
5036 | jacobian.topRows<2>().setZero(); |
436 |
3/6✓ Branch 1 taken 8602 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8602 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8602 times.
✗ Branch 8 not taken.
|
8602 | jacobian.row(2) = tmpJac.row(3); |
437 | 8602 | } | |
438 | |||
439 | ✗ | std::ostream& ConvexShapeContact::print(std::ostream& o) const { | |
440 | ✗ | o << "ConvexShapeContact: " << name() << ", active dof " | |
441 | ✗ | << pretty_print(BlockIndex::fromLogicalExpression(activeParameters_)) | |
442 | ✗ | << incindent; | |
443 | |||
444 | ✗ | o << iendl << "Object shapes:" << incindent << iendl; | |
445 | ✗ | for (ConvexShapes_t::const_iterator o_it = objectConvexShapes_.begin(); | |
446 | ✗ | o_it != objectConvexShapes_.end(); ++o_it) { | |
447 | ✗ | if (o_it->joint_) | |
448 | ✗ | o << "object on " << o_it->joint_->name() << iendl; | |
449 | else | ||
450 | ✗ | o << "object on universe" << iendl; | |
451 | ✗ | o << "position in joint:" << iendl; | |
452 | ✗ | o << incindent << o_it->positionInJoint(); | |
453 | ✗ | o << decindent << iendl; | |
454 | } | ||
455 | ✗ | for (ConvexShapes_t::const_iterator fl_it = floorConvexShapes_.begin(); | |
456 | ✗ | fl_it != floorConvexShapes_.end(); ++fl_it) { | |
457 | ✗ | if (fl_it->joint_) | |
458 | ✗ | o << "floor on " << fl_it->joint_->name() << iendl; | |
459 | else | ||
460 | ✗ | o << "floor on universe" << iendl; | |
461 | ✗ | o << "position in joint:" << iendl; | |
462 | ✗ | o << incindent << fl_it->positionInJoint(); | |
463 | ✗ | o << decindent << iendl; | |
464 | } | ||
465 | ✗ | return o << decindent; | |
466 | } | ||
467 | |||
468 | 1 | ConvexShapeContactHoldPtr_t ConvexShapeContactHold::create( | |
469 | const std::string& name, DevicePtr_t robot, | ||
470 | const JointAndShapes_t& floorSurfaces, | ||
471 | const JointAndShapes_t& objectSurfaces) { | ||
472 | ConvexShapeContactHold* ptr( | ||
473 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | new ConvexShapeContactHold(name, robot, floorSurfaces, objectSurfaces)); |
474 | 1 | return ConvexShapeContactHoldPtr_t(ptr); | |
475 | } | ||
476 | |||
477 | 1 | ConvexShapeContactHold::ConvexShapeContactHold( | |
478 | const std::string& name, DevicePtr_t robot, | ||
479 | const JointAndShapes_t& floorSurfaces, | ||
480 | 1 | const JointAndShapes_t& objectSurfaces) | |
481 | : DifferentiableFunction(robot->configSize(), robot->numberDof(), | ||
482 |
4/8✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
1 | LiegroupSpace::Rn(8), name) { |
483 | std::pair<ConvexShapeContactPtr_t, ConvexShapeContactComplementPtr_t> pair( | ||
484 | ConvexShapeContactComplement::createPair(name, robot, floorSurfaces, | ||
485 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | objectSurfaces)); |
486 | 1 | constraint_ = pair.first; | |
487 | 1 | complement_ = pair.second; | |
488 | 1 | } | |
489 | |||
490 | 10204 | void ConvexShapeContactHold::impl_compute(LiegroupElementRef result, | |
491 | vectorIn_t argument) const { | ||
492 |
4/8✓ Branch 1 taken 10204 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 10204 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 10204 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 10204 times.
✗ Branch 12 not taken.
|
10204 | LiegroupElementRef tmp1(result.vector().head<5>(), LiegroupSpace::Rn(5)); |
493 |
4/8✓ Branch 1 taken 10204 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 10204 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 10204 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 10204 times.
✗ Branch 12 not taken.
|
10204 | LiegroupElementRef tmp2(result.vector().tail<3>(), LiegroupSpace::Rn(3)); |
494 |
3/6✓ Branch 2 taken 10204 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10204 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 10204 times.
✗ Branch 9 not taken.
|
10204 | constraint_->impl_compute(tmp1, argument); |
495 |
3/6✓ Branch 2 taken 10204 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 10204 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 10204 times.
✗ Branch 9 not taken.
|
10204 | complement_->impl_compute(tmp2, argument); |
496 | 10204 | } | |
497 | |||
498 | 8602 | void ConvexShapeContactHold::impl_jacobian(matrixOut_t jacobian, | |
499 | vectorIn_t arg) const { | ||
500 |
3/6✓ Branch 3 taken 8602 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8602 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 8602 times.
✗ Branch 10 not taken.
|
8602 | constraint_->impl_jacobian(jacobian.topRows<5>(), arg); |
501 |
3/6✓ Branch 3 taken 8602 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8602 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 8602 times.
✗ Branch 10 not taken.
|
8602 | complement_->impl_jacobian(jacobian.bottomRows<3>(), arg); |
502 | 8602 | } | |
503 | |||
504 | ✗ | bool ConvexShapeContactHold::isEqual( | |
505 | const DifferentiableFunction& other) const { | ||
506 | const ConvexShapeContactHold& castother = | ||
507 | ✗ | dynamic_cast<const ConvexShapeContactHold&>(other); | |
508 | ✗ | if (!DifferentiableFunction::isEqual(other)) return false; | |
509 | ✗ | if (constraint_ != castother.constraint_) return false; | |
510 | ✗ | if (complement_ != castother.complement_) return false; | |
511 | ✗ | return true; | |
512 | } | ||
513 | |||
514 | } // namespace constraints | ||
515 | } // namespace hpp | ||
516 |