Crocoddyl
constraint-manager.hpp
1 // BSD 3-Clause License
3 //
4 // Copyright (C) 2020-2024, University of Edinburgh, Heriot-Watt University
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
8 
9 #ifndef CROCODDYL_CORE_CONSTRAINTS_CONSTRAINT_MANAGER_HPP_
10 #define CROCODDYL_CORE_CONSTRAINTS_CONSTRAINT_MANAGER_HPP_
11 
12 #include <map>
13 #include <set>
14 #include <string>
15 #include <utility>
16 
17 #include "crocoddyl/core/constraint-base.hpp"
18 #include "crocoddyl/core/utils/exception.hpp"
19 
20 namespace crocoddyl {
21 
22 template <typename _Scalar>
24  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
25 
26  typedef _Scalar Scalar;
28 
30  ConstraintItemTpl(const std::string& name,
31  boost::shared_ptr<ConstraintModelAbstract> constraint,
32  bool active = true)
33  : name(name), constraint(constraint), active(active) {}
34 
38  friend std::ostream& operator<<(std::ostream& os,
39  const ConstraintItemTpl<Scalar>& model) {
40  os << "{" << *model.constraint << "}";
41  return os;
42  }
43 
44  std::string name;
45  boost::shared_ptr<ConstraintModelAbstract> constraint;
46  bool active;
47 };
48 
67 template <typename _Scalar>
69  public:
70  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
71 
72  typedef _Scalar Scalar;
80  typedef typename MathBase::VectorXs VectorXs;
81  typedef typename MathBase::MatrixXs MatrixXs;
82 
83  typedef std::map<std::string, boost::shared_ptr<ConstraintItem> >
84  ConstraintModelContainer;
85  typedef std::map<std::string, boost::shared_ptr<ConstraintDataAbstract> >
86  ConstraintDataContainer;
87 
94  ConstraintModelManagerTpl(boost::shared_ptr<StateAbstract> state,
95  const std::size_t nu);
96 
104  explicit ConstraintModelManagerTpl(boost::shared_ptr<StateAbstract> state);
106 
115  void addConstraint(const std::string& name,
116  boost::shared_ptr<ConstraintModelAbstract> constraint,
117  const bool active = true);
118 
124  void removeConstraint(const std::string& name);
125 
133  void changeConstraintStatus(const std::string& name, bool active);
134 
142  void calc(const boost::shared_ptr<ConstraintDataManager>& data,
143  const Eigen::Ref<const VectorXs>& x,
144  const Eigen::Ref<const VectorXs>& u);
145 
156  void calc(const boost::shared_ptr<ConstraintDataManager>& data,
157  const Eigen::Ref<const VectorXs>& x);
158 
166  void calcDiff(const boost::shared_ptr<ConstraintDataManager>& data,
167  const Eigen::Ref<const VectorXs>& x,
168  const Eigen::Ref<const VectorXs>& u);
169 
181  void calcDiff(const boost::shared_ptr<ConstraintDataManager>& data,
182  const Eigen::Ref<const VectorXs>& x);
183 
195  boost::shared_ptr<ConstraintDataManager> createData(
196  DataCollectorAbstract* const data);
197 
201  const boost::shared_ptr<StateAbstract>& get_state() const;
202 
206  const ConstraintModelContainer& get_constraints() const;
207 
211  std::size_t get_nu() const;
212 
216  std::size_t get_ng() const;
217 
221  std::size_t get_nh() const;
222 
226  std::size_t get_ng_T() const;
227 
231  std::size_t get_nh_T() const;
232 
236  const std::set<std::string>& get_active_set() const;
237 
241  const std::set<std::string>& get_inactive_set() const;
242 
246  const VectorXs& get_lb() const;
247 
251  const VectorXs& get_ub() const;
252 
258  bool getConstraintStatus(const std::string& name) const;
259 
263  template <class Scalar>
264  friend std::ostream& operator<<(
265  std::ostream& os, const ConstraintModelManagerTpl<Scalar>& model);
266 
267  private:
268  boost::shared_ptr<StateAbstract> state_;
269  ConstraintModelContainer constraints_;
270  VectorXs lb_;
271  VectorXs ub_;
272  std::size_t nu_;
273  std::size_t ng_;
274  std::size_t nh_;
275  std::size_t ng_T_;
276  std::size_t nh_T_;
277  std::set<std::string> active_set_;
278  std::set<std::string>
279  inactive_set_;
280 };
281 
282 template <typename _Scalar>
284  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
285 
286  typedef _Scalar Scalar;
290  typedef typename MathBase::VectorXs VectorXs;
291  typedef typename MathBase::MatrixXs MatrixXs;
292 
293  template <template <typename Scalar> class Model>
294  ConstraintDataManagerTpl(Model<Scalar>* const model,
295  DataCollectorAbstract* const data)
296  : g_internal(model->get_ng()),
297  Gx_internal(model->get_ng(), model->get_state()->get_ndx()),
298  Gu_internal(model->get_ng(), model->get_nu()),
299  h_internal(model->get_nh()),
300  Hx_internal(model->get_nh(), model->get_state()->get_ndx()),
301  Hu_internal(model->get_nh(), model->get_nu()),
302  shared(data),
303  g(g_internal.data(), model->get_ng()),
304  Gx(Gx_internal.data(), model->get_ng(), model->get_state()->get_ndx()),
305  Gu(Gu_internal.data(), model->get_ng(), model->get_nu()),
306  h(h_internal.data(), model->get_nh()),
307  Hx(Hx_internal.data(), model->get_nh(), model->get_state()->get_ndx()),
308  Hu(Hu_internal.data(), model->get_nh(), model->get_nu()) {
309  g.setZero();
310  Gx.setZero();
311  Gu.setZero();
312  h.setZero();
313  Hx.setZero();
314  Hu.setZero();
315  for (typename ConstraintModelManagerTpl<
316  Scalar>::ConstraintModelContainer::const_iterator it =
317  model->get_constraints().begin();
318  it != model->get_constraints().end(); ++it) {
319  const boost::shared_ptr<ConstraintItem>& item = it->second;
320  constraints.insert(
321  std::make_pair(item->name, item->constraint->createData(data)));
322  }
323  }
324 
325  template <class ActionData>
326  void shareMemory(ActionData* const data) {
327  // Save memory by setting the internal variables with null dimension
328  g_internal.resize(0);
329  Gx_internal.resize(0, 0);
330  Gu_internal.resize(0, 0);
331  h_internal.resize(0);
332  Hx_internal.resize(0, 0);
333  Hu_internal.resize(0, 0);
334  // Share memory with the differential action data
335  new (&g) Eigen::Map<VectorXs>(data->g.data(), data->g.size());
336  new (&Gx)
337  Eigen::Map<MatrixXs>(data->Gx.data(), data->Gx.rows(), data->Gx.cols());
338  new (&Gu)
339  Eigen::Map<MatrixXs>(data->Gu.data(), data->Gu.rows(), data->Gu.cols());
340  new (&h) Eigen::Map<VectorXs>(data->h.data(), data->h.size());
341  new (&Hx)
342  Eigen::Map<MatrixXs>(data->Hx.data(), data->Hx.rows(), data->Hx.cols());
343  new (&Hu)
344  Eigen::Map<MatrixXs>(data->Hu.data(), data->Hu.rows(), data->Hu.cols());
345  }
346 
347  template <class Model>
348  void resize(Model* const model, const bool running_node = true) {
349  const std::size_t ndx = model->get_state()->get_ndx();
350  const std::size_t nu = model->get_nu();
351  const std::size_t ng = running_node ? model->get_ng() : model->get_ng_T();
352  const std::size_t nh = running_node ? model->get_nh() : model->get_nh_T();
353  new (&g) Eigen::Map<VectorXs>(g_internal.data(), ng);
354  new (&Gx) Eigen::Map<MatrixXs>(Gx_internal.data(), ng, ndx);
355  new (&Gu) Eigen::Map<MatrixXs>(Gu_internal.data(), ng, nu);
356  new (&h) Eigen::Map<VectorXs>(h_internal.data(), nh);
357  new (&Hx) Eigen::Map<MatrixXs>(Hx_internal.data(), nh, ndx);
358  new (&Hu) Eigen::Map<MatrixXs>(Hu_internal.data(), nh, nu);
359  }
360 
361  template <class ActionModel, class ActionData>
362  void resize(ActionModel* const model, ActionData* const data,
363  const bool running_node = true) {
364  const std::size_t ndx = model->get_state()->get_ndx();
365  const std::size_t nu = model->get_nu();
366  const std::size_t ng = running_node ? model->get_ng() : model->get_ng_T();
367  const std::size_t nh = running_node ? model->get_nh() : model->get_nh_T();
368  data->g.conservativeResize(ng);
369  data->Gx.conservativeResize(ng, ndx);
370  data->Gu.conservativeResize(ng, nu);
371  data->h.conservativeResize(nh);
372  data->Hx.conservativeResize(nh, ndx);
373  data->Hu.conservativeResize(nh, nu);
374  new (&g) Eigen::Map<VectorXs>(data->g.data(), ng);
375  new (&Gx) Eigen::Map<MatrixXs>(data->Gx.data(), ng, ndx);
376  new (&Gu) Eigen::Map<MatrixXs>(data->Gu.data(), ng, nu);
377  new (&h) Eigen::Map<VectorXs>(data->h.data(), nh);
378  new (&Hx) Eigen::Map<MatrixXs>(data->Hx.data(), nh, ndx);
379  new (&Hu) Eigen::Map<MatrixXs>(data->Hu.data(), nh, nu);
380  }
381 
382  VectorXs get_g() const { return g; }
383  MatrixXs get_Gx() const { return Gx; }
384  MatrixXs get_Gu() const { return Gu; }
385  VectorXs get_h() const { return h; }
386  MatrixXs get_Hx() const { return Hx; }
387  MatrixXs get_Hu() const { return Hu; }
388 
389  void set_g(const VectorXs& _g) {
390  if (g.size() != _g.size()) {
391  throw_pretty(
392  "Invalid argument: " << "g has wrong dimension (it should be " +
393  std::to_string(g.size()) + ")");
394  }
395  g = _g;
396  }
397  void set_Gx(const MatrixXs& _Gx) {
398  if (Gx.rows() != _Gx.rows() || Gx.cols() != _Gx.cols()) {
399  throw_pretty(
400  "Invalid argument: " << "Gx has wrong dimension (it should be " +
401  std::to_string(Gx.rows()) + ", " +
402  std::to_string(Gx.cols()) + ")");
403  }
404  Gx = _Gx;
405  }
406  void set_Gu(const MatrixXs& _Gu) {
407  if (Gu.rows() != _Gu.rows() || Gu.cols() != _Gu.cols()) {
408  throw_pretty(
409  "Invalid argument: " << "Gu has wrong dimension (it should be " +
410  std::to_string(Gu.rows()) + ", " +
411  std::to_string(Gu.cols()) + ")");
412  }
413  Gu = _Gu;
414  }
415  void set_h(const VectorXs& _h) {
416  if (h.size() != _h.size()) {
417  throw_pretty(
418  "Invalid argument: " << "h has wrong dimension (it should be " +
419  std::to_string(h.size()) + ")");
420  }
421  h = _h;
422  }
423  void set_Hx(const MatrixXs& _Hx) {
424  if (Hx.rows() != _Hx.rows() || Hx.cols() != _Hx.cols()) {
425  throw_pretty(
426  "Invalid argument: " << "Hx has wrong dimension (it should be " +
427  std::to_string(Hx.rows()) + ", " +
428  std::to_string(Hx.cols()) + ")");
429  }
430  Hx = _Hx;
431  }
432  void set_Hu(const MatrixXs& _Hu) {
433  if (Hu.rows() != _Hu.rows() || Hu.cols() != _Hu.cols()) {
434  throw_pretty(
435  "Invalid argument: " << "Hu has wrong dimension (it should be " +
436  std::to_string(Hu.rows()) + ", " +
437  std::to_string(Hu.cols()) + ")");
438  }
439  Hu = _Hu;
440  }
441 
442  // Creates internal data in case we don't share it externally
443  VectorXs g_internal;
444  MatrixXs Gx_internal;
445  MatrixXs Gu_internal;
446  VectorXs h_internal;
447  MatrixXs Hx_internal;
448  MatrixXs Hu_internal;
449 
451  constraints;
452  DataCollectorAbstract* shared;
453  Eigen::Map<VectorXs> g;
454  Eigen::Map<MatrixXs> Gx;
455  Eigen::Map<MatrixXs> Gu;
456  Eigen::Map<VectorXs> h;
457  Eigen::Map<MatrixXs> Hx;
458  Eigen::Map<MatrixXs> Hu;
459 };
460 
461 } // namespace crocoddyl
462 
463 /* --- Details -------------------------------------------------------------- */
464 /* --- Details -------------------------------------------------------------- */
465 /* --- Details -------------------------------------------------------------- */
466 #include "crocoddyl/core/constraints/constraint-manager.hxx"
467 
468 #endif // CROCODDYL_CORE_CONSTRAINTS_CONSTRAINT_MANAGER_HPP_
Abstract class for constraint models.
Manage the individual constraint models.
friend std::ostream & operator<<(std::ostream &os, const ConstraintModelManagerTpl< Scalar > &model)
Print information on the stack of constraints.
void removeConstraint(const std::string &name)
Remove a constraint item.
void changeConstraintStatus(const std::string &name, bool active)
Change the constraint status.
std::size_t get_nh_T() const
Return the number of active equality terminal constraints.
void calc(const boost::shared_ptr< ConstraintDataManager > &data, const Eigen::Ref< const VectorXs > &x, const Eigen::Ref< const VectorXs > &u)
Compute the total constraint value.
std::size_t get_ng_T() const
Return the number of active inequality terminal constraints.
std::size_t get_ng() const
Return the number of active inequality constraints.
ConstraintModelManagerTpl(boost::shared_ptr< StateAbstract > state, const std::size_t nu)
Initialize the constraint-manager model.
const boost::shared_ptr< StateAbstract > & get_state() const
Return the state.
void calc(const boost::shared_ptr< ConstraintDataManager > &data, const Eigen::Ref< const VectorXs > &x)
Compute the total constraint value for nodes that depends only on the state.
const VectorXs & get_lb() const
Return the state lower bound.
void calcDiff(const boost::shared_ptr< ConstraintDataManager > &data, const Eigen::Ref< const VectorXs > &x, const Eigen::Ref< const VectorXs > &u)
Compute the Jacobian of the total constraint.
const VectorXs & get_ub() const
Return the state upper bound.
boost::shared_ptr< ConstraintDataManager > createData(DataCollectorAbstract *const data)
Create the constraint data.
std::size_t get_nh() const
Return the number of active equality constraints.
const std::set< std::string > & get_inactive_set() const
Return the names of the set of inactive constraints.
void addConstraint(const std::string &name, boost::shared_ptr< ConstraintModelAbstract > constraint, const bool active=true)
Add a constraint item.
const std::set< std::string > & get_active_set() const
Return the names of the set of active constraints.
const ConstraintModelContainer & get_constraints() const
Return the stack of constraint models.
ConstraintModelManagerTpl(boost::shared_ptr< StateAbstract > state)
Initialize the constraint-manager model.
bool getConstraintStatus(const std::string &name) const
Return the status of a given constraint name.
std::size_t get_nu() const
Return the dimension of the control input.
void calcDiff(const boost::shared_ptr< ConstraintDataManager > &data, const Eigen::Ref< const VectorXs > &x)
Compute the Jacobian of the total constraint with respect to the state only.
Abstract class for the state representation.
Definition: state-base.hpp:46
friend std::ostream & operator<<(std::ostream &os, const ConstraintItemTpl< Scalar > &model)
Print information on the constraint item.