Directory: | ./ |
---|---|
File: | include/crocoddyl/multibody/contacts/multiple-contacts.hxx |
Date: | 2025-01-16 08:47:40 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 251 | 283 | 88.7% |
Branches: | 192 | 651 | 29.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 | namespace crocoddyl { | ||
11 | |||
12 | template <typename Scalar> | ||
13 | 766 | ContactModelMultipleTpl<Scalar>::ContactModelMultipleTpl( | |
14 | boost::shared_ptr<StateMultibody> state, const std::size_t nu) | ||
15 | 766 | : state_(state), | |
16 | 766 | nc_(0), | |
17 | 766 | nc_total_(0), | |
18 | 766 | nu_(nu), | |
19 | 766 | compute_all_contacts_(false) {} | |
20 | |||
21 | template <typename Scalar> | ||
22 | 18 | ContactModelMultipleTpl<Scalar>::ContactModelMultipleTpl( | |
23 | boost::shared_ptr<StateMultibody> state) | ||
24 | 18 | : state_(state), | |
25 | 18 | nc_(0), | |
26 | 18 | nc_total_(0), | |
27 | 18 | nu_(state->get_nv()), | |
28 | 36 | compute_all_contacts_(false) {} | |
29 | |||
30 | template <typename Scalar> | ||
31 | 786 | ContactModelMultipleTpl<Scalar>::~ContactModelMultipleTpl() {} | |
32 | |||
33 | template <typename Scalar> | ||
34 | 1717 | void ContactModelMultipleTpl<Scalar>::addContact( | |
35 | const std::string& name, boost::shared_ptr<ContactModelAbstract> contact, | ||
36 | const bool active) { | ||
37 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1717 times.
|
1717 | if (contact->get_nu() != nu_) { |
38 | ✗ | throw_pretty("Invalid argument: " | |
39 | << name | ||
40 | << " contact item doesn't have the same control dimension (" + | ||
41 | std::to_string(nu_) + ")"); | ||
42 | } | ||
43 | std::pair<typename ContactModelContainer::iterator, bool> ret = | ||
44 |
3/6✓ Branch 1 taken 1717 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1717 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1717 times.
✗ Branch 8 not taken.
|
1717 | contacts_.insert(std::make_pair( |
45 | name, boost::make_shared<ContactItem>(name, contact, active))); | ||
46 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1716 times.
|
1717 | if (ret.second == false) { |
47 | std::cerr << "Warning: we couldn't add the " << name | ||
48 |
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 | << " contact item, it already existed." << std::endl; |
49 |
2/2✓ Branch 0 taken 1715 times.
✓ Branch 1 taken 1 times.
|
1716 | } else if (active) { |
50 | 1715 | nc_ += contact->get_nc(); | |
51 | 1715 | nc_total_ += contact->get_nc(); | |
52 |
1/2✓ Branch 1 taken 1715 times.
✗ Branch 2 not taken.
|
1715 | active_set_.insert(name); |
53 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | } else if (!active) { |
54 | 1 | nc_total_ += contact->get_nc(); | |
55 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | inactive_set_.insert(name); |
56 | } | ||
57 | 1717 | } | |
58 | |||
59 | template <typename Scalar> | ||
60 | 2 | void ContactModelMultipleTpl<Scalar>::removeContact(const std::string& name) { | |
61 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | typename ContactModelContainer::iterator it = contacts_.find(name); |
62 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
|
2 | if (it != contacts_.end()) { |
63 | 1 | nc_ -= it->second->contact->get_nc(); | |
64 | 1 | nc_total_ -= it->second->contact->get_nc(); | |
65 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | contacts_.erase(it); |
66 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | active_set_.erase(name); |
67 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | inactive_set_.erase(name); |
68 | } else { | ||
69 | std::cerr << "Warning: we couldn't remove the " << name | ||
70 |
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 | << " contact item, it doesn't exist." << std::endl; |
71 | } | ||
72 | 2 | } | |
73 | |||
74 | template <typename Scalar> | ||
75 | 17 | void ContactModelMultipleTpl<Scalar>::changeContactStatus( | |
76 | const std::string& name, const bool active) { | ||
77 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | typename ContactModelContainer::iterator it = contacts_.find(name); |
78 |
2/2✓ Branch 2 taken 16 times.
✓ Branch 3 taken 1 times.
|
17 | if (it != contacts_.end()) { |
79 |
5/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 15 times.
|
16 | if (active && !it->second->active) { |
80 | 1 | nc_ += it->second->contact->get_nc(); | |
81 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | active_set_.insert(name); |
82 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | inactive_set_.erase(name); |
83 |
3/6✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
|
15 | } else if (!active && it->second->active) { |
84 | 15 | nc_ -= it->second->contact->get_nc(); | |
85 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
15 | inactive_set_.insert(name); |
86 |
1/2✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
|
15 | active_set_.erase(name); |
87 | } | ||
88 | // "else" case: Contact status unchanged - already in desired state | ||
89 | 16 | it->second->active = active; | |
90 | } else { | ||
91 | std::cerr << "Warning: we couldn't change the status of the " << name | ||
92 |
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 | << " contact item, it doesn't exist." << std::endl; |
93 | } | ||
94 | 17 | } | |
95 | |||
96 | template <typename Scalar> | ||
97 | 62660 | void ContactModelMultipleTpl<Scalar>::calc( | |
98 | const boost::shared_ptr<ContactDataMultiple>& data, | ||
99 | const Eigen::Ref<const VectorXs>& x) { | ||
100 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 62660 times.
|
62660 | if (data->contacts.size() != contacts_.size()) { |
101 | ✗ | throw_pretty("Invalid argument: " | |
102 | << "it doesn't match the number of contact datas and models"); | ||
103 | } | ||
104 | |||
105 | 62660 | std::size_t nc = 0; | |
106 | 62660 | const std::size_t nv = state_->get_nv(); | |
107 | 62660 | typename ContactModelContainer::iterator it_m, end_m; | |
108 | 62660 | typename ContactDataContainer::iterator it_d, end_d; | |
109 |
2/2✓ Branch 0 taken 25930 times.
✓ Branch 1 taken 36730 times.
|
62660 | if (compute_all_contacts_) { |
110 | 51860 | for (it_m = contacts_.begin(), end_m = contacts_.end(), | |
111 | 25930 | it_d = data->contacts.begin(), end_d = data->contacts.end(); | |
112 |
5/6✓ Branch 2 taken 25930 times.
✓ Branch 3 taken 63370 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 25930 times.
✓ Branch 7 taken 63370 times.
✓ Branch 8 taken 25930 times.
|
89300 | it_m != end_m || it_d != end_d; ++it_m, ++it_d) { |
113 | 63370 | const boost::shared_ptr<ContactItem>& m_i = it_m->second; | |
114 | 63370 | const std::size_t nc_i = m_i->contact->get_nc(); | |
115 |
2/2✓ Branch 1 taken 63366 times.
✓ Branch 2 taken 4 times.
|
63370 | if (m_i->active) { |
116 | 63366 | const boost::shared_ptr<ContactDataAbstract>& d_i = it_d->second; | |
117 |
1/18✗ Branch 3 not taken.
✓ Branch 4 taken 63366 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.
|
63366 | assert_pretty( |
118 | it_m->first == it_d->first, | ||
119 | "it doesn't match the contact name between model and data (" | ||
120 | << it_m->first << " != " << it_d->first << ")"); | ||
121 |
1/2✓ Branch 3 taken 63366 times.
✗ Branch 4 not taken.
|
63366 | m_i->contact->calc(d_i, x); |
122 |
2/4✓ Branch 3 taken 63366 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 63366 times.
✗ Branch 7 not taken.
|
63366 | data->a0.segment(nc, nc_i) = d_i->a0; |
123 |
2/4✓ Branch 3 taken 63366 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 63366 times.
✗ Branch 7 not taken.
|
63366 | data->Jc.block(nc, 0, nc_i, nv) = d_i->Jc; |
124 | } else { | ||
125 |
2/4✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
4 | data->a0.segment(nc, nc_i).setZero(); |
126 |
2/4✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
4 | data->Jc.block(nc, 0, nc_i, nv).setZero(); |
127 | } | ||
128 | 63370 | nc += nc_i; | |
129 | } | ||
130 | } else { | ||
131 | 73460 | for (it_m = contacts_.begin(), end_m = contacts_.end(), | |
132 | 36730 | it_d = data->contacts.begin(), end_d = data->contacts.end(); | |
133 |
5/6✓ Branch 3 taken 36730 times.
✓ Branch 4 taken 79602 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 36730 times.
✓ Branch 8 taken 79602 times.
✓ Branch 9 taken 36730 times.
|
116332 | it_m != end_m || it_d != end_d; ++it_m, ++it_d) { |
134 | 79602 | const boost::shared_ptr<ContactItem>& m_i = it_m->second; | |
135 |
2/2✓ Branch 1 taken 79586 times.
✓ Branch 2 taken 16 times.
|
79602 | if (m_i->active) { |
136 | 79586 | const boost::shared_ptr<ContactDataAbstract>& d_i = it_d->second; | |
137 |
1/18✗ Branch 3 not taken.
✓ Branch 4 taken 79586 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.
|
79586 | assert_pretty( |
138 | it_m->first == it_d->first, | ||
139 | "it doesn't match the contact name between model and data (" | ||
140 | << it_m->first << " != " << it_d->first << ")"); | ||
141 | |||
142 |
1/2✓ Branch 3 taken 79586 times.
✗ Branch 4 not taken.
|
79586 | m_i->contact->calc(d_i, x); |
143 | 79586 | const std::size_t nc_i = m_i->contact->get_nc(); | |
144 |
2/4✓ Branch 3 taken 79586 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 79586 times.
✗ Branch 7 not taken.
|
79586 | data->a0.segment(nc, nc_i) = d_i->a0; |
145 |
2/4✓ Branch 3 taken 79586 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 79586 times.
✗ Branch 7 not taken.
|
79586 | data->Jc.block(nc, 0, nc_i, nv) = d_i->Jc; |
146 | 79586 | nc += nc_i; | |
147 | } | ||
148 | } | ||
149 | } | ||
150 | 62660 | } | |
151 | |||
152 | template <typename Scalar> | ||
153 | 8845 | void ContactModelMultipleTpl<Scalar>::calcDiff( | |
154 | const boost::shared_ptr<ContactDataMultiple>& data, | ||
155 | const Eigen::Ref<const VectorXs>& x) { | ||
156 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 8845 times.
|
8845 | if (data->contacts.size() != contacts_.size()) { |
157 | ✗ | throw_pretty("Invalid argument: " | |
158 | << "it doesn't match the number of contact datas and models"); | ||
159 | } | ||
160 | |||
161 | 8845 | std::size_t nc = 0; | |
162 | 8845 | const std::size_t ndx = state_->get_ndx(); | |
163 | 8845 | typename ContactModelContainer::iterator it_m, end_m; | |
164 | 8845 | typename ContactDataContainer::iterator it_d, end_d; | |
165 |
2/2✓ Branch 0 taken 3762 times.
✓ Branch 1 taken 5083 times.
|
8845 | if (compute_all_contacts_) { |
166 | 7524 | for (it_m = contacts_.begin(), end_m = contacts_.end(), | |
167 | 3762 | it_d = data->contacts.begin(), end_d = data->contacts.end(); | |
168 |
5/6✓ Branch 2 taken 3762 times.
✓ Branch 3 taken 8778 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3762 times.
✓ Branch 7 taken 8778 times.
✓ Branch 8 taken 3762 times.
|
12540 | it_m != end_m || it_d != end_d; ++it_m, ++it_d) { |
169 | 8778 | const boost::shared_ptr<ContactItem>& m_i = it_m->second; | |
170 | 8778 | const std::size_t nc_i = m_i->contact->get_nc(); | |
171 |
1/2✓ Branch 1 taken 8778 times.
✗ Branch 2 not taken.
|
8778 | if (m_i->active) { |
172 |
1/18✗ Branch 3 not taken.
✓ Branch 4 taken 8778 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.
|
8778 | assert_pretty( |
173 | it_m->first == it_d->first, | ||
174 | "it doesn't match the contact name between model and data (" | ||
175 | << it_m->first << " != " << it_d->first << ")"); | ||
176 | 8778 | const boost::shared_ptr<ContactDataAbstract>& d_i = it_d->second; | |
177 | |||
178 |
1/2✓ Branch 3 taken 8778 times.
✗ Branch 4 not taken.
|
8778 | m_i->contact->calcDiff(d_i, x); |
179 |
2/4✓ Branch 3 taken 8778 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8778 times.
✗ Branch 7 not taken.
|
8778 | data->da0_dx.block(nc, 0, nc_i, ndx) = d_i->da0_dx; |
180 | } else { | ||
181 | ✗ | data->da0_dx.block(nc, 0, nc_i, ndx).setZero(); | |
182 | } | ||
183 | 8778 | nc += nc_i; | |
184 | } | ||
185 | } else { | ||
186 | 10166 | for (it_m = contacts_.begin(), end_m = contacts_.end(), | |
187 | 5083 | it_d = data->contacts.begin(), end_d = data->contacts.end(); | |
188 |
5/6✓ Branch 3 taken 5083 times.
✓ Branch 4 taken 10220 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 5083 times.
✓ Branch 8 taken 10220 times.
✓ Branch 9 taken 5083 times.
|
15303 | it_m != end_m || it_d != end_d; ++it_m, ++it_d) { |
189 | 10220 | const boost::shared_ptr<ContactItem>& m_i = it_m->second; | |
190 |
2/2✓ Branch 1 taken 10216 times.
✓ Branch 2 taken 4 times.
|
10220 | if (m_i->active) { |
191 | 10216 | const boost::shared_ptr<ContactDataAbstract>& d_i = it_d->second; | |
192 |
1/18✗ Branch 3 not taken.
✓ Branch 4 taken 10216 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.
|
10216 | assert_pretty( |
193 | it_m->first == it_d->first, | ||
194 | "it doesn't match the contact name between model and data (" | ||
195 | << it_m->first << " != " << it_d->first << ")"); | ||
196 | |||
197 |
1/2✓ Branch 3 taken 10216 times.
✗ Branch 4 not taken.
|
10216 | m_i->contact->calcDiff(d_i, x); |
198 | 10216 | const std::size_t nc_i = m_i->contact->get_nc(); | |
199 |
2/4✓ Branch 3 taken 10216 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 10216 times.
✗ Branch 7 not taken.
|
10216 | data->da0_dx.block(nc, 0, nc_i, ndx) = d_i->da0_dx; |
200 | 10216 | nc += nc_i; | |
201 | } | ||
202 | } | ||
203 | } | ||
204 | 8845 | } | |
205 | |||
206 | template <typename Scalar> | ||
207 | 32220 | void ContactModelMultipleTpl<Scalar>::updateAcceleration( | |
208 | const boost::shared_ptr<ContactDataMultiple>& data, | ||
209 | const VectorXs& dv) const { | ||
210 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 32220 times.
|
32220 | if (static_cast<std::size_t>(dv.size()) != state_->get_nv()) { |
211 | ✗ | throw_pretty( | |
212 | "Invalid argument: " << "dv has wrong dimension (it should be " + | ||
213 | std::to_string(state_->get_nv()) + ")"); | ||
214 | } | ||
215 | 32220 | data->dv = dv; | |
216 | 32220 | } | |
217 | |||
218 | template <typename Scalar> | ||
219 | 58151 | void ContactModelMultipleTpl<Scalar>::updateForce( | |
220 | const boost::shared_ptr<ContactDataMultiple>& data, const VectorXs& force) { | ||
221 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 58151 times.
|
116302 | if (static_cast<std::size_t>(force.size()) != |
222 |
2/2✓ Branch 0 taken 25930 times.
✓ Branch 1 taken 32221 times.
|
58151 | (compute_all_contacts_ ? nc_total_ : nc_)) { |
223 | ✗ | throw_pretty( | |
224 | "Invalid argument: " | ||
225 | << "force has wrong dimension (it should be " + | ||
226 | std::to_string((compute_all_contacts_ ? nc_total_ : nc_)) + ")"); | ||
227 | } | ||
228 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 58151 times.
|
58151 | if (static_cast<std::size_t>(data->contacts.size()) != contacts_.size()) { |
229 | ✗ | throw_pretty("Invalid argument: " | |
230 | << "it doesn't match the number of contact datas and models"); | ||
231 | } | ||
232 | |||
233 |
2/2✓ Branch 5 taken 1272028 times.
✓ Branch 6 taken 58151 times.
|
1330179 | for (ForceIterator it = data->fext.begin(); it != data->fext.end(); ++it) { |
234 |
2/4✓ Branch 1 taken 1272028 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1272028 times.
✗ Branch 6 not taken.
|
1272028 | *it = pinocchio::ForceTpl<Scalar>::Zero(); |
235 | } | ||
236 | |||
237 | 58151 | std::size_t nc = 0; | |
238 | 58151 | typename ContactModelContainer::iterator it_m, end_m; | |
239 | 58151 | typename ContactDataContainer::iterator it_d, end_d; | |
240 |
2/2✓ Branch 0 taken 25930 times.
✓ Branch 1 taken 32221 times.
|
58151 | if (compute_all_contacts_) { |
241 | 51860 | for (it_m = contacts_.begin(), end_m = contacts_.end(), | |
242 | 25930 | it_d = data->contacts.begin(), end_d = data->contacts.end(); | |
243 |
5/6✓ Branch 2 taken 25930 times.
✓ Branch 3 taken 63370 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 25930 times.
✓ Branch 7 taken 63370 times.
✓ Branch 8 taken 25930 times.
|
89300 | it_m != end_m || it_d != end_d; ++it_m, ++it_d) { |
244 | 63370 | const boost::shared_ptr<ContactItem>& m_i = it_m->second; | |
245 | 63370 | const boost::shared_ptr<ContactDataAbstract>& d_i = it_d->second; | |
246 |
1/10✗ Branch 3 not taken.
✓ Branch 4 taken 63370 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.
|
63370 | assert_pretty(it_m->first == it_d->first, |
247 | "it doesn't match the contact name between data and model"); | ||
248 | 63370 | const std::size_t nc_i = m_i->contact->get_nc(); | |
249 |
2/2✓ Branch 1 taken 63366 times.
✓ Branch 2 taken 4 times.
|
63370 | if (m_i->active) { |
250 | const Eigen::VectorBlock<const VectorXs, Eigen::Dynamic> force_i = | ||
251 |
1/2✓ Branch 1 taken 63366 times.
✗ Branch 2 not taken.
|
63366 | force.segment(nc, nc_i); |
252 |
2/4✓ Branch 3 taken 63366 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 63366 times.
✗ Branch 7 not taken.
|
63366 | m_i->contact->updateForce(d_i, force_i); |
253 | #if PINOCCHIO_VERSION_AT_LEAST(3, 0, 0) | ||
254 | 63366 | const pinocchio::JointIndex joint = | |
255 | 63366 | state_->get_pinocchio()->frames[d_i->frame].parentJoint; | |
256 | #else | ||
257 | const pinocchio::JointIndex joint = | ||
258 | state_->get_pinocchio()->frames[d_i->frame].parent; | ||
259 | #endif | ||
260 |
1/2✓ Branch 4 taken 63366 times.
✗ Branch 5 not taken.
|
63366 | data->fext[joint] = d_i->fext; |
261 | } else { | ||
262 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | m_i->contact->setZeroForce(d_i); |
263 | } | ||
264 | 63370 | nc += nc_i; | |
265 | } | ||
266 | } else { | ||
267 | 64442 | for (it_m = contacts_.begin(), end_m = contacts_.end(), | |
268 | 32221 | it_d = data->contacts.begin(), end_d = data->contacts.end(); | |
269 |
5/6✓ Branch 3 taken 32221 times.
✓ Branch 4 taken 69925 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 32221 times.
✓ Branch 8 taken 69925 times.
✓ Branch 9 taken 32221 times.
|
102146 | it_m != end_m || it_d != end_d; ++it_m, ++it_d) { |
270 | 69925 | const boost::shared_ptr<ContactItem>& m_i = it_m->second; | |
271 | 69925 | const boost::shared_ptr<ContactDataAbstract>& d_i = it_d->second; | |
272 |
1/10✗ Branch 3 not taken.
✓ Branch 4 taken 69925 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.
|
69925 | assert_pretty(it_m->first == it_d->first, |
273 | "it doesn't match the contact name between data and model"); | ||
274 |
2/2✓ Branch 1 taken 69921 times.
✓ Branch 2 taken 4 times.
|
69925 | if (m_i->active) { |
275 | 69921 | const std::size_t nc_i = m_i->contact->get_nc(); | |
276 | const Eigen::VectorBlock<const VectorXs, Eigen::Dynamic> force_i = | ||
277 |
1/2✓ Branch 1 taken 69921 times.
✗ Branch 2 not taken.
|
69921 | force.segment(nc, nc_i); |
278 |
2/4✓ Branch 3 taken 69921 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 69921 times.
✗ Branch 7 not taken.
|
69921 | m_i->contact->updateForce(d_i, force_i); |
279 | #if PINOCCHIO_VERSION_AT_LEAST(3, 0, 0) | ||
280 | 69921 | const pinocchio::JointIndex joint = | |
281 | 69921 | state_->get_pinocchio()->frames[d_i->frame].parentJoint; | |
282 | #else | ||
283 | const pinocchio::JointIndex joint = | ||
284 | state_->get_pinocchio()->frames[d_i->frame].parent; | ||
285 | #endif | ||
286 |
1/2✓ Branch 4 taken 69921 times.
✗ Branch 5 not taken.
|
69921 | data->fext[joint] = d_i->fext; |
287 | 69921 | nc += nc_i; | |
288 | } else { | ||
289 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | m_i->contact->setZeroForce(d_i); |
290 | } | ||
291 | } | ||
292 | } | ||
293 | 58151 | } | |
294 | |||
295 | template <typename Scalar> | ||
296 | 5078 | void ContactModelMultipleTpl<Scalar>::updateAccelerationDiff( | |
297 | const boost::shared_ptr<ContactDataMultiple>& data, | ||
298 | const MatrixXs& ddv_dx) const { | ||
299 |
3/6✓ Branch 3 taken 5078 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5078 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5078 times.
|
10156 | if (static_cast<std::size_t>(ddv_dx.rows()) != state_->get_nv() || |
300 | 5078 | static_cast<std::size_t>(ddv_dx.cols()) != state_->get_ndx()) { | |
301 | ✗ | throw_pretty( | |
302 | "Invalid argument: " << "ddv_dx has wrong dimension (it should be " + | ||
303 | std::to_string(state_->get_nv()) + "," + | ||
304 | std::to_string(state_->get_ndx()) + ")"); | ||
305 | } | ||
306 | 5078 | data->ddv_dx = ddv_dx; | |
307 | 5078 | } | |
308 | |||
309 | template <typename Scalar> | ||
310 | 36507 | void ContactModelMultipleTpl<Scalar>::updateForceDiff( | |
311 | const boost::shared_ptr<ContactDataMultiple>& data, const MatrixXs& df_dx, | ||
312 | const MatrixXs& df_du) const { | ||
313 | 36507 | const std::size_t ndx = state_->get_ndx(); | |
314 | 36507 | if (static_cast<std::size_t>(df_dx.rows()) != | |
315 |
4/6✓ Branch 0 taken 31430 times.
✓ Branch 1 taken 5077 times.
✓ Branch 2 taken 36507 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 36507 times.
|
73014 | (compute_all_contacts_ ? nc_total_ : nc_) || |
316 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 36507 times.
|
36507 | static_cast<std::size_t>(df_dx.cols()) != ndx) { |
317 | ✗ | throw_pretty( | |
318 | "Invalid argument: " | ||
319 | << "df_dx has wrong dimension (it should be " + | ||
320 | std::to_string((compute_all_contacts_ ? nc_total_ : nc_)) + "," + | ||
321 | std::to_string(ndx) + ")"); | ||
322 | } | ||
323 | 36507 | if (static_cast<std::size_t>(df_du.rows()) != | |
324 |
4/6✓ Branch 0 taken 31430 times.
✓ Branch 1 taken 5077 times.
✓ Branch 2 taken 36507 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 36507 times.
|
73014 | (compute_all_contacts_ ? nc_total_ : nc_) || |
325 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 36507 times.
|
36507 | static_cast<std::size_t>(df_du.cols()) != nu_) { |
326 | ✗ | throw_pretty( | |
327 | "Invalid argument: " | ||
328 | << "df_du has wrong dimension (it should be " + | ||
329 | std::to_string((compute_all_contacts_ ? nc_total_ : nc_)) + "," + | ||
330 | std::to_string(nu_) + ")"); | ||
331 | } | ||
332 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 36507 times.
|
36507 | if (static_cast<std::size_t>(data->contacts.size()) != contacts_.size()) { |
333 | ✗ | throw_pretty("Invalid argument: " | |
334 | << "it doesn't match the number of contact datas and models"); | ||
335 | } | ||
336 | |||
337 | 36507 | std::size_t nc = 0; | |
338 | 36507 | typename ContactModelContainer::const_iterator it_m, end_m; | |
339 | 36507 | typename ContactDataContainer::const_iterator it_d, end_d; | |
340 |
2/2✓ Branch 0 taken 31430 times.
✓ Branch 1 taken 5077 times.
|
36507 | if (compute_all_contacts_) { |
341 | 31430 | for (it_m = contacts_.begin(), end_m = contacts_.end(), | |
342 | 31430 | it_d = data->contacts.begin(), end_d = data->contacts.end(); | |
343 |
5/6✓ Branch 2 taken 31430 times.
✓ Branch 3 taken 76196 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 31430 times.
✓ Branch 7 taken 76196 times.
✓ Branch 8 taken 31430 times.
|
107626 | it_m != end_m || it_d != end_d; ++it_m, ++it_d) { |
344 | 76196 | const boost::shared_ptr<ContactItem>& m_i = it_m->second; | |
345 | 76196 | const boost::shared_ptr<ContactDataAbstract>& d_i = it_d->second; | |
346 |
1/10✗ Branch 3 not taken.
✓ Branch 4 taken 76196 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.
|
76196 | assert_pretty(it_m->first == it_d->first, |
347 | "it doesn't match the contact name between data and model"); | ||
348 | 76196 | const std::size_t nc_i = m_i->contact->get_nc(); | |
349 |
1/2✓ Branch 1 taken 76196 times.
✗ Branch 2 not taken.
|
76196 | if (m_i->active) { |
350 | const Eigen::Block<const MatrixXs> df_dx_i = | ||
351 |
1/2✓ Branch 1 taken 76196 times.
✗ Branch 2 not taken.
|
76196 | df_dx.block(nc, 0, nc_i, ndx); |
352 | const Eigen::Block<const MatrixXs> df_du_i = | ||
353 |
1/2✓ Branch 1 taken 76196 times.
✗ Branch 2 not taken.
|
76196 | df_du.block(nc, 0, nc_i, nu_); |
354 |
3/6✓ Branch 3 taken 76196 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 76196 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 76196 times.
✗ Branch 10 not taken.
|
76196 | m_i->contact->updateForceDiff(d_i, df_dx_i, df_du_i); |
355 | } else { | ||
356 | ✗ | m_i->contact->setZeroForceDiff(d_i); | |
357 | } | ||
358 | 76196 | nc += nc_i; | |
359 | } | ||
360 | } else { | ||
361 | 5077 | for (it_m = contacts_.begin(), end_m = contacts_.end(), | |
362 | 5077 | it_d = data->contacts.begin(), end_d = data->contacts.end(); | |
363 |
5/6✓ Branch 3 taken 5077 times.
✓ Branch 4 taken 10196 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 5077 times.
✓ Branch 8 taken 10196 times.
✓ Branch 9 taken 5077 times.
|
15273 | it_m != end_m || it_d != end_d; ++it_m, ++it_d) { |
364 | 10196 | const boost::shared_ptr<ContactItem>& m_i = it_m->second; | |
365 | 10196 | const boost::shared_ptr<ContactDataAbstract>& d_i = it_d->second; | |
366 |
1/10✗ Branch 3 not taken.
✓ Branch 4 taken 10196 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.
|
10196 | assert_pretty(it_m->first == it_d->first, |
367 | "it doesn't match the contact name between data and model"); | ||
368 |
1/2✓ Branch 1 taken 10196 times.
✗ Branch 2 not taken.
|
10196 | if (m_i->active) { |
369 | 10196 | const std::size_t nc_i = m_i->contact->get_nc(); | |
370 | const Eigen::Block<const MatrixXs> df_dx_i = | ||
371 |
1/2✓ Branch 1 taken 10196 times.
✗ Branch 2 not taken.
|
10196 | df_dx.block(nc, 0, nc_i, ndx); |
372 | const Eigen::Block<const MatrixXs> df_du_i = | ||
373 |
1/2✓ Branch 1 taken 10196 times.
✗ Branch 2 not taken.
|
10196 | df_du.block(nc, 0, nc_i, nu_); |
374 |
3/6✓ Branch 3 taken 10196 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 10196 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 10196 times.
✗ Branch 10 not taken.
|
10196 | m_i->contact->updateForceDiff(d_i, df_dx_i, df_du_i); |
375 | 10196 | nc += nc_i; | |
376 | } else { | ||
377 | ✗ | m_i->contact->setZeroForceDiff(d_i); | |
378 | } | ||
379 | } | ||
380 | } | ||
381 | 36507 | } | |
382 | |||
383 | template <typename Scalar> | ||
384 | 8839 | void ContactModelMultipleTpl<Scalar>::updateRneaDiff( | |
385 | const boost::shared_ptr<ContactDataMultiple>& data, | ||
386 | pinocchio::DataTpl<Scalar>& pinocchio) const { | ||
387 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 8839 times.
|
17678 | if (static_cast<std::size_t>(data->contacts.size()) != |
388 | 8839 | this->get_contacts().size()) { | |
389 | ✗ | throw_pretty("Invalid argument: " | |
390 | << "it doesn't match the number of contact datas and models"); | ||
391 | } | ||
392 | 8839 | typename ContactModelContainer::const_iterator it_m, end_m; | |
393 | 8839 | typename ContactDataContainer::const_iterator it_d, end_d; | |
394 | 8839 | for (it_m = contacts_.begin(), end_m = contacts_.end(), | |
395 | 8839 | it_d = data->contacts.begin(), end_d = data->contacts.end(); | |
396 |
5/6✓ Branch 3 taken 8839 times.
✓ Branch 4 taken 18974 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8839 times.
✓ Branch 8 taken 18974 times.
✓ Branch 9 taken 8839 times.
|
27813 | it_m != end_m || it_d != end_d; ++it_m, ++it_d) { |
397 | 18974 | const boost::shared_ptr<ContactItem>& m_i = it_m->second; | |
398 | 18974 | const boost::shared_ptr<ContactDataAbstract>& d_i = it_d->second; | |
399 |
1/10✗ Branch 3 not taken.
✓ Branch 4 taken 18974 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.
|
18974 | assert_pretty(it_m->first == it_d->first, |
400 | "it doesn't match the contact name between data and model"); | ||
401 |
1/2✓ Branch 1 taken 18974 times.
✗ Branch 2 not taken.
|
18974 | if (m_i->active) { |
402 |
2/3✓ Branch 3 taken 11384 times.
✓ Branch 4 taken 7590 times.
✗ Branch 5 not taken.
|
18974 | switch (m_i->contact->get_type()) { |
403 | 11384 | case pinocchio::ReferenceFrame::LOCAL: | |
404 | 11384 | break; | |
405 | 7590 | case pinocchio::ReferenceFrame::WORLD: | |
406 | case pinocchio::ReferenceFrame::LOCAL_WORLD_ALIGNED: | ||
407 |
1/2✓ Branch 2 taken 7590 times.
✗ Branch 3 not taken.
|
7590 | pinocchio.dtau_dq += d_i->dtau_dq; |
408 | 7590 | break; | |
409 | } | ||
410 | } | ||
411 | } | ||
412 | 8839 | } | |
413 | |||
414 | template <typename Scalar> | ||
415 | boost::shared_ptr<ContactDataMultipleTpl<Scalar> > | ||
416 | 70999 | ContactModelMultipleTpl<Scalar>::createData( | |
417 | pinocchio::DataTpl<Scalar>* const data) { | ||
418 | return boost::allocate_shared<ContactDataMultiple>( | ||
419 |
1/2✓ Branch 2 taken 70999 times.
✗ Branch 3 not taken.
|
141998 | Eigen::aligned_allocator<ContactDataMultiple>(), this, data); |
420 | } | ||
421 | |||
422 | template <typename Scalar> | ||
423 | const boost::shared_ptr<StateMultibodyTpl<Scalar> >& | ||
424 | 426022 | ContactModelMultipleTpl<Scalar>::get_state() const { | |
425 | 426022 | return state_; | |
426 | } | ||
427 | |||
428 | template <typename Scalar> | ||
429 | const typename ContactModelMultipleTpl<Scalar>::ContactModelContainer& | ||
430 | 459377 | ContactModelMultipleTpl<Scalar>::get_contacts() const { | |
431 | 459377 | return contacts_; | |
432 | } | ||
433 | |||
434 | template <typename Scalar> | ||
435 | 102819 | std::size_t ContactModelMultipleTpl<Scalar>::get_nc() const { | |
436 | 102819 | return nc_; | |
437 | } | ||
438 | |||
439 | template <typename Scalar> | ||
440 | 514944 | std::size_t ContactModelMultipleTpl<Scalar>::get_nc_total() const { | |
441 | 514944 | return nc_total_; | |
442 | } | ||
443 | |||
444 | template <typename Scalar> | ||
445 | 763 | std::size_t ContactModelMultipleTpl<Scalar>::get_nu() const { | |
446 | 763 | return nu_; | |
447 | } | ||
448 | |||
449 | template <typename Scalar> | ||
450 | 29693 | const std::set<std::string>& ContactModelMultipleTpl<Scalar>::get_active_set() | |
451 | const { | ||
452 | 29693 | return active_set_; | |
453 | } | ||
454 | |||
455 | template <typename Scalar> | ||
456 | 29693 | const std::set<std::string>& ContactModelMultipleTpl<Scalar>::get_inactive_set() | |
457 | const { | ||
458 | 29693 | return inactive_set_; | |
459 | } | ||
460 | |||
461 | template <typename Scalar> | ||
462 | ✗ | bool ContactModelMultipleTpl<Scalar>::getContactStatus( | |
463 | const std::string& name) const { | ||
464 | ✗ | typename ContactModelContainer::const_iterator it = contacts_.find(name); | |
465 | ✗ | if (it != contacts_.end()) { | |
466 | ✗ | return it->second->active; | |
467 | } else { | ||
468 | std::cerr << "Warning: we couldn't get the status of the " << name | ||
469 | ✗ | << " contact item, it doesn't exist." << std::endl; | |
470 | ✗ | return false; | |
471 | } | ||
472 | } | ||
473 | |||
474 | template <typename Scalar> | ||
475 | ✗ | bool ContactModelMultipleTpl<Scalar>::getComputeAllContacts() const { | |
476 | ✗ | return compute_all_contacts_; | |
477 | } | ||
478 | |||
479 | template <typename Scalar> | ||
480 | 4161 | void ContactModelMultipleTpl<Scalar>::setComputeAllContacts(const bool status) { | |
481 | 4161 | compute_all_contacts_ = status; | |
482 | 4161 | } | |
483 | |||
484 | template <class Scalar> | ||
485 | 1 | std::ostream& operator<<(std::ostream& os, | |
486 | const ContactModelMultipleTpl<Scalar>& model) { | ||
487 | 1 | const auto& active = model.get_active_set(); | |
488 | 1 | const auto& inactive = model.get_inactive_set(); | |
489 | 1 | os << "ContactModelMultiple:" << std::endl; | |
490 | 1 | os << " Active:" << std::endl; | |
491 | 1 | for (std::set<std::string>::const_iterator it = active.begin(); | |
492 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
|
1 | it != active.end(); ++it) { |
493 | const boost::shared_ptr< | ||
494 | ✗ | typename ContactModelMultipleTpl<Scalar>::ContactItem>& contact_item = | |
495 | ✗ | model.get_contacts().find(*it)->second; | |
496 | ✗ | if (it != --active.end()) { | |
497 | ✗ | os << " " << *it << ": " << *contact_item << std::endl; | |
498 | } else { | ||
499 | ✗ | os << " " << *it << ": " << *contact_item << std::endl; | |
500 | } | ||
501 | } | ||
502 | 1 | os << " Inactive:" << std::endl; | |
503 | 1 | for (std::set<std::string>::const_iterator it = inactive.begin(); | |
504 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
|
1 | it != inactive.end(); ++it) { |
505 | const boost::shared_ptr< | ||
506 | ✗ | typename ContactModelMultipleTpl<Scalar>::ContactItem>& contact_item = | |
507 | ✗ | model.get_contacts().find(*it)->second; | |
508 | ✗ | if (it != --inactive.end()) { | |
509 | ✗ | os << " " << *it << ": " << *contact_item << std::endl; | |
510 | } else { | ||
511 | ✗ | os << " " << *it << ": " << *contact_item; | |
512 | } | ||
513 | } | ||
514 | 1 | return os; | |
515 | } | ||
516 | |||
517 | } // namespace crocoddyl | ||
518 |