- Aldebaran documentation |
- C++ Libraries |
- index

libalmath 2.8.7.4

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
urdf.h
Go to the documentation of this file.
1 /*
2 * Copyright 2015 Aldebaran. All rights reserved.
3 *
4 */
5
6 #ifndef LIB_ALMATH_SCENEGRAPH_URDF_H
7 #define LIB_ALMATH_SCENEGRAPH_URDF_H
8
9 #include <almath/api.h>
10 #include <string>
11 #include <iosfwd>
12 #include <memory>
13 #include <array>
14 #include <boost/property_tree/ptree.hpp>
15 #include <boost/optional.hpp>
16 #include <boost/variant.hpp>
17 #include <boost/range/adaptor/map.hpp>
18 #include <boost/range/adaptor/filtered.hpp>
19 #include <boost/function/function_fwd.hpp>
20 #include <boost/ref.hpp>
21 #include <boost/tokenizer.hpp>
22 #include <boost/multi_index_container.hpp>
23 #include <boost/multi_index/ordered_index.hpp>
24 #include <boost/multi_index/identity.hpp>
25 #include <boost/multi_index/mem_fun.hpp>
26 #include <boost/multi_index/global_fun.hpp>
27 #include <boost/multi_index/sequenced_index.hpp>
28 #include <set>
29 #include <vector>
30 #include <type_traits>
31 #include <boost/property_tree/stream_translator.hpp>
32
33 namespace boost {
34 namespace property_tree {
35
36 // hack around ptree bug #10188 [1]: for floating point numbers they don't
37 // serialize with enough precision:
38 // they use digits10+1 instead of max_digits10
39 // [1] https://svn.boost.org/trac/boost/ticket/10188
40 template <typename Ch, typename Traits>
41 struct customize_stream<Ch, Traits, double, void> {
42 static void insert(std::basic_ostream<Ch, Traits> &s, const double &e) {
43 s.precision(std::numeric_limits<double>::max_digits10);
44 s << e;
45 }
46 static void extract(std::basic_istream<Ch, Traits> &s, double &e) {
47 s >> e;
48 if (!s.eof()) {
49 s >> std::ws;
50 }
51 }
52 };
53 }
54 }
55
56 namespace AL {
57
58 namespace urdf {
59
60 typedef boost::property_tree::ptree ptree;
61
62 namespace detail {
63 class RobotTreeP;
64 }
65
66 typedef std::array<double, 3> Array3d;
67
68 inline bool is_zero(const Array3d &a) {
69 return (a[0] == 0) && (a[1] == 0) && (a[2] == 0);
70 }
71
72 inline bool is_ones(const Array3d &a) {
73 return (a[0] == 1) && (a[1] == 1) && (a[2] == 1);
74 }
75
76 class Pose;
77
78 // return the name attribute of a joint or link element
79 ALMATH_API std::string name(const ptree &pt);
80
81 // return the parent link of a joint element
82 ALMATH_API std::string parent_link(const ptree &pt);
83
84 // return the child link of a joint element
85 ALMATH_API std::string child_link(const ptree &pt);
86
87 // A parser for urdf xml files [1].
88 //
89 // Contrary to the urdf parser from ROS [2], [3], this parser:
90 //
91 // * preserves joint ordering defined in XML file. This is useful if one
92 // wants to use this ordering to define the joint indexes in a
93 // state vector.
94 //
95 // * provides access to the raw XML elements, so that you can leverage the
96 // parser to handle unofficial URDF extensions and
97 // to modify the XML tree and write it back while altering the document as
98 // little as possible.
99 //
100 // * does not systematically convert roll-pitch-yaw angles to quaternions,
101 // which saves us some bugs and better fits the "alter the document as
102 // little as possible" philosophy.
103 //
104 // [1] http://wiki.ros.org/urdf/XML
105 // [2] https://github.com/ros/robot_model
106 // [3] https://github.com/ros/urdfdom_headers
107 //
108 // The UrdfTree class acts as an index for the boost::property_tree of the
109 // (URDF) XML document.
110 // Given the ptree of the robot XML element, it traverses the tree and
111 // indexes the ptree elements for the URDF joints and links.
112 //
113 // The class is akin to a set of iterators: it does not copy nor own the
114 // XML tree, and may be invalidated if the XML tree changes.
115 //
116 // The user shall ensure that the XML root and the joint and link ptree
117 // elements stay alive and valid for the lifetime of this RobotTree.
118 // For instance the user may use direct access to the ptree elements to alter
119 // the mass of a link, but shall no delete the link, otherwise calls to
120 // RobotTree::link("my_link_name") would use dandling pointers and return
121 // invalid references.
122 //
123 // On the other hand, some RobotTree functions enable the safe modification or
124 // removal of joints and links.
125 class ALMATH_API RobotTree {
126 public:
127 // Read a XML tree given the robot element.
128 // The ptree is not copied, a reference is kept instead.
129 // The user shall ensure that the reference is valid for the whole life
130 // of the RobotTree object.
131 RobotTree(ptree &robot);
132 ~RobotTree();
133 RobotTree(RobotTree const &) = delete;
134 void operator=(RobotTree const &other) = delete;
135
136 const ptree &link(const std::string &name) const;
137 ptree &link(const std::string &name);
138
139 const ptree &joint(const std::string &name) const;
140 ptree &joint(const std::string &name);
141
142 const std::string &root_link() const;
143
144 // If there is a single root joint, remove it and its parent link, throw otherwise.
145 //
146 // References and iterators to the removed link and joint are invalidated.
147 void rm_root_joint();
148
149 // If the given joint is a leaf in the kinematic tree,
150 // remove it and its child link, throw otherwise.
151 //
152 // References and iterators to the removed link and joint are invalidated.
153 void rm_leaf_joint(const std::string &name);
154
155 // Change the root link frame of reference.
156 //
157 // Each urdf link has an implicitly defined frame of reference with respect
158 // to which the pose of the link children elements (inertia, collisions,
159 // visuals) and joints are defined.
160 //
161 // This function changes the root link frame of reference, while updating
162 // all its children elements and joints accordingly so that the physical
163 // system being described does not change.
164 //
165 // The function takes one argument "pose" which is used to define the
166 // transform from the old frame of reference of the new one according to
167 // the formula:
168 //
169 // point_in_new_frame = pose * point_in_old_frame
170 //
171 // children elements and joints poses are updated using:
172 //
173 // child_pose_in_new_frame = pose.inverse() * child_pose_in_old_frame
174 //
175 // Note: changing the frame of reference of a link which is not the root one
176 // would also be possible, but only to some extent since its origin must
177 // lie on the parent joint axis.
178 void transport_root_link_frame(const Pose &pose);
179
180 // Modify the kinematic tree so that the given link is the root without
181 // changing the physical meaning of the described system.
182 //
183 // Flips all the joints on the path between the old and the new root.
184 //
185 // Throws is there is a multi-dof joint on the path, because flipping it
186 // would change the joint-space parametrization.
187
188 // Change the frame of reference of the links involved so that its
189 // origin lies on the parent joint axis.
190 //
191 // Let consider a root link "a" with children links "b" and "c" and
192 // joints "ab" and "bc".
193 //
194 // The kinematic tree can be written as: a --ab--> b
195 // +-ac--> c
196 //
197 // The frame may look like:
198 // / \ .
199 // / \ .
200 // / \ / / .
201 // / \ / / .
202 // --/ \/ /--/ \/ /-- .
203 // __________/ ab / \ b / .
204 // / / \ / .
205 // / a |_ / .
206 // / \ / __________/ .
207 // / \ / / .
208 // --/ \/ /--/ \/ /-- .
209 // / c / \ ac/ .
210 // / / \ / .
211 // \ / .
212 // \ / .
213 //
214 // After calling define_as_root_link("b")
215 // * the kinematic tree can be written as
216 // b --ab--> a --ac--> c
217 // * the reference frame of "b" and "c" are unchanged
218 // * the reference frame of "a" moved to joint "ab" frame, so as to lie
219 // on joint "ab" axis.
220 // * joint "ab" origin pose is now defined with respecte to link "b"
221 // frame and is thus the identity
222 // * joint "ac" origin pose has been updated to acount fot the
223 //
224 // The frames look like:
225 // / \ .
226 // / \ .
227 // / \ / / .
228 // / \ / / .
229 // --/ \/ /--/ \/ /-- .
230 // __________/ a / \ b / == ba .
231 // / / \ / .
232 // / / .
233 // / \ / __________/ .
234 // / \ / / .
235 // --/ \/ /--/ \/ /-- .
236 // / c / \ ac/ .
237 // / / \ / .
238 // \ / .
239 // \ / .
240 void define_as_root_link(const std::string &name);
241
242 class JointConstVisitor {
243 public:
244 // a false return value stops the traversal for the current branch
245 virtual bool discover(const ptree &) { return true; }
246 virtual void finish(const ptree &) {}
247 };
248 class JointVisitor {
249 public:
250 virtual bool discover(ptree &) { return true; }
251 virtual void finish(ptree &) {}
252 };
253
254 // Traverse the kinematic tree with a depth first traversal.
255 // Siblings joints are visited using the ordering from the urdf file.
256 void traverse_joints(JointConstVisitor &visitor) const;
257 void traverse_joints(JointVisitor &visitor);
258
259 bool is_mimic_tree_flat() const;
260
261 private:
262 std::unique_ptr<detail::RobotTreeP> _p;
263 };
264
265 typedef RobotTree::JointConstVisitor JointConstVisitor;
266 typedef RobotTree::JointVisitor JointVisitor;
267
268 // Convenience wrapper classes around URDF ptree elements
269
270 // helper to convert ptree to/from an array of floating point numbers
271 template <typename Scalar, std::size_t N>
272 struct ScalarArrayTranslator {
273 typedef std::string internal_type;
274 typedef std::array<Scalar, N> external_type;
275 static_assert(std::is_scalar<Scalar>::value,
276 "ScalarArrayTranslator requires a scalar");
277 boost::optional<external_type> get_value(const internal_type &str) {
278 // str is expected to hold N floating point numbers.
279 // let split it into N strings, then use the usual boost::property_tree
280 // translator to convert each substring into a Scalar.
281 // In case of failure, return an uninitialized boost::optional, like
282 // boost::property_tree does itself.
283 boost::tokenizer<> tok(
284 str, boost::char_delimiters_separator<char>(false, "", " \t\n\v\f\r"));
285 boost::optional<Scalar> d;
286 // note: maybe the tr variable could be made static const?
287 typename
288 boost::property_tree::translator_between<internal_type, Scalar>::type tr;
289 external_type x;
290 boost::tokenizer<>::iterator beg = tok.begin();
291 size_t i = 0;
292 for (; beg != tok.end() && i < N; ++beg, ++i) {
293 d = tr.get_value(*beg);
294 if (!d) return boost::optional<external_type>();
295 x[i] = *d;
296 }
297 if (i != N || beg != tok.end())
298 return boost::optional<external_type>();
299 return boost::optional<external_type>(x);
300 }
301
302 boost::optional<internal_type> put_value(const external_type &v) {
303 // note: maybe the tr variable could be made static const?
304 typename
305 boost::property_tree::translator_between<internal_type, Scalar>::type tr;
306 std::ostringstream ss;
307 if (N > 0u)
308 ss << *tr.put_value(v[0]);
309 for (auto i=1u; i < N; ++i) {
310 ss << " " << *tr.put_value(v[i]);
311 }
312 return ss.str();
313 }
314 };
315
316 using Array3dTranslator = ScalarArrayTranslator<double, 3>;
317
318 // Models an URDF pose/transform ("origin" XML element)
319 class ALMATH_API Pose {
320 public:
321 Pose(const Array3d &xyz, const Array3d &rpy) : _xyz(xyz), _rpy(rpy) {}
322 Pose() : Pose({{0, 0, 0}}, {{0, 0, 0}}) {}
323 const Array3d &xyz() const { return _xyz; }
324 const Array3d &rpy() const { return _rpy; }
325 Pose inverse() const;
326 ALMATH_API friend Pose operator*(const Pose &lhs, const Pose &rhs);
327
328 static Pose from_ptree(const ptree &pt);
329 static Pose from_ptree(const boost::optional<const ptree &> &pt);
330 boost::optional<ptree> to_ptree() const;
331
332 private:
333 Array3d _xyz;
334 Array3d _rpy;
335 };
336
337 inline bool operator==(const Pose &lhs, const Pose &rhs) {
338 return (lhs.xyz() == rhs.xyz()) && (lhs.rpy() == rhs.rpy());
339 }
340 inline bool operator!=(const Pose &lhs, const Pose &rhs) {
341 return !(lhs == rhs);
342 }
343
344 inline bool is_identity(const Pose &p) {
345 return is_zero(p.xyz()) && is_zero(p.rpy());
346 }
347
348 // Convenience wrapper around an URDF mimic XML element
349 class ALMATH_API Mimic {
350 public:
351 const ptree &pt;
352 Mimic(const ptree &pt);
353 std::string joint() const;
354 double multiplier() const;
355 double offset() const;
356 };
357
358 // Convenience wrapper around an URDF joint XML element
359 class ALMATH_API Joint {
360 public:
361 enum Type { revolute, continuous, prismatic, fixed, floating, planar };
362 const ptree &pt;
363 Joint(const ptree &pt);
364 std::string name() const;
365 Type type() const;
366 std::string parent_link() const;
367 std::string child_link() const;
368 Pose origin() const;
369 Array3d axis() const;
370
371 // Return the (lower, upper) limits pair.
372 //
373 // If both limits are missing, the pair is uninitialized
374 // If one of them is missing, it is defaulted to 0.
375 // This behavior is slightly different from the
376 // http://wiki.ros.org/urdf/XML/joint spec.
377 // Beware, there is no warranty that lower <= upper.
378 boost::optional<std::pair<double, double>> limit_lower_upper() const;
379 boost::optional<double> limit_effort() const;
380 boost::optional<double> limit_velocity() const;
381 boost::optional<Mimic> mimic() const;
382 };
383
384 // Convenience wrapper around an URDF inertial XML element
385 class ALMATH_API Inertial {
386 public:
387 const ptree &pt;
388 Inertial(const ptree &pt);
389 Pose origin() const;
390 double mass() const;
391 double ixx() const;
392 double ixy() const;
393 double ixz() const;
394 double iyy() const;
395 double iyz() const;
396 double izz() const;
397 };
398
399 class ALMATH_API Box {
400 public:
401 const ptree &pt;
402 Box(const ptree &pt);
403 Array3d size();
404 };
405
406 // z-axis cylinder, centered at the origin
407 class ALMATH_API Cylinder {
408 public:
409 const ptree &pt;
410 Cylinder(const ptree &pt);
411 double radius();
412 double length();
413 };
414
415 class ALMATH_API Sphere {
416 public:
417 const ptree &pt;
418 Sphere(const ptree &pt);
419 double radius();
420 };
421
422 class ALMATH_API Mesh {
423 public:
424 const ptree &pt;
425 Mesh(const ptree &pt);
426 std::string filename() const;
427 // Note: scale element is optional. When absent, we return (1, 1, 1)
428 Array3d scale() const;
429 };
430
431 using Geometry = boost::variant<Box, Cylinder, Sphere, Mesh>;
432
433 class ALMATH_API Visual {
434 public:
435 const ptree &pt;
436 Visual(const ptree &pt);
437 Pose origin() const;
438 Geometry geometry() const;
439
440 static bool is_visual(const ptree::value_type &val);
441 };
442
443 // Convenience wrapper around an URDF link XML element
444 class ALMATH_API Link {
445 public:
446 const ptree &pt;
447 Link(const ptree &pt);
448 std::string name() const;
449 boost::optional<Inertial> inertial() const;
450
451 private:
452 // helper: return the range of visual ptree children
453 inline auto _visual_ptrees() const
454 -> boost::select_second_const_range<
455 decltype(boost::adaptors::filter(pt, Visual::is_visual))> {
456 return boost::adaptors::values(
457 boost::adaptors::filter(pt, Visual::is_visual));
458 }
459 // helper, call the Visual ctor
460 static inline Visual _makeVisual(const ptree &pt) { return Visual(pt); }
461
462 public:
463 // return the range of Visual children
464 inline auto visuals() const
465 -> boost::transformed_range<
466 decltype(&_makeVisual),
467 const decltype(_visual_ptrees())> {
468 return boost::adaptors::transform(_visual_ptrees(), &_makeVisual);
469 }
470 };
471
472 // Utils
473
474 // make the type of the joint named "name" equal to "fixed",
475 // and erase the joint axis and limits, if any.
476 ALMATH_API void makeJointFixed(RobotTree &parser, const std::string &name);
477
478 // make the type of the joint named "name" equal to "floating",
479 // and erase the joint axis and limits, if any.
480 ALMATH_API void makeJointFloating(RobotTree &parser, const std::string &name);
481
482 // apply makeJointFixed to all joints of type "continuous".
483 // Return the names of the joints whose type was changed.
484 ALMATH_API
485 std::vector<std::string> makeContinuousJointsFixed(RobotTree &parser);
486
487 // Squash a joint's child link mass into its parent link mass.
488 // The child link mass element (if any) is erased.
489 ALMATH_API void squashJointMass(RobotTree &parser, const std::string &name);
490
491 // apply squashJointMass to all fixed joints.
492 ALMATH_API void squashFixedJointsMass(RobotTree &parser);
493
494 // Squash all fixed joint's child link mass into their parent link mass and
495 // then convert all massless joints into fixed joints.
496 // The point is to avoid massless mobile joints, which have no physical
497 // meaning.
498 // Return the names of the joints whose type was changed.
499 ALMATH_API std::vector<std::string> makeMasslessJointsFixed(RobotTree &parser);
500
501 // Remove kinematic tree subtrees starting at joints for which predicate
502 // returns true.
503 //
504 // Return the names of the removed joints.
505 //
506 // For instance, to cut the tree at joints whose name ends with "_useless",
507 // one could do:
508 //
509 // ptree robot = ...
510 // auto pred = [](const ptree &joint) {
511 // return boost::regex_match(urdf::name(joint), boost::regex(".*_useless$"));
512 // };
513 // urdf::removeSubTreeIfJoint(urdf::RobotTree(robot), pred);
514 ALMATH_API std::vector<std::string> removeSubTreeIfJoint(
515 RobotTree &parser,
516 std::function<bool(const ptree &joint)> pred);
517
518 // a visitor which prints the URDF kinematic tree as a dot graph
519 // when visiting its joints.
520 class ALMATH_API UrdfDotPrinterVisitor : public RobotTree::JointConstVisitor {
521 const char tab;
522 int depth;
523 bool do_indent;
524 std::ostream &os;
525
526 public:
527 UrdfDotPrinterVisitor(std::ostream &os);
528
529 public:
530 bool discover(const ptree &joint);
531 void finish(const ptree &joint);
532 };
533
534
535 ALMATH_API void put_name(ptree &pt, const std::string &name);
536
537 namespace robot {
538
539 // Replace each mesh and texture filename by the result of applying op() to it.
540 //
541 // For instance, to replace .mesh extensions by .dae, one could do:
542 //
543 // ptree robot = ...
544 // auto op = [](std::string in) {
545 // return boost::regex_replace(in, boost::regex("\\.mesh$"), ".dae");};
546 // urdf::robot::transform_filenames(robot, op);
547 ALMATH_API void transform_filenames(
548 ptree &robot, std::function<std::string(std::string)> op);
549 }
550 }
551 }
552
553 #endif
AL::urdf::RobotTree::JointConstVisitor
Definition: urdf.h:242
AL::urdf::ScalarArrayTranslator::external_type
std::array< Scalar, N > external_type
Definition: urdf.h:274
AL::urdf::ScalarArrayTranslator::put_value
boost::optional< internal_type > put_value(const external_type &v)
Definition: urdf.h:302
AL::urdf::Box::pt
const ptree & pt
Definition: urdf.h:401
AL::urdf::squashJointMass
ALMATH_API void squashJointMass(RobotTree &parser, const std::string &name)
AL::urdf::name
ALMATH_API std::string name(const ptree &pt)
AL::urdf::Joint
Definition: urdf.h:359
AL::urdf::put_name
ALMATH_API void put_name(ptree &pt, const std::string &name)
AL::urdf::makeMasslessJointsFixed
ALMATH_API std::vector< std::string > makeMasslessJointsFixed(RobotTree &parser)
AL::urdf::squashFixedJointsMass
ALMATH_API void squashFixedJointsMass(RobotTree &parser)
AL::urdf::ScalarArrayTranslator
Definition: urdf.h:272
AL::urdf::operator==
bool operator==(const Pose &lhs, const Pose &rhs)
Definition: urdf.h:337
AL::urdf::Pose
Definition: urdf.h:319
AL::urdf::Geometry
boost::variant< Box, Cylinder, Sphere, Mesh > Geometry
Definition: urdf.h:431
AL::urdf::Sphere
Definition: urdf.h:415
AL::urdf::Mimic::pt
const ptree & pt
Definition: urdf.h:351
AL::urdf::Sphere::pt
const ptree & pt
Definition: urdf.h:417
AL::urdf::Array3d
std::array< double, 3 > Array3d
Definition: urdf.h:66
AL::urdf::parent_link
ALMATH_API std::string parent_link(const ptree &pt)
AL::urdf::is_identity
bool is_identity(const Pose &p)
Definition: urdf.h:344
AL::urdf::Visual
Definition: urdf.h:433
AL::urdf::removeSubTreeIfJoint
ALMATH_API std::vector< std::string > removeSubTreeIfJoint(RobotTree &parser, std::function< bool(const ptree &joint)> pred)
AL::urdf::Visual::is_visual
static bool is_visual(const ptree::value_type &val)
AL::urdf::operator!=
bool operator!=(const Pose &lhs, const Pose &rhs)
Definition: urdf.h:340
AL::urdf::Joint::pt
const ptree & pt
Definition: urdf.h:362
AL::urdf::RobotTree::JointVisitor::finish
virtual void finish(ptree &)
Definition: urdf.h:251
AL::urdf::ScalarArrayTranslator::get_value
boost::optional< external_type > get_value(const internal_type &str)
Definition: urdf.h:277
AL::urdf::Mimic
Definition: urdf.h:349
qi::geometry::inverse
Transform inverse(const Transform &tf)
Definition: qigeometry.h:120
AL::urdf::Inertial::pt
const ptree & pt
Definition: urdf.h:387
AL::urdf::Link
Definition: urdf.h:444
AL::urdf::Joint::Type
Type
Definition: urdf.h:361
AL::urdf::Box
Definition: urdf.h:399
boost::property_tree::customize_stream< Ch, Traits, double, void >::extract
static void extract(std::basic_istream< Ch, Traits > &s, double &e)
Definition: urdf.h:46
AL::urdf::JointVisitor
RobotTree::JointVisitor JointVisitor
Definition: urdf.h:266
AL::urdf::RobotTree::JointVisitor::discover
virtual bool discover(ptree &)
Definition: urdf.h:250
AL::urdf::Mesh
Definition: urdf.h:422
AL::urdf::child_link
ALMATH_API std::string child_link(const ptree &pt)
AL::urdf::RobotTree::JointConstVisitor::discover
virtual bool discover(const ptree &)
Definition: urdf.h:245
boost::property_tree::customize_stream< Ch, Traits, double, void >::insert
static void insert(std::basic_ostream< Ch, Traits > &s, const double &e)
Definition: urdf.h:42
AL::urdf::Pose::Pose
Pose()
Definition: urdf.h:322
AL::urdf::makeJointFloating
ALMATH_API void makeJointFloating(RobotTree &parser, const std::string &name)
AL::urdf::makeJointFixed
ALMATH_API void makeJointFixed(RobotTree &parser, const std::string &name)
qi::geometry::operator*
Transform operator*(const Transform &lhs, const Transform &rhs)
Definition: qigeometry.h:96
AL::urdf::RobotTree::JointConstVisitor::finish
virtual void finish(const ptree &)
Definition: urdf.h:246
AL::urdf::Cylinder
Definition: urdf.h:407
AL::urdf::Inertial
Definition: urdf.h:385
AL::urdf::makeContinuousJointsFixed
ALMATH_API std::vector< std::string > makeContinuousJointsFixed(RobotTree &parser)
AL::urdf::robot::transform_filenames
ALMATH_API void transform_filenames(ptree &robot, std::function< std::string(std::string)> op)
AL::urdf::RobotTree::JointVisitor
Definition: urdf.h:248
AL::urdf::ptree
boost::property_tree::ptree ptree
Definition: urdf.h:60
AL::urdf::Link::pt
const ptree & pt
Definition: urdf.h:446
AL::urdf::RobotTree
Definition: urdf.h:125
AL::urdf::Mesh::pt
const ptree & pt
Definition: urdf.h:424
AL::urdf::Pose::Pose
Pose(const Array3d &xyz, const Array3d &rpy)
Definition: urdf.h:321
AL::urdf::UrdfDotPrinterVisitor
Definition: urdf.h:520
AL::urdf::is_ones
bool is_ones(const Array3d &a)
Definition: urdf.h:72
AL::urdf::Visual::pt
const ptree & pt
Definition: urdf.h:435
AL::urdf::ScalarArrayTranslator::internal_type
std::string internal_type
Definition: urdf.h:273
AL::urdf::JointConstVisitor
RobotTree::JointConstVisitor JointConstVisitor
Definition: urdf.h:265
AL::urdf::is_zero
bool is_zero(const Array3d &a)
Definition: urdf.h:68
AL::urdf::Link::visuals
auto visuals() const -> boost::transformed_range< decltype(&_makeVisual), const decltype(_visual_ptrees())>
Definition: urdf.h:464
AL::urdf::Cylinder::pt
const ptree & pt
Definition: urdf.h:409