KinematicsWorld.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2013-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarXSimulation::Simulator
19 * @author Nikolaus ( vahrenkamp at kit dot edu )
20 * @date 2017
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25#include "KinematicsWorld.h"
26
27#include <algorithm>
28
29#include <VirtualRobot/CollisionDetection/CollisionChecker.h>
30#include <VirtualRobot/IK/DifferentialIK.h>
31#include <VirtualRobot/IK/IKSolver.h>
32#include <VirtualRobot/Nodes/ForceTorqueSensor.h>
33#include <VirtualRobot/Nodes/RobotNode.h>
34#include <VirtualRobot/Obstacle.h>
35#include <VirtualRobot/Robot.h>
36#include <VirtualRobot/RobotFactory.h>
37#include <VirtualRobot/RobotNodeSet.h>
38#include <VirtualRobot/Visualization/VisualizationFactory.h>
39
43
44using namespace VirtualRobot;
45using namespace armarx;
46
48{
50 currentSimTimeSec = 0.0f;
51
52 floorPos.setZero();
53 floorUp.setZero();
54 floorDepthMM = 500.0f;
55 floorExtendMM = 50000.0f;
56}
57
59
60void
63 bool floorPlane,
64 std::string floorTexture)
65{
66 ARMARX_INFO_S << "Init KinematicsWorld...";
67
68 simVisuData.robots.clear();
69 simVisuData.objects.clear();
70 simVisuData.floorTextureFile.clear();
71 simVisuData.floor = false;
72
73 simReportData.robots.clear();
74
75 this->maxRealTimeSimSpeed = maxRealTimeSimSpeed;
76 this->stepSizeMs = stepSizeMS;
77
78 setupFloor(floorPlane, floorTexture);
79}
80
81void
82KinematicsWorld::createFloorPlane(const Eigen::Vector3f& pos, const Eigen::Vector3f& up)
83{
84 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
85 floorPos = pos;
86 floorUp = up;
87 float size = float(floorExtendMM);
88 float sizeSmall = float(floorDepthMM);
89 float w = size;
90 float h = size;
91 float d = sizeSmall;
92
93 if (up(1) == 0 && up(2) == 0)
94 {
95 w = sizeSmall;
96 h = size;
97 d = size;
98 }
99 else if (up(0) == 0 && up(2) == 0)
100 {
101 w = size;
102 h = sizeSmall;
103 d = size;
104 }
105
106 groundObject = VirtualRobot::Obstacle::createBox(
107 w, h, d, VirtualRobot::VisualizationFactory::Color::Gray());
108 std::string name("Floor");
109 groundObject->setName(name);
110 Eigen::Matrix4f gp;
111 gp.setIdentity();
112 gp(2, 3) = -sizeSmall * 0.5f;
113 groundObject->setGlobalPose(gp);
114
115 groundObject->getVisualization();
116 groundObject->setSimulationType(VirtualRobot::SceneObject::Physics::eStatic);
117
118 //addObstacleEngine(groundObject, VirtualRobot::SceneObject::Physics::eStatic);
119}
120
121void
122KinematicsWorld::actuateRobotJoints(const std::string& robotName,
123 const std::map<std::string, float>& angles,
124 const std::map<std::string, float>& velocities)
125{
126 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
127
128 ARMARX_DEBUG_S << "actuateRobotJoints: first:" << angles.begin()->first
129 << ", ang: " << angles.begin()->second << ", vel:" << velocities.begin()->second;
130 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
131 if (!kinRobot)
132 {
133 ARMARX_WARNING_S << "No robot available";
134 return;
135 }
136 kinRobot->setJointValues(angles);
137
138 // Set velocities to zero
139 KinematicRobotInfo& ri = kinematicRobots[robotName];
140 for (auto& entry : angles)
141 {
142 ri.targetVelocities[entry.first] = 0;
143 }
144}
145
146void
147KinematicsWorld::actuateRobotJointsPos(const std::string& robotName,
148 const std::map<std::string, float>& angles)
149{
150 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
151 if (angles.size() == 0)
152 {
153 return;
154 }
155 ARMARX_DEBUG_S << "actuateRobotJointsPos: first:" << angles.begin()->first
156 << ", ang: " << angles.begin()->second;
157
158 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
159 if (!kinRobot)
160 {
161 ARMARX_WARNING_S << "No robot available";
162 return;
163 }
164 kinRobot->setJointValues(angles);
165
166 // Set velocities to zero
167 KinematicRobotInfo& ri = kinematicRobots[robotName];
168 for (auto& entry : angles)
169 {
170 ri.targetVelocities[entry.first] = 0;
171 }
172}
173
174void
175KinematicsWorld::actuateRobotJointsVel(const std::string& robotName,
176 const std::map<std::string, float>& velocities)
177{
178 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
179 ARMARX_DEBUG_S << "actuateRobotJointsVel: first: vel:" << velocities.begin()->second;
180
181 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
182 if (!kinRobot)
183 {
184 ARMARX_WARNING_S << "No robot available";
185 return;
186 }
187
188 // store velocities for static robots
189 KinematicRobotInfo& ri = kinematicRobots[robotName];
190 // preserve all values of velocities, and add values of robotInfo
191 std::map<std::string, float> res = velocities;
192 res.insert(ri.targetVelocities.begin(), ri.targetVelocities.end());
193 ri.targetVelocities = res;
194}
195
196void
197KinematicsWorld::actuateRobotJointsTorque(const std::string& robotName,
198 const std::map<std::string, float>& torques)
199{
200 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
201 ARMARX_DEBUG_S << "actuateRobotJointsTorque: first:" << torques.begin()->first << ","
202 << torques.begin()->second;
203
204 ARMARX_DEBUG_S << "No torque mode available...";
205}
206
207void
208KinematicsWorld::setRobotPose(const std::string& robotName, const Eigen::Matrix4f& globalPose)
209{
210 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
211 ARMARX_DEBUG << "setRobotPose:" << globalPose(0, 3) << "," << globalPose(1, 3) << ", "
212 << globalPose(2, 3);
213
214 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
215 if (!kinRobot)
216 {
217 ARMARX_WARNING_S << "No robot available";
218 return;
219 }
220
221 kinRobot->setGlobalPose(globalPose);
222}
223
224void
225KinematicsWorld::applyForceRobotNode(const std::string& robotName,
226 const std::string& robotNodeName,
227 const Eigen::Vector3f& force)
228{
229 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
230 ARMARX_DEBUG_S << "ApplyForce not available";
231}
232
233void
234KinematicsWorld::applyTorqueRobotNode(const std::string& robotName,
235 const std::string& robotNodeName,
236 const Eigen::Vector3f& torque)
237{
238 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
239 ARMARX_DEBUG_S << "ApplyTorque not available";
240}
241
242void
243KinematicsWorld::applyForceObject(const std::string& objectName, const Eigen::Vector3f& force)
244{
245 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
246 ARMARX_DEBUG_S << "applyForceObject not available";
247}
248
249void
250KinematicsWorld::applyTorqueObject(const std::string& objectName, const Eigen::Vector3f& torque)
251{
252 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
253 ARMARX_DEBUG_S << "applyTorqueObject not available";
254}
255
256bool
257KinematicsWorld::hasObject(const std::string& instanceName)
258{
259 return getObject(instanceName).get();
260}
261
262void
263KinematicsWorld::setObjectPose(const std::string& objectName, const Eigen::Matrix4f& globalPose)
264{
265 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
266 VirtualRobot::SceneObjectPtr o = getObject(objectName);
267
268 if (!o)
269 {
270 ARMARX_WARNING_S << "No object found with name " << objectName;
271 return;
272 }
273
274 o->setGlobalPose(globalPose);
275}
276
277float
278KinematicsWorld::getRobotMass(const std::string& robotName)
279{
280 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
281
282 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
283 if (!kinRobot)
284 {
285 ARMARX_WARNING_S << "No robot available";
286 return 0;
287 }
288
289 return kinRobot->getMass();
290}
291
292std::map<std::string, float>
293KinematicsWorld::getRobotJointAngles(const std::string& robotName)
294{
295 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
296 std::map<std::string, float> res;
297
298 VirtualRobot::RobotPtr kinRob = getRobot(robotName);
299 if (!kinRob)
300 {
301 ARMARX_WARNING_S << "No robot available";
302 return std::map<std::string, float>();
303 }
304
305 std::vector<RobotNodePtr> rn = kinRob->getRobotNodes();
306
307 for (auto& i : rn)
308 {
309 if (i->isJoint())
310 {
311 res[i->getName()] = i->getJointValue();
312 }
313 }
314
315 ARMARX_DEBUG_S << "getRobotJointAngles:" << res.begin()->second;
316
317 return res;
318}
319
320float
321KinematicsWorld::getRobotJointAngle(const std::string& robotName, const std::string& nodeName)
322{
323 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
324
325 VirtualRobot::RobotPtr kinRob = getRobot(robotName);
326 if (!kinRob)
327 {
328 ARMARX_WARNING_S << "No robot available";
329 return 0;
330 }
331
332 if (!kinRob->hasRobotNode(nodeName))
333 {
334 ARMARX_WARNING_S << "No robotNode available with name " << nodeName;
335 return 0;
336 }
337
338 float res = kinRob->getRobotNode(nodeName)->getJointValue();
339 ARMARX_DEBUG_S << "getRobotJointAngle:" << res;
340 return res;
341}
342
343std::map<std::string, float>
344KinematicsWorld::getRobotJointVelocities(const std::string& robotName)
345{
346 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
347 std::map<std::string, float> res;
348
349 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
350 if (!kinRobot)
351 {
352 ARMARX_WARNING_S << "No robot available";
353 return res;
354 }
355
356 KinematicRobotInfo& ri = kinematicRobots[robotName];
357 res = ri.targetVelocities;
358
359 ARMARX_DEBUG_S << "getRobotJointVelocities:" << res.begin()->second;
360 return res;
361}
362
363float
364KinematicsWorld::getRobotJointVelocity(const std::string& robotName, const std::string& nodeName)
365{
366 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
367
368 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
369 if (!kinRobot)
370 {
371 ARMARX_WARNING_S << "No robot available";
372 return 0;
373 }
374
375 if (!kinRobot->hasRobotNode(nodeName))
376 {
377 ARMARX_WARNING_S << "No robotNode available with name " << nodeName;
378 return 0;
379 }
380 KinematicRobotInfo& ri = kinematicRobots[robotName];
381
382 float res = 0.0f;
383 if (ri.targetVelocities.find(nodeName) != ri.targetVelocities.end())
384 {
385 res = ri.targetVelocities[nodeName];
386 }
387
388 ARMARX_DEBUG_S << "getRobotJointVelocity:" << res;
389 return res;
390}
391
392std::map<std::string, float>
394{
395 return std::map<std::string, float>();
396}
397
398ForceTorqueDataSeq
400{
401 return {};
402}
403
404float
405KinematicsWorld::getRobotJointLimitLo(const std::string& robotName, const std::string& nodeName)
406{
407 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
408
409 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
410 if (!kinRobot)
411 {
412 ARMARX_WARNING_S << "No robot available";
413 return 0;
414 }
415
416 if (!kinRobot->hasRobotNode(nodeName))
417 {
418 ARMARX_WARNING_S << "No robotNode available with name " << nodeName;
419 return 0;
420 }
421
422 return kinRobot->getRobotNode(nodeName)->getJointLimitLo();
423}
424
425float
426KinematicsWorld::getRobotJointLimitHi(const std::string& robotName, const std::string& nodeName)
427{
428 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
429
430 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
431 if (!kinRobot)
432 {
433 ARMARX_WARNING_S << "No robot available";
434 return 0;
435 }
436
437 if (!kinRobot->hasRobotNode(nodeName))
438 {
439 ARMARX_WARNING_S << "No robotNode available with name " << nodeName;
440 return 0;
441 }
442
443 return kinRobot->getRobotNode(nodeName)->getJointLimitHi();
444}
445
446Eigen::Matrix4f
447KinematicsWorld::getRobotPose(const std::string& robotName)
448{
449 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
450 ARMARX_DEBUG_S << "get robot pose";
451
452 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
453 if (!kinRobot)
454 {
455 ARMARX_WARNING_S << "No robot available";
456 return Eigen::Matrix4f::Identity();
457 }
458
459 return kinRobot->getGlobalPose();
460}
461
462float
463KinematicsWorld::getRobotMaxTorque(const std::string& robotName, const std::string& nodeName)
464{
465 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
466 ARMARX_DEBUG_S << "getRobotMaxTorque";
467
468 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
469 if (!kinRobot)
470 {
471 ARMARX_WARNING_S << "Robot '" << robotName << "' not found";
472 return 0.0f;
473 }
474
475 if (!kinRobot->hasRobotNode(nodeName))
476 {
477 ARMARX_WARNING_S << "Robot node '" << nodeName << "' does not exist";
478 return 0.0f;
479 }
480
481 return kinRobot->getRobotNode(nodeName)->getMaxTorque();
482}
483
484void
485KinematicsWorld::setRobotMaxTorque(const std::string& robotName,
486 const std::string& nodeName,
487 float maxTorque)
488{
489 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
490 ARMARX_DEBUG_S << "setRobotMaxTorque";
491
492 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
493 if (!kinRobot)
494 {
495 ARMARX_WARNING_S << "Robot '" << robotName << "' not found";
496 return;
497 }
498
499 if (!kinRobot->hasRobotNode(nodeName))
500 {
501 ARMARX_WARNING_S << "Robot node '" << nodeName << "' does not exist";
502 return;
503 }
504
505 kinRobot->getRobotNode(nodeName)->setMaxTorque(maxTorque);
506}
507
508Eigen::Matrix4f
509KinematicsWorld::getRobotNodePose(const std::string& robotName, const std::string& robotNodeName)
510{
511 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
512 ARMARX_DEBUG_S << "get robot node pose";
513
514 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
515 if (!kinRobot)
516 {
517 ARMARX_WARNING_S << "No robot available";
518 return Eigen::Matrix4f::Identity();
519 }
520
521 if (!kinRobot->hasRobotNode(robotNodeName))
522 {
523 ARMARX_WARNING_S << "No robotNode available with name " << robotNodeName;
524 return Eigen::Matrix4f::Identity();
525 }
526
527 return kinRobot->getRobotNode(robotNodeName)->getGlobalPose();
528}
529
530Eigen::Vector3f
531KinematicsWorld::getRobotLinearVelocity(const std::string& robotName, const std::string& nodeName)
532{
533 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
534 ARMARX_DEBUG_S << "get robot linear velocity";
535
536 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
537 if (!kinRobot)
538 {
539 ARMARX_WARNING_S << "No robot available";
540 return Eigen::Vector3f::Identity();
541 }
542 KinematicRobotInfo& ri = kinematicRobots[robotName];
543
544 return ri.velTransActual;
545}
546
547Eigen::Vector3f
548KinematicsWorld::getRobotAngularVelocity(const std::string& robotName, const std::string& nodeName)
549{
550 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
551 ARMARX_DEBUG << "get robot angular vel";
552
553 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
554 if (!kinRobot)
555 {
556 ARMARX_WARNING << "No robot available";
557 return Eigen::Vector3f::Identity();
558 }
559 KinematicRobotInfo& ri = kinematicRobots[robotName];
560
561 RobotNodePtr rn = kinRobot->getRobotNode(nodeName);
562 if (!rn)
563 {
564 ARMARX_WARNING << "No rn found with name " << nodeName;
565 return Eigen::Vector3f::Identity();
566 }
567
568 // Get jacobian
569 RobotNodeSetPtr rns =
570 RobotNodeSet::createRobotNodeSet(kinRobot, "All_Nodes", kinRobot->getRobotNodes());
571 DifferentialIKPtr j(new DifferentialIK(rns));
572 Eigen::MatrixXf jac = j->getJacobianMatrix(rn, IKSolver::Orientation);
573
574 // Get joint velocities
575 std::vector<std::string> nodeNames = rns->getNodeNames();
576 Eigen::VectorXf joint_vel(nodeNames.size());
577 int i = 0;
578 for (std::vector<std::string>::iterator it = nodeNames.begin(); it != nodeNames.end();
579 ++it, ++i)
580 {
581 joint_vel(i) = ri.actualVelocities[*it];
582 }
583
584 Eigen::Vector3f omega;
585 omega = jac * joint_vel; // vel induced by robot joints
586
587 return ri.velRotActual + omega;
588}
589
590void
591KinematicsWorld::setRobotLinearVelocity(const std::string& robotName,
592 const std::string& robotNodeName,
593 const Eigen::Vector3f& vel)
594{
595 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
596 ARMARX_DEBUG_S << "set robot lin vel";
597
598 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
599 if (!kinRobot)
600 {
601 ARMARX_WARNING_S << "No robot available";
602 return;
603 }
604 KinematicRobotInfo& ri = kinematicRobots[robotName];
605
606 ri.velTransTarget = vel * 1000.0f; // m -> mm
607 ARMARX_DEBUG_S << "set robot lin vel end";
608}
609
610void
611KinematicsWorld::setRobotAngularVelocity(const std::string& robotName,
612 const std::string& robotNodeName,
613 const Eigen::Vector3f& vel)
614{
615 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
616 ARMARX_DEBUG_S << "set robot ang vel";
617
618 ARMARX_DEBUG_S << "set robot lin vel";
619
620 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
621 if (!kinRobot)
622 {
623 ARMARX_WARNING_S << "No robot available";
624 return;
625 }
626 KinematicRobotInfo& ri = kinematicRobots[robotName];
627
628 ri.velRotTarget = vel;
629 ARMARX_DEBUG_S << "set robot ang vel end";
630}
631
632void
634 const std::string& robotNodeName,
635 const Eigen::Vector3f& vel)
636{
637 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
638 ARMARX_DEBUG_S << "set robot lin vel";
639
640 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
641 if (!kinRobot)
642 {
643 ARMARX_WARNING_S << "No robot available";
644 return;
645 }
646 KinematicRobotInfo& ri = kinematicRobots[robotName];
647
648 Eigen::Matrix4f newPose;
649 newPose.setIdentity();
650 newPose.block<3, 1>(0, 3) = vel;
651 auto globalPose = kinRobot->getGlobalPose();
652 globalPose(0, 3) = 0;
653 globalPose(1, 3) = 0;
654 globalPose(2, 3) = 0;
655 Eigen::Matrix4f globalNewPose = globalPose * newPose;
656 ri.velTransTarget = globalNewPose.block<3, 1>(0, 3) * 1000.0f; // m -> mm
657 ARMARX_DEBUG_S << "set robot lin vel end";
658}
659
660void
662 const std::string& robotNodeName,
663 const Eigen::Vector3f& vel)
664{
665 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
666 ARMARX_DEBUG_S << "set robot ang vel";
667
668 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
669 if (!kinRobot)
670 {
671 ARMARX_WARNING_S << "No robot available";
672 return;
673 }
674 KinematicRobotInfo& ri = kinematicRobots[robotName];
675
676 Eigen::Matrix4f newPose;
677 newPose.setIdentity();
678 newPose.block<3, 1>(0, 3) = vel;
679 Eigen::Matrix4f globalPose = kinRobot->getGlobalPose();
680 globalPose(0, 3) = 0;
681 globalPose(1, 3) = 0;
682 globalPose(2, 3) = 0;
683 Eigen::Matrix4f globalNewPose = globalPose * newPose;
684 ri.velRotTarget = globalNewPose.block<3, 1>(0, 3);
685}
686
687bool
688KinematicsWorld::hasRobot(const std::string& robotName)
689{
690 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
691
692 std::map<std::string, KinematicRobotInfo>::iterator it = kinematicRobots.begin();
693 while (it != kinematicRobots.end())
694 {
695 if (it->first == robotName)
696 {
697 return true;
698 }
699 it++;
700 }
701
702 return false;
703}
704
705bool
706KinematicsWorld::hasRobotNode(const std::string& robotName, const std::string& robotNodeName)
707{
708 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
709
710 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
711 if (!kinRobot)
712 {
713 ARMARX_WARNING_S << "No robot available";
714 return false;
715 }
716
717 return (kinRobot->hasRobotNode(robotNodeName));
718}
719
721KinematicsWorld::getRobot(const std::string& robotName)
722{
723 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
724
725 if (!hasRobot(robotName))
726 {
727 ARMARX_WARNING_S << "No robot with name " << robotName;
728 return VirtualRobot::RobotPtr();
729 }
730
731 return kinematicRobots[robotName].robot;
732}
733
734std::map<std::string, RobotPtr>
736{
737 std::map<std::string, RobotPtr> result;
738 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
739 for (auto& elem : kinematicRobots)
740 {
741 const KinematicRobotInfo& info = elem.second;
742 result[elem.first] = (info.robot);
743 }
744 return result;
745}
746
747VirtualRobot::SceneObjectPtr
748KinematicsWorld::getObject(const std::string& objectName)
749{
750 VirtualRobot::SceneObjectPtr o;
751 std::vector<VirtualRobot::SceneObjectPtr>::const_iterator it;
752
753 for (it = kinematicObjects.begin(); it != kinematicObjects.end(); it++)
754 {
755 if ((*it)->getName() == objectName)
756 {
757 o = *it;
758 break;
759 }
760 }
761
762 return o;
763}
764
765Eigen::Matrix4f
766KinematicsWorld::getObjectPose(const std::string& objectName)
767{
768 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
769 ARMARX_DEBUG_S << "get object pose";
770
771 VirtualRobot::SceneObjectPtr o = getObject(objectName);
772 if (!o)
773 {
774 ARMARX_WARNING_S << "No object found with name " << objectName;
775 return Eigen::Matrix4f::Identity();
776 }
777
778 return o->getGlobalPose();
779}
780
781bool
782KinematicsWorld::objectReleasedEngine(const std::string& robotName,
783 const std::string& robotNodeName,
784 const std::string& objectName)
785{
786 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
787 ARMARX_INFO_S << "Object released, robot " << robotName << ", node:" << robotNodeName
788 << ", object:" << objectName;
789 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
790 if (!kinRobot)
791 {
792 ARMARX_WARNING_S << "No robot available";
793 return false;
794 }
795
796 if (!kinRobot->hasRobotNode(robotNodeName))
797 {
798 ARMARX_WARNING_S << "No robotNode available with name " << robotNodeName;
799 return false;
800 }
801
802 /*VirtualRobot::SceneObjectPtr o = getObject(objectName);
803
804 if (!o)
805 {
806 ARMARX_WARNING_S << "No object found with name " << objectName;
807 return false;
808 }*/
809 RobotNodePtr rn = kinRobot->getRobotNode(objectName);
810 if (!rn)
811 {
812 ARMARX_WARNING_S << "No rn found with name " << objectName;
813 return false;
814 }
815
816 bool res = RobotFactory::detach(kinRobot, rn);
817 return res;
818}
819
820bool
821KinematicsWorld::objectGraspedEngine(const std::string& robotName,
822 const std::string& robotNodeName,
823 const std::string& objectName,
824 Eigen::Matrix4f& storeLocalTransform)
825{
826 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
827 ARMARX_INFO_S << "Object grasped, robot " << robotName << ", node:" << robotNodeName
828 << ", object:" << objectName;
829
830 // check if object is already grasped
831 for (const auto& ao : attachedObjects)
832 {
833 if (ao.robotName == robotName && ao.robotNodeName == robotNodeName &&
834 ao.objectName == objectName)
835 {
836 ARMARX_INFO_S << "Object already attached, skipping...";
837 return false;
838 }
839 }
840 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
841 if (!kinRobot)
842 {
843 ARMARX_WARNING_S << "No robot available";
844 return false;
845 }
846
847 if (!kinRobot->hasRobotNode(robotNodeName))
848 {
849 ARMARX_WARNING_S << "No robotNode available with name " << robotNodeName;
850 return false;
851 }
852
853 RobotNodePtr rn = kinRobot->getRobotNode(robotNodeName);
854
855 VirtualRobot::SceneObjectPtr o = getObject(objectName);
856
857 if (!o)
858 {
859 ARMARX_WARNING_S << "No object found with name " << objectName;
860 return false;
861 }
862
863 storeLocalTransform = rn->toLocalCoordinateSystem(o->getGlobalPose());
864 bool res = RobotFactory::attach(kinRobot, o, rn, storeLocalTransform);
865 return res;
866}
867
868SceneObjectPtr
873
874bool
875KinematicsWorld::removeRobotEngine(const std::string& robotName)
876{
877 // lock engine and data
878 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
879
880 VirtualRobot::RobotPtr kinRobot = getRobot(robotName);
881 if (!kinRobot)
882 {
883 ARMARX_WARNING_S << "No robot available";
884 return false;
885 }
886
887 ARMARX_DEBUG_S << "Removing robot " << robotName;
888
889 kinematicRobots.erase(robotName);
890
891 return true;
892}
893
894bool
896 double pid_p,
897 double pid_i,
898 double pid_d,
899 const std::string& filename,
900 bool staticRobot,
901 bool selfCollisions)
902{
903 ARMARX_VERBOSE_S << "Adding robot " << robot->getName() << ", file:" << filename;
904
905 // lock engine and data
906 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
907
908 //access engine
909 ARMARX_DEBUG_S << "add robot";
910
911 if (hasRobot(robot->getName()))
912 {
913 ARMARX_ERROR_S << "More than robot with identical name is currently not supported!";
914 return false;
915 }
916
917 KinematicRobotInfo robInfo;
918
919 ARMARX_INFO_S << "Building static robot...";
920 /*std::vector< RobotNodePtr > nodes = robot->getRobotNodes();
921 for (auto n : nodes)
922 {
923 n->setSimulationType(SceneObject::Physics::eKinematic);
924 }*/
925
926 RobotPtr r = robot->clone(robot->getName());
927
928 // since we do not visualize this robot we can skip visualization updates
929 r->setThreadsafe(false); // we already got a mutex protection
930 r->setUpdateVisualization(false);
931 r->setPropagatingJointValuesEnabled(false);
932
933 robInfo.robot = r;
934
935 kinematicRobots[r->getName()] = robInfo;
936
937 return true;
938}
939
941KinematicsWorld::toFramedPose(const Eigen::Matrix4f& globalPose,
942 const std::string& robotName,
943 const std::string& frameName)
944{
945 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
946
947 RobotPtr kinRobot = getRobot(robotName);
948 if (!kinRobot)
949 {
950 ARMARX_WARNING_S << "No robot or wrong name:" << robotName;
951 return FramedPosePtr();
952 }
953
954 RobotNodePtr rn = kinRobot->getRobotNode(frameName);
955
956 if (!rn)
957 {
958 ARMARX_WARNING_S << "No robot node found (" << frameName << ")";
959 return FramedPosePtr();
960 }
961
962 Eigen::Matrix4f localPose = rn->toLocalCoordinateSystem(globalPose);
963
964 armarx::FramedPosePtr framedPose =
965 new armarx::FramedPose(localPose, frameName, kinRobot->getName());
966 return framedPose;
967}
968
969bool
971 std::map<std::string, armarx::PoseBasePtr>& objMap)
972{
973 // lock engine and data
974 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
975 ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
976
977 RobotPtr kinRobot = getRobot(robotName);
978 if (!kinRobot)
979 {
980 ARMARX_WARNING_S << "No robot or wrong name:" << robotName;
981 return false;
982 }
983
984 VirtualRobot::SceneObjectPtr currentObjEngine = kinRobot->getRootNode();
985
986 if (!synchronizeSceneObjectPoses(currentObjEngine, objMap))
987 {
988 ARMARX_ERROR_S << "Failed to synchronize objects...";
989 return false;
990 }
991 return true;
992}
993
994void
996{
997
998 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
999 for (const auto& data : kinematicRobots)
1000 {
1001 RobotPtr kinRobot = data.second.robot;
1002 auto robotName = data.first;
1003 if (!kinRobot)
1004 {
1005 ARMARX_WARNING_S << "No robot or wrong name:" << robotName;
1006 continue;
1007 }
1008
1009 NameValueMap jointAngles;
1010 std::vector<RobotNodePtr> rn = kinRobot->getRobotNodes();
1011 KinematicRobotInfo& ri = kinematicRobots[robotName];
1012 NameValueMap& jointVelocities = ri.actualVelocities;
1013 IceUtil::Time timestamp = IceUtil::Time::secondsDouble(currentSimTimeSec);
1014 for (auto& i : rn)
1015 {
1016 if ((i->isJoint()))
1017 {
1018 std::string n = i->getName();
1019
1020 jointAngles[n] = i->getJointValue();
1021 auto filterIt = jointAngleDerivationFilters.find(i);
1022 if (filterIt == jointAngleDerivationFilters.end())
1023 {
1024 // DerivationFilterBasePtr filter(new ) ;
1025 ARMARX_INFO << "Creating filter for " << n;
1027 .insert(std::make_pair(
1028 i, std::make_pair(timestamp, i->getJointValue())))
1029 .first;
1030 // filterIt->second.windowFilterSize = 25;
1031 }
1032 else
1033 {
1034 jointVelocities[n] = (i->getJointValue() - filterIt->second.second) /
1035 (timestamp - filterIt->second.first).toSecondsDouble();
1036 filterIt->second.second = i->getJointValue();
1037 filterIt->second.first = timestamp;
1038 }
1039 // filterIt->second.update(timestamp.toMicroSeconds(), new Variant(jointAngles[n]));
1040 // if (ri.targetVelocities.find(n) != ri.targetVelocities.end())
1041 // {
1042 // jointVelocities[n] = ri.targetVelocities[n];
1043 // }
1044 // else
1045 {
1046 // jointVelocities[n] = filterIt->second.getValue()->getFloat();
1047 }
1048 }
1049 }
1050 // ARMARX_INFO << deactivateSpam(1) << jointVelocities;
1051
1052 // calculate linear velocity of robot
1053 Eigen::Vector3f linearVelocity;
1054 auto filterIt = linearVelocityFilters.find(kinRobot);
1055 Eigen::Vector3f pos = kinRobot->getGlobalPose().block<3, 1>(0, 3);
1056 if (filterIt == linearVelocityFilters.end())
1057 {
1058 filterIt = linearVelocityFilters
1059 .insert(std::make_pair(kinRobot, std::make_pair(timestamp, pos)))
1060 .first;
1061 }
1062 linearVelocity = (pos - filterIt->second.second) /
1063 (timestamp - filterIt->second.first).toSecondsDouble();
1064 filterIt->second.second = pos;
1065 filterIt->second.first = timestamp;
1066 ri.velTransActual = linearVelocity;
1067 //ARMARX_INFO << deactivateSpam(1) << linearVelocity;
1068
1069
1070 // calculate angular velocity of robot
1071 Eigen::Vector3f angularVelocity;
1072 angularVelocity.setZero();
1073 auto filterVelIt = angularVelocityFilters.find(kinRobot);
1074 if (filterVelIt ==
1076 .end()) // store previous orientation (TODO: add filtering, e.g. on rpy)
1077 {
1078 //Eigen::Vector3f rpy;
1079 //MathTools::eigen4f2rpy(kinRobot->getGlobalPose(), rpy);
1080 filterVelIt = angularVelocityFilters
1081 .insert(std::make_pair(
1082 kinRobot, std::make_pair(timestamp, kinRobot->getGlobalPose())))
1083 .first;
1084 }
1085
1086 double deltaTimestamp = (timestamp - filterVelIt->second.first).toSecondsDouble();
1087
1088
1089 // old method
1090 // Eigen::Matrix4f deltaMat = kinRobot->getGlobalPose() * filterVelIt->second.second.inverse();
1091 // MathTools::eigen4f2rpy(deltaMat, angularVelocity);
1092 // if (deltaTimestamp > 0)
1093 // {
1094 // angularVelocity /= deltaTimestamp;
1095 // }
1096 // ri.velRotActual = angularVelocity;
1097
1098 // method from http://math.stackexchange.com/questions/668866/how-do-you-find-angular-velocity-given-a-pair-of-3x3-rotation-matrices
1099 Eigen::Matrix3f Rot_prev, Rot_new, A, Omega_mat;
1100 float theta;
1101 Rot_prev = filterVelIt->second.second.block(0, 0, 3, 3);
1102 Rot_new = kinRobot->getGlobalPose().block(0, 0, 3, 3);
1103 A = Rot_new * Rot_prev.transpose();
1104 theta = acos((A.trace() - 1) / 2.);
1105
1106 if (theta == 0.)
1107 {
1108 ri.velRotActual.setZero();
1109 return;
1110 }
1111
1112 Omega_mat = theta * (A - A.transpose()) / (2 * deltaTimestamp * sin(theta));
1113 ri.velRotActual[0] = Omega_mat(2, 1);
1114 ri.velRotActual[1] = Omega_mat(0, 2);
1115 ri.velRotActual[2] = Omega_mat(1, 0);
1116
1117 if (deltaTimestamp > 0.1)
1118 {
1119 angularVelocityFilters[kinRobot] = std::make_pair(timestamp, kinRobot->getGlobalPose());
1120 }
1121
1122 //ARMARX_INFO << deactivateSpam(1) << VAROUT(angularVelocity);
1123 }
1124}
1125
1126bool
1127KinematicsWorld::getRobotStatus(const std::string& robotName,
1128 NameValueMap& jointAngles,
1129 NameValueMap& jointVelocities,
1130 NameValueMap& jointTorques,
1131 Eigen::Vector3f& linearVelocity,
1132 Eigen::Vector3f& angularVelocity)
1133{
1134 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1135 RobotPtr kinRobot = getRobot(robotName);
1136 if (!kinRobot)
1137 {
1138 ARMARX_WARNING_S << "No robot or wrong name:" << robotName;
1139 return false;
1140 }
1141
1142 std::vector<RobotNodePtr> rn = kinRobot->getRobotNodes();
1143 KinematicRobotInfo& ri = kinematicRobots[robotName];
1144
1145 // float simTimeFactor = 1.0;
1146 // if (simStepExecutionTimeMS > 0)
1147 // {
1148 // simTimeFactor = simTimeStepMS / simStepExecutionTimeMS;
1149 // }
1150
1151 // IceUtil::Time timestamp = IceUtil::Time::secondsDouble(currentSimTimeSec);
1152 jointVelocities = ri.actualVelocities;
1153 for (auto& i : rn)
1154 {
1155 if ((i->isJoint()))
1156 {
1157 std::string n = i->getName();
1158
1159 jointAngles[n] = i->getJointValue();
1160 // auto filterIt = jointAngleDerivationFilters.find(rn[i]);
1161 // if (filterIt == jointAngleDerivationFilters.end())
1162 // {
1163 // filterIt = jointAngleDerivationFilters.insert(std::make_pair(rn[i], new filters::DerivationFilter())).first;
1164 // filterIt->second->windowFilterSize = 25;
1165 // }
1166 // filterIt->second->update(timestamp.toMicroSeconds(), new Variant(jointAngles[n]));
1167 // // if (ri.targetVelocities.find(n) != ri.targetVelocities.end())
1168 // // {
1169 // // jointVelocities[n] = ri.targetVelocities[n];
1170 // // }
1171 // // else
1172 // {
1173 // jointVelocities[n] = filterIt->second->getValue()->getFloat() * simTimeFactor;
1174 // }
1175 // ARMARX_INFO << deactivateSpam(1, n) << n << ": " << jointVelocities[n];
1176 jointTorques[n] = 0;
1177 }
1178 }
1179
1180 linearVelocity = ri.velTransActual;
1181
1182
1183 // filterIt = angularVelocityFilters.find(kinRobot);
1184 // if (filterIt == angularVelocityFilters.end())
1185 // {
1186 // filterIt = angularVelocityFilters.insert(std::make_pair(kinRobot, new filters::DerivationFilter())).first;
1187 // filterIt->second->windowFilterSize = 25;
1188 // }
1189 // filterIt->second->update(timestamp.toMicroSeconds(), new Variant(jointAngles[n]));
1190 angularVelocity = ri.velRotTarget;
1191
1192 return true;
1193}
1194
1195bool
1197{
1198 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1199
1200 // not implemented
1201
1202 return true;
1203}
1204
1205bool
1207{
1208 // lock engine and data
1209 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1210 ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
1211
1212 for (auto oEngine : kinematicObjects)
1213 {
1214 bool objectFound = false;
1215
1216 for (auto& s : simVisuData.objects)
1217 {
1218 if (s.name == oEngine->getName())
1219 {
1220 objectFound = true;
1221 synchronizeSceneObjectPoses(oEngine, s.objectPoses);
1222 s.updated = true;
1223 break;
1224 }
1225 }
1226
1227 if (!objectFound)
1228 {
1229 ARMARX_WARNING_S << "Object with name " << oEngine->getName()
1230 << " not in synchronized list";
1231 }
1232 }
1233
1234 return true;
1235}
1236
1237bool
1238KinematicsWorld::addObstacleEngine(VirtualRobot::SceneObjectPtr o,
1239 VirtualRobot::SceneObject::Physics::SimulationType simType)
1240{
1241 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1242
1243 ARMARX_DEBUG_S << "Adding obstacle " << o->getName();
1244 VirtualRobot::SceneObjectPtr clonedObj = o->clone(o->getName());
1245
1246 kinematicObjects.push_back(clonedObj);
1247
1248 // since we do not visualize this object we can skip visualization updates
1249 clonedObj->setUpdateVisualization(false);
1250
1251 return true;
1252}
1253
1254std::vector<std::string>
1256{
1257 std::vector<std::string> names;
1258 {
1259 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1260 std::map<std::string, KinematicRobotInfo>::iterator it = kinematicRobots.begin();
1261 while (it != kinematicRobots.end())
1262 {
1263 names.push_back(it->first);
1264 it++;
1265 }
1266 }
1267 return names;
1268}
1269
1270void
1271KinematicsWorld::setObjectSimType(const std::string& objectName,
1272 SceneObject::Physics::SimulationType simType)
1273{
1274 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1275 SceneObjectPtr o = getObject(objectName);
1276 if (!o)
1277 {
1278 ARMARX_WARNING_S << "Could not find object with name " << objectName;
1279 return;
1280 }
1281 //o->setSimType(simType);
1282}
1283
1284void
1285KinematicsWorld::setRobotNodeSimType(const std::string& robotName,
1286 const std::string& robotNodeName,
1287 SceneObject::Physics::SimulationType simType)
1288{
1289 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1290 RobotPtr r = getRobot(robotName);
1291 if (!r)
1292 {
1293 ARMARX_WARNING_S << "Could not find robot with name " << robotName;
1294 return;
1295 }
1296 RobotNodePtr rn = r->getRobotNode(robotNodeName);
1297 if (!rn)
1298 {
1299 ARMARX_WARNING_S << "Could not find robot node with name " << robotNodeName;
1300 return;
1301 }
1302 //rn->setSimType(simType);
1303}
1304
1305std::vector<std::string>
1307{
1308 std::vector<std::string> names;
1309 {
1310 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1311
1312 for (auto& o : kinematicObjects)
1313 {
1314 names.push_back(o->getName());
1315 }
1316 }
1317 return names;
1318}
1319
1320bool
1322{
1323 ARMARX_VERBOSE_S << "Removing obstacle " << name;
1324 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1325 {
1326 SceneObjectPtr o = getObject(name);
1327
1328 if (!o)
1329 {
1330 return false;
1331 }
1332
1333 std::vector<SceneObjectPtr>::iterator it =
1334 find(kinematicObjects.begin(), kinematicObjects.end(), o);
1335
1336 if (it != kinematicObjects.end())
1337 {
1338 kinematicObjects.erase(it);
1339 }
1340 else
1341 {
1342 ARMARX_WARNING_S << "Sync error";
1343 }
1344 }
1345
1346 return true;
1347}
1348
1349void
1351{
1352 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1353 ARMARX_DEBUG << "start sim physics";
1354
1355
1356 // IceUtil::Time startTime = IceUtil::Time::now();
1357 float dt1 = getDeltaTimeMilli();
1358
1359 // the engine has to be stepped with seconds
1360 // max 100 internal loops
1361 ARMARX_DEBUG << deactivateSpam(1) << "dt1: " << dt1 << " ms";
1362 simTimeStepMS = dt1;
1363 // step static objects and robots
1364 stepStaticObjects(dt1 / 1000.0);
1365 stepStaticRobots(dt1 / 1000.0);
1367
1368
1369 currentSimTimeSec += dt1 / 1000.0;
1370 // IceUtil::Time duration = IceUtil::Time::now() - startTime;
1372 ARMARX_DEBUG << "end sim physics, simTime ms:" << simStepExecutionDurationMS;
1373}
1374
1375void
1377{
1378 auto startTime = IceUtil::Time::now(); // this should always be real time and not virtual time
1379 {
1380 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1381
1382 float stepSize = (float)(stepSizeMs) / 1000.0f;
1383 ARMARX_DEBUG_S << "start sim physics: " << VAROUT(stepSize) << VAROUT(stepSizeMs);
1384
1386
1387 // step static robots
1388 stepStaticObjects(stepSize);
1389 stepStaticRobots(stepSize);
1391
1392 currentSimTimeSec += stepSize;
1393 }
1394
1395
1396 if (maxRealTimeSimSpeed > 0)
1397 {
1398 auto duration = (IceUtil::Time::now() - startTime).toMilliSecondsDouble();
1399 const double minStepSizeMs = static_cast<double>(stepSizeMs) / maxRealTimeSimSpeed;
1400 if (duration < minStepSizeMs)
1401 {
1402 ARMARX_DEBUG << "Sim calculation took " << duration << " - Sleeping now for "
1403 << (stepSizeMs - duration);
1404 usleep(1000 * (minStepSizeMs - duration));
1405 }
1406 }
1407
1408 IceUtil::Time duration = IceUtil::Time::now() - startTime;
1409 simStepExecutionDurationMS = (float)duration.toMilliSecondsDouble();
1410 ARMARX_DEBUG << "end sim physics, simTime ms:" << simStepExecutionDurationMS;
1411}
1412
1413void
1415{
1416 // step through all static robots and apply velocities
1417 for (auto dr : kinematicRobots)
1418 {
1419 KinematicRobotInfo ri = dr.second;
1420 std::map<std::string, float> targetPos;
1421 VirtualRobot::RobotPtr kinRob = ri.robot;
1422 ARMARX_DEBUG << "Applying velocities for static robot " << kinRob->getName();
1423 for (auto nv : ri.targetVelocities)
1424 {
1425 if (!kinRob->hasRobotNode(nv.first))
1426 {
1427 ARMARX_ERROR << deactivateSpam(4, nv.first) << "No rn with name " << nv.first;
1428 continue;
1429 }
1430 double change = (nv.second * deltaInSeconds);
1431
1432 //double randomNoiseValue = distribution(generator);
1433 //change += randomNoiseValue;
1434 double newAngle = kinRob->getRobotNode(nv.first)->getJointValue() + change;
1435 targetPos[nv.first] = (float)newAngle;
1436 }
1437 if (targetPos.size() > 0)
1438 {
1439 ARMARX_DEBUG << "Target joint angles:" << targetPos;
1440 kinRob->setJointValues(targetPos);
1441 }
1442 if (ri.velTransTarget.norm() > 0 || ri.velRotTarget.norm() > 0)
1443 {
1444 Eigen::Matrix4f gp = kinRob->getGlobalPose();
1445 gp.block(0, 3, 3, 1) += ri.velTransTarget * deltaInSeconds;
1446 Eigen::Matrix3f m3;
1447 m3 = Eigen::AngleAxisf(ri.velRotTarget(0) * deltaInSeconds, Eigen::Vector3f::UnitX()) *
1448 Eigen::AngleAxisf(ri.velRotTarget(1) * deltaInSeconds, Eigen::Vector3f::UnitY()) *
1449 Eigen::AngleAxisf(ri.velRotTarget(2) * deltaInSeconds, Eigen::Vector3f::UnitZ());
1450 gp.block(0, 0, 3, 3) *= m3;
1451 setRobotPose(kinRob->getName(), gp);
1452 }
1453 }
1454}
1455
1456void
1458{
1459 // Step attached objects
1460 for (auto& o : attachedObjects)
1461 {
1462 if (kinematicRobots.find(o.robotName) == kinematicRobots.end())
1463 {
1464 // Robot not found
1465 continue;
1466 }
1467
1468 VirtualRobot::RobotPtr kinRob = kinematicRobots[o.robotName].robot;
1469
1470 if (!kinRob->hasRobotNode(o.objectName))
1471 {
1472 // Object is not attached
1473 continue;
1474 }
1475
1476 Eigen::Matrix4f pose = kinRob->getRobotNode(o.objectName)->getGlobalPose();
1477
1478 for (auto& kino : kinematicObjects)
1479 {
1480 if (kino->getName() == o.objectName)
1481 {
1482 kino->setGlobalPose(pose);
1483 break;
1484 }
1485 }
1486 }
1487}
1488
1489int
1494
1495std::vector<SimDynamics::DynamicsEngine::DynamicsContactInfo>
1497{
1498 ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
1499 return std::vector<SimDynamics::DynamicsEngine::DynamicsContactInfo>();
1500}
1501
1502std::vector<SceneObjectPtr>
1507
1508void
1509KinematicsWorld::setupFloorEngine(bool enable, const std::string& floorTexture)
1510{
1511
1512 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1513
1514 std::string textureFile = floorTexture;
1515
1516 if (enable)
1517 {
1518 ARMARX_INFO_S << "Creating floor plane...";
1519 Eigen::Vector3f pos;
1520 pos.setZero();
1521 Eigen::Vector3f up = Eigen::Vector3f::UnitZ();
1522 createFloorPlane(pos, up);
1523 }
1524}
1525
1526void
1527KinematicsWorld::enableLogging(const std::string& robotName, const std::string& logFile)
1528{
1529 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1530}
1531
1532bool
1533KinematicsWorld::synchronizeSceneObjectPoses(SceneObjectPtr currentObjEngine,
1534 std::map<std::string, armarx::PoseBasePtr>& objMap)
1535{
1536 if (!currentObjEngine)
1537 {
1538 return false;
1539 }
1540
1541 PosePtr p(new Pose(currentObjEngine->getGlobalPose()));
1542 objMap[currentObjEngine->getName()] = p;
1543 std::vector<SceneObjectPtr> childrenE = currentObjEngine->getChildren();
1544
1545 for (const auto& i : childrenE)
1546 {
1547 if (!synchronizeSceneObjectPoses(i, objMap))
1548 {
1549 return false;
1550 }
1551 }
1552
1553 return true;
1554}
1555
1556bool
1558{
1559 // lock engine and data
1560 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1561
1562 // CONTACTS
1563 /*if (collectContacts)
1564 {
1565 contacts = dynamicsWorld->getEngine()->getContacts();
1566 std::stringstream ss;
1567 for (auto c : contacts)
1568 {
1569 ss << c.objectAName << " < - > " << c.objectBName;
1570 }
1571 ARMARX_DEBUG << "Contacts:" << endl << ss.str();
1572 }*/
1573 return true;
1574}
1575
1576float
1578{
1579 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1580
1581 auto newEndTime = IceUtil::Time::now();
1582 auto frameTime = newEndTime - lastTime;
1583 lastTime = newEndTime;
1584
1585 return (float)(frameTime).toMilliSecondsDouble();
1586 ;
1587}
1588
1589/*
1590int KinematicsWorld::getContactCont()
1591{
1592 ScopedRecursiveLockPtr l = getScopedSyncLock(__FUNCTION__);
1593 return contacts.size();
1594}*/
1595
1596DistanceInfo
1597KinematicsWorld::getRobotNodeDistance(const std::string& robotName,
1598 const std::string& robotNodeName1,
1599 const std::string& robotNodeName2)
1600{
1601 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1602
1603 VirtualRobot::RobotPtr robot = getRobot(robotName);
1604 if (!robot)
1605 {
1606 throw LocalException("Wrong robot name. '") << robotName << "'";
1607 }
1608
1609 if (!robot->hasRobotNode(robotNodeName1))
1610 {
1611 throw LocalException("Wrong robot node name. '") << robotNodeName1 << "'";
1612 }
1613 if (!robot->hasRobotNode(robotNodeName2))
1614 {
1615 throw LocalException("Wrong robot node name. '") << robotNodeName2 << "'";
1616 }
1617
1618 // Compute distance from node to the rest of the robot (does that make sense?!)
1619 Eigen::Vector3f p1, p2;
1620 auto model1 = robot->getRobotNode(robotNodeName1)->getCollisionModel();
1621 auto model2 = robot->getRobotNode(robotNodeName2)->getCollisionModel();
1622 float d = robot->getCollisionChecker()->calculateDistance(model1, model2, p1, p2);
1623 DistanceInfo di;
1624 di.distance = d;
1625 di.p1 = new Vector3(p1);
1626 di.p2 = new Vector3(p2);
1627
1628 return di;
1629}
1630
1631DistanceInfo
1632KinematicsWorld::getDistance(const std::string& robotName,
1633 const std::string& robotNodeName,
1634 const std::string& worldObjectName)
1635{
1636 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
1637
1638 VirtualRobot::RobotPtr robot = getRobot(robotName);
1639 if (!robot)
1640 {
1641 throw LocalException("Wrong robot name. '") << robotName << "'";
1642 }
1643
1644 if (!robot->hasRobotNode(robotNodeName))
1645 {
1646 throw LocalException("Wrong robot node name. '") << robotNodeName << "'";
1647 }
1648 VirtualRobot::SceneObjectPtr so = getObject(worldObjectName);
1649 if (!so)
1650 {
1651 throw LocalException("No object with name '") << worldObjectName << "'";
1652 }
1653 Eigen::Vector3f p1, p2;
1654
1655 float d = robot->getCollisionChecker()->calculateDistance(
1656 robot->getRobotNode(robotNodeName)->getCollisionModel(), so->getCollisionModel(), p1, p2);
1657 DistanceInfo di;
1658 di.distance = d;
1659 di.p1 = new Vector3(p1);
1660 di.p2 = new Vector3(p2);
1661
1662 return di;
1663}
#define float
Definition 16_Level.h:22
std::string timestamp()
class A(deque< T, A >)) ARMARX_OVERLOAD_STD_HASH_FOR_ITERABLE((class T
Enables hashing of std::list.
#define VAROUT(x)
The FramedPose class.
Definition FramedPose.h:281
void setRobotAngularVelocity(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &vel) override
void actuateRobotJoints(const std::string &robotName, const std::map< std::string, float > &angles, const std::map< std::string, float > &velocities) override
ignoring velocity target
std::vector< VirtualRobot::SceneObjectPtr > kinematicObjects
bool removeRobotEngine(const std::string &robotName) override
void setRobotLinearVelocity(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &vel) override
float getRobotJointLimitLo(const std::string &robotName, const std::string &nodeName) override
float getRobotMass(const std::string &robotName) override
bool hasRobot(const std::string &robotName) override
std::map< std::string, float > getRobotJointAngles(const std::string &robotName) override
float getRobotJointAngle(const std::string &robotName, const std::string &nodeName) override
VirtualRobot::SceneObjectPtr getFloor() override
void applyForceObject(const std::string &objectName, const Eigen::Vector3f &force) override
std::vector< std::string > getRobotNames() override
std::map< VirtualRobot::RobotNodePtr, std::pair< IceUtil::Time, float > > jointAngleDerivationFilters
Eigen::Vector3f getRobotLinearVelocity(const std::string &robotName, const std::string &nodeName) override
armarx::DistanceInfo getRobotNodeDistance(const std::string &robotName, const std::string &robotNodeName1, const std::string &robotNodeName2) override
std::map< VirtualRobot::RobotPtr, std::pair< IceUtil::Time, Eigen::Matrix4f > > angularVelocityFilters
armarx::DistanceInfo getDistance(const std::string &robotName, const std::string &robotNodeName, const std::string &worldObjectName) override
std::vector< SimDynamics::DynamicsEngine::DynamicsContactInfo > copyContacts() override
void applyForceRobotNode(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &force) override
std::vector< std::string > getObstacleNames() override
void stepStaticRobots(double deltaInSeconds)
Eigen::Vector3f getRobotAngularVelocity(const std::string &robotName, const std::string &nodeName) override
float getRobotMaxTorque(const std::string &robotName, const std::string &nodeName) override
void actuateRobotJointsPos(const std::string &robotName, const std::map< std::string, float > &angles) override
VirtualRobot::RobotPtr getRobot(const std::string &robotName) override
Eigen::Matrix4f getRobotNodePose(const std::string &robotName, const std::string &robotNodeName) override
void stepPhysicsRealTime() override
Perform one simulation step.
float getRobotJointVelocity(const std::string &robotName, const std::string &nodeName) override
std::map< std::string, float > getRobotJointVelocities(const std::string &robotName) override
bool getRobotStatus(const std::string &robotName, NameValueMap &jointAngles, NameValueMap &jointVelocities, NameValueMap &jointTorques, Eigen::Vector3f &linearVelocity, Eigen::Vector3f &angularVelocity) override
bool synchronizeRobotNodePoses(const std::string &robotName, std::map< std::string, armarx::PoseBasePtr > &objMap) override
bool objectGraspedEngine(const std::string &robotName, const std::string &robotNodeName, const std::string &objectName, Eigen::Matrix4f &storeLocalTransform) override
create a joint
void setRobotLinearVelocityRobotRootFrame(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &vel) override
void stepStaticObjects(double deltaInSeconds)
std::map< std::string, KinematicRobotInfo > kinematicRobots
bool objectReleasedEngine(const std::string &robotName, const std::string &robotNodeName, const std::string &objectName) override
remove a joint
bool removeObstacleEngine(const std::string &name) override
bool hasRobotNode(const std::string &robotName, const std::string &robotNodeName) override
bool synchronizeObjects() override
Eigen::Matrix4f getObjectPose(const std::string &objectName) override
Eigen::Matrix4f getRobotPose(const std::string &robotName) override
void enableLogging(const std::string &robotName, const std::string &logFile) override
std::map< std::string, float > getRobotJointTorques(const std::string &) override
bool synchronizeSimulationDataEngine() override
void applyTorqueObject(const std::string &objectName, const Eigen::Vector3f &torque) override
std::map< std::string, VirtualRobot::RobotPtr > getRobots() override
void applyTorqueRobotNode(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &torque) override
bool addObstacleEngine(VirtualRobot::SceneObjectPtr o, VirtualRobot::SceneObject::Physics::SimulationType simType) override
void setRobotMaxTorque(const std::string &robotName, const std::string &nodeName, float maxTorque) override
void setObjectSimType(const std::string &objectName, VirtualRobot::SceneObject::Physics::SimulationType simType) override
virtual void initialize(int stepSizeMS, float maxRealTimeSimSpeed=1, bool floorPlane=false, std::string floorTexture=std::string())
void setRobotNodeSimType(const std::string &robotName, const std::string &robotNodeName, VirtualRobot::SceneObject::Physics::SimulationType simType) override
bool addRobotEngine(VirtualRobot::RobotPtr robot, double pid_p, double pid_i, double pid_d, const std::string &filename, bool staticRobot, bool selfCollisions) override
float getRobotJointLimitHi(const std::string &robotName, const std::string &nodeName) override
void setRobotAngularVelocityRobotRootFrame(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &vel) override
void setRobotPose(const std::string &robotName, const Eigen::Matrix4f &globalPose) override
VirtualRobot::ObstaclePtr groundObject
virtual VirtualRobot::SceneObjectPtr getObject(const std::string &objectName)
void setObjectPose(const std::string &objectName, const Eigen::Matrix4f &globalPose) override
std::vector< VirtualRobot::SceneObjectPtr > getObjects() override
void stepPhysicsFixedTimeStep() override
Perform one simulation step.
FramedPosePtr toFramedPose(const Eigen::Matrix4f &globalPose, const std::string &robotName, const std::string &frameName) override
toFramedPose Constructs a framed pose
virtual void createFloorPlane(const Eigen::Vector3f &pos, const Eigen::Vector3f &up)
ForceTorqueDataSeq getRobotForceTorqueSensors(const std::string &) override
void setupFloorEngine(bool enable, const std::string &floorTexture) override
bool hasObject(const std::string &instanceName) override
void actuateRobotJointsVel(const std::string &robotName, const std::map< std::string, float > &velocities) override
bool updateForceTorqueSensor(ForceTorqueInfo &ftInfo) override
std::map< VirtualRobot::RobotPtr, std::pair< IceUtil::Time, Eigen::Vector3f > > linearVelocityFilters
bool synchronizeSceneObjectPoses(VirtualRobot::SceneObjectPtr currentObjEngine, std::map< std::string, armarx::PoseBasePtr > &objMap) override
void actuateRobotJointsTorque(const std::string &robotName, const std::map< std::string, float > &torques) override
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition Logging.cpp:99
The Pose class.
Definition Pose.h:243
SimulatedWorldData simReportData
std::vector< GraspingInfo > attachedObjects
virtual ScopedRecursiveLockPtr getScopedSyncLock(const std::string &callStr)
virtual ScopedRecursiveLockPtr getScopedEngineLock(const std::string &callStr)
virtual void setupFloor(bool enable, const std::string &floorTexture)
std::shared_ptr< ScopedRecursiveLock > ScopedRecursiveLockPtr
The Vector3 class.
Definition Pose.h:113
#define ARMARX_DEBUG_S
The logging level for output that is only interesting while debugging.
Definition Logging.h:205
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:216
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_INFO_S
Definition Logging.h:202
#define ARMARX_VERBOSE_S
Definition Logging.h:207
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< Pose > PosePtr
Definition Pose.h:306
IceInternal::Handle< FramedPose > FramedPosePtr
Definition FramedPose.h:272
std::map< std::string, float > actualVelocities
std::map< std::string, float > targetVelocities