GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/core/numdiff/cost.hxx
Date: 2025-01-30 11:01:55
Exec Total Coverage
Lines: 97 102 95.1%
Branches: 65 126 51.6%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2023, University of Edinburgh, LAAS-CNRS,
5 // Heriot-Watt University
6 // Copyright note valid unless otherwise stated in individual files.
7 // All rights reserved.
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #include "crocoddyl/core/numdiff/cost.hpp"
11 #include "crocoddyl/core/utils/exception.hpp"
12
13 namespace crocoddyl {
14
15 template <typename Scalar>
16 652 CostModelNumDiffTpl<Scalar>::CostModelNumDiffTpl(
17 const std::shared_ptr<Base>& model)
18 : Base(model->get_state(), model->get_activation(), model->get_nu()),
19 652 model_(model),
20
1/2
✓ Branch 9 taken 652 times.
✗ Branch 10 not taken.
652 e_jac_(std::sqrt(2.0 * std::numeric_limits<Scalar>::epsilon())) {}
21
22 template <typename Scalar>
23 1304 CostModelNumDiffTpl<Scalar>::~CostModelNumDiffTpl() {}
24
25 template <typename Scalar>
26 652 void CostModelNumDiffTpl<Scalar>::calc(
27 const std::shared_ptr<CostDataAbstract>& data,
28 const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) {
29 652 Data* d = static_cast<Data*>(data.get());
30 652 d->data_0->cost = 0.0;
31 652 model_->calc(d->data_0, x, u);
32 652 d->cost = d->data_0->cost;
33 652 d->residual->r = d->data_0->residual->r;
34 652 }
35
36 template <typename Scalar>
37 324 void CostModelNumDiffTpl<Scalar>::calc(
38 const std::shared_ptr<CostDataAbstract>& data,
39 const Eigen::Ref<const VectorXs>& x) {
40 324 Data* d = static_cast<Data*>(data.get());
41 324 d->data_0->cost = 0.0;
42 324 model_->calc(d->data_0, x);
43 324 d->cost = d->data_0->cost;
44 324 d->residual->r = d->data_0->residual->r;
45 324 }
46
47 template <typename Scalar>
48 326 void CostModelNumDiffTpl<Scalar>::calcDiff(
49 const std::shared_ptr<CostDataAbstract>& data,
50 const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) {
51 326 Data* d = static_cast<Data*>(data.get());
52
53 326 const Scalar c0 = d->cost;
54 326 const VectorXs& r0 = d->residual->r;
55
1/2
✓ Branch 1 taken 326 times.
✗ Branch 2 not taken.
326 if (get_with_gauss_approx()) {
56
1/2
✓ Branch 6 taken 326 times.
✗ Branch 7 not taken.
326 model_->get_activation()->calc(d->data_0->activation, r0);
57
1/2
✓ Branch 6 taken 326 times.
✗ Branch 7 not taken.
326 model_->get_activation()->calcDiff(d->data_0->activation, r0);
58 }
59 326 d->du.setZero();
60
61 326 assertStableStateFD(x);
62
63 // Computing the d cost(x,u) / dx
64
3/6
✓ Branch 8 taken 326 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 326 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 326 times.
✗ Branch 15 not taken.
326 model_->get_state()->diff(model_->get_state()->zero(), x, d->dx);
65 326 d->x_norm = d->dx.norm();
66 326 d->dx.setZero();
67 326 d->xh_jac = e_jac_ * std::max(1., d->x_norm);
68
2/2
✓ Branch 2 taken 13078 times.
✓ Branch 3 taken 326 times.
13404 for (std::size_t ix = 0; ix < state_->get_ndx(); ++ix) {
69 13078 d->dx(ix) = d->xh_jac;
70
2/4
✓ Branch 5 taken 13078 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13078 times.
✗ Branch 9 not taken.
13078 model_->get_state()->integrate(x, d->dx, d->xp);
71 // call the update function on the pinocchio data
72
2/2
✓ Branch 1 taken 13204 times.
✓ Branch 2 taken 13078 times.
26282 for (size_t i = 0; i < reevals_.size(); ++i) {
73
1/2
✓ Branch 3 taken 13204 times.
✗ Branch 4 not taken.
13204 reevals_[i](d->xp, u);
74 }
75
1/2
✓ Branch 4 taken 13078 times.
✗ Branch 5 not taken.
13078 model_->calc(d->data_x[ix], d->xp, u);
76 13078 d->Lx(ix) = (d->data_x[ix]->cost - c0) / d->xh_jac;
77
1/2
✓ Branch 1 taken 13078 times.
✗ Branch 2 not taken.
13078 if (get_with_gauss_approx()) {
78
3/6
✓ Branch 5 taken 13078 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 13078 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 13078 times.
✗ Branch 13 not taken.
13078 d->residual->Rx.col(ix) = (d->data_x[ix]->residual->r - r0) / d->xh_jac;
79 }
80 13078 d->dx(ix) = 0.;
81 }
82
83 // Computing the d cost(x,u) / du
84 326 d->uh_jac = e_jac_ * std::max(1., u.norm());
85
2/2
✓ Branch 2 taken 6539 times.
✓ Branch 3 taken 326 times.
6865 for (std::size_t iu = 0; iu < model_->get_nu(); ++iu) {
86 6539 d->du(iu) = d->uh_jac;
87
1/2
✓ Branch 2 taken 6539 times.
✗ Branch 3 not taken.
6539 d->up = u + d->du;
88 // call the update function
89
2/2
✓ Branch 1 taken 6602 times.
✓ Branch 2 taken 6539 times.
13141 for (std::size_t i = 0; i < reevals_.size(); ++i) {
90
1/2
✓ Branch 3 taken 6602 times.
✗ Branch 4 not taken.
6602 reevals_[i](x, d->up);
91 }
92
1/2
✓ Branch 4 taken 6539 times.
✗ Branch 5 not taken.
6539 model_->calc(d->data_u[iu], x, d->up);
93 6539 d->Lu(iu) = (d->data_u[iu]->cost - c0) / d->uh_jac;
94
1/2
✓ Branch 1 taken 6539 times.
✗ Branch 2 not taken.
6539 if (get_with_gauss_approx()) {
95
3/6
✓ Branch 5 taken 6539 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 6539 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 6539 times.
✗ Branch 13 not taken.
6539 d->residual->Ru.col(iu) = (d->data_u[iu]->residual->r - r0) / d->uh_jac;
96 }
97 6539 d->du(iu) = 0.;
98 }
99
100
1/2
✓ Branch 1 taken 326 times.
✗ Branch 2 not taken.
326 if (get_with_gauss_approx()) {
101
1/2
✓ Branch 3 taken 326 times.
✗ Branch 4 not taken.
326 const MatrixXs& Arr = d->data_0->activation->Arr;
102
4/8
✓ Branch 3 taken 326 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 326 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 326 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 326 times.
✗ Branch 13 not taken.
326 d->Lxx = d->residual->Rx.transpose() * Arr * d->residual->Rx;
103
4/8
✓ Branch 3 taken 326 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 326 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 326 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 326 times.
✗ Branch 13 not taken.
326 d->Lxu = d->residual->Rx.transpose() * Arr * d->residual->Ru;
104
4/8
✓ Branch 3 taken 326 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 326 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 326 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 326 times.
✗ Branch 13 not taken.
326 d->Luu = d->residual->Ru.transpose() * Arr * d->residual->Ru;
105 326 } else {
106 d->Lxx.fill(0.0);
107 d->Lxu.fill(0.0);
108 d->Luu.fill(0.0);
109 }
110 326 }
111
112 template <typename Scalar>
113 324 void CostModelNumDiffTpl<Scalar>::calcDiff(
114 const std::shared_ptr<CostDataAbstract>& data,
115 const Eigen::Ref<const VectorXs>& x) {
116 324 Data* d = static_cast<Data*>(data.get());
117
118 324 const Scalar c0 = d->cost;
119 324 const VectorXs& r0 = d->residual->r;
120
1/2
✓ Branch 1 taken 324 times.
✗ Branch 2 not taken.
324 if (get_with_gauss_approx()) {
121
1/2
✓ Branch 6 taken 324 times.
✗ Branch 7 not taken.
324 model_->get_activation()->calc(d->data_0->activation, r0);
122
1/2
✓ Branch 6 taken 324 times.
✗ Branch 7 not taken.
324 model_->get_activation()->calcDiff(d->data_0->activation, r0);
123 }
124 324 d->dx.setZero();
125
126 324 assertStableStateFD(x);
127
128 // Computing the d cost(x,u) / dx
129 324 d->xh_jac = e_jac_ * std::max(1., x.norm());
130
2/2
✓ Branch 2 taken 12978 times.
✓ Branch 3 taken 324 times.
13302 for (std::size_t ix = 0; ix < state_->get_ndx(); ++ix) {
131 12978 d->dx(ix) = d->xh_jac;
132
2/4
✓ Branch 5 taken 12978 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 12978 times.
✗ Branch 9 not taken.
12978 model_->get_state()->integrate(x, d->dx, d->xp);
133 // call the update function on the pinocchio data
134
2/2
✓ Branch 1 taken 13104 times.
✓ Branch 2 taken 12978 times.
26082 for (size_t i = 0; i < reevals_.size(); ++i) {
135 13104 reevals_[i](d->xp, unone_);
136 }
137
1/2
✓ Branch 4 taken 12978 times.
✗ Branch 5 not taken.
12978 model_->calc(d->data_x[ix], d->xp);
138 12978 d->Lx(ix) = (d->data_x[ix]->cost - c0) / d->xh_jac;
139
1/2
✓ Branch 1 taken 12978 times.
✗ Branch 2 not taken.
12978 if (get_with_gauss_approx()) {
140
3/6
✓ Branch 5 taken 12978 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 12978 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 12978 times.
✗ Branch 13 not taken.
12978 d->residual->Rx.col(ix) = (d->data_x[ix]->residual->r - r0) / d->xh_jac;
141 }
142 12978 d->dx(ix) = 0.;
143 }
144
145
1/2
✓ Branch 1 taken 324 times.
✗ Branch 2 not taken.
324 if (get_with_gauss_approx()) {
146
1/2
✓ Branch 3 taken 324 times.
✗ Branch 4 not taken.
324 const MatrixXs& Arr = d->data_0->activation->Arr;
147
4/8
✓ Branch 3 taken 324 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 324 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 324 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 324 times.
✗ Branch 13 not taken.
324 d->Lxx = d->residual->Rx.transpose() * Arr * d->residual->Rx;
148 324 } else {
149 d->Lxx.fill(0.0);
150 }
151 324 }
152
153 template <typename Scalar>
154 std::shared_ptr<CostDataAbstractTpl<Scalar> >
155 652 CostModelNumDiffTpl<Scalar>::createData(DataCollectorAbstract* const data) {
156 return std::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this,
157
1/2
✓ Branch 2 taken 652 times.
✗ Branch 3 not taken.
652 data);
158 }
159
160 template <typename Scalar>
161 const std::shared_ptr<CostModelAbstractTpl<Scalar> >&
162 41190 CostModelNumDiffTpl<Scalar>::get_model() const {
163 41190 return model_;
164 }
165
166 template <typename Scalar>
167 326 const Scalar CostModelNumDiffTpl<Scalar>::get_disturbance() const {
168 326 return e_jac_;
169 }
170
171 template <typename Scalar>
172 void CostModelNumDiffTpl<Scalar>::set_disturbance(const Scalar disturbance) {
173 if (disturbance < 0.) {
174 throw_pretty("Invalid argument: " << "Disturbance constant is positive");
175 }
176 e_jac_ = disturbance;
177 }
178
179 template <typename Scalar>
180 34545 bool CostModelNumDiffTpl<Scalar>::get_with_gauss_approx() {
181 34545 return activation_->get_nr() > 0;
182 }
183
184 template <typename Scalar>
185 326 void CostModelNumDiffTpl<Scalar>::set_reevals(
186 const std::vector<ReevaluationFunction>& reevals) {
187 326 reevals_ = reevals;
188 326 }
189
190 template <typename Scalar>
191 650 void CostModelNumDiffTpl<Scalar>::assertStableStateFD(
192 const Eigen::Ref<const VectorXs>& /*x*/) {
193 // do nothing in the general case
194 650 }
195
196 } // namespace crocoddyl
197