ocra-recipes
Doxygen documentation for the ocra-recipes repository
CascadeQPSolver.cpp
Go to the documentation of this file.
2 
3 #include <algorithm>
4 #include <ocra/util/Macros.h>
5 // #include <boost/range/adaptor/reversed.hpp>
6 
7 namespace ocra
8 {
10 {
11  Model::Ptr innerModel;
12  // EQUALITY CONSTRAINT OF THE DYNAMIC EQUATION
14 
15  // MINIMIZATION TASK FOR WHOLE VARIABLE MINIMIZATION
19 
23 
25 
26  : innerModel(m)
27  , dynamicEquation( new ocra::FullDynamicEquationFunction(*m) )
28 
29  , minDdqFunction( new ocra::SquaredLinearFunction( new LinearFunction(m->getAccelerationVariable(), Eigen::MatrixXd::Identity(m->nbDofs(), m->nbDofs()), Eigen::VectorXd::Zero(m->nbDofs()))))
30  , minTauFunction( new ocra::SquaredLinearFunction(new LinearFunction(m->getJointTorqueVariable(),
31  Eigen::MatrixXd::Identity(m->getJointTorqueVariable().getSize(),
32  m->getJointTorqueVariable().getSize()),
33  Eigen::VectorXd::Zero(m->getJointTorqueVariable().getSize())) ))
34 
35  , minFcFunction( new FcQuadraticFunction(m->getModelContacts().getContactForcesVariable()) )
36 
37  {
38  minDdqObjective.set(minDdqFunction);
39  minTauObjective.set(minTauFunction);
40  minFcObjective.set(minFcFunction);
41  minDdqObjective.getObjective().setWeight(1e-7);
42  minTauObjective.getObjective().setWeight(1e-8);
43  minFcObjective.getObjective().setWeight(1e-9);
44  dynamicEquation.getFunction().takeIntoAccountGravity(true);
45 
46  }
47 };
48 
49 
50 
51 CascadeQPSolver::CascadeQPSolver(const std::string& _ctrlName,
52  Model::Ptr _innerModel,
53  OneLevelSolver::Ptr _levelSolver,
54  bool _useReducedProblem):
55  ocra::Solver(),
56  ocra::NamedInstance("CascadeQPSolver"),
57  levelSolver(_levelSolver),
58  innerModel(_innerModel),
59  useReducedProblem(_useReducedProblem),
61 {
62 
63  internalAddConstraint(own_obj->dynamicEquation.getConstraint());
64  internalAddObjective(own_obj->minDdqObjective);
65  internalAddObjective(own_obj->minTauObjective);
66 // internalAddObjective(own_obj->minFcObjective);
67 
68  //std::cout << "CascadeQPSolver constructor WITH "<<this->getProblemVariable().getSize()<<" VARIABLES " << std::endl;
69 }
70 
72 {
73  //std::cout << "[[[[[[--------- CascadeQPSolver Update for level "<<level<<" -------- ]]]] "<< std::endl;
74 
75  for(auto m : solvermap)
76  {
77  if(level == m.first) return;
78  //std::cout << "---------\n Updating constraints from level "<<m.first<< std::endl;
79  auto solver = m.second;
80  Eigen::VectorXd full_solution = solver->getLastResult().solution;
81  //std::cout << "full_solution:"<<full_solution.transpose()<<std::endl;
82 
83  for(auto obj : solver->getObjectives())
84  {
85 
86  auto& f_obj = static_cast<SquaredLinearObjective*>(obj)->getFunction().getFunction();
87 
88  if(has_element(_exclusion_constraints[m.first],&obj->getFunction()))
89  {
90  //std::cout << "Function "<<&obj->getFunction()<<" is excluded, passing.."<<std::endl;
91  continue;
92  }
93 
94  auto& var = f_obj.getVariable();
95 
96  //std::cout << "f_obj.getA():\n\n"<<f_obj.getA()<<std::endl;
97 
98  const std::vector<int>& mapping = solver->findMapping(obj->getVariable());
99 
100  //std::cout << "Var size :"<<var.getSize()<<std::endl;
101 
102  Eigen::VectorXd minus_solution(var.getSize());
103  for(int i=0;i<mapping.size();i++)
104  minus_solution[i] = - full_solution[mapping[i]];
105 
106 
107  //std::cout << " solution:"<<minus_solution.transpose()<<std::endl;
108 
109  if(levelConstraints[level][m.first].find(&f_obj) == levelConstraints[level][m.first].end())
110  {
111  //std::cout << "Adding constaints for function "<<&f_obj<<std::endl;
112  levelConstraints[level][m.first][&f_obj] = EqualZeroConstraintPtr<LinearFunction>(new LinearFunction(var,f_obj.getA(),f_obj.getb()));
113 
114  getSolver(level)->addConstraint(levelConstraints[level][m.first][&f_obj].getConstraint());
115 
116  }else{
117  //std::cout << "Function "<<&f_obj<<" already exists"<<std::endl;
118  }
119 
120  auto& f = levelConstraints[level][m.first][&f_obj].getFunction();
121  f.changeb( f_obj.getA() * minus_solution );
122  f.changeA( f_obj.getA() );
123  }
124 
125  }
126 
127 }
129 {
130  int n = 0;
131  for(auto m : solvermap)
132  if(m.first == current_level)
133  break;
134  else
135  n++;
136  return n;
137 }
138 
140 {
141  //std::cout << "CascadeQPSolver::doSolve" << std::endl;
142  OptimizationResult tmp_res;
143  for(auto m : solvermap)
144  {
145 
147 
148  //std::cout << "Solving" << std::endl;
149 
150  tmp_res = m.second->solve();
151  if(tmp_res.info == ocra::RETURN_SUCCESS)
152  _result = tmp_res;
153  //std::cout << "RESULT "<<m.first<<" : "<< _result.solution.transpose() << std::endl;
154  //std::cout << "Solved" << std::endl;
155  }
156 
157  //std::cout << "FINAL RESULT : "<< _result.solution.transpose() << std::endl;
158 }
159 
160 
162 {
163  //std::cout << "CascadeQPSolver::doPrepare" << std::endl;
164 }
165 
166 
168 {
169  //std::cout << "CascadeQPSolver::doConclude" << std::endl;
170 }
171 
172 
174 {
175 
176 }
177 const std::map< int, OneLevelSolver::Ptr >& CascadeQPSolver::getSolvers()
178 {
179  return this->solvermap;
180 }
181 
182 void CascadeQPSolver::addSolver(OneLevelSolver::Ptr solver, int level)
183 {
184 
185  if(solvermap.find(level) == solvermap.end())
186  {
187  bool solverexists = false;
188  for( auto sm : solvermap)
189  if(sm.second.get() == solver.get())
190  solverexists = true;
191  if(solverexists)
192  {
193  //std::cout << "[Warning] You are tying to add al already existing solver, I'm cloning for you a new " << solver->getName() << std::endl;
194  this->solvermap[level] = solver->clone();
195  } else {
196  //std::cout << "Adding solver " << solver->getName() << " at level "<<level<< std::endl;
197  this->solvermap[level] = solver;
198  }
199  } else {
200  //std::cout << "A Solver is already present at level " << level<< " : "<<solvermap[level]->getName() << std::endl;
201  }
202 // int current_highest_hierarchy_level = solvermap.begin()->first;
203 // if(solvermap.size() > 1 &&
204 // current_highest_hierarchy_level != highest_hierarchy_level)
205 // {
206 // // Remove all the regularisation objectives
207 // // As the lower levels will have them as constraints
208 // solver->removeObjective(std_obj[level]->minDdqObjective);
209 // solver->removeObjective(std_obj[level]->minTauObjective);
210 //
211 // }
212 }
213 
214 OneLevelSolver::Ptr CascadeQPSolver::getSolver(int level)
215 {
216  return solvermap.at(level);
217 }
219 {
220 
221  if(_exclusion_constraints.find(at_level) == _exclusion_constraints.end() ||
222  has_element(_exclusion_constraints[at_level],&obj.getFunction()) == false)
223  {
224  //std::cout << "Function "<<&obj.getFunction()<<" at level "<<at_level<<" is EXCLUDED"<<std::endl;
225  _exclusion_constraints[at_level].push_back(&obj.getFunction());
226  }else
227  {
228  //std::cout << "Function "<<&obj.getFunction()<<" is already in the exclusion vector"<<std::endl;
229  }
230 }
231 
232 void CascadeQPSolver::addTask(Task::Ptr task)
233 {
234  const int level = task->getHierarchyLevel();
235  if(task->isActiveAsObjective())
236  this->taskmap[level].push_back(task);
237  else if(task->isActiveAsConstraint())
238  for(auto& tm : taskmap)
239  this->taskmap[level].push_back(task);
240 
241  if(std::find(solverInitialized.begin(),solverInitialized.end(),level) == solverInitialized.end())
242  {
243  //std::cout << "Initializing constraints and regulation terms at level "<<level << std::endl;
244  solverInitialized.push_back(level);
245  std_obj[level] = std::make_shared<StandardObjectivesAndConstraints>(innerModel);
246  auto new_solver = levelSolver->clone();
247 
248  new_solver->addConstraint(std_obj[level]->dynamicEquation.getConstraint());
249  new_solver->addObjective(std_obj[level]->minDdqObjective);
250  new_solver->addObjective(std_obj[level]->minTauObjective);
251 
252  excludeObjective(level,std_obj[level]->minDdqObjective);
253  excludeObjective(level,std_obj[level]->minTauObjective);
254 // new_solver->addObjective(std_obj[level]->minFcObjective);
255 
256  this->addSolver(new_solver,level);
257 
258  }
259  try {
260  task->connectToController(this->getSolver(level),
261  std_obj[level]->dynamicEquation,
263  }
264  catch(const std::exception & e) {
265  std::cerr << e.what() ;
266  throw std::runtime_error("[HocraController::doAddTask] cannot add task to controller (wrong type)");
267  }
268 }
269 
271 {
272 
273 }
274 
275 
276 } // Namespace ocra
const Variable & getVariable() const
Definition: Function.cpp:46
ocra::EqualZeroConstraintPtr< ocra::FullDynamicEquationFunction > dynamicEquation
OneLevelSolver::Ptr levelSolver
ObjectivePtr< ocra::QuadraticFunction > minFcObjective
void internalAddConstraint(const GenericConstraint &constraint)
Definition: Solver.cpp:91
virtual void doPrepare(void)
virtual void printValuesAtSolution()
int getNumberOfLevelsAbove(int current_level)
void excludeObjective(int at_level, const ocra::GenericObjective &obj)
void internalAddObjective(const GenericObjective &objective)
Definition: Solver.cpp:77
OptimizationResult _result
Definition: Solver.h:215
std::shared_ptr< StandardObjectivesAndConstraints > own_obj
CascadeQPSolver(const std::string &_ctrlName, Model::Ptr _innerModel, OneLevelSolver::Ptr _levelSolver, bool _useReducedProblem)
LinearFunction class.
ObjectivePtr< ocra::QuadraticFunction > minTauObjective
Objective< T > & getObjective()
ObjectivePtr< ocra::QuadraticFunction > minDdqObjective
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
virtual T & getFunction(void)
Definition: Objective.h:64
OneLevelSolver::Ptr getSolver(int level)
Create a linear function that represents the dynamic equation of motion.
SquaredLinearFunction class.
virtual void doSolve(void)
std::map< int, std::shared_ptr< StandardObjectivesAndConstraints > > std_obj
virtual Function & getFunction()
Definition: Objective.h:97
void updateHierarchicalContraints(int level)
int n()
Definition: Solver.h:146
void addTask(Task::Ptr task)
QuadraticFunction class.
Declaration file of the CascadeQPSolver class.
void set(T *f, double weight=1.)
Solver class.
Definition: Solver.h:70
std::vector< int > solverInitialized
void addSolver(OneLevelSolver::Ptr solver, int level)
virtual std::string toString()
const std::map< int, OneLevelSolver::Ptr > & getSolvers()