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  const std::set<std::string>& get_active_set() const;
227 
231  const std::set<std::string>& get_inactive_set() const;
232 
236  const VectorXs& get_lb() const;
237 
241  const VectorXs& get_ub() const;
242 
248  bool getConstraintStatus(const std::string& name) const;
249 
253  template <class Scalar>
254  friend std::ostream& operator<<(
255  std::ostream& os, const ConstraintModelManagerTpl<Scalar>& model);
256 
257  private:
258  boost::shared_ptr<StateAbstract> state_;
259  ConstraintModelContainer constraints_;
260  VectorXs lb_;
261  VectorXs ub_;
262  std::size_t nu_;
263  std::size_t ng_;
264  std::size_t nh_;
265  std::set<std::string> active_set_;
266  std::set<std::string>
267  inactive_set_;
268 };
269 
270 template <typename _Scalar>
272  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
273 
274  typedef _Scalar Scalar;
278  typedef typename MathBase::VectorXs VectorXs;
279  typedef typename MathBase::MatrixXs MatrixXs;
280 
281  template <template <typename Scalar> class Model>
282  ConstraintDataManagerTpl(Model<Scalar>* const model,
283  DataCollectorAbstract* const data)
284  : g_internal(model->get_ng()),
285  Gx_internal(model->get_ng(), model->get_state()->get_ndx()),
286  Gu_internal(model->get_ng(), model->get_nu()),
287  h_internal(model->get_nh()),
288  Hx_internal(model->get_nh(), model->get_state()->get_ndx()),
289  Hu_internal(model->get_nh(), model->get_nu()),
290  shared(data),
291  g(g_internal.data(), model->get_ng()),
292  Gx(Gx_internal.data(), model->get_ng(), model->get_state()->get_ndx()),
293  Gu(Gu_internal.data(), model->get_ng(), model->get_nu()),
294  h(h_internal.data(), model->get_nh()),
295  Hx(Hx_internal.data(), model->get_nh(), model->get_state()->get_ndx()),
296  Hu(Hu_internal.data(), model->get_nh(), model->get_nu()) {
297  g.setZero();
298  Gx.setZero();
299  Gu.setZero();
300  h.setZero();
301  Hx.setZero();
302  Hu.setZero();
303  for (typename ConstraintModelManagerTpl<
304  Scalar>::ConstraintModelContainer::const_iterator it =
305  model->get_constraints().begin();
306  it != model->get_constraints().end(); ++it) {
307  const boost::shared_ptr<ConstraintItem>& item = it->second;
308  constraints.insert(
309  std::make_pair(item->name, item->constraint->createData(data)));
310  }
311  }
312 
313  template <class ActionData>
314  void shareMemory(ActionData* const data) {
315  // Save memory by setting the internal variables with null dimension
316  g_internal.resize(0);
317  Gx_internal.resize(0, 0);
318  Gu_internal.resize(0, 0);
319  h_internal.resize(0);
320  Hx_internal.resize(0, 0);
321  Hu_internal.resize(0, 0);
322  // Share memory with the differential action data
323  new (&g) Eigen::Map<VectorXs>(data->g.data(), data->g.size());
324  new (&Gx)
325  Eigen::Map<MatrixXs>(data->Gx.data(), data->Gx.rows(), data->Gx.cols());
326  new (&Gu)
327  Eigen::Map<MatrixXs>(data->Gu.data(), data->Gu.rows(), data->Gu.cols());
328  new (&h) Eigen::Map<VectorXs>(data->h.data(), data->h.size());
329  new (&Hx)
330  Eigen::Map<MatrixXs>(data->Hx.data(), data->Hx.rows(), data->Hx.cols());
331  new (&Hu)
332  Eigen::Map<MatrixXs>(data->Hu.data(), data->Hu.rows(), data->Hu.cols());
333  }
334 
335  template <class ActionModel, class ActionData>
336  void resize(ActionModel* const model, ActionData* const data) {
337  const std::size_t ndx = model->get_state()->get_ndx();
338  const std::size_t nu = model->get_nu();
339  const std::size_t ng = model->get_ng();
340  const std::size_t nh = model->get_nh();
341  data->g.conservativeResize(ng);
342  data->Gx.conservativeResize(ng, ndx);
343  data->Gu.conservativeResize(ng, nu);
344  data->h.conservativeResize(nh);
345  data->Hx.conservativeResize(nh, ndx);
346  data->Hu.conservativeResize(nh, nu);
347  new (&g) Eigen::Map<VectorXs>(data->g.data(), ng);
348  new (&Gx) Eigen::Map<MatrixXs>(data->Gx.data(), ng, ndx);
349  new (&Gu) Eigen::Map<MatrixXs>(data->Gu.data(), ng, nu);
350  new (&h) Eigen::Map<VectorXs>(data->h.data(), nh);
351  new (&Hx) Eigen::Map<MatrixXs>(data->Hx.data(), nh, ndx);
352  new (&Hu) Eigen::Map<MatrixXs>(data->Hu.data(), nh, nu);
353  }
354 
355  VectorXs get_g() const { return g; }
356  MatrixXs get_Gx() const { return Gx; }
357  MatrixXs get_Gu() const { return Gu; }
358  VectorXs get_h() const { return h; }
359  MatrixXs get_Hx() const { return Hx; }
360  MatrixXs get_Hu() const { return Hu; }
361 
362  void set_g(const VectorXs& _g) {
363  if (g.size() != _g.size()) {
364  throw_pretty("Invalid argument: "
365  << "g has wrong dimension (it should be " +
366  std::to_string(g.size()) + ")");
367  }
368  g = _g;
369  }
370  void set_Gx(const MatrixXs& _Gx) {
371  if (Gx.rows() != _Gx.rows() || Gx.cols() != _Gx.cols()) {
372  throw_pretty("Invalid argument: "
373  << "Gx has wrong dimension (it should be " +
374  std::to_string(Gx.rows()) + ", " +
375  std::to_string(Gx.cols()) + ")");
376  }
377  Gx = _Gx;
378  }
379  void set_Gu(const MatrixXs& _Gu) {
380  if (Gu.rows() != _Gu.rows() || Gu.cols() != _Gu.cols()) {
381  throw_pretty("Invalid argument: "
382  << "Gu has wrong dimension (it should be " +
383  std::to_string(Gu.rows()) + ", " +
384  std::to_string(Gu.cols()) + ")");
385  }
386  Gu = _Gu;
387  }
388  void set_h(const VectorXs& _h) {
389  if (h.size() != _h.size()) {
390  throw_pretty("Invalid argument: "
391  << "h has wrong dimension (it should be " +
392  std::to_string(h.size()) + ")");
393  }
394  h = _h;
395  }
396  void set_Hx(const MatrixXs& _Hx) {
397  if (Hx.rows() != _Hx.rows() || Hx.cols() != _Hx.cols()) {
398  throw_pretty("Invalid argument: "
399  << "Hx has wrong dimension (it should be " +
400  std::to_string(Hx.rows()) + ", " +
401  std::to_string(Hx.cols()) + ")");
402  }
403  Hx = _Hx;
404  }
405  void set_Hu(const MatrixXs& _Hu) {
406  if (Hu.rows() != _Hu.rows() || Hu.cols() != _Hu.cols()) {
407  throw_pretty("Invalid argument: "
408  << "Hu has wrong dimension (it should be " +
409  std::to_string(Hu.rows()) + ", " +
410  std::to_string(Hu.cols()) + ")");
411  }
412  Hu = _Hu;
413  }
414 
415  // Creates internal data in case we don't share it externally
416  VectorXs g_internal;
417  MatrixXs Gx_internal;
418  MatrixXs Gu_internal;
419  VectorXs h_internal;
420  MatrixXs Hx_internal;
421  MatrixXs Hu_internal;
422 
424  constraints;
425  DataCollectorAbstract* shared;
426  Eigen::Map<VectorXs> g;
427  Eigen::Map<MatrixXs> Gx;
428  Eigen::Map<MatrixXs> Gu;
429  Eigen::Map<VectorXs> h;
430  Eigen::Map<MatrixXs> Hx;
431  Eigen::Map<MatrixXs> Hu;
432 };
433 
434 } // namespace crocoddyl
435 
436 /* --- Details -------------------------------------------------------------- */
437 /* --- Details -------------------------------------------------------------- */
438 /* --- Details -------------------------------------------------------------- */
439 #include "crocoddyl/core/constraints/constraint-manager.hxx"
440 
441 #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.
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() 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.