Directory: | ./ |
---|---|
File: | include/pinocchio/parsers/urdf/model.hxx |
Date: | 2025-02-12 21:03:38 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 172 | 200 | 86.0% |
Branches: | 153 | 336 | 45.5% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2015-2021 CNRS INRIA | ||
3 | // Copyright (c) 2015 Wandercraft, 86 rue de Paris 91400 Orsay, France. | ||
4 | // | ||
5 | |||
6 | #ifndef __pinocchio_multibody_parsers_urdf_model_hxx__ | ||
7 | #define __pinocchio_multibody_parsers_urdf_model_hxx__ | ||
8 | |||
9 | #include "pinocchio/math/matrix.hpp" | ||
10 | #include "pinocchio/parsers/config.hpp" | ||
11 | #include "pinocchio/parsers/urdf.hpp" | ||
12 | #include "pinocchio/multibody/model.hpp" | ||
13 | |||
14 | #include <sstream> | ||
15 | #include <boost/foreach.hpp> | ||
16 | #include <limits> | ||
17 | #include <iostream> | ||
18 | |||
19 | namespace pinocchio | ||
20 | { | ||
21 | namespace urdf | ||
22 | { | ||
23 | namespace details | ||
24 | { | ||
25 | typedef double urdf_scalar_type; | ||
26 | |||
27 | template<typename _Scalar, int Options> | ||
28 | class UrdfVisitorBaseTpl | ||
29 | { | ||
30 | public: | ||
31 | enum JointType | ||
32 | { | ||
33 | REVOLUTE, | ||
34 | CONTINUOUS, | ||
35 | PRISMATIC, | ||
36 | FLOATING, | ||
37 | PLANAR, | ||
38 | SPHERICAL | ||
39 | }; | ||
40 | |||
41 | typedef enum ::pinocchio::FrameType FrameType; | ||
42 | typedef _Scalar Scalar; | ||
43 | typedef SE3Tpl<Scalar, Options> SE3; | ||
44 | typedef InertiaTpl<Scalar, Options> Inertia; | ||
45 | |||
46 | typedef Eigen::Matrix<Scalar, 3, 1> Vector3; | ||
47 | typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1> Vector; | ||
48 | typedef Eigen::Ref<Vector> VectorRef; | ||
49 | typedef Eigen::Ref<const Vector> VectorConstRef; | ||
50 | |||
51 | virtual void setName(const std::string & name) = 0; | ||
52 | |||
53 | virtual void addRootJoint(const Inertia & Y, const std::string & body_name) = 0; | ||
54 | |||
55 | virtual void addJointAndBody( | ||
56 | JointType type, | ||
57 | const Vector3 & axis, | ||
58 | const FrameIndex & parentFrameId, | ||
59 | const SE3 & placement, | ||
60 | const std::string & joint_name, | ||
61 | const Inertia & Y, | ||
62 | const std::string & body_name, | ||
63 | const VectorConstRef & max_effort, | ||
64 | const VectorConstRef & max_velocity, | ||
65 | const VectorConstRef & min_config, | ||
66 | const VectorConstRef & max_config, | ||
67 | const VectorConstRef & friction, | ||
68 | const VectorConstRef & damping) = 0; | ||
69 | |||
70 | virtual void addJointAndBody( | ||
71 | JointType type, | ||
72 | const Vector3 & axis, | ||
73 | const FrameIndex & parentFrameId, | ||
74 | const SE3 & placement, | ||
75 | const std::string & joint_name, | ||
76 | const Inertia & Y, | ||
77 | const SE3 & frame_placement, | ||
78 | const std::string & body_name, | ||
79 | const VectorConstRef & max_effort, | ||
80 | const VectorConstRef & max_velocity, | ||
81 | const VectorConstRef & min_config, | ||
82 | const VectorConstRef & max_config, | ||
83 | const VectorConstRef & friction, | ||
84 | const VectorConstRef & damping) = 0; | ||
85 | |||
86 | virtual void addFixedJointAndBody( | ||
87 | const FrameIndex & parentFrameId, | ||
88 | const SE3 & joint_placement, | ||
89 | const std::string & joint_name, | ||
90 | const Inertia & Y, | ||
91 | const std::string & body_name) = 0; | ||
92 | |||
93 | virtual void appendBodyToJoint( | ||
94 | const FrameIndex fid, | ||
95 | const Inertia & Y, | ||
96 | const SE3 & placement, | ||
97 | const std::string & body_name) = 0; | ||
98 | |||
99 | virtual FrameIndex getBodyId(const std::string & frame_name) const = 0; | ||
100 | |||
101 | virtual JointIndex getJointId(const std::string & joint_name) const = 0; | ||
102 | |||
103 | virtual const std::string & getJointName(const JointIndex jointId) const = 0; | ||
104 | |||
105 | virtual Frame getBodyFrame(const std::string & frame_name) const = 0; | ||
106 | |||
107 | virtual JointIndex getParentId(const std::string & frame_name) const = 0; | ||
108 | |||
109 | virtual bool existFrame(const std::string & frame_name, const FrameType type) const = 0; | ||
110 | |||
111 | 127 | UrdfVisitorBaseTpl() | |
112 | 127 | : log(NULL) | |
113 | { | ||
114 | 127 | } | |
115 | |||
116 | template<typename T> | ||
117 | 86795 | UrdfVisitorBaseTpl & operator<<(const T & t) | |
118 | { | ||
119 | 86795 | if (log != NULL) | |
120 | ✗ | *log << t; | |
121 | 86795 | return *this; | |
122 | } | ||
123 | |||
124 | std::ostream * log; | ||
125 | }; | ||
126 | |||
127 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
128 | class UrdfVisitor : public UrdfVisitorBaseTpl<Scalar, Options> | ||
129 | { | ||
130 | public: | ||
131 | typedef UrdfVisitorBaseTpl<Scalar, Options> Base; | ||
132 | typedef typename Base::JointType JointType; | ||
133 | typedef typename Base::Vector3 Vector3; | ||
134 | typedef typename Base::VectorConstRef VectorConstRef; | ||
135 | typedef typename Base::SE3 SE3; | ||
136 | typedef typename Base::Inertia Inertia; | ||
137 | |||
138 | typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model; | ||
139 | typedef typename Model::JointCollection JointCollection; | ||
140 | typedef typename Model::JointModel JointModel; | ||
141 | typedef typename Model::Frame Frame; | ||
142 | |||
143 | Model & model; | ||
144 | std::string root_joint_name; | ||
145 | |||
146 | 69 | UrdfVisitor(Model & model) | |
147 | 69 | : model(model) | |
148 | { | ||
149 | 69 | } | |
150 | |||
151 | 58 | UrdfVisitor(Model & model, const std::string & rjn) | |
152 | 58 | : model(model) | |
153 | 58 | , root_joint_name(rjn) | |
154 | { | ||
155 | 58 | } | |
156 | |||
157 | 112 | void setName(const std::string & name) | |
158 | { | ||
159 | 112 | model.name = name; | |
160 | 112 | } | |
161 | |||
162 | 51 | virtual void addRootJoint(const Inertia & Y, const std::string & body_name) | |
163 | { | ||
164 | 51 | const Frame & parent_frame = model.frames[0]; | |
165 | |||
166 |
1/2✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
|
51 | model.addFrame( |
167 | 102 | Frame(body_name, parent_frame.parentJoint, 0, parent_frame.placement, BODY, Y)); | |
168 | 51 | } | |
169 | |||
170 | 2104 | void addJointAndBody( | |
171 | JointType type, | ||
172 | const Vector3 & axis, | ||
173 | const FrameIndex & parentFrameId, | ||
174 | const SE3 & placement, | ||
175 | const std::string & joint_name, | ||
176 | const Inertia & Y, | ||
177 | const std::string & body_name, | ||
178 | const VectorConstRef & max_effort, | ||
179 | const VectorConstRef & max_velocity, | ||
180 | const VectorConstRef & min_config, | ||
181 | const VectorConstRef & max_config, | ||
182 | const VectorConstRef & friction, | ||
183 | const VectorConstRef & damping) | ||
184 | { | ||
185 |
1/2✓ Branch 2 taken 2104 times.
✗ Branch 3 not taken.
|
2104 | addJointAndBody( |
186 | type, axis, parentFrameId, placement, joint_name, Y, SE3::Identity(), body_name, | ||
187 | max_effort, max_velocity, min_config, max_config, friction, damping); | ||
188 | 2104 | } | |
189 | |||
190 | 2268 | void addJointAndBody( | |
191 | JointType type, | ||
192 | const Vector3 & axis, | ||
193 | const FrameIndex & parentFrameId, | ||
194 | const SE3 & placement, | ||
195 | const std::string & joint_name, | ||
196 | const Inertia & Y, | ||
197 | const SE3 & frame_placement, | ||
198 | const std::string & body_name, | ||
199 | const VectorConstRef & max_effort, | ||
200 | const VectorConstRef & max_velocity, | ||
201 | const VectorConstRef & min_config, | ||
202 | const VectorConstRef & max_config, | ||
203 | const VectorConstRef & friction, | ||
204 | const VectorConstRef & damping) | ||
205 | { | ||
206 | JointIndex joint_id; | ||
207 | 2268 | const Frame & frame = model.frames[parentFrameId]; | |
208 | |||
209 |
5/7✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2220 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 34 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
|
2268 | switch (type) |
210 | { | ||
211 | 4 | case Base::FLOATING: | |
212 |
7/14✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 4 times.
✗ Branch 20 not taken.
|
16 | joint_id = model.addJoint( |
213 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
12 | frame.parentJoint, typename JointCollection::JointModelFreeFlyer(), |
214 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | frame.placement * placement, joint_name, max_effort, max_velocity, min_config, |
215 | max_config, friction, damping); | ||
216 | 4 | break; | |
217 | 2220 | case Base::REVOLUTE: | |
218 | 2220 | joint_id = addJoint< | |
219 | typename JointCollection::JointModelRX, typename JointCollection::JointModelRY, | ||
220 | typename JointCollection::JointModelRZ, | ||
221 |
1/2✓ Branch 1 taken 2220 times.
✗ Branch 2 not taken.
|
2220 | typename JointCollection::JointModelRevoluteUnaligned>( |
222 | axis, frame, placement, joint_name, max_effort, max_velocity, min_config, max_config, | ||
223 | friction, damping); | ||
224 | 2220 | break; | |
225 | 1 | case Base::CONTINUOUS: | |
226 | 1 | joint_id = addJoint< | |
227 | typename JointCollection::JointModelRUBX, typename JointCollection::JointModelRUBY, | ||
228 | typename JointCollection::JointModelRUBZ, | ||
229 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | typename JointCollection::JointModelRevoluteUnboundedUnaligned>( |
230 | axis, frame, placement, joint_name, max_effort, max_velocity, min_config, max_config, | ||
231 | friction, damping); | ||
232 | 1 | break; | |
233 | 34 | case Base::PRISMATIC: | |
234 | 34 | joint_id = addJoint< | |
235 | typename JointCollection::JointModelPX, typename JointCollection::JointModelPY, | ||
236 | typename JointCollection::JointModelPZ, | ||
237 |
1/2✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
|
34 | typename JointCollection::JointModelPrismaticUnaligned>( |
238 | axis, frame, placement, joint_name, max_effort, max_velocity, min_config, max_config, | ||
239 | friction, damping); | ||
240 | 34 | break; | |
241 | ✗ | case Base::PLANAR: | |
242 | ✗ | joint_id = model.addJoint( | |
243 | ✗ | frame.parentJoint, typename JointCollection::JointModelPlanar(), | |
244 | ✗ | frame.placement * placement, joint_name, max_effort, max_velocity, min_config, | |
245 | max_config, friction, damping); | ||
246 | ✗ | break; | |
247 | 9 | case Base::SPHERICAL: | |
248 |
7/14✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 9 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 9 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 9 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 9 times.
✗ Branch 20 not taken.
|
36 | joint_id = model.addJoint( |
249 |
2/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
27 | frame.parentJoint, typename JointCollection::JointModelSpherical(), |
250 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | frame.placement * placement, joint_name, max_effort, max_velocity, min_config, |
251 | max_config, friction, damping); | ||
252 | 9 | break; | |
253 | ✗ | default: | |
254 | ✗ | PINOCCHIO_CHECK_INPUT_ARGUMENT(false, "The joint type is not correct."); | |
255 | }; | ||
256 | |||
257 |
1/2✓ Branch 1 taken 2268 times.
✗ Branch 2 not taken.
|
2268 | FrameIndex jointFrameId = model.addJointFrame(joint_id, (int)parentFrameId); |
258 |
1/2✓ Branch 1 taken 2268 times.
✗ Branch 2 not taken.
|
2268 | appendBodyToJoint(jointFrameId, Y, frame_placement, body_name); |
259 | 2268 | } | |
260 | |||
261 | 1100 | void addFixedJointAndBody( | |
262 | const FrameIndex & parent_frame_id, | ||
263 | const SE3 & joint_placement, | ||
264 | const std::string & joint_name, | ||
265 | const Inertia & Y, | ||
266 | const std::string & body_name) | ||
267 | { | ||
268 | 1100 | const Frame & parent_frame = model.frames[parent_frame_id]; | |
269 | 1100 | const JointIndex parent_frame_parent = parent_frame.parentJoint; | |
270 | |||
271 |
1/2✓ Branch 1 taken 1100 times.
✗ Branch 2 not taken.
|
1100 | const SE3 placement = parent_frame.placement * joint_placement; |
272 |
1/2✓ Branch 1 taken 1100 times.
✗ Branch 2 not taken.
|
1100 | FrameIndex fid = model.addFrame(Frame( |
273 |
1/2✓ Branch 1 taken 1100 times.
✗ Branch 2 not taken.
|
1100 | joint_name, parent_frame.parentJoint, parent_frame_id, placement, FIXED_JOINT, Y)); |
274 | |||
275 |
1/2✓ Branch 1 taken 1100 times.
✗ Branch 2 not taken.
|
1100 | model.addBodyFrame(body_name, parent_frame_parent, placement, (int)fid); |
276 | 1100 | } | |
277 | |||
278 | 2332 | void appendBodyToJoint( | |
279 | const FrameIndex fid, | ||
280 | const Inertia & Y, | ||
281 | const SE3 & placement, | ||
282 | const std::string & body_name) | ||
283 | { | ||
284 | 2332 | const Frame & frame = model.frames[fid]; | |
285 |
1/2✓ Branch 1 taken 2332 times.
✗ Branch 2 not taken.
|
2332 | const SE3 & p = frame.placement * placement; |
286 | assert(frame.parentJoint >= 0); | ||
287 |
3/4✓ Branch 1 taken 2332 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1941 times.
✓ Branch 4 taken 391 times.
|
2332 | if (!Y.isZero(Scalar(0))) |
288 | { | ||
289 |
1/2✓ Branch 1 taken 1941 times.
✗ Branch 2 not taken.
|
1941 | model.appendBodyToJoint(frame.parentJoint, Y, p); |
290 | } | ||
291 | |||
292 |
1/2✓ Branch 1 taken 2332 times.
✗ Branch 2 not taken.
|
2332 | model.addBodyFrame(body_name, frame.parentJoint, p, (int)fid); |
293 | // Reference to model.frames[fid] can has changed because the vector | ||
294 | // may have been reallocated. | ||
295 | 2332 | assert(model.frames[fid].parentJoint >= 0); | |
296 | { | ||
297 |
4/8✓ Branch 4 taken 2332 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2332 times.
✗ Branch 7 not taken.
✓ Branch 13 taken 2332 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 2332 times.
✗ Branch 16 not taken.
|
2332 | assert( |
298 | !hasNaN(model.inertias[model.frames[fid].parentJoint].lever()) | ||
299 | && !hasNaN(model.inertias[model.frames[fid].parentJoint].inertia().data())); | ||
300 | } | ||
301 | 2332 | } | |
302 | |||
303 | 3562 | FrameIndex getBodyId(const std::string & frame_name) const | |
304 | { | ||
305 | |||
306 |
2/4✓ Branch 1 taken 3562 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3562 times.
✗ Branch 4 not taken.
|
3562 | if (model.existFrame(frame_name, BODY)) |
307 | { | ||
308 |
1/2✓ Branch 1 taken 3562 times.
✗ Branch 2 not taken.
|
3562 | FrameIndex fid = model.getFrameId(frame_name, BODY); |
309 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 3562 times.
|
3562 | assert(model.frames[fid].type == BODY); |
310 | 3562 | return fid; | |
311 | } | ||
312 | else | ||
313 | ✗ | throw std::invalid_argument("Model does not have any body named " + frame_name); | |
314 | } | ||
315 | |||
316 | 164 | FrameIndex getJointId(const std::string & joint_name) const | |
317 | { | ||
318 | |||
319 |
1/2✓ Branch 1 taken 164 times.
✗ Branch 2 not taken.
|
164 | if (model.existJointName(joint_name)) |
320 | { | ||
321 | 164 | JointIndex jid = model.getJointId(joint_name); | |
322 | 164 | return jid; | |
323 | } | ||
324 | else | ||
325 | ✗ | throw std::invalid_argument("Model does not have any joint named " + joint_name); | |
326 | } | ||
327 | |||
328 | ✗ | const std::string & getJointName(const JointIndex jointId) const | |
329 | { | ||
330 | ✗ | return model.names[jointId]; | |
331 | } | ||
332 | |||
333 | 29 | Frame getBodyFrame(const std::string & frame_name) const | |
334 | { | ||
335 | |||
336 |
2/4✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 29 times.
✗ Branch 4 not taken.
|
29 | if (model.existFrame(frame_name, BODY)) |
337 | { | ||
338 |
1/2✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
|
29 | FrameIndex fid = model.getFrameId(frame_name, BODY); |
339 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
|
29 | assert(model.frames[fid].type == BODY); |
340 | 29 | return model.frames[fid]; | |
341 | } | ||
342 | else | ||
343 | ✗ | throw std::invalid_argument("Model does not have any body named " + frame_name); | |
344 | } | ||
345 | |||
346 | 16 | JointIndex getParentId(const std::string & frame_name) const | |
347 | { | ||
348 | |||
349 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | if (model.existFrame(frame_name, BODY)) |
350 | { | ||
351 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
16 | FrameIndex fid = model.getFrameId(frame_name, BODY); |
352 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
|
16 | assert(model.frames[fid].type == BODY); |
353 | 16 | return model.frames[fid].parentJoint; | |
354 | } | ||
355 | else | ||
356 | ✗ | throw std::invalid_argument("Model does not have any body named " + frame_name); | |
357 | } | ||
358 | |||
359 | ✗ | bool existFrame(const std::string & frame_name, const FrameType type) const | |
360 | { | ||
361 | ✗ | return model.existFrame(frame_name, type); | |
362 | } | ||
363 | |||
364 | template<typename TypeX, typename TypeY, typename TypeZ, typename TypeUnaligned> | ||
365 | 4510 | JointIndex addJoint( | |
366 | const Vector3 & axis, | ||
367 | const Frame & frame, | ||
368 | const SE3 & placement, | ||
369 | const std::string & joint_name, | ||
370 | const VectorConstRef & max_effort, | ||
371 | const VectorConstRef & max_velocity, | ||
372 | const VectorConstRef & min_config, | ||
373 | const VectorConstRef & max_config, | ||
374 | const VectorConstRef & friction, | ||
375 | const VectorConstRef & damping) | ||
376 | { | ||
377 | 4510 | CartesianAxis axisType = extractCartesianAxis(axis); | |
378 |
4/5✓ Branch 0 taken 547 times.
✓ Branch 1 taken 797 times.
✓ Branch 2 taken 598 times.
✓ Branch 3 taken 313 times.
✗ Branch 4 not taken.
|
4510 | switch (axisType) |
379 | { | ||
380 | 1094 | case AXIS_X: | |
381 |
6/12✓ Branch 2 taken 547 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 547 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 547 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 547 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 547 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 547 times.
✗ Branch 18 not taken.
|
4376 | return model.addJoint( |
382 |
3/6✓ Branch 1 taken 547 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 547 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 547 times.
✗ Branch 8 not taken.
|
3282 | frame.parentJoint, TypeX(), frame.placement * placement, joint_name, max_effort, |
383 | 1094 | max_velocity, min_config, max_config, friction, damping); | |
384 | break; | ||
385 | |||
386 | 1594 | case AXIS_Y: | |
387 |
6/12✓ Branch 2 taken 797 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 797 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 797 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 797 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 797 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 797 times.
✗ Branch 18 not taken.
|
6376 | return model.addJoint( |
388 |
3/6✓ Branch 1 taken 797 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 797 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 797 times.
✗ Branch 8 not taken.
|
4782 | frame.parentJoint, TypeY(), frame.placement * placement, joint_name, max_effort, |
389 | 1594 | max_velocity, min_config, max_config, friction, damping); | |
390 | break; | ||
391 | |||
392 | 1196 | case AXIS_Z: | |
393 |
6/12✓ Branch 2 taken 598 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 598 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 598 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 598 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 598 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 598 times.
✗ Branch 18 not taken.
|
4784 | return model.addJoint( |
394 |
3/6✓ Branch 1 taken 598 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 598 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 598 times.
✗ Branch 8 not taken.
|
3588 | frame.parentJoint, TypeZ(), frame.placement * placement, joint_name, max_effort, |
395 | 1196 | max_velocity, min_config, max_config, friction, damping); | |
396 | break; | ||
397 | |||
398 | 626 | case AXIS_UNALIGNED: | |
399 |
6/12✓ Branch 2 taken 313 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 313 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 313 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 313 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 313 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 313 times.
✗ Branch 18 not taken.
|
2504 | return model.addJoint( |
400 |
4/8✓ Branch 1 taken 313 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 313 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 313 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 313 times.
✗ Branch 11 not taken.
|
1878 | frame.parentJoint, TypeUnaligned(axis.normalized()), frame.placement * placement, |
401 | 626 | joint_name, max_effort, max_velocity, min_config, max_config, friction, damping); | |
402 | break; | ||
403 | ✗ | default: | |
404 | ✗ | PINOCCHIO_CHECK_INPUT_ARGUMENT(false, "The axis type of the joint is of wrong type."); | |
405 | break; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | private: | ||
410 | /// | ||
411 | /// \brief The four possible cartesian types of an 3D axis. | ||
412 | /// | ||
413 | enum CartesianAxis | ||
414 | { | ||
415 | AXIS_X = 0, | ||
416 | AXIS_Y = 1, | ||
417 | AXIS_Z = 2, | ||
418 | AXIS_UNALIGNED | ||
419 | }; | ||
420 | |||
421 | /// | ||
422 | /// \brief Extract the cartesian property of a particular 3D axis. | ||
423 | /// | ||
424 | /// \param[in] axis The input URDF axis. | ||
425 | /// | ||
426 | /// \return The property of the particular axis pinocchio::urdf::CartesianAxis. | ||
427 | /// | ||
428 | 2255 | static inline CartesianAxis extractCartesianAxis(const Vector3 & axis) | |
429 | { | ||
430 |
4/6✓ Branch 2 taken 2255 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2255 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 547 times.
✓ Branch 8 taken 1708 times.
|
2255 | if (axis.isApprox(Vector3::UnitX())) |
431 | 547 | return AXIS_X; | |
432 |
4/6✓ Branch 2 taken 1708 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1708 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 797 times.
✓ Branch 8 taken 911 times.
|
1708 | else if (axis.isApprox(Vector3::UnitY())) |
433 | 797 | return AXIS_Y; | |
434 |
4/6✓ Branch 2 taken 911 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 911 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 598 times.
✓ Branch 8 taken 313 times.
|
911 | else if (axis.isApprox(Vector3::UnitZ())) |
435 | 598 | return AXIS_Z; | |
436 | else | ||
437 | 313 | return AXIS_UNALIGNED; | |
438 | } | ||
439 | }; | ||
440 | |||
441 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
442 | class UrdfVisitorWithRootJoint : public UrdfVisitor<Scalar, Options, JointCollectionTpl> | ||
443 | { | ||
444 | public: | ||
445 | typedef UrdfVisitor<Scalar, Options, JointCollectionTpl> Base; | ||
446 | typedef typename Base::Inertia Inertia; | ||
447 | using Base::appendBodyToJoint; | ||
448 | using Base::model; | ||
449 | |||
450 | typedef ModelTpl<Scalar, Options, JointCollectionTpl> Model; | ||
451 | typedef typename Model::JointCollection JointCollection; | ||
452 | typedef typename Model::JointModel JointModel; | ||
453 | |||
454 | JointModel root_joint; | ||
455 | |||
456 | 58 | UrdfVisitorWithRootJoint( | |
457 | Model & model, | ||
458 | const JointModelBase<JointModel> & root_joint, | ||
459 | const std::string & rjn = "root_joint") | ||
460 | : Base(model, rjn) | ||
461 |
1/2✓ Branch 3 taken 58 times.
✗ Branch 4 not taken.
|
58 | , root_joint(root_joint.derived()) |
462 | { | ||
463 | 58 | } | |
464 | |||
465 | 58 | void addRootJoint(const Inertia & Y, const std::string & body_name) | |
466 | { | ||
467 | 58 | const Frame & frame = model.frames[0]; | |
468 | |||
469 |
4/6✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 57 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
58 | PINOCCHIO_THROW( |
470 | !model.existJointName(this->root_joint_name), std::invalid_argument, | ||
471 | "root_joint already exists as a joint in the kinematic tree."); | ||
472 | |||
473 | ✗ | JointIndex idx = model.addJoint( | |
474 |
2/4✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
|
57 | frame.parentJoint, root_joint, SE3::Identity(), this->root_joint_name |
475 | // TODO ,max_effort,max_velocity,min_config,max_config | ||
476 | ); | ||
477 | |||
478 |
1/2✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
|
57 | FrameIndex jointFrameId = model.addJointFrame(idx, 0); |
479 |
2/4✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
|
57 | appendBodyToJoint(jointFrameId, Y, SE3::Identity(), body_name); |
480 | 57 | } | |
481 | }; | ||
482 | |||
483 | typedef UrdfVisitorBaseTpl<double, 0> UrdfVisitorBase; | ||
484 | |||
485 | PINOCCHIO_PARSERS_DLLAPI void | ||
486 | parseRootTree(const ::urdf::ModelInterface * urdfTree, UrdfVisitorBase & model); | ||
487 | |||
488 | PINOCCHIO_PARSERS_DLLAPI void | ||
489 | parseRootTree(const std::string & filename, UrdfVisitorBase & model); | ||
490 | |||
491 | PINOCCHIO_PARSERS_DLLAPI void | ||
492 | parseRootTreeFromXML(const std::string & xmlString, UrdfVisitorBase & model); | ||
493 | } // namespace details | ||
494 | |||
495 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
496 | 48 | ModelTpl<Scalar, Options, JointCollectionTpl> & buildModel( | |
497 | const std::string & filename, | ||
498 | const typename ModelTpl<Scalar, Options, JointCollectionTpl>::JointModel & rootJoint, | ||
499 | const std::string & rootJointName, | ||
500 | ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
501 | const bool verbose) | ||
502 | { | ||
503 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
|
48 | if (rootJointName.empty()) |
504 | ✗ | throw std::invalid_argument( | |
505 | "rootJoint was given without a name. Please fill the argument root_joint_name"); | ||
506 | |||
507 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | details::UrdfVisitorWithRootJoint<Scalar, Options, JointCollectionTpl> visitor( |
508 | model, rootJoint, rootJointName); | ||
509 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | if (verbose) |
510 | ✗ | visitor.log = &std::cout; | |
511 |
1/2✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
|
48 | details::parseRootTree(filename, visitor); |
512 | 48 | return model; | |
513 | 48 | } | |
514 | |||
515 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
516 | 46 | ModelTpl<Scalar, Options, JointCollectionTpl> & buildModel( | |
517 | const std::string & filename, | ||
518 | const typename ModelTpl<Scalar, Options, JointCollectionTpl>::JointModel & rootJoint, | ||
519 | ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
520 | const bool verbose) | ||
521 | { | ||
522 |
2/4✓ Branch 2 taken 46 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 46 times.
✗ Branch 6 not taken.
|
46 | return buildModel(filename, rootJoint, "root_joint", model, verbose); |
523 | } | ||
524 | |||
525 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
526 | 26 | ModelTpl<Scalar, Options, JointCollectionTpl> & buildModel( | |
527 | const std::string & filename, | ||
528 | ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
529 | const bool verbose) | ||
530 | { | ||
531 |
1/2✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
|
26 | details::UrdfVisitor<Scalar, Options, JointCollectionTpl> visitor(model); |
532 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
|
26 | if (verbose) |
533 | ✗ | visitor.log = &std::cout; | |
534 |
1/2✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
|
26 | details::parseRootTree(filename, visitor); |
535 | 26 | return model; | |
536 | 26 | } | |
537 | |||
538 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
539 | 4 | ModelTpl<Scalar, Options, JointCollectionTpl> & buildModelFromXML( | |
540 | const std::string & xmlStream, | ||
541 | const typename ModelTpl<Scalar, Options, JointCollectionTpl>::JointModel & rootJoint, | ||
542 | const std::string & rootJointName, | ||
543 | ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
544 | const bool verbose) | ||
545 | { | ||
546 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
4 | if (rootJointName.empty()) |
547 | ✗ | throw std::invalid_argument( | |
548 | "rootJoint was given without a name. Please fill the argument rootJointName"); | ||
549 | |||
550 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | details::UrdfVisitorWithRootJoint<Scalar, Options, JointCollectionTpl> visitor( |
551 | model, rootJoint, rootJointName); | ||
552 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (verbose) |
553 | ✗ | visitor.log = &std::cout; | |
554 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
|
4 | details::parseRootTreeFromXML(xmlStream, visitor); |
555 | 3 | return model; | |
556 | 4 | } | |
557 | |||
558 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
559 | 4 | ModelTpl<Scalar, Options, JointCollectionTpl> & buildModelFromXML( | |
560 | const std::string & xmlStream, | ||
561 | const typename ModelTpl<Scalar, Options, JointCollectionTpl>::JointModel & rootJoint, | ||
562 | ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
563 | const bool verbose) | ||
564 | { | ||
565 |
3/4✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 1 times.
|
5 | return buildModelFromXML(xmlStream, rootJoint, "root_joint", model, verbose); |
566 | } | ||
567 | |||
568 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
569 | 5 | ModelTpl<Scalar, Options, JointCollectionTpl> & buildModelFromXML( | |
570 | const std::string & xmlStream, | ||
571 | ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
572 | const bool verbose) | ||
573 | { | ||
574 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | details::UrdfVisitor<Scalar, Options, JointCollectionTpl> visitor(model); |
575 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | if (verbose) |
576 | ✗ | visitor.log = &std::cout; | |
577 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | details::parseRootTreeFromXML(xmlStream, visitor); |
578 | 5 | return model; | |
579 | 5 | } | |
580 | |||
581 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
582 | 1 | ModelTpl<Scalar, Options, JointCollectionTpl> & buildModel( | |
583 | const std::shared_ptr<::urdf::ModelInterface> urdfTree, | ||
584 | const typename ModelTpl<Scalar, Options, JointCollectionTpl>::JointModel & rootJoint, | ||
585 | const std::string & rootJointName, | ||
586 | ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
587 | const bool verbose) | ||
588 | { | ||
589 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (rootJointName.empty()) |
590 | ✗ | throw std::invalid_argument( | |
591 | "rootJoint was given without a name. Please fill the argument rootJointName"); | ||
592 | |||
593 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
1 | PINOCCHIO_CHECK_INPUT_ARGUMENT(urdfTree != NULL); |
594 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | details::UrdfVisitorWithRootJoint<Scalar, Options, JointCollectionTpl> visitor( |
595 | model, rootJoint, rootJointName); | ||
596 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (verbose) |
597 | ✗ | visitor.log = &std::cout; | |
598 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | details::parseRootTree(urdfTree.get(), visitor); |
599 | 1 | return model; | |
600 | 1 | } | |
601 | |||
602 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
603 | 1 | ModelTpl<Scalar, Options, JointCollectionTpl> & buildModel( | |
604 | const std::shared_ptr<::urdf::ModelInterface> urdfTree, | ||
605 | const typename ModelTpl<Scalar, Options, JointCollectionTpl>::JointModel & rootJoint, | ||
606 | ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
607 | const bool verbose) | ||
608 | { | ||
609 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
1 | return buildModel(urdfTree, rootJoint, "root_joint", model, verbose); |
610 | } | ||
611 | |||
612 | template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl> | ||
613 | 1 | ModelTpl<Scalar, Options, JointCollectionTpl> & buildModel( | |
614 | const std::shared_ptr<::urdf::ModelInterface> urdfTree, | ||
615 | ModelTpl<Scalar, Options, JointCollectionTpl> & model, | ||
616 | const bool verbose) | ||
617 | { | ||
618 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
1 | PINOCCHIO_CHECK_INPUT_ARGUMENT(urdfTree != NULL); |
619 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | details::UrdfVisitor<Scalar, Options, JointCollectionTpl> visitor(model); |
620 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (verbose) |
621 | ✗ | visitor.log = &std::cout; | |
622 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | details::parseRootTree(urdfTree.get(), visitor); |
623 | 1 | return model; | |
624 | 1 | } | |
625 | |||
626 | } // namespace urdf | ||
627 | } // namespace pinocchio | ||
628 | |||
629 | #endif // ifndef __pinocchio_multibody_parsers_urdf_model_hxx__ | ||
630 |