pinocchio  UNKNOWN
jacobian.hxx
1 //
2 // Copyright (c) 2015-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_jacobian_hxx__
19 #define __se3_jacobian_hxx__
20 
21 #include "pinocchio/multibody/visitor.hpp"
22 #include "pinocchio/algorithm/check.hpp"
23 
25 
26 namespace se3
27 {
28  struct JointJacobiansForwardStep : public fusion::JointVisitor<JointJacobiansForwardStep>
29  {
30  typedef boost::fusion::vector <const se3::Model &,
31  se3::Data &,
32  const Eigen::VectorXd &
33  > ArgsType;
34 
35  JOINT_VISITOR_INIT(JointJacobiansForwardStep);
36 
37  template<typename JointModel>
38  static void algo(const se3::JointModelBase<JointModel> & jmodel,
40  const se3::Model & model,
41  se3::Data & data,
42  const Eigen::VectorXd & q)
43  {
44  const Model::JointIndex & i = (Model::JointIndex) jmodel.id();
45  const Model::JointIndex & parent = model.parents[i];
46 
47  jmodel.calc(jdata.derived(),q);
48 
49  data.liMi[i] = model.jointPlacements[i]*jdata.M();
50  if(parent>0) data.oMi[i] = data.oMi[parent]*data.liMi[i];
51  else data.oMi[i] = data.liMi[i];
52 
53  jmodel.jointCols(data.J) = data.oMi[i].act(jdata.S());
54  }
55 
56  };
57 
58  inline const Data::Matrix6x &
59  computeJointJacobians(const Model & model, Data & data,
60  const Eigen::VectorXd & q)
61  {
62  assert(model.check(data) && "data is not consistent with model.");
63 
64  for( Model::JointIndex i=1; i< (Model::JointIndex) model.njoints;++i )
65  {
66  JointJacobiansForwardStep::run(model.joints[i],data.joints[i],
67  JointJacobiansForwardStep::ArgsType(model,data,q));
68  }
69 
70  return data.J;
71  }
72 
73  struct JointJacobiansForwardStep2 : public fusion::JointVisitor<JointJacobiansForwardStep2>
74  {
75  typedef boost::fusion::vector<se3::Data &> ArgsType;
76 
77  JOINT_VISITOR_INIT(JointJacobiansForwardStep2);
78 
79  template<typename JointModel>
80  static void algo(const se3::JointModelBase<JointModel> & jmodel,
82  se3::Data & data)
83  {
84  const Model::JointIndex & i = (Model::JointIndex) jmodel.id();
85 
86  jmodel.jointCols(data.J) = data.oMi[i].act(jdata.S());
87  }
88 
89  };
90 
91  inline const Data::Matrix6x &
92  computeJointJacobians(const Model & model, Data & data)
93  {
94  assert(model.check(data) && "data is not consistent with model.");
95 
96  for( Model::JointIndex i=1; i< (Model::JointIndex) model.njoints;++i )
97  {
98  JointJacobiansForwardStep2::run(model.joints[i],data.joints[i],
99  JointJacobiansForwardStep2::ArgsType(data));
100  }
101 
102  return data.J;
103  }
104 
105  /* Return the jacobian of the output frame attached to joint <jointId> in the
106  world frame or in the local frame depending on the template argument. The
107  function computeJacobians should have been called first. */
108  template<ReferenceFrame rf>
109  void getJointJacobian(const Model & model,
110  const Data & data,
111  const Model::JointIndex jointId,
112  Data::Matrix6x & J)
113  {
114  assert( J.rows() == data.J.rows() );
115  assert( J.cols() == data.J.cols() );
116  assert(model.check(data) && "data is not consistent with model.");
117 
118  const SE3 & oMjoint = data.oMi[jointId];
119  int colRef = nv(model.joints[jointId])+idx_v(model.joints[jointId])-1;
120  for(int j=colRef;j>=0;j=data.parents_fromRow[(Model::Index)j])
121  {
122  if(rf == WORLD) J.col(j) = data.J.col(j);
123  else J.col(j) = oMjoint.actInv(Motion(data.J.col(j))).toVector();
124  }
125  }
126 
127 
128  struct JointJacobianForwardStep : public fusion::JointVisitor<JointJacobianForwardStep>
129  {
130  typedef boost::fusion::vector<const se3::Model &,
131  se3::Data &,
132  const Eigen::VectorXd &,
134  > ArgsType;
135 
136  JOINT_VISITOR_INIT(JointJacobianForwardStep);
137 
138  template<typename JointModel>
139  static void algo(const se3::JointModelBase<JointModel> & jmodel,
141  const se3::Model & model,
142  se3::Data & data,
143  const Eigen::VectorXd & q,
145  {
146  const Model::JointIndex & i = (Model::JointIndex) jmodel.id();
147  const Model::JointIndex & parent = model.parents[i];
148 
149  jmodel.calc(jdata.derived(),q);
150 
151  data.liMi[i] = model.jointPlacements[i]*jdata.M();
152  data.iMf[parent] = data.liMi[i]*data.iMf[i];
153 
154  jmodel.jointCols(J) = data.iMf[i].inverse().act(jdata.S());
155  }
156 
157  };
158 
159  inline void jointJacobian(const Model & model, Data & data,
160  const Eigen::VectorXd & q,
161  const Model::JointIndex jointId,
162  Data::Matrix6x & J)
163  {
164  assert(model.check(data) && "data is not consistent with model.");
165 
166  data.iMf[jointId].setIdentity();
167  for( Model::JointIndex i=jointId;i>0;i=model.parents[i] )
168  {
169  JointJacobianForwardStep::run(model.joints[i],data.joints[i],
170  JointJacobianForwardStep::ArgsType(model,data,q,J));
171  }
172  }
173 
174  struct JointJacobiansTimeVariationForwardStep : public fusion::JointVisitor<JointJacobiansTimeVariationForwardStep>
175  {
176  typedef boost::fusion::vector <const se3::Model &,
177  se3::Data &,
178  const Eigen::VectorXd &,
179  const Eigen::VectorXd &
180  > ArgsType;
181 
182  JOINT_VISITOR_INIT(JointJacobiansTimeVariationForwardStep);
183 
184  template<typename JointModel>
185  static void algo(const se3::JointModelBase<JointModel> & jmodel,
187  const se3::Model & model,
188  se3::Data & data,
189  const Eigen::VectorXd & q,
190  const Eigen::VectorXd & v)
191  {
192  const Model::JointIndex & i = (Model::JointIndex) jmodel.id();
193  const Model::JointIndex & parent = model.parents[i];
194 
195  SE3 & oMi = data.oMi[i];
196  Motion & vJ = data.v[i];
197 
198  jmodel.calc(jdata.derived(),q,v);
199 
200  vJ = jdata.v();
201 
202  data.liMi[i] = model.jointPlacements[i]*jdata.M();
203  if(parent>0)
204  {
205  oMi = data.oMi[parent]*data.liMi[i];
206  vJ += data.liMi[i].actInv(data.v[parent]);
207  }
208  else
209  {
210  oMi = data.liMi[i];
211  }
212 
213  jmodel.jointCols(data.J) = oMi.act(jdata.S());
214 
215  // Spatial velocity of joint i expressed in the global frame o
216  data.ov[i] = oMi.act(vJ);
217 
218  typedef typename SizeDepType<JointModel::NV>::template ColsReturn<Data::Matrix6x>::Type ColsBlock;
219  ColsBlock dJcols = jmodel.jointCols(data.dJ);
220  ColsBlock Jcols = jmodel.jointCols(data.J);
221 
222  motionSet::motionAction(data.ov[i],Jcols,dJcols);
223  }
224 
225  };
226 
227  inline const Data::Matrix6x &
229  Data & data,
230  const Eigen::VectorXd & q,
231  const Eigen::VectorXd & v)
232  {
233  assert(model.check(data) && "data is not consistent with model.");
234 
235  for(Model::JointIndex i=1; i< (Model::JointIndex) model.njoints;++i)
236  {
237  JointJacobiansTimeVariationForwardStep::run(model.joints[i],data.joints[i],
238  JointJacobiansTimeVariationForwardStep::ArgsType(model,data,q,v));
239  }
240 
241  return data.dJ;
242  }
243 
244  template<ReferenceFrame rf>
246  const Data & data,
247  const Model::JointIndex jointId,
248  Data::Matrix6x & dJ)
249  {
250  assert( dJ.rows() == data.dJ.rows() );
251  assert( dJ.cols() == data.dJ.cols() );
252  assert(model.check(data) && "data is not consistent with model.");
253 
254  const SE3 & oMjoint = data.oMi[jointId];
255  int colRef = nv(model.joints[jointId])+idx_v(model.joints[jointId])-1;
256  for(int j=colRef;j>=0;j=data.parents_fromRow[(Model::Index)j])
257  {
258  if(rf == WORLD) dJ.col(j) = data.dJ.col(j);
259  else dJ.col(j) = oMjoint.actInv(Motion(data.dJ.col(j))).toVector();
260  }
261  }
262 
263 
264 } // namespace se3
265 
267 
268 #endif // ifndef __se3_jacobian_hxx__
void getJointJacobianTimeVariation(const Model &model, const Data &data, const Model::JointIndex jointId, Data::Matrix6x &dJ)
Computes the Jacobian time variation of a specific joint frame expressed either in the world frame (r...
Definition: jacobian.hxx:245
container::aligned_vector< SE3 > jointPlacements
Placement (SE3) of the input of joint i regarding to the parent joint output li.
Definition: model.hpp:67
container::aligned_vector< SE3 > iMf
Vector of joint placements wrt to algorithm end effector.
Definition: data.hpp:244
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef Eigen::Matrix< double, 6, Eigen::Dynamic > Matrix6x
The 6d jacobian type (temporary)
Definition: data.hpp:45
JointModelVector joints
Model of joint i, encapsulated in a JointModelAccessor.
Definition: model.hpp:70
Matrix6x J
Jacobian of joint placements.
Definition: data.hpp:217
std::vector< JointIndex > parents
Joint parent of joint i, denoted li (li==parents[i]).
Definition: model.hpp:73
int nv(const JointModelVariant &jmodel)
Visit a JointModelVariant through JointNvVisitor to get the dimension of the joint tangent space...
container::aligned_vector< Motion > ov
Vector of joint velocities expressed at the origin.
Definition: data.hpp:70
const Data::Matrix6x & computeJointJacobiansTimeVariation(const Model &model, Data &data, const Eigen::VectorXd &q, const Eigen::VectorXd &v)
Computes the full model Jacobian variations with respect to time. It corresponds to dJ/dt which depen...
Definition: jacobian.hxx:228
Matrix6x dJ
Derivative of the Jacobian with respect to the time.
Definition: data.hpp:220
JointDataVector joints
Vector of se3::JointData associated to the se3::JointModel stored in model, encapsulated in JointData...
Definition: data.hpp:55
void getJointJacobian(const Model &model, const Data &data, const Model::JointIndex jointId, Data::Matrix6x &J)
Computes the Jacobian of a specific joint frame expressed either in the world (rf = WORLD) frame or i...
Definition: jacobian.hxx:109
container::aligned_vector< SE3 > liMi
Vector of relative joint placements (wrt the body parent).
Definition: data.hpp:90
container::aligned_vector< SE3 > oMi
Vector of absolute joint placements (wrt the world).
Definition: data.hpp:87
int idx_v(const JointModelVariant &jmodel)
Visit a JointModelVariant through JointIdxVVisitor to get the index in the full model tangent space c...
bool check(const AlgorithmCheckerBase< D > &checker=AlgorithmCheckerBase< D >()) const
Definition: model.hpp:331
internal::SE3GroupAction< D >::ReturnType act(const D &d) const
ay = aXb.act(by)
Definition: se3.hpp:94
void jointJacobian(const Model &model, Data &data, const Eigen::VectorXd &q, const Model::JointIndex jointId, Data::Matrix6x &J)
Computes the Jacobian of a specific joint frame expressed in the local frame of the joint and store t...
Definition: jacobian.hxx:159
std::vector< int > parents_fromRow
First previous non-zero row in M (used in Cholesky Decomposition).
Definition: data.hpp:210
const Data::Matrix6x & computeJointJacobians(const Model &model, Data &data, const Eigen::VectorXd &q)
Computes the full model Jacobian, i.e. the stack of all motion subspace expressed in the world frame...
Definition: jacobian.hxx:59
container::aligned_vector< Motion > v
Vector of joint velocities expressed at the centers of the joints.
Definition: data.hpp:67
int njoints
Number of joints.
Definition: model.hpp:55