GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/core/numdiff/constraint.hxx
Date: 2025-03-26 19:23:43
Exec Total Coverage
Lines: 91 101 90.1%
Branches: 56 206 27.2%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2020-2025, University of Edinburgh, Heriot-Watt University
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #include "crocoddyl/core/numdiff/constraint.hpp"
10
11 namespace crocoddyl {
12
13 template <typename Scalar>
14 280 ConstraintModelNumDiffTpl<Scalar>::ConstraintModelNumDiffTpl(
15 const std::shared_ptr<Base>& model)
16 : Base(model->get_state(), model->get_nu(), model->get_ng(),
17 model->get_nh()),
18 280 model_(model),
19
1/2
✓ Branch 10 taken 140 times.
✗ Branch 11 not taken.
280 e_jac_(sqrt(Scalar(2.0) * std::numeric_limits<Scalar>::epsilon())) {}
20
21 template <typename Scalar>
22 280 void ConstraintModelNumDiffTpl<Scalar>::calc(
23 const std::shared_ptr<ConstraintDataAbstract>& data,
24 const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) {
25
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 140 times.
280 if (static_cast<std::size_t>(x.size()) != state_->get_nx()) {
26 throw_pretty(
27 "Invalid argument: " << "x has wrong dimension (it should be " +
28 std::to_string(state_->get_nx()) + ")");
29 }
30
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 140 times.
280 if (static_cast<std::size_t>(u.size()) != nu_) {
31 throw_pretty(
32 "Invalid argument: " << "u has wrong dimension (it should be " +
33 std::to_string(nu_) + ")");
34 }
35
36 280 Data* d = static_cast<Data*>(data.get());
37 280 d->data_0->g.setZero();
38 280 d->data_0->h.setZero();
39 280 model_->calc(d->data_0, x, u);
40 280 d->g = d->data_0->g;
41 280 d->h = d->data_0->h;
42 }
43
44 template <typename Scalar>
45 140 void ConstraintModelNumDiffTpl<Scalar>::calc(
46 const std::shared_ptr<ConstraintDataAbstract>& data,
47 const Eigen::Ref<const VectorXs>& x) {
48
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 70 times.
140 if (static_cast<std::size_t>(x.size()) != state_->get_nx()) {
49 throw_pretty(
50 "Invalid argument: " << "x has wrong dimension (it should be " +
51 std::to_string(state_->get_nx()) + ")");
52 }
53 140 Data* d = static_cast<Data*>(data.get());
54
55 140 d->data_0->g.setZero();
56 140 d->data_0->h.setZero();
57 140 model_->calc(d->data_0, x);
58 140 d->g = d->data_0->g;
59 140 d->h = d->data_0->h;
60 }
61
62 template <typename Scalar>
63 140 void ConstraintModelNumDiffTpl<Scalar>::calcDiff(
64 const std::shared_ptr<ConstraintDataAbstract>& data,
65 const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) {
66
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 70 times.
140 if (static_cast<std::size_t>(x.size()) != state_->get_nx()) {
67 throw_pretty(
68 "Invalid argument: " << "x has wrong dimension (it should be " +
69 std::to_string(state_->get_nx()) + ")");
70 }
71
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 70 times.
140 if (static_cast<std::size_t>(u.size()) != nu_) {
72 throw_pretty(
73 "Invalid argument: " << "u has wrong dimension (it should be " +
74 std::to_string(nu_) + ")");
75 }
76 140 Data* d = static_cast<Data*>(data.get());
77
78 140 const VectorXs& g0 = d->g;
79 140 const VectorXs& h0 = d->h;
80 140 const std::size_t ndx = model_->get_state()->get_ndx();
81 140 const std::size_t nu = model_->get_nu();
82 140 const std::size_t ng = model_->get_ng();
83 140 const std::size_t nh = model_->get_nh();
84 140 d->Gx.resize(ng, ndx);
85 140 d->Gu.resize(ng, nu);
86 140 d->Hx.resize(nh, ndx);
87 140 d->Hu.resize(nh, nu);
88 140 d->du.setZero();
89
90 140 assertStableStateFD(x);
91
92 // Computing the d constraint(x,u) / dx
93
4/8
✓ Branch 6 taken 70 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 70 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 70 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 70 times.
✗ Branch 17 not taken.
140 model_->get_state()->diff(model_->get_state()->zero(), x, d->dx);
94 140 d->x_norm = d->dx.norm();
95 140 d->dx.setZero();
96 140 d->xh_jac = e_jac_ * std::max(Scalar(1.), d->x_norm);
97
2/2
✓ Branch 2 taken 2856 times.
✓ Branch 3 taken 70 times.
5852 for (std::size_t ix = 0; ix < state_->get_ndx(); ++ix) {
98 5712 d->dx(ix) = d->xh_jac;
99
2/4
✓ Branch 5 taken 2856 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2856 times.
✗ Branch 9 not taken.
5712 model_->get_state()->integrate(x, d->dx, d->xp);
100 // call the update function
101
2/2
✓ Branch 1 taken 2856 times.
✓ Branch 2 taken 2856 times.
11424 for (size_t i = 0; i < reevals_.size(); ++i) {
102
1/2
✓ Branch 3 taken 2856 times.
✗ Branch 4 not taken.
5712 reevals_[i](d->xp, u);
103 }
104
1/2
✓ Branch 4 taken 2856 times.
✗ Branch 5 not taken.
5712 model_->calc(d->data_x[ix], d->xp, u);
105
3/6
✓ Branch 4 taken 2856 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2856 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2856 times.
✗ Branch 11 not taken.
5712 d->Gx.col(ix) = (d->data_x[ix]->g - g0) / d->xh_jac;
106
3/6
✓ Branch 4 taken 2856 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2856 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2856 times.
✗ Branch 11 not taken.
5712 d->Hx.col(ix) = (d->data_x[ix]->h - h0) / d->xh_jac;
107 5712 d->dx(ix) = Scalar(0.);
108 }
109
110 // Computing the d constraint(x,u) / du
111 140 d->uh_jac = e_jac_ * std::max(Scalar(1.), u.norm());
112
2/2
✓ Branch 2 taken 1428 times.
✓ Branch 3 taken 70 times.
2996 for (std::size_t iu = 0; iu < model_->get_nu(); ++iu) {
113 2856 d->du(iu) = d->uh_jac;
114
1/2
✓ Branch 2 taken 1428 times.
✗ Branch 3 not taken.
2856 d->up = u + d->du;
115 // call the update function
116
2/2
✓ Branch 1 taken 1428 times.
✓ Branch 2 taken 1428 times.
5712 for (std::size_t i = 0; i < reevals_.size(); ++i) {
117
1/2
✓ Branch 3 taken 1428 times.
✗ Branch 4 not taken.
2856 reevals_[i](x, d->up);
118 }
119
1/2
✓ Branch 4 taken 1428 times.
✗ Branch 5 not taken.
2856 model_->calc(d->data_u[iu], x, d->up);
120
3/6
✓ Branch 4 taken 1428 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1428 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1428 times.
✗ Branch 11 not taken.
2856 d->Gu.col(iu) = (d->data_u[iu]->g - g0) / d->uh_jac;
121
3/6
✓ Branch 4 taken 1428 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1428 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1428 times.
✗ Branch 11 not taken.
2856 d->Hu.col(iu) = (d->data_u[iu]->h - h0) / d->uh_jac;
122 2856 d->du(iu) = Scalar(0.);
123 }
124 }
125
126 template <typename Scalar>
127 140 void ConstraintModelNumDiffTpl<Scalar>::calcDiff(
128 const std::shared_ptr<ConstraintDataAbstract>& data,
129 const Eigen::Ref<const VectorXs>& x) {
130
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 70 times.
140 if (static_cast<std::size_t>(x.size()) != state_->get_nx()) {
131 throw_pretty(
132 "Invalid argument: " << "x has wrong dimension (it should be " +
133 std::to_string(state_->get_nx()) + ")");
134 }
135 140 Data* d = static_cast<Data*>(data.get());
136
137 140 const VectorXs& g0 = d->g;
138 140 const VectorXs& h0 = d->h;
139 140 const std::size_t ndx = model_->get_state()->get_ndx();
140 140 d->Gx.resize(model_->get_ng(), ndx);
141 140 d->Hx.resize(model_->get_nh(), ndx);
142
143 140 assertStableStateFD(x);
144
145 // Computing the d constraint(x) / dx
146
4/8
✓ Branch 6 taken 70 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 70 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 70 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 70 times.
✗ Branch 17 not taken.
140 model_->get_state()->diff(model_->get_state()->zero(), x, d->dx);
147 140 d->x_norm = d->dx.norm();
148 140 d->dx.setZero();
149 140 d->xh_jac = e_jac_ * std::max(Scalar(1.), d->x_norm);
150
2/2
✓ Branch 2 taken 2856 times.
✓ Branch 3 taken 70 times.
5852 for (std::size_t ix = 0; ix < state_->get_ndx(); ++ix) {
151 // x + dx
152 5712 d->dx(ix) = d->xh_jac;
153
2/4
✓ Branch 5 taken 2856 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2856 times.
✗ Branch 9 not taken.
5712 model_->get_state()->integrate(x, d->dx, d->xp);
154 // call the update function
155
2/2
✓ Branch 1 taken 2856 times.
✓ Branch 2 taken 2856 times.
11424 for (size_t i = 0; i < reevals_.size(); ++i) {
156 5712 reevals_[i](d->xp, unone_);
157 }
158
1/2
✓ Branch 4 taken 2856 times.
✗ Branch 5 not taken.
5712 model_->calc(d->data_x[ix], d->xp);
159
3/6
✓ Branch 4 taken 2856 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2856 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2856 times.
✗ Branch 11 not taken.
5712 d->Gx.col(ix) = (d->data_x[ix]->g - g0) / d->xh_jac;
160
3/6
✓ Branch 4 taken 2856 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2856 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2856 times.
✗ Branch 11 not taken.
5712 d->Hx.col(ix) = (d->data_x[ix]->h - h0) / d->xh_jac;
161 5712 d->dx(ix) = Scalar(0.);
162 }
163 }
164
165 template <typename Scalar>
166 std::shared_ptr<ConstraintDataAbstractTpl<Scalar> >
167 280 ConstraintModelNumDiffTpl<Scalar>::createData(
168 DataCollectorAbstract* const data) {
169 return std::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this,
170
1/2
✓ Branch 2 taken 140 times.
✗ Branch 3 not taken.
280 data);
171 }
172
173 template <typename Scalar>
174 template <typename NewScalar>
175 ConstraintModelNumDiffTpl<NewScalar> ConstraintModelNumDiffTpl<Scalar>::cast()
176 const {
177 typedef ConstraintModelNumDiffTpl<NewScalar> ReturnType;
178 ReturnType res(model_->template cast<NewScalar>());
179 return res;
180 }
181
182 template <typename Scalar>
183 const std::shared_ptr<ConstraintModelAbstractTpl<Scalar> >&
184 17976 ConstraintModelNumDiffTpl<Scalar>::get_model() const {
185 17976 return model_;
186 }
187
188 template <typename Scalar>
189 70 const Scalar ConstraintModelNumDiffTpl<Scalar>::get_disturbance() const {
190 70 return e_jac_;
191 }
192
193 template <typename Scalar>
194 void ConstraintModelNumDiffTpl<Scalar>::set_disturbance(
195 const Scalar disturbance) {
196 if (disturbance < Scalar(0.)) {
197 throw_pretty("Invalid argument: " << "Disturbance constant is positive");
198 }
199 e_jac_ = disturbance;
200 }
201
202 template <typename Scalar>
203 70 void ConstraintModelNumDiffTpl<Scalar>::set_reevals(
204 const std::vector<ReevaluationFunction>& reevals) {
205 70 reevals_ = reevals;
206 70 }
207
208 template <typename Scalar>
209 280 void ConstraintModelNumDiffTpl<Scalar>::assertStableStateFD(
210 const Eigen::Ref<const VectorXs>& /*x*/) {
211 // do nothing in the general case
212 }
213
214 } // namespace crocoddyl
215