ocra-recipes
Doxygen documentation for the ocra-recipes repository
JointLimitConstraint.cpp
Go to the documentation of this file.
1 
9 
10 
11 using namespace ocra;
12 
13 
16 
39  : NamedInstance("Joint Limit Equation Function")
40  , CoupledInputOutputSize(false)
41  , LinearFunction(var, 2*model.nbInternalDofs())
42  , hpos(.2)
43 {
44  // Set limit from model
47 }
48 
53 {
54 
55 }
56 
62 {
63  return hpos;
64 }
65 
71 {
72  hpos = newHpos;
73 }
74 
80 void JointLimitFunction::setJointLimits(const Eigen::VectorXd& lowerLimits, const Eigen::VectorXd& upperLimits)
81 {
82  setJointLowerLimits(lowerLimits);
83  setJointUpperLimits(upperLimits);
84 }
85 
90 void JointLimitFunction::setJointLowerLimits(const Eigen::VectorXd& newLowerLimits)
91 {
92  jointLowerLimits = newLowerLimits;
93 }
94 
99 void JointLimitFunction::setJointUpperLimits(const Eigen::VectorXd& newUpperLimits)
100 {
101  jointUpperLimits = newUpperLimits;
102 }
103 
110 void JointLimitFunction::setJointLimit(int i, double newLowerLimit, double newUpperLimit)
111 {
112  setJointLowerLimit(i, newLowerLimit);
113  setJointUpperLimit(i, newUpperLimit);
114 }
115 
121 void JointLimitFunction::setJointLowerLimit(int i, double newLowerLimit)
122 {
123  jointLowerLimits(i) = newLowerLimit;
124 }
125 
131 void JointLimitFunction::setJointUpperLimit(int i, double newUpperLimit)
132 {
133  jointUpperLimits(i) = newUpperLimit;
134 }
135 
140 const Eigen::VectorXd& JointLimitFunction::getJointLowerLimits() const
141 {
142  return jointLowerLimits;
143 }
144 
149 const Eigen::VectorXd& JointLimitFunction::getJointUpperLimits() const
150 {
151  return jointUpperLimits;
152 }
153 
160 {
161  return jointLowerLimits(i);
162 }
163 
170 {
171  return jointUpperLimits(i);
172 }
173 
185 void JointLimitFunction::computeFullJacobian(int varDofs, int nIDofs, Eigen::MatrixXd& fullJacobian) const
186 {
187  Eigen::MatrixXd Icut = Eigen::MatrixXd::Identity(varDofs, varDofs).bottomRows(nIDofs);
188 
189  fullJacobian = Eigen::MatrixXd::Zero(2*nIDofs, varDofs);
190  fullJacobian.topRows(nIDofs) = -Icut;
191  fullJacobian.bottomRows(nIDofs) = Icut;
192 }
193 
205 void JointLimitFunction::computeFullb(const Eigen::VectorXd& gpos, const Eigen::VectorXd& gvel, Eigen::VectorXd& fullb) const
206 {
207  // We compute the min and max accelerations of q to avoid joint limits:
208  // there is two min and max:
209  // - the first one is computed of a horizon h. The system brakes far from the limit, but can pass inside the constraint when close to it.
210  // - the second one is computed with the time of inflexion. The system brakes when close to the limits, but some singularities appears when it is on the limits.
211  //
212  // The two computation have their drawbacks, but together they allow limits avoidance properly.
213 
214  int nIDofs = gpos.size();
215 
216  Eigen::VectorXd maxDdqTotal = 2 * (jointUpperLimits - gpos - hpos * gvel)/(hpos*hpos);
217  Eigen::VectorXd minDdqTotal = 2 * (jointLowerLimits - gpos - hpos * gvel)/(hpos*hpos);
218 
219 
220 // tmin = -2*(gpos - qlim[:, 0]) / gvel
221 // tmax = -2*(gpos - qlim[:, 1]) / gvel
222 //
223 // tmin[tmin <= 0 ] = nan
224 // tmin[tmin > hpos] = nan
225 // tmin[isfinite(tmin)] = 1.
226 // tmax[tmax <= 0 ] = nan
227 // tmax[tmax > hpos] = nan
228 // tmax[isfinite(tmax)] = 1.
229 
230 // bmin_pos_time = gvel**2/(2*(gpos - qlim[:, 0])) * tmin
231 // bmax_pos_time = gvel**2/(2*(gpos - qlim[:, 1])) * tmax
232 
233 
234  for (int i=0; i<nIDofs; i++)
235  {
236  double tmax = -2*(gpos(i) - jointUpperLimits(i)) / gvel(i);
237  double tmin = -2*(gpos(i) - jointLowerLimits(i)) / gvel(i);
238 
239  if ((0 <= tmax) && (tmax <= hpos))
240  {
241  double ddqlim = (gvel(i)*gvel(i))/(2*(gpos(i) - jointUpperLimits(i)));
242  if (maxDdqTotal(i) >= ddqlim)
243  {
244  maxDdqTotal(i) = ddqlim;
245  }
246  }
247  if ((0 <= tmin) && (tmin <= hpos))
248  {
249  double ddqlim = (gvel(i)*gvel(i))/(2*(gpos(i) - jointLowerLimits(i)));
250  if (minDdqTotal(i) <= ddqlim)
251  {
252  minDdqTotal(i) = ddqlim;
253  }
254  }
255  }
256 
257  fullb.head(nIDofs) = maxDdqTotal;
258  fullb.tail(nIDofs) = - minDdqTotal;
259 
260 }
261 
262 
263 
264 
265 
266 
267 
268 
269 
270 
271 
272 
273 
274 
275 
276 
277 
279 {
280  const Model& _model;
281 
282  Pimpl(const Model& model)
283  : _model(model)
284  {
285 
286  }
287 };
288 
289 
298  : NamedInstance("Full Joint Limit Equation Function")
300  , CoupledInputOutputSize(false)
301  , JointLimitFunction(model, model.getAccelerationVariable())
302  , pimpl(new Pimpl(model))
303 {
304  //_model.connect<EVT_CHANGE_VALUE>(*this, &FullJointLimitFunction::invalidateAll); // not necessary because A (jacobian) is constant
305  pimpl->_model.connect<EVT_CHANGE_VALUE>(*this, &FullJointLimitFunction::invalidateb); //to update b at each time step
306 
307  int varDofs = model.getAccelerationVariable().getSize();
308 
309  computeFullJacobian(varDofs, pimpl->_model.nbInternalDofs(), _jacobian);
310 
311 }
312 
318 {
319  //_model.disconnect<EVT_CHANGE_VALUE>(*this, &FullJointLimitFunction::invalidateAll);
320  pimpl->_model.disconnect<EVT_CHANGE_VALUE>(*this, &FullJointLimitFunction::invalidateb);
321 }
322 
328 {
329  computeFullb(pimpl->_model.getJointPositions(), pimpl->_model.getJointVelocities(), _b);
330 }
331 
332 
333 
334 
335 
336 
337 
338 
339 
340 
341 
342 
343 
344 
345 
346 
347 
349 {
350  const Model& _model;
352 
353  Eigen::MatrixXd _fullJacobian;
354 
355  Pimpl(const Model& model, const FullDynamicEquationFunction& dynamicEquation)
356  : _model(model)
357  , _dynamicEquation(dynamicEquation)
358  {
359 
360  }
361 };
362 
363 
373  : NamedInstance("Reduced Joint Limit Equation Function")
375  , CoupledInputOutputSize(false)
376  , JointLimitFunction(model, dynamicEquation.getActionVariable())
377  , pimpl(new Pimpl(model, dynamicEquation))
378 {
379  pimpl->_model.connect<EVT_CHANGE_VALUE>(*this, &ReducedJointLimitFunction::invalidateAll);
380  pimpl->_model.connect<EVT_CHANGE_VALUE>(*this, &ReducedJointLimitFunction::invalidateb); //to update b at each time step
381 
382  computeFullJacobian(pimpl->_model.nbDofs(), pimpl->_model.nbInternalDofs(), pimpl->_fullJacobian);
383 }
384 
390 {
391  pimpl->_model.disconnect<EVT_CHANGE_VALUE>(*this, &ReducedJointLimitFunction::invalidateAll);
392  pimpl->_model.disconnect<EVT_CHANGE_VALUE>(*this, &ReducedJointLimitFunction::invalidateb);
393 }
394 
395 
396 
398 {
399 
400  _jacobian = - pimpl->_fullJacobian * pimpl->_dynamicEquation.getInertiaMatrixInverseJchiT();
401 }
402 
403 
410 {
411  Eigen::VectorXd _fullb(_b.size());
412  computeFullb(pimpl->_model.getJointPositions(), pimpl->_model.getJointVelocities(), _fullb);
413 
414  //_jacobian = pimpl->_fullJacobian * pimpl->_model.getInertiaMatrixInverseJchiT();
415  _b = _fullb - pimpl->_fullJacobian * pimpl->_dynamicEquation.getInertiaMatrixInverseLinNonLinGrav();
416 }
417 
418 
419 
425 void ReducedJointLimitFunction::doUpdateInputSizeBegin()
426 {
427  //do nothing : this overload allows to resize
428 }
429 
435 void ReducedJointLimitFunction::doUpdateInputSizeEnd()
436 {
437  computeFullJacobian(pimpl->_model.nbDofs(), pimpl->_model.nbInternalDofs(), pimpl->_fullJacobian);
438 }
439 
440 
441 
442 
443 
444 
445 
446 
447 
448 
449 
450 
451 
452 
454  : _model(model)
455  , _is_connected(false)
457 {
460 }
461 
462 JointLimitConstraint::JointLimitConstraint(const Model& model, const Eigen::VectorXd& lowerLimits, const Eigen::VectorXd& upperLimits, double hpos)
463  : _model(model)
464  , _is_connected(false)
466 {
468  setJointLimits(lowerLimits, upperLimits);
469 }
470 
471 
472 
474 {
475  return _hpos;
476 }
477 const Eigen::VectorXd& JointLimitConstraint::getJointLowerLimits() const
478 {
479  return _lowerLimits;
480 }
481 
482 const Eigen::VectorXd& JointLimitConstraint::getJointUpperLimits() const
483 {
484  return _upperLimits;
485 }
486 
488 {
489  return _lowerLimits(i);
490 }
491 
493 {
494  return _upperLimits(i);
495 }
496 
498 {
499  _hpos = newHpos;
500  if (_is_connected)
501  _jointLimitFunction->setHorizonOfPrediction(newHpos);
502 }
503 
504 void JointLimitConstraint::setJointLimits(const Eigen::VectorXd& lowerLimits, const Eigen::VectorXd& upperLimits)
505 {
506  _lowerLimits = lowerLimits;
507  _upperLimits = upperLimits;
508  if (_is_connected)
509  _jointLimitFunction->setJointLimits(lowerLimits, upperLimits);
510 }
511 
512 void JointLimitConstraint::setJointLowerLimits(const Eigen::VectorXd& newLowerLimits)
513 {
514  _lowerLimits = newLowerLimits;
515  if (_is_connected)
516  _jointLimitFunction->setJointLowerLimits(newLowerLimits);
517 }
518 
519 void JointLimitConstraint::setJointUpperLimits(const Eigen::VectorXd& newUpperLimits)
520 {
521  _upperLimits = newUpperLimits;
522  if (_is_connected)
523  _jointLimitFunction->setJointUpperLimits(newUpperLimits);
524 }
525 
526 void JointLimitConstraint::setJointLimit(int i, double newLowerLimit, double newUpperLimit)
527 {
528  _lowerLimits(i) = newLowerLimit;
529  _upperLimits(i) = newUpperLimit;
530  if (_is_connected)
531  _jointLimitFunction->setJointLimit(i, newLowerLimit, newUpperLimit);
532 }
533 void JointLimitConstraint::setJointLowerLimit(int i, double newLowerLimit)
534 {
535  _lowerLimits(i) = newLowerLimit;
536  if (_is_connected)
537  _jointLimitFunction->setJointLowerLimit(i, newLowerLimit);
538 }
539 
540 void JointLimitConstraint::setJointUpperLimit(int i, double newUpperLimit)
541 {
542  _upperLimits(i) = newUpperLimit;
543  if (_is_connected)
544  _jointLimitFunction->setJointUpperLimit(i, newUpperLimit);
545 }
546 
547 
548 void JointLimitConstraint::connectToController(const FullDynamicEquationFunction& dynamicEquation, bool useReducedProblem)
549 {
550  LinearFunction* f = NULL;
551  if (useReducedProblem)
552  f = createReducedJointLimitFunction(_model, dynamicEquation);
553  else
554  f = createFullJointLimitFunction(_model);
555 
556  _constraint.reset(new LinearConstraint(f));
557  _is_connected = true;
558 
559  setHorizonOfPrediction(_hpos);
560  setJointLowerLimits( _lowerLimits );
561  setJointUpperLimits( _upperLimits );
562 }
563 
565 {
566  _is_connected = false;
567 }
568 
569 
570 JointLimitFunction* JointLimitConstraint::createFullJointLimitFunction(const Model& model)
571 {
572  _jointLimitFunction = new FullJointLimitFunction(model);
573  return _jointLimitFunction;
574 }
575 
576 JointLimitFunction* JointLimitConstraint::createReducedJointLimitFunction(const Model& model, const FullDynamicEquationFunction& dynamicEquation)
577 {
578  _jointLimitFunction = new ReducedJointLimitFunction(model, dynamicEquation);
579  return _jointLimitFunction;
580 }
Create a linear function that represents the joint limit function for the reduced formalism...
ReducedJointLimitFunction(const Model &model, const FullDynamicEquationFunction &dynamicEquation)
void setJointUpperLimit(int i, double newUpperLimit)
double getJointUpperLimit(int i) const
void setJointLowerLimit(int i, double newLowerLimit)
void setJointLimit(int i, double newLowerLimit, double newUpperLimit)
JointLimitFunction(const Model &m, Variable &var)
virtual const Eigen::VectorXd & getJointUpperLimits() const =0
double getJointLowerLimit(int i) const
Define joint limit constraint for wOcra controller.
void setJointLimits(const Eigen::VectorXd &lowerLimits, const Eigen::VectorXd &upperLimits)
Constraint< LinearFunction > LinearConstraint
Definition: Constraint.h:673
void setHorizonOfPrediction(double newHpos)
void setJointUpperLimits(const Eigen::VectorXd &newUpperLimits)
double getJointUpperLimit(int i) const
const Eigen::VectorXd & getJointUpperLimits() const
Model class.
Definition: Model.h:38
LinearFunction class.
const Eigen::VectorXd & getJointLowerLimits() const
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
boost::shared_ptr< Constraint< LinearFunction > > _constraint
Create a linear function that represents the joint limit function.
MatrixXd & _jacobian
Definition: Function.h:313
Create a linear function that represents the joint limit function for the full formalism.
void computeFullb(const Eigen::VectorXd &gpos, const Eigen::VectorXd &gvel, Eigen::VectorXd &fullb) const
double getJointLowerLimit(int i) const
void setJointLowerLimit(int i, double newLowerLimit)
double getHorizonOfPrediction() const
FullJointLimitFunction(const Model &model)
int getSize() const
Definition: Variable.cpp:81
void computeFullJacobian(int varDofs, int nIDofs, Eigen::MatrixXd &fullJacobian) const
void invalidateb(int timestamp)
This class represents a variable in a mathematical sense.
Definition: Variable.h:105
Create a linear function that represents the dynamic equation of motion.
JointLimitConstraint(const Model &model, double hpos=.2)
void setHorizonOfPrediction(double newHpos)
virtual void connectToController(const FullDynamicEquationFunction &dynamicEquation, bool useReducedProblem)
Variable & getAccelerationVariable() const
Definition: Model.cpp:133
void invalidateAll()
Definition: Function.h:330
const Eigen::VectorXd & getJointLowerLimits() const
void setJointUpperLimits(const Eigen::VectorXd &newUpperLimits)
void setJointLimits(const Eigen::VectorXd &lowerLimits, const Eigen::VectorXd &upperLimits)
const FullDynamicEquationFunction & _dynamicEquation
void setJointLowerLimits(const Eigen::VectorXd &newLowerLimits)
void setJointLimit(int i, double newLowerLimit, double newUpperLimit)
virtual const Eigen::VectorXd & getJointLowerLimits() const =0
const Eigen::VectorXd & getJointUpperLimits() const
void setJointUpperLimit(int i, double newUpperLimit)
Pimpl(const Model &model, const FullDynamicEquationFunction &dynamicEquation)
void setJointLowerLimits(const Eigen::VectorXd &newLowerLimits)