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