5 #ifndef __pinocchio_multibody_liegroup_cartesian_product_operation_hpp__
6 #define __pinocchio_multibody_liegroup_cartesian_product_operation_hpp__
8 #include <pinocchio/multibody/liegroup/liegroup-base.hpp>
12 template<
int dim1,
int dim2>
26 value = Eigen::Dynamic
35 value = Eigen::Dynamic
39 template<
typename LieGroup1,
typename LieGroup2>
42 template<
typename LieGroup1,
typename LieGroup2>
50 LieGroup2::NQ > ::value,
52 LieGroup2::NV > ::value
56 template<
typename LieGroup1,
typename LieGroup2>
58 :
public LieGroupBase<CartesianProductOperation<LieGroup1, LieGroup2>>
73 return lg1.nq() + lg2.nq();
79 return lg1.nv() + lg2.nv();
82 ConfigVector_t neutral()
const
86 Qo1(n) = lg1.neutral();
87 Qo2(n) = lg2.neutral();
91 std::string name()
const
93 std::ostringstream oss;
94 oss << lg1.name() <<
"*" << lg2.name();
98 template<
class ConfigL_t,
class ConfigR_t,
class Tangent_t>
100 const Eigen::MatrixBase<ConfigL_t> & q0,
101 const Eigen::MatrixBase<ConfigR_t> & q1,
102 const Eigen::MatrixBase<Tangent_t> & d)
const
104 lg1.difference(Q1(q0), Q1(q1), Vo1(d));
105 lg2.difference(Q2(q0), Q2(q1), Vo2(d));
108 template<ArgumentPosition arg,
class ConfigL_t,
class ConfigR_t,
class JacobianOut_t>
109 void dDifference_impl(
110 const Eigen::MatrixBase<ConfigL_t> & q0,
111 const Eigen::MatrixBase<ConfigR_t> & q1,
112 const Eigen::MatrixBase<JacobianOut_t> & J)
const
117 lg1.template dDifference<arg>(Q1(q0), Q1(q1), J11(J));
118 lg2.template dDifference<arg>(Q2(q0), Q2(q1), J22(J));
121 template<
class ConfigIn_t,
class Velocity_t,
class ConfigOut_t>
123 const Eigen::MatrixBase<ConfigIn_t> & q,
124 const Eigen::MatrixBase<Velocity_t> & v,
125 const Eigen::MatrixBase<ConfigOut_t> & qout)
const
127 lg1.integrate(Q1(q), V1(v), Qo1(qout));
128 lg2.integrate(Q2(q), V2(v), Qo2(qout));
131 template<
class Config_t,
class Jacobian_t>
132 void integrateCoeffWiseJacobian_impl(
133 const Eigen::MatrixBase<Config_t> & q,
const Eigen::MatrixBase<Jacobian_t> & J)
const
135 assert(J.rows() == nq() && J.cols() == nv() &&
"J is not of the right dimension");
136 Jacobian_t & J_ = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, J);
137 J_.topRightCorner(lg1.nq(), lg2.nv()).setZero();
138 J_.bottomLeftCorner(lg2.nq(), lg1.nv()).setZero();
140 lg1.integrateCoeffWiseJacobian(Q1(q), J_.topLeftCorner(lg1.nq(), lg1.nv()));
141 lg2.integrateCoeffWiseJacobian(Q2(q), J_.bottomRightCorner(lg2.nq(), lg2.nv()));
144 template<
class Config_t,
class Tangent_t,
class JacobianOut_t>
145 void dIntegrate_dq_impl(
146 const Eigen::MatrixBase<Config_t> & q,
147 const Eigen::MatrixBase<Tangent_t> & v,
148 const Eigen::MatrixBase<JacobianOut_t> & J,
149 const AssignmentOperatorType op = SETTO)
const
159 lg1.dIntegrate_dq(Q1(q), V1(v), J11(J), op);
160 lg2.dIntegrate_dq(Q2(q), V2(v), J22(J), op);
163 assert(
false &&
"Wrong Op requesed value");
168 template<
class Config_t,
class Tangent_t,
class JacobianOut_t>
169 void dIntegrate_dv_impl(
170 const Eigen::MatrixBase<Config_t> & q,
171 const Eigen::MatrixBase<Tangent_t> & v,
172 const Eigen::MatrixBase<JacobianOut_t> & J,
173 const AssignmentOperatorType op = SETTO)
const
183 lg1.dIntegrate_dv(Q1(q), V1(v), J11(J), op);
184 lg2.dIntegrate_dv(Q2(q), V2(v), J22(J), op);
187 assert(
false &&
"Wrong Op requesed value");
192 template<
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
193 void dIntegrateTransport_dq_impl(
194 const Eigen::MatrixBase<Config_t> & q,
195 const Eigen::MatrixBase<Tangent_t> & v,
196 const Eigen::MatrixBase<JacobianIn_t> & J_in,
197 const Eigen::MatrixBase<JacobianOut_t> & J_out)
const
199 JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J_out);
200 JacobianOut_t & Jin = PINOCCHIO_EIGEN_CONST_CAST(JacobianIn_t, J_in);
201 lg1.dIntegrateTransport_dq(
202 Q1(q), V1(v), Jin.template topRows<LieGroup1::NV>(),
203 Jout.template topRows<LieGroup1::NV>());
204 lg2.dIntegrateTransport_dq(
205 Q2(q), V2(v), Jin.template bottomRows<LieGroup2::NV>(),
206 Jout.template bottomRows<LieGroup2::NV>());
209 template<
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
210 void dIntegrateTransport_dv_impl(
211 const Eigen::MatrixBase<Config_t> & q,
212 const Eigen::MatrixBase<Tangent_t> & v,
213 const Eigen::MatrixBase<JacobianIn_t> & J_in,
214 const Eigen::MatrixBase<JacobianOut_t> & J_out)
const
216 JacobianOut_t & Jout = PINOCCHIO_EIGEN_CONST_CAST(JacobianOut_t, J_out);
217 JacobianOut_t & Jin = PINOCCHIO_EIGEN_CONST_CAST(JacobianIn_t, J_in);
218 lg1.dIntegrateTransport_dv(
219 Q1(q), V1(v), Jin.template topRows<LieGroup1::NV>(),
220 Jout.template topRows<LieGroup1::NV>());
221 lg2.dIntegrateTransport_dv(
222 Q2(q), V2(v), Jin.template bottomRows<LieGroup2::NV>(),
223 Jout.template bottomRows<LieGroup2::NV>());
226 template<
class Config_t,
class Tangent_t,
class Jacobian_t>
227 void dIntegrateTransport_dq_impl(
228 const Eigen::MatrixBase<Config_t> & q,
229 const Eigen::MatrixBase<Tangent_t> & v,
230 const Eigen::MatrixBase<Jacobian_t> & Jin)
const
232 Jacobian_t & J = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, Jin);
233 lg1.dIntegrateTransport_dq(Q1(q), V1(v), J.template topRows<LieGroup1::NV>());
234 lg2.dIntegrateTransport_dq(Q2(q), V2(v), J.template bottomRows<LieGroup2::NV>());
237 template<
class Config_t,
class Tangent_t,
class Jacobian_t>
238 void dIntegrateTransport_dv_impl(
239 const Eigen::MatrixBase<Config_t> & q,
240 const Eigen::MatrixBase<Tangent_t> & v,
241 const Eigen::MatrixBase<Jacobian_t> & Jin)
const
243 Jacobian_t & J = PINOCCHIO_EIGEN_CONST_CAST(Jacobian_t, Jin);
244 lg1.dIntegrateTransport_dv(Q1(q), V1(v), J.template topRows<LieGroup1::NV>());
245 lg2.dIntegrateTransport_dv(Q2(q), V2(v), J.template bottomRows<LieGroup2::NV>());
248 template<
class ConfigL_t,
class ConfigR_t>
249 Scalar squaredDistance_impl(
250 const Eigen::MatrixBase<ConfigL_t> & q0,
const Eigen::MatrixBase<ConfigR_t> & q1)
const
252 return lg1.squaredDistance(Q1(q0), Q1(q1)) + lg2.squaredDistance(Q2(q0), Q2(q1));
255 template<
class Config_t>
256 void normalize_impl(
const Eigen::MatrixBase<Config_t> & qout)
const
258 lg1.normalize(Qo1(qout));
259 lg2.normalize(Qo2(qout));
262 template<
class Config_t>
263 bool isNormalized_impl(
const Eigen::MatrixBase<Config_t> & qin,
const Scalar & prec)
const
265 return lg1.isNormalized(Qo1(qin), prec) && lg2.isNormalized(Qo2(qin), prec);
268 template<
class Config_t>
269 void random_impl(
const Eigen::MatrixBase<Config_t> & qout)
const
271 lg1.random(Qo1(qout));
272 lg2.random(Qo2(qout));
275 template<
class ConfigL_t,
class ConfigR_t,
class ConfigOut_t>
276 void randomConfiguration_impl(
277 const Eigen::MatrixBase<ConfigL_t> & lower,
278 const Eigen::MatrixBase<ConfigR_t> & upper,
279 const Eigen::MatrixBase<ConfigOut_t> & qout)
const
281 lg1.randomConfiguration(Q1(lower), Q1(upper), Qo1(qout));
282 lg2.randomConfiguration(Q2(lower), Q2(upper), Qo2(qout));
285 template<
class ConfigL_t,
class ConfigR_t>
286 bool isSameConfiguration_impl(
287 const Eigen::MatrixBase<ConfigL_t> & q0,
288 const Eigen::MatrixBase<ConfigR_t> & q1,
289 const Scalar & prec)
const
291 return lg1.isSameConfiguration(Q1(q0), Q1(q1), prec)
292 && lg2.isSameConfiguration(Q2(q0), Q2(q1), prec);
297 return lg1 == other.lg1 && lg2 == other.lg2;
306 #if EIGEN_VERSION_AT_LEAST(3, 2, 1)
307 #define REMOVE_IF_EIGEN_TOO_LOW(x) x
309 #define REMOVE_IF_EIGEN_TOO_LOW(x)
312 template<
typename Config>
313 typename Config ::template ConstFixedSegmentReturnType<LieGroup1::NQ>::Type
314 Q1(
const Eigen::MatrixBase<Config> & q)
const
316 return q.derived().template head<LieGroup1::NQ>(REMOVE_IF_EIGEN_TOO_LOW(lg1.nq()));
318 template<
typename Config>
319 typename Config ::template ConstFixedSegmentReturnType<LieGroup2::NQ>::Type
320 Q2(
const Eigen::MatrixBase<Config> & q)
const
322 return q.derived().template tail<LieGroup2::NQ>(REMOVE_IF_EIGEN_TOO_LOW(lg2.nq()));
324 template<
typename Tangent>
325 typename Tangent::template ConstFixedSegmentReturnType<LieGroup1::NV>::Type
326 V1(
const Eigen::MatrixBase<Tangent> & v)
const
328 return v.derived().template head<LieGroup1::NV>(REMOVE_IF_EIGEN_TOO_LOW(lg1.nv()));
330 template<
typename Tangent>
331 typename Tangent::template ConstFixedSegmentReturnType<LieGroup2::NV>::Type
332 V2(
const Eigen::MatrixBase<Tangent> & v)
const
334 return v.derived().template tail<LieGroup2::NV>(REMOVE_IF_EIGEN_TOO_LOW(lg2.nv()));
337 template<
typename Config>
338 typename Config ::template FixedSegmentReturnType<LieGroup1::NQ>::Type
339 Qo1(
const Eigen::MatrixBase<Config> & q)
const
341 return PINOCCHIO_EIGEN_CONST_CAST(Config, q).template head<LieGroup1::NQ>(
342 REMOVE_IF_EIGEN_TOO_LOW(lg1.nq()));
344 template<
typename Config>
345 typename Config ::template FixedSegmentReturnType<LieGroup2::NQ>::Type
346 Qo2(
const Eigen::MatrixBase<Config> & q)
const
348 return PINOCCHIO_EIGEN_CONST_CAST(Config, q).template tail<LieGroup2::NQ>(
349 REMOVE_IF_EIGEN_TOO_LOW(lg2.nq()));
351 template<
typename Tangent>
352 typename Tangent::template FixedSegmentReturnType<LieGroup1::NV>::Type
353 Vo1(
const Eigen::MatrixBase<Tangent> & v)
const
355 return PINOCCHIO_EIGEN_CONST_CAST(Tangent, v)
356 .template head<LieGroup1::NV>(REMOVE_IF_EIGEN_TOO_LOW(lg1.nv()));
358 template<
typename Tangent>
359 typename Tangent::template FixedSegmentReturnType<LieGroup2::NV>::Type
360 Vo2(
const Eigen::MatrixBase<Tangent> & v)
const
362 return PINOCCHIO_EIGEN_CONST_CAST(Tangent, v)
363 .template tail<LieGroup2::NV>(REMOVE_IF_EIGEN_TOO_LOW(lg2.nv()));
366 template<
typename Jac>
367 Eigen::Block<Jac, LieGroup1::NV, LieGroup1::NV> J11(
const Eigen::MatrixBase<Jac> & J)
const
369 return PINOCCHIO_EIGEN_CONST_CAST(Jac, J)
370 .template topLeftCorner<LieGroup1::NV, LieGroup1::NV>(lg1.nv(), lg1.nv());
372 template<
typename Jac>
373 Eigen::Block<Jac, LieGroup1::NV, LieGroup2::NV> J12(
const Eigen::MatrixBase<Jac> & J)
const
375 return PINOCCHIO_EIGEN_CONST_CAST(Jac, J)
376 .template topRightCorner<LieGroup1::NV, LieGroup2::NV>(lg1.nv(), lg2.nv());
378 template<
typename Jac>
379 Eigen::Block<Jac, LieGroup2::NV, LieGroup1::NV> J21(
const Eigen::MatrixBase<Jac> & J)
const
381 return PINOCCHIO_EIGEN_CONST_CAST(Jac, J)
382 .template bottomLeftCorner<LieGroup2::NV, LieGroup1::NV>(lg2.nv(), lg1.nv());
384 template<
typename Jac>
385 Eigen::Block<Jac, LieGroup2::NV, LieGroup2::NV> J22(
const Eigen::MatrixBase<Jac> & J)
const
387 return PINOCCHIO_EIGEN_CONST_CAST(Jac, J)
388 .template bottomRightCorner<LieGroup2::NV, LieGroup2::NV>(lg2.nv(), lg2.nv());
390 #undef REMOVE_IF_EIGEN_TOO_LOW
Main pinocchio namespace.
Common traits structure to fully define base classes for CRTP.