GCC Code Coverage Report


Directory: ./
File: src/robot.impl.cc
Date: 2024-12-13 15:50:05
Exec Total Coverage
Lines: 123 743 16.6%
Branches: 142 1942 7.3%

Line Branch Exec Source
1 // Copyright (C) 2009, 2010 by Florent Lamiraux, Thomas Moulard, JRL.
2 //
3
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // 1. Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 // DAMAGE.
27 //
28 // This software is provided "as is" without warranty of any kind,
29 // either expressed or implied, including but not limited to the
30 // implied warranties of fitness for a particular purpose.
31 //
32 // See the COPYING file for more information.
33
34 #include "robot.impl.hh"
35
36 #include <coal/BVH/BVH_model.h>
37 #include <coal/shape/geometric_shapes.h>
38
39 #include <hpp/corbaserver/server-plugin.hh>
40 #include <hpp/core/config-validations.hh>
41 #include <hpp/core/configuration-shooter.hh>
42 #include <hpp/core/distance-between-objects.hh>
43 #include <hpp/core/problem.hh>
44 #include <hpp/core/weighed-distance.hh>
45 #include <hpp/pinocchio/body.hh>
46 #include <hpp/pinocchio/center-of-mass-computation.hh>
47 #include <hpp/pinocchio/collision-object.hh>
48 #include <hpp/pinocchio/configuration.hh>
49 #include <hpp/pinocchio/device.hh>
50 #include <hpp/pinocchio/frame.hh>
51 #include <hpp/pinocchio/fwd.hh>
52 #include <hpp/pinocchio/humanoid-robot.hh>
53 #include <hpp/pinocchio/joint-collection.hh>
54 #include <hpp/pinocchio/joint.hh>
55 #include <hpp/pinocchio/liegroup-element.hh>
56 #include <hpp/pinocchio/liegroup.hh>
57 #include <hpp/pinocchio/urdf/util.hh>
58 #include <hpp/util/debug.hh>
59 #include <hpp/util/exception-factory.hh>
60 #include <iostream>
61 #include <pinocchio/fwd.hpp>
62 #include <pinocchio/multibody/fcl.hpp>
63 #include <pinocchio/multibody/geometry.hpp>
64 #include <pinocchio/multibody/model.hpp>
65
66 #include "hpp/pinocchio_idl/robots-fwd.hh"
67 #include "tools.hh"
68
69 namespace hpp {
70 namespace corbaServer {
71 namespace impl {
72 using pinocchio::Data;
73 using pinocchio::FrameIndex;
74 using pinocchio::JointIndex;
75 using pinocchio::Model;
76
77 namespace {
78 using CORBA::Long;
79 using CORBA::ULong;
80 const ::pinocchio::FrameType JOINT_FRAME =
81 (::pinocchio::FrameType)(::pinocchio::JOINT | ::pinocchio::FIXED_JOINT);
82
83 static void localSetJointBounds(const JointPtr_t& joint, vector_t jointBounds) {
84 static const value_type inf = std::numeric_limits<value_type>::infinity();
85 if (jointBounds.size() % 2 == 1) {
86 HPP_THROW(std::invalid_argument, "Expect a vector of even size");
87 }
88 for (std::size_t i = 0; i < (std::size_t)jointBounds.size() / 2; i++) {
89 value_type& vMin = jointBounds[2 * i];
90 value_type& vMax = jointBounds[2 * i + 1];
91 if (vMin > vMax) {
92 vMin = -inf;
93 vMax = inf;
94 }
95 }
96 Eigen::Map<vector_t, Eigen::Unaligned, Eigen::InnerStride<2> > lower(
97 &jointBounds[0], (jointBounds.size() + 1) / 2);
98 Eigen::Map<vector_t, Eigen::Unaligned, Eigen::InnerStride<2> > upper(
99 &jointBounds[1], (jointBounds.size()) / 2);
100 joint->lowerBounds(lower);
101 joint->upperBounds(upper);
102 }
103
104 static floatSeq* localGetJointBounds(const JointPtr_t& joint) {
105 std::size_t jointNbDofs = joint->configSize();
106 floatSeq* ret = new floatSeq;
107 ret->length((ULong)(2 * jointNbDofs));
108 for (std::size_t iDof = 0; iDof < jointNbDofs; iDof++) {
109 if (joint->isBounded(iDof)) {
110 (*ret)[(ULong)(2 * iDof)] = joint->lowerBound(iDof);
111 (*ret)[(ULong)(2 * iDof + 1)] = joint->upperBound(iDof);
112 } else {
113 (*ret)[(ULong)(2 * iDof)] = 1;
114 (*ret)[(ULong)(2 * iDof + 1)] = 0;
115 }
116 }
117 return ret;
118 }
119 } // end of namespace.
120
121 // --------------------------------------------------------------------
122
123
1/2
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
16 Robot::Robot() : server_(NULL) {}
124
125 // --------------------------------------------------------------------
126
127 98 core::ProblemSolverPtr_t Robot::problemSolver() {
128 98 return server_->problemSolver();
129 }
130
131 // --------------------------------------------------------------------
132
133 6 void Robot::createRobot(const char* inRobotName) {
134
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 std::string robotName(inRobotName);
135
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 DevicePtr_t robot(problemSolver()->createRobot(robotName));
136
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 problemSolver()->robot(robot);
137 6 }
138
139 // --------------------------------------------------------------------
140
141 7 char* Robot::getRobotName() {
142
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
7 DevicePtr_t robot = getRobotOrThrow(problemSolver());
143
1/2
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
14 return c_str(robot->name());
144 7 }
145
146 // --------------------------------------------------------------------
147
148 void Robot::loadRobotModel(const char* robotName, const char* rootJointType,
149 const char* urdfName, const char* srdfName) {
150 try {
151 pinocchio::DevicePtr_t device(problemSolver()->createRobot(robotName));
152 hpp::pinocchio::urdf::loadModel(device, 0, "", std::string(rootJointType),
153 std::string(urdfName),
154 std::string(srdfName));
155 // Add device to the planner
156 problemSolver()->robot(device);
157 } catch (const std::exception& exc) {
158 hppDout(error, exc.what());
159 throw hpp::Error(exc.what());
160 }
161 }
162
163 // --------------------------------------------------------------------
164
165 void Robot::loadHumanoidModel(const char* robotName, const char* rootJointType,
166 const char* urdfName, const char* srdfName) {
167 try {
168 pinocchio::HumanoidRobotPtr_t robot(
169 pinocchio::HumanoidRobot::create(robotName));
170 hpp::pinocchio::urdf::loadModel(robot, 0, "", std::string(rootJointType),
171 std::string(urdfName),
172 std::string(srdfName));
173 hpp::pinocchio::urdf::setupHumanoidRobot(robot);
174 // Add robot to the planner
175 problemSolver()->robot(robot);
176 } catch (const std::exception& exc) {
177 hppDout(error, exc.what());
178 throw hpp::Error(exc.what());
179 }
180 }
181
182 // --------------------------------------------------------------------
183
184 2 void Robot::loadRobotModelFromString(const char* robotName,
185 const char* rootJointType,
186 const char* urdfString,
187 const char* srdfString) {
188 try {
189
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
4 pinocchio::DevicePtr_t device(problemSolver()->createRobot(robotName));
190
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
6 hpp::pinocchio::urdf::loadModelFromString(
191
3/6
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
6 device, 0, "", std::string(rootJointType), std::string(urdfString),
192
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
4 std::string(srdfString));
193 // Add device to the planner
194
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 problemSolver()->robot(device);
195
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 } catch (const std::exception& exc) {
196 hppDout(error, exc.what());
197 throw hpp::Error(exc.what());
198 }
199 2 }
200
201 // --------------------------------------------------------------------
202
203 void Robot::loadHumanoidModelFromString(const char* robotName,
204 const char* rootJointType,
205 const char* urdfString,
206 const char* srdfString) {
207 try {
208 pinocchio::HumanoidRobotPtr_t robot(
209 pinocchio::HumanoidRobot::create(robotName));
210 hpp::pinocchio::urdf::loadModelFromString(
211 robot, 0, "", std::string(rootJointType), std::string(urdfString),
212 std::string(srdfString));
213 hpp::pinocchio::urdf::setupHumanoidRobot(robot);
214 // Add robot to the planner
215 problemSolver()->robot(robot);
216 } catch (const std::exception& exc) {
217 hppDout(error, exc.what());
218 throw hpp::Error(exc.what());
219 }
220 }
221
222 // --------------------------------------------------------------------
223
224 Long Robot::getConfigSize() {
225 try {
226 return (Long)getRobotOrThrow(problemSolver())->configSize();
227 } catch (const std::exception& exc) {
228 hppDout(error, exc.what());
229 throw hpp::Error(exc.what());
230 }
231 }
232
233 // --------------------------------------------------------------------
234
235 Long Robot::getNumberDof() {
236 try {
237 return (Long)getRobotOrThrow(problemSolver())->numberDof();
238 } catch (const std::exception& exc) {
239 hppDout(error, exc.what());
240 throw hpp::Error(exc.what());
241 }
242 }
243
244 // --------------------------------------------------------------------
245
246 template <typename T>
247 26 void addJoint(Model& model, const JointIndex parent,
248 const Transform3s& placement, const std::string& name) {
249
3/6
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
26 JointIndex jid = model.addJoint(parent, T(), placement, name);
250
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 model.addJointFrame(jid, -1);
251 26 }
252
253 13 void Robot::appendJoint(const char* parentName, const char* jointName,
254 const char* jointType, const Transform_ pos) {
255 using namespace pinocchio;
256
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
13 DevicePtr_t robot = getRobotOrThrow(problemSolver());
257 13 Model& model = robot->model();
258
259
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 std::string pn(parentName);
260
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 std::string jn(jointName);
261
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 std::string jt(jointType);
262
263 // Find parent joint
264 13 JointIndex pid = 0;
265
2/2
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 2 times.
13 if (!pn.empty()) {
266
2/4
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
11 if (!model.existJointName(pn))
267 throw Error(("Joint " + pn + " not found.").c_str());
268
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 pid = model.getJointId(pn);
269 }
270
271 // Check that joint of this name does not already exist.
272
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
13 if (model.existJointName(jn))
273 throw Error(("Joint " + jn + " already exists.").c_str());
274
275 // Fill position matrix
276
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 Transform3s posMatrix = toTransform3s(pos);
277
278 // Determine type of joint.
279
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 11 times.
13 if (jt == "FreeFlyer")
280
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 addJoint<JointCollection::JointModelFreeFlyer>(model, pid, posMatrix, jn);
281
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 10 times.
11 else if (jt == "Planar")
282
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addJoint<JointCollection::JointModelPlanar>(model, pid, posMatrix, jn);
283
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 9 times.
10 else if (jt == "RX")
284
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addJoint<JointCollection::JointModelRX>(model, pid, posMatrix, jn);
285
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 8 times.
9 else if (jt == "RUBX")
286
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addJoint<JointCollection::JointModelRUBX>(model, pid, posMatrix, jn);
287
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
8 else if (jt == "RY")
288
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addJoint<JointCollection::JointModelRY>(model, pid, posMatrix, jn);
289
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6 times.
7 else if (jt == "RUBY")
290
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addJoint<JointCollection::JointModelRUBY>(model, pid, posMatrix, jn);
291
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
6 else if (jt == "RZ")
292
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addJoint<JointCollection::JointModelRZ>(model, pid, posMatrix, jn);
293
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
5 else if (jt == "RUBZ")
294
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addJoint<JointCollection::JointModelRUBZ>(model, pid, posMatrix, jn);
295
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
4 else if (jt == "PX")
296
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addJoint<JointCollection::JointModelPX>(model, pid, posMatrix, jn);
297
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 else if (jt == "PY")
298
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addJoint<JointCollection::JointModelPY>(model, pid, posMatrix, jn);
299
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2 else if (jt == "PZ")
300
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addJoint<JointCollection::JointModelPZ>(model, pid, posMatrix, jn);
301
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 else if (jt == "Translation")
302
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 addJoint<JointCollection::JointModelTranslation>(model, pid, posMatrix, jn);
303 else {
304 std::ostringstream oss;
305 oss << "Joint type \"" << jt << "\" does not exist.";
306 hppDout(error, oss.str());
307 throw hpp::Error(oss.str().c_str());
308 }
309
310
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 robot->createData();
311 13 }
312
313 // --------------------------------------------------------------------
314
315 1 Names_t* Robot::getJointNames() {
316 try {
317
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 DevicePtr_t robot = getRobotOrThrow(problemSolver());
318 1 const Model& model = robot->model();
319
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 return toNames_t((++model.names.begin()), model.names.end());
320
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 } catch (const std::exception& exc) {
321 throw hpp::Error(exc.what());
322 }
323 }
324
325 // --------------------------------------------------------------------
326
327 Names_t* Robot::getJointTypes() {
328 try {
329 DevicePtr_t robot = getRobotOrThrow(problemSolver());
330 const Model& model = robot->model();
331 std::vector<std::string> types(model.names.size() - 1);
332 for (std::size_t i = 0; i < types.size(); ++i)
333 types[i] = model.joints[i + 1].shortname();
334 return toNames_t(types.begin(), types.end());
335 } catch (const std::exception& exc) {
336 throw hpp::Error(exc.what());
337 }
338 }
339
340 // --------------------------------------------------------------------
341
342 1 Names_t* Robot::getAllJointNames() {
343 try {
344
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 DevicePtr_t robot = problemSolver()->robot();
345
1/8
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
1 if (!robot) return new Names_t(0, 0, Names_t::allocbuf(0));
346 // Compute number of real urdf joints
347 1 const Model& model = robot->model();
348 1 std::vector<std::string> jns;
349
2/2
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 1 times.
26 for (std::size_t i = 0; i < model.frames.size(); ++i)
350
1/2
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
25 jns.push_back(model.frames[i].name);
351
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 return toNames_t(jns.begin(), jns.end());
352
0/2
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1 } catch (const std::exception& exc) {
353 throw hpp::Error(exc.what());
354 }
355 }
356
357 // --------------------------------------------------------------------
358
359 Names_t* Robot::getChildJointNames(const char* jointName) {
360 try {
361 DevicePtr_t robot = problemSolver()->robot();
362 if (!robot) return new Names_t(0, 0, Names_t::allocbuf(0));
363 // Compute number of real urdf joints
364 JointPtr_t j = robot->getJointByName(std::string(jointName));
365 ULong size = (ULong)j->numberChildJoints();
366 char** nameList = Names_t::allocbuf(size);
367 Names_t* jointNames = new Names_t(size, size, nameList);
368 for (std::size_t i = 0; i < size; ++i) {
369 const JointPtr_t joint = j->childJoint(i);
370 nameList[i] = c_str(joint->name());
371 }
372 return jointNames;
373 } catch (const std::exception& exc) {
374 throw hpp::Error(exc.what());
375 }
376 }
377
378 // --------------------------------------------------------------------
379
380 char* Robot::getParentJointName(const char* jointName) {
381 try {
382 DevicePtr_t robot = getRobotOrThrow(problemSolver());
383 const std::string jn(jointName);
384 const Frame f = robot->getFrameByName(jn);
385
386 char* name;
387 if (f.isRootFrame()) {
388 name = CORBA::string_dup("");
389 } else {
390 // TODO if f.parentFrame is not of type JOINT or FIXED_JOINT
391 // we should continue to loop on the parent.
392 name = c_str(f.parentFrame().name());
393 }
394 return name;
395 } catch (const std::exception& exc) {
396 throw hpp::Error(exc.what());
397 }
398 }
399
400 // --------------------------------------------------------------------
401 Transform__slice* Robot::getRootJointPosition() {
402 try {
403 DevicePtr_t robot = getRobotOrThrow(problemSolver());
404 Frame root = robot->rootFrame();
405 return toHppTransform(root.positionInParentFrame());
406 } catch (const std::exception& exc) {
407 throw Error(exc.what());
408 }
409 }
410
411 // --------------------------------------------------------------------
412
413 void Robot::setRootJointPosition(const Transform_ position) {
414 try {
415 DevicePtr_t robot = getRobotOrThrow(problemSolver());
416 Transform3s t3f(toTransform3s(position));
417 robot->rootFrame().positionInParentFrame(t3f);
418 robot->computeForwardKinematics();
419 } catch (const std::exception& exc) {
420 throw Error(exc.what());
421 }
422 }
423
424 // --------------------------------------------------------------------
425
426 void Robot::setJointPositionInParentFrame(const char* jointName,
427 const Transform_ position) {
428 try {
429 DevicePtr_t robot = getRobotOrThrow(problemSolver());
430 Frame frame = robot->getFrameByName(jointName);
431 frame.positionInParentFrame(toTransform3s(position));
432 robot->computeForwardKinematics();
433 } catch (const std::exception& exc) {
434 throw Error(exc.what());
435 }
436 }
437
438 // --------------------------------------------------------------------
439
440 hpp::floatSeq* Robot::getJointConfig(const char* jointName) {
441 try {
442 // Get robot in hppPlanner object.
443 DevicePtr_t robot = getRobotOrThrow(problemSolver());
444 Frame frame = robot->getFrameByName(jointName);
445 if (frame.isFixed()) return new hpp::floatSeq();
446 JointPtr_t joint = frame.joint();
447 if (!joint) return new hpp::floatSeq();
448 vector_t config = robot->currentConfiguration();
449 size_type ric = joint->rankInConfiguration();
450 size_type dim = joint->configSize();
451 return vectorToFloatSeq(config.segment(ric, dim));
452 } catch (const std::exception& exc) {
453 throw hpp::Error(exc.what());
454 }
455 }
456
457 // --------------------------------------------------------------------
458
459 12 char* Robot::getJointType(const char* jointName) {
460 try {
461 // Get robot in hppPlanner object.
462
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 DevicePtr_t robot = getRobotOrThrow(problemSolver());
463
2/4
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
24 Frame frame = robot->getFrameByName(jointName);
464 12 std::string name;
465
2/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
12 if (frame.isFixed()) return CORBA::string_dup("anchor");
466
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 JointPtr_t joint = frame.joint();
467
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
12 if (!joint) return CORBA::string_dup("anchor");
468
3/6
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
12 return c_str(joint->jointModel().shortname());
469
0/2
✗ Branch 8 not taken.
✗ Branch 9 not taken.
12 } catch (const std::exception& exc) {
470 throw hpp::Error(exc.what());
471 }
472 }
473
474 // --------------------------------------------------------------------
475
476 void Robot::setJointConfig(const char* jointName, const hpp::floatSeq& q) {
477 try {
478 // Get robot in hppPlanner object.
479 DevicePtr_t robot = getRobotOrThrow(problemSolver());
480 JointPtr_t joint = robot->getJointByName(jointName);
481 if (!joint) {
482 std::ostringstream oss("Robot has no joint with name ");
483 oss << jointName;
484 hppDout(error, oss.str());
485 throw hpp::Error(oss.str().c_str());
486 }
487 vector_t config = robot->currentConfiguration();
488 size_type ric = joint->rankInConfiguration();
489 size_type dim = joint->configSize();
490 if (dim != (size_type)q.length()) {
491 throw Error("Wrong configuration dimension");
492 }
493 for (size_type i = 0; i < dim; i++) config[ric + i] = q[(ULong)i];
494 robot->currentConfiguration(config);
495 robot->computeForwardKinematics();
496 } catch (const std::exception& exc) {
497 throw hpp::Error(exc.what());
498 }
499 }
500
501 // --------------------------------------------------------------------
502
503 floatSeq* Robot::jointIntegrate(const floatSeq& jointCfg, const char* jointName,
504 const floatSeq& dq, bool saturate) {
505 try {
506 // Get robot in hppPlanner object.
507 DevicePtr_t robot = getRobotOrThrow(problemSolver());
508 JointPtr_t joint = robot->getJointByName(jointName);
509 if (!joint) {
510 std::ostringstream oss("Robot has no joint with name ");
511 oss << jointName;
512 hppDout(error, oss.str());
513 throw hpp::Error(oss.str().c_str());
514 }
515 const size_type nq = joint->configSize(), nv = joint->numberDof();
516 if (nv != (size_type)dq.length()) {
517 throw Error("Wrong speed dimension");
518 }
519 LiegroupElement q(floatSeqToVector(jointCfg, nq),
520 joint->configurationSpace());
521 q += floatSeqToVector(dq, nv);
522 if (saturate) {
523 for (size_type i = 0; i < nq; ++i) {
524 value_type ub = joint->upperBound(i);
525 value_type lb = joint->lowerBound(i);
526 q.vector()[i] = std::min(ub, std::max(lb, q.vector()[i]));
527 }
528 }
529 return vectorToFloatSeq(q.vector());
530 } catch (const std::exception& exc) {
531 throw hpp::Error(exc.what());
532 }
533 }
534
535 // --------------------------------------------------------------------
536
537 hpp::floatSeqSeq* Robot::getCurrentTransformation(const char* jointName) {
538 try {
539 DevicePtr_t robot = getRobotOrThrow(problemSolver());
540 JointPtr_t joint = robot->getJointByName(jointName);
541 if (!joint) {
542 std::ostringstream oss("Robot has no joint with name ");
543 oss << jointName;
544 hppDout(error, oss.str());
545 throw hpp::Error(oss.str().c_str());
546 }
547
548 // join translation & rotation into homog. transformation
549 const Transform3s& T = joint->currentTransformation();
550 Eigen::Matrix<hpp::pinocchio::value_type, 4, 4> trafo;
551 trafo.block<3, 3>(0, 0) = T.rotation();
552 trafo.block<3, 1>(0, 3) = T.translation();
553 trafo.block<1, 4>(3, 0) << 0, 0, 0, 1;
554 return matrixToFloatSeqSeq(trafo);
555 } catch (const std::exception& exc) {
556 throw Error(exc.what());
557 }
558 }
559
560 // --------------------------------------------------------------------
561
562 Transform__slice* Robot::getJointPosition(const char* jointName) {
563 try {
564 DevicePtr_t robot = getRobotOrThrow(problemSolver());
565 Frame frame = robot->getFrameByName(jointName);
566 return toHppTransform(frame.currentTransformation());
567 } catch (const std::exception& exc) {
568 throw Error(exc.what());
569 }
570 }
571
572 // --------------------------------------------------------------------
573
574 TransformSeq* Robot::getJointsPosition(const floatSeq& dofArray,
575 const Names_t& jointNames) {
576 try {
577 using hpp::pinocchio::DeviceSync;
578 DevicePtr_t _robot = getRobotOrThrow(problemSolver());
579 Configuration_t config = floatSeqToConfig(_robot, dofArray, true);
580 DeviceSync robot(_robot);
581 robot.currentConfiguration(config);
582 robot.computeForwardKinematics();
583 robot.computeFramesForwardKinematics();
584
585 const Model& model(robot.model());
586 const Data& data(robot.data());
587 TransformSeq* transforms = new TransformSeq();
588 transforms->length(jointNames.length());
589 std::string n;
590 for (CORBA::ULong i = 0; i < jointNames.length(); ++i) {
591 n = jointNames[i];
592 if (!model.existFrame(n)) {
593 HPP_THROW(Error, "Robot has no frame with name " << n);
594 }
595 FrameIndex joint = model.getFrameId(n);
596 if (model.frames.size() <= (std::size_t)joint)
597 HPP_THROW(Error,
598 "Frame index of joint " << n << " out of bounds: " << joint);
599
600 toHppTransform(data.oMf[joint], (*transforms)[i]);
601 }
602 return transforms;
603 } catch (const std::exception& exc) {
604 throw Error(exc.what());
605 }
606 }
607
608 // --------------------------------------------------------------------
609
610 floatSeq* Robot::getJointVelocity(const char* jointName) {
611 try {
612 DevicePtr_t robot = getRobotOrThrow(problemSolver());
613 Frame frame = robot->getFrameByName(jointName);
614 vector_t w = frame.jacobian() * robot->currentVelocity();
615 w.head<3>() = frame.currentTransformation().rotation() * w.head<3>();
616 w.tail<3>() = frame.currentTransformation().rotation() * w.tail<3>();
617 return vectorToFloatSeq(w);
618 } catch (const std::exception& exc) {
619 throw Error(exc.what());
620 }
621 }
622
623 // --------------------------------------------------------------------
624
625 floatSeq* Robot::getJointVelocityInLocalFrame(const char* jointName) {
626 try {
627 DevicePtr_t robot = getRobotOrThrow(problemSolver());
628 Frame frame = robot->getFrameByName(jointName);
629 return vectorToFloatSeq(frame.jacobian() * robot->currentVelocity());
630 } catch (const std::exception& exc) {
631 throw Error(exc.what());
632 }
633 }
634
635 // --------------------------------------------------------------------
636
637 Transform__slice* Robot::getJointPositionInParentFrame(const char* jointName) {
638 try {
639 DevicePtr_t robot = getRobotOrThrow(problemSolver());
640 Frame frame = robot->getFrameByName(jointName);
641 return toHppTransform(frame.positionInParentFrame());
642 } catch (const std::exception& exc) {
643 throw Error(exc.what());
644 }
645 }
646
647 // --------------------------------------------------------------------
648
649 12 Long Robot::getJointNumberDof(const char* jointName) {
650 try {
651
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 DevicePtr_t robot = getRobotOrThrow(problemSolver());
652
2/4
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
24 Frame frame = robot->getFrameByName(jointName);
653
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
12 if (frame.isFixed()) return 0;
654
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 JointPtr_t joint = frame.joint();
655
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
12 return (joint ? (Long)joint->numberDof() : 0);
656
0/2
✗ Branch 6 not taken.
✗ Branch 7 not taken.
12 } catch (const std::exception& exc) {
657 throw Error(exc.what());
658 }
659 }
660
661 // --------------------------------------------------------------------
662
663 12 Long Robot::getJointConfigSize(const char* jointName) {
664 try {
665
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 DevicePtr_t robot = getRobotOrThrow(problemSolver());
666
2/4
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 12 times.
✗ Branch 7 not taken.
24 Frame frame = robot->getFrameByName(jointName);
667
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
12 if (frame.isFixed()) return 0;
668
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 JointPtr_t joint = frame.joint();
669
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
12 return (joint ? (Long)joint->configSize() : 0);
670
0/2
✗ Branch 6 not taken.
✗ Branch 7 not taken.
12 } catch (const std::exception& exc) {
671 throw Error(exc.what());
672 }
673 }
674
675 // --------------------------------------------------------------------
676
677 floatSeq* Robot::getJointBounds(const char* jointName) {
678 try {
679 // Get robot in ProblemSolver object.
680 DevicePtr_t robot = getRobotOrThrow(problemSolver());
681 // get joint
682 JointPtr_t joint = robot->getJointByName(jointName);
683 if (!joint) {
684 HPP_THROW(std::invalid_argument, "Joint " << jointName << " not found.");
685 }
686 return localGetJointBounds(joint);
687 } catch (const std::exception& exc) {
688 throw hpp::Error(exc.what());
689 }
690 }
691
692 // --------------------------------------------------------------------
693
694 void Robot::setJointBounds(const char* jointName, const floatSeq& jointBounds) {
695 try {
696 // Get robot in ProblemSolver object.
697 DevicePtr_t robot = getRobotOrThrow(problemSolver());
698
699 // get joint
700 JointPtr_t joint = robot->getJointByName(jointName);
701 localSetJointBounds(joint, floatSeqToVector(jointBounds));
702 } catch (const std::exception& exc) {
703 throw hpp::Error(exc.what());
704 }
705 }
706
707 // --------------------------------------------------------------------
708
709 Transform__slice* Robot::getLinkPosition(const char* linkName) {
710 try {
711 DevicePtr_t robot = getRobotOrThrow(problemSolver());
712 if (!robot->model().existBodyName(std::string(linkName))) {
713 HPP_THROW(Error, "Robot has no link with name " << linkName);
714 }
715 FrameIndex body = robot->model().getBodyId(std::string(linkName));
716 const ::pinocchio::Frame& frame = robot->model().frames[body];
717 JointIndex joint = frame.parent;
718 if (frame.type != ::pinocchio::BODY)
719 HPP_THROW(Error, linkName << " is not a link");
720 if (robot->model().joints.size() <= (std::size_t)joint)
721 HPP_THROW(Error, "Joint index of link " << linkName
722 << " out of bounds: " << joint);
723
724 Transform3s T = robot->data().oMi[joint] * frame.placement;
725 return toHppTransform(T);
726 } catch (const std::exception& exc) {
727 throw Error(exc.what());
728 }
729 }
730
731 // --------------------------------------------------------------------
732
733 TransformSeq* Robot::getLinksPosition(const floatSeq& dofArray,
734 const Names_t& linkNames) {
735 try {
736 using hpp::pinocchio::DeviceSync;
737 DevicePtr_t _robot = getRobotOrThrow(problemSolver());
738 Configuration_t config = floatSeqToConfig(_robot, dofArray, true);
739 DeviceSync robot(_robot);
740 robot.currentConfiguration(config);
741 robot.computeFramesForwardKinematics();
742
743 const Model& model(robot.model());
744 const Data& data(robot.data());
745 TransformSeq* transforms = new TransformSeq();
746 transforms->length(linkNames.length());
747 std::string n;
748 for (CORBA::ULong i = 0; i < linkNames.length(); ++i) {
749 n = linkNames[i];
750 if (!model.existBodyName(n)) {
751 HPP_THROW(Error, "Robot has no link with name " << n);
752 }
753 FrameIndex body = model.getBodyId(n);
754 const ::pinocchio::Frame& frame = model.frames[body];
755 if (frame.type != ::pinocchio::BODY)
756 HPP_THROW(Error, n << " is not a link");
757
758 toHppTransform(data.oMf[body], (*transforms)[i]);
759 }
760 return transforms;
761 } catch (const std::exception& exc) {
762 throw Error(exc.what());
763 }
764 }
765
766 // --------------------------------------------------------------------
767
768 Names_t* Robot::getLinkNames(const char* jointName) {
769 try {
770 DevicePtr_t robot = getRobotOrThrow(problemSolver());
771 const Model& model = robot->model();
772 Frame frame = robot->getFrameByName(jointName);
773
774 std::vector<std::string> names;
775 for (size_type i = 0; i < (size_type)model.frames.size(); ++i) {
776 const ::pinocchio::Frame& f = model.frames[i];
777 if (f.type == ::pinocchio::BODY && f.previousFrame == frame.index())
778 names.push_back(f.name);
779 }
780 return toNames_t(names.begin(), names.end());
781 } catch (const std::exception& exc) {
782 throw Error(exc.what());
783 }
784 }
785
786 // --------------------------------------------------------------------
787
788 void Robot::setDimensionExtraConfigSpace(ULong dimension) {
789 // Get robot in ProblemSolver object.
790 try {
791 DevicePtr_t robot = getRobotOrThrow(problemSolver());
792 robot->setDimensionExtraConfigSpace(dimension);
793 } catch (const std::exception& exc) {
794 throw hpp::Error(exc.what());
795 }
796 }
797
798 ULong Robot::getDimensionExtraConfigSpace() {
799 // Get robot in ProblemSolver object.
800 ULong dim;
801 try {
802 DevicePtr_t robot = getRobotOrThrow(problemSolver());
803 dim = (ULong)robot->extraConfigSpace().dimension();
804 } catch (const std::exception& exc) {
805 throw hpp::Error(exc.what());
806 }
807 return dim;
808 }
809
810 // --------------------------------------------------------------------
811
812 void Robot::setExtraConfigSpaceBounds(const hpp::floatSeq& bounds) {
813 using hpp::pinocchio::ExtraConfigSpace;
814 // Get robot in ProblemSolver object.
815 try {
816 DevicePtr_t robot = getRobotOrThrow(problemSolver());
817 ExtraConfigSpace& extraCS = robot->extraConfigSpace();
818 size_type nbBounds = (size_type)bounds.length();
819 size_type dimension = extraCS.dimension();
820 if (nbBounds == 2 * dimension) {
821 for (size_type iDof = 0; iDof < dimension; ++iDof) {
822 double vMin = bounds[(ULong)(2 * iDof)];
823 double vMax = bounds[(ULong)(2 * iDof + 1)];
824 if (vMin <= vMax) {
825 /* Dof is actually bounded */
826 extraCS.lower(iDof) = vMin;
827 extraCS.upper(iDof) = vMax;
828 } else {
829 /* Dof is not bounded */
830 extraCS.lower(iDof) = -std::numeric_limits<double>::infinity();
831 extraCS.upper(iDof) = +std::numeric_limits<double>::infinity();
832 }
833 }
834 } else {
835 std::ostringstream oss("Expected list of ");
836 oss << 2 * dimension << "float, got " << nbBounds << ".";
837 throw hpp::Error(oss.str().c_str());
838 }
839 } catch (const std::exception& exc) {
840 throw hpp::Error(exc.what());
841 }
842 }
843
844 // --------------------------------------------------------------------
845
846 void Robot::setCurrentConfig(const hpp::floatSeq& dofArray) {
847 try {
848 DevicePtr_t robot = getRobotOrThrow(problemSolver());
849 // Create a config for robot initialized with dof vector.
850 Configuration_t config = floatSeqToConfig(robot, dofArray, true);
851 robot->currentConfiguration(config);
852 robot->computeForwardKinematics();
853 robot->computeFramesForwardKinematics();
854 } catch (const std::exception& exc) {
855 throw hpp::Error(exc.what());
856 }
857 }
858
859 // --------------------------------------------------------------------
860
861 hpp::floatSeq* Robot::shootRandomConfig() {
862 try {
863 core::ProblemPtr_t p = problemSolver()->problem();
864 if (p) {
865 Configuration_t q;
866 p->configurationShooter()->shoot(q);
867 return vectorToFloatSeq(q);
868 } else {
869 throw Error("No problem in the ProblemSolver");
870 }
871 } catch (const std::exception& exc) {
872 throw hpp::Error(exc.what());
873 }
874 }
875
876 // --------------------------------------------------------------------
877
878 hpp::floatSeq* Robot::getCurrentConfig() {
879 try {
880 // Get robot in hppPlanner object.
881 DevicePtr_t robot = getRobotOrThrow(problemSolver());
882 vector_t config = robot->currentConfiguration();
883 assert(robot->configSize() == config.size());
884 return vectorToFloatSeq(config);
885 } catch (const std::exception& exc) {
886 throw hpp::Error(exc.what());
887 }
888 }
889
890 // --------------------------------------------------------------------
891
892 hpp::floatSeq* Robot::getCurrentVelocity() {
893 try {
894 DevicePtr_t robot = getRobotOrThrow(problemSolver());
895 vector_t qDot = robot->currentVelocity();
896 assert(robot->numberDof() == qDot.size());
897 return vectorToFloatSeq(qDot);
898 } catch (const std::exception& exc) {
899 throw hpp::Error(exc.what());
900 }
901 }
902
903 // --------------------------------------------------------------------
904
905 void Robot::setCurrentVelocity(const hpp::floatSeq& qDot) {
906 try {
907 DevicePtr_t robot = getRobotOrThrow(problemSolver());
908 robot->currentVelocity(floatSeqToVector(qDot, robot->numberDof()));
909 robot->computeForwardKinematics();
910 } catch (const std::exception& exc) {
911 throw hpp::Error(exc.what());
912 }
913 }
914
915 // --------------------------------------------------------------------
916
917 Names_t* Robot::getJointInnerObjects(const char* jointName) {
918 Names_t* innerObjectSeq = 0x0;
919 JointPtr_t joint;
920 try {
921 DevicePtr_t robot = getRobotOrThrow(problemSolver());
922 joint = robot->getJointByName(std::string(jointName));
923 if (!joint) {
924 hppDout(error, "No joint with name " << jointName);
925 innerObjectSeq = new Names_t(0);
926 return innerObjectSeq;
927 }
928 BodyPtr_t body = joint->linkedBody();
929 if (!body) {
930 hppDout(error, "Joint " << jointName << " has no body.");
931 innerObjectSeq = new Names_t(0);
932 return innerObjectSeq;
933 }
934
935 if (body->nbInnerObjects() > 0) {
936 // Allocate result now that the size is known.
937 ULong size = (ULong)body->nbInnerObjects();
938 char** nameList = Names_t::allocbuf(size);
939 innerObjectSeq = new Names_t(size, size, nameList);
940 for (size_type i = 0; i < body->nbInnerObjects(); i++) {
941 CollisionObjectConstPtr_t object = body->innerObjectAt(i);
942 nameList[i] = c_str(object->name());
943 }
944 } else {
945 innerObjectSeq = new Names_t(0);
946 }
947 return innerObjectSeq;
948 } catch (const std::exception& exc) {
949 throw hpp::Error(exc.what());
950 }
951 }
952
953 // --------------------------------------------------------------------
954
955 Names_t* Robot::getJointOuterObjects(const char* jointName) {
956 Names_t* outerObjectSeq = 0x0;
957 JointPtr_t joint;
958
959 try {
960 DevicePtr_t robot = getRobotOrThrow(problemSolver());
961 joint = robot->getJointByName(std::string(jointName));
962 if (!joint) {
963 hppDout(error, "No joint with name " << jointName);
964 outerObjectSeq = new Names_t(0);
965 return outerObjectSeq;
966 }
967 BodyPtr_t body = joint->linkedBody();
968 if (!body) {
969 hppDout(error, "Joint " << jointName << " has no body.");
970 outerObjectSeq = new Names_t(0);
971 return outerObjectSeq;
972 }
973
974 if (body->nbOuterObjects() > 0) {
975 // Allocate result now that the size is known.
976 ULong size = (ULong)body->nbOuterObjects();
977 char** nameList = Names_t::allocbuf(size);
978 outerObjectSeq = new Names_t(size, size, nameList);
979 for (size_type i = 0; i < body->nbOuterObjects(); i++) {
980 CollisionObjectConstPtr_t object = body->outerObjectAt(i);
981 nameList[i] = c_str(object->name());
982 }
983 } else {
984 outerObjectSeq = new Names_t(0);
985 }
986 return outerObjectSeq;
987 } catch (const std::exception& exc) {
988 throw hpp::Error(exc.what());
989 }
990 }
991
992 // --------------------------------------------------------------------
993
994 CollisionObjectConstPtr_t Robot::getObjectByName(const char* name) {
995 try {
996 DevicePtr_t robot = getRobotOrThrow(problemSolver());
997 for (size_type i = 0; i < robot->nbObjects(); ++i) {
998 CollisionObjectConstPtr_t object = robot->objectAt(i);
999 if (object->name() == name) {
1000 return object;
1001 }
1002 }
1003 throw std::runtime_error("robot has no object with name " +
1004 std::string(name));
1005 } catch (const std::exception& exc) {
1006 throw hpp::Error(exc.what());
1007 }
1008 }
1009
1010 // --------------------------------------------------------------------
1011
1012 void Robot::getObjectPosition(const char* objectName, Transform_ cfg) {
1013 try {
1014 CollisionObjectConstPtr_t object = getObjectByName(objectName);
1015 Transform3s transform = object->getTransform();
1016 toHppTransform(transform, cfg);
1017 return;
1018 } catch (const std::exception& exc) {
1019 throw hpp::Error(exc.what());
1020 }
1021 }
1022
1023 // --------------------------------------------------------------------
1024
1025 void Robot::isConfigValid(const hpp::floatSeq& dofArray, Boolean& validity,
1026 CORBA::String_out report) {
1027 try {
1028 DevicePtr_t robot = getRobotOrThrow(problemSolver());
1029 Configuration_t config = floatSeqToConfig(robot, dofArray, true);
1030 core::ValidationReportPtr_t validationReport;
1031 validity = problemSolver()->problem()->configValidations()->validate(
1032 config, validationReport);
1033 if (validity) {
1034 report = CORBA::string_dup("");
1035 } else {
1036 std::ostringstream oss;
1037 oss << *validationReport;
1038 report = CORBA::string_dup(oss.str().c_str());
1039 }
1040 } catch (const std::exception& exc) {
1041 throw hpp::Error(exc.what());
1042 }
1043 }
1044
1045 // --------------------------------------------------------------------
1046
1047 void Robot::distancesToCollision(hpp::floatSeq_out distances,
1048 Names_t_out innerObjects,
1049 Names_t_out outerObjects,
1050 hpp::floatSeqSeq_out innerPoints,
1051 hpp::floatSeqSeq_out outerPoints) {
1052 try {
1053 DevicePtr_t robot = getRobotOrThrow(problemSolver());
1054 const DistanceBetweenObjectsPtr_t& distanceBetweenObjects =
1055 problemSolver()->distanceBetweenObjects();
1056 robot->computeDistances();
1057 const pinocchio::GeomModel& geomModel(robot->geomModel());
1058 const pinocchio::GeomData& geomData(robot->geomData());
1059
1060 distanceBetweenObjects->computeDistances();
1061 const CollisionPairs_t& cps = distanceBetweenObjects->collisionPairs();
1062 const DistanceResults_t& drs = distanceBetweenObjects->distanceResults();
1063
1064 const std::size_t nbAutoCol = geomModel.collisionPairs.size();
1065 const std::size_t nbObsCol = drs.size();
1066 const std::size_t nbDistPairs = nbAutoCol + nbObsCol;
1067
1068 hpp::core::vector_t dists(nbDistPairs);
1069 std::vector<std::string> innerObj(nbDistPairs);
1070 std::vector<std::string> outerObj(nbDistPairs);
1071 hpp::core::matrix_t innerPts(nbDistPairs, 3);
1072 hpp::core::matrix_t outerPts(nbDistPairs, 3);
1073
1074 for (std::size_t i = 0; i < nbAutoCol; ++i) {
1075 const ::pinocchio::CollisionPair& cp(geomModel.collisionPairs[i]);
1076 dists[i] = geomData.distanceResults[i].min_distance;
1077 innerObj[i] = geomModel.geometryObjects[cp.first].name;
1078 outerObj[i] = geomModel.geometryObjects[cp.second].name;
1079
1080 innerPts.row(i) = geomData.distanceResults[i].nearest_points[0];
1081 outerPts.row(i) = geomData.distanceResults[i].nearest_points[1];
1082 }
1083 for (std::size_t i = 0; i < nbObsCol; ++i) {
1084 dists[nbAutoCol + i] = drs[i].min_distance;
1085 innerObj[nbAutoCol + i] = cps[i].first->name();
1086 outerObj[nbAutoCol + i] = cps[i].second->name();
1087
1088 innerPts.row(nbAutoCol + i) = drs[i].nearest_points[0];
1089 outerPts.row(nbAutoCol + i) = drs[i].nearest_points[1];
1090 }
1091 distances = vectorToFloatSeq(dists);
1092 innerObjects = toNames_t(innerObj.begin(), innerObj.end());
1093 outerObjects = toNames_t(outerObj.begin(), outerObj.end());
1094 innerPoints = matrixToFloatSeqSeq(innerPts);
1095 outerPoints = matrixToFloatSeqSeq(outerPts);
1096 } catch (const std::exception& exc) {
1097 throw hpp::Error(exc.what());
1098 }
1099 }
1100
1101 // --------------------------------------------------------------------
1102
1103 void Robot::autocollisionCheck(hpp::boolSeq_out collide) {
1104 try {
1105 DevicePtr_t robot = getRobotOrThrow(problemSolver());
1106 robot->collisionTest(false);
1107 const pinocchio::GeomModel& geomModel(robot->geomModel());
1108 const pinocchio::GeomData& geomData(robot->geomData());
1109
1110 const std::size_t nbColPairs = geomModel.collisionPairs.size();
1111
1112 boolSeq* col_ptr = new boolSeq();
1113 col_ptr->length((ULong)nbColPairs);
1114 collide = col_ptr;
1115
1116 for (std::size_t i = 0; i < nbColPairs; ++i)
1117 (*col_ptr)[(ULong)i] = geomData.collisionResults[i].isCollision();
1118 } catch (const std::exception& exc) {
1119 throw hpp::Error(exc.what());
1120 }
1121 }
1122
1123 // --------------------------------------------------------------------
1124
1125 void Robot::autocollisionPairs(Names_t_out innerObjects,
1126 Names_t_out outerObjects, boolSeq_out active) {
1127 try {
1128 DevicePtr_t robot = getRobotOrThrow(problemSolver());
1129 const pinocchio::GeomModel& geomModel(robot->geomModel());
1130 const pinocchio::GeomData& geomData(robot->geomData());
1131
1132 const std::size_t nbAutoCol = geomModel.collisionPairs.size();
1133
1134 std::vector<std::string> innerObj(nbAutoCol);
1135 std::vector<std::string> outerObj(nbAutoCol);
1136
1137 boolSeq* active_ptr = new boolSeq();
1138 active_ptr->length((ULong)nbAutoCol);
1139 active = active_ptr;
1140
1141 for (std::size_t i = 0; i < nbAutoCol; ++i) {
1142 const ::pinocchio::CollisionPair& cp(geomModel.collisionPairs[i]);
1143 innerObj[i] = geomModel.geometryObjects[cp.first].name;
1144 outerObj[i] = geomModel.geometryObjects[cp.second].name;
1145 (*active_ptr)[(ULong)i] = geomData.activeCollisionPairs[i];
1146 }
1147 innerObjects = toNames_t(innerObj.begin(), innerObj.end());
1148 outerObjects = toNames_t(outerObj.begin(), outerObj.end());
1149 } catch (const std::exception& exc) {
1150 throw hpp::Error(exc.what());
1151 }
1152 }
1153
1154 // --------------------------------------------------------------------
1155
1156 void Robot::setAutoCollision(const char* innerObject, const char* outerObject,
1157 bool active) {
1158 try {
1159 core::ProblemSolverPtr_t ps = problemSolver();
1160 DevicePtr_t robot = getRobotOrThrow(ps);
1161
1162 const pinocchio::GeomModel& geomModel(robot->geomModel());
1163 pinocchio::GeomData& geomData(robot->geomData());
1164
1165 if (!geomModel.existGeometryName(innerObject))
1166 HPP_THROW(Error, "Object " << innerObject << " not found");
1167 if (!geomModel.existGeometryName(outerObject))
1168 HPP_THROW(Error, "Object " << outerObject << " not found");
1169 pinocchio::GeomIndex idxI = geomModel.getGeometryId(innerObject);
1170 pinocchio::GeomIndex idxO = geomModel.getGeometryId(outerObject);
1171 ::pinocchio::PairIndex pid =
1172 geomModel.findCollisionPair(::pinocchio::CollisionPair(idxI, idxO));
1173
1174 if (pid >= geomModel.collisionPairs.size()) {
1175 HPP_THROW(Error, "Collision pair (" << innerObject << ", " << outerObject
1176 << ") not found");
1177 }
1178
1179 if (active)
1180 geomData.activateCollisionPair(pid);
1181 else
1182 geomData.deactivateCollisionPair(pid);
1183
1184 ps->initValidations();
1185 } catch (const std::exception& exc) {
1186 throw hpp::Error(exc.what());
1187 }
1188 }
1189
1190 // --------------------------------------------------------------------
1191
1192 Double Robot::getMass() {
1193 try {
1194 return getRobotOrThrow(problemSolver())->mass();
1195 } catch (const std::exception& exc) {
1196 throw hpp::Error(exc.what());
1197 }
1198 }
1199
1200 // --------------------------------------------------------------------
1201
1202 hpp::floatSeq* Robot::getCenterOfMass() {
1203 try {
1204 DevicePtr_t robot = getRobotOrThrow(problemSolver());
1205 robot->computeForwardKinematics();
1206 return vectorToFloatSeq(robot->positionCenterOfMass());
1207 } catch (const std::exception& exc) {
1208 throw hpp::Error(exc.what());
1209 }
1210 }
1211
1212 // --------------------------------------------------------------------
1213
1214 hpp::floatSeq* Robot::getCenterOfMassVelocity() {
1215 try {
1216 DevicePtr_t robot = getRobotOrThrow(problemSolver());
1217 robot->computeForwardKinematics(pinocchio::COMPUTE_ALL);
1218 return vectorToFloatSeq(robot->jacobianCenterOfMass() *
1219 robot->currentVelocity());
1220 } catch (const std::exception& exc) {
1221 throw hpp::Error(exc.what());
1222 }
1223 }
1224
1225 // --------------------------------------------------------------------
1226
1227 hpp::floatSeqSeq* Robot::getJacobianCenterOfMass() {
1228 try {
1229 DevicePtr_t robot = getRobotOrThrow(problemSolver());
1230 robot->computeForwardKinematics(pinocchio::COMPUTE_ALL);
1231 const ComJacobian_t& jacobian = robot->jacobianCenterOfMass();
1232 return matrixToFloatSeqSeq(jacobian);
1233 } catch (const std::exception& exc) {
1234 throw hpp::Error(exc.what());
1235 }
1236 }
1237
1238 // --------------------------------------------------------------------
1239
1240 void Robot::createPolyhedron(const char* polyhedronName) {
1241 objectMap_.createPolyhedron(polyhedronName);
1242 }
1243
1244 // --------------------------------------------------------------------
1245
1246 void Robot::createBox(const char* name, Double x, Double y, Double z) {
1247 objectMap_.createBox(name, x, y, z);
1248 }
1249
1250 // --------------------------------------------------------------------
1251
1252 12 void Robot::createSphere(const char* name, Double radius) {
1253
2/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
12 objectMap_.createSphere(name, radius);
1254 12 }
1255
1256 // --------------------------------------------------------------------
1257
1258 void Robot::createCylinder(const char* name, Double radius, Double length) {
1259 objectMap_.createCylinder(name, radius, length);
1260 }
1261
1262 // --------------------------------------------------------------------
1263
1264 ULong Robot::addPoint(const char* polyhedronName, Double x, Double y,
1265 Double z) {
1266 return static_cast<Long>(objectMap_.addPoint(polyhedronName, x, y, z));
1267 }
1268
1269 // --------------------------------------------------------------------
1270
1271 ULong Robot::addTriangle(const char* polyhedronName, ULong pt1, ULong pt2,
1272 ULong pt3) {
1273 return static_cast<ULong>(
1274 objectMap_.addTriangle(polyhedronName, pt1, pt2, pt3));
1275 }
1276
1277 // --------------------------------------------------------------------
1278
1279 12 void Robot::addObjectToJoint(const char* jointName, const char* objectName,
1280 const Transform_ pos) {
1281 using namespace pinocchio;
1282
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 DevicePtr_t robot = getRobotOrThrow(problemSolver());
1283 12 Model& model = robot->model();
1284 12 GeomModel& geomModel = robot->geomModel();
1285
1286
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 std::string jn(jointName);
1287
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 std::string on(objectName);
1288
1289 // Find parent joint
1290
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
12 if (!model.existJointName(jn))
1291 throw Error(("Joint " + jn + " not found.").c_str());
1292
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 JointIndex jid = model.getJointId(jn);
1293
1294
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 Transform3s placement = toTransform3s(pos);
1295
1296 try {
1297
2/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
24 CollisionGeometryPtr_t geometry = objectMap_.geometry(objectName);
1298
1299
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 FrameIndex bid = model.addBodyFrame(on, jid, placement);
1300
7/14
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 12 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 12 times.
✗ Branch 15 not taken.
✓ Branch 18 taken 12 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 12 times.
✗ Branch 22 not taken.
24 GeometryObject geom(on, bid, jid, geometry, placement);
1301
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 GeomIndex idx = geomModel.addGeometryObject(geom, model);
1302
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 12 times.
78 for (GeomIndex i = 0; i < idx; ++i) {
1303
1/2
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
66 if (geomModel.geometryObjects[i].parentJoint != jid)
1304
2/4
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 66 times.
✗ Branch 5 not taken.
66 geomModel.addCollisionPair(::pinocchio::CollisionPair(i, idx));
1305 }
1306
1307
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 robot->createData();
1308
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 robot->createGeomData();
1309
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 problemSolver()->resetProblem();
1310
0/2
✗ Branch 4 not taken.
✗ Branch 5 not taken.
12 } catch (const std::exception& exc) {
1311 throw hpp::Error(exc.what());
1312 }
1313 12 }
1314
1315 void Robot::addPartialCom(const char* comName, const Names_t& jointNames) {
1316 try {
1317 DevicePtr_t robot = getRobotOrThrow(problemSolver());
1318 pinocchio::CenterOfMassComputationPtr_t comc =
1319 pinocchio::CenterOfMassComputation::create(robot);
1320
1321 for (ULong i = 0; i < jointNames.length(); ++i) {
1322 std::string name(jointNames[i]);
1323 JointPtr_t j = robot->getJointByName(name);
1324 if (!j) throw hpp::Error("One joint not found.");
1325 comc->add(j);
1326 }
1327 problemSolver()->centerOfMassComputations.add(std::string(comName), comc);
1328 } catch (const std::exception& exc) {
1329 throw hpp::Error(exc.what());
1330 }
1331 }
1332
1333 hpp::floatSeq* Robot::getPartialCom(const char* comName) {
1334 try {
1335 if (!problemSolver()->centerOfMassComputations.has(comName)) {
1336 HPP_THROW(std::invalid_argument,
1337 "Partial COM " << comName << " not found.");
1338 }
1339 pinocchio::CenterOfMassComputationPtr_t comc =
1340 problemSolver()->centerOfMassComputations.get(comName);
1341 comc->compute(hpp::pinocchio::COM);
1342 return vectorToFloatSeq(comc->com());
1343 } catch (const std::exception& exc) {
1344 throw hpp::Error(exc.what());
1345 }
1346 }
1347
1348 hpp::floatSeq* Robot::getVelocityPartialCom(const char* comName) {
1349 try {
1350 DevicePtr_t robot = getRobotOrThrow(problemSolver());
1351 if (!problemSolver()->centerOfMassComputations.has(comName)) {
1352 HPP_THROW(std::invalid_argument,
1353 "Partial COM " << comName << " not found.");
1354 }
1355 pinocchio::CenterOfMassComputationPtr_t comc =
1356 problemSolver()->centerOfMassComputations.get(comName);
1357 comc->compute(hpp::pinocchio::JACOBIAN);
1358 return vectorToFloatSeq(comc->jacobian() * robot->currentVelocity());
1359 } catch (const std::exception& exc) {
1360 throw hpp::Error(exc.what());
1361 }
1362 }
1363
1364 hpp::floatSeqSeq* Robot::getJacobianPartialCom(const char* comName) {
1365 try {
1366 if (!problemSolver()->centerOfMassComputations.has(comName)) {
1367 HPP_THROW(std::invalid_argument,
1368 "Partial COM " << comName << " not found.");
1369 }
1370 pinocchio::CenterOfMassComputationPtr_t comc =
1371 problemSolver()->centerOfMassComputations.get(comName);
1372 comc->compute(hpp::pinocchio::JACOBIAN);
1373 return matrixToFloatSeqSeq(comc->jacobian());
1374 } catch (const std::exception& exc) {
1375 throw hpp::Error(exc.what());
1376 }
1377 }
1378
1379 hpp::pinocchio_idl::CenterOfMassComputation_ptr
1380 Robot::getCenterOfMassComputation(const char* name) {
1381 const std::string cn(name);
1382 core::ProblemSolverPtr_t ps = problemSolver();
1383 if (!ps->centerOfMassComputations.has(cn))
1384 throw Error(("CenterOfMassComputation " + cn + " not found").c_str());
1385
1386 hpp::pinocchio_idl::CenterOfMassComputation_var d =
1387 makeServantDownCast<pinocchio_impl::CenterOfMassComputation>(
1388 server_->parent(), ps->centerOfMassComputations.get(cn));
1389 return d._retn();
1390 }
1391
1392 floatSeq* Robot::getRobotAABB() {
1393 DevicePtr_t robot = getRobotOrThrow(problemSolver());
1394 try {
1395 coal::AABB aabb = robot->computeAABB();
1396 vector_t v(6);
1397 v.head<3>() = aabb.min_;
1398 v.tail<3>() = aabb.max_;
1399 return vectorToFloatSeq(v);
1400 } catch (const std::exception& exc) {
1401 throw hpp::Error(exc.what());
1402 }
1403 }
1404 } // end of namespace impl.
1405 } // end of namespace corbaServer.
1406 } // end of namespace hpp.
1407