| Directory: | ./ |
|---|---|
| File: | src/urdf/util.cc |
| Date: | 2025-05-04 12:09:19 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 180 | 228 | 78.9% |
| Branches: | 203 | 502 | 40.4% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright (c) 2016, Joseph Mirabel | ||
| 2 | // Authors: Joseph Mirabel (joseph.mirabel@laas.fr) | ||
| 3 | // | ||
| 4 | |||
| 5 | // Redistribution and use in source and binary forms, with or without | ||
| 6 | // modification, are permitted provided that the following conditions are | ||
| 7 | // met: | ||
| 8 | // | ||
| 9 | // 1. Redistributions of source code must retain the above copyright | ||
| 10 | // notice, this list of conditions and the following disclaimer. | ||
| 11 | // | ||
| 12 | // 2. Redistributions in binary form must reproduce the above copyright | ||
| 13 | // notice, this list of conditions and the following disclaimer in the | ||
| 14 | // documentation and/or other materials provided with the distribution. | ||
| 15 | // | ||
| 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 20 | // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | ||
| 27 | // DAMAGE. | ||
| 28 | |||
| 29 | #include <coal/mesh_loader/loader.h> | ||
| 30 | #include <urdf_parser/urdf_parser.h> | ||
| 31 | |||
| 32 | #include <hpp/pinocchio/device.hh> | ||
| 33 | #include <hpp/pinocchio/humanoid-robot.hh> | ||
| 34 | #include <hpp/pinocchio/joint-collection.hh> | ||
| 35 | #include <hpp/pinocchio/joint.hh> | ||
| 36 | #include <hpp/pinocchio/urdf/util.hh> | ||
| 37 | #include <hpp/util/debug.hh> | ||
| 38 | #include <pinocchio/algorithm/geometry.hpp> | ||
| 39 | #include <pinocchio/algorithm/model.hpp> | ||
| 40 | #include <pinocchio/multibody/geometry.hpp> | ||
| 41 | #include <pinocchio/parsers/srdf.hpp> | ||
| 42 | #include <pinocchio/parsers/urdf.hpp> | ||
| 43 | #include <pinocchio/parsers/utils.hpp> | ||
| 44 | |||
| 45 | namespace hpp { | ||
| 46 | namespace pinocchio { | ||
| 47 | namespace srdf { | ||
| 48 | 12 | void removeCollisionPairs(const Model& model, GeomModel& geom_model, | |
| 49 | const std::string& prefix, std::istream& stream) { | ||
| 50 | // Read xml stream | ||
| 51 | using boost::property_tree::ptree; | ||
| 52 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | ptree pt; |
| 53 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | read_xml(stream, pt); |
| 54 | |||
| 55 | // Iterate over collision pairs | ||
| 56 | 12 | auto last = geom_model.collisionPairs.end(); | |
| 57 |
9/16✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 12 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 69 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 69 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 81 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 69 times.
✓ Branch 23 taken 12 times.
|
81 | for (const ptree::value_type& v : pt.get_child("robot")) { |
| 58 |
2/2✓ Branch 1 taken 27 times.
✓ Branch 2 taken 42 times.
|
69 | if (v.first == "disable_collisions") { |
| 59 | const std::string link1 = | ||
| 60 |
3/6✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 27 times.
✗ Branch 8 not taken.
|
54 | prefix + v.second.get<std::string>("<xmlattr>.link1"); |
| 61 | const std::string link2 = | ||
| 62 |
3/6✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 27 times.
✗ Branch 8 not taken.
|
54 | prefix + v.second.get<std::string>("<xmlattr>.link2"); |
| 63 | |||
| 64 | // Check first if the two bodies exist in model | ||
| 65 |
2/4✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 27 times.
|
27 | if (!model.existBodyName(link1)) { |
| 66 | hppDout(error, link1 << ", " << link2 | ||
| 67 | << ". Link1 does not exist in model. Skip"); | ||
| 68 | ✗ | continue; | |
| 69 | } | ||
| 70 |
2/4✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 27 times.
|
27 | if (!model.existBodyName(link2)) { |
| 71 | hppDout(error, link1 << ", " << link2 | ||
| 72 | << ". Link2 does not exist in model. Skip"); | ||
| 73 | ✗ | continue; | |
| 74 | } | ||
| 75 | |||
| 76 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | const typename Model::FrameIndex frame_id1 = model.getBodyId(link1); |
| 77 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | const typename Model::FrameIndex frame_id2 = model.getBodyId(link2); |
| 78 | |||
| 79 | // Malformed SRDF | ||
| 80 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
|
27 | if (frame_id1 == frame_id2) { |
| 81 | hppDout(info, "Cannot disable collision between " << link1 << " and " | ||
| 82 | << link2); | ||
| 83 | ✗ | continue; | |
| 84 | } | ||
| 85 | |||
| 86 |
1/2✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
|
27 | auto nlast = std::remove_if( |
| 87 | 54 | geom_model.collisionPairs.begin(), last, [&](const auto& colPair) { | |
| 88 | 54 | const auto &ga = geom_model.geometryObjects[colPair.first], | |
| 89 | 54 | &gb = geom_model.geometryObjects[colPair.second]; | |
| 90 | 117 | return ((ga.parentFrame == frame_id1) && | |
| 91 |
4/4✓ Branch 0 taken 27 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 18 times.
|
90 | (gb.parentFrame == frame_id2)) || |
| 92 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 27 times.
|
36 | ((gb.parentFrame == frame_id1) && |
| 93 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
63 | (ga.parentFrame == frame_id2)); |
| 94 | }); | ||
| 95 | 27 | if (last != nlast) { | |
| 96 | hppDout(info, | ||
| 97 | "Remove collision pair (" << link1 << "," << link2 << ")"); | ||
| 98 | } | ||
| 99 | 27 | last = nlast; | |
| 100 |
2/4✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
|
27 | } |
| 101 | } | ||
| 102 |
2/2✓ Branch 2 taken 9 times.
✓ Branch 3 taken 3 times.
|
12 | if (last != geom_model.collisionPairs.end()) { |
| 103 | hppDout(info, "Removing " | ||
| 104 | << std::distance(last, geom_model.collisionPairs.end()) | ||
| 105 | << " collision pairs."); | ||
| 106 |
1/2✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
9 | geom_model.collisionPairs.erase(last, geom_model.collisionPairs.end()); |
| 107 | } | ||
| 108 | 12 | } | |
| 109 | |||
| 110 | 11 | void removeCollisionPairs(const Model& model, GeomModel& geom_model, | |
| 111 | const std::string& prefix, | ||
| 112 | const std::string& filename) { | ||
| 113 | // Check extension | ||
| 114 |
1/2✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
|
11 | const std::string extension = filename.substr(filename.find_last_of('.') + 1); |
| 115 |
2/4✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
|
11 | if (extension != "srdf") { |
| 116 | const std::string exception_message(filename + | ||
| 117 | ✗ | " does not have the right extension."); | |
| 118 | ✗ | throw std::invalid_argument(exception_message); | |
| 119 | } | ||
| 120 | |||
| 121 | // Open file | ||
| 122 |
1/2✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
|
11 | std::ifstream srdf_stream(filename.c_str()); |
| 123 |
2/4✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
|
11 | if (!srdf_stream.is_open()) { |
| 124 | const std::string exception_message(filename + | ||
| 125 | ✗ | " does not seem to be a valid file."); | |
| 126 | ✗ | throw std::invalid_argument(exception_message); | |
| 127 | } | ||
| 128 | |||
| 129 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | removeCollisionPairs(model, geom_model, prefix, srdf_stream); |
| 130 | 11 | } | |
| 131 | |||
| 132 | 1 | void removeCollisionPairsFromXML(const Model& model, GeomModel& geom_model, | |
| 133 | const std::string& prefix, | ||
| 134 | const std::string& xmlString) { | ||
| 135 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | std::istringstream srdf_stream(xmlString); |
| 136 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | removeCollisionPairs(model, geom_model, prefix, srdf_stream); |
| 137 | 1 | } | |
| 138 | } // namespace srdf | ||
| 139 | |||
| 140 | namespace urdf { | ||
| 141 | namespace { | ||
| 142 | #ifdef HPP_DEBUG | ||
| 143 | const bool verbose = true; | ||
| 144 | #else | ||
| 145 | const bool verbose = false; | ||
| 146 | #endif | ||
| 147 | |||
| 148 | 12 | JointPtr_t findSpecialJoint(const HumanoidRobotPtr_t& robot, | |
| 149 | const std::string& linkName) { | ||
| 150 | 12 | return robot->getJointByBodyName(linkName); | |
| 151 | } | ||
| 152 | |||
| 153 | 2 | void setSpecialJoints(const HumanoidRobotPtr_t& robot, std::string prefix) { | |
| 154 |
2/6✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
|
2 | if (!prefix.empty() && *prefix.rbegin() != '/') prefix += "/"; |
| 155 | try { | ||
| 156 |
3/6✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
|
2 | robot->waist(robot->getJointByName(prefix + "root_joint")); |
| 157 | ✗ | } catch (const std::exception&) { | |
| 158 | hppDout(notice, "No waist joint found"); | ||
| 159 | } | ||
| 160 | try { | ||
| 161 |
2/6✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
4 | robot->chest(findSpecialJoint(robot, prefix + "chest")); |
| 162 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | } catch (const std::exception&) { |
| 163 | hppDout(notice, "No chest joint found"); | ||
| 164 | 2 | } | |
| 165 | try { | ||
| 166 |
3/6✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
|
2 | robot->leftWrist(findSpecialJoint(robot, prefix + "l_wrist")); |
| 167 | ✗ | } catch (const std::exception&) { | |
| 168 | hppDout(notice, "No left wrist joint found"); | ||
| 169 | } | ||
| 170 | try { | ||
| 171 |
3/6✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
|
2 | robot->rightWrist(findSpecialJoint(robot, prefix + "r_wrist")); |
| 172 | ✗ | } catch (const std::exception&) { | |
| 173 | hppDout(notice, "No right wrist joint found"); | ||
| 174 | } | ||
| 175 | try { | ||
| 176 |
3/6✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
|
2 | robot->leftAnkle(findSpecialJoint(robot, prefix + "l_ankle")); |
| 177 | ✗ | } catch (const std::exception&) { | |
| 178 | hppDout(notice, "No left ankle joint found"); | ||
| 179 | } | ||
| 180 | try { | ||
| 181 |
3/6✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
|
2 | robot->rightAnkle(findSpecialJoint(robot, prefix + "r_ankle")); |
| 182 | ✗ | } catch (const std::exception&) { | |
| 183 | hppDout(notice, "No right ankle joint found"); | ||
| 184 | } | ||
| 185 | try { | ||
| 186 |
3/6✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
|
2 | robot->gazeJoint(findSpecialJoint(robot, prefix + "gaze")); |
| 187 | ✗ | } catch (const std::exception&) { | |
| 188 | hppDout(notice, "No gaze joint found"); | ||
| 189 | } | ||
| 190 | 2 | } | |
| 191 | |||
| 192 | 2 | void fillGaze(const HumanoidRobotPtr_t robot) { | |
| 193 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | vector3_t dir, origin; |
| 194 | // Gaze direction is defined by the gaze joint local | ||
| 195 | // orientation. | ||
| 196 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | dir[0] = 1; |
| 197 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | dir[1] = 0; |
| 198 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | dir[2] = 0; |
| 199 | // Gaze position should is defined by the gaze joint local | ||
| 200 | // origin. | ||
| 201 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | origin[0] = 0; |
| 202 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | origin[1] = 0; |
| 203 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | origin[2] = 0; |
| 204 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | robot->gaze(dir, origin); |
| 205 | 2 | } | |
| 206 | |||
| 207 | 11 | JointModelVariant buildJoint(const std::string& type) { | |
| 208 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 9 times.
|
11 | if (type == "freeflyer") |
| 209 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | return JointCollection::JointModelFreeFlyer(); |
| 210 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
9 | else if (type == "planar") |
| 211 |
1/2✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
18 | return JointCollection::JointModelPlanar(); |
| 212 | ✗ | else if (type == "prismatic_x") | |
| 213 | ✗ | return JointCollection::JointModelPX(); | |
| 214 | ✗ | else if (type == "prismatic_y") | |
| 215 | ✗ | return JointCollection::JointModelPY(); | |
| 216 | ✗ | else if (type == "translation3d") | |
| 217 | ✗ | return JointCollection::JointModelTranslation(); | |
| 218 | else | ||
| 219 | ✗ | throw std::invalid_argument("Root joint type \"" + type + | |
| 220 | ✗ | "\" is currently not available."); | |
| 221 | } | ||
| 222 | |||
| 223 | 1 | void setPrefix(const std::string& prefix, Model& model, GeomModel& geomModel, | |
| 224 | const JointIndex& idFirstJoint, const FrameIndex& idFirstFrame) { | ||
| 225 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
|
3 | for (JointIndex i = idFirstJoint; i < model.joints.size(); ++i) { |
| 226 | 2 | model.names[i] = prefix + model.names[i]; | |
| 227 | } | ||
| 228 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
|
6 | for (FrameIndex i = idFirstFrame; i < model.frames.size(); ++i) { |
| 229 | 5 | ::pinocchio::Frame& f = model.frames[i]; | |
| 230 | 5 | f.name = prefix + f.name; | |
| 231 | } | ||
| 232 |
1/2✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
|
1 | for (::pinocchio::GeometryObject& go : geomModel.geometryObjects) |
| 233 | ✗ | go.name = prefix + go.name; | |
| 234 | 1 | } | |
| 235 | |||
| 236 | 19 | void setRootJointBounds(Model& model, const JointIndex& rtIdx, | |
| 237 | const std::string& rootType) { | ||
| 238 | 19 | value_type b = std::numeric_limits<value_type>::infinity(); | |
| 239 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 17 times.
|
19 | if (rootType == "freeflyer") { |
| 240 | 2 | const std::size_t idx = model.joints[rtIdx].idx_q(); | |
| 241 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | model.upperPositionLimit.segment<3>(idx).setConstant(+b); |
| 242 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | model.lowerPositionLimit.segment<3>(idx).setConstant(-b); |
| 243 | // Quaternion bounds | ||
| 244 | 2 | b = 1.01; | |
| 245 | 2 | const size_type quat_idx = idx + 3; | |
| 246 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | model.upperPositionLimit.segment<4>(quat_idx).setConstant(+b); |
| 247 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | model.lowerPositionLimit.segment<4>(quat_idx).setConstant(-b); |
| 248 |
2/2✓ Branch 1 taken 9 times.
✓ Branch 2 taken 8 times.
|
17 | } else if (rootType == "planar") { |
| 249 | 9 | const std::size_t idx = model.joints[rtIdx].idx_q(); | |
| 250 |
1/2✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
9 | model.upperPositionLimit.segment<2>(idx).setConstant(+b); |
| 251 |
1/2✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
9 | model.lowerPositionLimit.segment<2>(idx).setConstant(-b); |
| 252 | // Unit complex bounds | ||
| 253 | 9 | b = 1.01; | |
| 254 | 9 | const size_type cplx_idx = idx + 2; | |
| 255 |
1/2✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
9 | model.upperPositionLimit.segment<2>(cplx_idx).setConstant(+b); |
| 256 |
1/2✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
9 | model.lowerPositionLimit.segment<2>(cplx_idx).setConstant(-b); |
| 257 | } | ||
| 258 | 19 | } | |
| 259 | |||
| 260 | 22 | std::string makeModelPath(const std::string& package, const std::string& type, | |
| 261 | const std::string& modelName, | ||
| 262 | const std::string& suffix = "") { | ||
| 263 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
22 | std::stringstream ss; |
| 264 | ss << "package://" << package << "/" << type << "/" << modelName << suffix | ||
| 265 |
9/18✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 22 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 22 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 22 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 22 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 22 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 22 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 22 times.
✗ Branch 26 not taken.
|
22 | << "." << type; |
| 266 |
1/2✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
|
44 | return ss.str(); |
| 267 | 22 | } | |
| 268 | |||
| 269 | template <bool XmlString> | ||
| 270 | 1 | void _removeCollisionPairs(const Model& model, GeomModel& geomModel, | |
| 271 | const std::string& prefix, const std::string& srdf) { | ||
| 272 | hppDout(info, "parsing SRDF string:\n" << srdf); | ||
| 273 | 1 | srdf::removeCollisionPairsFromXML(model, geomModel, prefix, srdf); | |
| 274 | 1 | } | |
| 275 | |||
| 276 | template <> | ||
| 277 | 11 | void _removeCollisionPairs<false>(const Model& model, GeomModel& geomModel, | |
| 278 | const std::string& prefix, | ||
| 279 | const std::string& srdf) { | ||
| 280 | hppDout(info, "parsing SRDF file: " << srdf); | ||
| 281 | 11 | srdf::removeCollisionPairs(model, geomModel, prefix, srdf); | |
| 282 | 11 | } | |
| 283 | |||
| 284 | /// JointPtrType will be a boost or std shared_ptr depending on the | ||
| 285 | /// version of urdfdom. | ||
| 286 | template <typename JointPtrType> | ||
| 287 | 19 | void addMimicJoints(const std::map<std::string, JointPtrType>& joints, | |
| 288 | const std::string& prefix, const DevicePtr_t& robot) { | ||
| 289 | typedef std::map<std::string, JointPtrType> UrdfJointMap_t; | ||
| 290 | 19 | for (typename UrdfJointMap_t::const_iterator _joint = joints.begin(); | |
| 291 |
2/2✓ Branch 3 taken 471 times.
✓ Branch 4 taken 19 times.
|
490 | _joint != joints.end(); ++_joint) { |
| 292 | 471 | const JointPtrType& joint = _joint->second; | |
| 293 |
7/8✓ Branch 1 taken 471 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 197 times.
✓ Branch 5 taken 274 times.
✓ Branch 8 taken 13 times.
✓ Branch 9 taken 184 times.
✓ Branch 10 taken 13 times.
✓ Branch 11 taken 458 times.
|
471 | if (joint && joint->type != ::urdf::Joint::FIXED && joint->mimic) { |
| 294 | 13 | Device::JointLinearConstraint constraint; | |
| 295 |
2/4✓ Branch 3 taken 13 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
|
13 | constraint.joint = robot->getJointByName(prefix + joint->name); |
| 296 |
1/2✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
|
26 | constraint.reference = |
| 297 |
1/2✓ Branch 3 taken 13 times.
✗ Branch 4 not taken.
|
13 | robot->getJointByName(prefix + joint->mimic->joint_name); |
| 298 | 13 | constraint.multiplier = joint->mimic->multiplier; | |
| 299 | 13 | constraint.offset = joint->mimic->offset; | |
| 300 |
1/2✓ Branch 3 taken 13 times.
✗ Branch 4 not taken.
|
13 | robot->addJointConstraint(constraint); |
| 301 | 13 | } | |
| 302 | } | ||
| 303 | 19 | } | |
| 304 | |||
| 305 | template <bool srdfAsXmlString> | ||
| 306 | 38 | void _loadModel(const DevicePtr_t& robot, const FrameIndex& baseFrame, | |
| 307 | const SE3& bMr, std::string prefix, const std::string& rootType, | ||
| 308 | const ::urdf::ModelInterfaceSharedPtr urdfTree, | ||
| 309 | const std::istream& urdfStream, const std::string& srdf) { | ||
| 310 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
|
38 | if (!urdfTree) |
| 311 | ✗ | throw std::invalid_argument( | |
| 312 | "Failed to parse URDF. Use check_urdf command to know what's wrong."); | ||
| 313 | |||
| 314 |
3/6✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 19 times.
✗ Branch 8 not taken.
|
38 | ModelPtr_t model = ModelPtr_t(new Model); |
| 315 | 38 | const JointIndex idFirstJoint = model->joints.size(); | |
| 316 | 38 | const FrameIndex idFirstFrame = model->frames.size(); | |
| 317 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 11 times.
|
38 | if (rootType == "anchor") |
| 318 |
1/2✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
16 | ::pinocchio::urdf::buildModel(urdfTree, *model, verbose); |
| 319 | else | ||
| 320 |
3/6✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 11 times.
✗ Branch 10 not taken.
|
22 | ::pinocchio::urdf::buildModel(urdfTree, buildJoint(rootType), *model, |
| 321 | verbose); | ||
| 322 | |||
| 323 | hppDout(notice, "Finished parsing URDF file."); | ||
| 324 | |||
| 325 |
1/2✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
|
38 | GeomModel geomModel; |
| 326 | |||
| 327 |
1/2✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
|
38 | std::vector<std::string> baseDirs = ::pinocchio::rosPaths(); |
| 328 |
4/8✓ Branch 0 taken 6 times.
✓ Branch 1 taken 13 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
50 | static coal::MeshLoaderPtr loader( |
| 329 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
24 | new coal::CachedMeshLoader(coal::BV_OBBRSS)); |
| 330 |
1/2✓ Branch 3 taken 19 times.
✗ Branch 4 not taken.
|
38 | ::pinocchio::urdf::buildGeom(*model, urdfStream, ::pinocchio::COLLISION, |
| 331 | geomModel, baseDirs, loader); | ||
| 332 |
1/2✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
|
38 | geomModel.addAllCollisionPairs(); |
| 333 | |||
| 334 |
2/2✓ Branch 1 taken 11 times.
✓ Branch 2 taken 6 times.
|
38 | if (!srdf.empty()) { |
| 335 | if (!srdfAsXmlString) | ||
| 336 |
1/2✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
|
22 | ::pinocchio::srdf::loadReferenceConfigurations(*model, srdf, verbose); |
| 337 | else { | ||
| 338 | hppDout(warning, | ||
| 339 | "Neutral configuration won't be extracted from SRDF string."); | ||
| 340 | // TODO : A method getNeutralConfigurationFromSrdfString must be added in | ||
| 341 | // Pinocchio, | ||
| 342 | // similarly to removeCollisionPairsFromSrdf / | ||
| 343 | // removeCollisionPairsFromSrdfString | ||
| 344 | } | ||
| 345 | } | ||
| 346 | |||
| 347 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 18 times.
|
38 | if (!prefix.empty()) { |
| 348 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
2 | if (*prefix.rbegin() != '/') prefix += "/"; |
| 349 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | setPrefix(prefix, *model, geomModel, idFirstJoint, idFirstFrame); |
| 350 | } | ||
| 351 | |||
| 352 | // Update root joint bounds | ||
| 353 |
6/10✓ Branch 1 taken 11 times.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 11 times.
✓ Branch 12 taken 11 times.
✓ Branch 13 taken 8 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
|
38 | assert((rootType == "anchor") || |
| 354 | (model->names[idFirstJoint] == prefix + "root_joint")); | ||
| 355 |
1/2✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
|
38 | setRootJointBounds(*model, idFirstJoint, rootType); |
| 356 | |||
| 357 |
3/6✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 19 times.
✗ Branch 8 not taken.
|
38 | ModelPtr_t m(new Model); |
| 358 |
3/6✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 19 times.
✗ Branch 8 not taken.
|
38 | GeomModelPtr_t gm(new GeomModel); |
| 359 |
1/2✓ Branch 6 taken 19 times.
✗ Branch 7 not taken.
|
38 | ::pinocchio::appendModel(robot->model(), *model, robot->geomModel(), |
| 360 | 38 | geomModel, baseFrame, bMr, *m, *gm); | |
| 361 | 38 | robot->setModel(m); | |
| 362 | 38 | robot->setGeomModel(gm); | |
| 363 | |||
| 364 |
2/2✓ Branch 1 taken 12 times.
✓ Branch 2 taken 7 times.
|
38 | if (!srdf.empty()) { |
| 365 |
1/2✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
|
24 | _removeCollisionPairs<srdfAsXmlString>(robot->model(), robot->geomModel(), |
| 366 | prefix, srdf); | ||
| 367 | } | ||
| 368 | |||
| 369 |
1/2✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
|
38 | robot->createData(); |
| 370 |
1/2✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
|
38 | robot->createGeomData(); |
| 371 | |||
| 372 | // Build mimic joint table. | ||
| 373 |
1/2✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
|
38 | addMimicJoints(urdfTree->joints_, prefix, robot); |
| 374 | |||
| 375 | hppDout(notice, "Finished parsing SRDF file."); | ||
| 376 | 38 | } | |
| 377 | |||
| 378 | } // namespace | ||
| 379 | |||
| 380 | ✗ | void loadRobotModel(const DevicePtr_t& robot, const std::string& rootJointType, | |
| 381 | const std::string& package, const std::string& modelName, | ||
| 382 | const std::string& urdfSuffix, | ||
| 383 | const std::string& srdfSuffix) { | ||
| 384 | ✗ | loadModel(robot, 0, "", rootJointType, | |
| 385 | ✗ | makeModelPath(package, "urdf", modelName, urdfSuffix), | |
| 386 | ✗ | makeModelPath(package, "srdf", modelName, srdfSuffix)); | |
| 387 | } | ||
| 388 | |||
| 389 | 11 | void loadRobotModel(const DevicePtr_t& robot, const FrameIndex& baseFrame, | |
| 390 | const std::string& prefix, const std::string& rootJointType, | ||
| 391 | const std::string& package, const std::string& modelName, | ||
| 392 | const std::string& urdfSuffix, | ||
| 393 | const std::string& srdfSuffix, const SE3& bMr) { | ||
| 394 |
4/12✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 11 taken 11 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 11 times.
✗ Branch 15 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
11 | loadModel(robot, baseFrame, (prefix.empty() ? "" : prefix + "/"), |
| 395 | rootJointType, | ||
| 396 |
2/4✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
|
22 | makeModelPath(package, "urdf", modelName, urdfSuffix), |
| 397 |
2/4✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
|
22 | makeModelPath(package, "srdf", modelName, srdfSuffix), bMr); |
| 398 | 11 | } | |
| 399 | |||
| 400 | 2 | void setupHumanoidRobot(const HumanoidRobotPtr_t& robot, | |
| 401 | const std::string& prefix) { | ||
| 402 | // Look for special joints and attach them to the model. | ||
| 403 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | setSpecialJoints(robot, prefix); |
| 404 | // Fill gaze position and direction. | ||
| 405 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | fillGaze(robot); |
| 406 | 2 | } | |
| 407 | |||
| 408 | ✗ | void loadUrdfModel(const DevicePtr_t& robot, const FrameIndex& baseFrame, | |
| 409 | const std::string& prefix, const std::string& rootJointType, | ||
| 410 | const std::string& package, const std::string& filename, | ||
| 411 | const SE3& bMr) { | ||
| 412 | ✗ | loadModel(robot, baseFrame, (prefix.empty() ? "" : prefix + "/"), | |
| 413 | ✗ | rootJointType, makeModelPath(package, "urdf", filename), "", bMr); | |
| 414 | } | ||
| 415 | |||
| 416 | ✗ | void loadUrdfModel(const DevicePtr_t& robot, const std::string& rootType, | |
| 417 | const std::string& package, const std::string& filename) { | ||
| 418 | ✗ | loadModel(robot, 0, "", rootType, makeModelPath(package, "urdf", filename), | |
| 419 | ""); | ||
| 420 | } | ||
| 421 | |||
| 422 | 17 | void loadModel(const DevicePtr_t& robot, const FrameIndex& baseFrame, | |
| 423 | const std::string& prefix, const std::string& rootType, | ||
| 424 | const std::string& urdfPath, const std::string& srdfPath, | ||
| 425 | const SE3& bMr) { | ||
| 426 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | std::vector<std::string> baseDirs = ::pinocchio::rosPaths(); |
| 427 |
2/4✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 17 times.
✗ Branch 6 not taken.
|
17 | baseDirs.push_back(EXAMPLE_ROBOT_DATA_MODEL_DIR); |
| 428 |
2/4✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 17 times.
✗ Branch 6 not taken.
|
17 | baseDirs.push_back(EXAMPLE_ROBOT_DATA_MODEL_DIR "/../.."); |
| 429 | |||
| 430 | std::string urdfFileName = | ||
| 431 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | ::pinocchio::retrieveResourcePath(urdfPath, baseDirs); |
| 432 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | if (urdfFileName == "") { |
| 433 | ✗ | throw std::invalid_argument(std::string("Unable to retrieve ") + urdfPath); | |
| 434 | } | ||
| 435 | |||
| 436 | 17 | std::string srdfFileName; | |
| 437 |
2/2✓ Branch 1 taken 11 times.
✓ Branch 2 taken 6 times.
|
17 | if (!srdfPath.empty()) { |
| 438 |
1/2✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
|
11 | srdfFileName = ::pinocchio::retrieveResourcePath(srdfPath, baseDirs); |
| 439 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
|
11 | if (srdfFileName == "") { |
| 440 | ✗ | throw std::invalid_argument(std::string("Unable to retrieve ") + | |
| 441 | ✗ | srdfPath); | |
| 442 | } | ||
| 443 | } | ||
| 444 | |||
| 445 | ::urdf::ModelInterfaceSharedPtr urdfTree = | ||
| 446 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
17 | ::urdf::parseURDFFile(urdfFileName); |
| 447 |
1/2✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
|
17 | std::ifstream urdfStream(urdfFileName.c_str()); |
| 448 |
2/4✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 17 times.
✗ Branch 6 not taken.
|
17 | _loadModel<false>(robot, baseFrame, bMr, prefix, rootType, urdfTree, |
| 449 | urdfStream, srdfFileName); | ||
| 450 | 17 | } | |
| 451 | |||
| 452 | 2 | void loadModelFromString(const DevicePtr_t& robot, const FrameIndex& baseFrame, | |
| 453 | const std::string& prefix, const std::string& rootType, | ||
| 454 | const std::string& urdfString, | ||
| 455 | const std::string& srdfString, const SE3& bMr) { | ||
| 456 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | ::urdf::ModelInterfaceSharedPtr urdfTree = ::urdf::parseURDF(urdfString); |
| 457 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | std::istringstream urdfStream(urdfString); |
| 458 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
2 | _loadModel<true>(robot, baseFrame, bMr, prefix, rootType, urdfTree, |
| 459 | urdfStream, srdfString); | ||
| 460 | 2 | } | |
| 461 | |||
| 462 | ✗ | void loadSRDFModel(const DevicePtr_t& robot, std::string prefix, | |
| 463 | const std::string& srdfPath) { | ||
| 464 | ✗ | std::vector<std::string> baseDirs = ::pinocchio::rosPaths(); | |
| 465 | std::string srdfFileName = | ||
| 466 | ✗ | ::pinocchio::retrieveResourcePath(srdfPath, baseDirs); | |
| 467 | ✗ | if (srdfFileName == "") { | |
| 468 | ✗ | throw std::invalid_argument(std::string("Unable to retrieve ") + srdfPath); | |
| 469 | } | ||
| 470 | ✗ | if (!prefix.empty() && *prefix.rbegin() != '/') prefix += "/"; | |
| 471 | |||
| 472 | ✗ | _removeCollisionPairs<false>(robot->model(), robot->geomModel(), prefix, | |
| 473 | srdfFileName); | ||
| 474 | ✗ | ::pinocchio::srdf::loadReferenceConfigurations(robot->model(), srdfFileName, | |
| 475 | verbose); | ||
| 476 | ✗ | robot->createGeomData(); | |
| 477 | } | ||
| 478 | |||
| 479 | ✗ | void loadSRDFModelFromString(const DevicePtr_t& robot, std::string prefix, | |
| 480 | const std::string& srdfString) { | ||
| 481 | ✗ | if (!prefix.empty() && *prefix.rbegin() != '/') prefix += "/"; | |
| 482 | ✗ | _removeCollisionPairs<true>(robot->model(), robot->geomModel(), prefix, | |
| 483 | srdfString); | ||
| 484 | ✗ | robot->createGeomData(); | |
| 485 | } | ||
| 486 | } // end of namespace urdf. | ||
| 487 | } // end of namespace pinocchio. | ||
| 488 | } // end of namespace hpp. | ||
| 489 |