Directory: | ./ |
---|---|
File: | include/hpp/constraints/symbolic-calculus.hh |
Date: | 2025-05-05 12:19:30 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 277 | 382 | 72.5% |
Branches: | 180 | 545 | 33.0% |
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 | #ifndef HPP_CONSTRAINTS_SYMBOLIC_CALCULUS_HH | ||
30 | #define HPP_CONSTRAINTS_SYMBOLIC_CALCULUS_HH | ||
31 | |||
32 | #define HPP_CONSTRAINTS_CB_REF shared_ptr | ||
33 | #define HPP_CONSTRAINTS_CB_WKREF shared_ptr | ||
34 | |||
35 | #define HPP_CONSTRAINTS_CB_DEFINE_OPERATOR1(op, InType, OutType) \ | ||
36 | template <typename RhsType> \ | ||
37 | typename Traits<OutType<RhsType> >::Ptr_t op( \ | ||
38 | const InType& lhs, const HPP_CONSTRAINTS_CB_REF<RhsType>& rhs) { \ | ||
39 | typedef OutType<RhsType> Op_t; \ | ||
40 | return Op_t::create(lhs, rhs); \ | ||
41 | } | ||
42 | #define HPP_CONSTRAINTS_CB_FRIEND_OPERATOR1(op, InType, OutType) \ | ||
43 | template <typename RhsType> \ | ||
44 | friend typename Traits<OutType<RhsType> >::Ptr_t op( \ | ||
45 | const InType& lhs, const HPP_CONSTRAINTS_CB_REF<RhsType>& rhs); | ||
46 | |||
47 | #define HPP_CONSTRAINTS_CB_DEFINE_OPERATOR2(op, OutType) \ | ||
48 | template <typename LhsType, typename RhsType> \ | ||
49 | typename Traits<OutType<LhsType, RhsType> >::Ptr_t op( \ | ||
50 | const HPP_CONSTRAINTS_CB_REF<LhsType>& lhs, \ | ||
51 | const HPP_CONSTRAINTS_CB_REF<RhsType>& rhs) { \ | ||
52 | typedef OutType<LhsType, RhsType> Op_t; \ | ||
53 | return Op_t::create(lhs, rhs); \ | ||
54 | } | ||
55 | |||
56 | #define HPP_CONSTRAINTS_CB_FRIEND_OPERATOR2(op, OutType) \ | ||
57 | template <typename LhsType, typename RhsType> \ | ||
58 | friend typename Traits<OutType<LhsType, RhsType> >::Ptr_t op( \ | ||
59 | const HPP_CONSTRAINTS_CB_REF<LhsType>& lhs, \ | ||
60 | const HPP_CONSTRAINTS_CB_REF<RhsType>& rhs); | ||
61 | |||
62 | #define HPP_CONSTRAINTS_CB_CREATE1(Class, Arg0Type) \ | ||
63 | static typename Traits<Class>::Ptr_t create(Arg0Type arg0) { \ | ||
64 | typename Traits<Class>::Ptr_t ptr(new Class(arg0)); \ | ||
65 | ptr->init(ptr); \ | ||
66 | return ptr; \ | ||
67 | } | ||
68 | |||
69 | #define HPP_CONSTRAINTS_CB_CREATE2(Class, Arg0Type, Arg1Type) \ | ||
70 | static typename Traits<Class>::Ptr_t create(Arg0Type arg0, Arg1Type arg1) { \ | ||
71 | typename Traits<Class>::Ptr_t ptr(new Class(arg0, arg1)); \ | ||
72 | ptr->init(ptr); \ | ||
73 | return ptr; \ | ||
74 | } | ||
75 | |||
76 | #define HPP_CONSTRAINTS_CB_CREATE3(Class, Arg0Type, Arg1Type, Arg2Type) \ | ||
77 | static typename Traits<Class>::Ptr_t create(Arg0Type arg0, Arg1Type arg1, \ | ||
78 | Arg2Type arg2) { \ | ||
79 | typename Traits<Class>::Ptr_t ptr(new Class(arg0, arg1, arg2)); \ | ||
80 | ptr->init(ptr); \ | ||
81 | return ptr; \ | ||
82 | } | ||
83 | |||
84 | #include <Eigen/SVD> | ||
85 | #include <hpp/constraints/fwd.hh> | ||
86 | #include <hpp/constraints/macros.hh> | ||
87 | #include <hpp/constraints/svd.hh> | ||
88 | #include <hpp/constraints/tools.hh> | ||
89 | #include <hpp/pinocchio/center-of-mass-computation.hh> | ||
90 | #include <hpp/pinocchio/joint.hh> | ||
91 | #include <hpp/pinocchio/liegroup-element.hh> | ||
92 | |||
93 | namespace hpp { | ||
94 | namespace constraints { | ||
95 | /// \defgroup symbolic_calculus Symbolic calculus | ||
96 | |||
97 | /// \addtogroup symbolic_calculus | ||
98 | /// \{ | ||
99 | |||
100 | template <typename ValueType, typename JacobianType> | ||
101 | class CalculusBaseAbstract; | ||
102 | template <typename T> | ||
103 | class Traits; | ||
104 | |||
105 | template <typename LhsValue, typename RhsValue> | ||
106 | class Expression; | ||
107 | template <typename LhsValue, typename RhsValue> | ||
108 | class CrossProduct; | ||
109 | template <typename LhsValue, typename RhsValue> | ||
110 | class ScalarProduct; | ||
111 | template <typename LhsValue, typename RhsValue> | ||
112 | class Difference; | ||
113 | template <typename LhsValue, typename RhsValue> | ||
114 | class Sum; | ||
115 | template <typename RhsValue> | ||
116 | class ScalarMultiply; | ||
117 | template <typename RhsValue> | ||
118 | class RotationMultiply; | ||
119 | typedef eigen::matrix3_t CrossMatrix; | ||
120 | typedef Eigen::Matrix<value_type, 1, Eigen::Dynamic, Eigen::RowMajor> | ||
121 | RowJacobianMatrix; | ||
122 | typedef Eigen::Matrix<value_type, 3, Eigen::Dynamic, Eigen::RowMajor> | ||
123 | JacobianMatrix; | ||
124 | |||
125 | template <typename Class> | ||
126 | struct Traits { | ||
127 | typedef HPP_CONSTRAINTS_CB_REF<Class> Ptr_t; | ||
128 | typedef HPP_CONSTRAINTS_CB_WKREF<Class> WkPtr_t; | ||
129 | }; | ||
130 | template <> | ||
131 | struct Traits<value_type> { | ||
132 | typedef value_type Ptr_t; | ||
133 | typedef value_type WkPtr_t; | ||
134 | }; | ||
135 | template <> | ||
136 | struct Traits<pinocchio::Joint> { | ||
137 | typedef JointPtr_t Ptr_t; | ||
138 | typedef JointPtr_t WkPtr_t; | ||
139 | }; | ||
140 | |||
141 | struct JointTranspose { | ||
142 | 1 | JointTranspose(const JointPtr_t& joint) : j_(joint) {} | |
143 | const JointPtr_t j_; | ||
144 | }; | ||
145 | template <> | ||
146 | struct Traits<JointTranspose> { | ||
147 | typedef JointTranspose Ptr_t; | ||
148 | typedef JointTranspose WkPtr_t; | ||
149 | }; | ||
150 | |||
151 | /// Abstract class defining a basic common interface. | ||
152 | /// | ||
153 | /// The purpose of this class is to allow the user to define an expression | ||
154 | /// without requiring to explicitly write its type. The type will be | ||
155 | /// automatically deduced by the compiler. | ||
156 | /// | ||
157 | /// \code | ||
158 | /// // First define a, b and c with basic elements. | ||
159 | /// CalculusBaseAbstract<OutValueType, OutJacobianType>::Ptr_t | ||
160 | /// myExpression_ptr = | ||
161 | /// CalculusBaseAbstract<OutValueType, OutJacobianType>::create (a + b * c) | ||
162 | /// \endcode | ||
163 | template <class ValueType = eigen::vector3_t, | ||
164 | class JacobianType = JacobianMatrix> | ||
165 | class CalculusBaseAbstract { | ||
166 | public: | ||
167 | typedef ValueType ValueType_t; | ||
168 | typedef JacobianType JacobianType_t; | ||
169 | |||
170 | virtual const ValueType& value() const = 0; | ||
171 | virtual const JacobianType& jacobian() const = 0; | ||
172 | virtual void computeValue(const ConfigurationIn_t arg) = 0; | ||
173 | virtual void computeJacobian(const ConfigurationIn_t arg) = 0; | ||
174 | virtual void invalidate() = 0; | ||
175 | }; | ||
176 | |||
177 | /// Main abstract class. | ||
178 | /// | ||
179 | /// The framework is using CRTP to virtual function calls overload. | ||
180 | /// Keep in mind, so far, no mathematical simplification is done on the | ||
181 | /// expression you provide. It means that you may have a more efficient | ||
182 | /// expression by calculating and simplifying the jacobian yourself. | ||
183 | /// These classes provide: | ||
184 | /// \li a fast way of defining new constraints, | ||
185 | /// \li a robust way of calculation of jacobians - | ||
186 | /// hand calculation error proof | ||
187 | /// \li a fast way to check the results of your calculations. | ||
188 | template <class T, class ValueType = vector3_t, | ||
189 | class JacobianType = JacobianMatrix, class CrossType = CrossMatrix> | ||
190 | class CalculusBase : public CalculusBaseAbstract<ValueType, JacobianType> { | ||
191 | public: | ||
192 |
3/5✓ Branch 4 taken 49 times.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 49 times.
✗ Branch 8 not taken.
|
118 | CalculusBase() : cross_(CrossMatrix::Zero()) {} |
193 | |||
194 | 5 | CalculusBase(const ValueType& value, const JacobianType& jacobian) | |
195 |
5/8✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
|
5 | : value_(value), jacobian_(jacobian), cross_(CrossMatrix::Zero()) {} |
196 | |||
197 | CalculusBase(const CalculusBase& o) | ||
198 | : value_(o.value()), jacobian_(o.jacobian_), cross_(o.cross()) {} | ||
199 | |||
200 | 37270 | inline const ValueType& value() const { return value_; } | |
201 | 109638 | inline const JacobianType& jacobian() const { return jacobian_; } | |
202 | 21004 | void computeValue(const ConfigurationIn_t arg) { | |
203 |
2/2✓ Branch 0 taken 5520 times.
✓ Branch 1 taken 15484 times.
|
42008 | if (vValid_) return; |
204 |
1/2✓ Branch 2 taken 14714 times.
✗ Branch 3 not taken.
|
30968 | static_cast<T*>(this)->impl_value(arg); |
205 | 30968 | vValid_ = true; | |
206 | } | ||
207 | 48638 | void computeJacobian(const ConfigurationIn_t arg) { | |
208 |
2/2✓ Branch 0 taken 41806 times.
✓ Branch 1 taken 6832 times.
|
97276 | if (jValid_) return; |
209 |
1/2✓ Branch 2 taken 5016 times.
✗ Branch 3 not taken.
|
13664 | static_cast<T*>(this)->impl_jacobian(arg); |
210 | 13664 | jValid_ = true; | |
211 | } | ||
212 | 22026 | void invalidate() { | |
213 | 44052 | vValid_ = false; | |
214 | 44052 | jValid_ = false; | |
215 | 44052 | cValid_ = false; | |
216 | 44052 | } | |
217 | 5059 | inline const CrossType& cross() const { return cross_; } | |
218 | 5059 | void computeCrossValue(const ConfigurationIn_t arg) { | |
219 |
2/2✓ Branch 0 taken 1284 times.
✓ Branch 1 taken 3775 times.
|
10018 | if (cValid_) return; |
220 |
1/2✓ Branch 2 taken 3775 times.
✗ Branch 3 not taken.
|
7450 | computeValue(arg); |
221 | 7450 | computeCrossMatrix(value_, cross_); | |
222 | 7450 | cValid_ = true; | |
223 | } | ||
224 | |||
225 | protected: | ||
226 | ValueType value_; | ||
227 | JacobianType jacobian_; | ||
228 | CrossType cross_; | ||
229 | |||
230 | bool vValid_, jValid_, cValid_; | ||
231 | |||
232 | 122 | void init(const typename Traits<T>::Ptr_t& ptr) { wkPtr_ = ptr; } | |
233 | |||
234 | private: | ||
235 | typename Traits<T>::WkPtr_t wkPtr_; | ||
236 | |||
237 | public: | ||
238 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
239 | }; | ||
240 | |||
241 | 15 | HPP_CONSTRAINTS_CB_DEFINE_OPERATOR2(operator-, Difference) | |
242 | 2 | HPP_CONSTRAINTS_CB_DEFINE_OPERATOR2(operator+, Sum) | |
243 | 29 | HPP_CONSTRAINTS_CB_DEFINE_OPERATOR2(operator*, ScalarProduct) | |
244 | 15 | HPP_CONSTRAINTS_CB_DEFINE_OPERATOR2(operator^, CrossProduct) | |
245 | |||
246 | 1 | HPP_CONSTRAINTS_CB_DEFINE_OPERATOR1(operator*, value_type, ScalarMultiply) | |
247 | HPP_CONSTRAINTS_CB_DEFINE_OPERATOR1(operator*, JointPtr_t, RotationMultiply) | ||
248 | 1 | HPP_CONSTRAINTS_CB_DEFINE_OPERATOR1(operator*, JointTranspose, RotationMultiply) | |
249 | |||
250 | /// Base class for classes representing an operation. | ||
251 | template <typename LhsValue, typename RhsValue> | ||
252 | class Expression { | ||
253 | public: | ||
254 | typedef shared_ptr<Expression<LhsValue, RhsValue> > Ptr_t; | ||
255 | typedef weak_ptr<Expression<LhsValue, RhsValue> > WkPtr_t; | ||
256 | |||
257 | static Ptr_t create() { | ||
258 | Ptr_t p(new Expression()); | ||
259 | p->init(p); | ||
260 | return p; | ||
261 | } | ||
262 | |||
263 | 80 | static Ptr_t create(const typename Traits<LhsValue>::Ptr_t& lhs, | |
264 | const typename Traits<RhsValue>::Ptr_t& rhs) { | ||
265 |
1/2✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
|
80 | Ptr_t p(new Expression(lhs, rhs)); |
266 | 80 | p->init(p); | |
267 | 80 | return p; | |
268 | } | ||
269 | |||
270 | const LhsValue& lhs() const { return lhs_; } | ||
271 | |||
272 | const RhsValue& rhs() const { return rhs_; } | ||
273 | |||
274 | Expression() {} | ||
275 | |||
276 | Expression(const Expression& other) : rhs_(other.rhs()), lhs_(other.lhs()) {} | ||
277 | |||
278 | 80 | Expression(const typename Traits<LhsValue>::Ptr_t& lhs, | |
279 | const typename Traits<RhsValue>::Ptr_t& rhs) | ||
280 | 80 | : rhs_(rhs), lhs_(lhs) {} | |
281 | |||
282 | 80 | inline void init(Ptr_t self) { self_ = self; } | |
283 | |||
284 | typename Traits<RhsValue>::Ptr_t rhs_; | ||
285 | typename Traits<LhsValue>::Ptr_t lhs_; | ||
286 | typename Traits<Expression>::WkPtr_t self_; | ||
287 | |||
288 | public: | ||
289 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
290 | }; | ||
291 | |||
292 | /// Cross product of two expressions. | ||
293 | template <typename LhsValue, typename RhsValue> | ||
294 | class CrossProduct : public CalculusBase<CrossProduct<LhsValue, RhsValue> > { | ||
295 | public: | ||
296 | typedef CalculusBase<CrossProduct<LhsValue, RhsValue> > Parent_t; | ||
297 | |||
298 |
2/4✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
|
26 | HPP_CONSTRAINTS_CB_CREATE2(CrossProduct, |
299 | const typename Traits<LhsValue>::Ptr_t&, | ||
300 | const typename Traits<RhsValue>::Ptr_t&) | ||
301 | |||
302 | CrossProduct() {} | ||
303 | |||
304 | CrossProduct(const CalculusBase<CrossProduct>& other) | ||
305 | : Parent_t(other), e_(static_cast<const CrossProduct&>(other).e_) {} | ||
306 | |||
307 | 26 | CrossProduct(const typename Traits<LhsValue>::Ptr_t& lhs, | |
308 | const typename Traits<RhsValue>::Ptr_t& rhs) | ||
309 |
1/2✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
26 | : e_(Expression<LhsValue, RhsValue>::create(lhs, rhs)) {} |
310 | |||
311 | 5742 | void impl_value(const ConfigurationIn_t arg) { | |
312 |
1/2✓ Branch 4 taken 2871 times.
✗ Branch 5 not taken.
|
5742 | e_->lhs_->computeCrossValue(arg); |
313 |
1/2✓ Branch 4 taken 2871 times.
✗ Branch 5 not taken.
|
5742 | e_->rhs_->computeValue(arg); |
314 |
1/2✓ Branch 8 taken 2871 times.
✗ Branch 9 not taken.
|
5742 | this->value_ = e_->lhs_->cross() * e_->rhs_->value(); |
315 | 5742 | } | |
316 | 1044 | void impl_jacobian(const ConfigurationIn_t arg) { | |
317 |
1/2✓ Branch 4 taken 1044 times.
✗ Branch 5 not taken.
|
2088 | e_->lhs_->computeCrossValue(arg); |
318 |
1/2✓ Branch 4 taken 1044 times.
✗ Branch 5 not taken.
|
2088 | e_->rhs_->computeCrossValue(arg); |
319 |
1/2✓ Branch 4 taken 1044 times.
✗ Branch 5 not taken.
|
2088 | e_->lhs_->computeJacobian(arg); |
320 |
1/2✓ Branch 4 taken 1044 times.
✗ Branch 5 not taken.
|
2088 | e_->rhs_->computeJacobian(arg); |
321 |
4/8✓ Branch 3 taken 1044 times.
✗ Branch 4 not taken.
✓ Branch 9 taken 1044 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1044 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1044 times.
✗ Branch 16 not taken.
|
2088 | this->jacobian_ = e_->lhs_->cross() * e_->rhs_->jacobian() - |
322 | 2088 | e_->rhs_->cross() * e_->lhs_->jacobian(); | |
323 | 2088 | } | |
324 | 2871 | void invalidate() { | |
325 | 5742 | Parent_t::invalidate(); | |
326 | 5742 | e_->rhs_->invalidate(); | |
327 | 5742 | e_->lhs_->invalidate(); | |
328 | 5742 | } | |
329 | |||
330 | protected: | ||
331 | typename Expression<LhsValue, RhsValue>::Ptr_t e_; | ||
332 | |||
333 | friend class Expression<LhsValue, RhsValue>; | ||
334 | }; | ||
335 | |||
336 | /// Scalar product of two expressions. | ||
337 | template <typename LhsValue, typename RhsValue> | ||
338 | class ScalarProduct | ||
339 | : public CalculusBase<ScalarProduct<LhsValue, RhsValue>, | ||
340 | Eigen::Matrix<value_type, 1, 1>, RowJacobianMatrix> { | ||
341 | public: | ||
342 | typedef CalculusBase<ScalarProduct<LhsValue, RhsValue>, | ||
343 | Eigen::Matrix<value_type, 1, 1>, RowJacobianMatrix> | ||
344 | Parent_t; | ||
345 | |||
346 |
2/4✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 15 times.
✗ Branch 6 not taken.
|
29 | HPP_CONSTRAINTS_CB_CREATE2(ScalarProduct, |
347 | const typename Traits<LhsValue>::Ptr_t&, | ||
348 | const typename Traits<RhsValue>::Ptr_t&) | ||
349 | |||
350 | ScalarProduct() {} | ||
351 | |||
352 | ScalarProduct(const CalculusBase<ScalarProduct>& other) | ||
353 | : CalculusBase<ScalarProduct>(other), | ||
354 | e_(static_cast<const ScalarProduct&>(other).e_) {} | ||
355 | |||
356 | 29 | ScalarProduct(const typename Traits<LhsValue>::Ptr_t& lhs, | |
357 | const typename Traits<RhsValue>::Ptr_t& rhs) | ||
358 |
1/2✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
|
29 | : e_(Expression<LhsValue, RhsValue>::create(lhs, rhs)) {} |
359 | |||
360 | 2718 | void impl_value(const ConfigurationIn_t arg) { | |
361 |
1/2✓ Branch 4 taken 1409 times.
✗ Branch 5 not taken.
|
2718 | e_->lhs_->computeValue(arg); |
362 |
1/2✓ Branch 4 taken 1409 times.
✗ Branch 5 not taken.
|
2718 | e_->rhs_->computeValue(arg); |
363 | 2718 | this->value_[0] = e_->lhs_->value().dot(e_->rhs_->value()); | |
364 | 2718 | } | |
365 | 706 | void impl_jacobian(const ConfigurationIn_t arg) { | |
366 |
1/2✓ Branch 4 taken 706 times.
✗ Branch 5 not taken.
|
1312 | e_->lhs_->computeValue(arg); |
367 |
1/2✓ Branch 4 taken 706 times.
✗ Branch 5 not taken.
|
1312 | e_->rhs_->computeValue(arg); |
368 |
1/2✓ Branch 4 taken 706 times.
✗ Branch 5 not taken.
|
1312 | e_->lhs_->computeJacobian(arg); |
369 |
1/2✓ Branch 4 taken 706 times.
✗ Branch 5 not taken.
|
1312 | e_->rhs_->computeJacobian(arg); |
370 |
6/12✓ Branch 3 taken 706 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 706 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 706 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 706 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 706 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 706 times.
✗ Branch 21 not taken.
|
1312 | this->jacobian_ = e_->lhs_->value().transpose() * e_->rhs_->jacobian() + |
371 |
1/2✓ Branch 8 taken 706 times.
✗ Branch 9 not taken.
|
1312 | e_->rhs_->value().transpose() * e_->lhs_->jacobian(); |
372 | 1312 | } | |
373 | 2015 | void invalidate() { | |
374 | 3930 | Parent_t::invalidate(); | |
375 | 3930 | e_->rhs_->invalidate(); | |
376 | 3930 | e_->lhs_->invalidate(); | |
377 | 3930 | } | |
378 | |||
379 | protected: | ||
380 | typename Expression<LhsValue, RhsValue>::Ptr_t e_; | ||
381 | |||
382 | friend class Expression<LhsValue, RhsValue>; | ||
383 | }; | ||
384 | |||
385 | /// Difference of two expressions. | ||
386 | template <typename LhsValue, typename RhsValue> | ||
387 | class Difference : public CalculusBase<Difference<LhsValue, RhsValue> > { | ||
388 | public: | ||
389 | typedef CalculusBase<Difference<LhsValue, RhsValue> > Parent_t; | ||
390 | |||
391 |
2/4✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
|
15 | HPP_CONSTRAINTS_CB_CREATE2(Difference, |
392 | const typename Traits<LhsValue>::Ptr_t&, | ||
393 | const typename Traits<RhsValue>::Ptr_t&) | ||
394 | |||
395 | Difference() {} | ||
396 | |||
397 | Difference(const CalculusBase<Difference>& other) | ||
398 | : CalculusBase<Difference>(other), | ||
399 | e_(static_cast<const Difference&>(other).e_) {} | ||
400 | |||
401 | 15 | Difference(const typename Traits<LhsValue>::Ptr_t& lhs, | |
402 | const typename Traits<RhsValue>::Ptr_t& rhs) | ||
403 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
15 | : e_(Expression<LhsValue, RhsValue>::create(lhs, rhs)) {} |
404 | |||
405 | 6614 | void impl_value(const ConfigurationIn_t arg) { | |
406 |
1/2✓ Branch 4 taken 3357 times.
✗ Branch 5 not taken.
|
6614 | e_->lhs_->computeValue(arg); |
407 |
1/2✓ Branch 4 taken 3357 times.
✗ Branch 5 not taken.
|
6614 | e_->rhs_->computeValue(arg); |
408 |
1/2✓ Branch 8 taken 3357 times.
✗ Branch 9 not taken.
|
6614 | this->value_ = e_->lhs_->value() - e_->rhs_->value(); |
409 | 6614 | } | |
410 | 1266 | void impl_jacobian(const ConfigurationIn_t arg) { | |
411 |
1/2✓ Branch 4 taken 1266 times.
✗ Branch 5 not taken.
|
2432 | e_->lhs_->computeJacobian(arg); |
412 |
1/2✓ Branch 4 taken 1266 times.
✗ Branch 5 not taken.
|
2432 | e_->rhs_->computeJacobian(arg); |
413 |
1/2✓ Branch 8 taken 1266 times.
✗ Branch 9 not taken.
|
2432 | this->jacobian_ = e_->lhs_->jacobian() - e_->rhs_->jacobian(); |
414 | 2432 | } | |
415 | 4117 | void invalidate() { | |
416 | 8134 | Parent_t::invalidate(); | |
417 | 8134 | e_->rhs_->invalidate(); | |
418 | 8134 | e_->lhs_->invalidate(); | |
419 | 8134 | } | |
420 | |||
421 | protected: | ||
422 | typename Expression<LhsValue, RhsValue>::Ptr_t e_; | ||
423 | |||
424 | friend class Expression<LhsValue, RhsValue>; | ||
425 | }; | ||
426 | |||
427 | /// Sum of two expressions. | ||
428 | template <typename LhsValue, typename RhsValue> | ||
429 | class Sum : public CalculusBase<Sum<LhsValue, RhsValue> > { | ||
430 | public: | ||
431 | typedef CalculusBase<Sum<LhsValue, RhsValue> > Parent_t; | ||
432 | |||
433 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | HPP_CONSTRAINTS_CB_CREATE2(Sum, const typename Traits<LhsValue>::Ptr_t&, |
434 | const typename Traits<RhsValue>::Ptr_t&) | ||
435 | |||
436 | Sum() {} | ||
437 | |||
438 | Sum(const CalculusBase<Sum>& other) | ||
439 | : CalculusBase<Sum>(other), e_(static_cast<const Sum&>(other).e_) {} | ||
440 | |||
441 | 4 | Sum(const typename Traits<RhsValue>::Ptr_t& rhs, | |
442 | const typename Traits<LhsValue>::Ptr_t& lhs) | ||
443 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | : e_(Expression<LhsValue, RhsValue>::create(lhs, rhs)) {} |
444 | |||
445 | 400 | void impl_value(const ConfigurationIn_t arg) { | |
446 |
1/2✓ Branch 4 taken 200 times.
✗ Branch 5 not taken.
|
400 | e_->lhs_->computeValue(arg); |
447 |
1/2✓ Branch 4 taken 200 times.
✗ Branch 5 not taken.
|
400 | e_->rhs_->computeValue(arg); |
448 |
1/2✓ Branch 8 taken 200 times.
✗ Branch 9 not taken.
|
400 | this->value_ = e_->lhs_->value() + e_->rhs_->value(); |
449 | 400 | } | |
450 | 200 | void impl_jacobian(const ConfigurationIn_t arg) { | |
451 |
1/2✓ Branch 4 taken 200 times.
✗ Branch 5 not taken.
|
400 | e_->lhs_->computeJacobian(arg); |
452 |
1/2✓ Branch 4 taken 200 times.
✗ Branch 5 not taken.
|
400 | e_->rhs_->computeJacobian(arg); |
453 |
1/2✓ Branch 8 taken 200 times.
✗ Branch 9 not taken.
|
400 | this->jacobian_ = e_->lhs_->jacobian() + e_->rhs_->jacobian(); |
454 | 400 | } | |
455 | 200 | void invalidate() { | |
456 | 400 | Parent_t::invalidate(); | |
457 | 400 | e_->rhs_->invalidate(); | |
458 | 400 | e_->lhs_->invalidate(); | |
459 | 400 | } | |
460 | |||
461 | protected: | ||
462 | typename Expression<LhsValue, RhsValue>::Ptr_t e_; | ||
463 | |||
464 | friend class Expression<LhsValue, RhsValue>; | ||
465 | }; | ||
466 | |||
467 | /// Multiplication of an expression by a scalar. | ||
468 | template <typename RhsValue> | ||
469 | class ScalarMultiply : public CalculusBase<ScalarMultiply<RhsValue> > { | ||
470 | public: | ||
471 | typedef CalculusBase<ScalarMultiply<RhsValue> > Parent_t; | ||
472 | |||
473 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | HPP_CONSTRAINTS_CB_CREATE2(ScalarMultiply, |
474 | const typename Traits<value_type>::Ptr_t&, | ||
475 | const typename Traits<RhsValue>::Ptr_t&) | ||
476 | |||
477 | ScalarMultiply() {} | ||
478 | |||
479 | ScalarMultiply(const CalculusBase<ScalarMultiply>& other) | ||
480 | : CalculusBase<ScalarMultiply>(other), | ||
481 | e_(static_cast<const ScalarMultiply&>(other).e_) {} | ||
482 | |||
483 | 1 | ScalarMultiply(const typename Traits<value_type>::Ptr_t& scalar, | |
484 | const typename Traits<RhsValue>::Ptr_t& rhs) | ||
485 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | : e_(Expression<value_type, RhsValue>::create(scalar, rhs)) {} |
486 | |||
487 | 100 | void impl_value(const ConfigurationIn_t arg) { | |
488 |
1/2✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
|
100 | e_->rhs_->computeValue(arg); |
489 |
1/2✓ Branch 6 taken 100 times.
✗ Branch 7 not taken.
|
100 | this->value_ = e_->lhs_ * e_->rhs_->value(); |
490 | 100 | } | |
491 | 100 | void impl_jacobian(const ConfigurationIn_t arg) { | |
492 |
1/2✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
|
100 | e_->rhs_->computeJacobian(arg); |
493 |
1/2✓ Branch 6 taken 100 times.
✗ Branch 7 not taken.
|
100 | this->jacobian_ = e_->lhs_ * e_->rhs_->jacobian(); |
494 | 100 | } | |
495 | 100 | void invalidate() { | |
496 | 100 | Parent_t::invalidate(); | |
497 | 100 | e_->rhs_->invalidate(); | |
498 | 100 | } | |
499 | |||
500 | protected: | ||
501 | typename Expression<value_type, RhsValue>::Ptr_t e_; | ||
502 | |||
503 | friend class Expression<value_type, RhsValue>; | ||
504 | }; | ||
505 | |||
506 | /// Multiplication of an expression by a rotation matrix. | ||
507 | template <typename RhsValue> | ||
508 | class RotationMultiply : public CalculusBase<RotationMultiply<RhsValue> > { | ||
509 | public: | ||
510 | typedef CalculusBase<RotationMultiply<RhsValue> > Parent_t; | ||
511 | |||
512 | RotationMultiply() {} | ||
513 | |||
514 | RotationMultiply(const CalculusBase<RotationMultiply>& other) | ||
515 | : CalculusBase<RotationMultiply>(other), | ||
516 | e_(static_cast<const RotationMultiply&>(other).e_), | ||
517 | transpose_(other.transpose_) {} | ||
518 | |||
519 | HPP_CONSTRAINTS_CB_CREATE2(RotationMultiply, | ||
520 | const typename Traits<pinocchio::Joint>::Ptr_t&, | ||
521 | const typename Traits<RhsValue>::Ptr_t&) | ||
522 | |||
523 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | HPP_CONSTRAINTS_CB_CREATE2(RotationMultiply, |
524 | const typename Traits<JointTranspose>::Ptr_t&, | ||
525 | const typename Traits<RhsValue>::Ptr_t&) | ||
526 | |||
527 | 1 | RotationMultiply(const typename Traits<JointTranspose>::Ptr_t& joint, | |
528 | const typename Traits<RhsValue>::Ptr_t& rhs) | ||
529 | 1 | : e_(Expression<pinocchio::Joint, RhsValue>::create(joint.j_, rhs)), | |
530 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | transpose_(true) {} |
531 | |||
532 | RotationMultiply(const typename Traits<pinocchio::Joint>::Ptr_t& joint, | ||
533 | const typename Traits<RhsValue>::Ptr_t& rhs, | ||
534 | bool transpose = false) | ||
535 | : e_(Expression<pinocchio::Joint, RhsValue>::create(joint, rhs)), | ||
536 | transpose_(transpose) {} | ||
537 | |||
538 | 100 | void impl_value(const ConfigurationIn_t arg) { | |
539 |
1/2✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
|
100 | e_->rhs_->computeValue(arg); |
540 | 100 | const matrix3_t& R = e_->lhs_->currentTransformation().rotation(); | |
541 |
1/2✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
|
100 | if (transpose_) |
542 |
2/4✓ Branch 5 taken 100 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 100 times.
✗ Branch 9 not taken.
|
100 | this->value_ = R.transpose() * e_->rhs_->value(); |
543 | else | ||
544 | ✗ | this->value_ = R * e_->rhs_->value(); | |
545 | 100 | } | |
546 | 100 | void impl_jacobian(const ConfigurationIn_t arg) { | |
547 |
1/2✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
|
100 | e_->rhs_->computeJacobian(arg); |
548 |
1/2✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
|
100 | e_->rhs_->computeCrossValue(arg); |
549 | 100 | const JointJacobian_t& J = e_->lhs_->jacobian(); | |
550 | 100 | const matrix3_t& R = e_->lhs_->currentTransformation().rotation(); | |
551 |
1/2✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
|
100 | if (transpose_) |
552 |
3/6✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 100 times.
✗ Branch 8 not taken.
|
200 | this->jacobian_ = |
553 |
1/2✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
|
100 | R.transpose() * |
554 |
2/4✓ Branch 8 taken 100 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 100 times.
✗ Branch 12 not taken.
|
200 | ((e_->rhs_->cross() * R) * J.bottomRows<3>() + e_->rhs_->jacobian()); |
555 | else | ||
556 | ✗ | this->jacobian_ = R * ((e_->rhs_->cross() * R) * J.bottomRows<3>() + | |
557 | ✗ | e_->rhs_->jacobian()); | |
558 | 100 | } | |
559 | 100 | void invalidate() { | |
560 | 100 | Parent_t::invalidate(); | |
561 | 100 | e_->rhs_->invalidate(); | |
562 | 100 | } | |
563 | |||
564 | protected: | ||
565 | typename Expression<pinocchio::Joint, RhsValue>::Ptr_t e_; | ||
566 | |||
567 | friend class Expression<pinocchio::Joint, RhsValue>; | ||
568 | |||
569 | private: | ||
570 | bool transpose_; | ||
571 | }; | ||
572 | |||
573 | /// Basic expression representing a point in a joint frame. | ||
574 | class PointInJoint : public CalculusBase<PointInJoint> { | ||
575 | public: | ||
576 | typedef CalculusBase<PointInJoint> Parent_t; | ||
577 | |||
578 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
2 | HPP_CONSTRAINTS_CB_CREATE2(PointInJoint, const JointPtr_t&, const vector3_t&) |
579 | ✗ | HPP_CONSTRAINTS_CB_CREATE3(PointInJoint, const JointPtr_t&, const vector3_t&, | |
580 | const size_type&) | ||
581 | |||
582 | PointInJoint() {} | ||
583 | |||
584 | PointInJoint(const CalculusBase<PointInJoint>& other) | ||
585 | : CalculusBase<PointInJoint>(other) { | ||
586 | const PointInJoint& o = static_cast<const PointInJoint&>(other); | ||
587 | joint_ = o.joint(); | ||
588 | local_ = o.local(); | ||
589 | center_ = local_.isZero(); | ||
590 | } | ||
591 | |||
592 | PointInJoint(const PointInJoint& pointInJoint) | ||
593 | : CalculusBase<PointInJoint>(pointInJoint), | ||
594 | joint_(pointInJoint.joint()), | ||
595 | local_(pointInJoint.local()), | ||
596 | center_(local_.isZero()) {} | ||
597 | |||
598 | 2 | PointInJoint(const JointPtr_t& joint, const vector3_t& pointInLocalFrame) | |
599 | 4 | : joint_(joint), | |
600 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | local_(pointInLocalFrame), |
601 |
1/2✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
4 | center_(pointInLocalFrame.isZero()) { |
602 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | assert(joint_ != NULL); |
603 | 2 | } | |
604 | |||
605 | ✗ | PointInJoint(const JointPtr_t& joint, const vector3_t& pointInLocalFrame, | |
606 | size_type nbDof) | ||
607 | ✗ | : joint_(joint), | |
608 | ✗ | local_(pointInLocalFrame), | |
609 | ✗ | center_(pointInLocalFrame.isZero()) { | |
610 | ✗ | if (joint_ == NULL) { | |
611 | ✗ | for (int i = 0; i < 3; ++i) this->value_[i] = local_[i]; | |
612 | ✗ | this->jacobian_.resize(3, nbDof); | |
613 | ✗ | this->jacobian_.setZero(); | |
614 | ✗ | this->cross_.setZero(); | |
615 | } | ||
616 | } | ||
617 | |||
618 | ✗ | const JointPtr_t& joint() const { return joint_; } | |
619 | ✗ | const vector3_t& local() const { return local_; } | |
620 | 200 | void impl_value(const ConfigurationIn_t) { | |
621 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 200 times.
|
200 | if (joint_ == NULL) return; |
622 | 200 | this->value_ = joint_->currentTransformation().act(local_); | |
623 | } | ||
624 | 200 | void impl_jacobian(const ConfigurationIn_t) { | |
625 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 200 times.
|
200 | if (joint_ == NULL) return; |
626 | 200 | const JointJacobian_t& J(joint_->jacobian()); | |
627 | 200 | const matrix3_t& R = joint_->currentTransformation().rotation(); | |
628 |
3/6✓ Branch 2 taken 200 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 200 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 200 times.
✗ Branch 9 not taken.
|
200 | this->jacobian_.noalias() = R * J.topRows<3>(); |
629 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
|
200 | if (!center_) { |
630 | ✗ | computeCrossRXl(); | |
631 | ✗ | this->jacobian_.noalias() -= (this->cross_ * R) * J.bottomRows<3>(); | |
632 | } | ||
633 | } | ||
634 | ✗ | void computeCrossRXl() { | |
635 | ✗ | if (joint_ == NULL) return; | |
636 | ✗ | if (center_) { | |
637 | ✗ | this->cross_.setZero(); | |
638 | ✗ | return; | |
639 | } | ||
640 | ✗ | computeCrossMatrix(joint_->currentTransformation().rotation() * local_, | |
641 | ✗ | this->cross_); | |
642 | } | ||
643 | |||
644 | protected: | ||
645 | JointPtr_t joint_; | ||
646 | vector3_t local_; | ||
647 | bool center_; | ||
648 | |||
649 | public: | ||
650 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
651 | }; | ||
652 | |||
653 | /// Basic expression representing a vector in a joint frame. | ||
654 | class VectorInJoint : public CalculusBase<VectorInJoint> { | ||
655 | public: | ||
656 | HPP_CONSTRAINTS_CB_CREATE2(VectorInJoint, const JointPtr_t&, const vector3_t&) | ||
657 | ✗ | HPP_CONSTRAINTS_CB_CREATE3(VectorInJoint, const JointPtr_t&, const vector3_t&, | |
658 | const size_type&) | ||
659 | |||
660 | VectorInJoint() {} | ||
661 | |||
662 | VectorInJoint(const CalculusBase<VectorInJoint>& other) | ||
663 | : CalculusBase<VectorInJoint>(other), | ||
664 | joint_(static_cast<const VectorInJoint&>(other).joint()), | ||
665 | vector_(static_cast<const VectorInJoint&>(other).vector()) {} | ||
666 | |||
667 | VectorInJoint(const VectorInJoint& vectorInJoint) | ||
668 | : CalculusBase<VectorInJoint>(vectorInJoint), | ||
669 | joint_(vectorInJoint.joint()), | ||
670 | vector_(vectorInJoint.vector()) {} | ||
671 | |||
672 | VectorInJoint(const JointPtr_t& joint, const vector3_t& vectorInLocalFrame) | ||
673 | : joint_(joint), vector_(vectorInLocalFrame) {} | ||
674 | |||
675 | ✗ | VectorInJoint(const JointPtr_t& joint, const vector3_t& vectorInLocalFrame, | |
676 | const size_type& nbDof) | ||
677 | ✗ | : joint_(joint), vector_(vectorInLocalFrame) { | |
678 | ✗ | if (joint_ == NULL) { | |
679 | ✗ | for (int i = 0; i < 3; ++i) this->value_[i] = vector_[i]; | |
680 | ✗ | this->jacobian_.resize(3, nbDof); | |
681 | ✗ | this->jacobian_.setZero(); | |
682 | ✗ | this->cross_.setZero(); | |
683 | } | ||
684 | } | ||
685 | |||
686 | const JointPtr_t& joint() const { return joint_; } | ||
687 | const vector3_t& vector() const { return vector_; } | ||
688 | ✗ | void impl_value(const ConfigurationIn_t) { | |
689 | ✗ | if (joint_ == NULL) return; | |
690 | ✗ | this->value_ = joint_->currentTransformation().rotation() * vector_; | |
691 | } | ||
692 | ✗ | void impl_jacobian(const ConfigurationIn_t) { | |
693 | ✗ | if (joint_ == NULL) return; | |
694 | ✗ | const JointJacobian_t& J(joint_->jacobian()); | |
695 | ✗ | const matrix3_t& R = joint_->currentTransformation().rotation(); | |
696 | ✗ | computeCrossRXl(); | |
697 | ✗ | this->jacobian_.noalias() = (-this->cross_ * R) * J.bottomRows<3>(); | |
698 | } | ||
699 | ✗ | void computeCrossRXl() { | |
700 | ✗ | if (joint_ == NULL) return; | |
701 | ✗ | computeCrossMatrix(joint_->currentTransformation().rotation() * vector_, | |
702 | ✗ | this->cross_); | |
703 | } | ||
704 | |||
705 | protected: | ||
706 | JointPtr_t joint_; | ||
707 | vector3_t vector_; | ||
708 | |||
709 | public: | ||
710 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
711 | }; | ||
712 | |||
713 | /// Basic expression mapping a function as an expression | ||
714 | template <typename FunctionType> | ||
715 | class FunctionExp | ||
716 | : public CalculusBase<FunctionExp<FunctionType>, vector_t, matrix_t> { | ||
717 | public: | ||
718 | typedef CalculusBase<FunctionExp<FunctionType>, vector_t, matrix_t> Parent_t; | ||
719 | typedef shared_ptr<FunctionType> FunctionTypePtr_t; | ||
720 | |||
721 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | HPP_CONSTRAINTS_CB_CREATE1(FunctionExp<FunctionType>, |
722 | const FunctionTypePtr_t&) | ||
723 | |||
724 | FunctionExp() {} | ||
725 | |||
726 | FunctionExp(const Parent_t& other) | ||
727 | : Parent_t(other), f_(other.f_), lge_(other.lge_) {} | ||
728 | |||
729 | FunctionExp(const FunctionExp& other) | ||
730 | : Parent_t(other), f_(other.f_), lge_(other.lge_) {} | ||
731 | |||
732 | /// Constructor | ||
733 | /// | ||
734 | /// \param func the inner function | ||
735 | 1 | FunctionExp(const FunctionTypePtr_t& func) | |
736 | 1 | : Parent_t(vector_t::Zero(func->outputSize()), | |
737 | 1 | matrix_t::Zero(func->outputDerivativeSize(), | |
738 | 1 | func->inputDerivativeSize())), | |
739 | 1 | f_(func), | |
740 |
5/10✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
|
3 | lge_(func->outputSpace()) {} |
741 | |||
742 | 100 | void impl_value(const ConfigurationIn_t arg) { | |
743 |
2/4✓ Branch 3 taken 100 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 100 times.
✗ Branch 7 not taken.
|
100 | f_->value(lge_, arg); |
744 | 100 | this->value_ = lge_.vector(); | |
745 | 100 | } | |
746 | 100 | void impl_jacobian(const ConfigurationIn_t arg) { | |
747 |
2/4✓ Branch 3 taken 100 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 100 times.
✗ Branch 7 not taken.
|
100 | f_->jacobian(this->jacobian_, arg); |
748 | 100 | } | |
749 | |||
750 | private: | ||
751 | FunctionTypePtr_t f_; | ||
752 | LiegroupElement lge_; | ||
753 | }; | ||
754 | |||
755 | /// Basic expression representing a static point | ||
756 | /// | ||
757 | /// Its value is constant and its jacobian is a zero matrix. | ||
758 | class Point : public CalculusBase<Point, vector3_t, JacobianMatrix> { | ||
759 | public: | ||
760 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | HPP_CONSTRAINTS_CB_CREATE2(Point, const vector3_t&, const size_t&) |
761 | |||
762 | Point() {} | ||
763 | |||
764 | Point(const CalculusBase<Point, vector3_t, JacobianMatrix>& other) | ||
765 | : CalculusBase<Point, eigen::vector3_t, JacobianMatrix>(other) {} | ||
766 | |||
767 | Point(const Point& point) | ||
768 | : CalculusBase<Point, vector3_t, JacobianMatrix>(point) {} | ||
769 | |||
770 | /// Constructor | ||
771 | /// | ||
772 | /// \param point the static point | ||
773 | /// \param jacobianNbCols number of column of the jacobian | ||
774 | 1 | Point(const vector3_t& point, size_t jacobianNbCols) | |
775 | 1 | : CalculusBase<Point, vector3_t, JacobianMatrix>( | |
776 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | point, JacobianMatrix::Zero(3, jacobianNbCols)) {} |
777 | |||
778 | 770 | void impl_value(const ConfigurationIn_t) {} | |
779 | 244 | void impl_jacobian(const ConfigurationIn_t) {} | |
780 | }; | ||
781 | |||
782 | /// Basic expression representing a COM. | ||
783 | class PointCom : public CalculusBase<PointCom, vector3_t, ComJacobian_t> { | ||
784 | public: | ||
785 | typedef CalculusBase<PointCom, vector3_t, ComJacobian_t> Parent_t; | ||
786 | ✗ | HPP_CONSTRAINTS_CB_CREATE1(PointCom, const CenterOfMassComputationPtr_t&) | |
787 | |||
788 | PointCom() {} | ||
789 | |||
790 | PointCom(const Parent_t& other) | ||
791 | : Parent_t(other), | ||
792 | comc_(static_cast<const PointCom&>(other).centerOfMassComputation()) {} | ||
793 | |||
794 | ✗ | PointCom(const CenterOfMassComputationPtr_t& comc) : comc_(comc) {} | |
795 | |||
796 | ✗ | inline const vector3_t& value() const { return comc_->com(); } | |
797 | ✗ | inline const ComJacobian_t& jacobian() const { return comc_->jacobian(); } | |
798 | |||
799 | ✗ | const CenterOfMassComputationPtr_t& centerOfMassComputation() const { | |
800 | ✗ | return comc_; | |
801 | } | ||
802 | ✗ | void impl_value(const ConfigurationIn_t) { | |
803 | ✗ | comc_->compute(hpp::pinocchio::COM); | |
804 | } | ||
805 | ✗ | void impl_jacobian(const ConfigurationIn_t) { | |
806 | ✗ | comc_->compute(hpp::pinocchio::COMPUTE_ALL); | |
807 | // TODO: there is memory and time to be saved here as this copy is | ||
808 | // not important. | ||
809 | // this->jacobian_ = comc_->jacobian (); | ||
810 | } | ||
811 | |||
812 | protected: | ||
813 | CenterOfMassComputationPtr_t comc_; | ||
814 | }; | ||
815 | |||
816 | class JointFrame | ||
817 | : public CalculusBase<JointFrame, Eigen::Matrix<value_type, 6, 1>, | ||
818 | Eigen::Matrix<value_type, 6, Eigen::Dynamic> > { | ||
819 | public: | ||
820 | typedef CalculusBase<JointFrame, ValueType_t, JacobianType_t> Parent_t; | ||
821 | |||
822 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
1 | HPP_CONSTRAINTS_CB_CREATE1(JointFrame, const JointPtr_t&) |
823 | |||
824 | JointFrame() {} | ||
825 | |||
826 | JointFrame(const Parent_t& other) | ||
827 | : Parent_t(other), joint_(static_cast<const JointFrame&>(other).joint_) {} | ||
828 | |||
829 | JointFrame(const JointFrame& jf) : Parent_t(jf), joint_(jf.joint()) {} | ||
830 | |||
831 | 1 | JointFrame(const JointPtr_t& joint) : joint_(joint) { | |
832 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | assert(joint_ != NULL); |
833 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | this->jacobian_.resize(6, |
834 |
1/2✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | joint->robot()->numberDof() - |
835 | 2 | joint->robot()->extraConfigSpace().dimension()); | |
836 | 1 | } | |
837 | |||
838 | const JointPtr_t& joint() const { return joint_; } | ||
839 | 200 | void impl_value(const ConfigurationIn_t) { | |
840 | 200 | const Transform3s& M = joint_->currentTransformation(); | |
841 |
1/2✓ Branch 3 taken 200 times.
✗ Branch 4 not taken.
|
200 | this->value_.head<3>() = M.translation(); |
842 |
2/4✓ Branch 2 taken 200 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 200 times.
✗ Branch 6 not taken.
|
200 | logSO3(M.rotation(), theta_, this->value_.tail<3>()); |
843 | 200 | } | |
844 | 100 | void impl_jacobian(const ConfigurationIn_t arg) { | |
845 |
2/4✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
|
100 | computeValue(arg); |
846 |
1/2✓ Branch 2 taken 100 times.
✗ Branch 3 not taken.
|
100 | const JointJacobian_t& J(joint_->jacobian()); |
847 |
2/4✓ Branch 2 taken 100 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 100 times.
✗ Branch 6 not taken.
|
100 | const matrix3_t& R(joint_->currentTransformation().rotation()); |
848 | // Compute vector r | ||
849 |
1/2✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
|
100 | eigen::matrix3_t Jlog; |
850 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
|
100 | assert(theta_ >= 0); |
851 |
2/4✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
|
100 | JlogSO3(theta_, this->value_.tail<3>(), Jlog); |
852 |
5/10✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 100 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 100 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 100 times.
✗ Branch 14 not taken.
|
100 | this->jacobian_.topRows<3>().noalias() = R * J.topRows<3>(); |
853 |
5/10✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 100 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 100 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 100 times.
✗ Branch 14 not taken.
|
100 | this->jacobian_.bottomRows<3>().noalias() = Jlog * J.bottomRows<3>(); |
854 | 100 | } | |
855 | |||
856 | protected: | ||
857 | JointPtr_t joint_; | ||
858 | double theta_; | ||
859 | |||
860 | public: | ||
861 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
862 | }; | ||
863 | |||
864 | /// Matrix having Expression elements | ||
865 | template <typename ValueType = eigen::vector3_t, | ||
866 | typename JacobianType = JacobianMatrix> | ||
867 | class MatrixOfExpressions | ||
868 | : public CalculusBase< | ||
869 | MatrixOfExpressions<ValueType, JacobianType>, | ||
870 | Eigen::Matrix<value_type, Eigen::Dynamic, Eigen::Dynamic>, | ||
871 | Eigen::Matrix<value_type, Eigen::Dynamic, Eigen::Dynamic> > { | ||
872 | public: | ||
873 | typedef Eigen::Matrix<value_type, Eigen::Dynamic, Eigen::Dynamic> Value_t; | ||
874 | typedef Eigen::Matrix<value_type, Eigen::Dynamic, Eigen::Dynamic> Jacobian_t; | ||
875 | typedef Eigen::Matrix<value_type, Eigen::Dynamic, Eigen::Dynamic> PseudoInv_t; | ||
876 | typedef Eigen::Matrix<value_type, Eigen::Dynamic, Eigen::Dynamic> | ||
877 | PseudoInvJacobian_t; | ||
878 | typedef CalculusBase<MatrixOfExpressions, Value_t, Jacobian_t> Parent_t; | ||
879 | typedef CalculusBaseAbstract<ValueType, JacobianType> Element_t; | ||
880 | typedef typename Traits<Element_t>::Ptr_t ElementPtr_t; | ||
881 | typedef Eigen::JacobiSVD<Value_t> SVD_t; | ||
882 | |||
883 | HPP_CONSTRAINTS_CB_CREATE2(MatrixOfExpressions, | ||
884 | const Eigen::Ref<const Value_t>&, | ||
885 | const Eigen::Ref<const Jacobian_t>&) | ||
886 | |||
887 | 1 | MatrixOfExpressions(const Eigen::Ref<const Value_t>& value, | |
888 | const Eigen::Ref<const Jacobian_t>& jacobian) | ||
889 | : Parent_t(value, jacobian), | ||
890 | 1 | nRows_(0), | |
891 | 1 | nCols_(0), | |
892 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | svd_(value.rows(), value.cols(), |
893 | Eigen::ComputeFullU | Eigen::ComputeFullV), | ||
894 | 1 | piValid_(false), | |
895 |
6/12✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
|
2 | svdValid_(false) {} |
896 | |||
897 | MatrixOfExpressions(const Parent_t& other) | ||
898 | : Parent_t(other), | ||
899 | nRows_(static_cast<const MatrixOfExpressions&>(other).nRows_), | ||
900 | nCols_(static_cast<const MatrixOfExpressions&>(other).nCols_), | ||
901 | elements_(static_cast<const MatrixOfExpressions&>(other).elements_), | ||
902 | svd_(static_cast<const MatrixOfExpressions&>(other).svd_), | ||
903 | piValid_(static_cast<const MatrixOfExpressions&>(other).piValid_), | ||
904 | svdValid_(static_cast<const MatrixOfExpressions&>(other).svdValid_) {} | ||
905 | |||
906 | MatrixOfExpressions(const MatrixOfExpressions& matrix) | ||
907 | : Parent_t(matrix), | ||
908 | nRows_(matrix.nRows_), | ||
909 | nCols_(matrix.nCols_), | ||
910 | elements_(matrix.elements_), | ||
911 | svd_(matrix.svd_), | ||
912 | piValid_(matrix.piValid_), | ||
913 | svdValid_(matrix.svdValid_) {} | ||
914 | |||
915 | 1 | void setSize(std::size_t nRows, std::size_t nCols) { | |
916 | 1 | nRows_ = nRows; | |
917 | 1 | nCols_ = nCols; | |
918 | 1 | elements_.resize(nRows_); | |
919 |
2/2✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
|
3 | for (std::size_t i = 0; i < nRows; ++i) elements_[i].resize(nCols); |
920 | 1 | } | |
921 | |||
922 | ✗ | ElementPtr_t& operator()(std::size_t i, std::size_t j) { | |
923 | ✗ | return elements_[i][j]; | |
924 | } | ||
925 | |||
926 | 4 | void set(std::size_t i, std::size_t j, const ElementPtr_t ptr) { | |
927 | 4 | elements_[i][j] = ptr; | |
928 | 4 | } | |
929 | |||
930 | 100 | void impl_value(const ConfigurationIn_t arg) { | |
931 | 100 | size_type r = 0, c = 0, nr = 0, nc = 0; | |
932 |
2/2✓ Branch 0 taken 200 times.
✓ Branch 1 taken 100 times.
|
300 | for (std::size_t i = 0; i < nRows_; ++i) { |
933 | 200 | c = 0; | |
934 | 200 | nr = elements_[i][0]->value().rows(); | |
935 |
2/2✓ Branch 0 taken 400 times.
✓ Branch 1 taken 200 times.
|
600 | for (std::size_t j = 0; j < nCols_; ++j) { |
936 |
1/2✓ Branch 5 taken 400 times.
✗ Branch 6 not taken.
|
400 | elements_[i][j]->computeValue(arg); |
937 |
1/2✗ Branch 5 not taken.
✓ Branch 6 taken 400 times.
|
400 | assert(nr == elements_[i][j]->value().rows()); |
938 | 400 | nc = elements_[i][j]->value().cols(); | |
939 |
1/2✓ Branch 6 taken 400 times.
✗ Branch 7 not taken.
|
400 | this->value_.block(r, c, nr, nc) = elements_[i][j]->value(); |
940 | 400 | c += nc; | |
941 | } | ||
942 | 200 | r += nr; | |
943 | } | ||
944 | 100 | } | |
945 | 100 | void impl_jacobian(const ConfigurationIn_t arg) { | |
946 | 100 | size_type r = 0, c = 0, nr = 0, nc = 0; | |
947 |
2/2✓ Branch 0 taken 200 times.
✓ Branch 1 taken 100 times.
|
300 | for (std::size_t i = 0; i < nRows_; ++i) { |
948 | 200 | c = 0; | |
949 | 200 | nr = elements_[i][0]->jacobian().rows(); | |
950 |
2/2✓ Branch 0 taken 400 times.
✓ Branch 1 taken 200 times.
|
600 | for (std::size_t j = 0; j < nCols_; ++j) { |
951 |
1/2✓ Branch 5 taken 400 times.
✗ Branch 6 not taken.
|
400 | elements_[i][j]->computeJacobian(arg); |
952 |
1/2✗ Branch 5 not taken.
✓ Branch 6 taken 400 times.
|
400 | assert(nr == elements_[i][j]->jacobian().rows()); |
953 | 400 | nc = elements_[i][j]->jacobian().cols(); | |
954 |
1/2✓ Branch 6 taken 400 times.
✗ Branch 7 not taken.
|
400 | this->jacobian_.block(r, c, nr, nc) = elements_[i][j]->jacobian(); |
955 | 400 | c += nc; | |
956 | } | ||
957 | 200 | r += nr; | |
958 | } | ||
959 | 100 | } | |
960 | |||
961 | ✗ | inline const PseudoInv_t& pinv() const { return pi_; } | |
962 | ✗ | inline const PseudoInvJacobian_t& pinvJacobian() const { return pij_; } | |
963 | ✗ | void computeSVD(const ConfigurationIn_t arg) { | |
964 | ✗ | if (svdValid_) return; | |
965 | ✗ | this->computeValue(arg); | |
966 | ✗ | svd_.compute(this->value_); | |
967 | HPP_DEBUG_SVDCHECK(svd_); | ||
968 | ✗ | svdValid_ = true; | |
969 | } | ||
970 | ✗ | void computePseudoInverse(const ConfigurationIn_t arg) { | |
971 | ✗ | if (piValid_) return; | |
972 | ✗ | this->computeValue(arg); | |
973 | ✗ | this->computeSVD(arg); | |
974 | ✗ | pi_.resize(this->value_.cols(), this->value_.rows()); | |
975 | ✗ | pseudoInverse<SVD_t>(svd_, pi_); | |
976 | ✗ | piValid_ = true; | |
977 | } | ||
978 | ✗ | void computePseudoInverseJacobian( | |
979 | const ConfigurationIn_t arg, | ||
980 | const Eigen::Ref<const Eigen::Matrix<value_type, Eigen::Dynamic, 1> >& | ||
981 | rhs) { | ||
982 | ✗ | this->computeJacobian(arg); | |
983 | ✗ | computePseudoInverse(arg); | |
984 | ✗ | const std::size_t nbDof = elements_[0][0]->jacobian().cols(); | |
985 | ✗ | const std::size_t inSize = this->value_.cols(); | |
986 | ✗ | const vector_t piTrhs = svd_.solve(rhs); | |
987 | ✗ | assert(pi_.rows() == (size_type)inSize); | |
988 | |||
989 | ✗ | Jacobian_t cache(this->jacobian_.rows(), nbDof); | |
990 | ✗ | jacobianTimes(arg, piTrhs, cache); | |
991 | ✗ | pij_.noalias() = -pi_ * cache; | |
992 | ✗ | cache.resize(inSize, nbDof); | |
993 | |||
994 | ✗ | pkInv_.resize(pi_.cols(), pi_.cols()); | |
995 | ✗ | projectorOnKernelOfInv<SVD_t>(svd_, pkInv_, true); | |
996 | ✗ | jacobianTransposeTimes(arg, pkInv_ * rhs, cache); | |
997 | ✗ | pij_.noalias() += (pi_ * pi_.transpose()) * cache; | |
998 | |||
999 | ✗ | jacobianTransposeTimes(arg, pi_.transpose() * piTrhs, cache); | |
1000 | ✗ | pk_.resize(inSize, inSize); | |
1001 | ✗ | projectorOnKernel<SVD_t>(svd_, pk_, true); | |
1002 | ✗ | pij_.noalias() += pk_ * cache; | |
1003 | } | ||
1004 | |||
1005 | 10000 | void jacobianTimes( | |
1006 | const ConfigurationIn_t arg, | ||
1007 | const Eigen::Ref<const Eigen::Matrix<value_type, Eigen::Dynamic, 1> >& | ||
1008 | rhs, | ||
1009 | Eigen::Ref<Jacobian_t> cache) const { | ||
1010 | 10000 | size_type r = 0, c = 0, nr = 0, nc = 0; | |
1011 | 10000 | cache.setZero(); | |
1012 |
2/2✓ Branch 0 taken 20000 times.
✓ Branch 1 taken 10000 times.
|
30000 | for (std::size_t i = 0; i < nRows_; ++i) { |
1013 | 20000 | c = 0; | |
1014 | 20000 | nr = elements_[i][0]->jacobian().rows(); | |
1015 |
2/2✓ Branch 0 taken 40000 times.
✓ Branch 1 taken 20000 times.
|
60000 | for (std::size_t j = 0; j < nCols_; ++j) { |
1016 |
1/2✓ Branch 5 taken 40000 times.
✗ Branch 6 not taken.
|
40000 | elements_[i][j]->computeJacobian(arg); |
1017 |
1/2✗ Branch 5 not taken.
✓ Branch 6 taken 40000 times.
|
40000 | assert(nr == elements_[i][j]->jacobian().rows()); |
1018 | 40000 | nc = elements_[i][j]->jacobian().cols(); | |
1019 |
4/8✓ Branch 1 taken 40000 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 40000 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 40000 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 40000 times.
✗ Branch 11 not taken.
|
40000 | cache.middleRows(r, nr).noalias() += |
1020 |
1/2✓ Branch 2 taken 40000 times.
✗ Branch 3 not taken.
|
40000 | this->jacobian_.block(r, c, nr, nc) * rhs[j]; |
1021 | 40000 | c += nc; | |
1022 | } | ||
1023 | 20000 | r += nr; | |
1024 | } | ||
1025 | 10000 | } | |
1026 | |||
1027 | ✗ | void jacobianTransposeTimes( | |
1028 | const ConfigurationIn_t arg, | ||
1029 | const Eigen::Ref<const Eigen::Matrix<value_type, Eigen::Dynamic, 1> >& | ||
1030 | rhs, | ||
1031 | Eigen::Ref<Jacobian_t> cache) const { | ||
1032 | ✗ | size_type r = 0, c = 0, nr = 0, nc = 0; | |
1033 | ✗ | cache.setZero(); | |
1034 | ✗ | for (std::size_t i = 0; i < nRows_; ++i) { | |
1035 | ✗ | c = 0; | |
1036 | ✗ | nr = elements_[i][0]->jacobian().rows(); | |
1037 | ✗ | for (std::size_t j = 0; j < nCols_; ++j) { | |
1038 | ✗ | elements_[i][j]->computeJacobian(arg); | |
1039 | ✗ | assert(nr == elements_[i][j]->jacobian().rows()); | |
1040 | ✗ | nc = elements_[i][j]->jacobian().cols(); | |
1041 | ✗ | cache.row(j) += rhs.segment(r, nr).transpose() * | |
1042 | ✗ | this->jacobian_.block(r, c, nr, nc); | |
1043 | ✗ | c += nc; | |
1044 | } | ||
1045 | ✗ | r += nr; | |
1046 | } | ||
1047 | } | ||
1048 | |||
1049 | ✗ | Eigen::JacobiSVD<Value_t>& svd() { return svd_; } | |
1050 | |||
1051 | 100 | void invalidate() { | |
1052 | 100 | Parent_t::invalidate(); | |
1053 |
2/2✓ Branch 0 taken 200 times.
✓ Branch 1 taken 100 times.
|
300 | for (std::size_t i = 0; i < nRows_; ++i) |
1054 |
2/2✓ Branch 4 taken 400 times.
✓ Branch 5 taken 200 times.
|
600 | for (std::size_t j = 0; j < nCols_; ++j) elements_[i][j]->invalidate(); |
1055 | 100 | piValid_ = false; | |
1056 | 100 | svdValid_ = false; | |
1057 | 100 | } | |
1058 | |||
1059 | std::size_t nRows_, nCols_; | ||
1060 | std::vector<std::vector<ElementPtr_t> > elements_; | ||
1061 | |||
1062 | private: | ||
1063 | SVD_t svd_; | ||
1064 | matrix_t pkInv_, pk_; | ||
1065 | PseudoInv_t pi_; | ||
1066 | PseudoInvJacobian_t pij_; | ||
1067 | bool piValid_, svdValid_; | ||
1068 | |||
1069 | public: | ||
1070 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW | ||
1071 | }; | ||
1072 | |||
1073 | /// \} | ||
1074 | } // namespace constraints | ||
1075 | } // namespace hpp | ||
1076 | |||
1077 | #endif // HPP_CONSTRAINTS_SYMBOLIC_CALCULUS_HH | ||
1078 |