ocra-recipes
Doxygen documentation for the ocra-recipes repository
WocraController.cpp
Go to the documentation of this file.
1 
9 
10 #include <iostream>
11 
13 #include "wocra/Performances.h"
14 
18 namespace wocra
19 {
20 
22  {
23  std::shared_ptr<Model> innerModel;
24  std::shared_ptr<OneLevelSolver> innerSolver;
26 
27 
28  // EQUALITY CONSTRAINT OF THE DYNAMIC EQUATION
30 
31  // MINIMIZATION TASK FOR WHOLE VARIABLE MINIMIZATION
35 
39 
40 
41  // PERFORMANCE RECORDERS
43 
45 
46 
47  Pimpl(std::shared_ptr<Model> m, std::shared_ptr<OneLevelSolver> s, bool useReducedProblem)
48 
49  : innerModel(m)
50 
51  , innerSolver(s)
52 
53  , reducedProblem(useReducedProblem)
54  , dynamicEquation( new ocra::FullDynamicEquationFunction(*m) )
55 
56  , minDdqFunction( new ocra::QuadraticFunction(m->getAccelerationVariable(), Eigen::MatrixXd::Identity(m->nbDofs(), m->nbDofs()), Eigen::VectorXd::Zero(m->nbDofs()), 0) )
57 
58  , minTauFunction( new ocra::QuadraticFunction(m->getJointTorqueVariable(), Eigen::MatrixXd::Identity(m->getJointTorqueVariable().getSize(), m->getJointTorqueVariable().getSize()), Eigen::VectorXd::Zero(m->getJointTorqueVariable().getSize()), 0) )
59 
60  , minFcFunction( new FcQuadraticFunction(m->getModelContacts().getContactForcesVariable()) )
61 
62  {
63  minDdqObjective.set(minDdqFunction);
64  minTauObjective.set(minTauFunction);
65  minFcObjective.set(minFcFunction);
66 
67  }
68 
70  {
71  }
72 
73  };
74 
75 
76 
77  // ############# WocraController Class ###############################################################
78 
79 
80  WocraController::WocraController(const std::string& ctrlName, std::shared_ptr<Model> innerModel, std::shared_ptr<OneLevelSolver> innerSolver, bool useReducedProblem)
81 
82  : Controller(ctrlName, *innerModel)
83 
84  , pimpl( new Pimpl(innerModel, innerSolver, useReducedProblem) )
85 
86  {
87 
88  if (!pimpl->reducedProblem)
89 
90  {
91 
92  pimpl->innerSolver->addConstraint(pimpl->dynamicEquation.getConstraint());
93  pimpl->innerSolver->addObjective(pimpl->minDdqObjective);
94  pimpl->innerSolver->addObjective(pimpl->minTauObjective);
95  pimpl->innerSolver->addObjective(pimpl->minFcObjective);
96 
97  // double predictionHorizon = 0.2;
98  // jointLimitConstraint = std::make_shared<ocra::JointLimitConstraint>(*pimpl->innerModel);//, predictionHorizon);
99  // addConstraint(*jointLimitConstraint);
100  // Eigen::VectorXd torqueLims = Eigen::VectorXd::Constant(pimpl->innerModel->nbInternalDofs(), 2.0);
101  // torqueLimitConstraint = std::make_shared<ocra::TorqueLimitConstraint>(*pimpl->innerModel, torqueLims);//, predictionHorizon);
102  // addConstraint(*torqueLimitConstraint);
103 
104 
105  }
106  else
107  {
108  pimpl->innerSolver->addObjective(pimpl->minTauObjective);
109  pimpl->innerSolver->addObjective(pimpl->minFcObjective);
110  }
111  setVariableMinimizationWeights(1e-7, 1e-8, 1e-9);
113 
114  };
115 
117 
118  {
119  const std::map<std::string, std::shared_ptr<Task>>& taskMap = getTasks();
120  for (std::map<std::string, std::shared_ptr<Task>>::const_iterator it = taskMap.begin(); it != taskMap.end(); ++it)
121  {
122  if(it->second)
123  it->second->disconnectFromController();
124  }
125 
126 
127  if (!pimpl->reducedProblem)
128 
129  {
130 
131  pimpl->innerSolver->removeConstraint(pimpl->dynamicEquation.getConstraint());
132  pimpl->innerSolver->removeObjective(pimpl->minDdqObjective);
133  pimpl->innerSolver->removeObjective(pimpl->minTauObjective);
134  pimpl->innerSolver->removeObjective(pimpl->minFcObjective);
135 
136  }
137  else
138  {
139  pimpl->innerSolver->removeObjective(pimpl->minTauObjective);
140  pimpl->innerSolver->removeObjective(pimpl->minFcObjective);
141  }
142 
143  };
144 
145  std::shared_ptr<Model> WocraController::getModel()
146 
147  {
148 
149  return pimpl->innerModel;
150 
151  }
152 
153  std::shared_ptr<OneLevelSolver> WocraController::getSolver()
154 
155  {
156 
157  return pimpl->innerSolver;
158 
159  }
160 
162 
163  {
164 
165  return pimpl->reducedProblem;
166 
167  }
168 
169  void WocraController::setVariableMinimizationWeights(double w_ddq, double w_tau, double w_fc)
170  {
171  pimpl->minDdqObjective.getObjective().setWeight(w_ddq);
172  pimpl->minTauObjective.getObjective().setWeight(w_tau);
173  pimpl->minFcObjective.getObjective().setWeight(w_fc);
174  }
175 
177  {
178  pimpl->dynamicEquation.getFunction().takeIntoAccountGravity(useGrav);
179  }
180 
182  {
183  pimpl->innerSolver->addConstraint(constraint);
184  }
185 
187  {
188  pimpl->innerSolver->removeConstraint(constraint);
189  }
190 
192  {
193  constraint.connectToController(pimpl->dynamicEquation, pimpl->reducedProblem);
194  pimpl->innerSolver->addConstraint(constraint.getConstraint());
195  }
196 
198  {
199  pimpl->innerSolver->removeConstraint(constraint.getConstraint());
200  constraint.disconnectFromController();
201  }
202 
203  void WocraController::doAddTask(std::shared_ptr<Task> task)
204  {
205  try {
206  task->connectToController(pimpl->innerSolver, pimpl->dynamicEquation, pimpl->reducedProblem);
207  }
208  catch(const std::exception & e) {
209  std::cerr << e.what() ;
210  throw std::runtime_error("[WocraController::doAddTask] cannot add task to controller (wrong type)");
211  }
212  };
213 
215 
216  {
217 
218  throw std::runtime_error("[WocraController::doAddTask] not implemented");
219 
220  };
221 
222 
223 
224 
225  //
226  //
227  // /** Create an WocraTask.
228  // *
229  // * \return an WocraTask instance that is a dynamic_cast of the task returned by ocra::Controller::createTask(const std::string& name, Feature::Ptr feature, Feature::Ptr featureDes) const
230  // */
231  // WocraTask& WocraController::createWocraTask(const std::string& name, Feature::Ptr feature, Feature::Ptr featureDes) const
232  // {
233  // return dynamic_cast<WocraTask&>(createTask(name, feature, featureDes));
234  // }
235  //
236  // /** Create an WocraTask.
237  // *
238  // * \return an WocraTask instance that is a dynamic_cast of the task returned by ocra::Controller::createTask(const std::string& name, Feature::Ptr feature) const
239  // */
240  // WocraTask& WocraController::createWocraTask(const std::string& name, Feature::Ptr feature) const
241  // {
242  // return dynamic_cast<WocraTask&>(createTask(name, feature));
243  // }
244  //
245  // /** Create an WocraContactTask.
246  // *
247  // * \return an WocraTask instance that is a dynamic_cast of the task returned by ocra::Controller::createContactTask(const std::string& name, PointContactFeature::Ptr feature, double mu, double margin) const
248  // */
249  // WocraTask& WocraController::createWocraContactTask(const std::string& name, PointContactFeature::Ptr feature, double mu, double margin) const
250  // {
251  // return dynamic_cast<WocraTask&>(createContactTask(name, feature, mu, margin));
252  // }
253 
254 
255 
256  std::shared_ptr<Task> WocraController::doCreateTask(const std::string& name, Feature::Ptr feature, Feature::Ptr featureDes) const
257  {
258  return std::make_shared<ocra::Task>(name, pimpl->innerModel, feature, featureDes);
259  };
260 
261  std::shared_ptr<Task> WocraController::doCreateTask(const std::string& name, Feature::Ptr feature) const
262  {
263  return std::make_shared<ocra::Task>(name, pimpl->innerModel, feature);
264  };
265 
266  std::shared_ptr<Task> WocraController::doCreateContactTask(const std::string& name, PointContactFeature::Ptr feature, double mu, double margin) const
267  {
268  return std::make_shared<ocra::Task>(name, pimpl->innerModel, feature);
269  };
270 
278  void WocraController::doComputeOutput(Eigen::VectorXd& tau)
279 
280  {
281 
282  pimpl->updateTasksRecorder.initializeTime();
283 
284  const std::vector<std::shared_ptr<Task>>& tasks = getActiveTasks();
285 
286  for(auto task : tasks)
287  {
288  task->update();
289  }
290 
291  pimpl->updateTasksRecorder.saveRelativeTime();
292 
293 
294  pimpl->solveProblemRecorder.initializeTime();
295  if(!pimpl->innerSolver->solve().info)
296  {
297  tau = pimpl->innerModel->getJointTorqueVariable().getValue();
298  }
299 
300  else
301  {
302  setErrorMessage("solver error");
304  }
305  pimpl->solveProblemRecorder.saveRelativeTime();
306 
307  }
308 
309  void WocraController::writePerformanceInStream(std::ostream& outstream, bool addCommaAtEnd) const
310 
311  {
312 
313  pimpl->updateTasksRecorder.writeInStream("controller_update_tasks", outstream, true);
314 
315  pimpl->solveProblemRecorder.writeInStream("controller_solve_problem", outstream, true);
316 
317  pimpl->innerSolver->writePerformanceInStream(outstream, addCommaAtEnd);
318 
319  }
320 
322  {
323  std::ostringstream osstream;
324  // Write it in a json style
325  osstream <<"{\n";
326  writePerformanceInStream(osstream, false);
327  osstream <<"}";
328  return osstream.str();
329  }
330 
331 
332 
333 
334 
335 
336 } // namespace wocra
void setErrorFlag(int eflag)
Definition: Controller.cpp:401
PerformanceRecorder solveProblemRecorder
ObjectivePtr< ocra::QuadraticFunction > minFcObjective
std::shared_ptr< Model > innerModel
std::shared_ptr< Model > getModel()
virtual ~WocraController()
Destructor of Wocra controller.
ocra::QuadraticFunction * minTauFunction
Contact task factory.
Definition: ContactSet.h:59
Define the LQP-based controller developped during my PhD thesis with ocra framework.
ObjectivePtr< ocra::QuadraticFunction > minDdqObjective
std::shared_ptr< OneLevelSolver > getSolver()
PerformanceRecorder updateTasksRecorder
virtual void doAddContactSet(const ContactSet &contacts)
Contains all the abstract & concrete classes for robotic control with optimization, based on the ocra framework.
void removeConstraint(ocra::LinearConstraint &constraint) const
virtual void connectToController(const FullDynamicEquationFunction &dynamicEquation, bool useReducedProblem)=0
Pimpl(std::shared_ptr< Model > m, std::shared_ptr< OneLevelSolver > s, bool useReducedProblem)
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
To get and save time information to collect some data on performances.
virtual void doComputeOutput(Eigen::VectorXd &tau)
Interface for controllers.
Definition: Controller.h:53
Constraint class.
Definition: Constraint.h:100
WocraController(const std::string &ctrlName, std::shared_ptr< Model > innerModel, std::shared_ptr< OneLevelSolver > innerSolver, bool useReducedProblem)
std::string getPerformances() const
ocra::EqualZeroConstraintPtr< ocra::FullDynamicEquationFunction > dynamicEquation
void takeIntoAccountGravity(bool useGrav)
LinearConstraint & getConstraint()
Create a linear function that represents the dynamic equation of motion.
void writePerformanceInStream(std::ostream &myOstream, bool addCommaAtEnd) const
ObjectivePtr< ocra::QuadraticFunction > minTauObjective
ocra::FcQuadraticFunction * minFcFunction
virtual std::shared_ptr< Task > doCreateTask(const std::string &name, Feature::Ptr feature, Feature::Ptr featureDes) const
ocra::QuadraticFunction * minDdqFunction
void setErrorMessage(const std::string &msg)
Definition: Controller.cpp:406
void setVariableMinimizationWeights(double w_ddq, double w_tau, double w_fc)
virtual void doAddTask(std::shared_ptr< Task > task)
const std::map< std::string, std::shared_ptr< Task > > & getTasks() const
Definition: Controller.cpp:411
void addConstraint(ocra::LinearConstraint &constraint) const
QuadraticFunction class.
std::shared_ptr< OneLevelSolver > innerSolver
void set(T *f, double weight=1.)
const std::vector< std::shared_ptr< Task > > & getActiveTasks() const
Definition: Controller.cpp:394
virtual void disconnectFromController()=0
Declaration file of the QuadraticFunction class.
virtual std::shared_ptr< Task > doCreateContactTask(const std::string &name, PointContactFeature::Ptr feature, double mu, double margin) const