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