QPSolver.h
Go to the documentation of this file.
1 /*
2  * Copyright 2012-2019 CNRS-UM LIRMM, CNRS-AIST JRL
3  */
4 
5 #pragma once
6 
7 // includes
8 // std
9 #include <memory>
10 #include <vector>
11 
12 // boost
13 #include <boost/timer/timer.hpp>
14 
15 // Eigen
16 #include <Eigen/Core>
17 
18 // Tasks
19 #include <tasks/config.hh>
20 
21 #include "QPContacts.h"
22 #include "QPSolverData.h"
23 
24 // forward declaration
25 // RBDyn
26 namespace rbd
27 {
28 class MultiBody;
29 struct MultiBodyConfig;
30 } // namespace rbd
31 
32 namespace tasks
33 {
34 
35 namespace qp
36 {
37 class Constraint;
38 class Equality;
39 class Inequality;
40 class GenInequality;
41 class Bound;
42 class Task;
43 class GenQPSolver;
44 
45 class TASKS_DLLAPI QPSolver
46 {
47 public:
50 
55  bool solve(const std::vector<rbd::MultiBody> & mbs, std::vector<rbd::MultiBodyConfig> & mbcs);
56 
62  bool solveNoMbcUpdate(const std::vector<rbd::MultiBody> & mbs, const std::vector<rbd::MultiBodyConfig> & mbcs);
63 
68  void updateMbc(rbd::MultiBodyConfig & mbc, int robotIndex) const;
69 
71 
72  void nrVars(const std::vector<rbd::MultiBody> & mbs,
73  std::vector<UnilateralContact> uni,
74  std::vector<BilateralContact> bi);
75  int nrVars() const;
76 
78  void updateTasksNrVars(const std::vector<rbd::MultiBody> & mbs) const;
80  void updateConstrsNrVars(const std::vector<rbd::MultiBody> & mbs) const;
82  void updateNrVars(const std::vector<rbd::MultiBody> & mbs) const;
83 
86  int nrEqualityConstraints() const;
87 
91 
95 
98  int nrBoundConstraints() const;
99 
101  void addConstraint(const std::vector<rbd::MultiBody> & mbs, Constraint * co);
103  int nrConstraints() const;
104 
105  void addTask(Task * task);
106  void addTask(const std::vector<rbd::MultiBody> & mbs, Task * task);
107  void removeTask(Task * task);
108  void resetTasks();
109  int nrTasks() const;
110 
111  void solver(const std::string & name);
112  std::string solver() const;
113 
114  const SolverData & data() const;
116 
117  const Eigen::VectorXd & result() const;
118  Eigen::VectorXd alphaDVec() const;
119  Eigen::VectorXd alphaDVec(int rIndex) const;
120 
121  Eigen::VectorXd lambdaVec() const;
122  Eigen::VectorXd lambdaVec(int cIndex) const;
123 
124  int contactLambdaPosition(const ContactId & cId) const;
125 
126  boost::timer::cpu_times solveTime() const;
127  boost::timer::cpu_times solveAndBuildTime() const;
128 
129 protected:
130  void preUpdate(const std::vector<rbd::MultiBody> & mbs, const std::vector<rbd::MultiBodyConfig> & mbcs);
131  void postUpdate(const std::vector<rbd::MultiBody> & mbs, std::vector<rbd::MultiBodyConfig> & mbcs, bool success);
132 
133 private:
134  std::vector<Constraint *> constr_;
135  std::vector<Equality *> eqConstr_;
136  std::vector<Inequality *> inEqConstr_;
137  std::vector<GenInequality *> genInEqConstr_;
138  std::vector<Bound *> boundConstr_;
139 
140  std::vector<Task *> tasks_;
141 
142  SolverData data_;
143 
144  int maxEqLines_, maxInEqLines_, maxGenInEqLines_;
145 
146  std::unique_ptr<GenQPSolver> solver_;
147 
148  boost::timer::cpu_timer solverTimer_, solverAndBuildTimer_;
149 };
150 
151 class TASKS_DLLAPI Constraint
152 {
153 public:
154  virtual ~Constraint() {}
155  virtual void updateNrVars(const std::vector<rbd::MultiBody> & msb, const SolverData & data) = 0;
156 
157  virtual void update(const std::vector<rbd::MultiBody> & mbs,
158  const std::vector<rbd::MultiBodyConfig> & mbcs,
159  const SolverData & data) = 0;
160 };
161 
162 template<typename... Fun>
163 class ConstraintFunction : public Constraint, public Fun...
164 {
165 public:
166  virtual ~ConstraintFunction() override {}
167 
168  void addToSolver(QPSolver & sol)
169  {
170  sol.addConstraint(this);
171  addToSolver_p(sol, (&Fun::addToSolver)...);
172  }
173 
174  void addToSolver(const std::vector<rbd::MultiBody> & mbs, QPSolver & sol)
175  {
176  sol.addConstraint(mbs, this);
177  addToSolver_p(sol, (&Fun::addToSolver)...);
178  }
179 
181  {
182  sol.removeConstraint(this);
183  removeFromSolver_p(sol, (&Fun::removeFromSolver)...);
184  }
185 
186 private:
187  void addToSolver_p(QPSolver & /* sol */) {}
188 
189  template<typename F, typename... NextFun>
190  void addToSolver_p(QPSolver & sol, F function, NextFun... nFun)
191  {
192  (this->*function)(sol);
193  addToSolver_p(sol, nFun...);
194  }
195 
196  void removeFromSolver_p(QPSolver & /* sol */) {}
197 
198  template<typename F, typename... NextFun>
199  void removeFromSolver_p(QPSolver & sol, F function, NextFun... nFun)
200  {
201  (this->*function)(sol);
202  removeFromSolver_p(sol, nFun...);
203  }
204 };
205 
206 class TASKS_DLLAPI Equality
207 {
208 public:
209  virtual ~Equality() {}
210  virtual int maxEq() const = 0;
211  virtual int nrEq() const { return maxEq(); }
212 
213  virtual const Eigen::MatrixXd & AEq() const = 0;
214  virtual const Eigen::VectorXd & bEq() const = 0;
215 
216  virtual std::string nameEq() const = 0;
217  virtual std::string descEq(const std::vector<rbd::MultiBody> & mbs, int i) = 0;
218 
219  void addToSolver(QPSolver & sol) { sol.addEqualityConstraint(this); }
220 
222 };
223 
224 class TASKS_DLLAPI Inequality
225 {
226 public:
227  virtual ~Inequality() {}
228  virtual int maxInEq() const = 0;
229  virtual int nrInEq() const { return maxInEq(); }
230 
231  virtual const Eigen::MatrixXd & AInEq() const = 0;
232  virtual const Eigen::VectorXd & bInEq() const = 0;
233 
234  virtual std::string nameInEq() const = 0;
235  virtual std::string descInEq(const std::vector<rbd::MultiBody> & mbs, int i) = 0;
236 
237  void addToSolver(QPSolver & sol) { sol.addInequalityConstraint(this); }
238 
240 };
241 
242 class TASKS_DLLAPI GenInequality
243 {
244 public:
245  virtual ~GenInequality() {}
246  virtual int maxGenInEq() const = 0;
247  virtual int nrGenInEq() const { return maxGenInEq(); }
248 
249  virtual const Eigen::MatrixXd & AGenInEq() const = 0;
250  virtual const Eigen::VectorXd & LowerGenInEq() const = 0;
251  virtual const Eigen::VectorXd & UpperGenInEq() const = 0;
252 
253  virtual std::string nameGenInEq() const = 0;
254  virtual std::string descGenInEq(const std::vector<rbd::MultiBody> & mbs, int i) = 0;
255 
257 
259 };
260 
261 class TASKS_DLLAPI Bound
262 {
263 public:
264  virtual ~Bound() {}
265  virtual int beginVar() const = 0;
266 
267  virtual const Eigen::VectorXd & Lower() const = 0;
268  virtual const Eigen::VectorXd & Upper() const = 0;
269 
270  virtual std::string nameBound() const = 0;
271  virtual std::string descBound(const std::vector<rbd::MultiBody> & mbs, int i) = 0;
272 
273  void addToSolver(QPSolver & sol) { sol.addBoundConstraint(this); }
274 
276 };
277 
278 class TASKS_DLLAPI Task
279 {
280 public:
281  Task(double weight) : weight_(weight) {}
282  virtual ~Task() {}
283 
284  virtual double weight() const { return weight_; }
285 
286  virtual void weight(double w) { weight_ = w; }
287 
288  virtual std::pair<int, int> begin() const = 0;
289 
290  virtual void updateNrVars(const std::vector<rbd::MultiBody> & mbs, const SolverData & data) = 0;
291  virtual void update(const std::vector<rbd::MultiBody> & mbs,
292  const std::vector<rbd::MultiBodyConfig> & mbcs,
293  const SolverData & data) = 0;
294 
295  virtual const Eigen::MatrixXd & Q() const = 0;
296  virtual const Eigen::VectorXd & C() const = 0;
297 
298 private:
299  double weight_;
300 };
301 
302 class TASKS_DLLAPI HighLevelTask
303 {
304 public:
305  virtual ~HighLevelTask() {}
306 
307  virtual int dim() = 0;
308 
309  virtual void update(const std::vector<rbd::MultiBody> & mbs,
310  const std::vector<rbd::MultiBodyConfig> & mbcs,
311  const SolverData & data) = 0;
312 
313  virtual const Eigen::MatrixXd & jac() const = 0;
314  virtual const Eigen::VectorXd & eval() const = 0;
315  virtual const Eigen::VectorXd & speed() const = 0;
316  virtual const Eigen::VectorXd & normalAcc() const = 0;
317 };
318 
319 template<typename T>
321 {
322 };
323 
324 template<>
326 {
327  static int maxLines(const Equality * constr) { return constr->maxEq(); }
328 
329  static int nrLines(const Equality * constr) { return constr->nrEq(); }
330 
331  static std::string name(const Equality * constr) { return constr->nameEq(); }
332 
333  static std::string desc(Equality * constr, const std::vector<rbd::MultiBody> & mbs, int i)
334  {
335  return constr->descEq(mbs, i);
336  }
337 };
338 
339 template<>
341 {
342  static int maxLines(const Inequality * constr) { return constr->maxInEq(); }
343 
344  static int nrLines(const Inequality * constr) { return constr->nrInEq(); }
345 
346  static std::string name(const Inequality * constr) { return constr->nameInEq(); }
347 
348  static std::string desc(Inequality * constr, const std::vector<rbd::MultiBody> & mbs, int i)
349  {
350  return constr->descInEq(mbs, i);
351  }
352 };
353 
354 template<>
356 {
357  static int maxLines(const GenInequality * constr) { return constr->maxGenInEq(); }
358 
359  static int nrLines(const GenInequality * constr) { return constr->nrGenInEq(); }
360 
361  static std::string name(const GenInequality * constr) { return constr->nameGenInEq(); }
362 
363  static std::string desc(GenInequality * constr, const std::vector<rbd::MultiBody> & mbs, int i)
364  {
365  return constr->descGenInEq(mbs, i);
366  }
367 };
368 
369 } // namespace qp
370 
371 } // namespace tasks
Definition: QPSolver.h:262
void addToSolver(QPSolver &sol)
Definition: QPSolver.h:273
virtual int beginVar() const =0
virtual std::string nameBound() const =0
virtual const Eigen::VectorXd & Upper() const =0
virtual std::string descBound(const std::vector< rbd::MultiBody > &mbs, int i)=0
virtual const Eigen::VectorXd & Lower() const =0
virtual ~Bound()
Definition: QPSolver.h:264
void removeFromSolver(QPSolver &sol)
Definition: QPSolver.h:275
Definition: QPSolver.h:164
void addToSolver(const std::vector< rbd::MultiBody > &mbs, QPSolver &sol)
Definition: QPSolver.h:174
void removeFromSolver(QPSolver &sol)
Definition: QPSolver.h:180
virtual ~ConstraintFunction() override
Definition: QPSolver.h:166
void addToSolver(QPSolver &sol)
Definition: QPSolver.h:168
Definition: QPSolver.h:152
virtual void updateNrVars(const std::vector< rbd::MultiBody > &msb, const SolverData &data)=0
virtual ~Constraint()
Definition: QPSolver.h:154
virtual void update(const std::vector< rbd::MultiBody > &mbs, const std::vector< rbd::MultiBodyConfig > &mbcs, const SolverData &data)=0
Definition: QPSolver.h:207
virtual int maxEq() const =0
virtual ~Equality()
Definition: QPSolver.h:209
virtual std::string descEq(const std::vector< rbd::MultiBody > &mbs, int i)=0
virtual int nrEq() const
Definition: QPSolver.h:211
virtual std::string nameEq() const =0
void addToSolver(QPSolver &sol)
Definition: QPSolver.h:219
virtual const Eigen::VectorXd & bEq() const =0
void removeFromSolver(QPSolver &sol)
Definition: QPSolver.h:221
virtual const Eigen::MatrixXd & AEq() const =0
Definition: QPSolver.h:243
void removeFromSolver(QPSolver &sol)
Definition: QPSolver.h:258
virtual const Eigen::MatrixXd & AGenInEq() const =0
void addToSolver(QPSolver &sol)
Definition: QPSolver.h:256
virtual int nrGenInEq() const
Definition: QPSolver.h:247
virtual std::string descGenInEq(const std::vector< rbd::MultiBody > &mbs, int i)=0
virtual std::string nameGenInEq() const =0
virtual const Eigen::VectorXd & UpperGenInEq() const =0
virtual ~GenInequality()
Definition: QPSolver.h:245
virtual int maxGenInEq() const =0
virtual const Eigen::VectorXd & LowerGenInEq() const =0
Definition: QPSolver.h:303
virtual void update(const std::vector< rbd::MultiBody > &mbs, const std::vector< rbd::MultiBodyConfig > &mbcs, const SolverData &data)=0
virtual const Eigen::VectorXd & normalAcc() const =0
virtual const Eigen::VectorXd & speed() const =0
virtual ~HighLevelTask()
Definition: QPSolver.h:305
virtual const Eigen::MatrixXd & jac() const =0
virtual const Eigen::VectorXd & eval() const =0
Definition: QPSolver.h:225
virtual int nrInEq() const
Definition: QPSolver.h:229
void removeFromSolver(QPSolver &sol)
Definition: QPSolver.h:239
virtual const Eigen::MatrixXd & AInEq() const =0
virtual int maxInEq() const =0
virtual ~Inequality()
Definition: QPSolver.h:227
virtual const Eigen::VectorXd & bInEq() const =0
void addToSolver(QPSolver &sol)
Definition: QPSolver.h:237
virtual std::string nameInEq() const =0
virtual std::string descInEq(const std::vector< rbd::MultiBody > &mbs, int i)=0
Definition: QPSolver.h:46
void updateNrVars(const std::vector< rbd::MultiBody > &mbs) const
call updateNrVars on all tasks and constraints
int nrEqualityConstraints() const
int nrTasks() const
const Eigen::VectorXd & result() const
void addConstraint(Constraint *co)
void removeConstraint(Constraint *co)
int nrConstraints() const
boost::timer::cpu_times solveAndBuildTime() const
void addEqualityConstraint(Equality *co)
void nrVars(const std::vector< rbd::MultiBody > &mbs, std::vector< UnilateralContact > uni, std::vector< BilateralContact > bi)
int nrInequalityConstraints() const
Eigen::VectorXd alphaDVec(int rIndex) const
void preUpdate(const std::vector< rbd::MultiBody > &mbs, const std::vector< rbd::MultiBodyConfig > &mbcs)
void updateTasksNrVars(const std::vector< rbd::MultiBody > &mbs) const
call updateNrVars on all tasks
Eigen::VectorXd alphaDVec() const
void postUpdate(const std::vector< rbd::MultiBody > &mbs, std::vector< rbd::MultiBodyConfig > &mbcs, bool success)
bool solveNoMbcUpdate(const std::vector< rbd::MultiBody > &mbs, const std::vector< rbd::MultiBodyConfig > &mbcs)
std::string solver() const
SolverData & data()
bool solve(const std::vector< rbd::MultiBody > &mbs, std::vector< rbd::MultiBodyConfig > &mbcs)
void removeEqualityConstraint(Equality *co)
void removeBoundConstraint(Bound *co)
Eigen::VectorXd lambdaVec(int cIndex) const
int nrGenInequalityConstraints() const
void solver(const std::string &name)
void addTask(Task *task)
void addTask(const std::vector< rbd::MultiBody > &mbs, Task *task)
void removeGenInequalityConstraint(GenInequality *co)
boost::timer::cpu_times solveTime() const
void updateMbc(rbd::MultiBodyConfig &mbc, int robotIndex) const
fill mbc with the solution of the problem
int nrBoundConstraints() const
int nrVars() const
void updateConstrsNrVars(const std::vector< rbd::MultiBody > &mbs) const
call updateNrVars on all constraints
void removeTask(Task *task)
void addConstraint(const std::vector< rbd::MultiBody > &mbs, Constraint *co)
void addInequalityConstraint(Inequality *co)
void addBoundConstraint(Bound *co)
Eigen::VectorXd lambdaVec() const
int contactLambdaPosition(const ContactId &cId) const
void removeInequalityConstraint(Inequality *co)
void addGenInequalityConstraint(GenInequality *co)
const SolverData & data() const
Definition: QPSolverData.h:28
Definition: QPSolver.h:279
virtual const Eigen::MatrixXd & Q() const =0
virtual void weight(double w)
Definition: QPSolver.h:286
Task(double weight)
Definition: QPSolver.h:281
virtual std::pair< int, int > begin() const =0
virtual void updateNrVars(const std::vector< rbd::MultiBody > &mbs, const SolverData &data)=0
virtual const Eigen::VectorXd & C() const =0
virtual double weight() const
Definition: QPSolver.h:284
virtual ~Task()
Definition: QPSolver.h:282
virtual void update(const std::vector< rbd::MultiBody > &mbs, const std::vector< rbd::MultiBodyConfig > &mbcs, const SolverData &data)=0
Definition: GenQPSolver.h:21
Definition: GenQPUtils.h:19
Definition: QPContacts.h:50
static std::string name(const Equality *constr)
Definition: QPSolver.h:331
static int maxLines(const Equality *constr)
Definition: QPSolver.h:327
static int nrLines(const Equality *constr)
Definition: QPSolver.h:329
static std::string desc(Equality *constr, const std::vector< rbd::MultiBody > &mbs, int i)
Definition: QPSolver.h:333
static std::string desc(GenInequality *constr, const std::vector< rbd::MultiBody > &mbs, int i)
Definition: QPSolver.h:363
static std::string name(const GenInequality *constr)
Definition: QPSolver.h:361
static int maxLines(const GenInequality *constr)
Definition: QPSolver.h:357
static int nrLines(const GenInequality *constr)
Definition: QPSolver.h:359
static int nrLines(const Inequality *constr)
Definition: QPSolver.h:344
static int maxLines(const Inequality *constr)
Definition: QPSolver.h:342
static std::string name(const Inequality *constr)
Definition: QPSolver.h:346
static std::string desc(Inequality *constr, const std::vector< rbd::MultiBody > &mbs, int i)
Definition: QPSolver.h:348
Definition: QPSolver.h:321