28 #include <VirtualRobot/ManipulationObject.h>
29 #include <VirtualRobot/Scene.h>
30 #define MAX_SIM_TIME_WARNING 25
31 #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>
54 SimulatedWorld::SimulatedWorld()
58 simStepExecutionDurationMS = 0.0f;
59 synchronizeDurationMS = 0.0f;
61 currentSimTimeSec = 0.0;
62 collectContacts =
false;
66 SimulatedWorld::activateObject(
const std::string& objectName)
72 SimulatedWorld::resetData()
75 const bool resetRobots = removeRobots();
76 const bool resetObstacles = removeObstacles();
78 return resetRobots && resetObstacles;
82 SimulatedWorld::getCurrentSimTime()
88 return currentSyncTimeSec;
92 SimulatedWorld::resetSimTime()
94 currentSimTimeSec = 0;
98 SimulatedWorld::removeRobots()
104 std::vector<std::string>
names = getRobotNames();
107 res &= removeRobot(n);
114 SimulatedWorld::getReportData()
116 return simReportData;
120 SimulatedWorld::copyReportData()
123 return simReportData;
147 robot = robot->clone(robot->getName(), robot->getCollisionChecker(), scaling);
151 bool ok = addRobotEngine(robot, pid_p, pid_i, pid_d,
filename, staticRobot, selfCollisions);
157 RobotVisuData robData;
159 robData.name = robot->getName();
161 robData.updated =
true;
162 robData.scaling = scaling;
163 robData.colModel = colModel;
165 simVisuData.robots.push_back(robData);
176 std::vector<SensorPtr> sensors = robot->getSensors();
178 for (
const auto& sensor : sensors)
180 ForceTorqueSensorPtr ft = std::dynamic_pointer_cast<ForceTorqueSensor>(sensor);
201 simReportData.robots.push_back(robInfo);
208 SimulatedWorld::objectReleased(
const std::string& robotName,
209 const std::string& robotNodeName,
210 const std::string& objectName)
213 ARMARX_INFO_S <<
"Object released, robot " << robotName <<
", node:" << robotNodeName
214 <<
", object:" << objectName;
216 if (objectReleasedEngine(robotName, robotNodeName, objectName))
219 auto aoIt = attachedObjects.begin();
220 bool objectFound =
false;
222 while (aoIt != attachedObjects.end())
224 if (aoIt->robotName == robotName && aoIt->robotNodeName == robotNodeName &&
225 aoIt->objectName == objectName)
227 attachedObjects.erase(aoIt);
240 ARMARX_INFO_S <<
"Successfully detached object " << objectName;
245 SimulatedWorld::objectGrasped(
const std::string& robotName,
246 const std::string& robotNodeName,
247 const std::string& objectName)
250 ARMARX_INFO_S <<
"Object grasped, robot " << robotName <<
", node:" << robotNodeName
251 <<
", object:" << objectName;
254 for (
const auto& ao : attachedObjects)
256 if (ao.robotName == robotName && ao.robotNodeName == robotNodeName &&
257 ao.objectName == objectName)
265 if (objectGraspedEngine(robotName, robotNodeName, objectName, localTransform))
267 ARMARX_INFO_S <<
"Successfully attached object " << objectName;
277 attachedObjects.push_back(g);
282 SimulatedWorld::removeObstacles()
286 std::vector<std::string>
names = getObstacleNames();
288 for (
auto& n :
names)
290 if (!removeObstacle(n))
301 SimulatedWorld::removeObstacle(
const std::string& name)
307 if (!removeObstacleEngine(name))
314 bool objectFound =
false;
316 for (
auto s = simVisuData.objects.begin();
s != simVisuData.objects.end();
s++)
321 simVisuData.objects.erase(
s);
329 <<
" not in synchronized list, cannot remove";
337 SimulatedWorld::addRobot(std::string& robotInstanceName,
340 const std::string& filenameLocal,
347 const std::map<std::string, float>& initConfig,
361 loadMode = VirtualRobot::RobotIO::eCollisionModel;
364 robot = RobotIO::loadRobot(
filename, loadMode);
365 robot = adaptRobotToWorld(robot);
369 if (robotInstanceName.empty())
371 robotInstanceName = robot->getType();
373 const std::string baseName = robotInstanceName;
374 for (std::size_t i = 2; hasRobot(robotInstanceName); ++i)
378 robot->setName(robotInstanceName);
380 catch (VirtualRobotException& e)
383 <<
" ERROR while creating robot (file:" <<
filename <<
")\n"
394 ARMARX_INFO_S <<
"Loaded robot with name " << robot->getName();
402 if (pose.isIdentity() && getFloor())
405 VirtualRobot::BoundingBox bbox = robot->getBoundingBox();
409 std::vector<CollisionModelPtr> colModels = robot->getCollisionModels();
410 CollisionModelPtr floorCol = getFloor()->getCollisionModel();
413 std::size_t loop = 0;
414 float z = -bbox.getMin()(2) + 20.0f;
416 robot->setGlobalPose(pose);
417 found = (robot->getCollisionChecker()->checkCollision(colModels, floorCol));
419 while (loop < 1000 && !found)
423 robot->setGlobalPose(pose);
424 found = (robot->getCollisionChecker()->checkCollision(colModels, floorCol));
433 robot->setGlobalPose(pose);
438 robot->setGlobalPose(pose);
441 if (!filenameLocal.empty())
448 addRobot(robot, pid_p, pid_i, pid_d, fn, staticRobot, scaling, colModel, selfCollisions);
451 if (
success && initConfig.size() > 0)
454 actuateRobotJointsPos(robot->getName(), initConfig);
466 SimulatedWorld::removeRobot(
const std::string& robotName)
474 bool ok = removeRobotEngine(robotName);
487 ::armarx::RobotVisuList
robots;
488 for (
auto robot : simVisuData.robots)
490 if (robot.name != robotName)
496 std::vector<RobotInfo> robotInfos;
497 for (
auto robot : simReportData.robots)
499 if (robot.robotName != robotName)
501 robotInfos.push_back(robot);
505 simVisuData.robots =
robots;
506 simReportData.robots = robotInfos;
513 auto aoIt = attachedObjects.begin();
515 while (aoIt != attachedObjects.end())
517 if (aoIt->robotName == robotName)
519 ARMARX_DEBUG_S <<
"Removing attached object " << aoIt->objectName;
520 aoIt = attachedObjects.erase(aoIt);
532 SimulatedWorld::addScene(
const std::string&
filename,
533 VirtualRobot::SceneObject::Physics::SimulationType simType)
540 scene = SceneIO::loadScene(
filename);
542 catch (VirtualRobotException& e)
554 return addScene(scene, simType);
558 SimulatedWorld::addScene(
ScenePtr scene, VirtualRobot::SceneObject::Physics::SimulationType simType)
567 std::vector<ManipulationObjectPtr> mo = scene->getManipulationObjects();
572 addObstacle(i, simType, i->getFilename());
576 std::vector<ObstaclePtr> o = scene->getObstacles();
581 addObstacle(i, simType, i->getFilename());
586 std::vector<RobotPtr> ro = scene->getRobots();
591 i->setName(i->getType());
592 ARMARX_VERBOSE_S <<
"Scene: Robot " << i->getName() <<
", type:" << i->getType();
593 addRobot(i, 10.0, 0.0, 0.0, i->getFilename());
597 ARMARX_INFO_S <<
" Added " << countrobot <<
" robots and " << count <<
" objects";
603 SimulatedWorld::addObstacle(
const std::string&
filename,
605 VirtualRobot::SceneObject::Physics::SimulationType simType,
606 const std::string& localFilename)
614 o = ObjectIO::loadObstacle(
filename);
616 catch (VirtualRobotException& e)
628 o->setGlobalPose(pose);
631 if (!localFilename.empty())
633 std::string absoluteFilename;
635 bool fileFound = ArmarXDataPath::getAbsolutePath(localFilename, absoluteFilename);
646 <<
" -> usign " << fn;
650 return addObstacle(o, simType, fn);
655 VirtualRobot::SceneObject::Physics::SimulationType simType,
657 const std::string& objectClassName,
658 ObjectVisuPrimitivePtr primitiveData,
673 if (hasObject(o->getName()))
676 <<
" already present! Choose a different instance name";
680 bool ok = addObstacleEngine(o, simType);
689 if (primitiveData && (!
filename.empty() || !objectClassName.empty()))
691 ARMARX_WARNING_S <<
"Internal error, either filename or classname or primitive";
695 armarx::ObjectVisuData ovd;
696 ovd.name = o->getName();
699 ovd.objectPoses[o->getName()] =
new Pose(o->getGlobalPose());
700 ovd.objectClassName = objectClassName;
705 ovd.objectPrimitiveData = primitiveData;
709 simVisuData.objects.push_back(ovd);
719 #ifdef PERFORMANCE_EVALUATION_LOCKS
720 if (engineMtxAccTime.find(callStr) == engineMtxAccTime.end())
722 engineMtxAccCalls[callStr] = 1;
723 engineMtxAccTime[callStr] = 0;
724 engineMtxLastTime[callStr] = IceUtil::Time::now();
728 IceUtil::Time delta = IceUtil::Time::now() - engineMtxLastTime[callStr];
729 engineMtxAccCalls[callStr] += 1;
730 engineMtxAccTime[callStr] += delta.toMilliSecondsDouble();
731 engineMtxLastTime[callStr] = IceUtil::Time::now();
732 if (engineMtxAccTime[callStr] > 1000)
734 ARMARX_INFO <<
"engine mutex performance [" << callStr
735 <<
"]: Nr Calls:" << engineMtxAccCalls[callStr] <<
", Calls/Sec:"
736 << (
float)engineMtxAccCalls[callStr] / engineMtxAccTime[callStr] * 1000.0f;
737 engineMtxAccCalls[callStr] = 1;
738 engineMtxAccTime[callStr] = 0;
739 engineMtxLastTime[callStr] = IceUtil::Time::now();
752 #ifdef PERFORMANCE_EVALUATION_LOCKS
753 if (syncMtxAccTime.find(callStr) == syncMtxAccTime.end())
755 syncMtxAccCalls[callStr] = 1;
756 syncMtxAccTime[callStr] = 0;
757 syncMtxLastTime[callStr] = IceUtil::Time::now();
761 IceUtil::Time delta = IceUtil::Time::now() - syncMtxLastTime[callStr];
762 syncMtxAccCalls[callStr] += 1;
763 syncMtxAccTime[callStr] += delta.toMilliSecondsDouble();
764 syncMtxLastTime[callStr] = IceUtil::Time::now();
765 if (syncMtxAccTime[callStr] > 1000)
767 ARMARX_INFO <<
"snyc mutex performance [" << callStr
768 <<
"]: Nr Calls:" << syncMtxAccCalls[callStr] <<
", Calls/Sec:"
769 << (
float)syncMtxAccCalls[callStr] / syncMtxAccTime[callStr] * 1000.0f;
770 syncMtxAccCalls[callStr] = 1;
771 syncMtxAccTime[callStr] = 0;
772 syncMtxLastTime[callStr] = IceUtil::Time::now();
782 SimulatedWorld::setupFloor(
bool enable,
const std::string& floorTexture)
784 setupFloorEngine(enable, floorTexture);
788 simVisuData.floor = enable;
789 simVisuData.floorTextureFile = floorTexture;
794 SimulatedWorld::getSimulationStepDuration()
796 return simTimeStepMS;
800 SimulatedWorld::getSimulationStepTimeMeasured()
802 return simStepExecutionDurationMS;
806 SimulatedWorld::enableLogging(
const std::string& robotName,
const std::string& logFile)
808 (void)robotName, (
void)logFile;
812 SimulatedWorld::getSimTime()
814 return simStepExecutionDurationMS;
818 SimulatedWorld::getSyncEngineTime()
820 return synchronizeDurationMS;
824 SimulatedWorld::synchronizeRobots()
831 if (simVisuData.robots.size() == 0)
835 std::map<std::string, RobotVisuData*> visuRobotPtr;
836 for (
auto& robot : simVisuData.robots)
838 std::string name = robot.name;
840 if (!synchronizeRobotNodePoses(name, robot.robotNodePoses))
848 robot.updated =
true;
849 visuRobotPtr[robot.name] = &robot;
854 for (
auto& robot : simReportData.robots)
856 std::string name = robot.robotName;
858 robot.pose = getRobotPose(name);
862 robot.jointVelocities,
864 robot.linearVelocity,
865 robot.angularVelocity);
866 if (visuRobotPtr.count(robot.robotName))
868 visuRobotPtr.at(robot.robotName)->jointValues = robot.jointAngles;
872 for (
size_t i = 0; i < robot.forceTorqueSensors.size(); i++)
874 updateForceTorqueSensor(robot.forceTorqueSensors[i]);
882 SimulatedWorld::synchronizeSimulationData()
890 IceUtil::Time durationlock = IceUtil::Time::now() - startTime;
892 if (durationlock.toMilliSecondsDouble() > 4)
895 <<
"Engine/Sync locking took long :" << durationlock.toMilliSecondsDouble()
899 simVisuData.timestamp =
static_cast<Ice::Long>(getCurrentSimTime() * 1000);
900 simReportData.timestamp = IceUtil::Time::secondsDouble(getCurrentSimTime());
906 if (durationR.toMilliSecondsDouble() > 4)
909 <<
"Robot sync took long:" << durationR.toMilliSecondsDouble() <<
" ms";
914 synchronizeObjects();
916 if (durationO.toMilliSecondsDouble() > 4)
919 <<
"Object sync took long:" << durationO.toMilliSecondsDouble() <<
" ms";
923 synchronizeSimulationDataEngine();
926 synchronizeDurationMS =
static_cast<float>(duration.toMilliSecondsDouble());
928 currentSyncTimeSec = currentSimTimeSec;
934 SimulatedWorld::updateContacts(
bool enable)
936 collectContacts = enable;
940 SimulatedWorld::copySceneVisuData()
947 SimulatedWorld::getRobotJointAngleCount()
951 if (simVisuData.robots.size() == 0)
956 return static_cast<int>(simVisuData.robots.at(0).robotNodePoses.size());
960 SimulatedWorld::getContactCount()
967 SimulatedWorld::getObjectCount()
970 return static_cast<int>(simVisuData.objects.size());