GCC Code Coverage Report


Directory: ./
File: src/device.cc
Date: 2025-05-04 12:09:19
Exec Total Coverage
Lines: 202 305 66.2%
Branches: 171 530 32.3%

Line Branch Exec Source
1 //
2 // Copyright (c) 2016 CNRS
3 // Author: NMansard
4 //
5 //
6
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met:
10 //
11 // 1. Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //
14 // 2. Redistributions in binary form must reproduce the above copyright
15 // notice, this list of conditions and the following disclaimer in the
16 // documentation and/or other materials provided with the distribution.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30
31 #include <pinocchio/fwd.hpp>
32
33 // include pinocchio first
34
35 #include <coal/BV/AABB.h>
36 #include <coal/BVH/BVH_model.h>
37
38 #include <Eigen/Core>
39 #include <boost/foreach.hpp>
40 #include <boost/serialization/export.hpp>
41 #include <hpp/pinocchio/device.hh>
42 #include <hpp/pinocchio/fwd.hh>
43 #include <hpp/pinocchio/joint-collection.hh>
44 #include <hpp/util/serialization.hh>
45 #include <pinocchio/algorithm/geometry.hpp>
46 #include <pinocchio/algorithm/joint-configuration.hpp> // ::pinocchio::details::Dispatch
47 #include <pinocchio/algorithm/model.hpp>
48 #include <pinocchio/multibody/geometry.hpp>
49 #include <pinocchio/multibody/model.hpp>
50 #include <pinocchio/serialization/model.hpp>
51 // #include <hpp/pinocchio/distance-result.hh>
52 #include <hpp/pinocchio/body.hh>
53 #include <hpp/pinocchio/collision-object.hh>
54 #include <hpp/pinocchio/extra-config-space.hh>
55 #include <hpp/pinocchio/gripper.hh>
56 #include <hpp/pinocchio/joint.hh>
57 #include <hpp/pinocchio/liegroup-space.hh>
58 #include <hpp/pinocchio/liegroup.hh>
59 #include <hpp/pinocchio/serialization.hh>
60
61 namespace hpp {
62 namespace pinocchio {
63 const ::pinocchio::FrameType all_joint_type =
64 (::pinocchio::FrameType)(::pinocchio::JOINT | ::pinocchio::FIXED_JOINT);
65
66 30 Device::Device(const std::string& name)
67
4/8
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 30 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 30 times.
✗ Branch 12 not taken.
✓ Branch 16 taken 30 times.
✗ Branch 17 not taken.
30 : AbstractDevice(), name_(name), weakPtr_() {
68 30 invalidate();
69
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 createData();
70
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 createGeomData();
71
72
1/2
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
30 numberDeviceData(1);
73 30 }
74
75 Device::Device(const Device& other)
76 : AbstractDevice(other.model_, other.geomModel_),
77 d_(other.d_),
78 name_(other.name_),
79 grippers_(),
80 extraConfigSpace_(other.extraConfigSpace_),
81 weakPtr_(),
82 datas_() {
83 numberDeviceData(other.numberDeviceData());
84 }
85
86 118 Device::~Device() { datas_.clear(); }
87
88 155 void Device::numberDeviceData(const size_type& s) {
89 // Delete current device datas
90
1/2
✓ Branch 1 taken 155 times.
✗ Branch 2 not taken.
155 datas_.clear();
91 // Create new device datas
92
1/2
✓ Branch 2 taken 155 times.
✗ Branch 3 not taken.
155 std::vector<DeviceData*> datas((std::size_t)s);
93
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 155 times.
255 for (std::size_t i = 0; i < (std::size_t)s; ++i)
94
2/4
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
100 datas[i] = new DeviceData(d_);
95
1/2
✓ Branch 3 taken 155 times.
✗ Branch 4 not taken.
155 datas_.push_back(datas.begin(), datas.end());
96 155 }
97
98 124 size_type Device::numberDeviceData() const { return (size_type)datas_.size(); }
99
100 // static method
101 28 DevicePtr_t Device::create(const std::string& name) {
102
2/4
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 28 times.
✗ Branch 6 not taken.
28 DevicePtr_t res = DevicePtr_t(new Device(name)); // init shared ptr
103
1/2
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
28 res->init(res);
104 28 return res;
105 }
106
107 // static method
108 DevicePtr_t Device::createCopy(const DevicePtr_t& other) {
109 DevicePtr_t res = DevicePtr_t(new Device(*other)); // init shared ptr
110 res->initCopy(res, *other);
111 return res;
112 }
113
114 // static method
115 DevicePtr_t Device::createCopyConst(const DeviceConstPtr_t& device) {
116 DevicePtr_t res = Device::create(device->name()); // init shared ptr
117 /* The copy of Pinocchio::Model is not implemented yet. */
118 /* We need this feature to finish the implementation of this method. */
119 assert(false && "TODO: createCopyConst is not implemented yet.");
120 return res;
121 }
122
123 30 void Device::init(const DeviceWkPtr_t& weakPtr) {
124 30 weakPtr_ = weakPtr;
125 30 d_.devicePtr_ = weakPtr;
126 30 }
127
128 void Device::initCopy(const DeviceWkPtr_t& weakPtr, const Device& other) {
129 init(weakPtr);
130 grippers_.resize(other.grippers_.size());
131 for (std::size_t i = 0; i < grippers_.size(); ++i)
132 grippers_[i] = Gripper::createCopy(other.grippers_[i], weakPtr);
133 }
134
135 60 void Device::createData() {
136
1/2
✓ Branch 3 taken 60 times.
✗ Branch 4 not taken.
60 d_.data_ = DataPtr_t(new Data(model()));
137 // We assume that model is now complete and state can be resized.
138 60 resizeState();
139 60 }
140
141 60 void Device::createGeomData() {
142
2/4
✓ Branch 3 taken 60 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 60 times.
✗ Branch 8 not taken.
60 d().geomData_ = GeomDataPtr_t(new GeomData(geomModel()));
143 60 ::pinocchio::computeBodyRadius(model(), geomModel(), geomData());
144 60 d().invalidate();
145
1/2
✓ Branch 2 taken 60 times.
✗ Branch 3 not taken.
60 numberDeviceData(numberDeviceData());
146 60 }
147
148 1 void Device::removeJoints(const std::vector<std::string>& jointNames,
149 Configuration_t referenceConfig) {
150
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 std::vector<JointIndex> joints(jointNames.size());
151
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 std::transform(jointNames.begin(), jointNames.end(), joints.begin(),
152 4 [this](const std::string& n) {
153 2 auto id = model_->getJointId(n);
154
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if (id >= model_->joints.size())
155 throw std::invalid_argument("Device " + name_ +
156 " does not have "
157 "any joint named " +
158 n);
159 2 return id;
160 });
161
162
3/6
✓ 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.
1 ModelPtr_t nModel(new Model);
163
3/6
✓ 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.
1 GeomModelPtr_t nGeomModel(new GeomModel);
164
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 ::pinocchio::buildReducedModel(*model_, *geomModel_, joints,
165
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 referenceConfig.head(model_->nq), *nModel,
166 1 *nGeomModel);
167 1 model_ = nModel;
168 1 geomModel_ = nGeomModel;
169
170 // update the grippers
171
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 std::transform(grippers_.begin(), grippers_.end(), grippers_.begin(),
172 [this](GripperPtr_t g) {
173 return Gripper::create(g->name(), this->weakPtr_);
174 });
175
176 1 invalidate();
177
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 createData();
178
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 createGeomData();
179
180
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 numberDeviceData(numberDeviceData());
181 1 }
182
183 /* ---------------------------------------------------------------------- */
184 /* --- JOINT ------------------------------------------------------------ */
185 /* ---------------------------------------------------------------------- */
186
187 18 JointPtr_t Device::rootJoint() const {
188
1/2
✓ Branch 3 taken 18 times.
✗ Branch 4 not taken.
18 return Joint::create(weakPtr_.lock(), 1);
189 }
190
191 Frame Device::rootFrame() const {
192 return Frame(weakPtr_.lock(),
193 model().getFrameId("root_joint", all_joint_type));
194 }
195
196 81 size_type Device::nbJoints() const {
197 81 return size_type(model().joints.size() - 1);
198 }
199
200 80 JointPtr_t Device::jointAt(const size_type& i) const {
201
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
80 assert(i < nbJoints());
202
1/2
✓ Branch 3 taken 80 times.
✗ Branch 4 not taken.
80 return Joint::create(weakPtr_.lock(), JointIndex(i + 1));
203 }
204
205 JointPtr_t Device::getJointAtConfigRank(const size_type& r) const {
206 // BOOST_FOREACH( const JointModel & j, // Skip "universe" joint
207 // std::make_pair(model_->joints.begin()+1,model_->joints.end()) )
208 BOOST_FOREACH (const JointModel& j, model().joints) {
209 if (j.id() == 0) continue; // Skip "universe" joint
210 const size_type iq = r - j.idx_q();
211 if (0 <= iq && iq < j.nq()) return Joint::create(weakPtr_.lock(), j.id());
212 }
213 assert(false && "The joint at config rank has not been found");
214 return JointPtr_t();
215 }
216
217 JointPtr_t Device::getJointAtVelocityRank(const size_type& r) const {
218 BOOST_FOREACH (const JointModel& j, model().joints) {
219 if (j.id() == 0) continue; // Skip "universe" joint
220 const size_type iv = r - j.idx_v();
221 if (0 <= iv && iv < j.nv()) return Joint::create(weakPtr_.lock(), j.id());
222 }
223 assert(false && "The joint at velocity rank has not been found");
224 return JointPtr_t();
225 }
226
227 30 JointPtr_t Device::getJointByName(const std::string& name) const {
228
2/2
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 28 times.
30 if (!model().existJointName(name))
229
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
6 throw std::runtime_error("Device " + name_ +
230
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
8 " does not have any joint named " + name);
231 28 JointIndex id = model().getJointId(name);
232
1/2
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
28 return Joint::create(weakPtr_.lock(), id);
233 }
234
235 12 JointPtr_t Device::getJointByBodyName(const std::string& name) const {
236
3/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 2 times.
12 if (model().existFrame(name)) {
237
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 FrameIndex bodyId = model().getFrameId(name);
238
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 if (model().frames[bodyId].type == ::pinocchio::BODY) {
239 10 JointIndex jointId = model().frames[bodyId].parent;
240 // assert(jointId>=0);
241
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
10 assert((std::size_t)jointId < model().joints.size());
242
1/2
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
10 return Joint::create(weakPtr_.lock(), jointId);
243 }
244 }
245
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
6 throw std::runtime_error("Device " + name_ +
246
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
8 " has no joint with body of name " + name);
247 }
248
249 8 Frame Device::getFrameByName(const std::string& name) const {
250
2/4
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
8 if (!model().existFrame(name))
251 throw std::logic_error("Device " + name_ +
252 " does not have any frame named " + name);
253
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 FrameIndex id = model().getFrameId(name);
254
1/2
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
8 return Frame(weakPtr_.lock(), id);
255 }
256
257 168 size_type Device::configSize() const {
258 168 return model().nq + extraConfigSpace_.dimension();
259 }
260
261 171 size_type Device::numberDof() const {
262 171 return model().nv + extraConfigSpace_.dimension();
263 }
264
265 /* ---------------------------------------------------------------------- */
266 /* --- CONFIG ----------------------------------------------------------- */
267 /* ---------------------------------------------------------------------- */
268
269 62 void Device::resizeState() {
270 62 d_.invalidate();
271 62 d_.currentConfiguration_ = neutralConfiguration();
272
1/2
✓ Branch 3 taken 62 times.
✗ Branch 4 not taken.
62 d_.currentVelocity_ = vector_t::Zero(numberDof());
273
1/2
✓ Branch 3 taken 62 times.
✗ Branch 4 not taken.
62 d_.currentAcceleration_ = vector_t::Zero(numberDof());
274 62 d_.jointJacobians_.resize((std::size_t)model().njoints);
275
276 62 configSpace_ = LiegroupSpace::empty();
277 62 configSpaceRnxSOn_ = LiegroupSpace::empty();
278 62 const Model& m(model());
279
2/2
✓ Branch 1 taken 557 times.
✓ Branch 2 taken 62 times.
619 for (JointIndex i = 1; i < m.joints.size(); ++i) {
280
3/6
✓ Branch 2 taken 557 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 557 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 557 times.
✗ Branch 11 not taken.
557 *configSpace_ *= Joint(weakPtr_, i).configurationSpace();
281
3/6
✓ Branch 2 taken 557 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 557 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 557 times.
✗ Branch 11 not taken.
557 *configSpaceRnxSOn_ *= Joint(weakPtr_, i).RnxSOnConfigurationSpace();
282 }
283
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 59 times.
62 if (extraConfigSpace_.dimension() > 0) {
284 LiegroupSpacePtr_t extra =
285
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 LiegroupSpace::create(extraConfigSpace_.dimension());
286
1/2
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
3 *configSpace_ *= extra;
287
1/2
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
3 *configSpaceRnxSOn_ *= extra;
288 3 }
289
290
1/2
✓ Branch 2 taken 62 times.
✗ Branch 3 not taken.
62 numberDeviceData(numberDeviceData());
291 62 }
292
293 82 Configuration_t Device::neutralConfiguration() const {
294 82 const Model& m(model());
295
1/2
✓ Branch 2 taken 82 times.
✗ Branch 3 not taken.
82 Configuration_t n(configSize());
296
2/4
✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 82 times.
✗ Branch 5 not taken.
82 ::pinocchio::neutral(m, n.head(m.nq));
297
2/4
✓ Branch 2 taken 82 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 82 times.
✗ Branch 6 not taken.
82 n.tail(extraConfigSpace_.dimension()).setZero();
298 82 return n;
299 }
300
301 13 void Device::addJointConstraint(JointLinearConstraint constraint) {
302
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
13 assert(constraint.joint && constraint.reference);
303
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 assert(constraint.joint->configSize() == 1);
304
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 assert(constraint.reference->configSize() == 1);
305
306 13 jointConstraints_.push_back(constraint);
307 13 }
308
309 std::ostream& Device::print(std::ostream& os) const {
310 os << model() << iendl;
311 // Print frame names
312 os << "Frames" << std::endl;
313 for (FrameIndex i = 0; i < (FrameIndex)model().nframes; ++i) {
314 const ::pinocchio::Frame& frame(model().frames[i]);
315 os << frame.name << "\t parent:" << model().names[frame.parent]
316 << std::endl;
317 }
318 if (jointConstraints_.size() > 0)
319 os << "Joint linear constraints:" << incindent;
320 for (std::size_t i = 0; i < jointConstraints_.size(); ++i)
321 os << iendl << jointConstraints_[i].joint->name() << " = "
322 << jointConstraints_[i].multiplier << " * "
323 << jointConstraints_[i].reference->name() << " + "
324 << jointConstraints_[i].offset;
325 return os << decindent << std::endl;
326 }
327
328 /* ---------------------------------------------------------------------- */
329 /* --- COLLISIONS ------------------------------------------------------- */
330 /* ---------------------------------------------------------------------- */
331
332 BodyPtr_t Device::obstacles() const {
333 return BodyPtr_t(new Body(weakPtr_.lock(), 0));
334 }
335
336 size_type Device::nbObjects() const {
337 return (size_type)geomModel().geometryObjects.size();
338 }
339
340 CollisionObjectPtr_t Device::objectAt(const size_type& i) const {
341 assert(i < nbObjects());
342 return CollisionObjectPtr_t(
343 new CollisionObject(weakPtr_.lock(), (GeomIndex)i));
344 }
345
346 bool Device::collisionTest(const bool stopAtFirstCollision) {
347 /* Following hpp::model API, the forward kinematics (joint placement) is
348 * supposed to have already been computed. */
349 updateGeometryPlacements();
350 return ::pinocchio::computeCollisions(geomModel(), geomData(),
351 stopAtFirstCollision);
352 }
353
354 void Device::computeDistances() {
355 /* Following hpp::model API, the forward kinematics (joint placement) is
356 * supposed to have already been computed. */
357 updateGeometryPlacements();
358 ::pinocchio::computeDistances(geomModel(), geomData());
359 }
360
361 const DistanceResults_t& Device::distanceResults() const {
362 return geomData().distanceResults;
363 }
364
365 /* ---------------------------------------------------------------------- */
366 /* --- Bounding box ----------------------------------------------------- */
367 /* ---------------------------------------------------------------------- */
368
369 struct AABBStep : public ::pinocchio::fusion::JointUnaryVisitorBase<AABBStep> {
370 typedef boost::fusion::vector<const Model&, Configuration_t, bool,
371 coal::AABB&>
372 ArgsType;
373
374 template <typename JointModel>
375 6 static void algo(const ::pinocchio::JointModelBase<JointModel>& jmodel,
376 const Model& model, Configuration_t q, bool initializeAABB,
377 coal::AABB& aabb) {
378 typedef typename RnxSOnLieGroupMap::operation<JointModel>::type LG_t;
379 /*
380 if (LG_t::NT == 0) {
381 aabb.min_.setZero();
382 aabb.max_.setZero();
383 return;
384 }
385 */
386
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 typename JointModel::JointDataDerived data(jmodel.createData());
387 // Set configuration to lower bound.
388
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
6 jmodel.jointConfigSelector(q).template head<LG_t::NT>() =
389
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 jmodel.jointConfigSelector(model.lowerPositionLimit)
390
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 .template head<LG_t::NT>();
391
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 jmodel.calc(data, q);
392
2/5
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
6 vector3_t min = data.M_accessor().translation();
393 // Set configuration to upper bound.
394
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
6 jmodel.jointConfigSelector(q).template head<LG_t::NT>() =
395
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 jmodel.jointConfigSelector(model.upperPositionLimit)
396
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 .template head<LG_t::NT>();
397
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 jmodel.calc(data, q);
398
2/5
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
6 vector3_t max = data.M_accessor().translation();
399
400 // This should not be required as it should be done in
401 // AABB::operator+=(Vec3f) for(int i = 0; i < 3; ++i) { if (min[i] > max[i])
402 // std::swap(min[i], max[i]);
403 // }
404 // aabb.min_ = min;
405 // aabb.max_ = max;
406
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
6 if (initializeAABB)
407
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
6 aabb = coal::AABB(min);
408 else
409 aabb += min;
410
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 aabb += max;
411 }
412 };
413
414 3 coal::AABB Device::computeAABB() const {
415 // TODO check that user has called
416
417 3 const Model& m(model());
418
419 // Compute maximal distance to parent joint.
420
1/2
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
3 std::vector<value_type> maxDistToParent(m.joints.size(), 0);
421
2/2
✓ Branch 1 taken 81 times.
✓ Branch 2 taken 3 times.
84 for (JointIndex i = 1; i < m.joints.size(); ++i) {
422
1/2
✓ Branch 3 taken 81 times.
✗ Branch 4 not taken.
162 Joint joint(weakPtr_.lock(), i);
423
1/2
✓ Branch 1 taken 81 times.
✗ Branch 2 not taken.
81 joint.computeMaximalDistanceToParent();
424
1/2
✓ Branch 1 taken 81 times.
✗ Branch 2 not taken.
81 maxDistToParent[i] = joint.maximalDistanceToParent();
425 81 }
426
427 // Compute maximal distance to root joint.
428
1/2
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
3 std::vector<value_type> maxDistToRoot(m.joints.size(), 0);
429
1/2
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
3 std::vector<value_type> distances(m.joints.size(), 0);
430
431 3 std::vector<JointIndex> rootIdxs;
432 3 std::vector<value_type> maxRadius;
433
2/2
✓ Branch 1 taken 81 times.
✓ Branch 2 taken 3 times.
84 for (JointIndex i = 1; i < m.joints.size(); ++i) {
434
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 78 times.
81 if (m.parents[i] == 0) // Moving child of universe
435 {
436
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 rootIdxs.push_back(i);
437
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 maxRadius.push_back(0);
438 // This is the root of a subtree.
439 // maxDistToRoot[i] = 0; // Already zero by initialization
440 } else {
441 78 maxDistToRoot[i] = maxDistToRoot[m.parents[i]] + maxDistToParent[i];
442 }
443
444
1/2
✓ Branch 3 taken 81 times.
✗ Branch 4 not taken.
162 Body body(weakPtr_.lock(), i);
445
1/2
✓ Branch 1 taken 81 times.
✗ Branch 2 not taken.
81 distances[i] = body.radius() + maxDistToRoot[i];
446
447 81 maxRadius.back() = std::max(maxRadius.back(), distances[i]);
448 81 }
449
450 // Compute AABB
451
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 Configuration_t q(neutralConfiguration());
452
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 coal::AABB aabb;
453
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
6 for (std::size_t k = 0; k < rootIdxs.size(); ++k) {
454 3 JointIndex i = rootIdxs[k];
455 3 value_type radius = maxRadius[k];
456
457
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 coal::AABB aabb_subtree;
458
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
3 AABBStep::run(m.joints[i], AABBStep::ArgsType(m, q, true, aabb_subtree));
459
460 // Move AABB
461
2/4
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
3 coal::rotate(aabb_subtree, m.jointPlacements[i].rotation());
462
2/4
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
3 coal::translate(aabb_subtree, m.jointPlacements[i].translation());
463
464 // Add radius
465
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 aabb_subtree.min_.array() -= radius;
466
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 aabb_subtree.max_.array() += radius;
467
468 // Merge back into previous one.
469
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (k == 0)
470
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 aabb = aabb_subtree;
471 else
472 aabb += aabb_subtree;
473 }
474 6 return aabb;
475 3 }
476
477 void replaceGeometryByConvexHull(GeomModel& gmodel,
478 const std::vector<std::string>& gnames) {
479 for (std::size_t i = 0; i < gnames.size(); ++i) {
480 if (!gmodel.existGeometryName(gnames[i]))
481 throw std::invalid_argument("Geometry " + gnames[i] +
482 " does not "
483 "exist.");
484 GeomIndex gid = gmodel.getGeometryId(gnames[i]);
485 GeometryObject& go = gmodel.geometryObjects[gid];
486 if (go.geometry->getObjectType() == coal::OT_BVH) {
487 coal::BVHModelBase* bvh =
488 dynamic_cast<coal::BVHModelBase*>(go.geometry.get());
489 assert(bvh != NULL);
490 bvh->buildConvexHull(false, "Qx");
491 go.geometry = bvh->convex;
492 }
493 }
494 }
495
496 template <typename To, typename Ti, typename UnaryOp>
497 inline std::vector<To> serialize_to(const std::vector<Ti>& in, UnaryOp op) {
498 std::vector<To> out;
499 out.reserve(in.size());
500 std::transform(in.begin(), in.end(), out.begin(), op);
501 return out;
502 }
503
504 template <class Archive>
505 2 void Device::save(Archive& ar, const unsigned int version) const {
506 (void)version;
507
508 2 auto* har = hpp::serialization::cast(&ar);
509
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(name_);
510 // write it is not present in the HPP archive.
511 2 bool written =
512
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
2 (!har || har->template get<hpp::pinocchio::Device>(name_, false) != this);
513
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(written);
514
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 if (written) {
515 // AbstractDevice
516
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(model_);
517 // ar & BOOST_SERIALIZATION_NVP(geomModel_);
518
519 // Device
520 // - grippers_
521 2 std::vector<FrameIndex> grippers;
522 2 std::transform(
523 grippers_.begin(), grippers_.end(), grippers.begin(),
524 [](const GripperPtr_t& g) -> FrameIndex { return g->frameId(); });
525
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(grippers);
526
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(jointConstraints_);
527
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(weakPtr_);
528
529
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(extraConfigSpace_.dimension_);
530
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(extraConfigSpace_.lowerBounds_);
531
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(extraConfigSpace_.upperBounds_);
532
533
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 size_type nbDeviceData = numberDeviceData();
534
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(nbDeviceData);
535 }
536 }
537
538 template <class Archive>
539 2 void Device::load(Archive& ar, const unsigned int version) {
540 (void)version;
541
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(name_);
542 bool written;
543
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(written);
544
545 2 auto* har = hpp::serialization::cast(&ar);
546 2 bool dummyDevice =
547
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
2 har && har->template get<hpp::pinocchio::Device>(name_, false);
548
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 if (written) {
549 // AbstractDevice
550
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(model_);
551 // ar & BOOST_SERIALIZATION_NVP(geomModel_);
552
553 // Device
554 // - grippers_
555 2 std::vector<FrameIndex> grippers;
556
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(grippers);
557
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(jointConstraints_);
558
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(weakPtr_);
559
560
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(extraConfigSpace_.dimension_);
561
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(extraConfigSpace_.lowerBounds_);
562
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(extraConfigSpace_.upperBounds_);
563
564 size_type nbDeviceData;
565
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(nbDeviceData);
566
567
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
2 if (!dummyDevice) { // If this device will not be thrown away, initialize
568 // it cleanly.
569 grippers_.reserve(grippers.size());
570 std::transform(grippers.begin(), grippers.end(), grippers_.begin(),
571 [this](FrameIndex i) -> GripperPtr_t {
572 return Gripper::create(model_->frames[i].name, weakPtr_);
573 });
574 createData();
575 createGeomData();
576 numberDeviceData(nbDeviceData);
577 }
578
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
2 } else if (!dummyDevice)
579 throw std::logic_error(
580 "This archive does not contain a valid Device "
581 "of name " +
582 name_);
583 }
584
585 HPP_SERIALIZATION_SPLIT_IMPLEMENT(Device);
586 } // namespace pinocchio
587 } // namespace hpp
588
589 namespace boost {
590 namespace serialization {
591 template <class Archive>
592 void serialize(Archive& ar, hpp::pinocchio::Device::JointLinearConstraint& c,
593 const unsigned int version) {
594 (void)version;
595 ar& make_nvp("offset", c.offset);
596 ar& make_nvp("multiplier", c.multiplier);
597 ar& make_nvp("joint", c.joint);
598 ar& make_nvp("reference", c.reference);
599 }
600 } // namespace serialization
601 } // namespace boost
602