GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/core/constraint-base.hpp
Date: 2025-01-16 08:47:40
Exec Total Coverage
Lines: 17 18 94.4%
Branches: 16 40 40.0%

Line Branch Exec Source
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.
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #ifndef CROCODDYL_CORE_CONSTRAINT_BASE_HPP_
10 #define CROCODDYL_CORE_CONSTRAINT_BASE_HPP_
11
12 #include <boost/make_shared.hpp>
13 #include <boost/shared_ptr.hpp>
14
15 #include "crocoddyl/core/fwd.hpp"
16 //
17 #include "crocoddyl/core/data-collector-base.hpp"
18 #include "crocoddyl/core/residual-base.hpp"
19 #include "crocoddyl/core/state-base.hpp"
20
21 namespace crocoddyl {
22
23 enum ConstraintType { Inequality = 0, Equality, Both };
24
25 /**
26 * @brief Abstract class for constraint models
27 *
28 * A constraint model defines both: inequality \f$\mathbf{g}(\mathbf{x},
29 * \mathbf{u})\in\mathbb{R}^{ng}\f$ and equality \f$\mathbf{h}(\mathbf{x},
30 * \mathbf{u})\in\mathbb{R}^{nh}\f$ constraints. The constraint function depends
31 * on the state point \f$\mathbf{x}\in\mathcal{X}\f$, which lies in the state
32 * manifold described with a `nx`-tuple, its velocity \f$\dot{\mathbf{x}}\in
33 * T_{\mathbf{x}}\mathcal{X}\f$ that belongs to the tangent space with `ndx`
34 * dimension, and the control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$.
35 *
36 * The main computations are carried out in `calc()` and `calcDiff()` routines.
37 * `calc()` computes the constraint residual and `calcDiff()` computes the
38 * Jacobians of the constraint function. Concretely speaking, `calcDiff()`
39 * builds a linear approximation of the constraint function with the form:
40 * \f$\mathbf{g_x}\in\mathbb{R}^{ng\times ndx}\f$,
41 * \f$\mathbf{g_u}\in\mathbb{R}^{ng\times nu}\f$,
42 * \f$\mathbf{h_x}\in\mathbb{R}^{nh\times ndx}\f$
43 * \f$\mathbf{h_u}\in\mathbb{R}^{nh\times nu}\f$. Additionally, it is important
44 * to note that `calcDiff()` computes the derivatives using the latest stored
45 * values by `calc()`. Thus, we need to first run `calc()`.
46 *
47 * \sa `calc()`, `calcDiff()`, `createData()`
48 */
49 template <typename _Scalar>
50 class ConstraintModelAbstractTpl {
51 public:
52 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
53
54 typedef _Scalar Scalar;
55 typedef MathBaseTpl<Scalar> MathBase;
56 typedef ConstraintDataAbstractTpl<Scalar> ConstraintDataAbstract;
57 typedef StateAbstractTpl<Scalar> StateAbstract;
58 typedef ResidualModelAbstractTpl<Scalar> ResidualModelAbstract;
59 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
60 typedef typename MathBase::VectorXs VectorXs;
61
62 /**
63 * @brief Initialize the constraint model
64 *
65 * @param[in] state State of the multibody system
66 * @param[in] residual Residual model
67 * @param[in] ng Number of inequality constraints
68 * @param[in] nh Number of equality constraints
69 */
70 ConstraintModelAbstractTpl(boost::shared_ptr<StateAbstract> state,
71 boost::shared_ptr<ResidualModelAbstract> residual,
72 const std::size_t ng, const std::size_t nh);
73
74 /**
75 * @copybrief Initialize the constraint model
76 *
77 * @param[in] state State of the multibody system
78 * @param[in] nu Dimension of control vector
79 * @param[in] ng Number of inequality constraints
80 * @param[in] nh Number of equality constraints
81 * @param[in] T_const True if this is a constraint in both running and
82 * terminal nodes. False if it is a constraint on running nodes only (default
83 * true)
84 */
85 ConstraintModelAbstractTpl(boost::shared_ptr<StateAbstract> state,
86 const std::size_t nu, const std::size_t ng,
87 const std::size_t nh, const bool T_const = true);
88
89 /**
90 * @copybrief ConstraintModelAbstractTpl()
91 *
92 * The default `nu` value is obtained from `StateAbstractTpl::get_nv()`.
93 *
94 * @param[in] state State of the multibody system
95 * @param[in] ng Number of inequality constraints
96 * @param[in] nh Number of equality constraints
97 * @param[in] T_const True if this is a constraint in both running and
98 * terminal nodes. False if it is a constraint on running nodes only (default
99 * true)
100 */
101 ConstraintModelAbstractTpl(boost::shared_ptr<StateAbstract> state,
102 const std::size_t ng, const std::size_t nh,
103 const bool T_const = true);
104 virtual ~ConstraintModelAbstractTpl();
105
106 /**
107 * @brief Compute the constraint value
108 *
109 * @param[in] data Constraint data
110 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
111 * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
112 */
113 virtual void calc(const boost::shared_ptr<ConstraintDataAbstract>& data,
114 const Eigen::Ref<const VectorXs>& x,
115 const Eigen::Ref<const VectorXs>& u) = 0;
116
117 /**
118 * @brief Compute the constraint value for nodes that depends only on the
119 * state
120 *
121 * It updates the constraint based on the state only. This function is
122 * commonly used in the terminal nodes of an optimal control problem.
123 *
124 * @param[in] data Constraint data
125 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
126 */
127 virtual void calc(const boost::shared_ptr<ConstraintDataAbstract>& data,
128 const Eigen::Ref<const VectorXs>& x);
129
130 /**
131 * @brief Compute the Jacobian of the constraint
132 *
133 * It computes the Jacobian of the constraint function. It assumes that
134 * `calc()` has been run first.
135 *
136 * @param[in] data Constraint data
137 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
138 * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
139 */
140 virtual void calcDiff(const boost::shared_ptr<ConstraintDataAbstract>& data,
141 const Eigen::Ref<const VectorXs>& x,
142 const Eigen::Ref<const VectorXs>& u) = 0;
143
144 /**
145 * @brief Compute the Jacobian of the constraint with respect to the state
146 * only
147 *
148 * It computes the Jacobian of the constraint function based on the state
149 * only. This function is commonly used in the terminal nodes of an optimal
150 * control problem.
151 *
152 * @param[in] data Constraint data
153 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
154 */
155 virtual void calcDiff(const boost::shared_ptr<ConstraintDataAbstract>& data,
156 const Eigen::Ref<const VectorXs>& x);
157
158 /**
159 * @brief Create the constraint data
160 *
161 * The default data contains objects to store the values of the constraint,
162 * residual vector and their first derivatives. However, it is possible to
163 * specialize this function is we need to create additional data, for
164 * instance, to avoid dynamic memory allocation.
165 *
166 * @param data Data collector
167 * @return the constraint data
168 */
169 virtual boost::shared_ptr<ConstraintDataAbstract> createData(
170 DataCollectorAbstract* const data);
171
172 /**
173 * @brief Update the lower and upper bounds the upper bound of constraint
174 */
175 void update_bounds(const VectorXs& lower, const VectorXs& upper);
176
177 /**
178 * @brief Remove the bounds of the constraint
179 */
180 void remove_bounds();
181
182 /**
183 * @brief Return the state
184 */
185 const boost::shared_ptr<StateAbstract>& get_state() const;
186
187 /**
188 * @brief Return the residual model
189 */
190 const boost::shared_ptr<ResidualModelAbstract>& get_residual() const;
191
192 /**
193 * @brief Return the type of constraint
194 */
195 ConstraintType get_type() const;
196
197 /**
198 * @brief Return the lower bound of the constraint
199 */
200 const VectorXs& get_lb() const;
201
202 /**
203 * @brief Return the upper bound of the constraint
204 */
205 const VectorXs& get_ub() const;
206
207 /**
208 * @brief Return the dimension of the control input
209 */
210 std::size_t get_nu() const;
211
212 /**
213 * @brief Return the number of inequality constraints
214 */
215 std::size_t get_ng() const;
216
217 /**
218 * @brief Return the number of equality constraints
219 */
220 std::size_t get_nh() const;
221
222 /**
223 * @brief Return true if the constraint is imposed in terminal nodes as well.
224 */
225 bool get_T_constraint() const;
226
227 /**
228 * @brief Print information on the constraint model
229 */
230 template <class Scalar>
231 friend std::ostream& operator<<(std::ostream& os,
232 const CostModelAbstractTpl<Scalar>& model);
233
234 /**
235 * @brief Print relevant information of the constraint model
236 *
237 * @param[out] os Output stream object
238 */
239 virtual void print(std::ostream& os) const;
240
241 private:
242 std::size_t ng_internal_; //!< Number of inequality constraints defined at
243 //!< construction time
244 std::size_t nh_internal_; //!< Number of equality constraints defined at
245 //!< construction time
246
247 protected:
248 boost::shared_ptr<StateAbstract> state_; //!< State description
249 boost::shared_ptr<ResidualModelAbstract> residual_; //!< Residual model
250 ConstraintType
251 type_; //!< Type of constraint: inequality=0, equality=1, both=2
252 VectorXs lb_; //!< Lower bound of the constraint
253 VectorXs ub_; //!< Upper bound of the constraint
254 std::size_t nu_; //!< Control dimension
255 std::size_t ng_; //!< Number of inequality constraints
256 std::size_t nh_; //!< Number of equality constraints
257 bool T_constraint_; //!< Label that indicates if the constraint is imposed in
258 //!< terminal nodes as well
259 VectorXs unone_; //!< No control vector
260 };
261
262 template <typename _Scalar>
263 struct ConstraintDataAbstractTpl {
264 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
265
266 typedef _Scalar Scalar;
267 typedef MathBaseTpl<Scalar> MathBase;
268 typedef ResidualDataAbstractTpl<Scalar> ResidualDataAbstract;
269 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
270 typedef typename MathBase::VectorXs VectorXs;
271 typedef typename MathBase::MatrixXs MatrixXs;
272
273 template <template <typename Scalar> class Model>
274 459616 ConstraintDataAbstractTpl(Model<Scalar>* const model,
275 DataCollectorAbstract* const data)
276 459616 : shared(data),
277 459616 residual(model->get_residual()->createData(data)),
278
1/2
✓ Branch 2 taken 229808 times.
✗ Branch 3 not taken.
459616 g(model->get_ng()),
279
1/2
✓ Branch 5 taken 229808 times.
✗ Branch 6 not taken.
459616 Gx(model->get_ng(), model->get_state()->get_ndx()),
280
1/2
✓ Branch 3 taken 229808 times.
✗ Branch 4 not taken.
459616 Gu(model->get_ng(), model->get_nu()),
281
1/2
✓ Branch 2 taken 229808 times.
✗ Branch 3 not taken.
459616 h(model->get_nh()),
282
1/2
✓ Branch 5 taken 229808 times.
✗ Branch 6 not taken.
459616 Hx(model->get_nh(), model->get_state()->get_ndx()),
283
1/2
✓ Branch 4 taken 229808 times.
✗ Branch 5 not taken.
919232 Hu(model->get_nh(), model->get_nu()) {
284
4/6
✓ Branch 1 taken 222503 times.
✓ Branch 2 taken 7305 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 222503 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 229808 times.
459616 if (model->get_ng() == 0 && model->get_nh() == 0) {
285 throw_pretty("Invalid argument: " << "ng and nh cannot be equals to 0");
286 }
287
1/2
✓ Branch 1 taken 229808 times.
✗ Branch 2 not taken.
459616 g.setZero();
288
1/2
✓ Branch 1 taken 229808 times.
✗ Branch 2 not taken.
459616 Gx.setZero();
289
1/2
✓ Branch 1 taken 229808 times.
✗ Branch 2 not taken.
459616 Gu.setZero();
290
1/2
✓ Branch 1 taken 229808 times.
✗ Branch 2 not taken.
459616 h.setZero();
291
1/2
✓ Branch 1 taken 229808 times.
✗ Branch 2 not taken.
459616 Hx.setZero();
292
1/2
✓ Branch 1 taken 229808 times.
✗ Branch 2 not taken.
459616 Hu.setZero();
293 }
294 229818 virtual ~ConstraintDataAbstractTpl() {}
295
296 DataCollectorAbstract* shared; //!< Shared data
297 boost::shared_ptr<ResidualDataAbstract> residual; //!< Residual data
298 VectorXs g; //!< Inequality constraint values
299 MatrixXs Gx; //!< Jacobian of the inequality constraint
300 MatrixXs Gu; //!< Jacobian of the inequality constraint
301 VectorXs h; //!< Equality constraint values
302 MatrixXs Hx; //!< Jacobian of the equality constraint
303 MatrixXs Hu; //!< Jacobian of the equality constraint
304 };
305
306 } // namespace crocoddyl
307
308 /* --- Details -------------------------------------------------------------- */
309 /* --- Details -------------------------------------------------------------- */
310 /* --- Details -------------------------------------------------------------- */
311 #include "crocoddyl/core/constraint-base.hxx"
312
313 #endif // CROCODDYL_CORE_CONSTRAINT_BASE_HPP_
314