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>
21 enum {
value = Eigen::Dynamic };
27 enum {
value = Eigen::Dynamic };
30 template<
typename LieGroup1,
typename LieGroup2>
33 template<
typename LieGroup1,
typename LieGroup2>
43 template<
typename LieGroup1,
typename LieGroup2>
57 return lg1.nq () + lg2.nq ();
63 return lg1.nv () + lg2.nv ();
70 Qo1(n) = lg1.neutral ();
71 Qo2(n) = lg2.neutral ();
77 std::ostringstream oss; oss << lg1.name () <<
"*" << lg2.name ();
81 template <
class ConfigL_t,
class ConfigR_t,
class Tangent_t>
83 const Eigen::MatrixBase<ConfigR_t> &
q1,
84 const Eigen::MatrixBase<Tangent_t> &
d)
const 86 lg1.difference(
Q1(q0),
Q1(q1), Vo1(d));
87 lg2.difference(
Q2(q0),
Q2(q1), Vo2(d));
90 template <ArgumentPosition arg,
class ConfigL_t,
class ConfigR_t,
class JacobianOut_t>
92 const Eigen::MatrixBase<ConfigR_t> &
q1,
93 const Eigen::MatrixBase<JacobianOut_t> &
J)
const 98 lg1.template dDifference<arg> (
Q1(q0),
Q1(q1), J11(J));
99 lg2.template dDifference<arg> (
Q2(q0),
Q2(q1), J22(J));
102 template <
class ConfigIn_t,
class Velocity_t,
class ConfigOut_t>
104 const Eigen::MatrixBase<Velocity_t> &
v,
105 const Eigen::MatrixBase<ConfigOut_t> & qout)
const 107 lg1.integrate(
Q1(q), V1(v), Qo1(qout));
108 lg2.integrate(
Q2(q), V2(v), Qo2(qout));
111 template <
class Config_t,
class Jacobian_t>
113 const Eigen::MatrixBase<Jacobian_t> &
J)
const 115 assert(J.rows() ==
nq() && J.cols() ==
nv() &&
"J is not of the right dimension");
117 J_.topRightCorner(lg1.nq(),lg2.nv()).
setZero();
118 J_.bottomLeftCorner(lg2.nq(),lg1.nv()).
setZero();
120 lg1.integrateCoeffWiseJacobian(
Q1(q),
121 J_.topLeftCorner(lg1.nq(),lg1.nv()));
122 lg2.integrateCoeffWiseJacobian(
Q2(q), J_.bottomRightCorner(lg2.nq(),lg2.nv()));
125 template <
class Config_t,
class Tangent_t,
class JacobianOut_t>
127 const Eigen::MatrixBase<Tangent_t> &
v,
128 const Eigen::MatrixBase<JacobianOut_t> &
J,
139 lg1.dIntegrate_dq(
Q1(q), V1(v), J11(J),op);
140 lg2.dIntegrate_dq(
Q2(q), V2(v), J22(J),op);
143 assert(
false &&
"Wrong Op requesed value");
148 template <
class Config_t,
class Tangent_t,
class JacobianOut_t>
150 const Eigen::MatrixBase<Tangent_t> &
v,
151 const Eigen::MatrixBase<JacobianOut_t> &
J,
162 lg1.dIntegrate_dv(
Q1(q), V1(v), J11(J),op);
163 lg2.dIntegrate_dv(
Q2(q), V2(v), J22(J),op);
166 assert(
false &&
"Wrong Op requesed value");
171 template <
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
173 const Eigen::MatrixBase<Tangent_t> &
v,
174 const Eigen::MatrixBase<JacobianIn_t> & J_in,
175 const Eigen::MatrixBase<JacobianOut_t> & J_out)
const 179 lg1.dIntegrateTransport_dq(
Q1(q), V1(v), Jin.template topRows<LieGroup1::NV>(),Jout.template topRows<LieGroup1::NV>());
180 lg2.dIntegrateTransport_dq(
Q2(q), V2(v), Jin.template bottomRows<LieGroup2::NV>(),Jout.template bottomRows<LieGroup2::NV>());
183 template <
class Config_t,
class Tangent_t,
class JacobianIn_t,
class JacobianOut_t>
185 const Eigen::MatrixBase<Tangent_t> &
v,
186 const Eigen::MatrixBase<JacobianIn_t> & J_in,
187 const Eigen::MatrixBase<JacobianOut_t> & J_out)
const 191 lg1.dIntegrateTransport_dv(
Q1(q), V1(v), Jin.template topRows<LieGroup1::NV>(),Jout.template topRows<LieGroup1::NV>());
192 lg2.dIntegrateTransport_dv(
Q2(q), V2(v), Jin.template bottomRows<LieGroup2::NV>(),Jout.template bottomRows<LieGroup2::NV>());
196 template <
class Config_t,
class Tangent_t,
class Jacobian_t>
198 const Eigen::MatrixBase<Tangent_t> &
v,
199 const Eigen::MatrixBase<Jacobian_t> & Jin)
const 202 lg1.dIntegrateTransport_dq(
Q1(q), V1(v), J.template topRows<LieGroup1::NV>());
203 lg2.dIntegrateTransport_dq(
Q2(q), V2(v), J.template bottomRows<LieGroup2::NV>());
206 template <
class Config_t,
class Tangent_t,
class Jacobian_t>
208 const Eigen::MatrixBase<Tangent_t> &
v,
209 const Eigen::MatrixBase<Jacobian_t> & Jin)
const 212 lg1.dIntegrateTransport_dv(
Q1(q), V1(v), J.template topRows<LieGroup1::NV>());
213 lg2.dIntegrateTransport_dv(
Q2(q), V2(v), J.template bottomRows<LieGroup2::NV>());
216 template <
class ConfigL_t,
class ConfigR_t>
218 const Eigen::MatrixBase<ConfigR_t> &
q1)
const 220 return lg1.squaredDistance(
Q1(q0),
Q1(q1))
221 + lg2.squaredDistance(
Q2(q0),
Q2(q1));
224 template <
class Config_t>
227 lg1.normalize(Qo1(qout));
228 lg2.normalize(Qo2(qout));
231 template <
class Config_t>
234 return lg1.isNormalized(Qo1(qin), prec) && lg2.isNormalized(Qo2(qin), prec);
237 template <
class Config_t>
240 lg1.random(Qo1(qout));
241 lg2.random(Qo2(qout));
244 template <
class ConfigL_t,
class ConfigR_t,
class ConfigOut_t>
246 const Eigen::MatrixBase<ConfigR_t> & upper,
247 const Eigen::MatrixBase<ConfigOut_t> & qout)
250 lg1.randomConfiguration(
Q1(lower),
Q1(upper), Qo1(qout));
251 lg2.randomConfiguration(
Q2(lower),
Q2(upper), Qo2(qout));
254 template <
class ConfigL_t,
class ConfigR_t>
256 const Eigen::MatrixBase<ConfigR_t> &
q1,
257 const Scalar & prec)
const 259 return lg1.isSameConfiguration(
Q1(q0),
Q1(q1), prec)
260 && lg2.isSameConfiguration(
Q2(q0),
Q2(q1), prec);
265 return lg1 == other.
lg1 && lg2 == other.
lg2;
274 #if EIGEN_VERSION_AT_LEAST(3,2,1) 275 # define REMOVE_IF_EIGEN_TOO_LOW(x) x 277 # define REMOVE_IF_EIGEN_TOO_LOW(x) 280 template <
typename Config >
typename Config ::template ConstFixedSegmentReturnType<LieGroup1::NQ>::Type
Q1 (
const Eigen::MatrixBase<Config >&
q)
const {
return q.derived().template head<LieGroup1::NQ>(
REMOVE_IF_EIGEN_TOO_LOW(lg1.nq())); }
281 template <
typename Config >
typename Config ::template ConstFixedSegmentReturnType<LieGroup2::NQ>::Type
Q2 (
const Eigen::MatrixBase<Config >&
q)
const {
return q.derived().template tail<LieGroup2::NQ>(
REMOVE_IF_EIGEN_TOO_LOW(lg2.nq())); }
282 template <
typename Tangent>
typename Tangent::template ConstFixedSegmentReturnType<LieGroup1::NV>::Type
V1 (
const Eigen::MatrixBase<Tangent>&
v)
const {
return v.derived().template head<LieGroup1::NV>(
REMOVE_IF_EIGEN_TOO_LOW(lg1.nv())); }
283 template <
typename Tangent>
typename Tangent::template ConstFixedSegmentReturnType<LieGroup2::NV>::Type
V2 (
const Eigen::MatrixBase<Tangent>&
v)
const {
return v.derived().template tail<LieGroup2::NV>(
REMOVE_IF_EIGEN_TOO_LOW(lg2.nv())); }
290 template <
typename Jac> Eigen::Block<Jac, LieGroup1::NV, LieGroup1::NV>
J11 (
const Eigen::MatrixBase<Jac>&
J)
const {
return PINOCCHIO_EIGEN_CONST_CAST(Jac,J).template topLeftCorner<LieGroup1::NV, LieGroup1::NV>(lg1.nv(),lg1.nv()); }
291 template <
typename Jac> Eigen::Block<Jac, LieGroup1::NV, LieGroup2::NV>
J12 (
const Eigen::MatrixBase<Jac>&
J)
const {
return PINOCCHIO_EIGEN_CONST_CAST(Jac,J).template topRightCorner<LieGroup1::NV, LieGroup2::NV>(lg1.nv(),lg2.nv()); }
292 template <
typename Jac> Eigen::Block<Jac, LieGroup2::NV, LieGroup1::NV>
J21 (
const Eigen::MatrixBase<Jac>&
J)
const {
return PINOCCHIO_EIGEN_CONST_CAST(Jac,J).template bottomLeftCorner<LieGroup2::NV, LieGroup1::NV>(lg2.nv(),lg1.nv()); }
293 template <
typename Jac> Eigen::Block<Jac, LieGroup2::NV, LieGroup2::NV>
J22 (
const Eigen::MatrixBase<Jac>&
J)
const {
return PINOCCHIO_EIGEN_CONST_CAST(Jac,J).template bottomRightCorner<LieGroup2::NV, LieGroup2::NV>(lg2.nv(),lg2.nv()); }
294 #undef REMOVE_IF_EIGEN_TOO_LOW 300 #endif // ifndef __pinocchio_multibody_liegroup_cartesian_product_operation_hpp__ Eigen::Block< Jac, LieGroup2::NV, LieGroup1::NV > J21(const Eigen::MatrixBase< Jac > &J) const
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorType > const Eigen::MatrixBase< TangentVectorType > & v
int nv(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNvVisitor to get the dimension of the joint tangent space...
Eigen::Matrix< Scalar, NQ, 1, Options > ConfigVector_t
Eigen::Block< Jac, LieGroup2::NV, LieGroup2::NV > J22(const Eigen::MatrixBase< Jac > &J) const
Eigen::Block< Jac, LieGroup1::NV, LieGroup2::NV > J12(const Eigen::MatrixBase< Jac > &J) const
int nq(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNqVisitor to get the dimension of the joint configuration space...
CartesianProductOperation()
void normalize_impl(const Eigen::MatrixBase< Config_t > &qout) const
Eigen::Block< Jac, LieGroup1::NV, LieGroup1::NV > J11(const Eigen::MatrixBase< Jac > &J) const
Scalar squaredDistance_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1) const
#define PINOCCHIO_LIE_GROUP_TPL_PUBLIC_INTERFACE(Derived)
traits< LieGroupDerived >::Scalar Scalar
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorType > & q
#define PINOCCHIO_EIGEN_CONST_CAST(TYPE, OBJ)
Macro for an automatic const_cast.
Config ::template ConstFixedSegmentReturnType< LieGroup1::NQ >::Type Q1(const Eigen::MatrixBase< Config > &q) const
void integrate_impl(const Eigen::MatrixBase< ConfigIn_t > &q, const Eigen::MatrixBase< Velocity_t > &v, const Eigen::MatrixBase< ConfigOut_t > &qout) const
Tangent::template FixedSegmentReturnType< LieGroup1::NV >::Type Vo1(const Eigen::MatrixBase< Tangent > &v) const
void dDifference_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1, const Eigen::MatrixBase< JacobianOut_t > &J) const
void integrateCoeffWiseJacobian_impl(const Eigen::MatrixBase< Config_t > &q, const Eigen::MatrixBase< Jacobian_t > &J) const
bool isSameConfiguration_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1, const Scalar &prec) const
void dIntegrateTransport_dq_impl(const Eigen::MatrixBase< Config_t > &q, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< Jacobian_t > &Jin) const
bool isEqual_impl(const CartesianProductOperation &other) const
void dIntegrateTransport_dv_impl(const Eigen::MatrixBase< Config_t > &q, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< JacobianIn_t > &J_in, const Eigen::MatrixBase< JacobianOut_t > &J_out) const
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorIn1 > const Eigen::MatrixBase< ConfigVectorIn2 > & q1
traits< LieGroup1 >::Scalar Scalar
Tangent::template ConstFixedSegmentReturnType< LieGroup2::NV >::Type V2(const Eigen::MatrixBase< Tangent > &v) const
void random_impl(const Eigen::MatrixBase< Config_t > &qout) const
#define REMOVE_IF_EIGEN_TOO_LOW(x)
ConfigVector_t neutral() const
Tangent::template FixedSegmentReturnType< LieGroup2::NV >::Type Vo2(const Eigen::MatrixBase< Tangent > &v) const
Main pinocchio namespace.
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorIn1 > & q0
void difference_impl(const Eigen::MatrixBase< ConfigL_t > &q0, const Eigen::MatrixBase< ConfigR_t > &q1, const Eigen::MatrixBase< Tangent_t > &d) const
void setZero(std::vector< MatType, Eigen::aligned_allocator< MatType > > &Ms)
Tangent::template ConstFixedSegmentReturnType< LieGroup1::NV >::Type V1(const Eigen::MatrixBase< Tangent > &v) const
Common traits structure to fully define base classes for CRTP.
void randomConfiguration_impl(const Eigen::MatrixBase< ConfigL_t > &lower, const Eigen::MatrixBase< ConfigR_t > &upper, const Eigen::MatrixBase< ConfigOut_t > &qout) const
void dIntegrateTransport_dv_impl(const Eigen::MatrixBase< Config_t > &q, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< Jacobian_t > &Jin) const
void dIntegrate_dv_impl(const Eigen::MatrixBase< Config_t > &q, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< JacobianOut_t > &J, const AssignmentOperatorType op=SETTO) const
bool isNormalized_impl(const Eigen::MatrixBase< Config_t > &qin, const Scalar &prec) const
void dIntegrateTransport_dq_impl(const Eigen::MatrixBase< Config_t > &q, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< JacobianIn_t > &J_in, const Eigen::MatrixBase< JacobianOut_t > &J_out) const
Config ::template FixedSegmentReturnType< LieGroup2::NQ >::Type Qo2(const Eigen::MatrixBase< Config > &q) const
void dIntegrate_dq_impl(const Eigen::MatrixBase< Config_t > &q, const Eigen::MatrixBase< Tangent_t > &v, const Eigen::MatrixBase< JacobianOut_t > &J, const AssignmentOperatorType op=SETTO) const
Config ::template FixedSegmentReturnType< LieGroup1::NQ >::Type Qo1(const Eigen::MatrixBase< Config > &q) const
Config ::template ConstFixedSegmentReturnType< LieGroup2::NQ >::Type Q2(const Eigen::MatrixBase< Config > &q) const