Crocoddyl
 
Loading...
Searching...
No Matches
constraint-manager.hpp
1
2// 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
20namespace crocoddyl {
21
22template <typename _Scalar>
24 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
25
26 typedef _Scalar Scalar;
28
30 ConstraintItemTpl(const std::string& name,
31 std::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 std::shared_ptr<ConstraintModelAbstract> constraint;
46 bool active;
47};
48
67template <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, std::shared_ptr<ConstraintItem> >
84 ConstraintModelContainer;
85 typedef std::map<std::string, std::shared_ptr<ConstraintDataAbstract> >
86 ConstraintDataContainer;
87
94 ConstraintModelManagerTpl(std::shared_ptr<StateAbstract> state,
95 const std::size_t nu);
96
104 explicit ConstraintModelManagerTpl(std::shared_ptr<StateAbstract> state);
106
115 void addConstraint(const std::string& name,
116 std::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 std::shared_ptr<ConstraintDataManager>& data,
143 const Eigen::Ref<const VectorXs>& x,
144 const Eigen::Ref<const VectorXs>& u);
145
156 void calc(const std::shared_ptr<ConstraintDataManager>& data,
157 const Eigen::Ref<const VectorXs>& x);
158
166 void calcDiff(const std::shared_ptr<ConstraintDataManager>& data,
167 const Eigen::Ref<const VectorXs>& x,
168 const Eigen::Ref<const VectorXs>& u);
169
181 void calcDiff(const std::shared_ptr<ConstraintDataManager>& data,
182 const Eigen::Ref<const VectorXs>& x);
183
195 std::shared_ptr<ConstraintDataManager> createData(
196 DataCollectorAbstract* const data);
197
201 const std::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 std::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
282template <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 std::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
450 typename ConstraintModelManagerTpl<Scalar>::ConstraintDataContainer
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.
const VectorXs & get_ub() const
Return the state upper bound.
std::shared_ptr< ConstraintDataManager > createData(DataCollectorAbstract *const data)
Create the constraint data.
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.
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.
const std::set< std::string > & get_active_set() const
Return the names of the set of active constraints.
const std::set< std::string > & get_inactive_set() const
Return the names of the set of inactive constraints.
const ConstraintModelContainer & get_constraints() const
Return the stack of constraint models.
const VectorXs & get_lb() const
Return the state lower bound.
std::size_t get_nh() const
Return the number of active equality constraints.
void calcDiff(const std::shared_ptr< ConstraintDataManager > &data, const Eigen::Ref< const VectorXs > &x, const Eigen::Ref< const VectorXs > &u)
Compute the Jacobian of the total constraint.
void calc(const std::shared_ptr< ConstraintDataManager > &data, const Eigen::Ref< const VectorXs > &x, const Eigen::Ref< const VectorXs > &u)
Compute the total constraint value.
friend std::ostream & operator<<(std::ostream &os, const ConstraintModelManagerTpl< Scalar > &model)
Print information on the stack of constraints.
ConstraintModelManagerTpl(std::shared_ptr< StateAbstract > state, const std::size_t nu)
Initialize the constraint-manager model.
const std::shared_ptr< StateAbstract > & get_state() const
Return the state.
ConstraintModelManagerTpl(std::shared_ptr< StateAbstract > state)
Initialize the constraint-manager model.
void calcDiff(const std::shared_ptr< ConstraintDataManager > &data, const Eigen::Ref< const VectorXs > &x)
Compute the Jacobian of the total constraint with respect to the state only.
void calc(const std::shared_ptr< ConstraintDataManager > &data, const Eigen::Ref< const VectorXs > &x)
Compute the total constraint value for nodes that depends only on the state.
void addConstraint(const std::string &name, std::shared_ptr< ConstraintModelAbstract > constraint, const bool active=true)
Add a constraint item.
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.
Abstract class for the state representation.
friend std::ostream & operator<<(std::ostream &os, const ConstraintItemTpl< Scalar > &model)
Print information on the constraint item.