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 namespace 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
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 
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 
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 
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 
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 
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
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,
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
847  MujocoPhysicsWorld::updateForceTorqueSensor(ForceTorqueInfo& ftInfo)
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
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:26
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:407
MujocoPhysicsWorld.h
mujoco::SimRobot
A robot in simulation.
Definition: SimRobot.h:10
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:187
armarx::SimulatedWorld::simVisuData
SceneVisuData simVisuData
Definition: SimulatedWorld.h:504
armarx::MujocoPhysicsWorld::stepPhysicsFixedTimeStep
virtual void stepPhysicsFixedTimeStep() override
Perform one simulation step.
armarx::SimulatedWorld::getScopedSyncLock
virtual ScopedRecursiveLockPtr getScopedSyncLock(const std::string &callStr)
Definition: SimulatedWorld.cpp:749
armarx::SimulatedWorld::collectContacts
bool collectContacts
Definition: SimulatedWorld.h:492
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:190
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:30
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
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
armarx::SimMJCF::addFloor
void addFloor(bool enabled, const std::string &texture, const std::string &name, float size)
Definition: SimMjcf.cpp:68
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:272
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::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:129
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:716
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:362
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:26
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:86
mujoco::SimObject
Definition: SimObject.h:11
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:196
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:62
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::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:351
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::control::njoint_controller::platform::platform_follower_controller::NameValueMap
std::map< std::string, float > NameValueMap
Definition: PlatformFollowerController.h:88
armarx::channels::KinematicUnitObserver::jointAngles
const KinematicUnitDatafieldCreator jointAngles("jointAngles")
armarx::MujocoPhysicsWorld::getContactCount
virtual int getContactCount() override
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:19
armarx::viz::data::ElementFlags::names
const simox::meta::IntEnumNames names
Definition: json_elements.cpp:13
armarx::MujocoPhysicsWorld::getRobotJointAngle
virtual float getRobotJointAngle(const std::string &robotName, const std::string &nodeName) override
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
armarx::MujocoPhysicsWorld::setObjectPose
virtual void setObjectPose(const std::string &objectName, const Eigen::Matrix4f &globalPose) override
armarx::SimulatedWorld::currentSimTimeSec
double currentSimTimeSec
Definition: SimulatedWorld.h:486
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:24
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:54
armarx::MujocoPhysicsWorld::getRobotJointVelocity
virtual float getRobotJointVelocity(const std::string &robotName, const std::string &nodeName) override
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
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:27
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:19
armarx::MujocoPhysicsWorld::getObjectPose
virtual Eigen::Matrix4f getObjectPose(const std::string &objectName) override
armarx::SimMJCF::addObjectDefaults
void addObjectDefaults(const std::string &className)
Definition: SimMjcf.cpp:47
armarx::MujocoPhysicsWorld::setRobotLinearVelocityRobotRootFrame
virtual void setRobotLinearVelocityRobotRootFrame(const std::string &robotName, const std::string &robotNodeName, const Eigen::Vector3f &vel) override