| 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 |