GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/multibody/impulses/multiple-impulses.hxx
Date: 2025-01-16 08:47:40
Exec Total Coverage
Lines: 171 198 86.4%
Branches: 116 437 26.5%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2024, 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 #include "crocoddyl/core/utils/exception.hpp"
11 #include "crocoddyl/multibody/impulses/multiple-impulses.hpp"
12
13 namespace crocoddyl {
14
15 template <typename Scalar>
16 101 ImpulseModelMultipleTpl<Scalar>::ImpulseModelMultipleTpl(
17 boost::shared_ptr<StateMultibody> state)
18 101 : state_(state), nc_(0), nc_total_(0) {}
19
20 template <typename Scalar>
21 103 ImpulseModelMultipleTpl<Scalar>::~ImpulseModelMultipleTpl() {}
22
23 template <typename Scalar>
24 266 void ImpulseModelMultipleTpl<Scalar>::addImpulse(
25 const std::string& name, boost::shared_ptr<ImpulseModelAbstract> impulse,
26 const bool active) {
27 std::pair<typename ImpulseModelContainer::iterator, bool> ret =
28
3/6
✓ Branch 1 taken 266 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 266 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 266 times.
✗ Branch 8 not taken.
266 impulses_.insert(std::make_pair(
29 name, boost::make_shared<ImpulseItem>(name, impulse, active)));
30
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 265 times.
266 if (ret.second == false) {
31 std::cerr << "Warning: we couldn't add the " << name
32
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
1 << " impulse item, it already existed." << std::endl;
33
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 1 times.
265 } else if (active) {
34 264 nc_ += impulse->get_nc();
35 264 nc_total_ += impulse->get_nc();
36
1/2
✓ Branch 1 taken 264 times.
✗ Branch 2 not taken.
264 active_set_.insert(name);
37
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 } else if (!active) {
38 1 nc_total_ += impulse->get_nc();
39
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 inactive_set_.insert(name);
40 }
41 266 }
42
43 template <typename Scalar>
44 2 void ImpulseModelMultipleTpl<Scalar>::removeImpulse(const std::string& name) {
45
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 typename ImpulseModelContainer::iterator it = impulses_.find(name);
46
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 if (it != impulses_.end()) {
47 1 nc_ -= it->second->impulse->get_nc();
48 1 nc_total_ -= it->second->impulse->get_nc();
49
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 impulses_.erase(it);
50
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 active_set_.erase(name);
51
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 inactive_set_.erase(name);
52 } else {
53 std::cerr << "Warning: we couldn't remove the " << name
54
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
1 << " impulse item, it doesn't exist." << std::endl;
55 }
56 2 }
57
58 template <typename Scalar>
59 9 void ImpulseModelMultipleTpl<Scalar>::changeImpulseStatus(
60 const std::string& name, const bool active) {
61
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 typename ImpulseModelContainer::iterator it = impulses_.find(name);
62
2/2
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 1 times.
9 if (it != impulses_.end()) {
63
5/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 7 times.
8 if (active && !it->second->active) {
64 1 nc_ += it->second->impulse->get_nc();
65
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 active_set_.insert(name);
66
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 inactive_set_.erase(name);
67
3/6
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
7 } else if (!active && it->second->active) {
68 7 nc_ -= it->second->impulse->get_nc();
69
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 inactive_set_.insert(name);
70
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 active_set_.erase(name);
71 }
72 8 it->second->active = active;
73 } else {
74 std::cerr << "Warning: we couldn't change the status of the " << name
75
4/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
1 << " impulse item, it doesn't exist." << std::endl;
76 }
77 9 }
78
79 template <typename Scalar>
80 6988 void ImpulseModelMultipleTpl<Scalar>::calc(
81 const boost::shared_ptr<ImpulseDataMultiple>& data,
82 const Eigen::Ref<const VectorXs>& x) {
83
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 6988 times.
6988 if (data->impulses.size() != impulses_.size()) {
84 throw_pretty("Invalid argument: "
85 << "it doesn't match the number of impulse datas and models");
86 }
87
88 6988 std::size_t nc = 0;
89 6988 const std::size_t nv = state_->get_nv();
90 6988 typename ImpulseModelContainer::iterator it_m, end_m;
91 6988 typename ImpulseDataContainer::iterator it_d, end_d;
92 13976 for (it_m = impulses_.begin(), end_m = impulses_.end(),
93 6988 it_d = data->impulses.begin(), end_d = data->impulses.end();
94
5/6
✓ Branch 3 taken 6988 times.
✓ Branch 4 taken 16476 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6988 times.
✓ Branch 8 taken 16476 times.
✓ Branch 9 taken 6988 times.
23464 it_m != end_m || it_d != end_d; ++it_m, ++it_d) {
95 16476 const boost::shared_ptr<ImpulseItem>& m_i = it_m->second;
96
2/2
✓ Branch 1 taken 16472 times.
✓ Branch 2 taken 4 times.
16476 if (m_i->active) {
97 16472 const boost::shared_ptr<ImpulseDataAbstract>& d_i = it_d->second;
98
1/18
✗ Branch 3 not taken.
✓ Branch 4 taken 16472 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
16472 assert_pretty(it_m->first == it_d->first,
99 "it doesn't match the impulse name between model and data ("
100 << it_m->first << " != " << it_d->first << ")");
101
102
1/2
✓ Branch 3 taken 16472 times.
✗ Branch 4 not taken.
16472 m_i->impulse->calc(d_i, x);
103 16472 const std::size_t nc_i = m_i->impulse->get_nc();
104
2/4
✓ Branch 3 taken 16472 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 16472 times.
✗ Branch 7 not taken.
16472 data->Jc.block(nc, 0, nc_i, nv) = d_i->Jc;
105 16472 nc += nc_i;
106 }
107 }
108 6988 }
109
110 template <typename Scalar>
111 254 void ImpulseModelMultipleTpl<Scalar>::calcDiff(
112 const boost::shared_ptr<ImpulseDataMultiple>& data,
113 const Eigen::Ref<const VectorXs>& x) {
114
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 254 times.
254 if (data->impulses.size() != impulses_.size()) {
115 throw_pretty("Invalid argument: "
116 << "it doesn't match the number of impulse datas and models");
117 }
118
119 254 std::size_t nc = 0;
120 254 const std::size_t nv = state_->get_nv();
121 254 typename ImpulseModelContainer::iterator it_m, end_m;
122 254 typename ImpulseDataContainer::iterator it_d, end_d;
123 508 for (it_m = impulses_.begin(), end_m = impulses_.end(),
124 254 it_d = data->impulses.begin(), end_d = data->impulses.end();
125
5/6
✓ Branch 3 taken 254 times.
✓ Branch 4 taken 724 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 254 times.
✓ Branch 8 taken 724 times.
✓ Branch 9 taken 254 times.
978 it_m != end_m || it_d != end_d; ++it_m, ++it_d) {
126 724 const boost::shared_ptr<ImpulseItem>& m_i = it_m->second;
127
2/2
✓ Branch 1 taken 720 times.
✓ Branch 2 taken 4 times.
724 if (m_i->active) {
128 720 const boost::shared_ptr<ImpulseDataAbstract>& d_i = it_d->second;
129
1/18
✗ Branch 3 not taken.
✓ Branch 4 taken 720 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
720 assert_pretty(it_m->first == it_d->first,
130 "it doesn't match the impulse name between model and data ("
131 << it_m->first << " != " << it_d->first << ")");
132
133
1/2
✓ Branch 3 taken 720 times.
✗ Branch 4 not taken.
720 m_i->impulse->calcDiff(d_i, x);
134 720 const std::size_t nc_i = m_i->impulse->get_nc();
135
2/4
✓ Branch 3 taken 720 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 720 times.
✗ Branch 7 not taken.
720 data->dv0_dq.block(nc, 0, nc_i, nv) = d_i->dv0_dq;
136 720 nc += nc_i;
137 }
138 }
139 254 }
140
141 template <typename Scalar>
142 6980 void ImpulseModelMultipleTpl<Scalar>::updateVelocity(
143 const boost::shared_ptr<ImpulseDataMultiple>& data,
144 const VectorXs& vnext) const {
145
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 6980 times.
6980 if (static_cast<std::size_t>(vnext.size()) != state_->get_nv()) {
146 throw_pretty(
147 "Invalid argument: " << "vnext has wrong dimension (it should be " +
148 std::to_string(state_->get_nv()) + ")");
149 }
150 6980 data->vnext = vnext;
151 6980 }
152
153 template <typename Scalar>
154 6981 void ImpulseModelMultipleTpl<Scalar>::updateForce(
155 const boost::shared_ptr<ImpulseDataMultiple>& data, const VectorXs& force) {
156
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6981 times.
6981 if (static_cast<std::size_t>(force.size()) != nc_) {
157 throw_pretty(
158 "Invalid argument: " << "force has wrong dimension (it should be " +
159 std::to_string(nc_) + ")");
160 }
161
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 6981 times.
6981 if (static_cast<std::size_t>(data->impulses.size()) != impulses_.size()) {
162 throw_pretty("Invalid argument: "
163 << "it doesn't match the number of impulse datas and models");
164 }
165
166
2/2
✓ Branch 5 taken 210488 times.
✓ Branch 6 taken 6981 times.
217469 for (ForceIterator it = data->fext.begin(); it != data->fext.end(); ++it) {
167
2/4
✓ Branch 1 taken 210488 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 210488 times.
✗ Branch 6 not taken.
210488 *it = pinocchio::ForceTpl<Scalar>::Zero();
168 }
169
170 6981 std::size_t nc = 0;
171 6981 typename ImpulseModelContainer::iterator it_m, end_m;
172 6981 typename ImpulseDataContainer::iterator it_d, end_d;
173 13962 for (it_m = impulses_.begin(), end_m = impulses_.end(),
174 6981 it_d = data->impulses.begin(), end_d = data->impulses.end();
175
5/6
✓ Branch 3 taken 6981 times.
✓ Branch 4 taken 16453 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6981 times.
✓ Branch 8 taken 16453 times.
✓ Branch 9 taken 6981 times.
23434 it_m != end_m || it_d != end_d; ++it_m, ++it_d) {
176 16453 const boost::shared_ptr<ImpulseItem>& m_i = it_m->second;
177 16453 const boost::shared_ptr<ImpulseDataAbstract>& d_i = it_d->second;
178
1/10
✗ Branch 3 not taken.
✓ Branch 4 taken 16453 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
16453 assert_pretty(it_m->first == it_d->first,
179 "it doesn't match the impulse name between data and model");
180
1/2
✓ Branch 1 taken 16453 times.
✗ Branch 2 not taken.
16453 if (m_i->active) {
181 16453 const std::size_t nc_i = m_i->impulse->get_nc();
182 const Eigen::VectorBlock<const VectorXs, Eigen::Dynamic> force_i =
183
1/2
✓ Branch 1 taken 16453 times.
✗ Branch 2 not taken.
16453 force.segment(nc, nc_i);
184
2/4
✓ Branch 3 taken 16453 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 16453 times.
✗ Branch 7 not taken.
16453 m_i->impulse->updateForce(d_i, force_i);
185 #if PINOCCHIO_VERSION_AT_LEAST(3, 0, 0)
186 16453 const pinocchio::JointIndex joint =
187 16453 state_->get_pinocchio()->frames[d_i->frame].parentJoint;
188 #else
189 const pinocchio::JointIndex joint =
190 state_->get_pinocchio()->frames[d_i->frame].parent;
191 #endif
192
1/2
✓ Branch 4 taken 16453 times.
✗ Branch 5 not taken.
16453 data->fext[joint] = d_i->fext;
193 16453 nc += nc_i;
194 } else {
195 m_i->impulse->setZeroForce(d_i);
196 }
197 }
198 6981 }
199
200 template <typename Scalar>
201 249 void ImpulseModelMultipleTpl<Scalar>::updateVelocityDiff(
202 const boost::shared_ptr<ImpulseDataMultiple>& data,
203 const MatrixXs& dvnext_dx) const {
204
3/6
✓ Branch 3 taken 249 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 249 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 249 times.
498 if (static_cast<std::size_t>(dvnext_dx.rows()) != state_->get_nv() ||
205 249 static_cast<std::size_t>(dvnext_dx.cols()) != state_->get_ndx()) {
206 throw_pretty(
207 "Invalid argument: " << "dvnext_dx has wrong dimension (it should be " +
208 std::to_string(state_->get_nv()) + "," +
209 std::to_string(state_->get_ndx()) + ")");
210 }
211 249 data->dvnext_dx = dvnext_dx;
212 249 }
213
214 template <typename Scalar>
215 248 void ImpulseModelMultipleTpl<Scalar>::updateForceDiff(
216 const boost::shared_ptr<ImpulseDataMultiple>& data,
217 const MatrixXs& df_dx) const {
218 248 const std::size_t ndx = state_->get_ndx();
219
2/4
✓ Branch 1 taken 248 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 248 times.
496 if (static_cast<std::size_t>(df_dx.rows()) != nc_ ||
220
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 248 times.
248 static_cast<std::size_t>(df_dx.cols()) != ndx) {
221 throw_pretty("Invalid argument: "
222 << "df_dx has wrong dimension (it should be " +
223 std::to_string(nc_) + "," + std::to_string(ndx) + ")");
224 }
225
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 248 times.
248 if (static_cast<std::size_t>(data->impulses.size()) != impulses_.size()) {
226 throw_pretty("Invalid argument: "
227 << "it doesn't match the number of impulse datas and models");
228 }
229
230 248 std::size_t nc = 0;
231 248 typename ImpulseModelContainer::const_iterator it_m, end_m;
232 248 typename ImpulseDataContainer::const_iterator it_d, end_d;
233 248 for (it_m = impulses_.begin(), end_m = impulses_.end(),
234 248 it_d = data->impulses.begin(), end_d = data->impulses.end();
235
5/6
✓ Branch 3 taken 248 times.
✓ Branch 4 taken 700 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 248 times.
✓ Branch 8 taken 700 times.
✓ Branch 9 taken 248 times.
948 it_m != end_m || it_d != end_d; ++it_m, ++it_d) {
236 700 const boost::shared_ptr<ImpulseItem>& m_i = it_m->second;
237 700 const boost::shared_ptr<ImpulseDataAbstract>& d_i = it_d->second;
238
1/10
✗ Branch 3 not taken.
✓ Branch 4 taken 700 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
700 assert_pretty(it_m->first == it_d->first,
239 "it doesn't match the impulse name between data and model");
240
1/2
✓ Branch 1 taken 700 times.
✗ Branch 2 not taken.
700 if (m_i->active) {
241 700 const std::size_t nc_i = m_i->impulse->get_nc();
242 const Eigen::Block<const MatrixXs> df_dx_i =
243
1/2
✓ Branch 1 taken 700 times.
✗ Branch 2 not taken.
700 df_dx.block(nc, 0, nc_i, ndx);
244
2/4
✓ Branch 3 taken 700 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 700 times.
✗ Branch 7 not taken.
700 m_i->impulse->updateForceDiff(d_i, df_dx_i);
245 700 nc += nc_i;
246 } else {
247 m_i->impulse->setZeroForceDiff(d_i);
248 }
249 }
250 248 }
251
252 template <typename Scalar>
253 248 void ImpulseModelMultipleTpl<Scalar>::updateRneaDiff(
254 const boost::shared_ptr<ImpulseDataMultiple>& data,
255 pinocchio::DataTpl<Scalar>& pinocchio) const {
256
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 248 times.
496 if (static_cast<std::size_t>(data->impulses.size()) !=
257 248 this->get_impulses().size()) {
258 throw_pretty("Invalid argument: "
259 << "it doesn't match the number of impulse datas and models");
260 }
261 248 typename ImpulseModelContainer::const_iterator it_m, end_m;
262 248 typename ImpulseDataContainer::const_iterator it_d, end_d;
263 248 for (it_m = impulses_.begin(), end_m = impulses_.end(),
264 248 it_d = data->impulses.begin(), end_d = data->impulses.end();
265
5/6
✓ Branch 3 taken 248 times.
✓ Branch 4 taken 700 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 248 times.
✓ Branch 8 taken 700 times.
✓ Branch 9 taken 248 times.
948 it_m != end_m || it_d != end_d; ++it_m, ++it_d) {
266 700 const boost::shared_ptr<ImpulseItem>& m_i = it_m->second;
267 700 const boost::shared_ptr<ImpulseDataAbstract>& d_i = it_d->second;
268
1/10
✗ Branch 3 not taken.
✓ Branch 4 taken 700 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
700 assert_pretty(it_m->first == it_d->first,
269 "it doesn't match the impulse name between data and model");
270
1/2
✓ Branch 1 taken 700 times.
✗ Branch 2 not taken.
700 if (m_i->active) {
271
2/3
✓ Branch 3 taken 364 times.
✓ Branch 4 taken 336 times.
✗ Branch 5 not taken.
700 switch (m_i->impulse->get_type()) {
272 364 case pinocchio::ReferenceFrame::LOCAL:
273 364 break;
274 336 case pinocchio::ReferenceFrame::WORLD:
275 case pinocchio::ReferenceFrame::LOCAL_WORLD_ALIGNED:
276
1/2
✓ Branch 2 taken 336 times.
✗ Branch 3 not taken.
336 pinocchio.dtau_dq += d_i->dtau_dq;
277 336 break;
278 }
279 }
280 }
281 248 }
282
283 template <typename Scalar>
284 boost::shared_ptr<ImpulseDataMultipleTpl<Scalar> >
285 4270 ImpulseModelMultipleTpl<Scalar>::createData(
286 pinocchio::DataTpl<Scalar>* const data) {
287 return boost::allocate_shared<ImpulseDataMultiple>(
288
1/2
✓ Branch 2 taken 4270 times.
✗ Branch 3 not taken.
8540 Eigen::aligned_allocator<ImpulseDataMultiple>(), this, data);
289 }
290
291 template <typename Scalar>
292 const boost::shared_ptr<StateMultibodyTpl<Scalar> >&
293 25643 ImpulseModelMultipleTpl<Scalar>::get_state() const {
294 25643 return state_;
295 }
296
297 template <typename Scalar>
298 const typename ImpulseModelMultipleTpl<Scalar>::ImpulseModelContainer&
299 19023 ImpulseModelMultipleTpl<Scalar>::get_impulses() const {
300 19023 return impulses_;
301 }
302
303 template <typename Scalar>
304 7282 std::size_t ImpulseModelMultipleTpl<Scalar>::get_nc() const {
305 7282 return nc_;
306 }
307
308 template <typename Scalar>
309 21312 std::size_t ImpulseModelMultipleTpl<Scalar>::get_nc_total() const {
310 21312 return nc_total_;
311 }
312
313 template <typename Scalar>
314 1 const std::set<std::string>& ImpulseModelMultipleTpl<Scalar>::get_active_set()
315 const {
316 1 return active_set_;
317 }
318
319 template <typename Scalar>
320 1 const std::set<std::string>& ImpulseModelMultipleTpl<Scalar>::get_inactive_set()
321 const {
322 1 return inactive_set_;
323 }
324
325 template <typename Scalar>
326 bool ImpulseModelMultipleTpl<Scalar>::getImpulseStatus(
327 const std::string& name) const {
328 typename ImpulseModelContainer::const_iterator it = impulses_.find(name);
329 if (it != impulses_.end()) {
330 return it->second->active;
331 } else {
332 std::cerr << "Warning: we couldn't get the status of the " << name
333 << " impulse item, it doesn't exist." << std::endl;
334 return false;
335 }
336 }
337
338 template <class Scalar>
339 1 std::ostream& operator<<(std::ostream& os,
340 const ImpulseModelMultipleTpl<Scalar>& model) {
341 1 const auto& active = model.get_active_set();
342 1 const auto& inactive = model.get_inactive_set();
343 1 os << "ImpulseModelMultiple:" << std::endl;
344 1 os << " Active:" << std::endl;
345 1 for (std::set<std::string>::const_iterator it = active.begin();
346
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 it != active.end(); ++it) {
347 const boost::shared_ptr<
348 typename ImpulseModelMultipleTpl<Scalar>::ImpulseItem>& impulse_item =
349 model.get_impulses().find(*it)->second;
350 if (it != --active.end()) {
351 os << " " << *it << ": " << *impulse_item << std::endl;
352 } else {
353 os << " " << *it << ": " << *impulse_item << std::endl;
354 }
355 }
356 1 os << " Inactive:" << std::endl;
357 1 for (std::set<std::string>::const_iterator it = inactive.begin();
358
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1 it != inactive.end(); ++it) {
359 const boost::shared_ptr<
360 typename ImpulseModelMultipleTpl<Scalar>::ImpulseItem>& impulse_item =
361 model.get_impulses().find(*it)->second;
362 if (it != --inactive.end()) {
363 os << " " << *it << ": " << *impulse_item << std::endl;
364 } else {
365 os << " " << *it << ": " << *impulse_item;
366 }
367 }
368 1 return os;
369 }
370
371 } // namespace crocoddyl
372