pinocchio  UNKNOWN
cartesian-product.hpp
1 //
2 // Copyright (c) 2016-2018 CNRS
3 //
4 // This file is part of Pinocchio
5 // Pinocchio is free software: you can redistribute it
6 // and/or modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation, either version
8 // 3 of the License, or (at your option) any later version.
9 //
10 // Pinocchio is distributed in the hope that it will be
11 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Lesser Public License for more details. You should have
14 // received a copy of the GNU Lesser General Public License along with
15 // Pinocchio If not, see
16 // <http://www.gnu.org/licenses/>.
17 
18 #ifndef __se3_cartesian_product_operation_hpp__
19 #define __se3_cartesian_product_operation_hpp__
20 
21 #include <pinocchio/multibody/liegroup/operation-base.hpp>
22 
23 namespace se3
24 {
25  template<int dim1, int dim2>
26  struct eval_set_dim
27  {
28  enum { value = dim1 + dim2 };
29  };
30 
31  template<int dim>
32  struct eval_set_dim<dim,Eigen::Dynamic>
33  {
34  enum { value = Eigen::Dynamic };
35  };
36 
37  template<int dim>
38  struct eval_set_dim<Eigen::Dynamic,dim>
39  {
40  enum { value = Eigen::Dynamic };
41  };
42 
43  template<typename LieGroup1, typename LieGroup2>
45  template<typename LieGroup1, typename LieGroup2>
46  struct traits<CartesianProductOperation<LieGroup1, LieGroup2> > {
47  typedef double Scalar;
48  enum {
51  };
52  };
53 
54  template<typename LieGroup1, typename LieGroup2>
55  struct CartesianProductOperation : public LieGroupBase <CartesianProductOperation<LieGroup1, LieGroup2> >
56  {
57  SE3_LIE_GROUP_TPL_PUBLIC_INTERFACE(CartesianProductOperation);
58 
59  CartesianProductOperation () : lg1_ (), lg2_ ()
60  {
61  }
66  Index nq () const
67  {
68  return lg1_.nq () + lg2_.nq ();
69  }
71  Index nv () const
72  {
73  return lg1_.nv () + lg2_.nv ();
74  }
75 
76  ConfigVector_t neutral () const
77  {
78  ConfigVector_t n;
79  n.resize (nq ());
80  Qo1(n) = lg1_.neutral ();
81  Qo2(n) = lg2_.neutral ();
82  return n;
83  }
84 
85  std::string name () const
86  {
87  std::ostringstream oss; oss << lg1_.name () << "*" << lg2_.name ();
88  return oss.str ();
89  }
90 
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
95  {
96  lg1_.difference(Q1(q0), Q1(q1), Vo1(d));
97  lg2_.difference(Q2(q0), Q2(q1), Vo2(d));
98  }
99 
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
105  {
106  J12(J0).setZero();
107  J21(J0).setZero();
108 
109  J12(J1).setZero();
110  J21(J1).setZero();
111 
112  lg1_.Jdifference (Q1(q0), Q1(q1), J11(J0), J11(J1));
113  lg2_.Jdifference (Q2(q0), Q2(q1), J22(J0), J22(J1));
114  }
115 
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
120  {
121  lg1_.integrate(Q1(q), V1(v), Qo1(qout));
122  lg2_.integrate(Q2(q), V2(v), Qo2(qout));
123  }
124 
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
129  {
130  J12(J).setZero();
131  J21(J).setZero();
132  lg1_.dIntegrate_dq(Q1(q), V1(v), J11(J));
133  lg2_.dIntegrate_dq(Q2(q), V2(v), J22(J));
134  }
135 
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
140  {
141  J12(J).setZero();
142  J21(J).setZero();
143  lg1_.dIntegrate_dv(Q1(q), V1(v), J11(J));
144  lg2_.dIntegrate_dv(Q2(q), V2(v), J22(J));
145  }
146 
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
150  {
151  return lg1_.squaredDistance(Q1(q0), Q1(q1))
152  + lg2_.squaredDistance(Q2(q0), Q2(q1));
153  }
154 
155  template <class Config_t>
156  void normalize_impl (const Eigen::MatrixBase<Config_t>& qout) const
157  {
158  lg1_.normalize(Qo1(qout));
159  lg2_.normalize(Qo2(qout));
160  }
161 
162  template <class Config_t>
163  void random_impl (const Eigen::MatrixBase<Config_t>& qout) const
164  {
165  lg1_.random(Qo1(qout));
166  lg2_.random(Qo2(qout));
167  }
168 
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)
173  const
174  {
175  lg1_.randomConfiguration(Q1(lower), Q1(upper), Qo1(qout));
176  lg2_.randomConfiguration(Q2(lower), Q2(upper), Qo2(qout));
177  }
178 
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
183  {
184  return lg1_.isSameConfiguration(Q1(q0), Q1(q1), prec)
185  && lg2_.isSameConfiguration(Q2(q0), Q2(q1), prec);
186  }
187  private:
188  LieGroup1 lg1_;
189  LieGroup2 lg2_;
190 
191  // VectorSpaceOperation<-1> within CartesianProductOperation will not work
192  // if Eigen version is lower than 3.2.1
193 #if EIGEN_VERSION_AT_LEAST(3,2,1)
194 # define REMOVE_IF_EIGEN_TOO_LOW(x) x
195 #else
196 # define REMOVE_IF_EIGEN_TOO_LOW(x)
197 #endif
198 
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())); }
203 
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())); }
208 
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
214 
215  }; // struct CartesianProductOperation
216 
217 } // namespace se3
218 
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.