GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/multibody/residuals/contact-control-gravity.hpp
Date: 2025-03-26 19:23:43
Exec Total Coverage
Lines: 12 14 85.7%
Branches: 9 28 32.1%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2020-2025, LAAS-CNRS, University of Edinburgh,
5 // Heriot-Watt University
6 // Copyright note valid unless otherwise stated in individual files.
7 // All rights reserved.
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #ifndef CROCODDYL_MULTIBODY_RESIDUALS_CONTACT_CONTROL_GRAVITY_HPP_
11 #define CROCODDYL_MULTIBODY_RESIDUALS_CONTACT_CONTROL_GRAVITY_HPP_
12
13 #include "crocoddyl/core/residual-base.hpp"
14 #include "crocoddyl/multibody/data/contacts.hpp"
15 #include "crocoddyl/multibody/states/multibody.hpp"
16
17 namespace crocoddyl {
18
19 /**
20 * @brief Control gravity residual under contact
21 *
22 * This residual function is defined as
23 * \f$\mathbf{r}=\mathbf{u}-(\mathbf{g}(\mathbf{q}) - \sum
24 * \mathbf{J}_c(\mathbf{q})^{\top} \mathbf{f}_c)\f$, where
25 * \f$\mathbf{u}\in~\mathbb{R}^{nu}\f$ is the current control input,
26 * \f$\mathbf{J}_c(\mathbf{q})\f$ is the contact Jacobians, \f$\mathbf{f}_c\f$
27 * contains the contact forces, \f$\mathbf{g}(\mathbf{q})\f$ is the gravity
28 * torque corresponding to the current configuration,
29 * \f$\mathbf{q}\in~\mathbb{R}^{nq}\f$ is the current position joints input.
30 * Note that the dimension of the residual vector is obtained from
31 * `state->get_nv()`.
32 *
33 * As described in `ResidualModelAbstractTpl()`, the residual value and its
34 * Jacobians are calculated by `calc()` and `calcDiff()`, respectively.
35 *
36 * \sa `ResidualModelAbstractTpl`, `calc()`, `calcDiff()`, `createData()`
37 */
38 template <typename _Scalar>
39 class ResidualModelContactControlGravTpl
40 : public ResidualModelAbstractTpl<_Scalar> {
41 public:
42 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
43 CROCODDYL_DERIVED_CAST(ResidualModelBase, ResidualModelContactControlGravTpl)
44
45 typedef _Scalar Scalar;
46 typedef MathBaseTpl<Scalar> MathBase;
47 typedef ResidualModelAbstractTpl<Scalar> Base;
48 typedef ResidualDataContactControlGravTpl<Scalar> Data;
49 typedef ResidualDataAbstractTpl<Scalar> ResidualDataAbstract;
50 typedef StateMultibodyTpl<Scalar> StateMultibody;
51 typedef ActuationModelAbstractTpl<Scalar> ActuationModelAbstract;
52 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
53 typedef typename MathBase::VectorXs VectorXs;
54 typedef typename MathBase::MatrixXs MatrixXs;
55
56 /**
57 * @brief Initialize the contact control gravity contact residual model
58 *
59 * @param[in] state State of the multibody system
60 * @param[in] nu Dimension of the control vector
61 */
62 ResidualModelContactControlGravTpl(std::shared_ptr<StateMultibody> state,
63 const std::size_t nu);
64
65 /**
66 * @brief Initialize the contact control gravity contact residual model
67 *
68 * The default `nu` value is obtained from `StateAbstractTpl::get_nv()`.
69 *
70 * @param[in] state State of the multibody system
71 */
72 explicit ResidualModelContactControlGravTpl(
73 std::shared_ptr<StateMultibody> state);
74 84 virtual ~ResidualModelContactControlGravTpl() = default;
75
76 /**
77 * @brief Compute the contact control gravity contact residual
78 *
79 * @param[in] data Contact control gravity residual data
80 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
81 * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
82 */
83 virtual void calc(const std::shared_ptr<ResidualDataAbstract>& data,
84 const Eigen::Ref<const VectorXs>& x,
85 const Eigen::Ref<const VectorXs>& u) override;
86
87 /**
88 * @brief Compute the residual vector for nodes that depends only on the state
89 *
90 * It updates the residual vector based on the state only (i.e., it ignores
91 * the contact forces). This function is used in the terminal nodes of an
92 * optimal control problem.
93 *
94 * @param[in] data Residual data
95 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
96 */
97 virtual void calc(const std::shared_ptr<ResidualDataAbstract>& data,
98 const Eigen::Ref<const VectorXs>& x) override;
99
100 /**
101 * @brief Compute the Jacobians of the contact control gravity contact
102 * residual
103 *
104 * @param[in] data Contact control gravity residual data
105 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
106 * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
107 */
108 virtual void calcDiff(const std::shared_ptr<ResidualDataAbstract>& data,
109 const Eigen::Ref<const VectorXs>& x,
110 const Eigen::Ref<const VectorXs>& u) override;
111
112 /**
113 * @brief Compute the Jacobian of the residual functions with respect to the
114 * state only
115 *
116 * It updates the Jacobian of the residual function based on the state only
117 * (i.e., it ignores the contact forces). This function is used in the
118 * terminal nodes of an optimal control problem.
119 *
120 * @param[in] data Residual data
121 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
122 */
123 virtual void calcDiff(const std::shared_ptr<ResidualDataAbstract>& data,
124 const Eigen::Ref<const VectorXs>& x) override;
125
126 /**
127 * @brief Create the contact-control-gravity residual data
128 */
129 virtual std::shared_ptr<ResidualDataAbstract> createData(
130 DataCollectorAbstract* const data) override;
131
132 /**
133 * @brief Cast the contact-control-gravity residual model to a different
134 * scalar type.
135 *
136 * It is useful for operations requiring different precision or scalar types.
137 *
138 * @tparam NewScalar The new scalar type to cast to.
139 * @return ResidualModelContactControlGravTpl<NewScalar> A residual model with
140 * the new scalar type.
141 */
142 template <typename NewScalar>
143 ResidualModelContactControlGravTpl<NewScalar> cast() const;
144
145 /**
146 * @brief Print relevant information of the contact-control-grav residual
147 *
148 * @param[out] os Output stream object
149 */
150 virtual void print(std::ostream& os) const override;
151
152 protected:
153 using Base::nu_;
154 using Base::state_;
155 using Base::v_dependent_;
156
157 private:
158 typename StateMultibody::PinocchioModel pin_model_;
159 };
160
161 template <typename _Scalar>
162 struct ResidualDataContactControlGravTpl
163 : public ResidualDataAbstractTpl<_Scalar> {
164 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
165
166 typedef _Scalar Scalar;
167 typedef MathBaseTpl<Scalar> MathBase;
168 typedef ResidualDataAbstractTpl<Scalar> Base;
169 typedef StateMultibodyTpl<Scalar> StateMultibody;
170 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
171 typedef pinocchio::DataTpl<Scalar> PinocchioData;
172
173 template <template <typename Scalar> class Model>
174 2776 ResidualDataContactControlGravTpl(Model<Scalar>* const model,
175 DataCollectorAbstract* const data)
176
2/4
✓ Branch 2 taken 2774 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2774 times.
✗ Branch 7 not taken.
2776 : Base(model, data) {
177
1/2
✓ Branch 1 taken 2774 times.
✗ Branch 2 not taken.
2776 StateMultibody* sm = static_cast<StateMultibody*>(model->get_state().get());
178
3/6
✓ Branch 1 taken 2774 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2774 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2774 times.
✗ Branch 9 not taken.
2776 pinocchio = PinocchioData(*(sm->get_pinocchio().get()));
179
180 // Check that proper shared data has been passed
181 2776 DataCollectorActMultibodyInContactTpl<Scalar>* d =
182
1/2
✓ Branch 0 taken 2774 times.
✗ Branch 1 not taken.
2776 dynamic_cast<DataCollectorActMultibodyInContactTpl<Scalar>*>(shared);
183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2774 times.
2776 if (d == NULL) {
184 throw_pretty(
185 "Invalid argument: the shared data should be derived from "
186 "DataCollectorActMultibodyInContactTpl");
187 }
188 // Avoids data casting at runtime
189 // pinocchio = d->pinocchio;
190
1/2
✓ Branch 2 taken 2774 times.
✗ Branch 3 not taken.
2776 fext = d->contacts->fext;
191 2776 actuation = d->actuation;
192 2776 }
193 5548 virtual ~ResidualDataContactControlGravTpl() = default;
194
195 PinocchioData pinocchio; //!< Pinocchio data
196 std::shared_ptr<ActuationDataAbstractTpl<Scalar> >
197 actuation; //!< Actuation data
198 pinocchio::container::aligned_vector<pinocchio::ForceTpl<Scalar> >
199 fext; //!< External spatial forces
200 using Base::r;
201 using Base::Ru;
202 using Base::Rx;
203 using Base::shared;
204 };
205
206 } // namespace crocoddyl
207
208 /* --- Details -------------------------------------------------------------- */
209 /* --- Details -------------------------------------------------------------- */
210 /* --- Details -------------------------------------------------------------- */
211 #include "crocoddyl/multibody/residuals/contact-control-gravity.hxx"
212
213 CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS(
214 crocoddyl::ResidualModelContactControlGravTpl)
215 CROCODDYL_DECLARE_EXTERN_TEMPLATE_STRUCT(
216 crocoddyl::ResidualDataContactControlGravTpl)
217
218 #endif // CROCODDYL_MULTIBODY_RESIDUALS_CONTACT_CONTROL_GRAVITY_HPP_
219