28 #define MAX_SIM_TIME_WARNING 25
29 #define FORCE_TORQUE_TOPIC_NAME "ForceTorqueDynamicSimulationValues"
36 #include <VirtualRobot/CollisionDetection/CollisionChecker.h>
37 #include <VirtualRobot/Nodes/ForceTorqueSensor.h>
38 #include <VirtualRobot/XML/ObjectIO.h>
39 #include <VirtualRobot/XML/RobotIO.h>
40 #include <VirtualRobot/XML/SceneIO.h>
52 SimulatedWorld::SimulatedWorld()
56 simStepExecutionDurationMS = 0.0f;
57 synchronizeDurationMS = 0.0f;
59 currentSimTimeSec = 0.0;
60 collectContacts =
false;
64 SimulatedWorld::activateObject(
const std::string& objectName)
70 SimulatedWorld::resetData()
73 const bool resetRobots = removeRobots();
74 const bool resetObstacles = removeObstacles();
76 return resetRobots && resetObstacles;
80 SimulatedWorld::getCurrentSimTime()
86 return currentSyncTimeSec;
90 SimulatedWorld::resetSimTime()
92 currentSimTimeSec = 0;
96 SimulatedWorld::removeRobots()
102 std::vector<std::string>
names = getRobotNames();
105 res &= removeRobot(n);
112 SimulatedWorld::getReportData()
114 return simReportData;
118 SimulatedWorld::copyReportData()
121 return simReportData;
145 robot = robot->clone(robot->getName(), robot->getCollisionChecker(), scaling);
149 bool ok = addRobotEngine(robot, pid_p, pid_i, pid_d,
filename, staticRobot, selfCollisions);
155 RobotVisuData robData;
157 robData.name = robot->getName();
159 robData.updated =
true;
160 robData.scaling = scaling;
161 robData.colModel = colModel;
163 simVisuData.robots.push_back(robData);
174 std::vector<SensorPtr> sensors = robot->getSensors();
176 for (
const auto& sensor : sensors)
178 ForceTorqueSensorPtr ft = std::dynamic_pointer_cast<ForceTorqueSensor>(sensor);
199 simReportData.robots.push_back(robInfo);
206 SimulatedWorld::objectReleased(
const std::string& robotName,
207 const std::string& robotNodeName,
208 const std::string& objectName)
211 ARMARX_INFO_S <<
"Object released, robot " << robotName <<
", node:" << robotNodeName
212 <<
", object:" << objectName;
214 if (objectReleasedEngine(robotName, robotNodeName, objectName))
217 auto aoIt = attachedObjects.begin();
218 bool objectFound =
false;
220 while (aoIt != attachedObjects.end())
222 if (aoIt->robotName == robotName && aoIt->robotNodeName == robotNodeName &&
223 aoIt->objectName == objectName)
225 attachedObjects.erase(aoIt);
238 ARMARX_INFO_S <<
"Successfully detached object " << objectName;
243 SimulatedWorld::objectGrasped(
const std::string& robotName,
244 const std::string& robotNodeName,
245 const std::string& objectName)
248 ARMARX_INFO_S <<
"Object grasped, robot " << robotName <<
", node:" << robotNodeName
249 <<
", object:" << objectName;
252 for (
const auto& ao : attachedObjects)
254 if (ao.robotName == robotName && ao.robotNodeName == robotNodeName &&
255 ao.objectName == objectName)
263 if (objectGraspedEngine(robotName, robotNodeName, objectName, localTransform))
265 ARMARX_INFO_S <<
"Successfully attached object " << objectName;
275 attachedObjects.push_back(g);
280 SimulatedWorld::removeObstacles()
284 std::vector<std::string>
names = getObstacleNames();
286 for (
auto& n :
names)
288 if (!removeObstacle(n))
299 SimulatedWorld::removeObstacle(
const std::string& name)
305 if (!removeObstacleEngine(name))
312 bool objectFound =
false;
314 for (
auto s = simVisuData.objects.begin();
s != simVisuData.objects.end();
s++)
319 simVisuData.objects.erase(
s);
327 <<
" not in synchronized list, cannot remove";
335 SimulatedWorld::addRobot(std::string& robotInstanceName,
338 const std::string& filenameLocal,
345 const std::map<std::string, float>& initConfig,
359 loadMode = VirtualRobot::RobotIO::eCollisionModel;
362 robot = RobotIO::loadRobot(
filename, loadMode);
363 robot = adaptRobotToWorld(robot);
367 if (robotInstanceName.empty())
369 robotInstanceName = robot->getType();
371 const std::string baseName = robotInstanceName;
372 for (std::size_t i = 2; hasRobot(robotInstanceName); ++i)
376 robot->setName(robotInstanceName);
378 catch (VirtualRobotException& e)
381 <<
" ERROR while creating robot (file:" <<
filename <<
")\n"
392 ARMARX_INFO_S <<
"Loaded robot with name " << robot->getName();
400 if (pose.isIdentity() && getFloor())
403 VirtualRobot::BoundingBox bbox = robot->getBoundingBox();
407 std::vector<CollisionModelPtr> colModels = robot->getCollisionModels();
408 CollisionModelPtr floorCol = getFloor()->getCollisionModel();
411 std::size_t loop = 0;
412 float z = -bbox.getMin()(2) + 20.0f;
414 robot->setGlobalPose(pose);
415 found = (robot->getCollisionChecker()->checkCollision(colModels, floorCol));
417 while (loop < 1000 && !found)
421 robot->setGlobalPose(pose);
422 found = (robot->getCollisionChecker()->checkCollision(colModels, floorCol));
431 robot->setGlobalPose(pose);
436 robot->setGlobalPose(pose);
439 if (!filenameLocal.empty())
446 addRobot(robot, pid_p, pid_i, pid_d, fn, staticRobot, scaling, colModel, selfCollisions);
449 if (
success && initConfig.size() > 0)
452 actuateRobotJointsPos(robot->getName(), initConfig);
464 SimulatedWorld::removeRobot(
const std::string& robotName)
472 bool ok = removeRobotEngine(robotName);
485 ::armarx::RobotVisuList
robots;
486 for (
auto robot : simVisuData.robots)
488 if (robot.name != robotName)
494 std::vector<RobotInfo> robotInfos;
495 for (
auto robot : simReportData.robots)
497 if (robot.robotName != robotName)
499 robotInfos.push_back(robot);
503 simVisuData.robots =
robots;
504 simReportData.robots = robotInfos;
511 auto aoIt = attachedObjects.begin();
513 while (aoIt != attachedObjects.end())
515 if (aoIt->robotName == robotName)
517 ARMARX_DEBUG_S <<
"Removing attached object " << aoIt->objectName;
518 aoIt = attachedObjects.erase(aoIt);
530 SimulatedWorld::addScene(
const std::string&
filename,
531 VirtualRobot::SceneObject::Physics::SimulationType simType)
538 scene = SceneIO::loadScene(
filename);
540 catch (VirtualRobotException& e)
552 return addScene(scene, simType);
556 SimulatedWorld::addScene(
ScenePtr scene, VirtualRobot::SceneObject::Physics::SimulationType simType)
565 std::vector<ManipulationObjectPtr> mo = scene->getManipulationObjects();
570 addObstacle(i, simType, i->getFilename());
574 std::vector<ObstaclePtr> o = scene->getObstacles();
579 addObstacle(i, simType, i->getFilename());
584 std::vector<RobotPtr> ro = scene->getRobots();
589 i->setName(i->getType());
590 ARMARX_VERBOSE_S <<
"Scene: Robot " << i->getName() <<
", type:" << i->getType();
591 addRobot(i, 10.0, 0.0, 0.0, i->getFilename());
595 ARMARX_INFO_S <<
" Added " << countrobot <<
" robots and " << count <<
" objects";
601 SimulatedWorld::addObstacle(
const std::string&
filename,
603 VirtualRobot::SceneObject::Physics::SimulationType simType,
604 const std::string& localFilename)
612 o = ObjectIO::loadObstacle(
filename);
614 catch (VirtualRobotException& e)
626 o->setGlobalPose(pose);
629 if (!localFilename.empty())
631 std::string absoluteFilename;
633 bool fileFound = ArmarXDataPath::getAbsolutePath(localFilename, absoluteFilename);
644 <<
" -> usign " << fn;
648 return addObstacle(o, simType, fn);
653 VirtualRobot::SceneObject::Physics::SimulationType simType,
655 const std::string& objectClassName,
656 ObjectVisuPrimitivePtr primitiveData,
671 if (hasObject(o->getName()))
674 <<
" already present! Choose a different instance name";
678 bool ok = addObstacleEngine(o, simType);
687 if (primitiveData && (!
filename.empty() || !objectClassName.empty()))
689 ARMARX_WARNING_S <<
"Internal error, either filename or classname or primitive";
693 armarx::ObjectVisuData ovd;
694 ovd.name = o->getName();
697 ovd.objectPoses[o->getName()] =
new Pose(o->getGlobalPose());
698 ovd.objectClassName = objectClassName;
703 ovd.objectPrimitiveData = primitiveData;
707 simVisuData.objects.push_back(ovd);
717 #ifdef PERFORMANCE_EVALUATION_LOCKS
718 if (engineMtxAccTime.find(callStr) == engineMtxAccTime.end())
720 engineMtxAccCalls[callStr] = 1;
721 engineMtxAccTime[callStr] = 0;
722 engineMtxLastTime[callStr] = IceUtil::Time::now();
726 IceUtil::Time delta = IceUtil::Time::now() - engineMtxLastTime[callStr];
727 engineMtxAccCalls[callStr] += 1;
728 engineMtxAccTime[callStr] += delta.toMilliSecondsDouble();
729 engineMtxLastTime[callStr] = IceUtil::Time::now();
730 if (engineMtxAccTime[callStr] > 1000)
732 ARMARX_INFO <<
"engine mutex performance [" << callStr
733 <<
"]: Nr Calls:" << engineMtxAccCalls[callStr] <<
", Calls/Sec:"
734 << (
float)engineMtxAccCalls[callStr] / engineMtxAccTime[callStr] * 1000.0f;
735 engineMtxAccCalls[callStr] = 1;
736 engineMtxAccTime[callStr] = 0;
737 engineMtxLastTime[callStr] = IceUtil::Time::now();
750 #ifdef PERFORMANCE_EVALUATION_LOCKS
751 if (syncMtxAccTime.find(callStr) == syncMtxAccTime.end())
753 syncMtxAccCalls[callStr] = 1;
754 syncMtxAccTime[callStr] = 0;
755 syncMtxLastTime[callStr] = IceUtil::Time::now();
759 IceUtil::Time delta = IceUtil::Time::now() - syncMtxLastTime[callStr];
760 syncMtxAccCalls[callStr] += 1;
761 syncMtxAccTime[callStr] += delta.toMilliSecondsDouble();
762 syncMtxLastTime[callStr] = IceUtil::Time::now();
763 if (syncMtxAccTime[callStr] > 1000)
765 ARMARX_INFO <<
"snyc mutex performance [" << callStr
766 <<
"]: Nr Calls:" << syncMtxAccCalls[callStr] <<
", Calls/Sec:"
767 << (
float)syncMtxAccCalls[callStr] / syncMtxAccTime[callStr] * 1000.0f;
768 syncMtxAccCalls[callStr] = 1;
769 syncMtxAccTime[callStr] = 0;
770 syncMtxLastTime[callStr] = IceUtil::Time::now();
780 SimulatedWorld::setupFloor(
bool enable,
const std::string& floorTexture)
782 setupFloorEngine(enable, floorTexture);
786 simVisuData.floor = enable;
787 simVisuData.floorTextureFile = floorTexture;
792 SimulatedWorld::getSimulationStepDuration()
794 return simTimeStepMS;
798 SimulatedWorld::getSimulationStepTimeMeasured()
800 return simStepExecutionDurationMS;
804 SimulatedWorld::enableLogging(
const std::string& robotName,
const std::string& logFile)
806 (void)robotName, (
void)logFile;
810 SimulatedWorld::getSimTime()
812 return simStepExecutionDurationMS;
816 SimulatedWorld::getSyncEngineTime()
818 return synchronizeDurationMS;
822 SimulatedWorld::synchronizeRobots()
829 if (simVisuData.robots.size() == 0)
833 std::map<std::string, RobotVisuData*> visuRobotPtr;
834 for (
auto& robot : simVisuData.robots)
836 std::string name = robot.name;
838 if (!synchronizeRobotNodePoses(name, robot.robotNodePoses))
846 robot.updated =
true;
847 visuRobotPtr[robot.name] = &robot;
852 for (
auto& robot : simReportData.robots)
854 std::string name = robot.robotName;
856 robot.pose = getRobotPose(name);
860 robot.jointVelocities,
862 robot.linearVelocity,
863 robot.angularVelocity);
864 if (visuRobotPtr.count(robot.robotName))
866 visuRobotPtr.at(robot.robotName)->jointValues = robot.jointAngles;
870 for (
size_t i = 0; i < robot.forceTorqueSensors.size(); i++)
872 updateForceTorqueSensor(robot.forceTorqueSensors[i]);
880 SimulatedWorld::synchronizeSimulationData()
888 IceUtil::Time durationlock = IceUtil::Time::now() - startTime;
890 if (durationlock.toMilliSecondsDouble() > 4)
893 <<
"Engine/Sync locking took long :" << durationlock.toMilliSecondsDouble()
897 simVisuData.timestamp =
static_cast<Ice::Long>(getCurrentSimTime() * 1000);
898 simReportData.timestamp = IceUtil::Time::secondsDouble(getCurrentSimTime());
904 if (durationR.toMilliSecondsDouble() > 4)
907 <<
"Robot sync took long:" << durationR.toMilliSecondsDouble() <<
" ms";
912 synchronizeObjects();
914 if (durationO.toMilliSecondsDouble() > 4)
917 <<
"Object sync took long:" << durationO.toMilliSecondsDouble() <<
" ms";
921 synchronizeSimulationDataEngine();
924 synchronizeDurationMS =
static_cast<float>(duration.toMilliSecondsDouble());
926 currentSyncTimeSec = currentSimTimeSec;
932 SimulatedWorld::updateContacts(
bool enable)
934 collectContacts = enable;
938 SimulatedWorld::copySceneVisuData()
945 SimulatedWorld::getRobotJointAngleCount()
949 if (simVisuData.robots.size() == 0)
954 return static_cast<int>(simVisuData.robots.at(0).robotNodePoses.size());
958 SimulatedWorld::getContactCount()
965 SimulatedWorld::getObjectCount()
968 return static_cast<int>(simVisuData.objects.size());