mc_rtc  2.16.0
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,
72  SkipQP
73 };
74 
75 MC_RTC_diagnostic_pop
76 
77 struct ConstraintSet;
78 struct DynamicsConstraint;
79 struct TasksQPSolver;
80 
88 {
89 public:
92  enum class Backend
93  {
95  Unset,
97  Tasks,
99  TVM
100  };
101 
104  {
106  friend struct QPSolver;
107 
108  private:
109  ControllerToken() = default;
110  };
111 
118  QPSolver(mc_rbdyn::RobotsPtr robots, double timeStep, Backend backend);
119 
123  QPSolver(double timeStep, Backend backend);
124 
125  virtual ~QPSolver() = default;
126 
128  inline Backend backend() const noexcept { return backend_; }
129 
142 
144  static void context_backend(Backend backend);
145 
150 
155  template<typename T>
156  inline void addConstraintSet(const std::unique_ptr<T> & ptr)
157  { addConstraintSet(*ptr); }
158 
163 
168  template<typename T>
169  inline void removeConstraintSet(const std::unique_ptr<T> & ptr)
170  { removeConstraintSet(*ptr); }
171 
182 
184  inline void addTask(std::shared_ptr<mc_tasks::MetaTask> task)
185  {
186  if(task)
187  {
188  addTask(task.get());
189  shPtrTasksStorage.emplace_back(task);
190  }
191  }
192 
202 
204  inline void removeTask(std::shared_ptr<mc_tasks::MetaTask> task)
205  {
206  if(task) { removeTask(task.get()); }
207  }
208 
212  void setContacts(const std::vector<mc_rbdyn::Contact> & contacts = {});
213 
214  /* Called by the owning controller to actually set the contacts or internally by QPSolver when it has no owning
215  * controller */
216  virtual void setContacts(ControllerToken, const std::vector<mc_rbdyn::Contact> & contacts) = 0;
217 
219  inline const std::vector<mc_rbdyn::Contact> & contacts() const noexcept { return contacts_; }
220 
222  inline const std::vector<mc_solver::ConstraintSet *> & constraints() const noexcept { return constraints_; }
223 
225  inline const std::vector<mc_tasks::MetaTask *> & tasks() const noexcept { return metaTasks_; }
226 
232  virtual const sva::ForceVecd desiredContactForce(const mc_rbdyn::Contact & id) const = 0;
233 
242  bool run(FeedbackType fType = FeedbackType::None);
243 
245  const mc_rbdyn::Robot & robot() const;
248 
250  mc_rbdyn::Robot & robot(unsigned int idx);
252  const mc_rbdyn::Robot & robot(unsigned int idx) const;
253 
255  const mc_rbdyn::Robot & env() const;
258 
260  const mc_rbdyn::Robots & robots() const;
263 
265  const mc_rbdyn::Robots & realRobots() const;
268 
272  double dt() const;
273 
275  virtual double solveTime() = 0;
276 
278  virtual double solveAndBuildTime() = 0;
279 
281  void logger(std::shared_ptr<mc_rtc::Logger> logger);
283  std::shared_ptr<mc_rtc::Logger> logger() const;
284 
286  void gui(std::shared_ptr<mc_rtc::gui::StateBuilder> gui);
288  std::shared_ptr<mc_rtc::gui::StateBuilder> gui() const;
289 
291  inline void controller(mc_control::MCController * ctl) noexcept { controller_ = ctl; }
293  inline const mc_control::MCController * controller() const noexcept { return controller_; }
295  inline mc_control::MCController * controller() noexcept { return controller_; }
296 
297 protected:
301  double timeStep;
302 
304  std::vector<mc_rbdyn::Contact> contacts_;
305 
307  std::vector<mc_tasks::MetaTask *> metaTasks_;
308 
310  std::vector<std::shared_ptr<void>> shPtrTasksStorage;
311 
313  std::vector<mc_solver::ConstraintSet *> constraints_;
314 
316  std::shared_ptr<mc_rtc::Logger> logger_ = nullptr;
317 
319  std::shared_ptr<mc_rtc::gui::StateBuilder> gui_ = nullptr;
320 
322 
324  mc_control::MCController * controller_ = nullptr;
325 
327  virtual bool run_impl(FeedbackType fType = FeedbackType::None) = 0;
328 
331 
333  virtual void removeDynamicsConstraint(mc_solver::ConstraintSet * maybe_dynamics) = 0;
334 };
335 
336 } // namespace mc_solver
337 
338 namespace fmt
339 {
340 
341 template<>
342 struct formatter<mc_solver::QPSolver::Backend> : public formatter<string_view>
343 {
344  template<typename FormatContext>
345 #if FMT_VERSION <= 9 * 10000
346  auto format(const mc_solver::QPSolver::Backend & backend, FormatContext & ctx)
347 #else
348  auto format(const mc_solver::QPSolver::Backend & backend, FormatContext & ctx) const -> decltype(ctx.out())
349 #endif
350  {
351  using Backend = mc_solver::QPSolver::Backend;
352  switch(backend)
353  {
354  case Backend::Tasks:
355  return formatter<string_view>::format("Tasks", ctx);
356  case Backend::TVM:
357  return formatter<string_view>::format("TVM", ctx);
358  case Backend::Unset:
359  return formatter<string_view>::format("Unset", ctx);
360  default:
361  return formatter<string_view>::format("UNEXPECTED", ctx);
362  }
363  }
364 };
365 
366 } // namespace fmt
#define MC_SOLVER_DLLAPI
Definition: api.h:50
Definition: Configuration.h:1804
Definition: CompletionCriteria.h:11
std::shared_ptr< Robots > RobotsPtr
Definition: fwd.h:17
Definition: Contact.h:88
Definition: Contact.h:18
MC_RTC_diagnostic_push MC_RTC_diagnostic_ignored(GCC, "-Wattributes") enum class MC_SOLVER_DLLAPI FeedbackType
Definition: QPSolver.h:50
Definition: StabilizerStandingState.h:12
auto format(const mc_solver::QPSolver::Backend &backend, FormatContext &ctx)
Definition: QPSolver.h:346
MCController is the base class to implement all controllers. It assumes that at least two robots are ...
Definition: MCController.h:99
Definition: Contact.h:49
Definition: Robot.h:63
Definition: Robots.h:17
This class is a basis to wrap Constraint functions from Tasks. The aim of such wrappers should be two...
Definition: ConstraintSet.h:21
Definition: DynamicsConstraint.h:21
Definition: QPSolver.h:104
Definition: QPSolver.h:88
virtual void addDynamicsConstraint(mc_solver::DynamicsConstraint *dynamics)=0
const mc_rbdyn::Robot & robot() const
QPSolver(double timeStep, Backend backend)
double timeStep
Definition: QPSolver.h:301
void addTask(std::shared_ptr< mc_tasks::MetaTask > task)
Definition: QPSolver.h:184
void removeTask(mc_tasks::MetaTask *task)
void removeConstraintSet(ConstraintSet &cs)
void addConstraintSet(ConstraintSet &cs)
virtual ~QPSolver()=default
mc_rbdyn::RobotsPtr realRobots_p
Definition: QPSolver.h:300
virtual void setContacts(ControllerToken, const std::vector< mc_rbdyn::Contact > &contacts)=0
virtual double solveAndBuildTime()=0
const std::vector< mc_tasks::MetaTask * > & tasks() const noexcept
Definition: QPSolver.h:225
mc_rbdyn::Robot & robot(unsigned int idx)
Backend backend() const noexcept
Definition: QPSolver.h:128
void removeConstraintSet(const std::unique_ptr< T > &ptr)
Definition: QPSolver.h:169
Backend
Definition: QPSolver.h:93
mc_control::MCController * controller() noexcept
Definition: QPSolver.h:295
void addTask(mc_tasks::MetaTask *task)
QPSolver(mc_rbdyn::RobotsPtr robots, double timeStep, Backend backend)
const mc_rbdyn::Robots & realRobots() const
void logger(std::shared_ptr< mc_rtc::Logger > logger)
const mc_rbdyn::Robot & robot(unsigned int idx) const
static Backend context_backend()
std::vector< mc_tasks::MetaTask * > metaTasks_
Definition: QPSolver.h:307
virtual void removeDynamicsConstraint(mc_solver::ConstraintSet *maybe_dynamics)=0
static void context_backend(Backend backend)
virtual const sva::ForceVecd desiredContactForce(const mc_rbdyn::Contact &id) const =0
void removeTask(std::shared_ptr< mc_tasks::MetaTask > task)
Definition: QPSolver.h:204
void addTaskToGUI(mc_tasks::MetaTask *task)
mc_rbdyn::Robot & robot()
const std::vector< mc_solver::ConstraintSet * > & constraints() const noexcept
Definition: QPSolver.h:222
std::vector< mc_rbdyn::Contact > contacts_
Definition: QPSolver.h:304
std::vector< mc_solver::ConstraintSet * > constraints_
Definition: QPSolver.h:313
const mc_rbdyn::Robots & robots() const
double dt() const
std::shared_ptr< mc_rtc::gui::StateBuilder > gui() const
virtual double solveTime()=0
bool run(FeedbackType fType=FeedbackType::None)
std::vector< std::shared_ptr< void > > shPtrTasksStorage
Definition: QPSolver.h:310
void controller(mc_control::MCController *ctl) noexcept
Definition: QPSolver.h:291
void gui(std::shared_ptr< mc_rtc::gui::StateBuilder > gui)
const mc_control::MCController * controller() const noexcept
Definition: QPSolver.h:293
mc_rbdyn::RobotsPtr robots_p
Definition: QPSolver.h:299
mc_rbdyn::Robots & realRobots()
Backend backend_
Definition: QPSolver.h:298
mc_rbdyn::Robot & env()
void setContacts(const std::vector< mc_rbdyn::Contact > &contacts={})
std::shared_ptr< mc_rtc::Logger > logger() const
void addConstraintSet(const std::unique_ptr< T > &ptr)
Definition: QPSolver.h:156
const std::vector< mc_rbdyn::Contact > & contacts() const noexcept
Definition: QPSolver.h:219
const mc_rbdyn::Robot & env() const
virtual bool run_impl(FeedbackType fType=FeedbackType::None)=0
mc_rbdyn::Robots & robots()
Represents a generic task.
Definition: MetaTask.h:40