SimulatedWorld.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 Nikolaus ( vahrenkamp at kit dot edu )
20  * @date 2014
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 // print who is querying for locks (scoped lock queries are counted)
26 //#define PERFORMANCE_EVALUATION_LOCKS
27 
28 #define MAX_SIM_TIME_WARNING 25
29 #define FORCE_TORQUE_TOPIC_NAME "ForceTorqueDynamicSimulationValues"
30 
31 #include "SimulatedWorld.h"
32 
33 #include <algorithm>
34 #include <memory>
35 
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>
41 
46 
47 using namespace VirtualRobot;
48 using namespace armarx;
49 
50 //#define PRINT_TEST_DEBUG_MESSAGES
51 
52 SimulatedWorld::SimulatedWorld()
53 {
54  engineMutex.reset(new MutexType);
55  synchronizeMutex.reset(new MutexType);
56  simStepExecutionDurationMS = 0.0f;
57  synchronizeDurationMS = 0.0f;
58  simTimeStepMS = 0.0f;
59  currentSimTimeSec = 0.0;
60  collectContacts = false;
61 }
62 
63 void
64 SimulatedWorld::activateObject(const std::string& objectName)
65 {
66  (void)objectName; // unused
67 }
68 
69 bool
70 SimulatedWorld::resetData()
71 {
72  ARMARX_DEBUG_S << "Removing all robots & objects";
73  const bool resetRobots = removeRobots();
74  const bool resetObstacles = removeObstacles();
75 
76  return resetRobots && resetObstacles;
77 }
78 
79 double
80 SimulatedWorld::getCurrentSimTime()
81 {
82  // Return time of last update of robot/object data instead of last step.
83  // => The caller can rely on robot/object data being synced to this time.
84 
85  // return currentSimTimeSec;
86  return currentSyncTimeSec;
87 }
88 
89 void
90 SimulatedWorld::resetSimTime()
91 {
92  currentSimTimeSec = 0;
93 }
94 
95 bool
96 SimulatedWorld::removeRobots()
97 {
98  ARMARX_DEBUG_S << "Removing all robots";
99 
100  bool res = true;
101 
102  std::vector<std::string> names = getRobotNames();
103  for (auto n : names)
104  {
105  res &= removeRobot(n);
106  }
107 
108  return res;
109 }
110 
112 SimulatedWorld::getReportData()
113 {
114  return simReportData;
115 }
116 
118 SimulatedWorld::copyReportData()
119 {
120  ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
121  return simReportData;
122 }
123 
124 bool
125 SimulatedWorld::addRobot(RobotPtr robot,
126  double pid_p,
127  double pid_i,
128  double pid_d,
129  const std::string& filename,
130  bool staticRobot,
131  float scaling,
132  bool colModel,
133  bool selfCollisions)
134 {
135  ARMARX_VERBOSE_S << "Adding robot " << robot->getName() << ", file:" << filename;
136  assert(robot);
137 
138  // lock engine and data
139  ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
140  ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
141 
142  if (scaling != 1.0f)
143  {
144  ARMARX_INFO_S << "Scaling robot, factor: " << scaling;
145  robot = robot->clone(robot->getName(), robot->getCollisionChecker(), scaling);
146  }
147 
148 
149  bool ok = addRobotEngine(robot, pid_p, pid_i, pid_d, filename, staticRobot, selfCollisions);
150  if (!ok)
151  {
152  return false;
153  }
154 
155  RobotVisuData robData;
156 
157  robData.name = robot->getName();
158  robData.robotFile = filename;
159  robData.updated = true;
160  robData.scaling = scaling;
161  robData.colModel = colModel;
162 
163  simVisuData.robots.push_back(robData);
164 
165  RobotInfo robInfo;
166  robInfo.robotName = robot->getName();
167 
168  try
169  {
170  // setup robot report data
171  robInfo.robotTopicName = "Simulator_Robot_";
172  robInfo.robotTopicName += robot->getName();
173 
174  std::vector<SensorPtr> sensors = robot->getSensors();
175 
176  for (const auto& sensor : sensors)
177  {
178  ForceTorqueSensorPtr ft = std::dynamic_pointer_cast<ForceTorqueSensor>(sensor);
179 
180  if (ft)
181  {
182  ForceTorqueInfo fti;
183  fti.enable = true;
184  fti.robotName = robot->getName();
185  fti.sensorName = ft->getName();
186  fti.ftSensor = ft;
187  fti.robotNodeName = ft->getRobotNode()->getName();
189 
190  robInfo.forceTorqueSensors.push_back(fti);
191  }
192  }
193  }
194  catch (...)
195  {
196  ARMARX_WARNING_S << "addRobot failed";
197  }
198 
199  simReportData.robots.push_back(robInfo);
200 
201  synchronizeRobots();
202  return true;
203 }
204 
205 void
206 SimulatedWorld::objectReleased(const std::string& robotName,
207  const std::string& robotNodeName,
208  const std::string& objectName)
209 {
210  ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
211  ARMARX_INFO_S << "Object released, robot " << robotName << ", node:" << robotNodeName
212  << ", object:" << objectName;
213 
214  if (objectReleasedEngine(robotName, robotNodeName, objectName))
215  {
216  // check if object is in grasped list
217  auto aoIt = attachedObjects.begin();
218  bool objectFound = false;
219 
220  while (aoIt != attachedObjects.end())
221  {
222  if (aoIt->robotName == robotName && aoIt->robotNodeName == robotNodeName &&
223  aoIt->objectName == objectName)
224  {
225  attachedObjects.erase(aoIt);
226  objectFound = true;
227  break;
228  }
229 
230  aoIt++;
231  }
232 
233  if (!objectFound)
234  {
235  ARMARX_WARNING_S << "Object was not attached to robot: " << objectName;
236  }
237 
238  ARMARX_INFO_S << "Successfully detached object " << objectName;
239  }
240 }
241 
242 void
243 SimulatedWorld::objectGrasped(const std::string& robotName,
244  const std::string& robotNodeName,
245  const std::string& objectName)
246 {
247  ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
248  ARMARX_INFO_S << "Object grasped, robot " << robotName << ", node:" << robotNodeName
249  << ", object:" << objectName;
250 
251  // check if object is already grasped
252  for (const auto& ao : attachedObjects)
253  {
254  if (ao.robotName == robotName && ao.robotNodeName == robotNodeName &&
255  ao.objectName == objectName)
256  {
257  ARMARX_INFO_S << "Object already attached, skipping...";
258  return;
259  }
260  }
261 
262  Eigen::Matrix4f localTransform;
263  if (objectGraspedEngine(robotName, robotNodeName, objectName, localTransform))
264  {
265  ARMARX_INFO_S << "Successfully attached object " << objectName;
266  // store grasping information
267  GraspingInfo g;
268  g.robotName = robotName;
269  g.robotNodeName = robotNodeName;
270  g.objectName = objectName;
271 
273  localTransform; //rn->toLocalCoordinateSystem(o->getSceneObject()->getGlobalPose());
274 
275  attachedObjects.push_back(g);
276  }
277 }
278 
279 bool
280 SimulatedWorld::removeObstacles()
281 {
282  ARMARX_VERBOSE_S << "Removing all obstacles";
283  bool result = true;
284  std::vector<std::string> names = getObstacleNames();
285 
286  for (auto& n : names)
287  {
288  if (!removeObstacle(n))
289  {
290  ARMARX_WARNING_S << "Could not remove object with name " << n;
291  result = false;
292  }
293  }
294 
295  return result;
296 }
297 
298 bool
299 SimulatedWorld::removeObstacle(const std::string& name)
300 {
301  ARMARX_VERBOSE_S << "Removing obstacle " << name;
302  ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
303  ScopedRecursiveLockPtr lockData = getScopedSyncLock(__FUNCTION__);
304 
305  if (!removeObstacleEngine(name))
306  {
307  return false;
308  }
309 
310  {
311  // access data
312  bool objectFound = false;
313 
314  for (auto s = simVisuData.objects.begin(); s != simVisuData.objects.end(); s++)
315  {
316  if (s->name == name)
317  {
318  objectFound = true;
319  simVisuData.objects.erase(s);
320  break;
321  }
322  }
323 
324  if (!objectFound)
325  {
326  ARMARX_WARNING_S << "Object with name " << name
327  << " not in synchronized list, cannot remove";
328  }
329  }
330 
331  return true;
332 }
333 
334 bool
335 SimulatedWorld::addRobot(std::string& robotInstanceName,
336  const std::string& filename,
337  Eigen::Matrix4f pose,
338  const std::string& filenameLocal,
339  double pid_p,
340  double pid_i,
341  double pid_d,
342  bool staticRobot,
343  float scaling,
344  bool colModel,
345  const std::map<std::string, float>& initConfig,
346  bool selfCollisions)
347 {
348  ARMARX_TRACE;
349  ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
350  ARMARX_INFO_S << "Loading Robot from " << filename;
351  RobotPtr robot;
352 
353  try
354  {
355  ARMARX_TRACE;
356  VirtualRobot::RobotIO::RobotDescription loadMode = VirtualRobot::RobotIO::eFull;
357  if (colModel)
358  {
359  loadMode = VirtualRobot::RobotIO::eCollisionModel;
360  }
361 
362  robot = RobotIO::loadRobot(filename, loadMode);
363  robot = adaptRobotToWorld(robot);
364 
365  ARMARX_TRACE;
366  // ensure that the robot has the standard name
367  if (robotInstanceName.empty())
368  {
369  robotInstanceName = robot->getType();
370  }
371  const std::string baseName = robotInstanceName;
372  for (std::size_t i = 2; hasRobot(robotInstanceName); ++i)
373  {
374  robotInstanceName = baseName + "_" + std::to_string(i);
375  }
376  robot->setName(robotInstanceName);
377  }
378  catch (VirtualRobotException& e)
379  {
381  << " ERROR while creating robot (file:" << filename << ")\n"
382  << e.what();
383  return false;
384  }
385 
386  if (!robot)
387  {
388  ARMARX_ERROR_S << " ERROR while creating robot (file:" << filename << ")";
389  return false;
390  }
391 
392  ARMARX_INFO_S << "Loaded robot with name " << robot->getName();
393 
394  /*if (initConfig.size() > 0)
395  {
396  robot->setJointValues(initConfig);
397  }*/
398 
399  ARMARX_TRACE;
400  if (pose.isIdentity() && getFloor())
401  {
402  ARMARX_TRACE;
403  VirtualRobot::BoundingBox bbox = robot->getBoundingBox();
404  //pose(2,3) = -bbox.getMin()(2) + 1.0f;
405 
406  // move down robot until collision
407  std::vector<CollisionModelPtr> colModels = robot->getCollisionModels();
408  CollisionModelPtr floorCol = getFloor()->getCollisionModel();
409 
410  bool found = false;
411  std::size_t loop = 0;
412  float z = -bbox.getMin()(2) + 20.0f;
413  pose(2, 3) = z;
414  robot->setGlobalPose(pose);
415  found = (robot->getCollisionChecker()->checkCollision(colModels, floorCol));
416 
417  while (loop < 1000 && !found)
418  {
419  z -= 2.0f;
420  pose(2, 3) = z;
421  robot->setGlobalPose(pose);
422  found = (robot->getCollisionChecker()->checkCollision(colModels, floorCol));
423  loop++;
424  }
425 
426  if (found)
427  {
428  // move up
429  z += 2.0f;
430  pose(2, 3) = z;
431  robot->setGlobalPose(pose);
432  }
433  }
434  ARMARX_TRACE;
435 
436  robot->setGlobalPose(pose);
437  std::string fn = filename;
438 
439  if (!filenameLocal.empty())
440  {
441  fn = filenameLocal;
442  }
443 
444  ARMARX_TRACE;
445  bool success =
446  addRobot(robot, pid_p, pid_i, pid_d, fn, staticRobot, scaling, colModel, selfCollisions);
447 
448  ARMARX_TRACE;
449  if (success && initConfig.size() > 0)
450  {
451  ARMARX_TRACE;
452  actuateRobotJointsPos(robot->getName(), initConfig);
453  }
454  return success;
455 }
456 
458 SimulatedWorld::adaptRobotToWorld(VirtualRobot::RobotPtr robot)
459 {
460  return robot;
461 }
462 
463 bool
464 SimulatedWorld::removeRobot(const std::string& robotName)
465 {
466  ARMARX_DEBUG_S << "Removing robot " << robotName;
467 
468  // lock engine and data
469  ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
470  ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
471 
472  bool ok = removeRobotEngine(robotName);
473  if (!ok)
474  {
475  return false;
476  }
477 
478  // access data
479  {
480  // if (simVisuData.robots.size() != 1 || simVisuData.robots.at(0).name != robotName)
481  // {g
482  // ARMARX_WARNING_S << "Internal data structure wrong...";
483  // }
484 
485  ::armarx::RobotVisuList robots;
486  for (auto robot : simVisuData.robots)
487  {
488  if (robot.name != robotName)
489  {
490  robots.push_back(robot);
491  }
492  }
493 
494  std::vector<RobotInfo> robotInfos;
495  for (auto robot : simReportData.robots)
496  {
497  if (robot.robotName != robotName)
498  {
499  robotInfos.push_back(robot);
500  }
501  }
502 
503  simVisuData.robots = robots;
504  simReportData.robots = robotInfos;
505 
506  //simVisuData.robots.clear();
507  //simReportData.robots.clear();
508  }
509 
510  // check if there are grasped objects
511  auto aoIt = attachedObjects.begin();
512 
513  while (aoIt != attachedObjects.end())
514  {
515  if (aoIt->robotName == robotName)
516  {
517  ARMARX_DEBUG_S << "Removing attached object " << aoIt->objectName;
518  aoIt = attachedObjects.erase(aoIt);
519  }
520  else
521  {
522  aoIt++;
523  }
524  }
525 
526  return true;
527 }
528 
529 bool
530 SimulatedWorld::addScene(const std::string& filename,
531  VirtualRobot::SceneObject::Physics::SimulationType simType)
532 {
533  ARMARX_INFO_S << "Loading Scene from " << filename;
534  ScenePtr scene;
535 
536  try
537  {
538  scene = SceneIO::loadScene(filename);
539  }
540  catch (VirtualRobotException& e)
541  {
542  ARMARX_ERROR_S << " ERROR while creating scene (file:" << filename << ")\n" << e.what();
543  return false;
544  }
545 
546  if (!scene)
547  {
548  ARMARX_ERROR_S << " ERROR while creating scene (file:" << filename << ")";
549  return false;
550  }
551 
552  return addScene(scene, simType);
553 }
554 
555 bool
556 SimulatedWorld::addScene(ScenePtr scene, VirtualRobot::SceneObject::Physics::SimulationType simType)
557 {
558  if (!scene)
559  {
560  ARMARX_ERROR_S << "No Scene!";
561  return false;
562  }
563 
564  int count = 0;
565  std::vector<ManipulationObjectPtr> mo = scene->getManipulationObjects();
566 
567  for (auto& i : mo)
568  {
569  ARMARX_VERBOSE_S << "Scene: ManipulationObject " << i->getName();
570  addObstacle(i, simType, i->getFilename());
571  count++;
572  }
573 
574  std::vector<ObstaclePtr> o = scene->getObstacles();
575 
576  for (auto& i : o)
577  {
578  ARMARX_VERBOSE_S << "Scene: Obstacle " << i->getName();
579  addObstacle(i, simType, i->getFilename());
580  count++;
581  }
582 
583  int countrobot = 0;
584  std::vector<RobotPtr> ro = scene->getRobots();
585 
586  for (auto& i : ro)
587  {
588  // ensure consistent name
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());
592  countrobot++;
593  }
594 
595  ARMARX_INFO_S << " Added " << countrobot << " robots and " << count << " objects";
596 
597  return true;
598 }
599 
600 bool
601 SimulatedWorld::addObstacle(const std::string& filename,
602  const Eigen::Matrix4f& pose,
603  VirtualRobot::SceneObject::Physics::SimulationType simType,
604  const std::string& localFilename)
605 {
606  ARMARX_INFO_S << "Loading obstacle from " << filename << ", (local file:" << localFilename
607  << ")";
608  ObstaclePtr o;
609 
610  try
611  {
612  o = ObjectIO::loadObstacle(filename);
613  }
614  catch (VirtualRobotException& e)
615  {
616  ARMARX_ERROR_S << " ERROR while creating obstacle (file:" << filename << ")\n" << e.what();
617  return false;
618  }
619 
620  if (!o)
621  {
622  ARMARX_ERROR_S << " ERROR while creating (file:" << filename << ")";
623  return false;
624  }
625 
626  o->setGlobalPose(pose);
627  std::string fn = filename;
628 
629  if (!localFilename.empty())
630  {
631  std::string absoluteFilename;
632  // check if we would find the local file
633  bool fileFound = ArmarXDataPath::getAbsolutePath(localFilename, absoluteFilename);
634 
635  if (fileFound)
636  {
637  ARMARX_IMPORTANT_S << "found local path:" << localFilename << " -> "
638  << absoluteFilename;
639  fn = localFilename;
640  }
641  else
642  {
643  ARMARX_IMPORTANT_S << "could not find global path from local path:" << localFilename
644  << " -> usign " << fn;
645  }
646  }
647 
648  return addObstacle(o, simType, fn);
649 }
650 
651 bool
652 SimulatedWorld::addObstacle(VirtualRobot::SceneObjectPtr o,
653  VirtualRobot::SceneObject::Physics::SimulationType simType,
654  const std::string& filename,
655  const std::string& objectClassName,
656  ObjectVisuPrimitivePtr primitiveData,
657  const std::string& project)
658 {
659  if (!o)
660  {
661  return false;
662  }
663 
664  ARMARX_VERBOSE_S << "Adding obstacle " << o->getName();
665 
666  // lock engine and data
667  ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
668  ScopedRecursiveLockPtr lockData = getScopedSyncLock(__FUNCTION__);
669 
670  //VirtualRobot::SceneObjectPtr clonedObj;
671  if (hasObject(o->getName()))
672  {
673  ARMARX_ERROR_S << "Object with name " << o->getName()
674  << " already present! Choose a different instance name";
675  return false;
676  }
677 
678  bool ok = addObstacleEngine(o, simType);
679  if (!ok)
680  {
681  return false;
682  }
683 
684  {
685  // access data
686 
687  if (primitiveData && (!filename.empty() || !objectClassName.empty()))
688  {
689  ARMARX_WARNING_S << "Internal error, either filename or classname or primitive";
690  }
691 
692 
693  armarx::ObjectVisuData ovd;
694  ovd.name = o->getName();
695  ovd.filename = filename;
696  ovd.project = project;
697  ovd.objectPoses[o->getName()] = new Pose(o->getGlobalPose());
698  ovd.objectClassName = objectClassName;
699 
700 
701  if (primitiveData)
702  {
703  ovd.objectPrimitiveData = primitiveData;
704  }
705 
706  ovd.updated = true;
707  simVisuData.objects.push_back(ovd);
708  }
709 
710  return true;
711 }
712 
713 auto
714 SimulatedWorld::getScopedEngineLock(const std::string& callStr) -> ScopedRecursiveLockPtr
715 {
716  ScopedRecursiveLockPtr l(new ScopedRecursiveLock(*engineMutex));
717 #ifdef PERFORMANCE_EVALUATION_LOCKS
718  if (engineMtxAccTime.find(callStr) == engineMtxAccTime.end())
719  {
720  engineMtxAccCalls[callStr] = 1;
721  engineMtxAccTime[callStr] = 0;
722  engineMtxLastTime[callStr] = IceUtil::Time::now();
723  }
724  else
725  {
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)
731  {
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();
738  }
739  }
740 #else
741  (void)callStr; // unused
742 #endif
743  return l;
744 }
745 
746 auto
747 SimulatedWorld::getScopedSyncLock(const std::string& callStr) -> ScopedRecursiveLockPtr
748 {
749  ScopedRecursiveLockPtr l(new ScopedRecursiveLock(*synchronizeMutex));
750 #ifdef PERFORMANCE_EVALUATION_LOCKS
751  if (syncMtxAccTime.find(callStr) == syncMtxAccTime.end())
752  {
753  syncMtxAccCalls[callStr] = 1;
754  syncMtxAccTime[callStr] = 0;
755  syncMtxLastTime[callStr] = IceUtil::Time::now();
756  }
757  else
758  {
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)
764  {
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();
771  }
772  }
773 #else
774  (void)callStr; // unused
775 #endif
776  return l;
777 }
778 
779 void
780 SimulatedWorld::setupFloor(bool enable, const std::string& floorTexture)
781 {
782  setupFloorEngine(enable, floorTexture);
783 
784  {
785  ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
786  simVisuData.floor = enable;
787  simVisuData.floorTextureFile = floorTexture;
788  }
789 }
790 
791 float
792 SimulatedWorld::getSimulationStepDuration()
793 {
794  return simTimeStepMS;
795 }
796 
797 float
798 SimulatedWorld::getSimulationStepTimeMeasured()
799 {
800  return simStepExecutionDurationMS;
801 }
802 
803 void
804 SimulatedWorld::enableLogging(const std::string& robotName, const std::string& logFile)
805 {
806  (void)robotName, (void)logFile; // unused
807 }
808 
809 float
810 SimulatedWorld::getSimTime()
811 {
812  return simStepExecutionDurationMS;
813 }
814 
815 float
816 SimulatedWorld::getSyncEngineTime()
817 {
818  return synchronizeDurationMS;
819 }
820 
821 bool
822 SimulatedWorld::synchronizeRobots()
823 {
824  // lock engine and data
825  ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
826  ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
827 
828  // update visu data
829  if (simVisuData.robots.size() == 0)
830  {
831  return false;
832  }
833  std::map<std::string, RobotVisuData*> visuRobotPtr;
834  for (auto& robot : simVisuData.robots)
835  {
836  std::string name = robot.name;
837 
838  if (!synchronizeRobotNodePoses(name, robot.robotNodePoses))
839  {
840  ARMARX_ERROR_S << "Failed to synchronize robot...";
841  return false;
842  }
843 
844  armarx::PosePtr p(new Pose(getRobotPose(name)));
845  robot.pose = p;
846  robot.updated = true;
847  visuRobotPtr[robot.name] = &robot;
848  }
849 
850  // update data for reporting
851 
852  for (auto& robot : simReportData.robots)
853  {
854  std::string name = robot.robotName;
855 
856  robot.pose = getRobotPose(name);
857 
858  getRobotStatus(name,
859  robot.jointAngles,
860  robot.jointVelocities,
861  robot.jointTorques,
862  robot.linearVelocity,
863  robot.angularVelocity);
864  if (visuRobotPtr.count(robot.robotName))
865  {
866  visuRobotPtr.at(robot.robotName)->jointValues = robot.jointAngles;
867  }
868 
869  // update force torque info
870  for (size_t i = 0; i < robot.forceTorqueSensors.size(); i++)
871  {
872  updateForceTorqueSensor(robot.forceTorqueSensors[i]);
873  }
874  }
875 
876  return true;
877 }
878 
879 bool
880 SimulatedWorld::synchronizeSimulationData()
881 {
882  IceUtil::Time startTime = IceUtil::Time::now();
883 
884  // lock engine and data
885  ScopedRecursiveLockPtr lockEngine = getScopedEngineLock(__FUNCTION__);
886  ScopedRecursiveLockPtr lockSync = getScopedSyncLock(__FUNCTION__);
887 
888  IceUtil::Time durationlock = IceUtil::Time::now() - startTime;
889 
890  if (durationlock.toMilliSecondsDouble() > 4)
891  {
893  << "Engine/Sync locking took long :" << durationlock.toMilliSecondsDouble()
894  << " ms";
895  }
896 
897  simVisuData.timestamp = static_cast<Ice::Long>(getCurrentSimTime() * 1000);
898  simReportData.timestamp = IceUtil::Time::secondsDouble(getCurrentSimTime());
899 
900  IceUtil::Time startTimeR = IceUtil::Time::now();
901  // ROBOT -> update visu & report data
902  synchronizeRobots();
903  IceUtil::Time durationR = IceUtil::Time::now() - startTimeR;
904  if (durationR.toMilliSecondsDouble() > 4)
905  {
907  << "Robot sync took long:" << durationR.toMilliSecondsDouble() << " ms";
908  }
909 
910  IceUtil::Time startTimeO = IceUtil::Time::now();
911  // OBJECTS -> visu & report data update
912  synchronizeObjects();
913  IceUtil::Time durationO = IceUtil::Time::now() - startTimeO;
914  if (durationO.toMilliSecondsDouble() > 4)
915  {
917  << "Object sync took long:" << durationO.toMilliSecondsDouble() << " ms";
918  }
919 
920  // CONTACTS
921  synchronizeSimulationDataEngine();
922 
923  IceUtil::Time duration = IceUtil::Time::now() - startTime;
924  synchronizeDurationMS = static_cast<float>(duration.toMilliSecondsDouble());
925 
926  currentSyncTimeSec = currentSimTimeSec;
927 
928  return true;
929 }
930 
931 void
932 SimulatedWorld::updateContacts(bool enable)
933 {
934  collectContacts = enable;
935 }
936 
937 SceneVisuData
938 SimulatedWorld::copySceneVisuData()
939 {
940  ScopedRecursiveLockPtr lock = getScopedSyncLock(__FUNCTION__);
941  return simVisuData;
942 }
943 
944 int
945 SimulatedWorld::getRobotJointAngleCount()
946 {
947  ScopedRecursiveLockPtr l = getScopedSyncLock(__FUNCTION__);
948 
949  if (simVisuData.robots.size() == 0)
950  {
951  return 0;
952  }
953 
954  return static_cast<int>(simVisuData.robots.at(0).robotNodePoses.size());
955 }
956 
957 int
958 SimulatedWorld::getContactCount()
959 {
960  ScopedRecursiveLockPtr l = getScopedSyncLock(__FUNCTION__);
961  return 0;
962 }
963 
964 int
965 SimulatedWorld::getObjectCount()
966 {
967  ScopedRecursiveLockPtr l = getScopedSyncLock(__FUNCTION__);
968  return static_cast<int>(simVisuData.objects.size());
969 }
armarx::ForceTorqueInfo::sensorName
std::string sensorName
Definition: SimulatedWorld.h:59
ARMARX_IMPORTANT_S
#define ARMARX_IMPORTANT_S
Definition: Logging.h:203
armarx::eFull
@ eFull
Definition: MorphingItem.h:35
armarx::SimulatedWorld::GraspingInfo::node2objectTransformation
Eigen::Matrix4f node2objectTransformation
Definition: SimulatedWorld.h:446
armarx::ForceTorqueInfo::robotName
std::string robotName
Definition: SimulatedWorld.h:57
LocalException.h
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
robots
std::vector< VirtualRobot::RobotPtr > robots
Definition: VisualizationRobot.cpp:86
VirtualRobot
Definition: FramedPose.h:43
armarx::ForceTorqueInfo::topicName
std::string topicName
Definition: SimulatedWorld.h:65
armarx::SimulatedWorld::GraspingInfo::robotName
std::string robotName
Definition: SimulatedWorld.h:443
armarx::ForceTorqueInfo
Definition: SimulatedWorld.h:48
armarx::RobotInfo::robotName
std::string robotName
Definition: SimulatedWorld.h:86
scene3D::ScenePtr
std::shared_ptr< Scene > ScenePtr
Definition: PointerDefinitions.h:36
visionx::imrecman::ok
@ ok
Definition: ImageRecordingManagerInterface.ice:46
project
std::string project
Definition: VisualizationRobot.cpp:83
armarx::ForceTorqueInfo::robotNodeName
std::string robotNodeName
Definition: SimulatedWorld.h:58
IceInternal::Handle< Pose >
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:72
armarx::GetHandledExceptionString
std::string GetHandledExceptionString()
Definition: Exception.cpp:147
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:69
ARMARX_DEBUG_S
#define ARMARX_DEBUG_S
Definition: Logging.h:198
armarx::SimulatedWorld::GraspingInfo
Definition: SimulatedWorld.h:441
armarx::SimulatedWorld::ScopedRecursiveLockPtr
std::shared_ptr< ScopedRecursiveLock > ScopedRecursiveLockPtr
Definition: SimulatedWorld.h:319
ARMARX_ERROR_S
#define ARMARX_ERROR_S
Definition: Logging.h:209
armarx::ScopedRecursiveLock
RecursiveMutex::scoped_lock ScopedRecursiveLock
Definition: Synchronization.h:142
armarx::ForceTorqueInfo::ftSensor
VirtualRobot::ForceTorqueSensorPtr ftSensor
Definition: SimulatedWorld.h:60
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:917
filename
std::string filename
Definition: VisualizationRobot.cpp:84
armarx::RobotInfo::forceTorqueSensors
std::vector< ForceTorqueInfo > forceTorqueSensors
Definition: SimulatedWorld.h:98
armarx::SimulatedWorld::GraspingInfo::robotNodeName
std::string robotNodeName
Definition: SimulatedWorld.h:444
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::RobotInfo
Definition: SimulatedWorld.h:70
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
armarx::viz::data::ElementFlags::names
const simox::meta::IntEnumNames names
Definition: json_elements.cpp:14
TimeUtil.h
float
#define float
Definition: 16_Level.h:22
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
FORCE_TORQUE_TOPIC_NAME
#define FORCE_TORQUE_TOPIC_NAME
Definition: SimulatedWorld.cpp:29
armarx::RobotInfo::robotTopicName
std::string robotTopicName
Definition: SimulatedWorld.h:87
scene3D::SceneObjectPtr
boost::intrusive_ptr< SceneObject > SceneObjectPtr
Definition: PointerDefinitions.h:40
armarx::SimulatedWorld::MutexType
MutexPtrType::element_type MutexType
Definition: SimulatedWorld.h:316
SimulatedWorld.h
ARMARX_VERBOSE_S
#define ARMARX_VERBOSE_S
Definition: Logging.h:200
armarx::SimulatedWorld::GraspingInfo::objectName
std::string objectName
Definition: SimulatedWorld.h:445
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
Logging.h
ArmarXDataPath.h
armarx::ForceTorqueInfo::enable
bool enable
Definition: SimulatedWorld.h:61
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::status::success
@ success
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18
armarx::SimulatedWorldData
The SimulatedWorldData class This data is queried by the simulated in order to offer it via topics.
Definition: SimulatedWorld.h:105