ocra-recipes
Doxygen documentation for the ocra-recipes repository
FullDynamicEquationFunction.cpp
Go to the documentation of this file.
1 
9 
10 
11 using namespace ocra;
12 
13 
14 
17 {
18  const Model& _model;
21 
22  // ADD ACTION VARIABLE
25 
26  Eigen::MatrixXd _InertiaMatrixInverseJchiT;
28  bool _useGrav;
29 
30 
31  Pimpl(const Model& model)
32  : _model(model)
33  , _tau(model.getJointTorqueVariable())
34  , _fc(model.getModelContacts().getContactForcesVariable())
35  , _chi("chi", model.getJointTorqueVariable(), model.getModelContacts().getContactForcesVariable())
36  , _reducedProblemDataAreUpToDate(false)
37  , _useGrav(true)
38  , _InertiaMatrixInverseJchiT(model.nbDofs(), model.nbDofs())
39  , _InertiaMatrixInverseLinNonLinGrav(model.nbDofs())
40  {
41 
42  }
43 
44  void updateReduceProblemData(const Eigen::MatrixXd& _jacobian, const Eigen::VectorXd& _b)
45  {
46  const Eigen::MatrixXd& Minv = _model.getInertiaMatrixInverse();
47  const Eigen::MatrixXd& JchiT = _jacobian.rightCols(_chi.getSize());
48 
49  _InertiaMatrixInverseJchiT = Minv * JchiT;
50  _InertiaMatrixInverseLinNonLinGrav = Minv * _b;
51 
52  _reducedProblemDataAreUpToDate = true;
53  }
54 };
55 
63  : NamedInstance("Full Dynamic Equation Function")
65  , CoupledInputOutputSize(false)
66  , LinearFunction(createDEVariable(model), model.nbDofs())
67  , pimpl( new Pimpl(model))
68 {
69  buildA();
70 
71  pimpl->_model.connect<EVT_CHANGE_VALUE>(*this, &FullDynamicEquationFunction::invalidateAll);
72  pimpl->_model.connect<EVT_CHANGE_VALUE>(*this, &FullDynamicEquationFunction::invalidateb);
73  pimpl->_model.connect<EVT_CHANGE_VALUE>(*this, &FullDynamicEquationFunction::invalidateReducedProblemData);
74 }
75 
80 {
81  pimpl->_model.disconnect<EVT_CHANGE_VALUE>(*this, &FullDynamicEquationFunction::invalidateAll);
82  pimpl->_model.disconnect<EVT_CHANGE_VALUE>(*this, &FullDynamicEquationFunction::invalidateb);
83  pimpl->_model.disconnect<EVT_CHANGE_VALUE>(*this, &FullDynamicEquationFunction::invalidateReducedProblemData);
84  delete &getVariable();
85 }
86 
87 
89 {
90  pimpl->_useGrav = useGrav;
91 }
92 
93 
94 
101 {
102  _jacobian.leftCols(_dim) = pimpl->_model.getInertiaMatrix(); // we update the M part
103  _jacobian.rightCols(pimpl->_fc.getSize()) = pimpl->_model.getModelContacts().getJct(); // we update the Jc.T part
104 }
105 
111 {
112  if (pimpl->_useGrav)
113  _b = pimpl->_model.getLinearTerms() + pimpl->_model.getNonLinearTerms() + pimpl->_model.getGravityTerms();
114  else
115  _b = pimpl->_model.getLinearTerms() + pimpl->_model.getNonLinearTerms();
116 }
117 
124 {
125  /* the dynamic equation is of the form:
126  *
127  * M ddq + n + l + g = S tau - Jc.T fc
128  *
129  * by gathering all the variables, it leads to:
130  *
131  * | ddq |
132  * | tau |
133  * [ M -S Jc.T]| fc | + (n + l + g) = 0
134  *
135  * The dimension should not change, so we initialize all the jacobian and b here;
136  * S is constant so we can set here;
137  */
138  _jacobian.setZero();
139 
140  // Here we update the S part;
141  // If the robot has not a fixed root, then we need to delete the 6 first column in the actuatedDof diag, that's why this trick
142  int index = pimpl->_model.hasFixedRoot() ? 0 : 6;
143  _jacobian.block(0, _dim, _dim, pimpl->_tau.getSize()).setZero();
144  _jacobian.block(index, _dim, pimpl->_tau.getSize(), pimpl->_tau.getSize()).diagonal() = -pimpl->_model.getActuatedDofs();
145 }
146 
147 
156 Variable& FullDynamicEquationFunction::createDEVariable(const Model& model)
157 {
158  static int cpt = 0;
159  std::stringstream name;
160  name << "dyn_eq" << cpt++;
161  CompositeVariable* var = new CompositeVariable(name.str(), model.getAccelerationVariable());
162  var->add(model.getJointTorqueVariable()); //
163  var->add(model.getModelContacts().getContactForcesVariable()); // [tau, fc] should be the same order as that of _chi in pimpl
164  return *var;
165 }
166 
167 
174 {
175  //do nothing : this overload allows to resize
176 }
177 
184 {
185  buildA();
186 }
187 
188 void FullDynamicEquationFunction::invalidateReducedProblemData(int timestamp)
189 {
190  pimpl->_reducedProblemDataAreUpToDate = false;
191 }
192 
193 
195 {
196  if (!pimpl->_reducedProblemDataAreUpToDate)
197  pimpl->updateReduceProblemData( getJacobian(), getb() );
198  return pimpl->_InertiaMatrixInverseJchiT;
199 }
200 
202 {
203  if (!pimpl->_reducedProblemDataAreUpToDate)
204  pimpl->updateReduceProblemData( getJacobian(), getb() );
205  return pimpl->_InertiaMatrixInverseLinNonLinGrav;
206 }
207 
209 {
210  return pimpl->_chi;
211 }
const Variable & getVariable() const
Definition: Function.cpp:46
void updateReduceProblemData(const Eigen::MatrixXd &_jacobian, const Eigen::VectorXd &_b)
const Eigen::VectorXd & getInertiaMatrixInverseLinNonLinGrav() const
Model class.
Definition: Model.h:38
LinearFunction class.
Variable & getContactForcesVariable() const
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
MatrixXd & _jacobian
Definition: Function.h:313
const MatrixXd & getJacobian() const
Definition: Function.h:375
int getSize() const
Definition: Variable.cpp:81
const VectorXd & getb() const
void invalidateb(int timestamp)
This class represents a variable in a mathematical sense.
Definition: Variable.h:105
Variable & getJointTorqueVariable() const
Definition: Model.cpp:138
Variable & getAccelerationVariable() const
Definition: Model.cpp:133
void invalidateAll()
Definition: Function.h:330
CompositeVariable & add(Variable &child)
Attach/detach the child to/from this node.
Definition: Variable.cpp:580
A concatenation of base variables and other composite variables.
Definition: Variable.h:357
virtual const Eigen::MatrixXd & getInertiaMatrixInverse() const =0
Define base class that can be used as constraints in wOcra controller.
const int & _dim
Definition: Function.h:320
const Eigen::MatrixXd & getInertiaMatrixInverseJchiT() const
ModelContacts & getModelContacts() const
Definition: Model.cpp:186