28 #define MAX_SIM_TIME_WARNING 25
32 #ifdef MUJOCO_PHYSICS_WORLD
36 #include <SimoxUtility/algorithm/string/string_tools.h>
37 #include <SimoxUtility/json.h>
38 #include <VirtualRobot/Scene.h>
39 #include <VirtualRobot/SceneObject.h>
40 #include <VirtualRobot/XML/ObjectIO.h>
41 #include <VirtualRobot/math/Helpers.h>
47 #include <RobotAPI/interface/core/GeometryBase.h>
59 #include <SimDynamics/DynamicsEngine/DynamicsObject.h>
60 #include <SimDynamics/DynamicsEngine/DynamicsRobot.h>
69 defineOptionalProperty<std::string>(
70 "SimoxSceneFileName",
"",
"Simox/VirtualRobot scene file name, e.g. myScene.xml");
71 defineOptionalProperty<bool>(
"FloorPlane",
true,
"Enable floor plane.");
72 defineOptionalProperty<std::string>(
"FloorTexture",
"",
"Texture file for floor.");
73 defineOptionalProperty<std::string>(
74 "LongtermMemory.SnapshotName",
"",
"Name of snapshot to load the scene")
75 .setCaseInsensitive(
true);
76 defineOptionalProperty<bool>(
77 "LoadSnapshotToWorkingMemory",
true,
"Load the snapshot also into the WorkingMemory");
78 defineOptionalProperty<bool>(
"LoadAgentsFromSnapshot",
80 "Also load the agents from the snapshot into the WorkingMemory");
82 defineOptionalProperty<std::string>(
83 "WorkingMemoryName",
"WorkingMemory",
"Name of WorkingMemory")
84 .setCaseInsensitive(
true);
85 defineOptionalProperty<std::string>(
86 "CommonStorageName",
"CommonStorage",
"Name of CommonStorage")
87 .setCaseInsensitive(
true);
88 defineOptionalProperty<std::string>(
89 "PriorKnowledgeName",
"PriorKnowledge",
"Name of PriorKnowledge")
90 .setCaseInsensitive(
true);
91 defineOptionalProperty<std::string>(
92 "LongtermMemoryName",
"LongtermMemory",
"Name of LongtermMemory")
93 .setCaseInsensitive(
true);
95 defineOptionalProperty<std::string>(
"Scene.ObjectPackage",
97 "Package to search for object models."
98 "Used when loading scenes from JSON files.");
99 defineOptionalProperty<std::string>(
"Scene.Path",
101 "Path to one or multiple JSON scene file(s) to load.\n"
102 "Example: 'PriorKnowledgeData/scenes/MyScene.json'.\n"
103 "Multiple paths are separated by semicolons (';').\n"
104 "The package to load a scene from is automatically"
105 "extracted from its first path segment.");
107 defineOptionalProperty<SimulatorType>(
"SimulationType",
109 "Simulation type (Supported: Bullet, Kinematics, Mujoco)")
113 .setCaseInsensitive(
true);
123 defineOptionalProperty<std::string>(
124 "RobotFileName" + postfix,
126 "Simox/VirtualRobot robot file name, e.g. robot_model.xml");
127 defineOptionalProperty<std::string>(
128 "RobotInstanceName" + postfix,
"",
"Name of this robot instance");
129 defineOptionalProperty<bool>(
130 "RobotIsStatic" + postfix,
132 "A static robot does not move due to the physical environment (i.e. no gravity). \n"
133 "It is a static (but kinematic) object in the world.");
134 defineOptionalProperty<bool>(
"ReportRobotPose",
false,
"Report the global robot pose.");
135 defineOptionalProperty<bool>(
136 "RobotCollisionModel" + postfix,
false,
"Show the collision model of the robot.");
137 defineOptionalProperty<float>(
138 "InitialRobotPose.x" + postfix, 0.f,
"x component of initial robot position (mm)");
139 defineOptionalProperty<float>(
140 "InitialRobotPose.y" + postfix, 0.f,
"y component of initial robot position (mm)");
141 defineOptionalProperty<float>(
142 "InitialRobotPose.z" + postfix, 0.f,
"z component of initial robot position (mm)");
143 defineOptionalProperty<float>(
"InitialRobotPose.roll" + postfix,
145 "Initial robot pose: roll component of RPY angles (radian)");
146 defineOptionalProperty<float>(
"InitialRobotPose.pitch" + postfix,
148 "Initial robot pose: pitch component of RPY angles (radian)");
149 defineOptionalProperty<float>(
"InitialRobotPose.yaw" + postfix,
151 "Initial robot pose: yaw component of RPY angles (radian)");
152 defineOptionalProperty<std::string>(
153 "InitialRobotConfig" + postfix,
155 "Initial robot config as comma separated list (RobotNodeName:value)");
156 defineOptionalProperty<float>(
157 "RobotScaling" + postfix, 1.0f,
"Scaling of the robot (1 = no scaling).");
158 defineOptionalProperty<double>(
159 "RobotControllerPID.p" + postfix, 10.0,
"Setup robot controllers: PID paramter p.");
160 defineOptionalProperty<double>(
161 "RobotControllerPID.i" + postfix, 0.0,
"Setup robot controllers: PID paramter i.");
162 defineOptionalProperty<double>(
163 "RobotControllerPID.d" + postfix, 0.0,
"Setup robot controllers: PID paramter d.");
164 defineOptionalProperty<bool>(
165 "RobotSelfCollisions" + postfix,
167 "If false, the robot bodies will not collide with other bodies of this \n"
168 "robot but with all other bodies in the world. \n"
169 "If true, the robot bodies will collide with all other bodies \n"
170 "(This needs an accurately modelled robot model without self collisions \n"
171 "if the robot does not move.)");
173 defineOptionalProperty<int>(
174 "FixedTimeStepLoopNrSteps",
176 "The maximum number of internal simulation loops (fixed time step mode).\n"
177 "After max number of time steps, the remaining time is interpolated.");
178 defineOptionalProperty<int>(
179 "FixedTimeStepStepTimeMS",
181 "The simulation's internal timestep (fixed time step mode). \n"
182 "This property determines the precision of the simulation. \n"
183 "Needs to be set to bigger values for slow PCs, but the simulation results might be bad. "
184 "Smaller value for higher precision, but slower calculation.");
185 defineOptionalProperty<int>(
"StepTimeMS", 25,
"The simulation's time progress per step. ");
186 defineOptionalProperty<bool>(
189 "If true the timestep is adjusted to the computing power of the host and \n"
190 "the time progress in real time. Can result in bad results on slow PCs. \n"
191 "The property StepTimeMS has then no effect. FixedTimeStepStepTimeMS needs \n"
192 "to be adjusted if real time cannot be achieved on slower PCs.");
193 defineOptionalProperty<float>(
196 "If not zero and the real time mode is off, the simulator will not run \n"
197 "\tfaster than real-time * MaxRealTime even if the machine is fast enough \n"
198 "\t(a sleep is inserted to slow down the simulator - the precision remains unchanged).\n"
199 "\tIf set to 2, the simulator will not run faster than double speed. \n"
200 "\tIf set to 0.5, the simulator will not run faster than half speed. \n"
201 "\tIf set to 0, the simulator will run as fast as possible.\n");
203 defineOptionalProperty<bool>(
206 "Enable robot logging. If true, the complete robot state is logged to a file each step.");
208 defineOptionalProperty<int>(
"ReportVisuFrequency",
210 "How often should the visualization data be published. Value is "
211 "given in Hz. (0 to disable)");
212 defineOptionalProperty<std::string>(
213 "ReportVisuTopicName",
214 "SimulatorVisuUpdates",
215 "The topic on which the visualization updates are published.");
216 defineOptionalProperty<int>(
217 "ReportDataFrequency",
219 "How often should the robot data be published. Value is given in Hz. (0 to disable)");
220 defineOptionalProperty<std::string>(
223 "Fixate objects or parts of a robot in the world. Comma separated list. \n"
224 "Define objects by their name, robots can be defined with robotName:RobotNodeName");
225 defineOptionalProperty<bool>(
"DrawCoMVisu",
227 "If true the CoM of each robot is drawn as a circle on the ground "
228 "after each simulation cycle.");
270 std::string snapshotName = getProperty<std::string>(
"LongtermMemory.SnapshotName").getValue();
272 if (!snapshotName.empty())
274 ARMARX_LOG <<
"UsingProxy LongtermMemory for snapshot " << snapshotName;
275 usingProxy(getProperty<std::string>(
"WorkingMemoryName").getValue());
276 usingProxy(getProperty<std::string>(
"LongtermMemoryName").getValue());
277 usingProxy(getProperty<std::string>(
"CommonStorageName").getValue());
278 usingProxy(getProperty<std::string>(
"PriorKnowledgeName").getValue());
282 ARMARX_LOG <<
"Not using LongtermMemoryProxy";
285 bool floorPlane = getProperty<bool>(
"FloorPlane").getValue();
286 std::string floorTexture = getProperty<std::string>(
"FloorTexture");
291 simulatorType = getProperty<SimulatorType>(
"SimulationType");
301 const int stepTimeMs = getProperty<int>(
"StepTimeMS");
302 const float maxRealTime = getProperty<float>(
"MaxRealTime");
306 switch (simulatorType)
311 kw->initialize(stepTimeMs, maxRealTime, floorPlane, floorTexture);
317 int bulletFixedTimeStepMS = getProperty<int>(
"FixedTimeStepStepTimeMS").getValue();
318 int bulletFixedTimeStepMaxNrLoops =
319 getProperty<int>(
"FixedTimeStepLoopNrSteps").getValue();
321 bw->initialize(stepTimeMs,
322 bulletFixedTimeStepMS,
323 bulletFixedTimeStepMaxNrLoops,
332 #ifdef MUJOCO_PHYSICS_WORLD
336 mw->initialize(stepTimeMs, floorPlane, floorTexture);
340 ARMARX_ERROR <<
"Simulator type 'mujoco' is not supported, since simulator was built "
342 <<
"\nGet the package MujocoX from: https://gitlab.com/h2t/mujoco .";
355 Simulator::addRobotsFromProperties()
364 if (!getProperty<std::string>(
"RobotFileName" + postfix).isSet() ||
365 getProperty<std::string>(
"RobotFileName" + postfix).getValue().
empty())
370 std::string robotFile = getProperty<std::string>(
"RobotFileName" + postfix).getValue();
373 VirtualRobot::MathTools::rpy2eigen4f(
374 getProperty<float>(
"InitialRobotPose.roll" + postfix).
getValue(),
375 getProperty<float>(
"InitialRobotPose.pitch" + postfix).
getValue(),
376 getProperty<float>(
"InitialRobotPose.yaw" + postfix).
getValue(),
380 Eigen::Vector3f(getProperty<float>(
"InitialRobotPose.x" + postfix).
getValue(),
381 getProperty<float>(
"InitialRobotPose.y" + postfix).
getValue(),
382 getProperty<float>(
"InitialRobotPose.z" + postfix).
getValue());
385 std::map<std::string, float> initConfig;
386 if (getProperty<std::string>(
"InitialRobotConfig" + postfix).isSet())
389 std::string confStr =
390 getProperty<std::string>(
"InitialRobotConfig" + postfix).getValue();
391 std::vector<std::string> confList =
Split(confStr,
",",
true,
true);
392 for (
auto& pos : confList)
395 std::vector<std::string> d =
Split(pos,
":",
true,
true);
401 std::string name = d.at(0);
403 initConfig[name] =
static_cast<float>(atof(d.at(1).c_str()));
404 ARMARX_INFO <<
"1:'" << name <<
"', 2:" << initConfig[name];
409 double pid_p = getProperty<double>(
"RobotControllerPID.p" + postfix).getValue();
410 double pid_i = getProperty<double>(
"RobotControllerPID.i" + postfix).getValue();
411 double pid_d = getProperty<double>(
"RobotControllerPID.d" + postfix).getValue();
413 std::string robotInstanceName =
414 getProperty<std::string>(
"RobotInstanceName" + postfix).getValue();
416 bool staticRobot = getProperty<bool>(
"RobotIsStatic" + postfix).getValue();
417 bool colModelRobot = getProperty<bool>(
"RobotCollisionModel" + postfix).getValue();
418 float scaling = getProperty<float>(
"RobotScaling" + postfix).getValue();
419 bool selfCollisions = getProperty<bool>(
"RobotSelfCollisions" + postfix);
420 if (!robotFile.empty())
422 std::string robFileGlobal = robotFile;
426 ARMARX_ERROR <<
"Could not find robot file " << robotFile;
430 ARMARX_INFO <<
"Adding robot with name '" << robotInstanceName <<
"' from file "
450 Simulator::addSceneFromFile(
const std::string& sceneFile)
455 ARMARX_ERROR <<
"Could not find scene file " << sceneFile;
467 Simulator::addSceneFromMemorySnapshot(
const std::string& snapshotName)
472 ARMARX_ERROR <<
"No connection to memory - cannot add snapshot!";
475 memoryPrx = getProxy<WorkingMemoryInterfacePrx>(
476 getProperty<std::string>(
"WorkingMemoryName").
getValue());
481 getProperty<std::string>(
"LongtermMemoryName").
getValue());
482 WorkingMemorySnapshotInterfacePrx snapshotInterfacePrx;
486 ARMARX_LOG <<
"Loading snapshot " << snapshotName;
490 snapshotInterfacePrx =
493 if (getProperty<bool>(
"LoadSnapshotToWorkingMemory").
getValue())
495 if (snapshotInterfacePrx)
501 ARMARX_ERROR <<
"Could not get snapshot segment from longterm memory...";
505 catch (memoryx::SnapshotNotFoundException&)
507 ARMARX_ERROR <<
"Could not find snapshot: " << snapshotName;
511 ARMARX_ERROR <<
"Failed to load snapshot with name:" << snapshotName;
516 ARMARX_ERROR <<
"Could not get PriorKnowledge/LongtermMemory/WorkingMemory Proxy";
521 ARMARX_LOG <<
"Found and opened snapshot " << snapshotName;
526 ARMARX_ERROR <<
"Failed to open snapshot " << snapshotName;
531 Simulator::addSceneFromSdfFile(
const std::string& scenePath)
535 if (!cmakeFinder.packageFound())
537 ARMARX_WARNING <<
"Could not find CMake package " << scenePackage <<
".";
541 std::filesystem::path dataDir = cmakeFinder.getDataDir();
542 std::filesystem::path path = dataDir / scenePath;
545 sdf::SDFPtr sdfFile(
new sdf::SDF());
548 std::filesystem::path modelDirectory = path.parent_path();
550 const std::string modelURI =
"model://";
552 auto findFileCallback = [
this, &modelURI](
const std::string& uri) -> std::string
554 std::stringstream ss;
555 ss <<
"Find '" << uri <<
"' ... -> ";
557 const std::string classIDStr = simox::alg::remove_prefix(uri, modelURI);
562 if (std::optional<PackageFileLocation> modelPath = info->getModel())
564 std::filesystem::path result = modelPath->absolutePath.parent_path();
578 parser.AddURIPath(modelURI, modelDirectory.string());
579 parser.SetFindCallback(findFileCallback);
582 sdf::Errors errors = root.Load(path.string(),
parser);
584 for (
auto const& error : errors)
595 if (root.WorldCount() == 0)
601 if (root.WorldCount() > 1)
607 sdf::World* world = root.WorldByIndex(0);
608 auto addSceneObject = [&](sdf::Model* model)
610 const std::string name = model->Name();
613 ARMARX_WARNING <<
"Object with name \"" << name <<
"\" already exists.";
617 const std::string uri = model->Uri();
620 ARMARX_WARNING <<
"No URI set for object \"" << name <<
"\" in SDF.";
626 const std::filesystem::path modelPath = findFileCallback(uri);
628 gz::math::Pose3d pose = model->RawPose();
630 const float meterToMillimeter = 1000.0F;
632 Eigen::Vector3f position;
633 position.x() =
static_cast<float>(pose.Pos().X() * meterToMillimeter);
634 position.y() =
static_cast<float>(pose.Pos().Y() * meterToMillimeter);
635 position.z() =
static_cast<float>(pose.Pos().Z() * meterToMillimeter);
638 orientation.x() =
static_cast<float>(pose.Rot().X());
639 orientation.y() =
static_cast<float>(pose.Rot().Y());
640 orientation.z() =
static_cast<float>(pose.Rot().Z());
641 orientation.w() =
static_cast<float>(pose.Rot().W());
643 auto isStatic = model->Static();
645 std::string robotFilename = modelPath.filename().generic_string() +
".urdf";
646 std::filesystem::path robotPath = modelPath / robotFilename;
648 std::string xmlFilename = modelPath.filename().generic_string() +
".xml";
649 std::filesystem::path xmlPath = modelPath / xmlFilename;
651 if (std::filesystem::exists(xmlPath))
653 ARMARX_INFO <<
"Loading object '" << name <<
"' from object XML file " << xmlPath;
654 VirtualRobot::ManipulationObjectPtr simoxObject =
655 VirtualRobot::ObjectIO::loadManipulationObject(xmlPath.string());
657 simoxObject->setGlobalPose(simox::math::pose(position, orientation));
659 VirtualRobot::SceneObject::Physics::SimulationType simType =
660 isStatic ? VirtualRobot::SceneObject::Physics::eKinematic
661 : VirtualRobot::SceneObject::Physics::eDynamic;
663 simoxObject->setSimulationType(simType);
664 simoxObject->setFilename(xmlPath.string());
665 simoxObject->setName(name);
668 simoxObject, simType, xmlPath.string(), name, {}, scenePackage);
670 else if (std::filesystem::exists(robotPath))
672 ARMARX_INFO <<
"Loading object '" << name <<
"' from robot URDF file " << xmlPath;
675 robot->setGlobalPose(simox::math::pose(position, orientation));
677 VirtualRobot::SceneObject::Physics::SimulationType simType =
678 isStatic ? VirtualRobot::SceneObject::Physics::eKinematic
679 : VirtualRobot::SceneObject::Physics::eDynamic;
681 robot->setSimulationType(simType);
682 robot->setFilename(robotPath.string());
683 robot->setName(name);
685 physicsWorld->addRobot(robot, 10.0, 0.0, 0.0, robotPath.string(), isStatic);
690 <<
"Not adding object '" << name
691 <<
"' because neither object XML nor robot URDF file exist. (Tried object XML = "
692 << xmlPath <<
" and robot URDF = " << robotPath <<
")";
698 addSceneObject(world->ModelByIndex(
index));
703 Simulator::addSceneFromJsonFile(
const std::string& scenePath)
705 std::string mutScenePath = scenePath;
708 mutScenePath +=
".json";
713 if (!cmakeFinder.packageFound())
715 ARMARX_WARNING <<
"Could not find CMake package " << scenePackage <<
".";
719 std::filesystem::path dataDir = cmakeFinder.getDataDir();
720 std::filesystem::path path = dataDir / scenePath;
725 scene = simox::json::read<armarx::objects::Scene>(path);
727 catch (
const simox::json::error::JsonError& e)
729 ARMARX_WARNING <<
"Loading scene snapshot failed: \n" << e.what();
733 std::map<ObjectID, int> idCounters;
734 for (
const auto&
object : scene.
objects)
742 addJsonSceneObject(
object, idCounters);
748 std::map<ObjectID, int>& idCounters)
751 const std::string name =
754 :
object.instanceName)
759 ARMARX_INFO <<
"Object with name \"" << name <<
"\" already exists.";
763 ARMARX_INFO <<
"Adding object with name \"" << name <<
"\" to scene.";
766 VirtualRobot::ManipulationObjectPtr simoxObject =
767 VirtualRobot::ObjectIO::loadManipulationObject(objectInfo->simoxXML().absolutePath);
768 simoxObject->setGlobalPose(simox::math::pose(
object.position,
object.orientation));
770 VirtualRobot::SceneObject::Physics::SimulationType simType;
771 if (
object.isStatic.has_value())
773 simType = *
object.isStatic ? VirtualRobot::SceneObject::Physics::eKinematic
774 : VirtualRobot::SceneObject::Physics::eDynamic;
778 simType = VirtualRobot::SceneObject::Physics::eKinematic;
782 simoxObject->setSimulationType(simType);
784 simoxObject->setName(name);
791 Simulator::fixateRobotNode(
const std::string& robotName,
const std::string& robotNodeName)
793 ARMARX_VERBOSE <<
"Fixing robot node" << robotName <<
"." << robotNodeName;
795 robotName, robotNodeName, VirtualRobot::SceneObject::Physics::eStatic);
799 Simulator::fixateObject(
const std::string& objectName)
802 physicsWorld->setObjectSimType(objectName, VirtualRobot::SceneObject::Physics::eStatic);
810 addRobotsFromProperties();
812 std::string sceneFile = getProperty<std::string>(
"SimoxSceneFileName").getValue();
813 if (!sceneFile.empty())
815 addSceneFromFile(sceneFile);
818 std::string snapshotName = getProperty<std::string>(
"LongtermMemory.SnapshotName").getValue();
819 if (!snapshotName.empty())
821 addSceneFromMemorySnapshot(snapshotName);
824 std::string objectPackage = getProperty<std::string>(
"Scene.ObjectPackage").getValue();
827 std::string scenePaths = getProperty<std::string>(
"Scene.Path").getValue();
828 if (!scenePaths.empty())
833 std::filesystem::path path = scenePath;
834 std::string sdfExtension =
".sdf";
836 if (path.has_extension() && path.extension().string() == sdfExtension)
838 ARMARX_INFO <<
"Loading scene from SDF file '" << scenePath <<
"' ...";
839 addSceneFromSdfFile(scenePath);
843 ARMARX_INFO <<
"Loading scene from JSON file '" << scenePath <<
"' ...";
844 addSceneFromJsonFile(scenePath);
850 std::string fixedObjects = getProperty<std::string>(
"FixedObjects").getValue();
851 if (!fixedObjects.empty())
853 std::vector<std::string> objects =
Split(fixedObjects,
",;");
854 for (
auto o : objects)
856 std::vector<std::string> rob =
Split(o,
":");
860 fixateRobotNode(rob.at(0), rob.at(1));
876 SimulatedRobotState state;
878 state.hasRobot =
true;
879 state.timestampInMicroSeconds = timestamp.toMicroSeconds();
891 if (forceTorqueSensor.enable)
893 ForceTorqueData& ftData = state.forceTorqueValues.emplace_back();
894 ftData.force =
new Vector3(forceTorqueSensor.currentForce);
895 ftData.torque =
new Vector3(forceTorqueSensor.currentTorque);
896 ftData.sensorName = forceTorqueSensor.sensorName;
897 ftData.nodeName = forceTorqueSensor.robotNodeName;
910 <<
"Was able to find a reference to the CommonStorage. Continue with existing "
911 "connection to memory.";
914 CommonStorageInterfacePrx commonStoragePrx =
917 if (commonStoragePrx)
920 <<
"Was able to find a reference to the CommonStorage. Reset GridFSManager and "
921 "continue with memory.";
927 <<
"Could not get CommonStorage Proxy - continuing without memory";
940 entityDrawerPrx = getTopic<memoryx::EntityDrawerInterfacePrx>(
"DebugDrawerUpdates");
942 int hzVisu = getProperty<int>(
"ReportVisuFrequency").getValue();
943 int hzData = getProperty<int>(
"ReportDataFrequency").getValue();
944 std::string top = getProperty<std::string>(
"ReportVisuTopicName").getValue();
948 ARMARX_DEBUG <<
"Starting periodic simulation task in ArmarX Simulator";
950 timeTopicPrx = ManagedIceObject::getTopic<TimeServerListenerPrx>(TIME_TOPIC_NAME);
953 ARMARX_DEBUG <<
"Starting periodic visualization report task in ArmarX Simulator";
967 int cycleTime = 1000 / hzVisu;
974 ARMARX_DEBUG <<
"Starting periodic data report task in ArmarX Simulator";
983 int cycleTime = 1000 / hzData;
1046 IceUtil::ThreadControl threadControl = getThreadControl();
1051 threadControl.join();
1062 auto lockEngine =
physicsWorld->getScopedEngineLock(__FUNCTION__);
1063 auto lockData =
physicsWorld->getScopedSyncLock(__FUNCTION__);
1099 const std::string segmentName =
"objectInstances";
1103 PersistentEntitySegmentBasePrx segInstances = snapshotInterfacePrx->getSegment(segmentName);
1107 ARMARX_ERROR <<
"Segment not found in snapshot: " << segmentName;
1112 PersistentObjectClassSegmentBasePrx classesSegmentPrx =
1115 if (!classesSegmentPrx)
1117 ARMARX_ERROR <<
"Classes Segment not found in PriorKnowledge";
1122 EntityIdList ids = segInstances->getAllEntityIds();
1126 for (EntityIdList::const_iterator it = ids.begin(); it != ids.end(); ++it)
1128 EntityBasePtr snapEntity = segInstances->getEntityById(*it);
1130 std::string
id = snapInstance->getId();
1131 bool ok = snapInstance->hasAttribute(
"classes");
1136 <<
" has no classes attribute, could not load iv files, skipping";
1140 std::string classesName = snapInstance->getAttributeValue(
"classes")->getString();
1142 EntityBasePtr classesEntity = classesSegmentPrx->getEntityByName(classesName);
1146 ARMARX_ERROR <<
"Classes Segment does not know class with name : " << classesName;
1150 ObjectClassPtr objectClass = ObjectClassPtr::dynamicCast(classesEntity);
1154 ARMARX_ERROR <<
"Could not cast class entity : " << classesName;
1166 m.block(0, 3, 3, 1) = objPos->toEigen();
1174 m.block(0, 0, 3, 3) = objOrient->toEigen();
1180 VirtualRobot::ManipulationObjectPtr mo = sw->getManipulationObject()->clone(
1181 sw->getManipulationObject()
1186 std::string instanceName = snapInstance->getName();
1190 instanceName = snapInstance->getName() +
"_" +
to_string(i);
1193 if (instanceName != snapInstance->getName())
1195 ARMARX_INFO <<
"Object instance with name '" << snapInstance->getName()
1196 <<
"'' already exists - using '" << instanceName <<
"'";
1199 mo->getSimulationType() == VirtualRobot::SceneObject::Physics::eStatic;
1200 addObject(objectClass, instanceName, poseGlobal, isStatic);
1211 if (getProperty<bool>(
"LoadAgentsFromSnapshot").getValue())
1224 const std::string segmentName =
"agentInstances";
1228 PersistentEntitySegmentBasePrx segInstances = snapshotInterfacePrx->getSegment(segmentName);
1232 ARMARX_ERROR <<
"Segment not found in snapshot: " << segmentName;
1236 EntityIdList ids = segInstances->getAllEntityIds();
1239 for (EntityIdList::const_iterator it = ids.begin(); it != ids.end(); ++it)
1241 EntityBasePtr snapEntity = segInstances->getEntityById(*it);
1244 auto agentName = snapAgent->getName();
1245 std::string agentModelFile = snapAgent->getAgentFilePath();
1246 std::string absModelFile;
1249 ARMARX_INFO <<
"Robot with name '" << agentName <<
"' already exists.";
1255 <<
"'- file not found: " << agentModelFile;
1261 if (
addRobot(agentName, absModelFile, snapAgent->getPose()->toEigen(), agentModelFile)
1280 const Ice::Current&)
1282 physicsWorld->actuateRobotJoints(robotName, angles, velocities);
1288 const Ice::Current&)
1290 physicsWorld->actuateRobotJointsPos(robotName, angles);
1296 const Ice::Current&)
1298 physicsWorld->actuateRobotJointsVel(robotName, velocities);
1304 const Ice::Current&)
1306 physicsWorld->actuateRobotJointsTorque(robotName, torques);
1311 const PoseBasePtr& globalPose,
1312 const Ice::Current&)
1315 qa.x = globalPose->orientation->qx;
1316 qa.y = globalPose->orientation->qy;
1317 qa.z = globalPose->orientation->qz;
1318 qa.w = globalPose->orientation->qw;
1320 gp(0, 3) = globalPose->position->x;
1321 gp(1, 3) = globalPose->position->y;
1322 gp(2, 3) = globalPose->position->z;
1328 const std::string& robotNodeName,
1329 const Vector3BasePtr& force,
1330 const Ice::Current&)
1332 Vector3Ptr v3p = Vector3Ptr::dynamicCast(force);
1333 physicsWorld->applyForceRobotNode(robotName, robotNodeName, v3p->toEigen());
1338 const std::string& robotNodeName,
1339 const Vector3BasePtr& torque,
1340 const Ice::Current&)
1342 Vector3Ptr v3p = Vector3Ptr::dynamicCast(torque);
1343 physicsWorld->applyTorqueRobotNode(robotName, robotNodeName, v3p->toEigen());
1348 const Vector3BasePtr& force,
1349 const Ice::Current&)
1351 Vector3Ptr v3p = Vector3Ptr::dynamicCast(force);
1352 physicsWorld->applyForceObject(objectName, v3p->toEigen());
1357 const Vector3BasePtr& torque,
1358 const Ice::Current&)
1360 Vector3Ptr v3p = Vector3Ptr::dynamicCast(torque);
1361 physicsWorld->applyTorqueObject(objectName, v3p->toEigen());
1366 const std::string& instanceName,
1367 const PoseBasePtr& globalPose,
1369 const Ice::Current&)
1374 ARMARX_WARNING <<
"Cannot add object - no connection to common storage";
1377 auto lockEngine =
physicsWorld->getScopedEngineLock(__FUNCTION__);
1378 auto lockData =
physicsWorld->getScopedSyncLock(__FUNCTION__);
1383 ObjectClassPtr objectClass = ObjectClassPtr::dynamicCast(objectClassBase);
1387 ARMARX_ERROR <<
"Object with instance name \"" << instanceName <<
"\" already exists";
1393 ARMARX_ERROR <<
"Invalid object class; could not create object with instance name "
1401 VirtualRobot::ManipulationObjectPtr mo =
1402 sw->getManipulationObject();
1406 ARMARX_ERROR <<
"Could not retrieve manipulation object of object class "
1407 << objectClass->getName();
1414 mo->setName(instanceName);
1416 ARMARX_LOG <<
"Adding manipulation object " << mo->getName() <<
" of class "
1417 << objectClass->getName();
1421 qa.x = globalPose->orientation->qx;
1422 qa.y = globalPose->orientation->qy;
1423 qa.z = globalPose->orientation->qz;
1424 qa.w = globalPose->orientation->qw;
1426 gp(0, 3) = globalPose->position->x;
1427 gp(1, 3) = globalPose->position->y;
1428 gp(2, 3) = globalPose->position->z;
1429 mo->setGlobalPose(gp);
1430 VirtualRobot::SceneObject::Physics::SimulationType simType =
1431 (isStatic) ? VirtualRobot::SceneObject::Physics::eKinematic
1432 : VirtualRobot::SceneObject::Physics::eDynamic;
1433 physicsWorld->addObstacle(mo, simType, std::string(), objectClassBase->getName());
1443 const std::string& instanceName,
1444 const PoseBasePtr& globalPose,
1446 const Ice::Current&)
1448 ARMARX_INFO <<
"Add object from packagePath " << packagePath <<
": " << instanceName;
1454 auto lockEngine =
physicsWorld->getScopedEngineLock(__FUNCTION__);
1455 auto lockData =
physicsWorld->getScopedSyncLock(__FUNCTION__);
1461 ARMARX_ERROR <<
"Could not find file: \"" << packagePath.path <<
"\".";
1471 ARMARX_ERROR <<
"Object with instance name \"" << instanceName <<
"\" already exists";
1476 VirtualRobot::ManipulationObjectPtr mo =
1477 VirtualRobot::ObjectIO::loadManipulationObject(
filename);
1488 mo->setName(instanceName);
1494 qa.x = globalPose->orientation->qx;
1495 qa.y = globalPose->orientation->qy;
1496 qa.z = globalPose->orientation->qz;
1497 qa.w = globalPose->orientation->qw;
1499 gp(0, 3) = globalPose->position->x;
1500 gp(1, 3) = globalPose->position->y;
1501 gp(2, 3) = globalPose->position->z;
1502 mo->setGlobalPose(gp);
1503 VirtualRobot::SceneObject::Physics::SimulationType simType =
1504 (isStatic) ? VirtualRobot::SceneObject::Physics::eKinematic
1505 : VirtualRobot::SceneObject::Physics::eDynamic;
1519 const DrawColor& color,
1520 const std::string& instanceName,
1521 const PoseBasePtr& globalPose,
1523 const Ice::Current&)
1527 auto lockEngine =
physicsWorld->getScopedEngineLock(__FUNCTION__);
1528 auto lockData =
physicsWorld->getScopedSyncLock(__FUNCTION__);
1535 ARMARX_ERROR <<
"Object with instance name \"" << instanceName <<
"\" already exists";
1539 if (depth <= 0 || width <= 0 || height <= 0)
1541 ARMARX_ERROR <<
"Invalid properties; could not create object with instance name "
1550 c.transparency = color.a;
1551 VirtualRobot::ObstaclePtr o = VirtualRobot::Obstacle::createBox(width, height, depth,
c);
1561 o->setName(instanceName);
1563 ARMARX_LOG <<
"Adding box object " << o->getName();
1569 qa.x = globalPose->orientation->qx;
1570 qa.y = globalPose->orientation->qy;
1571 qa.z = globalPose->orientation->qz;
1572 qa.w = globalPose->orientation->qw;
1574 gp(0, 3) = globalPose->position->x;
1575 gp(1, 3) = globalPose->position->y;
1576 gp(2, 3) = globalPose->position->z;
1577 o->setGlobalPose(gp);
1578 VirtualRobot::SceneObject::Physics::SimulationType simType =
1579 (isStatic) ? VirtualRobot::SceneObject::Physics::eStatic
1580 : VirtualRobot::SceneObject::Physics::eDynamic;
1582 BoxVisuPrimitivePtr bp(
new BoxVisuPrimitive());
1585 bp->height = height;
1587 bp->massKG = massKG;
1590 physicsWorld->addObstacle(o, simType, std::string(), std::string(), bp);
1603 auto lockData =
physicsWorld->getScopedSyncLock(__FUNCTION__);
1612 auto lockEngine =
physicsWorld->getScopedEngineLock(__FUNCTION__);
1613 auto lockData =
physicsWorld->getScopedSyncLock(__FUNCTION__);
1619 ARMARX_ERROR <<
"Object with instance name \"" << instanceName <<
"\" does not exist";
1623 ARMARX_LOG <<
"Removing object " << instanceName;
1627 ARMARX_ERROR <<
"Could not remove object with instance name \"" << instanceName <<
"\"";
1639 const PoseBasePtr& globalPose,
1640 const Ice::Current&)
1643 q.x = globalPose->orientation->qx;
1644 q.y = globalPose->orientation->qy;
1645 q.z = globalPose->orientation->qz;
1646 q.w = globalPose->orientation->qw;
1648 gp(0, 3) = globalPose->position->x;
1649 gp(1, 3) = globalPose->position->y;
1650 gp(2, 3) = globalPose->position->z;
1657 SimulationType type,
1658 const Ice::Current&)
1660 VirtualRobot::SceneObject::Physics::SimulationType st =
1661 VirtualRobot::SceneObject::Physics::eDynamic;
1662 if (type == armarx::Kinematic)
1664 st = VirtualRobot::SceneObject::Physics::eKinematic;
1666 ARMARX_DEBUG <<
"setting simulation type of " << objectName <<
" to " << st;
1696 const std::string& nodeName,
1697 const Ice::Current&)
1699 return physicsWorld->getRobotJointAngle(robotName, nodeName);
1705 return physicsWorld->getRobotJointVelocities(robotName);
1710 const std::string& nodeName,
1711 const Ice::Current&)
1713 return physicsWorld->getRobotJointVelocity(robotName, nodeName);
1725 return physicsWorld->getRobotForceTorqueSensors(robotName);
1730 const std::string& nodeName,
1731 const Ice::Current&)
1733 return physicsWorld->getRobotJointLimitLo(robotName, nodeName);
1738 const std::string& nodeName,
1739 const Ice::Current&)
1741 return physicsWorld->getRobotJointLimitHi(robotName, nodeName);
1753 const std::string& nodeName,
1754 const Ice::Current&)
1756 return physicsWorld->getRobotMaxTorque(robotName, nodeName);
1761 const std::string& nodeName,
1763 const Ice::Current&)
1765 physicsWorld->setRobotMaxTorque(robotName, nodeName, maxTorque);
1770 const std::string& robotNodeName,
1771 const Ice::Current&)
1779 const std::string& nodeName,
1780 const Ice::Current&)
1788 const std::string& nodeName,
1789 const Ice::Current&)
1797 const std::string& robotNodeName,
1798 const Vector3BasePtr& vel,
1799 const Ice::Current&)
1801 Eigen::Vector3f newVel = Vector3Ptr::dynamicCast(vel)->toEigen();
1802 physicsWorld->setRobotLinearVelocity(robotName, robotNodeName, newVel);
1807 const std::string& robotNodeName,
1808 const Vector3BasePtr& vel,
1809 const Ice::Current&)
1811 Vector3Ptr newVel = Vector3Ptr::dynamicCast(vel);
1812 physicsWorld->setRobotAngularVelocity(robotName, robotNodeName, newVel->toEigen());
1817 const std::string& robotNodeName,
1818 const Vector3BasePtr& vel,
1819 const Ice::Current&)
1821 Eigen::Vector3f newVel = Vector3Ptr::dynamicCast(vel)->toEigen();
1822 physicsWorld->setRobotLinearVelocityRobotRootFrame(robotName, robotNodeName, newVel);
1827 const std::string& robotNodeName,
1828 const Vector3BasePtr& vel,
1829 const Ice::Current&)
1831 Eigen::Vector3f newVel = Vector3Ptr::dynamicCast(vel)->toEigen();
1832 physicsWorld->setRobotAngularVelocityRobotRootFrame(robotName, robotNodeName, newVel);
1843 const std::string& robotNodeName,
1844 const Ice::Current&)
1847 return physicsWorld->hasRobotNode(robotName, robotNodeName);
1859 const std::string& robotNodeName,
1860 const std::string& objectName,
1861 const Ice::Current&)
1863 ARMARX_VERBOSE <<
"Object released " << robotName <<
"," << objectName;
1864 physicsWorld->objectReleased(robotName, robotNodeName, objectName);
1869 const std::string& robotNodeName,
1870 const std::string& objectName,
1871 const Ice::Current&)
1873 ARMARX_VERBOSE <<
"Object grasped" << robotName <<
"," << objectName;
1874 physicsWorld->objectGrasped(robotName, robotNodeName, objectName);
1880 return static_cast<float>(
physicsWorld->getCurrentSimTime());
1892 SimulatorInformation
1897 auto lockData =
physicsWorld->getScopedSyncLock(__FUNCTION__);
1898 SimulatorInformation res;
1903 std::vector<std::string> robNames =
physicsWorld->getRobotNames();
1904 res.nrRobots =
static_cast<int>(robNames.size());
1906 res.nrActuatedJoints =
physicsWorld->getRobotJointAngleCount();
1910 res.simTimeStepMeasuredMS =
physicsWorld->getSimulationStepTimeMeasured();
1911 res.simTimeStepDurationMS =
physicsWorld->getSimulationStepDuration();
1913 res.simTimeFactor = 0;
1914 if (res.simTimeStepMeasuredMS > 0)
1916 res.simTimeFactor = res.simTimeStepDurationMS / res.simTimeStepMeasuredMS;
1919 std::vector<VirtualRobot::SceneObjectPtr> objects =
physicsWorld->getObjects();
1925 ovd.name = o->getName();
1927 ovd.objectPoses[ovd.name] = p;
1928 VirtualRobot::Obstacle* ob =
dynamic_cast<VirtualRobot::Obstacle*
>(o.get());
1932 ovd.filename = ob->getFilename();
1935 if (o->getSimulationType() == VirtualRobot::SceneObject::Physics::eStatic)
1937 ovd.staticObject =
true;
1941 ovd.staticObject =
false;
1944 res.objects.push_back(ovd);
1947 for (
auto& r : robNames)
1956 ovd.robotFile = rob->getFilename();
1959 res.robots.push_back(ovd);
1985 ARMARX_ERROR <<
"Could not find file: \"" << packagePath.path <<
"\".";
1991 const std::string& robFileGlobal,
1993 const std::string& robFile,
2000 std::map<std::string, float> initConfig,
2001 bool selfCollisions)
2003 ARMARX_DEBUG <<
"Add robot from file " << robFileGlobal;
2004 auto lockEngine =
physicsWorld->getScopedEngineLock(__FUNCTION__);
2005 auto lockData =
physicsWorld->getScopedSyncLock(__FUNCTION__);
2032 return robotInstanceName;
2042 for (
auto& rob : syncData.
robots)
2045 std::string top = rob.robotTopicName;
2051 rob.simulatorRobotListenerPrx = getTopic<SimulatorRobotListenerInterfacePrx>(top);
2054 for (
auto& fti : rob.forceTorqueSensors)
2056 ARMARX_INFO <<
"Offering topic " << fti.topicName;
2061 ARMARX_INFO <<
"Connecting to topic " << fti.topicName;
2062 fti.prx = getTopic<SimulatorForceTorqueListenerInterfacePrx>(fti.topicName);
2082 ObjectClassInformationSequence
2084 const std::string& frameName,
2085 const std::string& className,
2086 const Ice::Current&)
2088 auto lockEngine =
physicsWorld->getScopedEngineLock(__FUNCTION__);
2089 auto lockData =
physicsWorld->getScopedSyncLock(__FUNCTION__);
2093 ObjectClassInformationSequence result;
2096 for (
const auto&
object : objects)
2098 ObjectClassInformation inf;
2100 inf.timestampMicroSeconds =
2102 inf.className = className;
2103 inf.manipulationObjectName = object;
2112 inf.pose =
physicsWorld->toFramedPose(worldPose, robotName, frameName);
2115 result.push_back(inf);
2123 const std::string& robotNodeName,
2124 const std::string& worldObjectName,
2125 const Ice::Current&)
2127 return physicsWorld->getDistance(robotName, robotNodeName, worldObjectName);
2132 const std::string& robotNodeName1,
2133 const std::string& robotNodeName2,
2134 const Ice::Current&)
2136 return physicsWorld->getRobotNodeDistance(robotName, robotNodeName1, robotNodeName2);
2142 auto lockData =
physicsWorld->getScopedSyncLock(__FUNCTION__);
2217 startTime = IceUtil::Time::now();
2219 sleepTimeMS =
static_cast<int>(
2221 static_cast<float>((IceUtil::Time::now() - startTime).toMilliSeconds()));
2223 if (sleepTimeMS < 0)
2226 <<
" milliseconds too long!";
2230 usleep(
static_cast<unsigned int>(sleepTimeMS * 1000));
2270 return static_cast<long>(
physicsWorld->getCurrentSimTime() * 1000);
2278 if (getProperty<bool>(
"RealTimeMode"))
2287 IceUtil::Time durationSim = IceUtil::Time::now() - startTime;
2292 << durationSim.toMilliSecondsDouble();
2295 ARMARX_DEBUG <<
"*** Step Physics, MS:" << durationSim.toMilliSecondsDouble();
2297 startTime = IceUtil::Time::now();
2300 IceUtil::Time durationSync = IceUtil::Time::now() - startTime;
2303 auto lockData =
physicsWorld->getScopedSyncLock(__FUNCTION__);
2325 SceneVisuData reportData =
physicsWorld->copySceneVisuData();
2341 const auto lockEngine =
physicsWorld->getScopedEngineLock(__FUNCTION__);
2342 const auto lockSync =
physicsWorld->getScopedSyncLock(__FUNCTION__);
2347 std::vector<SimDynamics::DynamicsEngine::DynamicsContactInfo> contacts =
2349 VirtualRobot::ColorMap cm(VirtualRobot::ColorMap::eHot);
2350 float maxImpulse = 2.0f;
2351 float arrowLength = 50.0f;
2355 for (
auto&
c : contacts)
2357 std::stringstream ss;
2358 ss <<
"Contact_" << i;
2363 std::string name = ss.str();
2364 std::string name2 = name +
"_2";
2367 if (!
c.objectAName.empty())
2369 objA =
c.objectAName;
2378 if (!
c.objectBName.empty())
2380 objB =
c.objectBName;
2387 ARMARX_DEBUG <<
"CONTACT " << name <<
", objects: " << objA <<
"-" << objB
2388 <<
", impulse:" <<
c.appliedImpulse;
2389 float intensity =
static_cast<float>(
c.appliedImpulse);
2391 if (intensity > maxImpulse)
2393 intensity = maxImpulse;
2396 intensity /= maxImpulse;
2404 Eigen::Vector3f dir2 = -(
c.normalGlobalB);
2419 std::stringstream ss;
2420 ss <<
"Contact_" << j;
2421 std::string name = ss.str();
2422 std::string name2 = name +
"_2";
2430 if (getProperty<bool>(
"DrawCoMVisu"))
2437 "CoM",
"GlobalCoM_" + name, pos, DrawColor{0.f, 0.f, 1.f, 0.5f}, 20);
2477 ctx[
"origin"] =
"simulation";
2483 header.timestampInMicroSeconds = reportData.
timestamp.toMicroSeconds();
2485 TransformStamped globalRobotPose;
2486 globalRobotPose.header = header;
2487 globalRobotPose.transform = r.
pose;
2520 ContactInfoSequence result;
2522 for (
auto& contact : contacts)
2524 ContactInformation contactInfo;
2525 contactInfo.objectNameA = contact.objectAName;
2526 contactInfo.objectNameB = contact.objectBName;
2527 contactInfo.posGlobalA =
new Vector3(contact.posGlobalA);
2528 contactInfo.posGlobalB =
new Vector3(contact.posGlobalB);
2529 result.push_back(contactInfo);
2544 std::string instanceName;
2547 return instanceName;
2554 const Ice::Current&)
2557 std::string name = instanceName;
2573 std::string instanceName;
2576 return instanceName;
2583 for (
auto& robot : report.
robots)
2585 if (robot.robotName == robotName)
2587 return stateFromRobotInfo(robot, report.
timestamp);
2591 return SimulatedRobotState();