QPSolver.h
Go to the documentation of this file.
1 /*
2  * Copyright 2015-2022 CNRS-UM LIRMM, CNRS-AIST JRL
3  */
4 
5 #pragma once
6 
7 #include <mc_solver/api.h>
8 
9 #include <mc_control/api.h>
10 #include <mc_rbdyn/Contact.h>
11 #include <mc_rbdyn/Robots.h>
12 
13 #include <mc_rtc/pragma.h>
14 
15 #include <memory>
16 
17 namespace mc_tasks
18 {
19 
20 struct MetaTask;
21 
22 } // namespace mc_tasks
23 
24 namespace mc_rtc
25 {
26 
27 struct Logger;
28 
29 namespace gui
30 {
31 
32 struct StateBuilder;
33 
34 } // namespace gui
35 
36 } // namespace mc_rtc
37 
38 namespace mc_control
39 {
40 
41 struct MCController;
42 
43 } // namespace mc_control
44 
45 namespace mc_solver
46 {
47 
48 // Work around GCC bug see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43407
49 MC_RTC_diagnostic_push
50 MC_RTC_diagnostic_ignored(GCC, "-Wattributes")
51 
52 
53 enum class MC_SOLVER_DLLAPI FeedbackType
54 {
56  None,
58  OpenLoop = None,
60  Joints,
62  JointsWVelocity,
65  ObservedRobots,
67  ClosedLoop = ObservedRobots,
70  ClosedLoopIntegrateReal
71 };
72 
73 MC_RTC_diagnostic_pop
74 
75 struct ConstraintSet;
76 struct DynamicsConstraint;
77 struct TasksQPSolver;
78 
86 {
87 public:
90  enum class Backend
91  {
93  Unset,
95  Tasks,
97  TVM
98  };
99 
102  {
104  friend struct QPSolver;
105 
106  private:
107  ControllerToken() = default;
108  };
109 
116  QPSolver(mc_rbdyn::RobotsPtr robots, double timeStep, Backend backend);
117 
121  QPSolver(double timeStep, Backend backend);
122 
123  virtual ~QPSolver() = default;
124 
126  inline Backend backend() const noexcept { return backend_; }
127 
139  static Backend context_backend();
140 
142  static void context_backend(Backend backend);
143 
147  void addConstraintSet(ConstraintSet & cs);
148 
153  template<typename T>
154  inline void addConstraintSet(const std::unique_ptr<T> & ptr)
155  {
156  addConstraintSet(*ptr);
157  }
158 
162  void removeConstraintSet(ConstraintSet & cs);
163 
168  template<typename T>
169  inline void removeConstraintSet(const std::unique_ptr<T> & ptr)
170  {
171  removeConstraintSet(*ptr);
172  }
173 
183  void addTask(mc_tasks::MetaTask * task);
184 
186  inline void addTask(std::shared_ptr<mc_tasks::MetaTask> task)
187  {
188  if(task)
189  {
190  addTask(task.get());
191  shPtrTasksStorage.emplace_back(task);
192  }
193  }
194 
203  void removeTask(mc_tasks::MetaTask * task);
204 
206  inline void removeTask(std::shared_ptr<mc_tasks::MetaTask> task)
207  {
208  if(task) { removeTask(task.get()); }
209  }
210 
214  void setContacts(const std::vector<mc_rbdyn::Contact> & contacts = {});
215 
216  /* Called by the owning controller to actually set the contacts or internally by QPSolver when it has no owning
217  * controller */
218  virtual void setContacts(ControllerToken, const std::vector<mc_rbdyn::Contact> & contacts) = 0;
219 
221  inline const std::vector<mc_rbdyn::Contact> & contacts() const noexcept { return contacts_; }
222 
224  inline const std::vector<mc_solver::ConstraintSet *> & constraints() const noexcept { return constraints_; }
225 
227  inline const std::vector<mc_tasks::MetaTask *> & tasks() const noexcept { return metaTasks_; }
228 
234  virtual const sva::ForceVecd desiredContactForce(const mc_rbdyn::Contact & id) const = 0;
235 
244  bool run(FeedbackType fType = FeedbackType::None);
245 
247  const mc_rbdyn::Robot & robot() const;
249  mc_rbdyn::Robot & robot();
250 
252  mc_rbdyn::Robot & robot(unsigned int idx);
254  const mc_rbdyn::Robot & robot(unsigned int idx) const;
255 
257  const mc_rbdyn::Robot & env() const;
259  mc_rbdyn::Robot & env();
260 
262  const mc_rbdyn::Robots & robots() const;
264  mc_rbdyn::Robots & robots();
265 
267  const mc_rbdyn::Robots & realRobots() const;
269  mc_rbdyn::Robots & realRobots();
270 
274  double dt() const;
275 
277  virtual double solveTime() = 0;
278 
280  virtual double solveAndBuildTime() = 0;
281 
283  void logger(std::shared_ptr<mc_rtc::Logger> logger);
285  std::shared_ptr<mc_rtc::Logger> logger() const;
286 
288  void gui(std::shared_ptr<mc_rtc::gui::StateBuilder> gui);
290  std::shared_ptr<mc_rtc::gui::StateBuilder> gui() const;
291 
293  inline void controller(mc_control::MCController * ctl) noexcept { controller_ = ctl; }
295  inline const mc_control::MCController * controller() const noexcept { return controller_; }
297  inline mc_control::MCController * controller() noexcept { return controller_; }
298 
299 protected:
303  double timeStep;
304 
306  std::vector<mc_rbdyn::Contact> contacts_;
307 
309  std::vector<mc_tasks::MetaTask *> metaTasks_;
310 
312  std::vector<std::shared_ptr<void>> shPtrTasksStorage;
313 
315  std::vector<mc_solver::ConstraintSet *> constraints_;
316 
318  std::shared_ptr<mc_rtc::Logger> logger_ = nullptr;
319 
321  std::shared_ptr<mc_rtc::gui::StateBuilder> gui_ = nullptr;
322 
323  void addTaskToGUI(mc_tasks::MetaTask * task);
324 
326  mc_control::MCController * controller_ = nullptr;
327 
329  virtual bool run_impl(FeedbackType fType = FeedbackType::None) = 0;
330 
332  virtual void addDynamicsConstraint(mc_solver::DynamicsConstraint * dynamics) = 0;
333 
335  virtual void removeDynamicsConstraint(mc_solver::ConstraintSet * maybe_dynamics) = 0;
336 };
337 
338 } // namespace mc_solver
339 
340 namespace fmt
341 {
342 
343 template<>
344 struct formatter<mc_solver::QPSolver::Backend> : public formatter<string_view>
345 {
346  template<typename FormatContext>
347  auto format(const mc_solver::QPSolver::Backend & backend, FormatContext & ctx) -> decltype(ctx.out())
348  {
349  using Backend = mc_solver::QPSolver::Backend;
350  switch(backend)
351  {
352  case Backend::Tasks:
353  return formatter<string_view>::format("Tasks", ctx);
354  case Backend::TVM:
355  return formatter<string_view>::format("TVM", ctx);
356  case Backend::Unset:
357  return formatter<string_view>::format("Unset", ctx);
358  default:
359  return formatter<string_view>::format("UNEXPECTED", ctx);
360  }
361  }
362 };
363 
364 } // namespace fmt
mc_solver::DynamicsConstraint
Definition: DynamicsConstraint.h:20
mc_rbdyn::Robots
Definition: Robots.h:15
mc_solver::QPSolver::addConstraintSet
void addConstraintSet(const std::unique_ptr< T > &ptr)
Definition: QPSolver.h:154
mc_solver::QPSolver::realRobots_p
mc_rbdyn::RobotsPtr realRobots_p
Definition: QPSolver.h:302
mc_solver::QPSolver::ControllerToken
Definition: QPSolver.h:101
mc_tasks::MetaTask
Represents a generic task.
Definition: MetaTask.h:39
mc_solver::QPSolver::backend
Backend backend() const noexcept
Definition: QPSolver.h:126
mc_solver::MC_RTC_diagnostic_ignored
MC_RTC_diagnostic_push MC_RTC_diagnostic_ignored(GCC, "-Wattributes") enum class MC_SOLVER_DLLAPI FeedbackType
Definition: QPSolver.h:50
mc_solver::QPSolver
Definition: QPSolver.h:85
api.h
pragma.h
mc_rbdyn::Robot
Definition: Robot.h:62
mc_rbdyn::RobotsPtr
std::shared_ptr< Robots > RobotsPtr
Definition: fwd.h:17
fmt::formatter< mc_solver::QPSolver::Backend >::format
auto format(const mc_solver::QPSolver::Backend &backend, FormatContext &ctx) -> decltype(ctx.out())
Definition: QPSolver.h:347
mc_solver::QPSolver::controller
const mc_control::MCController * controller() const noexcept
Definition: QPSolver.h:295
mc_solver::ConstraintSet
This class is a basis to wrap Constraint functions from Tasks. The aim of such wrappers should be two...
Definition: ConstraintSet.h:20
mc_solver::QPSolver::contacts
const std::vector< mc_rbdyn::Contact > & contacts() const noexcept
Definition: QPSolver.h:221
mc_solver::QPSolver::tasks
const std::vector< mc_tasks::MetaTask * > & tasks() const noexcept
Definition: QPSolver.h:227
Contact.h
mc_solver::QPSolver::controller
mc_control::MCController * controller() noexcept
Definition: QPSolver.h:297
mc_solver::QPSolver::removeTask
void removeTask(std::shared_ptr< mc_tasks::MetaTask > task)
Definition: QPSolver.h:206
mc_solver::QPSolver::contacts_
std::vector< mc_rbdyn::Contact > contacts_
Definition: QPSolver.h:306
mc_solver::QPSolver::addTask
void addTask(std::shared_ptr< mc_tasks::MetaTask > task)
Definition: QPSolver.h:186
mc_solver::QPSolver::Backend
Backend
Definition: QPSolver.h:90
api.h
mc_solver::QPSolver::removeConstraintSet
void removeConstraintSet(const std::unique_ptr< T > &ptr)
Definition: QPSolver.h:169
Robots.h
mc_solver::QPSolver::robots_p
mc_rbdyn::RobotsPtr robots_p
Definition: QPSolver.h:301
mc_solver::QPSolver::backend_
Backend backend_
Definition: QPSolver.h:300
mc_solver::QPSolver::shPtrTasksStorage
std::vector< std::shared_ptr< void > > shPtrTasksStorage
Definition: QPSolver.h:312
mc_solver::QPSolver::timeStep
double timeStep
Definition: QPSolver.h:303
fmt
Definition: Configuration.h:1754
mc_rbdyn::Contact
Definition: Contact.h:48
mc_solver::QPSolver::constraints_
std::vector< mc_solver::ConstraintSet * > constraints_
Definition: QPSolver.h:315
mc_solver
Definition: Contact.h:17
mc_control
Definition: CompletionCriteria.h:10
mc_solver::QPSolver::controller
void controller(mc_control::MCController *ctl) noexcept
Definition: QPSolver.h:293
mc_solver::QPSolver::constraints
const std::vector< mc_solver::ConstraintSet * > & constraints() const noexcept
Definition: QPSolver.h:224
MC_SOLVER_DLLAPI
#define MC_SOLVER_DLLAPI
Definition: api.h:50
mc_control::MCController
MCController is the base class to implement all controllers. It assumes that at least two robots are ...
Definition: MCController.h:98
mc_tasks
Definition: StabilizerStandingState.h:11
mc_solver::QPSolver::metaTasks_
std::vector< mc_tasks::MetaTask * > metaTasks_
Definition: QPSolver.h:309
mc_rtc
Definition: Contact.h:87