18 #ifndef __se3_cartesian_product_operation_hpp__ 19 #define __se3_cartesian_product_operation_hpp__ 21 #include <pinocchio/multibody/liegroup/operation-base.hpp> 25 template<
int dim1,
int dim2>
28 enum { value = dim1 + dim2 };
34 enum { value = Eigen::Dynamic };
40 enum { value = Eigen::Dynamic };
43 template<
typename LieGroup1,
typename LieGroup2>
45 template<
typename LieGroup1,
typename LieGroup2>
47 typedef double Scalar;
54 template<
typename LieGroup1,
typename LieGroup2>
68 return lg1_.nq () + lg2_.nq ();
73 return lg1_.nv () + lg2_.nv ();
80 Qo1(n) = lg1_.neutral ();
81 Qo2(n) = lg2_.neutral ();
85 std::string
name ()
const 87 std::ostringstream oss; oss << lg1_.name () <<
"*" << lg2_.name ();
91 template <
class ConfigL_t,
class ConfigR_t,
class Tangent_t>
92 void difference_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
93 const Eigen::MatrixBase<ConfigR_t> & q1,
94 const Eigen::MatrixBase<Tangent_t> & d)
const 96 lg1_.difference(Q1(q0), Q1(q1), Vo1(d));
97 lg2_.difference(Q2(q0), Q2(q1), Vo2(d));
100 template <
class ConfigL_t,
class ConfigR_t,
class JacobianLOut_t,
class JacobianROut_t>
101 void Jdifference_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
102 const Eigen::MatrixBase<ConfigR_t> & q1,
103 const Eigen::MatrixBase<JacobianLOut_t>& J0,
104 const Eigen::MatrixBase<JacobianROut_t>& J1)
const 112 lg1_.Jdifference (Q1(q0), Q1(q1), J11(J0), J11(J1));
113 lg2_.Jdifference (Q2(q0), Q2(q1), J22(J0), J22(J1));
116 template <
class ConfigIn_t,
class Velocity_t,
class ConfigOut_t>
117 void integrate_impl(
const Eigen::MatrixBase<ConfigIn_t> & q,
118 const Eigen::MatrixBase<Velocity_t> & v,
119 const Eigen::MatrixBase<ConfigOut_t> & qout)
const 121 lg1_.integrate(Q1(q), V1(v), Qo1(qout));
122 lg2_.integrate(Q2(q), V2(v), Qo2(qout));
125 template <
class Config_t,
class Tangent_t,
class JacobianOut_t>
126 void dIntegrate_dq_impl(
const Eigen::MatrixBase<Config_t > & q,
127 const Eigen::MatrixBase<Tangent_t> & v,
128 const Eigen::MatrixBase<JacobianOut_t> & J)
const 132 lg1_.dIntegrate_dq(Q1(q), V1(v), J11(J));
133 lg2_.dIntegrate_dq(Q2(q), V2(v), J22(J));
136 template <
class Config_t,
class Tangent_t,
class JacobianOut_t>
137 void dIntegrate_dv_impl(
const Eigen::MatrixBase<Config_t > & q,
138 const Eigen::MatrixBase<Tangent_t> & v,
139 const Eigen::MatrixBase<JacobianOut_t> & J)
const 143 lg1_.dIntegrate_dv(Q1(q), V1(v), J11(J));
144 lg2_.dIntegrate_dv(Q2(q), V2(v), J22(J));
147 template <
class ConfigL_t,
class ConfigR_t>
148 Scalar squaredDistance_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
149 const Eigen::MatrixBase<ConfigR_t> & q1)
const 151 return lg1_.squaredDistance(Q1(q0), Q1(q1))
152 + lg2_.squaredDistance(Q2(q0), Q2(q1));
155 template <
class Config_t>
156 void normalize_impl (
const Eigen::MatrixBase<Config_t>& qout)
const 158 lg1_.normalize(Qo1(qout));
159 lg2_.normalize(Qo2(qout));
162 template <
class Config_t>
163 void random_impl (
const Eigen::MatrixBase<Config_t>& qout)
const 165 lg1_.random(Qo1(qout));
166 lg2_.random(Qo2(qout));
169 template <
class ConfigL_t,
class ConfigR_t,
class ConfigOut_t>
170 void randomConfiguration_impl(
const Eigen::MatrixBase<ConfigL_t> & lower,
171 const Eigen::MatrixBase<ConfigR_t> & upper,
172 const Eigen::MatrixBase<ConfigOut_t> & qout)
175 lg1_.randomConfiguration(Q1(lower), Q1(upper), Qo1(qout));
176 lg2_.randomConfiguration(Q2(lower), Q2(upper), Qo2(qout));
179 template <
class ConfigL_t,
class ConfigR_t>
180 bool isSameConfiguration_impl(
const Eigen::MatrixBase<ConfigL_t> & q0,
181 const Eigen::MatrixBase<ConfigR_t> & q1,
182 const Scalar & prec)
const 184 return lg1_.isSameConfiguration(Q1(q0), Q1(q1), prec)
185 && lg2_.isSameConfiguration(Q2(q0), Q2(q1), prec);
193 #if EIGEN_VERSION_AT_LEAST(3,2,1) 194 # define REMOVE_IF_EIGEN_TOO_LOW(x) x 196 # define REMOVE_IF_EIGEN_TOO_LOW(x) 199 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())); }
200 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())); }
201 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())); }
202 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())); }
204 template <
typename Config >
typename Config ::template FixedSegmentReturnType<LieGroup1::NQ>::Type Qo1 (
const Eigen::MatrixBase<Config >& q)
const {
return const_cast<Config &
>(q.derived()).
template head<LieGroup1::NQ>(REMOVE_IF_EIGEN_TOO_LOW(lg1_.nq())); }
205 template <
typename Config >
typename Config ::template FixedSegmentReturnType<LieGroup2::NQ>::Type Qo2 (
const Eigen::MatrixBase<Config >& q)
const {
return const_cast<Config &
>(q.derived()).
template tail<LieGroup2::NQ>(REMOVE_IF_EIGEN_TOO_LOW(lg2_.nq())); }
206 template <
typename Tangent>
typename Tangent::template FixedSegmentReturnType<LieGroup1::NV>::Type Vo1 (
const Eigen::MatrixBase<Tangent>& v)
const {
return const_cast<Tangent&
>(v.derived()).
template head<LieGroup1::NV>(REMOVE_IF_EIGEN_TOO_LOW(lg1_.nv())); }
207 template <
typename Tangent>
typename Tangent::template FixedSegmentReturnType<LieGroup2::NV>::Type Vo2 (
const Eigen::MatrixBase<Tangent>& v)
const {
return const_cast<Tangent&
>(v.derived()).
template tail<LieGroup2::NV>(REMOVE_IF_EIGEN_TOO_LOW(lg2_.nv())); }
209 template <
typename Jac> Eigen::Block<Jac, LieGroup1::NV, LieGroup1::NV> J11 (
const Eigen::MatrixBase<Jac>& J)
const {
return const_cast<Jac&
>(J.derived()).
template topLeftCorner<LieGroup1::NV, LieGroup1::NV>(lg1_.nv(),lg1_.nv()); }
210 template <
typename Jac> Eigen::Block<Jac, LieGroup1::NV, LieGroup2::NV> J12 (
const Eigen::MatrixBase<Jac>& J)
const {
return const_cast<Jac&
>(J.derived()).
template topRightCorner<LieGroup1::NV, LieGroup2::NV>(lg1_.nv(),lg2_.nv()); }
211 template <
typename Jac> Eigen::Block<Jac, LieGroup2::NV, LieGroup1::NV> J21 (
const Eigen::MatrixBase<Jac>& J)
const {
return const_cast<Jac&
>(J.derived()).
template bottomLeftCorner<LieGroup2::NV, LieGroup1::NV>(lg2_.nv(),lg1_.nv()); }
212 template <
typename Jac> Eigen::Block<Jac, LieGroup2::NV, LieGroup2::NV> J22 (
const Eigen::MatrixBase<Jac>& J)
const {
return const_cast<Jac&
>(J.derived()).
template bottomRightCorner<LieGroup2::NV, LieGroup2::NV>(lg2_.nv(),lg2_.nv()); }
213 #undef REMOVE_IF_EIGEN_TOO_LOW 219 #endif // ifndef __se3_cartesian_product_operation_hpp__
std::string name(const LieGroupVariant &lg)
Visit a LieGroupVariant to get the name of it.
Eigen::VectorXd neutral(const Model &model)
Return the neutral configuration element related to the model configuration space.
int nq(const JointModelVariant &jmodel)
Visit a JointModelVariant through JointNqVisitor to get the dimension of the joint configuration spac...
Index nv() const
Get dimension of Lie Group tangent space.