MujocoPhysicsWorld.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 Rainer Kartmann ( rainer dot kartmann at student dot kit dot edu )
20 * @date 2019
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25#ifdef MUJOCO_PHYSICS_WORLD
26
27#include "MujocoPhysicsWorld.h"
28
29#include <thread>
30
31#include <VirtualRobot/math/Helpers.h>
32
35
36#include <MujocoX/libraries/Simulation/utils/eigen_conversion.h>
37
38
39namespace fs = std::filesystem;
40
41namespace armarx
42{
43
44 struct FunctionLogger
45 {
46 FunctionLogger(const std::string& functionName) : functionName(functionName)
47 {
48 ARMARX_VERBOSE << "Enter: \t" << functionName << "()";
49 }
50
51 ~FunctionLogger()
52 {
53 ARMARX_VERBOSE << "Exit: \t" << functionName << "()";
54 }
55
56 std::string functionName;
57 };
58
59 //#define THROW
60
61#ifdef THROW
62
63#define NOT_YET_IMPLEMENTED() throw exceptions::user::NotImplementedYetException(__FUNCTION__)
64#else
65
66 //#define NOT_YET_IMPLEMENTED() (void) 0
67#define NOT_YET_IMPLEMENTED() ARMARX_WARNING << "Not implemented: \t" << __FUNCTION__ << "()"
68
69#endif
70
71
72#define DO_LOG_FUNCTIONS
73#ifdef DO_LOG_FUNCTIONS
74#define LOG_FUNCTION() const FunctionLogger __functionLogger__(__FUNCTION__)
75#else
76#define LOG_FUNCTION() (void)0
77#endif
78
79
80 // STATIC
81
82 const fs::path MujocoPhysicsWorld::BASE_MJCF_FILENAME =
83 "ArmarXSimulation/mujoco_base_model.xml";
84
85 const fs::path MujocoPhysicsWorld::TEMP_DIR = fs::temp_directory_path() / "MujocoSimulation";
86
87 const fs::path MujocoPhysicsWorld::TEMP_MODEL_FILE = TEMP_DIR / "SimulationModel.xml";
88
89 const fs::path MujocoPhysicsWorld::TEMP_MESH_DIR_REL = "meshes";
90 const fs::path MujocoPhysicsWorld::TEMP_MESH_DIR = TEMP_DIR / TEMP_MESH_DIR_REL;
91
92 const std::string MujocoPhysicsWorld::FLOOR_NAME = "floor";
93 const std::string MujocoPhysicsWorld::OBJECT_CLASS_NAME = "object";
94
95 // NON-STATIC
96
98 {
99 Logging::setTag("MujocoPhysicsWorld");
100 sim.addCallbackListener(*this);
101 }
102
103 void
104 MujocoPhysicsWorld::initialize(int stepTimeMs,
105 bool floorEnabled,
106 const std::string& floorTexture)
107 {
108 LOG_FUNCTION();
109
110 simMjcf.includeBaseFile(BASE_MJCF_FILENAME, TEMP_DIR);
111 simMjcf.addObjectDefaults(OBJECT_CLASS_NAME);
112
113 fixedTimeStep = std::chrono::milliseconds(stepTimeMs);
114 simMjcf.setTimeStep(fixedTimeStep.count() / 1000.f);
115
116 setupFloorEngine(floorEnabled, floorTexture);
117
118 ARMARX_VERBOSE << "Activating MuJoCo ... with key file " << MUJOCO_KEY_FILE;
119 mujoco::MujocoSim::ensureActivated(MUJOCO_KEY_FILE);
120
121 ARMARX_VERBOSE << "Load empty model ...";
122 reloadModel();
123 sim.simLoopPrepare();
124
125 ARMARX_IMPORTANT << "Initialization finished.";
126 }
127
128 void
129 MujocoPhysicsWorld::onLoadModel(mujoco::Model& model)
130 {
131 LOG_FUNCTION();
132
133 model->opt.timestep = fixedTimeStep.count() / 1000.0;
134
135 // Fetch object IDs.
136
137 floor.update(model);
138 floor.sceneObject = makeFloorObject(model, floor.geom);
139
140 for (auto& objectItem : objects)
141 {
142 objectItem.second.update(model);
143 }
144 }
145
146 void
147 MujocoPhysicsWorld::onMakeData(mujoco::Model& model, mujoco::Data& data)
148 {
149 LOG_FUNCTION();
150 (void)model, (void)data;
151 }
152
153 void
155 {
156 NOT_YET_IMPLEMENTED();
157 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
158 }
159
160 void
162 {
163 LOG_FUNCTION();
164 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
165
166 sim.handleLoadRequest();
167
168 auto start = std::chrono::system_clock::now();
169 auto end = start + std::chrono::milliseconds(getFixedTimeStepMS());
170
171 sim.step();
172 sim.pollEvents();
173 sim.render();
174
175 currentSimTimeSec = sim.data()->time;
176
177 std::chrono::milliseconds sleepTime = std::chrono::duration_cast<std::chrono::milliseconds>(
178 end - std::chrono::system_clock::now());
179 ARMARX_VERBOSE << "Sleeping for " << sleepTime.count() << "ms";
180 std::this_thread::sleep_until(end);
181 }
182
183 int
185 {
186 return static_cast<int>(sim.model()->opt.timestep * 1000);
187 }
188
189 std::vector<std::string>
191 {
192 LOG_FUNCTION();
193 std::vector<std::string> result;
194 std::transform(obstacles.begin(),
195 obstacles.end(),
196 std::back_inserter(result),
197 [](const auto& item) { return item.first; });
198 return result;
199 }
200
201 std::vector<std::string>
203 {
204 LOG_FUNCTION();
205 std::vector<std::string> names;
206 std::transform(robots.begin(),
207 robots.end(),
208 std::back_inserter(names),
209 [](const auto& item) { return item.first; });
210 return names;
211 }
212
213 void
214 MujocoPhysicsWorld::setupFloorEngine(bool enable, const std::string& floorTexture)
215 {
216 LOG_FUNCTION();
217 simMjcf.addFloor(enable, floorTexture, FLOOR_NAME, 20);
218 this->floorTextureFile = floorTexture;
219 }
220
221 bool
223 VirtualRobot::SceneObjectPtr object,
224 VirtualRobot::SceneObject::Physics::SimulationType simType)
225 {
226 LOG_FUNCTION();
227 simMjcf.addObject(object, simType, OBJECT_CLASS_NAME, TEMP_MESH_DIR);
228 obstacles[object->getName()] = object;
229
230 reloadModel();
231 return true;
232 }
233
234 bool
235 MujocoPhysicsWorld::removeObstacleEngine(const std::string& name)
236 {
237 NOT_YET_IMPLEMENTED();
238 return {};
239 }
240
241 bool
242 MujocoPhysicsWorld::removeRobotEngine(const std::string& robotName)
243 {
244 NOT_YET_IMPLEMENTED();
245 return {};
246 }
247
248 bool
250 double pid_p,
251 double pid_i,
252 double pid_d,
253 const std::string& filename,
254 bool staticRobot,
255 bool selfCollisions)
256 {
257 LOG_FUNCTION();
258 ARMARX_IMPORTANT << "Adding robot " << robot->getName() << "\n- filename: \t" << filename
259 << "\n- (p, i, d): \t(" << pid_p << " " << pid_i << " " << pid_d << ")"
260 << "\n- static: \t" << staticRobot << "\n- self coll.: \t"
261 << selfCollisions;
262
263 // lock engine and data
264 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
265
266 if (!sim.isModelLoaded())
267 {
268 ARMARX_ERROR << "Simulation not loaded.";
269 return false;
270 }
271 if (hasRobot(robot->getName()))
272 {
273 ARMARX_ERROR << "More than one robot with identical name is currently not supported.";
274 return false;
275 }
276
277 if (staticRobot)
278 {
279 ARMARX_ERROR << "Static robots are currently not supported.";
280 return false;
281 }
282
283 {
284
285 // Make MJCF robot model.
286 ARMARX_INFO << "Making robot MJCF model.";
287
288 mujoco::SimRobot simRobot(robot);
289
290 simRobot.mjcf = makeRobotMjcfModel(robot);
291
292 // Include Paths must be relative.
293 const fs::path robotModelFile =
294 ArmarXDataPath::relativeTo(TEMP_DIR, simRobot.mjcf.getOutputFile());
295
296 // Include robot in model file.
297 mjcfDocument.addInclude(robotModelFile);
298
299 // Store robot entry.
300 robots[robot->getName()] = std::move(simRobot);
301 }
302
303 // Request reload.
304 reloadModel(false);
305
306 return true;
307 }
308
309 void
310 MujocoPhysicsWorld::actuateRobotJoints(const std::string& robotName,
311 const std::map<std::string, float>& angles,
312 const std::map<std::string, float>& velocities)
313 {
314 NOT_YET_IMPLEMENTED();
315 }
316
317 void
318 MujocoPhysicsWorld::actuateRobotJointsPos(const std::string& robotName,
319 const std::map<std::string, float>& angles)
320 {
321 NOT_YET_IMPLEMENTED();
322 }
323
324 void
325 MujocoPhysicsWorld::actuateRobotJointsVel(const std::string& robotName,
326 const std::map<std::string, float>& velocities)
327 {
328 NOT_YET_IMPLEMENTED();
329 }
330
331 void
332 MujocoPhysicsWorld::actuateRobotJointsTorque(const std::string& robotName,
333 const std::map<std::string, float>& torques)
334 {
335 NOT_YET_IMPLEMENTED();
336 }
337
338 void
339 MujocoPhysicsWorld::applyForceRobotNode(const std::string& robotName,
340 const std::string& robotNodeName,
341 const Eigen::Vector3f& force)
342 {
343 NOT_YET_IMPLEMENTED();
344 }
345
346 void
347 MujocoPhysicsWorld::applyTorqueRobotNode(const std::string& robotName,
348 const std::string& robotNodeName,
349 const Eigen::Vector3f& torque)
350 {
351 NOT_YET_IMPLEMENTED();
352 }
353
354 void
355 MujocoPhysicsWorld::applyForceObject(const std::string& objectName,
356 const Eigen::Vector3f& force)
357 {
358 NOT_YET_IMPLEMENTED();
359 }
360
361 void
362 MujocoPhysicsWorld::applyTorqueObject(const std::string& objectName,
363 const Eigen::Vector3f& torque)
364 {
365 NOT_YET_IMPLEMENTED();
366 }
367
368 std::map<std::string, float>
369 MujocoPhysicsWorld::getRobotJointAngles(const std::string& robotName)
370 {
371 NOT_YET_IMPLEMENTED();
372 return {};
373 }
374
375 float
376 MujocoPhysicsWorld::getRobotJointAngle(const std::string& robotName,
377 const std::string& nodeName)
378 {
379 NOT_YET_IMPLEMENTED();
380 return {};
381 }
382
383 std::map<std::string, float>
384 MujocoPhysicsWorld::getRobotJointVelocities(const std::string& robotName)
385 {
386 NOT_YET_IMPLEMENTED();
387 return {};
388 }
389
390 float
391 MujocoPhysicsWorld::getRobotJointVelocity(const std::string& robotName,
392 const std::string& nodeName)
393 {
394 NOT_YET_IMPLEMENTED();
395 return {};
396 }
397
398 std::map<std::string, float>
399 MujocoPhysicsWorld::getRobotJointTorques(const std::string& robotName)
400 {
401 NOT_YET_IMPLEMENTED();
402 return {};
403 }
404
405 ForceTorqueDataSeq
406 MujocoPhysicsWorld::getRobotForceTorqueSensors(const std::string& robotName)
407 {
408 NOT_YET_IMPLEMENTED();
409 return {};
410 }
411
412 Eigen::Matrix4f
413 MujocoPhysicsWorld::getObjectPose(const std::string& objectName)
414 {
415 NOT_YET_IMPLEMENTED();
416 return {};
417 }
418
419 void
420 MujocoPhysicsWorld::setObjectPose(const std::string& objectName,
421 const Eigen::Matrix4f& globalPose)
422 {
423 NOT_YET_IMPLEMENTED();
424 }
425
426 Eigen::Matrix4f
427 MujocoPhysicsWorld::getRobotPose(const std::string& robotName)
428 {
429 return {};
430 }
431
432 void
433 MujocoPhysicsWorld::setRobotPose(const std::string& robotName,
434 const Eigen::Matrix4f& globalPose)
435 {
436 NOT_YET_IMPLEMENTED();
437 }
438
439 Eigen::Matrix4f
440 MujocoPhysicsWorld::getRobotNodePose(const std::string& robotName,
441 const std::string& robotNodeName)
442 {
443 NOT_YET_IMPLEMENTED();
444 return {};
445 }
446
447 Eigen::Vector3f
448 MujocoPhysicsWorld::getRobotLinearVelocity(const std::string& robotName,
449 const std::string& nodeName)
450 {
451 NOT_YET_IMPLEMENTED();
452 return {};
453 }
454
455 Eigen::Vector3f
456 MujocoPhysicsWorld::getRobotAngularVelocity(const std::string& robotName,
457 const std::string& nodeName)
458 {
459 NOT_YET_IMPLEMENTED();
460 return {};
461 }
462
463 void
464 MujocoPhysicsWorld::setRobotLinearVelocity(const std::string& robotName,
465 const std::string& robotNodeName,
466 const Eigen::Vector3f& vel)
467 {
468 NOT_YET_IMPLEMENTED();
469 }
470
471 void
472 MujocoPhysicsWorld::setRobotAngularVelocity(const std::string& robotName,
473 const std::string& robotNodeName,
474 const Eigen::Vector3f& vel)
475 {
476 NOT_YET_IMPLEMENTED();
477 }
478
479 void
481 const std::string& robotNodeName,
482 const Eigen::Vector3f& vel)
483 {
484 NOT_YET_IMPLEMENTED();
485 }
486
487 void
489 const std::string& robotNodeName,
490 const Eigen::Vector3f& vel)
491 {
492 NOT_YET_IMPLEMENTED();
493 }
494
495 bool
496 MujocoPhysicsWorld::hasObject(const std::string& instanceName)
497 {
498 LOG_FUNCTION();
499 return objects.find(instanceName) != objects.end();
500 }
501
502 bool
503 MujocoPhysicsWorld::hasRobot(const std::string& robotName)
504 {
505 LOG_FUNCTION();
506 return robots.find(robotName) != robots.end();
507 }
508
509 bool
510 MujocoPhysicsWorld::hasRobotNode(const std::string& robotName, const std::string& robotNodeName)
511 {
512 LOG_FUNCTION();
513 return hasRobot(robotName) && getRobot(robotName)->hasRobotNode(robotNodeName);
514 }
515
516 std::vector<VirtualRobot::SceneObjectPtr>
518 {
519 LOG_FUNCTION();
520 std::vector<VirtualRobot::SceneObjectPtr> sceneObjects;
521 std::transform(objects.begin(),
522 objects.end(),
523 std::back_inserter(sceneObjects),
524 [](const auto& item) { return item.second.sceneObject; });
525 return sceneObjects;
526 }
527
529 MujocoPhysicsWorld::getRobot(const std::string& robotName)
530 {
531 LOG_FUNCTION();
532 return robots.at(robotName).robot;
533 }
534
535 std::map<std::string, VirtualRobot::RobotPtr>
537 {
538 LOG_FUNCTION();
539 std::map<std::string, VirtualRobot::RobotPtr> res;
540 for (const auto& item : robots)
541 {
542 res[item.first] = item.second.robot;
543 }
544 return res;
545 }
546
547 float
548 MujocoPhysicsWorld::getRobotJointLimitLo(const std::string& robotName,
549 const std::string& nodeName)
550 {
551 NOT_YET_IMPLEMENTED();
552 return {};
553 }
554
555 float
556 MujocoPhysicsWorld::getRobotJointLimitHi(const std::string& robotName,
557 const std::string& nodeName)
558 {
559 NOT_YET_IMPLEMENTED();
560 return {};
561 }
562
563 float
564 MujocoPhysicsWorld::getRobotMaxTorque(const std::string& robotName, const std::string& nodeName)
565 {
566 NOT_YET_IMPLEMENTED();
567 return {};
568 }
569
570 void
571 MujocoPhysicsWorld::setRobotMaxTorque(const std::string& robotName,
572 const std::string& nodeName,
573 float maxTorque)
574 {
575 NOT_YET_IMPLEMENTED();
576 }
577
578 float
579 MujocoPhysicsWorld::getRobotMass(const std::string& robotName)
580 {
581 NOT_YET_IMPLEMENTED();
582 return {};
583 }
584
585 DistanceInfo
586 MujocoPhysicsWorld::getRobotNodeDistance(const std::string& robotName,
587 const std::string& robotNodeName1,
588 const std::string& robotNodeName2)
589 {
590 NOT_YET_IMPLEMENTED();
591 return {};
592 }
593
594 DistanceInfo
595 MujocoPhysicsWorld::getDistance(const std::string& robotName,
596 const std::string& robotNodeName,
597 const std::string& worldObjectName)
598 {
599 NOT_YET_IMPLEMENTED();
600 return {};
601 }
602
603 std::vector<SimDynamics::DynamicsEngine::DynamicsContactInfo>
605 {
606 LOG_FUNCTION();
607 ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
608
609 std::vector<SimDynamics::DynamicsEngine::DynamicsContactInfo> copy;
610
611 for (const mjContact& contact : contacts)
612 {
613 SimDynamics::DynamicsEngine::DynamicsContactInfo info;
614 info.distance = lengthScaling.meterToMilli(contact.dist);
615 info.objectAName = sim.model().id2nameGeom(contact.geom1);
616 info.objectBName = sim.model().id2nameGeom(contact.geom2);
617
618 Eigen::Vector3f pos = mujoco::utils::toVec3(contact.pos);
619 Eigen::Vector3f normalOnB = mujoco::utils::toVec3(contact.frame);
620
621 info.normalGlobalB = normalOnB;
622 info.posGlobalA = pos + static_cast<float>(contact.dist / 2) * normalOnB;
623 info.posGlobalB = pos - static_cast<float>(contact.dist / 2) * normalOnB;
624
625 info.posGlobalA = lengthScaling.meterToMilli(info.posGlobalA);
626 info.posGlobalB = lengthScaling.meterToMilli(info.posGlobalB);
627
628 info.combinedFriction = contact.friction[0];
629 copy.push_back(info);
630 }
631
632 return copy;
633 }
634
636 MujocoPhysicsWorld::toFramedPose(const Eigen::Matrix4f& globalPose,
637 const std::string& robotName,
638 const std::string& frameName)
639 {
640 NOT_YET_IMPLEMENTED();
641 return {};
642 }
643
644 void
645 MujocoPhysicsWorld::setObjectSimType(const std::string& objectName,
646 VirtualRobot::SceneObject::Physics::SimulationType simType)
647 {
648 NOT_YET_IMPLEMENTED();
649 }
650
651 void
653 const std::string& robotName,
654 const std::string& robotNodeName,
655 VirtualRobot::SceneObject::Physics::SimulationType simType)
656 {
657 NOT_YET_IMPLEMENTED();
658 }
659
660 // SimulatedWorld interface
661
662
663 bool
664 MujocoPhysicsWorld::objectGraspedEngine(const std::string& robotName,
665 const std::string& robotNodeName,
666 const std::string& objectName,
667 Eigen::Matrix4f& storeLocalTransform)
668 {
669 NOT_YET_IMPLEMENTED();
670 return {};
671 }
672
673 bool
674 MujocoPhysicsWorld::objectReleasedEngine(const std::string& robotName,
675 const std::string& robotNodeName,
676 const std::string& objectName)
677 {
678 NOT_YET_IMPLEMENTED();
679 return {};
680 }
681
682 VirtualRobot::SceneObjectPtr
684 {
685 LOG_FUNCTION();
686
687 if (floor.sceneObject && sim.data())
688 {
689 floor.updateSceneObjectPose(sim.data());
690 }
691 return floor.sceneObject;
692 }
693
694 bool
696 {
697 LOG_FUNCTION();
698 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
699
700 if (collectContacts)
701 {
702 contacts.clear();
703 for (int i = 0; i < sim.data()->ncon; ++i)
704 {
705 contacts.push_back(sim.data()->contact[i]);
706 }
707 }
708
709 return true;
710 }
711
712 int
714 {
715 return static_cast<int>(contacts.size());
716 }
717
718 bool
720 {
721 LOG_FUNCTION();
722 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
723 ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
724
725 if (floor.sceneObject && !simVisuData.floor)
726 {
727 simVisuData.floor = true;
728 simVisuData.floorTextureFile = floorTextureFile;
729 }
730
731 for (auto& item : objects)
732 {
733 mujoco::SimObject& object = item.second;
734
735 if (object.body.id() >= 0 && object.sceneObject && sim.data())
736 {
737 object.updateSceneObjectPose(sim.data(), lengthScaling.meterToMilli());
738 }
739
740 VirtualRobot::SceneObjectPtr sceneObject = object.sceneObject;
741
742 bool objectFound = false;
743
744 for (ObjectVisuData& visuData : simVisuData.objects)
745 {
746 if (visuData.name == sceneObject->getName())
747 {
748 objectFound = true;
749 synchronizeSceneObjectPoses(sceneObject, visuData.objectPoses);
750 visuData.updated = true;
751 break;
752 }
753 }
754
755 if (!objectFound)
756 {
757 ARMARX_WARNING << "Object '" << sceneObject->getName()
758 << "' not in synchronized list.";
759 }
760 }
761
762 return true;
763 }
764
765 bool
766 MujocoPhysicsWorld::synchronizeSceneObjectPoses(VirtualRobot::SceneObjectPtr sceneObject,
767 std::map<std::string, PoseBasePtr>& poseMap)
768 {
769 LOG_FUNCTION();
770
771 if (!sceneObject)
772 {
773 return false;
774 }
775
776 poseMap[sceneObject->getName()] = new Pose(sceneObject->getGlobalPose());
777
778 for (VirtualRobot::SceneObjectPtr& child : sceneObject->getChildren())
779 {
780 if (!synchronizeSceneObjectPoses(child, poseMap))
781 {
782 return false;
783 }
784 }
785
786 return true;
787 }
788
789 bool
790 MujocoPhysicsWorld::synchronizeRobotNodePoses(const std::string& robotName,
791 std::map<std::string, PoseBasePtr>& objMap)
792 {
793 LOG_FUNCTION();
794
795 // Lock engine and data.
796 ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
797 ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
798
799 if (!hasRobot(robotName))
800 {
801 ARMARX_ERROR << "Robot '" << robotName << "' does not exist in simulation.";
802 return false;
803 }
804
805 mujoco::SimRobot& robot = robots.at(robotName);
806
807 for (const std::string& nodeName : robot.robot->getRobotNodeNames())
808 {
809 const int bodyID = sim.model().name2idBody(nodeName);
810 objMap[nodeName] = PosePtr(new Pose(sim.data().getBodyPose(bodyID)));
811 }
812
813 return true;
814 }
815
816 bool
817 MujocoPhysicsWorld::getRobotStatus(const std::string& robotName,
818 NameValueMap& jointAngles,
819 NameValueMap& jointVelocities,
820 NameValueMap& jointTorques,
821 Eigen::Vector3f& linearVelocity,
822 Eigen::Vector3f& angularVelocity)
823 {
824 LOG_FUNCTION();
825
826 mujoco::SimRobot& robot = robots.at(robotName);
827
828 for (const auto& node : robot.robot->getConfig()->getNodes())
829 {
830 const std::string& nodeName = node->getName();
831
832 node->isRotationalJoint();
833 const int jointID = sim.model().name2id(mjtObj::mjOBJ_JOINT, nodeName);
834
835 jointAngles[nodeName] = sim.data().getJointValue1D(jointID);
836 jointVelocities[nodeName] = sim.data().getJointVelocity1D(jointID);
837
838 const int actuatorID = sim.model().name2id(mjtObj::mjOBJ_ACTUATOR, nodeName);
839 jointTorques[nodeName] = sim.data().getActivation(actuatorID);
840 }
841
842
843 return true;
844 }
845
846 bool
848 {
849 NOT_YET_IMPLEMENTED();
850 return {};
851 }
852
853 VirtualRobot::ObstaclePtr
854 MujocoPhysicsWorld::makeFloorObject(mujoco::Model& model,
855 const mujoco::SimGeom& floorGeom) const
856 {
857 Eigen::Vector3f size = lengthScaling.meterToMilli(model.getGeomSize(floorGeom));
858
859 VirtualRobot::ObstaclePtr floorObject = VirtualRobot::Obstacle::createBox(
860 size.x(), size.y(), 500, VirtualRobot::VisualizationFactory::Color::Gray());
861
862 floorObject->setName(FLOOR_NAME);
863 floorObject->getVisualization();
864 floorObject->setSimulationType(VirtualRobot::SceneObject::Physics::eStatic);
865
866 return floorObject;
867 }
868
869 VirtualRobot::mujoco::RobotMjcf
870 MujocoPhysicsWorld::makeRobotMjcfModel(const VirtualRobot::RobotPtr& robot) const
871 {
872 VirtualRobot::mujoco::RobotMjcf mjcf(robot);
873
874 // Use absolute paths to avoid issues with relative paths.
875 mjcf.setUseRelativePaths(false);
876 // Scale from mm to m.
877 mjcf.setLengthScale(0.001f);
878
879 mjcf.setOutputFile(TEMP_DIR / (robot->getName() + ".xml"));
880 mjcf.setOutputMeshRelativeDirectory(TEMP_MESH_DIR_REL / robot->getName());
881
882 mjcf.build(VirtualRobot::mujoco::WorldMountMode::FREE,
883 VirtualRobot::mujoco::ActuatorType::MOTOR);
884
885 // Add sensors.
886 mjcf::SensorSection sensors = mjcf.getDocument().sensor();
887
888 // Needed by getRobotStatus().
889 mjcf::VelocimeterSensor velocimeter = sensors.addChild<mjcf::VelocimeterSensor>();
890
891 // TODO: continue adding sensors
892
893 mjcf.save();
894
895 return mjcf;
896 }
897
898 void
899 MujocoPhysicsWorld::reloadModel(bool request)
900 {
901 // does nothing if it already exists
902 fs::create_directory(TEMP_DIR);
903 ARMARX_INFO << "Saving temporary model file and requesting reload.\n " << TEMP_MODEL_FILE;
904 mjcfDocument.saveFile(TEMP_MODEL_FILE);
905
906 if (request)
907 {
908 sim.loadModelRequest(TEMP_MODEL_FILE);
909 }
910 else
911 {
912 sim.loadModel(TEMP_MODEL_FILE);
913 }
914 }
915
916
917} // namespace armarx
918
919#endif
uint8_t data[1]
static std::string relativeTo(const std::string &from, const std::string &to)
Transform an absolute filepath into a relative path of the other absolute filepath.
void setTag(const LogTag &tag)
Definition Logging.cpp:54
virtual bool removeObstacleEngine(const std::string &name) override
virtual ForceTorqueDataSeq getRobotForceTorqueSensors(const std::string &robotName) override
virtual bool objectReleasedEngine(const std::string &robotName, const std::string &robotNodeName, const std::string &objectName) override
remove a joint
virtual float getRobotJointVelocity(const std::string &robotName, const std::string &nodeName) override
virtual void applyTorqueRobotNode(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &torque) override
virtual bool synchronizeSceneObjectPoses(VirtualRobot::SceneObjectPtr currentObjEngine, std::map< std::string, PoseBasePtr > &objMap) override
virtual void setupFloorEngine(bool enable, const std::string &floorTexture) override
virtual void stepPhysicsFixedTimeStep() override
Perform one simulation step.
virtual bool hasObject(const std::string &instanceName) override
virtual VirtualRobot::SceneObjectPtr getFloor() override
virtual void setRobotPose(const std::string &robotName, const Eigen::Matrix4f &globalPose) override
virtual VirtualRobot::RobotPtr getRobot(const std::string &robotName) override
virtual void setRobotNodeSimType(const std::string &robotName, const std::string &robotNodeName, VirtualRobot::SceneObject::Physics::SimulationType simType) override
virtual void setRobotAngularVelocity(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &vel) override
virtual float getRobotMass(const std::string &robotName) override
virtual bool addObstacleEngine(VirtualRobot::SceneObjectPtr o, VirtualRobot::SceneObject::Physics::SimulationType simType) override
virtual bool getRobotStatus(const std::string &robotName, NameValueMap &jointAngles, NameValueMap &jointVelocities, NameValueMap &jointTorques, Eigen::Vector3f &linearVelocity, Eigen::Vector3f &angularVelocity) override
virtual bool objectGraspedEngine(const std::string &robotName, const std::string &robotNodeName, const std::string &objectName, Eigen::Matrix4f &storeLocalTransform) override
create a joint
virtual std::vector< std::string > getObstacleNames() override
virtual void applyForceObject(const std::string &objectName, const Eigen::Vector3f &force) override
virtual void applyForceRobotNode(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &force) override
virtual std::vector< VirtualRobot::SceneObjectPtr > getObjects() override
virtual void onLoadModel(mujoco::Model &model) override
Sets time step and fetches entity IDs.
virtual void setRobotLinearVelocity(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &vel) override
virtual Eigen::Vector3f getRobotLinearVelocity(const std::string &robotName, const std::string &nodeName) override
virtual float getRobotMaxTorque(const std::string &robotName, const std::string &nodeName) override
virtual void setObjectSimType(const std::string &objectName, VirtualRobot::SceneObject::Physics::SimulationType simType) override
virtual std::vector< std::string > getRobotNames() override
virtual void stepPhysicsRealTime() override
Perform one simulation step.
virtual int getFixedTimeStepMS() override
virtual int getContactCount() override
virtual void setRobotAngularVelocityRobotRootFrame(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &vel) override
void initialize(int stepTimeMs, bool floorEnabled, const std::string &floorTexture)
Initialize *this.
virtual void actuateRobotJointsTorque(const std::string &robotName, const std::map< std::string, float > &torques) override
virtual void actuateRobotJointsVel(const std::string &robotName, const std::map< std::string, float > &velocities) override
virtual void setRobotLinearVelocityRobotRootFrame(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &vel) override
virtual bool hasRobot(const std::string &robotName) override
virtual float getRobotJointLimitLo(const std::string &robotName, const std::string &nodeName) override
virtual std::map< std::string, float > getRobotJointVelocities(const std::string &robotName) override
virtual bool removeRobotEngine(const std::string &robotName) override
virtual Eigen::Matrix4f getObjectPose(const std::string &objectName) override
virtual DistanceInfo getDistance(const std::string &robotName, const std::string &robotNodeName, const std::string &worldObjectName) override
virtual bool synchronizeRobotNodePoses(const std::string &robotName, std::map< std::string, PoseBasePtr > &objMap) override
virtual float getRobotJointAngle(const std::string &robotName, const std::string &nodeName) override
virtual void actuateRobotJointsPos(const std::string &robotName, const std::map< std::string, float > &angles) override
virtual std::map< std::string, VirtualRobot::RobotPtr > getRobots() override
virtual std::map< std::string, float > getRobotJointTorques(const std::string &robotName) override
virtual bool synchronizeObjects() override
virtual Eigen::Matrix4f getRobotPose(const std::string &robotName) override
virtual DistanceInfo getRobotNodeDistance(const std::string &robotName, const std::string &robotNodeName1, const std::string &robotNodeName2) override
virtual std::vector< SimDynamics::DynamicsEngine::DynamicsContactInfo > copyContacts() override
virtual void actuateRobotJoints(const std::string &robotName, const std::map< std::string, float > &angles, const std::map< std::string, float > &velocities) override
virtual bool addRobotEngine(VirtualRobot::RobotPtr robot, double pid_p, double pid_i, double pid_d, const std::string &filename, bool staticRobot, bool selfCollisions) override
virtual FramedPosePtr toFramedPose(const Eigen::Matrix4f &globalPose, const std::string &robotName, const std::string &frameName) override
toFramedPose Constructs a framed pose
virtual void onMakeData(mujoco::Model &model, mujoco::Data &data) override
virtual bool updateForceTorqueSensor(ForceTorqueInfo &ftInfo) override
virtual void setRobotMaxTorque(const std::string &robotName, const std::string &nodeName, float maxTorque) override
virtual Eigen::Matrix4f getRobotNodePose(const std::string &robotName, const std::string &robotNodeName) override
virtual bool synchronizeSimulationDataEngine() override
According to other SimulatedWorlds, this method's only job is to update contacts.
virtual Eigen::Vector3f getRobotAngularVelocity(const std::string &robotName, const std::string &nodeName) override
virtual void setObjectPose(const std::string &objectName, const Eigen::Matrix4f &globalPose) override
virtual void applyTorqueObject(const std::string &objectName, const Eigen::Vector3f &torque) override
virtual float getRobotJointLimitHi(const std::string &robotName, const std::string &nodeName) override
virtual bool hasRobotNode(const std::string &robotName, const std::string &robotNodeName) override
virtual std::map< std::string, float > getRobotJointAngles(const std::string &robotName) override
virtual ScopedRecursiveLockPtr getScopedSyncLock(const std::string &callStr)
virtual ScopedRecursiveLockPtr getScopedEngineLock(const std::string &callStr)
std::shared_ptr< ScopedRecursiveLock > ScopedRecursiveLockPtr
VirtualRobot::RobotPtr robot
The VirtualRobot robot.
Definition SimRobot.h:19
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
const KinematicUnitDatafieldCreator jointVelocities("jointVelocities")
const KinematicUnitDatafieldCreator jointAngles("jointAngles")
const KinematicUnitDatafieldCreator jointTorques("jointTorques")
Eigen::Isometry3f Pose
Definition basic_types.h:31
const simox::meta::IntEnumNames names
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