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