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:
48  QPSolver();
49  ~QPSolver();
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 
70  void updateConstrSize();
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 
84  void addEqualityConstraint(Equality * co);
85  void removeEqualityConstraint(Equality * co);
86  int nrEqualityConstraints() const;
87 
88  void addInequalityConstraint(Inequality * co);
89  void removeInequalityConstraint(Inequality * co);
90  int nrInequalityConstraints() const;
91 
92  void addGenInequalityConstraint(GenInequality * co);
93  void removeGenInequalityConstraint(GenInequality * co);
94  int nrGenInequalityConstraints() const;
95 
96  void addBoundConstraint(Bound * co);
97  void removeBoundConstraint(Bound * co);
98  int nrBoundConstraints() const;
99 
100  void addConstraint(Constraint * co);
101  void addConstraint(const std::vector<rbd::MultiBody> & mbs, Constraint * co);
102  void removeConstraint(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;
115  SolverData & data();
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
tasks::qp::ContactId
Definition: QPContacts.h:49
tasks::qp::constr_traits< GenInequality >::name
static std::string name(const GenInequality *constr)
Definition: QPSolver.h:361
tasks::qp::QPSolver::removeGenInequalityConstraint
void removeGenInequalityConstraint(GenInequality *co)
tasks::qp::constr_traits< Equality >::name
static std::string name(const Equality *constr)
Definition: QPSolver.h:331
tasks::qp::QPSolver
Definition: QPSolver.h:45
tasks::qp::constr_traits< GenInequality >::maxLines
static int maxLines(const GenInequality *constr)
Definition: QPSolver.h:357
tasks::qp::Equality::nameEq
virtual std::string nameEq() const =0
tasks::qp::Inequality
Definition: QPSolver.h:224
tasks::qp::GenInequality::removeFromSolver
void removeFromSolver(QPSolver &sol)
Definition: QPSolver.h:258
tasks::qp::Equality::~Equality
virtual ~Equality()
Definition: QPSolver.h:209
tasks::qp::Equality::descEq
virtual std::string descEq(const std::vector< rbd::MultiBody > &mbs, int i)=0
tasks::qp::QPSolver::addInequalityConstraint
void addInequalityConstraint(Inequality *co)
tasks::qp::ConstraintFunction::~ConstraintFunction
virtual ~ConstraintFunction() override
Definition: QPSolver.h:166
tasks::qp::ConstraintFunction::addToSolver
void addToSolver(QPSolver &sol)
Definition: QPSolver.h:168
tasks::qp::QPSolver::addGenInequalityConstraint
void addGenInequalityConstraint(GenInequality *co)
tasks::qp::GenInequality::addToSolver
void addToSolver(QPSolver &sol)
Definition: QPSolver.h:256
tasks::qp::Equality::nrEq
virtual int nrEq() const
Definition: QPSolver.h:211
tasks::qp::SolverData
Definition: QPSolverData.h:27
tasks::qp::Task::weight
virtual double weight() const
Definition: QPSolver.h:284
QPContacts.h
tasks::qp::ConstraintFunction::addToSolver
void addToSolver(const std::vector< rbd::MultiBody > &mbs, QPSolver &sol)
Definition: QPSolver.h:174
tasks::qp::GenInequality::descGenInEq
virtual std::string descGenInEq(const std::vector< rbd::MultiBody > &mbs, int i)=0
tasks::qp::constr_traits< Equality >::desc
static std::string desc(Equality *constr, const std::vector< rbd::MultiBody > &mbs, int i)
Definition: QPSolver.h:333
QPSolverData.h
tasks::qp::Inequality::removeFromSolver
void removeFromSolver(QPSolver &sol)
Definition: QPSolver.h:239
tasks::qp::constr_traits< Equality >::nrLines
static int nrLines(const Equality *constr)
Definition: QPSolver.h:329
tasks::qp::QPSolver::addBoundConstraint
void addBoundConstraint(Bound *co)
tasks::qp::GenInequality::maxGenInEq
virtual int maxGenInEq() const =0
tasks::qp::Inequality::nrInEq
virtual int nrInEq() const
Definition: QPSolver.h:229
tasks::qp::constr_traits< Inequality >::name
static std::string name(const Inequality *constr)
Definition: QPSolver.h:346
tasks::qp::Inequality::maxInEq
virtual int maxInEq() const =0
tasks::qp::constr_traits< GenInequality >::nrLines
static int nrLines(const GenInequality *constr)
Definition: QPSolver.h:359
tasks::qp::QPSolver::addConstraint
void addConstraint(Constraint *co)
tasks::qp::QPSolver::removeBoundConstraint
void removeBoundConstraint(Bound *co)
tasks::qp::HighLevelTask
Definition: QPSolver.h:302
tasks::qp::Equality::addToSolver
void addToSolver(QPSolver &sol)
Definition: QPSolver.h:219
tasks::qp::constr_traits< Inequality >::maxLines
static int maxLines(const Inequality *constr)
Definition: QPSolver.h:342
tasks::qp::QPSolver::removeInequalityConstraint
void removeInequalityConstraint(Inequality *co)
tasks::qp::Task::~Task
virtual ~Task()
Definition: QPSolver.h:282
tasks::qp::Task::Task
Task(double weight)
Definition: QPSolver.h:281
tasks::qp::Equality
Definition: QPSolver.h:206
tasks::qp::QPSolver::addEqualityConstraint
void addEqualityConstraint(Equality *co)
tasks::qp::GenInequality::nrGenInEq
virtual int nrGenInEq() const
Definition: QPSolver.h:247
tasks::qp::Inequality::~Inequality
virtual ~Inequality()
Definition: QPSolver.h:227
tasks::qp::constr_traits
Definition: QPSolver.h:320
tasks::qp::Bound::removeFromSolver
void removeFromSolver(QPSolver &sol)
Definition: QPSolver.h:275
tasks::qp::Bound::~Bound
virtual ~Bound()
Definition: QPSolver.h:264
tasks::qp::Inequality::nameInEq
virtual std::string nameInEq() const =0
tasks::qp::constr_traits< GenInequality >::desc
static std::string desc(GenInequality *constr, const std::vector< rbd::MultiBody > &mbs, int i)
Definition: QPSolver.h:363
tasks::qp::QPSolver::removeEqualityConstraint
void removeEqualityConstraint(Equality *co)
rbd
Definition: GenQPSolver.h:20
tasks::qp::Task::weight
virtual void weight(double w)
Definition: QPSolver.h:286
tasks::qp::constr_traits< Inequality >::desc
static std::string desc(Inequality *constr, const std::vector< rbd::MultiBody > &mbs, int i)
Definition: QPSolver.h:348
tasks::qp::Equality::removeFromSolver
void removeFromSolver(QPSolver &sol)
Definition: QPSolver.h:221
tasks::qp::Constraint
Definition: QPSolver.h:151
tasks::qp::ConstraintFunction::removeFromSolver
void removeFromSolver(QPSolver &sol)
Definition: QPSolver.h:180
tasks::qp::Bound
Definition: QPSolver.h:261
tasks::qp::Equality::maxEq
virtual int maxEq() const =0
tasks::qp::QPSolver::removeConstraint
void removeConstraint(Constraint *co)
tasks::qp::GenInequality::nameGenInEq
virtual std::string nameGenInEq() const =0
tasks::qp::Bound::addToSolver
void addToSolver(QPSolver &sol)
Definition: QPSolver.h:273
tasks::qp::Constraint::~Constraint
virtual ~Constraint()
Definition: QPSolver.h:154
tasks::qp::HighLevelTask::~HighLevelTask
virtual ~HighLevelTask()
Definition: QPSolver.h:305
tasks::qp::Inequality::descInEq
virtual std::string descInEq(const std::vector< rbd::MultiBody > &mbs, int i)=0
tasks::qp::Inequality::addToSolver
void addToSolver(QPSolver &sol)
Definition: QPSolver.h:237
tasks::qp::GenInequality
Definition: QPSolver.h:242
tasks::qp::GenInequality::~GenInequality
virtual ~GenInequality()
Definition: QPSolver.h:245
tasks::qp::constr_traits< Inequality >::nrLines
static int nrLines(const Inequality *constr)
Definition: QPSolver.h:344
tasks::qp::Task
Definition: QPSolver.h:278
tasks
Definition: GenQPUtils.h:18
tasks::qp::constr_traits< Equality >::maxLines
static int maxLines(const Equality *constr)
Definition: QPSolver.h:327
tasks::qp::ConstraintFunction
Definition: QPSolver.h:163