mc_rtc  2.14.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  {
158  addConstraintSet(*ptr);
159  }
160 
165 
170  template<typename T>
171  inline void removeConstraintSet(const std::unique_ptr<T> & ptr)
172  {
173  removeConstraintSet(*ptr);
174  }
175 
186 
188  inline void addTask(std::shared_ptr<mc_tasks::MetaTask> task)
189  {
190  if(task)
191  {
192  addTask(task.get());
193  shPtrTasksStorage.emplace_back(task);
194  }
195  }
196 
206 
208  inline void removeTask(std::shared_ptr<mc_tasks::MetaTask> task)
209  {
210  if(task) { removeTask(task.get()); }
211  }
212 
216  void setContacts(const std::vector<mc_rbdyn::Contact> & contacts = {});
217 
218  /* Called by the owning controller to actually set the contacts or internally by QPSolver when it has no owning
219  * controller */
220  virtual void setContacts(ControllerToken, const std::vector<mc_rbdyn::Contact> & contacts) = 0;
221 
223  inline const std::vector<mc_rbdyn::Contact> & contacts() const noexcept { return contacts_; }
224 
226  inline const std::vector<mc_solver::ConstraintSet *> & constraints() const noexcept { return constraints_; }
227 
229  inline const std::vector<mc_tasks::MetaTask *> & tasks() const noexcept { return metaTasks_; }
230 
236  virtual const sva::ForceVecd desiredContactForce(const mc_rbdyn::Contact & id) const = 0;
237 
246  bool run(FeedbackType fType = FeedbackType::None);
247 
249  const mc_rbdyn::Robot & robot() const;
252 
254  mc_rbdyn::Robot & robot(unsigned int idx);
256  const mc_rbdyn::Robot & robot(unsigned int idx) const;
257 
259  const mc_rbdyn::Robot & env() const;
262 
264  const mc_rbdyn::Robots & robots() const;
267 
269  const mc_rbdyn::Robots & realRobots() const;
272 
276  double dt() const;
277 
279  virtual double solveTime() = 0;
280 
282  virtual double solveAndBuildTime() = 0;
283 
285  void logger(std::shared_ptr<mc_rtc::Logger> logger);
287  std::shared_ptr<mc_rtc::Logger> logger() const;
288 
290  void gui(std::shared_ptr<mc_rtc::gui::StateBuilder> gui);
292  std::shared_ptr<mc_rtc::gui::StateBuilder> gui() const;
293 
295  inline void controller(mc_control::MCController * ctl) noexcept { controller_ = ctl; }
297  inline const mc_control::MCController * controller() const noexcept { return controller_; }
299  inline mc_control::MCController * controller() noexcept { return controller_; }
300 
301 protected:
305  double timeStep;
306 
308  std::vector<mc_rbdyn::Contact> contacts_;
309 
311  std::vector<mc_tasks::MetaTask *> metaTasks_;
312 
314  std::vector<std::shared_ptr<void>> shPtrTasksStorage;
315 
317  std::vector<mc_solver::ConstraintSet *> constraints_;
318 
320  std::shared_ptr<mc_rtc::Logger> logger_ = nullptr;
321 
323  std::shared_ptr<mc_rtc::gui::StateBuilder> gui_ = nullptr;
324 
326 
328  mc_control::MCController * controller_ = nullptr;
329 
331  virtual bool run_impl(FeedbackType fType = FeedbackType::None) = 0;
332 
335 
337  virtual void removeDynamicsConstraint(mc_solver::ConstraintSet * maybe_dynamics) = 0;
338 };
339 
340 } // namespace mc_solver
341 
342 namespace fmt
343 {
344 
345 template<>
346 struct formatter<mc_solver::QPSolver::Backend> : public formatter<string_view>
347 {
348  template<typename FormatContext>
349 #if FMT_VERSION <= 9 * 10000
350  auto format(const mc_solver::QPSolver::Backend & backend, FormatContext & ctx)
351 #else
352  auto format(const mc_solver::QPSolver::Backend & backend, FormatContext & ctx) const -> decltype(ctx.out())
353 #endif
354  {
355  using Backend = mc_solver::QPSolver::Backend;
356  switch(backend)
357  {
358  case Backend::Tasks:
359  return formatter<string_view>::format("Tasks", ctx);
360  case Backend::TVM:
361  return formatter<string_view>::format("TVM", ctx);
362  case Backend::Unset:
363  return formatter<string_view>::format("Unset", ctx);
364  default:
365  return formatter<string_view>::format("UNEXPECTED", ctx);
366  }
367  }
368 };
369 
370 } // 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:350
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:305
void addTask(std::shared_ptr< mc_tasks::MetaTask > task)
Definition: QPSolver.h:188
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:304
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:229
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:171
Backend
Definition: QPSolver.h:93
mc_control::MCController * controller() noexcept
Definition: QPSolver.h:299
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:311
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:208
void addTaskToGUI(mc_tasks::MetaTask *task)
mc_rbdyn::Robot & robot()
const std::vector< mc_solver::ConstraintSet * > & constraints() const noexcept
Definition: QPSolver.h:226
std::vector< mc_rbdyn::Contact > contacts_
Definition: QPSolver.h:308
std::vector< mc_solver::ConstraintSet * > constraints_
Definition: QPSolver.h:317
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:314
void controller(mc_control::MCController *ctl) noexcept
Definition: QPSolver.h:295
void gui(std::shared_ptr< mc_rtc::gui::StateBuilder > gui)
const mc_control::MCController * controller() const noexcept
Definition: QPSolver.h:297
mc_rbdyn::RobotsPtr robots_p
Definition: QPSolver.h:303
mc_rbdyn::Robots & realRobots()
Backend backend_
Definition: QPSolver.h:302
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:223
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