ocra-recipes
Doxygen documentation for the ocra-recipes repository
Feature.cpp
Go to the documentation of this file.
1 #include "ocra/control/Feature.h"
2 
3 
4 #include <iostream>
5 
6 using namespace Eigen;
7 
8 namespace ocra
9 {
10  // --- ABSTRACT -----------------------------------------------
11 
12  Feature::Feature(const std::string& name)
13  : NamedInstance(name)
14  {
15  }
16 
18  {
19  }
20 
21 
22  // --- POSITION -----------------------------------------------
23 
25  {
26  ControlFrame::Ptr controlFrame;
28  MatrixXd u;
29  MatrixXd spaceTransform;
30  VectorXd error;
31  VectorXd errorDot;
32  VectorXd acceleration;
33  VectorXd effort;
34  MatrixXd jacobian;
35  MatrixXd M;
36  MatrixXd Minv;
37 
38  Pimpl(ControlFrame::Ptr cf, ECartesianDof a)
39  : controlFrame(cf), axes(a)
40  {
41  int dim = utils::computeDimensionFor(axes, NONE);
42 
43  u.resize(3, dim);
44  int k = 0;
45  if(axes & X)
46  u.col(k++) = Vector3d(1., 0., 0.);
47  if(axes & Y)
48  u.col(k++) = Vector3d(0., 1., 0.);
49  if(axes & Z)
50  u.col(k++) = Vector3d(0., 0., 1.);
51 
52  error = VectorXd::Zero(dim);
53  errorDot = VectorXd::Zero(dim);
54  effort = VectorXd::Zero(dim);
55  acceleration = VectorXd::Zero(dim);
56  jacobian = MatrixXd::Zero(dim, cf->getJacobian().cols());
57  }
58  };
59 
60  PositionFeature::PositionFeature(const std::string& name, ControlFrame::Ptr frame, ECartesianDof axes)
61  : Feature(name)
62  , pimpl(new Pimpl(frame, axes))
63  {
64 
65  }
66 
67  const MatrixXd& PositionFeature::getSpaceTransform() const
68  {
69  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
70  pimpl->spaceTransform = pimpl->u.transpose() * R.adjoint();
71  return pimpl->spaceTransform;
72  }
73 
75  {
76  return utils::computeDimensionFor(pimpl->axes, NONE);
77  }
78 
79  const VectorXd& PositionFeature::computeEffort(const Feature& featureDes) const
80  {
81  const PositionFeature& sdes = dynamic_cast<const PositionFeature&>(featureDes);
82 
83 // // first compute the linear velocity error in the mobile frame
84 // const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
85 // const Eigen::Displacementd::Rotation3D& Rdes = sdes.pimpl->controlFrame->getPosition().getRotation();
86 // const Eigen::Displacementd::Rotation3D Rdes_in_r = R.inverse() * Rdes;
87 // const Vector3d eff = pimpl->controlFrame->getWrench().getForce() - Rdes_in_r.adjoint() * sdes.pimpl->controlFrame->getWrench().getForce();
88 
89 // // then project it on the controlled axes
90 // pimpl->effort = getSpaceTransform() * eff;
91 
92  pimpl->effort = pimpl->u.transpose() * (pimpl->controlFrame->getWrench().getForce() - sdes.pimpl->controlFrame->getWrench().getForce());
93 
94  return pimpl->effort;
95  }
96 
97  const VectorXd& PositionFeature::computeEffort() const
98  {
99 // // first compute the linear velocity error in the mobile frame
100 // const Vector3d eff = pimpl->controlFrame->getWrench().getForce();
101 
102 // // then project it on the controlled axes
103 // pimpl->effort = getSpaceTransform() * eff;
104 
105  pimpl->effort = pimpl->u.transpose() * pimpl->controlFrame->getWrench().getForce();
106  return pimpl->effort;
107  }
108 
109  const VectorXd& PositionFeature::computeAcceleration(const Feature& featureDes) const
110  {
111  const PositionFeature& sdes = dynamic_cast<const PositionFeature&>(featureDes);
112 
113 // const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
114 // const Eigen::Displacementd::Rotation3D& Rdes = sdes.pimpl->controlFrame->getPosition().getRotation();
115 // const Eigen::Displacementd::Rotation3D Rdes_in_r = R.inverse() * Rdes;
116 // const VectorXd acc = pimpl->controlFrame->getAcceleration().getLinearVelocity() - Rdes_in_r.adjoint() * sdes.pimpl->controlFrame->getAcceleration().getLinearVelocity();
117 
118 // pimpl->acceleration = getSpaceTransform() * acc;
119 
120  pimpl->acceleration = pimpl->u.transpose() * (pimpl->controlFrame->getAcceleration().getLinearVelocity() - sdes.pimpl->controlFrame->getAcceleration().getLinearVelocity());
121  return pimpl->acceleration;
122  }
123 
124  const VectorXd& PositionFeature::computeAcceleration() const
125  {
126 // const VectorXd acc = pimpl->controlFrame->getAcceleration().getLinearVelocity();
127 // pimpl->acceleration = getSpaceTransform() * acc;
128 
129  pimpl->acceleration = pimpl->u.transpose() * pimpl->controlFrame->getAcceleration().getLinearVelocity();
130  return pimpl->acceleration;
131  }
132 
133  const VectorXd& PositionFeature::computeError(const Feature& featureDes) const
134  {
135  const PositionFeature& sdes = dynamic_cast<const PositionFeature&>(featureDes);
136 
138 // const Vector3d e0 = pimpl->controlFrame->getPosition().getTranslation() - sdes.pimpl->controlFrame->getPosition().getTranslation();
139 // const Vector3d e_in_r = pimpl->controlFrame->getPosition().getRotation().inverse() * e0;
140 
141 // // then project it on the controlled axes
142 // pimpl->error = getSpaceTransform() * e_in_r;
143 
144  pimpl->error = pimpl->u.transpose() * (pimpl->controlFrame->getPosition().getTranslation() - sdes.pimpl->controlFrame->getPosition().getTranslation());
145 
146  return pimpl->error;
147  }
148 
149  const VectorXd& PositionFeature::computeError() const
150  {
151 // // first compute the position error in the mobile frame
152 // const Vector3d e0 = pimpl->controlFrame->getPosition().getTranslation();
153 // const Vector3d e_in_r = pimpl->controlFrame->getPosition().getRotation().inverse() * e0;
154 
155 // // then project it on the controlled axes
156 // pimpl->error = getSpaceTransform() * e_in_r;
157 
158  pimpl->error = pimpl->u.transpose() * pimpl->controlFrame->getPosition().getTranslation();
159  return pimpl->error;
160  }
161 
162  const VectorXd& PositionFeature::computeErrorDot(const Feature& featureDes) const
163  {
164  const PositionFeature& sdes = dynamic_cast<const PositionFeature&>(featureDes);
165 
166 // // first compute the linear velocity error in the mobile frame
167 // const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
168 // const Eigen::Displacementd::Rotation3D& Rdes = sdes.pimpl->controlFrame->getPosition().getRotation();
169 // const Eigen::Displacementd::Rotation3D Rdes_in_r = R.inverse() * Rdes;
170 // const Vector3d errDot = pimpl->controlFrame->getVelocity().getLinearVelocity() - Rdes_in_r.adjoint() * sdes.pimpl->controlFrame->getVelocity().getLinearVelocity();
171 
172 
173 // // then project it on the controlled axes
174 // pimpl->errorDot = getSpaceTransform() * errDot;
175 
176  pimpl->errorDot = pimpl->u.transpose() * (pimpl->controlFrame->getVelocity().getLinearVelocity()-sdes.pimpl->controlFrame->getVelocity().getLinearVelocity());
177 
178 
179  return pimpl->errorDot;
180  }
181 
182  const VectorXd& PositionFeature::computeErrorDot() const
183  {
184 // // first compute the linear velocity error in the mobile frame
185 // const Vector3d errDot = pimpl->controlFrame->getVelocity().getLinearVelocity();
186 
187 // // then project it on the controlled axes
188 // pimpl->errorDot = getSpaceTransform() * errDot;
189 
190  pimpl->errorDot = pimpl->u.transpose() * pimpl->controlFrame->getVelocity().getLinearVelocity();
191 
192  return pimpl->errorDot;
193  }
194 
195  const MatrixXd& PositionFeature::computeJacobian(const Feature& featureDes) const
196  {
197 // const PositionFeature& sdes = dynamic_cast<const PositionFeature&>(featureDes);
198 
199 // // first compute the jacobian of the position error in the mobile frame
200 // const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
201 // const Eigen::Displacementd::Rotation3D& Rdes = sdes.pimpl->controlFrame->getPosition().getRotation();
202 // const Eigen::Displacementd::Rotation3D Rdes_in_r = R.inverse() * Rdes;
203 // const MatrixXd jacobian = pimpl->controlFrame->getJacobian().bottomRows(3) - Rdes_in_r.adjoint() * sdes.pimpl->controlFrame->getJacobian().bottomRows(3);
204 
205 
206  // then project it on the controlled axes
207 // pimpl->jacobian = getSpaceTransform() * jacobian;
208 
209  pimpl->jacobian = pimpl->u.transpose() * pimpl->controlFrame->getJacobian().bottomRows(3);
210 
211  return pimpl->jacobian;
212  }
213 
214  const MatrixXd& PositionFeature::computeJacobian() const
215  {
216 // // first compute the jacobian of the position error in the mobile frame
217 // const MatrixXd jacobian = pimpl->controlFrame->getJacobian().bottomRows(3);
218 
219 // // then project it on the controlled axes
220 // pimpl->jacobian = getSpaceTransform() * jacobian;
221 
222  pimpl->jacobian = pimpl->u.transpose() * pimpl->controlFrame->getJacobian().bottomRows(3);
223  return pimpl->jacobian;
224  }
225 
226  const Eigen::MatrixXd& PositionFeature::computeProjectedMass(const Feature& featureDes) const
227  {
228  if(!pimpl->controlFrame->dependsOnModelConfiguration())
229  throw std::runtime_error("[PositionFeature::computeProjectedMass] feature does not depend on configuration");
230 
231  pimpl->M = computeProjectedMassInverse(featureDes).inverse();
232 
233  return pimpl->M;
234  }
235 
236  const Eigen::MatrixXd& PositionFeature::computeProjectedMass() const
237  {
238  if(!pimpl->controlFrame->dependsOnModelConfiguration())
239  throw std::runtime_error("[PositionFeature::computeProjectedMass] feature does not depend on configuration");
240 
241  pimpl->M = computeProjectedMassInverse().inverse();
242 
243  return pimpl->M;
244  }
245 
246  const Eigen::MatrixXd& PositionFeature::computeProjectedMassInverse(const Feature& featureDes) const
247  {
248  if(!pimpl->controlFrame->dependsOnModelConfiguration())
249  throw std::runtime_error("[PositionFeature::computeProjectedMassInverse] feature does not depend on configuration");
250 
251  const MatrixXd& J = computeJacobian(featureDes);
252  const MatrixXd& Minv = pimpl->controlFrame->getModel().getInertiaMatrixInverse();
253  pimpl->Minv = J * Minv * J.transpose();
254 
255  return pimpl->Minv;
256  }
257 
258  const Eigen::MatrixXd& PositionFeature::computeProjectedMassInverse() const
259  {
260  if(!pimpl->controlFrame->dependsOnModelConfiguration())
261  throw std::runtime_error("[PositionFeature::computeProjectedMassInverse] feature does not depend on configuration");
262 
263  const MatrixXd& J = computeJacobian();
264  const MatrixXd& Minv = pimpl->controlFrame->getModel().getInertiaMatrixInverse();
265  pimpl->Minv = J * Minv * J.transpose();
266 
267  return pimpl->Minv;
268  }
269 
271  {
272  TaskState state;
273  state.setPosition(pimpl->controlFrame->getPosition());
274  state.setVelocity(pimpl->controlFrame->getVelocity());
275  // state.setAcceleration(pimpl->controlFrame->getAcceleration());
276  // state.setWrench(pimpl->controlFrame->getWrench());
277 
278  return state;
279  }
280 
281  void PositionFeature::setState(const TaskState& newState)
282  {
283  try {
284  TargetFrame::Ptr targetFrame = std::dynamic_pointer_cast<TargetFrame>(pimpl->controlFrame);
285  if(newState.hasPosition()) {
286  targetFrame->setPosition(newState.getPosition());
287  }
288  if(newState.hasVelocity()) {
289  targetFrame->setVelocity(newState.getVelocity());
290  }
291  if(newState.hasAcceleration()) {
292  targetFrame->setAcceleration(newState.getAcceleration());
293  }
294  if(newState.hasWrench()) {
295  targetFrame->setWrench(newState.getWrench());
296  }
297  } catch (int errCode) {
298  std::cout << "You cannot set the state of this feature because it is not a desired feature. It must be constructed with a TargetFrame." << errCode << std::endl;
299  }
300  }
301 
302 
303  // --- POINT CONTACT ------------------------------------------
304 
306  {
307  ControlFrame::Ptr controlFrame;
308  MatrixXd spaceTransform;
309  VectorXd error;
310  VectorXd errorDot;
311  VectorXd effort;
312  VectorXd acceleration;
313  MatrixXd jacobian;
314  MatrixXd M;
315  MatrixXd Minv;
316 
317  Pimpl(ControlFrame::Ptr cf)
318  : controlFrame(cf)
319  , spaceTransform(Matrix3d::Identity())
320  , error(VectorXd::Zero(3))
321  , errorDot(VectorXd::Zero(3))
322  , effort(VectorXd::Zero(3))
323  , acceleration(VectorXd::Zero(3))
324  , jacobian(MatrixXd::Zero(3, cf->getJacobian().cols()))
325  {
326  }
327  };
328 
329  PointContactFeature::PointContactFeature(const std::string& name, ControlFrame::Ptr frame)
330  : Feature(name)
331  , pimpl(new Pimpl(frame))
332  {
333  }
334 
336  {
337  return pimpl->spaceTransform;
338  }
339 
341  {
342  return 3;
343  }
344 
345  const VectorXd& PointContactFeature::computeEffort(const Feature& featureDes) const
346  {
347  throw std::runtime_error("[PointContactFeature::computeEffort(const Feature&)] Desired feature are irrelevant in PointContactFeatures");
348  }
349 
350  const VectorXd& PointContactFeature::computeEffort() const
351  {
352  pimpl->effort = pimpl->controlFrame->getWrench().getForce();
353  return pimpl->effort;
354  }
355 
356  const VectorXd& PointContactFeature::computeAcceleration(const Feature& featureDes) const
357  {
358  throw std::runtime_error("[PointContactFeature::computeAcceleration(const Feature&)] Desired feature are irrelevant in PointContactFeatures");
359  }
360 
362  {
363  pimpl->acceleration = pimpl->controlFrame->getAcceleration().getLinearVelocity();
364  return pimpl->acceleration;
365  }
366 
367  const VectorXd& PointContactFeature::computeError(const Feature& featureDes) const
368  {
369  throw std::runtime_error("[PointContactFeature::computeError(const Feature&)] Desired feature are irrelevant in PointContactFeatures");
370  }
371 
372  const VectorXd& PointContactFeature::computeError() const
373  {
374 // const Vector3d& e0 = pimpl->controlFrame->getPosition().getTranslation();
375 // pimpl->error = pimpl->controlFrame->getPosition().getRotation().inverse() * e0;
376 
377  pimpl->error = pimpl->controlFrame->getPosition().getTranslation();
378  return pimpl->error;
379  }
380 
381  const VectorXd& PointContactFeature::computeErrorDot(const Feature& featureDes) const
382  {
383  throw std::runtime_error("[PointContactFeature::computeErrorDot(const Feature&)] Desired feature are irrelevant in PointContactFeatures");
384  }
385 
386  const VectorXd& PointContactFeature::computeErrorDot() const
387  {
388  pimpl->errorDot = pimpl->controlFrame->getVelocity().getLinearVelocity();
389  return pimpl->errorDot;
390  }
391 
392  const MatrixXd& PointContactFeature::computeJacobian(const Feature& featureDes) const
393  {
394  throw std::runtime_error("[PointContactFeature::computeJacobian(const Feature&)] Desired feature are irrelevant in PointContactFeatures");
395  }
396 
397  const MatrixXd& PointContactFeature::computeJacobian() const
398  {
399  pimpl->jacobian = pimpl->controlFrame->getJacobian().bottomRows(3);
400  return pimpl->jacobian;
401  }
402 
403  const Eigen::MatrixXd& PointContactFeature::computeProjectedMass(const Feature& featureDes) const
404  {
405  throw std::runtime_error("[PointContactFeature::computeProjectedMass(const Feature&)] Desired feature are irrelevant in PointContactFeatures");
406  }
407 
408  const Eigen::MatrixXd& PointContactFeature::computeProjectedMass() const
409  {
410  if(!pimpl->controlFrame->dependsOnModelConfiguration())
411  throw std::runtime_error("[PositionFeature::computeProjectedMass] Feature must depend on configuration!");
412 
413  pimpl->M = computeProjectedMassInverse().inverse();
414 
415  return pimpl->M;
416  }
417 
418  const Eigen::MatrixXd& PointContactFeature::computeProjectedMassInverse(const Feature& featureDes) const
419  {
420  throw std::runtime_error("[PointContactFeature::computeProjectedMassInverse(const Feature&)] Desired feature are irrelevant in PointContactFeatures");
421  }
422 
424  {
425  if(!pimpl->controlFrame->dependsOnModelConfiguration())
426  throw std::runtime_error("[PositionFeature::computeProjectedMassInverse] feature does not depend on configuration");
427 
428  const MatrixXd& J = computeJacobian();
429  const MatrixXd& Minv = pimpl->controlFrame->getModel().getInertiaMatrixInverse();
430  pimpl->Minv = J * Minv * J.transpose();
431 
432  return pimpl->Minv;
433  }
435  {
436  TaskState state;
437  state.setPosition(pimpl->controlFrame->getPosition());
438  state.setVelocity(pimpl->controlFrame->getVelocity());
439  state.setAcceleration(pimpl->controlFrame->getAcceleration());
440  state.setWrench(pimpl->controlFrame->getWrench());
441 
442  return state;
443  }
444 
446  {
447  try {
448  TargetFrame::Ptr targetFrame = std::dynamic_pointer_cast<TargetFrame>(pimpl->controlFrame);
449  if(newState.hasPosition()) {
450  targetFrame->setPosition(newState.getPosition());
451  }
452  if(newState.hasVelocity()) {
453  targetFrame->setVelocity(newState.getVelocity());
454  }
455  if(newState.hasAcceleration()) {
456  targetFrame->setAcceleration(newState.getAcceleration());
457  }
458  if(newState.hasWrench()) {
459  targetFrame->setWrench(newState.getWrench());
460  }
461  } catch (int errCode) {
462  std::cout << "You cannot set the state of this feature because it is not a desired feature. It must be constructed with a TargetFrame." << errCode << std::endl;
463  }
464  }
465 
466  // --- ORIENTATION --------------------------------------------
467 
469  {
470  ControlFrame::Ptr controlFrame;
471  MatrixXd spaceTransform;
472  VectorXd error;
473  VectorXd errorDot;
474  VectorXd effort;
475  VectorXd acceleration;
476  MatrixXd jacobian;
477  MatrixXd M;
478  MatrixXd Minv;
479 
480  Pimpl(ControlFrame::Ptr cf)
481  : controlFrame(cf)
482  {
483  spaceTransform = MatrixXd::Identity(3, 3);
484  error = VectorXd::Zero(3);
485  errorDot = VectorXd::Zero(3);
486  effort = VectorXd::Zero(3);
487  acceleration = VectorXd::Zero(3);
488  jacobian = MatrixXd::Zero(3, cf->getJacobian().cols());
489  }
490  };
491 
492  OrientationFeature::OrientationFeature(const std::string& name, ControlFrame::Ptr frame)
493  : Feature(name)
494  , pimpl(new Pimpl(frame))
495  {
496  }
497 
499  {
500  return pimpl->spaceTransform;
501  }
502 
504  {
505  return 3;
506  }
507 
508  const VectorXd& OrientationFeature::computeEffort(const Feature& featureDes) const
509  {
510  const OrientationFeature& sdes = dynamic_cast<const OrientationFeature&>(featureDes);
511 
512  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
513  const Eigen::Displacementd::Rotation3D& Rdes = sdes.pimpl->controlFrame->getPosition().getRotation();
514  const Eigen::Displacementd::Rotation3D Rdes_in_r = R.inverse() * Rdes;
515 
516  pimpl->effort = pimpl->controlFrame->getWrench().getTorque() - Rdes_in_r.adjoint() * sdes.pimpl->controlFrame->getWrench().getTorque();
517 
518  return pimpl->effort;
519  }
520 
521  const VectorXd& OrientationFeature::computeEffort() const
522  {
523  pimpl->effort = pimpl->controlFrame->getWrench().getTorque();
524  return pimpl->effort;
525  }
526 
527  const VectorXd& OrientationFeature::computeAcceleration(const Feature& featureDes) const
528  {
529  const OrientationFeature& sdes = dynamic_cast<const OrientationFeature&>(featureDes);
530 
531  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
532 // const Eigen::Displacementd::Rotation3D& Rdes = sdes.pimpl->controlFrame->getPosition().getRotation();
533 // const Eigen::Displacementd::Rotation3D Rdes_in_r = R.inverse() * Rdes;
534 
535 // pimpl->acceleration = pimpl->controlFrame->getAcceleration().getAngularVelocity() - Rdes_in_r.adjoint() * sdes.pimpl->controlFrame->getAcceleration().getAngularVelocity();
536 
537  pimpl->acceleration = pimpl->controlFrame->getAcceleration().getAngularVelocity() - sdes.pimpl->controlFrame->getAcceleration().getAngularVelocity();
538  return pimpl->acceleration;
539  }
540 
542  {
543  pimpl->acceleration = pimpl->controlFrame->getAcceleration().getAngularVelocity();
544  return pimpl->acceleration;
545  }
546 
547  const VectorXd& OrientationFeature::computeError(const Feature& featureDes) const
548  {
549  const OrientationFeature& sdes = dynamic_cast<const OrientationFeature&>(featureDes);
550 
551  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
552  const Eigen::Displacementd::Rotation3D& Rdes = sdes.pimpl->controlFrame->getPosition().getRotation();
553 
554 // pimpl->error = (Rdes.inverse() * R).log();
555  pimpl->error = Rdes.adjoint()*((Rdes.inverse() * R).log());
556 
557  return pimpl->error;
558  }
559 
560  const VectorXd& OrientationFeature::computeError() const
561  {
562  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
563  pimpl->error = R.log();
564  return pimpl->error;
565  }
566 
567  const VectorXd& OrientationFeature::computeErrorDot(const Feature& featureDes) const
568  {
569  const OrientationFeature& sdes = dynamic_cast<const OrientationFeature&>(featureDes);
570 
571  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
572  const Eigen::Displacementd::Rotation3D& Rdes = sdes.pimpl->controlFrame->getPosition().getRotation();
573  const Eigen::Displacementd::Rotation3D Rdes_in_r = R.inverse() * Rdes;
574 
575 // pimpl->errorDot = pimpl->controlFrame->getVelocity().getAngularVelocity() - Rdes_in_r.adjoint() * sdes.pimpl->controlFrame->getVelocity().getAngularVelocity();
576  pimpl->errorDot = pimpl->controlFrame->getVelocity().getAngularVelocity() - sdes.pimpl->controlFrame->getVelocity().getAngularVelocity();
577 
578  return pimpl->errorDot;
579  }
580 
581  const VectorXd& OrientationFeature::computeErrorDot() const
582  {
583  pimpl->errorDot = pimpl->controlFrame->getVelocity().getAngularVelocity();
584  return pimpl->errorDot;
585  }
586 
587  const MatrixXd& OrientationFeature::computeJacobian(const Feature& featureDes) const
588  {
589  const OrientationFeature& sdes = dynamic_cast<const OrientationFeature&>(featureDes);
590 
591  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
592  const Eigen::Displacementd::Rotation3D& Rdes = sdes.pimpl->controlFrame->getPosition().getRotation();
593  const Eigen::Displacementd::Rotation3D Rdes_in_r = R.inverse() * Rdes;
594 
595 // pimpl->jacobian = pimpl->controlFrame->getJacobian().topRows(3) - Rdes_in_r.adjoint() * sdes.pimpl->controlFrame->getJacobian().topRows(3);
596 
597  pimpl->jacobian = pimpl->controlFrame->getJacobian().topRows(3) - sdes.pimpl->controlFrame->getJacobian().topRows(3);
598  return pimpl->jacobian;
599  }
600 
601  const MatrixXd& OrientationFeature::computeJacobian() const
602  {
603  pimpl->jacobian = pimpl->controlFrame->getJacobian().topRows(3);
604  return pimpl->jacobian;
605  }
606 
607  const MatrixXd& OrientationFeature::computeProjectedMass(const Feature& featureDes) const
608  {
609  if(!pimpl->controlFrame->dependsOnModelConfiguration())
610  throw std::runtime_error("[OrientationFeature::computeProjectedMass] feature does not depend on configuration");
611 
612  pimpl->M = computeProjectedMassInverse(featureDes).inverse();
613 
614  return pimpl->M;
615  }
616 
618  {
619  if(!pimpl->controlFrame->dependsOnModelConfiguration())
620  throw std::runtime_error("[OrientationFeature::computeProjectedMass] feature does not depend on configuration");
621 
622  pimpl->M = computeProjectedMassInverse().inverse();
623 
624  return pimpl->M;
625  }
626 
627  const MatrixXd& OrientationFeature::computeProjectedMassInverse(const Feature& featureDes) const
628  {
629  if(!pimpl->controlFrame->dependsOnModelConfiguration())
630  throw std::runtime_error("[OrientationFeature::computeProjectedMassInverse] feature does not depend on configuration");
631 
632  const MatrixXd& J = computeJacobian(featureDes);
633  const MatrixXd& Minv = pimpl->controlFrame->getModel().getInertiaMatrixInverse();
634  pimpl->Minv = J * Minv * J.transpose();
635 
636  return pimpl->Minv;
637  }
638 
640  {
641  if(!pimpl->controlFrame->dependsOnModelConfiguration())
642  throw std::runtime_error("[OrientationFeature::computeProjectedMassInverse] feature does not depend on configuration");
643 
644  const MatrixXd& J = computeJacobian();
645  const MatrixXd& Minv = pimpl->controlFrame->getModel().getInertiaMatrixInverse();
646  pimpl->Minv = J * Minv * J.transpose();
647 
648  return pimpl->Minv;
649  }
651  {
652  TaskState state;
653  state.setPosition(pimpl->controlFrame->getPosition());
654  state.setVelocity(pimpl->controlFrame->getVelocity());
655  state.setAcceleration(pimpl->controlFrame->getAcceleration());
656  state.setWrench(pimpl->controlFrame->getWrench());
657 
658  return state;
659  }
660 
662  {
663  try {
664  TargetFrame::Ptr targetFrame = std::dynamic_pointer_cast<TargetFrame>(pimpl->controlFrame);
665  if(newState.hasPosition()) {
666  targetFrame->setPosition(newState.getPosition());
667  }
668  if(newState.hasVelocity()) {
669  targetFrame->setVelocity(newState.getVelocity());
670  }
671  if(newState.hasAcceleration()) {
672  targetFrame->setAcceleration(newState.getAcceleration());
673  }
674  if(newState.hasWrench()) {
675  targetFrame->setWrench(newState.getWrench());
676  }
677  } catch (int errCode) {
678  std::cout << "You cannot set the state of this feature because it is not a desired feature. It must be constructed with a TargetFrame." << errCode << std::endl;
679  }
680  }
681 
682  // --- DISPLACEMENT -------------------------------------------
683 
685  {
686  ControlFrame::Ptr controlFrame;
688  int dim;
689  MatrixXd u;
690  MatrixXd spaceTransform;
691  VectorXd error;
692  VectorXd errorDot;
693  VectorXd effort;
694  VectorXd acceleration;
695  MatrixXd jacobian;
696  MatrixXd M;
697  MatrixXd Minv;
698 
699  Pimpl(ControlFrame::Ptr cf, ECartesianDof a)
700  : controlFrame(cf)
701  , dim(3 + utils::computeDimensionFor(axes, NONE))
702  , axes(a)
703  {
704  u.resize(3, dim-3);
705  int k = 0;
706  if(axes & X)
707  u.col(k++) = Vector3d(1., 0., 0.);
708  if(axes & Y)
709  u.col(k++) = Vector3d(0., 1., 0.);
710  if(axes & Z)
711  u.col(k++) = Vector3d(0., 0., 1.);
712 
713  error = VectorXd::Zero(dim);
714  errorDot = VectorXd::Zero(dim);
715  effort = VectorXd::Zero(dim);
716  acceleration = VectorXd::Zero(dim);
717  jacobian = MatrixXd::Zero(dim, cf->getJacobian().cols());
718  spaceTransform = MatrixXd(dim, 6);
719  }
720  };
721 
722  DisplacementFeature::DisplacementFeature(const std::string& name, ControlFrame::Ptr frame, ECartesianDof axes)
723  : Feature(name)
724  , pimpl(new Pimpl(frame, axes))
725  {
726  }
727 
729  {
730  pimpl->spaceTransform.topRows(3).setIdentity();
731 
732  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
733  pimpl->spaceTransform.bottomRows(3) = pimpl->u.transpose() * R.adjoint();
734 
735  return pimpl->spaceTransform;
736  }
737 
739  {
740  return pimpl->dim;
741  }
742 
743  const VectorXd& DisplacementFeature::computeEffort(const Feature& featureDes) const
744  {
745  const DisplacementFeature& sdes = dynamic_cast<const DisplacementFeature&>(featureDes);
746 
747  // Twist error in the mobile frame
748  const Eigen::Displacementd Herror = sdes.pimpl->controlFrame->getPosition().inverse() * pimpl->controlFrame->getPosition();
749  const Eigen::Wrenchd Werror = pimpl->controlFrame->getWrench() - Herror.adjointTr(sdes.pimpl->controlFrame->getWrench());
750 
751  // project the translational part on the controlled axes
752  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
753  const MatrixXd u_in_mobileFrame = R.inverse().adjoint() * pimpl->u;
754  pimpl->effort.tail(pimpl->dim - 3) = u_in_mobileFrame.transpose() * Werror.getForce();
755 
756  pimpl->effort.head(3) = Werror.getTorque();
757 
758  return pimpl->effort;
759  }
760 
761  const VectorXd& DisplacementFeature::computeEffort() const
762  {
763  // Twist error in the mobile frame
764  const Eigen::Wrenchd Werror = pimpl->controlFrame->getWrench();
765 
766  // project the translational part on the controlled axes
767  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
768  const MatrixXd u_in_mobileFrame = R.inverse().adjoint() * pimpl->u;
769  pimpl->effort.tail(pimpl->dim - 3) = u_in_mobileFrame.transpose() * Werror.getForce();
770  pimpl->effort.head(3) = Werror.getTorque();
771 
772  return pimpl->effort;
773  }
774 
775  const VectorXd& DisplacementFeature::computeAcceleration(const Feature& featureDes) const
776  {
777  const DisplacementFeature& sdes = dynamic_cast<const DisplacementFeature&>(featureDes);
778 
779 // // Twist error in the mobile frame
780 // const Eigen::Displacementd Herror = pimpl->controlFrame->getPosition().inverse() * sdes.pimpl->controlFrame->getPosition();
781 // const Eigen::Twistd Terror = sdes.pimpl->controlFrame->getVelocity() - Herror.inverse().adjoint() * pimpl->controlFrame->getVelocity();
782 // //const Eigen::Twistd gamma_error =
783 // // pimpl->controlFrame->getAcceleration() -
784 // // Herror.adjoint() * sdes.pimpl->controlFrame->getAcceleration() -
785 // // Herror.adjoint() * Terror.bracket(sdes.pimpl->controlFrame->getAcceleration());
786 // const Eigen::Twistd gamma_error =
787 // pimpl->controlFrame->getAcceleration() - sdes.pimpl->controlFrame->getAcceleration();
788 
789 // // project the translational part on the controlled axes
790 // const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
791 // const MatrixXd u_in_mobileFrame = R.inverse().adjoint() * pimpl->u;
792 // pimpl->acceleration.tail(pimpl->dim - 3) = u_in_mobileFrame.transpose() * gamma_error.getLinearVelocity();
793 
794 // pimpl->acceleration.head(3) = gamma_error.getAngularVelocity();
795 
796  pimpl->acceleration = pimpl->controlFrame->getAcceleration() - sdes.pimpl->controlFrame->getAcceleration();
797 
798  return pimpl->acceleration;
799  }
800 
802  {
803 // const VectorXd acc = pimpl->controlFrame->getAcceleration();
804 
805 // // project the translational part on the controlled axes
806 // const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
807 // const MatrixXd u_in_mobileFrame = R.inverse().adjoint() * pimpl->u;
808 // pimpl->acceleration.tail(pimpl->dim - 3) = u_in_mobileFrame.transpose() * acc.tail(3);
809 // pimpl->acceleration.head(3) = acc.head(3);
810 
811  pimpl->acceleration = pimpl->controlFrame->getAcceleration();
812 
813  return pimpl->acceleration;
814  }
815 
816  const VectorXd& DisplacementFeature::computeError(const Feature& featureDes) const
817  {
818  const DisplacementFeature& sdes = dynamic_cast<const DisplacementFeature&>(featureDes);
819 
820  // Displacement error in the mobile frame
821 // const Eigen::Displacementd Herror = pimpl->controlFrame->getPosition().inverse() * sdes.pimpl->controlFrame->getPosition();
822 
823  // Project the opposite translational part on the controlled axes
824  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
825 // const MatrixXd u_in_mobileFrame = R.inverse().adjoint() * pimpl->u;
826 // pimpl->error.tail(pimpl->dim - 3) = - u_in_mobileFrame.transpose() * Herror.getTranslation();
827 
828  const Eigen::Displacementd::Rotation3D& Rdes = sdes.pimpl->controlFrame->getPosition().getRotation();
829 // pimpl->error.head(3) = (Rdes.inverse() * R).log();
830  pimpl->error.head(3) = Rdes.adjoint()*((Rdes.inverse() * R).log());
831 
832  pimpl->error.tail(pimpl->dim - 3) = pimpl->controlFrame->getPosition().getTranslation() - sdes.pimpl->controlFrame->getPosition().getTranslation();
833  return pimpl->error;
834  }
835 
836  const VectorXd& DisplacementFeature::computeError() const
837  {
838  // Displacement error in the mobile frame
839 // const Eigen::Displacementd Herror = pimpl->controlFrame->getPosition().inverse();
840 
841  // Project the opposite translational part on the controlled axes
842  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
843  const MatrixXd u_in_mobileFrame = R.inverse().adjoint() * pimpl->u;
844 // pimpl->error.tail(pimpl->dim - 3) = - u_in_mobileFrame.transpose() * Herror.getTranslation();
845  pimpl->error.tail(pimpl->dim - 3) = pimpl->controlFrame->getPosition().getTranslation();
846  pimpl->error.head(3) = R.log();
847 
848  return pimpl->error;
849  }
850 
851  const VectorXd& DisplacementFeature::computeErrorDot(const Feature& featureDes) const
852  {
853  const DisplacementFeature& sdes = dynamic_cast<const DisplacementFeature&>(featureDes);
854 
855 // // Twist error in the mobile frame
856 // const Eigen::Displacementd Herror = pimpl->controlFrame->getPosition().inverse() * sdes.pimpl->controlFrame->getPosition();
857 // const Eigen::Twistd Terror = pimpl->controlFrame->getVelocity() - Herror.adjoint() * sdes.pimpl->controlFrame->getVelocity();
858 
859 // // project the translational part on the controlled axes
860 // const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
861 // const MatrixXd u_in_mobileFrame = R.inverse().adjoint() * pimpl->u;
862 // pimpl->errorDot.tail(pimpl->dim - 3) = u_in_mobileFrame.transpose() * Terror.getLinearVelocity();
863  pimpl->errorDot.tail(pimpl->dim - 3) = pimpl->controlFrame->getVelocity().getLinearVelocity() - sdes.pimpl->controlFrame->getVelocity().getLinearVelocity();
864 
865 // pimpl->errorDot.head(3) = Terror.getAngularVelocity();
866 
867  pimpl->errorDot.head(3) = pimpl->controlFrame->getVelocity().getAngularVelocity() - sdes.pimpl->controlFrame->getVelocity().getAngularVelocity();
868 
869 
870  return pimpl->errorDot;
871  }
872 
873  const VectorXd& DisplacementFeature::computeErrorDot() const
874  {
875 // // Twist error in the mobile frame
876 // const Eigen::Twistd Terror = pimpl->controlFrame->getVelocity();
877 
878 // // project the translational part on the controlled axes
879 // const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
880 // const MatrixXd u_in_mobileFrame = R.inverse().adjoint() * pimpl->u;
881 // pimpl->errorDot.tail(pimpl->dim - 3) = u_in_mobileFrame.transpose() * Terror.getLinearVelocity();
882  pimpl->errorDot.tail(pimpl->dim - 3) = pimpl->controlFrame->getVelocity().getLinearVelocity();
883 
884 // pimpl->errorDot.head(3) = Terror.getAngularVelocity();
885  pimpl->errorDot.head(3) = pimpl->controlFrame->getVelocity().getAngularVelocity();
886 
887  return pimpl->errorDot;
888  }
889 
890  const MatrixXd& DisplacementFeature::computeJacobian(const Feature& featureDes) const
891  {
892  const DisplacementFeature& sdes = dynamic_cast<const DisplacementFeature&>(featureDes);
893 
894 // // Twist error in the mobile frame
895 // const Eigen::Displacementd Herror = pimpl->controlFrame->getPosition().inverse() * sdes.pimpl->controlFrame->getPosition();
896 // const MatrixXd J = pimpl->controlFrame->getJacobian() - Herror.adjoint() * sdes.pimpl->controlFrame->getJacobian();
897 
898 // // project the translational part on the controlled axes
899 // const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
900 // const MatrixXd u_in_mobileFrame = R.inverse().adjoint() * pimpl->u;
901 // pimpl->jacobian.bottomRows(pimpl->dim - 3) = u_in_mobileFrame.transpose() * J.bottomRows(3);
902 
903 // pimpl->jacobian.topRows(3) = J.topRows(3);
904 
905  const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
906  const MatrixXd J = pimpl->controlFrame->getJacobian() - sdes.pimpl->controlFrame->getJacobian();
907 
908  return pimpl->jacobian;
909  }
910 
911  const MatrixXd& DisplacementFeature::computeJacobian() const
912  {
913  // Twist error in the mobile frame
914  const Eigen::Displacementd Herror = pimpl->controlFrame->getPosition().inverse();
915 // const MatrixXd J = pimpl->controlFrame->getJacobian();
916  pimpl->jacobian = pimpl->controlFrame->getJacobian();
917 
918 // // project the translational part on the controlled axes
919 // const Eigen::Displacementd::Rotation3D& R = pimpl->controlFrame->getPosition().getRotation();
920 // const MatrixXd u_in_mobileFrame = R.inverse().adjoint() * pimpl->u;
921 // pimpl->jacobian.bottomRows(pimpl->dim - 3) = u_in_mobileFrame.transpose() * J.bottomRows(3);
922 // pimpl->jacobian.topRows(3) = J.topRows(3);
923 
924  return pimpl->jacobian;
925  }
926 
927  const MatrixXd& DisplacementFeature::computeProjectedMass(const Feature& featureDes) const
928  {
929  if(!pimpl->controlFrame->dependsOnModelConfiguration())
930  throw std::runtime_error("[DisplacementFeature::computeProjectedMass] feature does not depend on configuration");
931 
932  pimpl->M = computeProjectedMassInverse(featureDes).inverse();
933 
934  return pimpl->M;
935  }
936 
938  {
939  if(!pimpl->controlFrame->dependsOnModelConfiguration())
940  throw std::runtime_error("[DisplacementFeature::computeProjectedMass] feature does not depend on configuration");
941 
942  pimpl->M = computeProjectedMassInverse().inverse();
943 
944  return pimpl->M;
945  }
946 
947  const MatrixXd& DisplacementFeature::computeProjectedMassInverse(const Feature& featureDes) const
948  {
949  if(!pimpl->controlFrame->dependsOnModelConfiguration())
950  throw std::runtime_error("[DisplacementFeature::computeProjectedMassInverse] feature does not depend on configuration");
951 
952  const MatrixXd& J = computeJacobian(featureDes);
953  const MatrixXd& Minv = pimpl->controlFrame->getModel().getInertiaMatrixInverse();
954  pimpl->Minv = J * Minv * J.transpose();
955 
956  return pimpl->Minv;
957  }
958 
960  {
961  if(!pimpl->controlFrame->dependsOnModelConfiguration())
962  throw std::runtime_error("[DisplacementFeature::computeProjectedMassInverse] feature does not depend on configuration");
963 
964  const MatrixXd& J = computeJacobian();
965  const MatrixXd& Minv = pimpl->controlFrame->getModel().getInertiaMatrix().inverse();
966  pimpl->Minv = J * Minv * J.transpose();
967 
968  return pimpl->Minv;
969  }
971  {
972  TaskState state;
973  state.setPosition(pimpl->controlFrame->getPosition());
974  state.setVelocity(pimpl->controlFrame->getVelocity());
975  state.setAcceleration(pimpl->controlFrame->getAcceleration());
976  state.setWrench(pimpl->controlFrame->getWrench());
977 
978  return state;
979  }
980 
982  {
983  try {
984  TargetFrame::Ptr targetFrame = std::dynamic_pointer_cast<TargetFrame>(pimpl->controlFrame);
985  if(newState.hasPosition()) {
986  targetFrame->setPosition(newState.getPosition());
987  }
988  if(newState.hasVelocity()) {
989  targetFrame->setVelocity(newState.getVelocity());
990  }
991  if(newState.hasAcceleration()) {
992  targetFrame->setAcceleration(newState.getAcceleration());
993  }
994  if(newState.hasWrench()) {
995  targetFrame->setWrench(newState.getWrench());
996  }
997  } catch (int errCode) {
998  std::cout << "You cannot set the state of this feature because it is not a desired feature. It must be constructed with a TargetFrame." << errCode << std::endl;
999  }
1000  }
1001 
1002  // --- CONTACT CONSTRAINT FEATURES ----------------------------
1003 
1005  {
1006  ControlFrame::Ptr controlFrame;
1007  MatrixXd spaceTransform;
1008  VectorXd error;
1009  VectorXd errorDot;
1010  VectorXd effort;
1011  VectorXd acceleration;
1012  MatrixXd jacobian;
1013  MatrixXd M;
1014  MatrixXd Minv;
1015 
1016  Pimpl(ControlFrame::Ptr cf)
1017  : controlFrame(cf)
1018  , spaceTransform(MatrixXd::Identity(6, 6))
1019  , error(VectorXd::Zero(6))
1020  , errorDot(VectorXd::Zero(6))
1021  , effort(VectorXd::Zero(6))
1022  , acceleration(VectorXd::Zero(6))
1023  , jacobian(MatrixXd::Zero(6, cf->getJacobian().cols()))
1024  {
1025  }
1026  };
1027 
1028  ContactConstraintFeature::ContactConstraintFeature(const std::string& name, ControlFrame::Ptr frame)
1029  : Feature(name)
1030  , pimpl(new Pimpl(frame))
1031  {
1032  }
1033 
1035  {
1036  return pimpl->spaceTransform;
1037  }
1038 
1040  {
1041  return 6;
1042  }
1043 
1044  const VectorXd& ContactConstraintFeature::computeEffort(const Feature& featureDes) const
1045  {
1046  throw std::runtime_error("[ContactConstraintFeature::computeEffort(const Feature&)] Desired feature are irrelevant in ContactConstraintFeature");
1047  }
1048 
1050  {
1051  const Eigen::Wrenchd Werror = pimpl->controlFrame->getWrench();
1052  pimpl->effort.tail(3) = Werror.getForce();
1053  pimpl->effort.head(3) = Werror.getTorque();
1054  return pimpl->effort;
1055  }
1056 
1057  const VectorXd& ContactConstraintFeature::computeAcceleration(const Feature& featureDes) const
1058  {
1059  throw std::runtime_error("[ContactConstraintFeature::computeAcceleration(const Feature&)] Desired feature are irrelevant in ContactConstraintFeature");
1060  }
1061 
1063  {
1064  pimpl->acceleration.head(3) = pimpl->controlFrame->getAcceleration().getAngularVelocity();
1065  pimpl->acceleration.tail(3) = pimpl->controlFrame->getAcceleration().getLinearVelocity();
1066  return pimpl->acceleration;
1067  }
1068 
1069  const VectorXd& ContactConstraintFeature::computeError(const Feature& featureDes) const
1070  {
1071  throw std::runtime_error("[ContactConstraintFeature::computeError(const Feature&)] Desired feature are irrelevant in ContactConstraintFeature");
1072  }
1073 
1075  {
1076  const Eigen::Displacementd H = pimpl->controlFrame->getPosition();
1077  const Eigen::Displacementd::Rotation3D& R = H.getRotation();
1078 // pimpl->error.tail(3) = R.adjoint().transpose() * H.getTranslation();
1079  pimpl->error.tail(3) = H.getTranslation();
1080  pimpl->error.head(3) = R.log();
1081  return pimpl->error;
1082  }
1083 
1084  const VectorXd& ContactConstraintFeature::computeErrorDot(const Feature& featureDes) const
1085  {
1086  throw std::runtime_error("[ContactConstraintFeature::computeErrorDot(const Feature&)] Desired feature are irrelevant in ContactConstraintFeature");
1087  }
1088 
1090  {
1091  const Eigen::Twistd Terror = pimpl->controlFrame->getVelocity();
1092  pimpl->errorDot.tail(3) = Terror.getLinearVelocity();
1093  pimpl->errorDot.head(3) = Terror.getAngularVelocity();
1094  return pimpl->errorDot;
1095  }
1096 
1097  const MatrixXd& ContactConstraintFeature::computeJacobian(const Feature& featureDes) const
1098  {
1099  throw std::runtime_error("[ContactConstraintFeature::computeJacobian(const Feature&)] Desired feature are irrelevant in ContactConstraintFeature");
1100  }
1101 
1103  {
1104  pimpl->jacobian = pimpl->controlFrame->getJacobian();
1105  return pimpl->jacobian;
1106  }
1107 
1108  const MatrixXd& ContactConstraintFeature::computeProjectedMass(const Feature& featureDes) const
1109  {
1110  throw std::runtime_error("[ContactConstraintFeature::computeProjectedMass(const Feature&)] Desired feature are irrelevant in ContactConstraintFeature");
1111  }
1112 
1114  {
1115  if(!pimpl->controlFrame->dependsOnModelConfiguration())
1116  throw std::runtime_error("[DisplacementFeature::computeProjectedMass] feature does not depend on configuration");
1117 
1118  pimpl->M = computeProjectedMassInverse().inverse();
1119 
1120  return pimpl->M;
1121  }
1122 
1123  const MatrixXd& ContactConstraintFeature::computeProjectedMassInverse(const Feature& featureDes) const
1124  {
1125  throw std::runtime_error("[ContactConstraintFeature::computeProjectedMassInverse(const Feature&)] Desired feature are irrelevant in ContactConstraintFeature");
1126  }
1127 
1129  {
1130  if(!pimpl->controlFrame->dependsOnModelConfiguration())
1131  throw std::runtime_error("[DisplacementFeature::computeProjectedMassInverse] feature does not depend on configuration");
1132 
1133  const MatrixXd& J = computeJacobian();
1134  const MatrixXd& Minv = pimpl->controlFrame->getModel().getInertiaMatrix().inverse();
1135  pimpl->Minv = J * Minv * J.transpose();
1136 
1137  return pimpl->Minv;
1138  }
1140  {
1141  TaskState state;
1142  state.setPosition(pimpl->controlFrame->getPosition());
1143  state.setVelocity(pimpl->controlFrame->getVelocity());
1144  state.setAcceleration(pimpl->controlFrame->getAcceleration());
1145  state.setWrench(pimpl->controlFrame->getWrench());
1146 
1147  return state;
1148  }
1149 
1151  {
1152  try {
1153  TargetFrame::Ptr targetFrame = std::dynamic_pointer_cast<TargetFrame>(pimpl->controlFrame);
1154  if(newState.hasPosition()) {
1155  targetFrame->setPosition(newState.getPosition());
1156  }
1157  if(newState.hasVelocity()) {
1158  targetFrame->setVelocity(newState.getVelocity());
1159  }
1160  if(newState.hasAcceleration()) {
1161  targetFrame->setAcceleration(newState.getAcceleration());
1162  }
1163  if(newState.hasWrench()) {
1164  targetFrame->setWrench(newState.getWrench());
1165  }
1166  } catch (int errCode) {
1167  std::cout << "You cannot set the state of this feature because it is not a desired feature. It must be constructed with a TargetFrame." << errCode << std::endl;
1168  }
1169  }
1170 
1171 
1172 
1173 
1174  // --- ARTICULAR ----------------------------------------------
1175 
1177  {
1178  FullState::Ptr state;
1179  VectorXd error;
1180  VectorXd errorDot;
1181  VectorXd effort;
1182  VectorXd acceleration;
1183  MatrixXd J;
1184  MatrixXd M;
1185  MatrixXd Minv;
1186  MatrixXd spaceTransform;
1187 
1188  Pimpl(FullState::Ptr fs)
1189  : state(fs)
1190  {
1191  spaceTransform = MatrixXd::Identity(state->getSize(), state->getSize());
1192  }
1193  };
1194 
1195  FullStateFeature::FullStateFeature(const std::string& name, FullState::Ptr state)
1196  : Feature(name)
1197  , pimpl( new Pimpl(state) )
1198  {
1199  }
1200 
1201  const MatrixXd& FullStateFeature::getSpaceTransform() const
1202  {
1203  return pimpl->spaceTransform;
1204  }
1205 
1207  {
1208  return pimpl->state->getSize();
1209  }
1210 
1211  const VectorXd& FullStateFeature::computeEffort(const Feature& featureDes) const
1212  {
1213  const FullStateFeature& sdes = dynamic_cast<const FullStateFeature&>(featureDes);
1214  pimpl->effort = pimpl->state->tau() - sdes.pimpl->state->tau();
1215  return pimpl->effort;
1216  }
1217 
1218  const VectorXd& FullStateFeature::computeEffort() const
1219  {
1220  pimpl->effort = pimpl->state->tau();
1221  return pimpl->effort;
1222  }
1223 
1224  const VectorXd& FullStateFeature::computeAcceleration(const Feature& featureDes) const
1225  {
1226  const FullStateFeature& sdes = dynamic_cast<const FullStateFeature&>(featureDes);
1227  pimpl->acceleration = pimpl->state->qddot() - sdes.pimpl->state->qddot();
1228  return pimpl->acceleration;
1229  }
1230 
1232  {
1233  pimpl->acceleration = pimpl->state->qddot();
1234  return pimpl->acceleration;
1235  }
1236 
1237  const VectorXd& FullStateFeature::computeError(const Feature& featureDes) const
1238  {
1239  const FullStateFeature& sdes = dynamic_cast<const FullStateFeature&>(featureDes);
1240  pimpl->error = pimpl->state->q() - sdes.pimpl->state->q();
1241  return pimpl->error;
1242  }
1243 
1244  const VectorXd& FullStateFeature::computeError() const
1245  {
1246  pimpl->error = pimpl->state->q();
1247  return pimpl->error;
1248  }
1249 
1250  const VectorXd& FullStateFeature::computeErrorDot(const Feature& featureDes) const
1251  {
1252  const FullStateFeature& sdes = dynamic_cast<const FullStateFeature&>(featureDes);
1253  pimpl->errorDot = pimpl->state->qdot() - sdes.pimpl->state->qdot();
1254  return pimpl->errorDot;
1255  }
1256 
1257  const VectorXd& FullStateFeature::computeErrorDot() const
1258  {
1259  pimpl->errorDot = pimpl->state->qdot();
1260  return pimpl->errorDot;
1261  }
1262 
1263  const MatrixXd& FullStateFeature::computeJacobian(const Feature& featureDes) const
1264  {
1265  const FullStateFeature& sdes = dynamic_cast<const FullStateFeature&>(featureDes);
1266  pimpl->J = pimpl->state->getJacobian();
1267  return pimpl->J;
1268  }
1269 
1270  const MatrixXd& FullStateFeature::computeJacobian() const
1271  {
1272  pimpl->J = pimpl->state->getJacobian();
1273  return pimpl->J;
1274  }
1275 
1276  const MatrixXd& FullStateFeature::computeProjectedMass(const Feature& featureDes) const
1277  {
1278  const FullStateFeature& sdes = dynamic_cast<const FullStateFeature&>(featureDes);
1279  pimpl->M = pimpl->state->getInertiaMatrix();
1280  return pimpl->M;
1281  }
1282 
1284  {
1285  pimpl->M = pimpl->state->getInertiaMatrix();
1286  return pimpl->M;
1287  }
1288 
1289  const MatrixXd& FullStateFeature::computeProjectedMassInverse(const Feature& featureDes) const
1290  {
1291  const FullStateFeature& sdes = dynamic_cast<const FullStateFeature&>(featureDes);
1292  pimpl->M = pimpl->state->getInertiaMatrixInverse();
1293  return pimpl->M;
1294  }
1295 
1297  {
1298  pimpl->M = pimpl->state->getInertiaMatrixInverse();
1299  return pimpl->M;
1300  }
1301 
1303  {
1304  TaskState state;
1305  state.setQ(pimpl->state->q());
1306  state.setQd(pimpl->state->qdot());
1307  state.setQdd(pimpl->state->qddot());
1308 
1309  return state;
1310  }
1311 
1313  {
1314  try {
1315  FullTargetState::Ptr targetState = std::dynamic_pointer_cast<FullTargetState>(pimpl->state);
1316  if(newState.hasQ()) {
1317  targetState->set_q(newState.getQ());
1318  }
1319  if(newState.hasQd()) {
1320  targetState->set_qdot(newState.getQd());
1321  }
1322  if(newState.hasQdd()) {
1323  targetState->set_qddot(newState.getQdd());
1324  }
1325  } catch (int errCode) {
1326  std::cout << "You cannot set the state of this feature because it is not a desired feature. It must be constructed with a FullTargetState." << errCode << std::endl;
1327  }
1328  }
1329 
1330  // --- PARTIAL - ARTICULAR ------------------------------------
1331 
1333  {
1334  PartialState::Ptr state;
1335  VectorXd error;
1336  VectorXd errorDot;
1337  VectorXd effort;
1338  VectorXd acceleration;
1339  MatrixXd J;
1340  MatrixXd M;
1341  MatrixXd Minv;
1342  MatrixXd spaceTransform;
1343 
1344  Pimpl(PartialState::Ptr ps)
1345  : state(ps)
1346  {
1347  spaceTransform = MatrixXd::Identity(state->getSize(), state->getSize());
1348  }
1349  };
1350 
1351  PartialStateFeature::PartialStateFeature(const std::string& name, PartialState::Ptr state)
1352  : Feature(name)
1353  , pimpl( new Pimpl(state) )
1354  {
1355  }
1356 
1358  {
1359  return pimpl->spaceTransform;
1360  }
1361 
1363  {
1364  return pimpl->state->getSize();
1365  }
1366 
1367  const VectorXd& PartialStateFeature::computeEffort(const Feature& featureDes) const
1368  {
1369  const PartialStateFeature& sdes = dynamic_cast<const PartialStateFeature&>(featureDes);
1370  pimpl->effort = pimpl->state->tau() - sdes.pimpl->state->tau();
1371  return pimpl->effort;
1372  }
1373 
1374  const VectorXd& PartialStateFeature::computeEffort() const
1375  {
1376  pimpl->effort = pimpl->state->tau();
1377  return pimpl->effort;
1378  }
1379 
1380  const VectorXd& PartialStateFeature::computeAcceleration(const Feature& featureDes) const
1381  {
1382  const PartialStateFeature& sdes = dynamic_cast<const PartialStateFeature&>(featureDes);
1383  pimpl->acceleration = pimpl->state->qddot() - sdes.pimpl->state->qddot();
1384  return pimpl->acceleration;
1385  }
1386 
1388  {
1389  pimpl->acceleration = pimpl->state->qddot();
1390  return pimpl->acceleration;
1391  }
1392 
1393  const VectorXd& PartialStateFeature::computeError(const Feature& featureDes) const
1394  {
1395  const PartialStateFeature& sdes = dynamic_cast<const PartialStateFeature&>(featureDes);
1396  pimpl->error = pimpl->state->q() - sdes.pimpl->state->q();
1397  return pimpl->error;
1398  }
1399 
1400  const VectorXd& PartialStateFeature::computeError() const
1401  {
1402  pimpl->error = pimpl->state->q();
1403  return pimpl->error;
1404  }
1405 
1406  const VectorXd& PartialStateFeature::computeErrorDot(const Feature& featureDes) const
1407  {
1408  const PartialStateFeature& sdes = dynamic_cast<const PartialStateFeature&>(featureDes);
1409  pimpl->errorDot = pimpl->state->qdot() - sdes.pimpl->state->qdot();
1410  return pimpl->errorDot;
1411  }
1412 
1414  {
1415  pimpl->errorDot = pimpl->state->qdot();
1416  return pimpl->errorDot;
1417  }
1418 
1419  const MatrixXd& PartialStateFeature::computeJacobian(const Feature& featureDes) const
1420  {
1421  const PartialStateFeature& sdes = dynamic_cast<const PartialStateFeature&>(featureDes);
1422  pimpl->J = pimpl->state->getJacobian();
1423  return pimpl->J;
1424  }
1425 
1427  {
1428  pimpl->J = pimpl->state->getJacobian();
1429  return pimpl->J;
1430  }
1431 
1432  const MatrixXd& PartialStateFeature::computeProjectedMass(const Feature& featureDes) const
1433  {
1434  const PartialStateFeature& sdes = dynamic_cast<const PartialStateFeature&>(featureDes);
1435  pimpl->M = pimpl->state->getInertiaMatrix();
1436  return pimpl->M;
1437  }
1438 
1440  {
1441  pimpl->M = pimpl->state->getInertiaMatrix();
1442  return pimpl->M;
1443  }
1444 
1445  const MatrixXd& PartialStateFeature::computeProjectedMassInverse(const Feature& featureDes) const
1446  {
1447  const PartialStateFeature& sdes = dynamic_cast<const PartialStateFeature&>(featureDes);
1448  pimpl->M = pimpl->state->getInertiaMatrixInverse();
1449  return pimpl->M;
1450  }
1451 
1453  {
1454  pimpl->M = pimpl->state->getInertiaMatrixInverse();
1455  return pimpl->M;
1456  }
1458  {
1459  TaskState state;
1460  state.setQ(pimpl->state->q());
1461  state.setQd(pimpl->state->qdot());
1462  state.setQdd(pimpl->state->qddot());
1463 
1464  return state;
1465  }
1466 
1468  {
1469  try {
1470  PartialTargetState::Ptr targetState = std::dynamic_pointer_cast<PartialTargetState>(pimpl->state);
1471  if(newState.hasQ()) {
1472  targetState->set_q(newState.getQ());
1473  }
1474  if(newState.hasQd()) {
1475  targetState->set_qdot(newState.getQd());
1476  }
1477  if(newState.hasQdd()) {
1478  targetState->set_qddot(newState.getQdd());
1479  }
1480  } catch (int errCode) {
1481  std::cout << "You cannot set the state of this feature because it is not a desired feature. It must be constructed with a PartialTargetState." << errCode << std::endl;
1482  }
1483  }
1484 
1485 }
1486 
1487 // cmake:sourcegroup=Api
const Eigen::VectorXd & computeError() const
Definition: Feature.cpp:149
Used to build tasks in a partial configuration space.
Definition: Feature.h:369
const Eigen::MatrixXd & computeProjectedMassInverse() const
Definition: Feature.cpp:1128
PartialStateFeature(const std::string &name, PartialState::Ptr state)
Definition: Feature.cpp:1351
const Eigen::MatrixXd & getSpaceTransform() const
Definition: Feature.cpp:728
void setPosition(const Eigen::Displacementd &newPosition)
Definition: TaskState.cpp:79
const Eigen::MatrixXd & computeProjectedMassInverse() const
Definition: Feature.cpp:1296
void setState(const TaskState &newState)
Definition: Feature.cpp:981
TaskState getState() const
Definition: Feature.cpp:650
bool hasVelocity() const
Definition: TaskState.cpp:139
void setAcceleration(const Eigen::Twistd &newAcceleration)
Definition: TaskState.cpp:93
const Eigen::VectorXd & computeAcceleration() const
Definition: Feature.cpp:124
void setState(const TaskState &newState)
Definition: Feature.cpp:281
const Eigen::MatrixXd & computeJacobian() const
Definition: Feature.cpp:601
const Eigen::MatrixXd & computeProjectedMass() const
Definition: Feature.cpp:236
Used to build orientation tasks.
Definition: Feature.h:191
const Eigen::VectorXd & computeError() const
Definition: Feature.cpp:836
const Eigen::VectorXd & computeEffort() const
Definition: Feature.cpp:521
int getDimension() const
Definition: Feature.cpp:503
const Eigen::VectorXd & computeErrorDot() const
Definition: Feature.cpp:1413
const Eigen::MatrixXd & computeProjectedMass() const
Definition: Feature.cpp:937
Pimpl(ControlFrame::Ptr cf)
Definition: Feature.cpp:317
bool hasPosition() const
Definition: TaskState.cpp:134
int getDimension() const
Definition: Feature.cpp:1206
void setState(const TaskState &newState)
Definition: Feature.cpp:1150
void setState(const TaskState &newState)
Definition: Feature.cpp:1467
const Eigen::MatrixXd & computeJacobian() const
Definition: Feature.cpp:214
bool hasQ() const
Definition: TaskState.cpp:149
Eigen::VectorXd getQdd() const
Definition: TaskState.cpp:61
void set_q(const Eigen::VectorXd &q)
Definition: FullState.cpp:208
const Eigen::VectorXd & computeAcceleration() const
Definition: Feature.cpp:1387
const Eigen::MatrixXd & computeProjectedMass() const
Definition: Feature.cpp:408
DisplacementFeature(const std::string &name, ControlFrame::Ptr frame, ECartesianDof axes)
Definition: Feature.cpp:722
void setVelocity(const Eigen::Twistd &newVelocity)
Definition: TaskState.cpp:86
Pimpl(ControlFrame::Ptr cf)
Definition: Feature.cpp:480
const Eigen::VectorXd & computeEffort() const
Definition: Feature.cpp:97
A class hierarchy to compute task errors based on control frames.
const Eigen::VectorXd & computeErrorDot() const
Definition: Feature.cpp:1089
const Eigen::MatrixXd & computeJacobian() const
Definition: Feature.cpp:911
bool hasQd() const
Definition: TaskState.cpp:154
void setState(const TaskState &newState)
Definition: Feature.cpp:661
const Eigen::VectorXd & computeErrorDot() const
Definition: Feature.cpp:386
Feature interface, used by tasks to compute errors and jacobians.
Definition: Feature.h:55
Eigen::VectorXd getQd() const
Definition: TaskState.cpp:55
const Eigen::VectorXd & computeAcceleration() const
Definition: Feature.cpp:541
const Eigen::VectorXd & computeError() const
Definition: Feature.cpp:372
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
const Eigen::VectorXd & computeErrorDot() const
Definition: Feature.cpp:581
const Eigen::MatrixXd & getSpaceTransform() const
Definition: Feature.cpp:1357
const Eigen::MatrixXd & computeProjectedMassInverse() const
Definition: Feature.cpp:423
FullStateFeature(const std::string &name, FullState::Ptr state)
Definition: Feature.cpp:1195
const Eigen::VectorXd & computeErrorDot() const
Definition: Feature.cpp:873
const Eigen::VectorXd & computeEffort() const
Definition: Feature.cpp:761
const Eigen::VectorXd & computeError() const
Definition: Feature.cpp:1400
const Eigen::MatrixXd & computeProjectedMass() const
Definition: Feature.cpp:1283
const Eigen::MatrixXd & getSpaceTransform() const
Definition: Feature.cpp:1034
TaskState getState() const
Definition: Feature.cpp:1457
const Eigen::VectorXd & computeErrorDot() const
Definition: Feature.cpp:182
ControlFrame::Ptr controlFrame
Definition: Feature.cpp:470
virtual ~Feature()=0
Definition: Feature.cpp:17
Used to build positioning tasks.
Definition: Feature.h:101
int getDimension() const
Definition: Feature.cpp:1362
const Eigen::MatrixXd & getSpaceTransform() const
Definition: Feature.cpp:1201
const Eigen::MatrixXd & getSpaceTransform() const
Definition: Feature.cpp:335
const Eigen::VectorXd & computeAcceleration() const
Definition: Feature.cpp:361
bool hasAcceleration() const
Definition: TaskState.cpp:144
const Eigen::MatrixXd & computeProjectedMass() const
Definition: Feature.cpp:1439
const Eigen::MatrixXd & computeProjectedMassInverse() const
Definition: Feature.cpp:1452
Eigen::VectorXd getQ() const
Definition: TaskState.cpp:49
const Eigen::VectorXd & computeError() const
Definition: Feature.cpp:1074
void setPosition(const Eigen::Displacementd &H)
const Eigen::VectorXd & computeEffort() const
Definition: Feature.cpp:350
ECartesianDof
Definition: ControlEnum.h:18
Used to build tasks in the manikin configuration space.
Definition: Feature.h:326
PointContactFeature(const std::string &name, ControlFrame::Ptr frame)
Definition: Feature.cpp:329
const Eigen::MatrixXd & computeProjectedMass() const
Definition: Feature.cpp:617
const Eigen::VectorXd & computeEffort() const
Definition: Feature.cpp:1049
TaskState getState() const
Definition: Feature.cpp:970
const Eigen::VectorXd & computeError() const
Definition: Feature.cpp:1244
const Eigen::VectorXd & computeAcceleration() const
Definition: Feature.cpp:1062
TaskState getState() const
Definition: Feature.cpp:1139
ControlFrame::Ptr controlFrame
Definition: Feature.cpp:26
const Eigen::MatrixXd & computeProjectedMassInverse() const
Definition: Feature.cpp:959
const Eigen::MatrixXd & computeJacobian() const
Definition: Feature.cpp:1270
void set_q(const Eigen::VectorXd &q)
void setQd(const Eigen::VectorXd &newQd)
Definition: TaskState.cpp:107
const Eigen::MatrixXd & getSpaceTransform() const
Definition: Feature.cpp:498
ControlFrame::Ptr controlFrame
Definition: Feature.cpp:686
PositionFeature(const std::string &name, ControlFrame::Ptr frame, ECartesianDof axes)
Definition: Feature.cpp:60
void setState(const TaskState &newState)
Definition: Feature.cpp:445
TaskState getState() const
Definition: Feature.cpp:1302
Used to build position/orientation tasks.
Definition: Feature.h:235
const Eigen::MatrixXd & computeJacobian() const
Definition: Feature.cpp:397
const Eigen::MatrixXd & computeProjectedMass() const
Definition: Feature.cpp:1113
const Eigen::MatrixXd & computeProjectedMassInverse() const
Definition: Feature.cpp:639
const Eigen::MatrixXd & computeJacobian() const
Definition: Feature.cpp:1102
ContactConstraintFeature(const std::string &name, ControlFrame::Ptr frame)
Definition: Feature.cpp:1028
Pimpl(FullState::Ptr fs)
Definition: Feature.cpp:1188
bool hasWrench() const
Definition: TaskState.cpp:169
OrientationFeature(const std::string &name, ControlFrame::Ptr frame)
Definition: Feature.cpp:492
TaskState getState() const
Definition: Feature.cpp:270
void setQdd(const Eigen::VectorXd &newQdd)
Definition: TaskState.cpp:114
Eigen::Wrenchd getWrench() const
Definition: TaskState.cpp:73
Pimpl(ControlFrame::Ptr cf, ECartesianDof a)
Definition: Feature.cpp:38
Pimpl(ControlFrame::Ptr cf, ECartesianDof a)
Definition: Feature.cpp:699
bool hasQdd() const
Definition: TaskState.cpp:159
const Eigen::MatrixXd & getSpaceTransform() const
Definition: Feature.cpp:67
void setWrench(const Eigen::Wrenchd &newWrench)
Definition: TaskState.cpp:128
Eigen::Twistd getAcceleration() const
Definition: TaskState.cpp:43
const Eigen::VectorXd & computeError() const
Definition: Feature.cpp:560
void setQ(const Eigen::VectorXd &newQ)
Definition: TaskState.cpp:100
Eigen::Displacementd getPosition() const
Definition: TaskState.cpp:31
Eigen::Twistd getVelocity() const
Definition: TaskState.cpp:37
TaskState getState() const
Definition: Feature.cpp:434
int getDimension() const
Definition: Feature.cpp:738
const Eigen::MatrixXd & computeJacobian() const
Definition: Feature.cpp:1426
const Eigen::VectorXd & computeEffort() const
Definition: Feature.cpp:1374
const Eigen::MatrixXd & computeProjectedMassInverse() const
Definition: Feature.cpp:258
int getDimension() const
Definition: Feature.cpp:340
const Eigen::VectorXd & computeErrorDot() const
Definition: Feature.cpp:1257
int getDimension() const
Definition: Feature.cpp:74
int computeDimensionFor(ECartesianDof fixedPosition, ECartesianDof fixedOrientation)
Computes the number of directions specified by two ECartesianDof enums.
Definition: ControlEnum.h:39
void setState(const TaskState &newState)
Definition: Feature.cpp:1312
const Eigen::VectorXd & computeAcceleration() const
Definition: Feature.cpp:1231
A target for a model partial state.
Definition: PartialState.h:92
Represents a &#39;target&#39;, i.e. something that does not depend on a model but must match with another fra...
Definition: ControlFrame.h:75
const Eigen::VectorXd & computeEffort() const
Definition: Feature.cpp:1218
Pimpl(PartialState::Ptr ps)
Definition: Feature.cpp:1344
const Eigen::VectorXd & computeAcceleration() const
Definition: Feature.cpp:801
ControlFrame::Ptr controlFrame
Definition: Feature.cpp:307