Directory: | ./ |
---|---|
File: | include/crocoddyl/core/numdiff/residual.hxx |
Date: | 2025-03-26 19:23:43 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 61 | 65 | 93.8% |
Branches: | 37 | 64 | 57.8% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /////////////////////////////////////////////////////////////////////////////// | ||
2 | // BSD 3-Clause License | ||
3 | // | ||
4 | // Copyright (C) 2021-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/residual.hpp" | ||
10 | |||
11 | namespace crocoddyl { | ||
12 | |||
13 | template <typename Scalar> | ||
14 | 648 | ResidualModelNumDiffTpl<Scalar>::ResidualModelNumDiffTpl( | |
15 | const std::shared_ptr<Base>& model) | ||
16 | : Base(model->get_state(), model->get_nr(), model->get_nu()), | ||
17 | 648 | model_(model), | |
18 |
1/2✓ Branch 8 taken 324 times.
✗ Branch 9 not taken.
|
648 | e_jac_(sqrt(Scalar(2.0) * std::numeric_limits<Scalar>::epsilon())) {} |
19 | |||
20 | template <typename Scalar> | ||
21 | 648 | void ResidualModelNumDiffTpl<Scalar>::calc( | |
22 | const std::shared_ptr<ResidualDataAbstract>& data, | ||
23 | const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) { | ||
24 | 648 | Data* d = static_cast<Data*>(data.get()); | |
25 | 648 | model_->calc(d->data_0, x, u); | |
26 | 648 | d->r = d->data_0->r; | |
27 | } | ||
28 | |||
29 | template <typename Scalar> | ||
30 | 324 | void ResidualModelNumDiffTpl<Scalar>::calc( | |
31 | const std::shared_ptr<ResidualDataAbstract>& data, | ||
32 | const Eigen::Ref<const VectorXs>& x) { | ||
33 | 324 | Data* d = static_cast<Data*>(data.get()); | |
34 | 324 | model_->calc(d->data_0, x); | |
35 | 324 | d->r = d->data_0->r; | |
36 | } | ||
37 | |||
38 | template <typename Scalar> | ||
39 | 324 | void ResidualModelNumDiffTpl<Scalar>::calcDiff( | |
40 | const std::shared_ptr<ResidualDataAbstract>& data, | ||
41 | const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) { | ||
42 | 324 | Data* d = static_cast<Data*>(data.get()); | |
43 | |||
44 | 324 | const VectorXs& r0 = d->r; | |
45 | 324 | d->dx.setZero(); | |
46 | 324 | d->du.setZero(); | |
47 | |||
48 | 324 | assertStableStateFD(x); | |
49 | |||
50 | // Computing the d residual(x,u) / dx | ||
51 |
4/8✓ Branch 6 taken 162 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 162 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 162 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 162 times.
✗ Branch 17 not taken.
|
324 | model_->get_state()->diff(model_->get_state()->zero(), x, d->dx); |
52 | 324 | d->x_norm = d->dx.norm(); | |
53 | 324 | d->dx.setZero(); | |
54 | 324 | d->xh_jac = e_jac_ * std::max(Scalar(1.), d->x_norm); | |
55 |
2/2✓ Branch 2 taken 7092 times.
✓ Branch 3 taken 162 times.
|
14508 | for (std::size_t ix = 0; ix < state_->get_ndx(); ++ix) { |
56 | 14184 | d->dx(ix) = d->xh_jac; | |
57 |
2/4✓ Branch 5 taken 7092 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 7092 times.
✗ Branch 9 not taken.
|
14184 | model_->get_state()->integrate(x, d->dx, d->xp); |
58 | // call the update function | ||
59 |
2/2✓ Branch 1 taken 14184 times.
✓ Branch 2 taken 7092 times.
|
42552 | for (size_t i = 0; i < reevals_.size(); ++i) { |
60 |
1/2✓ Branch 3 taken 14184 times.
✗ Branch 4 not taken.
|
28368 | reevals_[i](d->xp, u); |
61 | } | ||
62 |
1/2✓ Branch 4 taken 7092 times.
✗ Branch 5 not taken.
|
14184 | model_->calc(d->data_x[ix], d->xp, u); |
63 |
3/6✓ Branch 4 taken 7092 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7092 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7092 times.
✗ Branch 11 not taken.
|
14184 | d->Rx.col(ix) = (d->data_x[ix]->r - r0) / d->xh_jac; |
64 | 14184 | d->dx(ix) = Scalar(0.); | |
65 | } | ||
66 | |||
67 | // Computing the d residual(x,u) / du | ||
68 | 324 | d->uh_jac = e_jac_ * std::max(Scalar(1.), u.norm()); | |
69 |
2/2✓ Branch 2 taken 3312 times.
✓ Branch 3 taken 162 times.
|
6948 | for (std::size_t iu = 0; iu < model_->get_nu(); ++iu) { |
70 | 6624 | d->du(iu) = d->uh_jac; | |
71 |
1/2✓ Branch 2 taken 3312 times.
✗ Branch 3 not taken.
|
6624 | d->up = u + d->du; |
72 | // call the update function | ||
73 |
2/2✓ Branch 1 taken 6624 times.
✓ Branch 2 taken 3312 times.
|
19872 | for (std::size_t i = 0; i < reevals_.size(); ++i) { |
74 |
1/2✓ Branch 3 taken 6624 times.
✗ Branch 4 not taken.
|
13248 | reevals_[i](x, d->up); |
75 | } | ||
76 |
1/2✓ Branch 4 taken 3312 times.
✗ Branch 5 not taken.
|
6624 | model_->calc(d->data_u[iu], x, d->up); |
77 |
3/6✓ Branch 4 taken 3312 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3312 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3312 times.
✗ Branch 11 not taken.
|
6624 | d->Ru.col(iu) = (d->data_u[iu]->r - r0) / d->uh_jac; |
78 | 6624 | d->du(iu) = Scalar(0.); | |
79 | } | ||
80 | } | ||
81 | |||
82 | template <typename Scalar> | ||
83 | 324 | void ResidualModelNumDiffTpl<Scalar>::calcDiff( | |
84 | const std::shared_ptr<ResidualDataAbstract>& data, | ||
85 | const Eigen::Ref<const VectorXs>& x) { | ||
86 | 324 | Data* d = static_cast<Data*>(data.get()); | |
87 | |||
88 | 324 | const VectorXs& r0 = d->r; | |
89 | 324 | assertStableStateFD(x); | |
90 | |||
91 | // Computing the d residual(x,u) / dx | ||
92 | 324 | d->dx.setZero(); | |
93 |
2/2✓ Branch 2 taken 7092 times.
✓ Branch 3 taken 162 times.
|
14508 | for (std::size_t ix = 0; ix < state_->get_ndx(); ++ix) { |
94 | 14184 | d->dx(ix) = d->xh_jac; | |
95 |
2/4✓ Branch 5 taken 7092 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 7092 times.
✗ Branch 9 not taken.
|
14184 | model_->get_state()->integrate(x, d->dx, d->xp); |
96 | // call the update function | ||
97 |
2/2✓ Branch 1 taken 14184 times.
✓ Branch 2 taken 7092 times.
|
42552 | for (size_t i = 0; i < reevals_.size(); ++i) { |
98 | 28368 | reevals_[i](d->xp, unone_); | |
99 | } | ||
100 |
1/2✓ Branch 4 taken 7092 times.
✗ Branch 5 not taken.
|
14184 | model_->calc(d->data_x[ix], d->xp); |
101 |
3/6✓ Branch 4 taken 7092 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7092 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 7092 times.
✗ Branch 11 not taken.
|
14184 | d->Rx.col(ix) = (d->data_x[ix]->r - r0) / d->xh_jac; |
102 | 14184 | d->dx(ix) = Scalar(0.); | |
103 | } | ||
104 | } | ||
105 | |||
106 | template <typename Scalar> | ||
107 | std::shared_ptr<ResidualDataAbstractTpl<Scalar> > | ||
108 | 648 | ResidualModelNumDiffTpl<Scalar>::createData(DataCollectorAbstract* const data) { | |
109 | ✗ | return std::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this, | |
110 |
1/2✓ Branch 2 taken 324 times.
✗ Branch 3 not taken.
|
648 | data); |
111 | } | ||
112 | |||
113 | template <typename Scalar> | ||
114 | template <typename NewScalar> | ||
115 | ✗ | ResidualModelNumDiffTpl<NewScalar> ResidualModelNumDiffTpl<Scalar>::cast() | |
116 | const { | ||
117 | typedef ResidualModelNumDiffTpl<NewScalar> ReturnType; | ||
118 | ✗ | ReturnType res(model_->template cast<NewScalar>()); | |
119 | ✗ | return res; | |
120 | } | ||
121 | |||
122 | template <typename Scalar> | ||
123 | const std::shared_ptr<ResidualModelAbstractTpl<Scalar> >& | ||
124 | 43560 | ResidualModelNumDiffTpl<Scalar>::get_model() const { | |
125 | 43560 | return model_; | |
126 | } | ||
127 | |||
128 | template <typename Scalar> | ||
129 | 162 | const Scalar ResidualModelNumDiffTpl<Scalar>::get_disturbance() const { | |
130 | 162 | return e_jac_; | |
131 | } | ||
132 | |||
133 | template <typename Scalar> | ||
134 | void ResidualModelNumDiffTpl<Scalar>::set_disturbance( | ||
135 | const Scalar disturbance) { | ||
136 | if (disturbance < Scalar(0.)) { | ||
137 | throw_pretty("Invalid argument: " << "Disturbance constant is positive"); | ||
138 | } | ||
139 | e_jac_ = disturbance; | ||
140 | } | ||
141 | |||
142 | template <typename Scalar> | ||
143 | 324 | void ResidualModelNumDiffTpl<Scalar>::set_reevals( | |
144 | const std::vector<ReevaluationFunction>& reevals) { | ||
145 | 324 | reevals_ = reevals; | |
146 | 324 | } | |
147 | |||
148 | template <typename Scalar> | ||
149 | 648 | void ResidualModelNumDiffTpl<Scalar>::assertStableStateFD( | |
150 | const Eigen::Ref<const VectorXs>& /*x*/) { | ||
151 | // do nothing in the general case | ||
152 | } | ||
153 | |||
154 | } // namespace crocoddyl | ||
155 |