Simulator.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 2015
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25#include <filesystem>
26
27#include <VirtualRobot/MathTools.h>
28#include <VirtualRobot/XML/BaseIO.h>
29#include <VirtualRobot/XML/RobotIO.h>
30
34#define MAX_SIM_TIME_WARNING 25
35
36#include "Simulator.h"
37
38#ifdef MUJOCO_PHYSICS_WORLD
39#include "MujocoPhysicsWorld.h"
40#endif
41
42#include <SimoxUtility/algorithm/string/string_tools.h>
43#include <SimoxUtility/json.h>
44#include <VirtualRobot/Scene.h>
45#include <VirtualRobot/SceneObject.h>
46#include <VirtualRobot/XML/ObjectIO.h>
47#include <VirtualRobot/math/Helpers.h>
48
52
53#include <RobotAPI/interface/core/GeometryBase.h>
59
65#include <SimDynamics/DynamicsEngine/DynamicsObject.h>
66#include <SimDynamics/DynamicsEngine/DynamicsRobot.h>
67
68#ifdef ENABLE_SDF_FORMAT
69#include <sdf/sdf.hh>
70#endif
71
72using namespace armarx;
73using namespace memoryx;
74
77{
79 "SimoxSceneFileName", "", "Simox/VirtualRobot scene file name, e.g. myScene.xml");
80 defineOptionalProperty<bool>("FloorPlane", true, "Enable floor plane.");
81 defineOptionalProperty<std::string>("FloorTexture", "", "Texture file for floor.");
83 "LongtermMemory.SnapshotName", "", "Name of snapshot to load the scene")
84 .setCaseInsensitive(true);
86 "LoadSnapshotToWorkingMemory", true, "Load the snapshot also into the WorkingMemory");
87 defineOptionalProperty<bool>("LoadAgentsFromSnapshot",
88 false,
89 "Also load the agents from the snapshot into the WorkingMemory");
90
92 "WorkingMemoryName", "WorkingMemory", "Name of WorkingMemory")
93 .setCaseInsensitive(true);
95 "CommonStorageName", "CommonStorage", "Name of CommonStorage")
96 .setCaseInsensitive(true);
98 "PriorKnowledgeName", "PriorKnowledge", "Name of PriorKnowledge")
99 .setCaseInsensitive(true);
101 "LongtermMemoryName", "LongtermMemory", "Name of LongtermMemory")
102 .setCaseInsensitive(true);
103
104 defineOptionalProperty<std::string>("Scene.ObjectPackage",
105 "PriorKnowledgeData",
106 "Package to search for object models."
107 "Used when loading scenes from JSON files.");
109 "",
110 "Path to one or multiple JSON scene file(s) to load.\n"
111 "Example: 'PriorKnowledgeData/scenes/MyScene.json'.\n"
112 "Multiple paths are separated by semicolons (';').\n"
113 "The package to load a scene from is automatically"
114 "extracted from its first path segment.");
115
118 "Simulation type (Supported: Bullet, Kinematics, Mujoco)")
119 .map("bullet", SimulatorType::Bullet)
120 .map("kinematics", SimulatorType::Kinematics)
121 .map("mujoco", SimulatorType::Mujoco)
122 .setCaseInsensitive(true);
123
124 for (int i = -1; i < MAX_INITIAL_ROBOT_COUNT - 1; ++i)
125 {
126 std::string postfix;
127 if (i >= 0)
128 {
129 postfix = "_" + ValueToString(i);
130 }
131
133 "RobotFileName" + postfix,
134 "",
135 "Simox/VirtualRobot robot file name, e.g. robot_model.xml");
137 "RobotInstanceName" + postfix, "", "Name of this robot instance");
139 "RobotIsStatic" + postfix,
140 false,
141 "A static robot does not move due to the physical environment (i.e. no gravity). \n"
142 "It is a static (but kinematic) object in the world.");
143 defineOptionalProperty<bool>("ReportRobotPose", false, "Report the global robot pose.");
145 "RobotCollisionModel" + postfix, false, "Show the collision model of the robot.");
147 "InitialRobotPose.x" + postfix, 0.f, "x component of initial robot position (mm)");
149 "InitialRobotPose.y" + postfix, 0.f, "y component of initial robot position (mm)");
151 "InitialRobotPose.z" + postfix, 0.f, "z component of initial robot position (mm)");
152 defineOptionalProperty<float>("InitialRobotPose.roll" + postfix,
153 0.f,
154 "Initial robot pose: roll component of RPY angles (radian)");
155 defineOptionalProperty<float>("InitialRobotPose.pitch" + postfix,
156 0.f,
157 "Initial robot pose: pitch component of RPY angles (radian)");
158 defineOptionalProperty<float>("InitialRobotPose.yaw" + postfix,
159 0.f,
160 "Initial robot pose: yaw component of RPY angles (radian)");
162 "InitialRobotConfig" + postfix,
163 "",
164 "Initial robot config as comma separated list (RobotNodeName:value)");
165
167 "InitialNamedRobotConfig" + postfix,
168 "",
169 "Initial named robot config, e.g., `Home`.");
170
172 "RobotScaling" + postfix, 1.0f, "Scaling of the robot (1 = no scaling).");
174 "RobotControllerPID.p" + postfix, 10.0, "Setup robot controllers: PID paramter p.");
176 "RobotControllerPID.i" + postfix, 0.0, "Setup robot controllers: PID paramter i.");
178 "RobotControllerPID.d" + postfix, 0.0, "Setup robot controllers: PID paramter d.");
180 "RobotSelfCollisions" + postfix,
181 false,
182 "If false, the robot bodies will not collide with other bodies of this \n"
183 "robot but with all other bodies in the world. \n"
184 "If true, the robot bodies will collide with all other bodies \n"
185 "(This needs an accurately modelled robot model without self collisions \n"
186 "if the robot does not move.)");
187 }
189 "FixedTimeStepLoopNrSteps",
190 10,
191 "The maximum number of internal simulation loops (fixed time step mode).\n"
192 "After max number of time steps, the remaining time is interpolated.");
194 "FixedTimeStepStepTimeMS",
195 16,
196 "The simulation's internal timestep (fixed time step mode). \n"
197 "This property determines the precision of the simulation. \n"
198 "Needs to be set to bigger values for slow PCs, but the simulation results might be bad. "
199 "Smaller value for higher precision, but slower calculation.");
200 defineOptionalProperty<int>("StepTimeMS", 25, "The simulation's time progress per step. ");
202 "RealTimeMode",
203 false,
204 "If true the timestep is adjusted to the computing power of the host and \n"
205 "the time progress in real time. Can result in bad results on slow PCs. \n"
206 "The property StepTimeMS has then no effect. FixedTimeStepStepTimeMS needs \n"
207 "to be adjusted if real time cannot be achieved on slower PCs.");
209 "MaxRealTime",
210 1,
211 "If not zero and the real time mode is off, the simulator will not run \n"
212 "\tfaster than real-time * MaxRealTime even if the machine is fast enough \n"
213 "\t(a sleep is inserted to slow down the simulator - the precision remains unchanged).\n"
214 "\tIf set to 2, the simulator will not run faster than double speed. \n"
215 "\tIf set to 0.5, the simulator will not run faster than half speed. \n"
216 "\tIf set to 0, the simulator will run as fast as possible.\n");
217
219 "LogRobot",
220 false,
221 "Enable robot logging. If true, the complete robot state is logged to a file each step.");
222
223 defineOptionalProperty<int>("ReportVisuFrequency",
224 30,
225 "How often should the visualization data be published. Value is "
226 "given in Hz. (0 to disable)");
228 "ReportVisuTopicName",
229 "SimulatorVisuUpdates",
230 "The topic on which the visualization updates are published.");
232 "ReportDataFrequency",
233 30,
234 "How often should the robot data be published. Value is given in Hz. (0 to disable)");
236 "FixedObjects",
237 "",
238 "Fixate objects or parts of a robot in the world. Comma separated list. \n"
239 "Define objects by their name, robots can be defined with robotName:RobotNodeName");
240 defineOptionalProperty<bool>("DrawCoMVisu",
241 true,
242 "If true the CoM of each robot is drawn as a circle on the ground "
243 "after each simulation cycle.");
244}
245
249
250Simulator::Simulator() : SimulatorInterface(), Component()
251{
252 // create data object
253 //physicsWorld.reset(new BulletPhysicsWorld());
254 //physicsWorldData.reset(new ArmarXPhysicsWorldData());
255
260 timeServerSpeed = 1;
261
262 publishContacts = false;
263 contactLayerName = "contacts";
265}
266
268{
269 ARMARX_VERBOSE << "~Simulator";
270}
271
272std::string
274{
275 return "Simulator";
276}
277
278void
280{
281 priorKnowledgeName = getProperty<std::string>("PriorKnowledgeName").getValue();
282 commonStorageName = getProperty<std::string>("CommonStorageName").getValue();
283 ARMARX_INFO << "Init component.";
284
285 std::string snapshotName = getProperty<std::string>("LongtermMemory.SnapshotName").getValue();
286
287 if (!snapshotName.empty())
288 {
289 ARMARX_LOG << "UsingProxy LongtermMemory for snapshot " << snapshotName;
290 usingProxy(getProperty<std::string>("WorkingMemoryName").getValue());
291 usingProxy(getProperty<std::string>("LongtermMemoryName").getValue());
292 usingProxy(getProperty<std::string>("CommonStorageName").getValue());
293 usingProxy(getProperty<std::string>("PriorKnowledgeName").getValue());
294 }
295 else
296 {
297 ARMARX_LOG << "Not using LongtermMemoryProxy";
298 }
299
300 bool floorPlane = getProperty<bool>("FloorPlane").getValue();
301 std::string floorTexture = getProperty<std::string>("FloorTexture");
302
303 SimulatorType simulatorType = SimulatorType::Bullet;
304 try
305 {
306 simulatorType = getProperty<SimulatorType>("SimulationType");
307 }
308 catch (...)
309 {
310 }
311
312 offeringTopic("GlobalRobotPoseLocalization");
313 offeringTopic("SimulatorResetEvent");
314 getProperty(reportRobotPose, "ReportRobotPose");
315
316 const int stepTimeMs = getProperty<int>("StepTimeMS");
317 const float maxRealTime = getProperty<float>("MaxRealTime");
318 ARMARX_CHECK_NONNEGATIVE(maxRealTime);
319
320
321 switch (simulatorType)
322 {
324 {
326 kw->initialize(stepTimeMs, maxRealTime, floorPlane, floorTexture);
327 physicsWorld = kw;
328 }
329 break;
331 {
332 int bulletFixedTimeStepMS = getProperty<int>("FixedTimeStepStepTimeMS").getValue();
333 int bulletFixedTimeStepMaxNrLoops =
334 getProperty<int>("FixedTimeStepLoopNrSteps").getValue();
336 bw->initialize(stepTimeMs,
337 bulletFixedTimeStepMS,
338 bulletFixedTimeStepMaxNrLoops,
339 maxRealTime,
340 floorPlane,
341 floorTexture);
342 physicsWorld = bw;
343 }
344 break;
346 {
347#ifdef MUJOCO_PHYSICS_WORLD
349 // initialize mujoco
350
351 mw->initialize(stepTimeMs, floorPlane, floorTexture);
352
353 physicsWorld = mw;
354#else
355 ARMARX_ERROR << "Simulator type 'mujoco' is not supported, since simulator was built "
356 "without MujocoX."
357 << "\nGet the package MujocoX from: https://gitlab.com/h2t/mujoco .";
358 return;
359#endif
360 }
361 break;
362 }
363
365 getArmarXManager()->addObject(timeserverProxy);
366 offeringTopic(TIME_TOPIC_NAME);
367}
368
369void
370Simulator::addRobotsFromProperties()
371{
372 for (int i = -1; i < MAX_INITIAL_ROBOT_COUNT - 1; ++i)
373 {
374 std::string postfix;
375 if (i >= 0)
376 {
377 postfix = "_" + ValueToString(i);
378 }
379 if (!getProperty<std::string>("RobotFileName" + postfix).isSet() ||
380 getProperty<std::string>("RobotFileName" + postfix).getValue().empty())
381 {
382 continue;
383 }
384
385 std::string robotFile = getProperty<std::string>("RobotFileName" + postfix).getValue();
386 Eigen::Matrix4f gp = Eigen::Matrix4f::Identity();
387
388 VirtualRobot::MathTools::rpy2eigen4f(
389 getProperty<float>("InitialRobotPose.roll" + postfix).getValue(),
390 getProperty<float>("InitialRobotPose.pitch" + postfix).getValue(),
391 getProperty<float>("InitialRobotPose.yaw" + postfix).getValue(),
392 gp);
393
394 math::Helpers::Position(gp) =
395 Eigen::Vector3f(getProperty<float>("InitialRobotPose.x" + postfix).getValue(),
396 getProperty<float>("InitialRobotPose.y" + postfix).getValue(),
397 getProperty<float>("InitialRobotPose.z" + postfix).getValue());
398
399 ARMARX_INFO << "Initial robot pose:\n" << gp;
400 std::map<std::string, float> initConfig;
401
402 if(getProperty<std::string>("InitialNamedRobotConfig" + postfix).isSet())
403 {
404 std::string confStr =
405 getProperty<std::string>("InitialNamedRobotConfig" + postfix).getValue();
406
407 ARMARX_INFO << "Using named robot config: " << QUOTED(confStr);
408
409 ARMARX_CHECK_NOT_EMPTY(robotFile);
410 std::string robFileGlobal = robotFile;
411
412 if (!ArmarXDataPath::getAbsolutePath(robotFile, robFileGlobal))
413 {
414 ARMARX_ERROR << "Could not find robot file " << robotFile;
415 }
416
417 const auto robot = VirtualRobot::RobotIO::loadRobot(robFileGlobal, VirtualRobot::BaseIO::eStructure);
418 ARMARX_CHECK_NOT_NULL(robot) << "Could not load robot from file " << QUOTED(robFileGlobal);
419
420 const std::optional<std::map<std::string, float>> namedConfig =
421 robot->getConfiguration(confStr);
422
423 ARMARX_CHECK_NOT_NULL(namedConfig)
424 << "Could not find named robot config " << QUOTED(confStr) << " in robot file "
425 << QUOTED(robFileGlobal);
426
427 initConfig = namedConfig.value();
428
429 if (getProperty<std::string>("InitialRobotConfig" + postfix).isSet())
430 {
431 ARMARX_WARNING << "Ignoring InitialRobotConfig entry "
432 << getProperty<std::string>("InitialRobotConfig" + postfix).getValue()
433 << " because InitialNamedRobotConfig is set.";
434 }
435
436 }
437 else if (getProperty<std::string>("InitialRobotConfig" + postfix).isSet())
438 {
439
440 std::string confStr =
441 getProperty<std::string>("InitialRobotConfig" + postfix).getValue();
442 std::vector<std::string> confList = Split(confStr, ",", true, true);
443 for (auto& pos : confList)
444 {
445 ARMARX_INFO << "Processing '" << pos << "'";
446 std::vector<std::string> d = Split(pos, ":", true, true);
447 if (d.size() != 2)
448 {
449 ARMARX_WARNING << "Ignoring InitialRobotConfig entry " << pos;
450 continue;
451 }
452 std::string name = d.at(0);
453
454 initConfig[name] = static_cast<float>(atof(d.at(1).c_str()));
455 ARMARX_INFO << "1:'" << name << "', 2:" << initConfig[name];
456 }
457 }
458
459
460 double pid_p = getProperty<double>("RobotControllerPID.p" + postfix).getValue();
461 double pid_i = getProperty<double>("RobotControllerPID.i" + postfix).getValue();
462 double pid_d = getProperty<double>("RobotControllerPID.d" + postfix).getValue();
463
464 std::string robotInstanceName =
465 getProperty<std::string>("RobotInstanceName" + postfix).getValue();
466
467 bool staticRobot = getProperty<bool>("RobotIsStatic" + postfix).getValue();
468 bool colModelRobot = getProperty<bool>("RobotCollisionModel" + postfix).getValue();
469 float scaling = getProperty<float>("RobotScaling" + postfix).getValue();
470 bool selfCollisions = getProperty<bool>("RobotSelfCollisions" + postfix);
471 if (!robotFile.empty())
472 {
473 std::string robFileGlobal = robotFile;
474
475 if (!ArmarXDataPath::getAbsolutePath(robotFile, robFileGlobal))
476 {
477 ARMARX_ERROR << "Could not find robot file " << robotFile;
478 }
479 else
480 {
481 ARMARX_INFO << "Adding robot with name '" << robotInstanceName << "' from file "
482 << robFileGlobal;
483 addRobot(robotInstanceName,
484 robFileGlobal,
485 gp,
486 robotFile,
487 pid_p,
488 pid_i,
489 pid_d,
490 staticRobot,
491 scaling,
492 colModelRobot,
493 initConfig,
494 selfCollisions);
495 }
496 }
497 }
498}
499
500void
501Simulator::addSceneFromFile(const std::string& sceneFile)
502{
503 std::string sf;
504 if (!ArmarXDataPath::getAbsolutePath(sceneFile, sf))
505 {
506 ARMARX_ERROR << "Could not find scene file " << sceneFile;
507 }
508 else
509 {
510 ARMARX_INFO << "Loading scene " << sf << "...";
511 physicsWorld->addScene(sf);
512 // setup robot topics
514 }
515}
516
517void
518Simulator::addSceneFromMemorySnapshot(const std::string& snapshotName)
519{
521 if (!fileManager)
522 {
523 ARMARX_ERROR << "No connection to memory - cannot add snapshot!";
524 return;
525 }
527 getProperty<std::string>("WorkingMemoryName").getValue());
528
529
532 getProperty<std::string>("LongtermMemoryName").getValue());
533 WorkingMemorySnapshotInterfacePrx snapshotInterfacePrx;
534
536 {
537 ARMARX_LOG << "Loading snapshot " << snapshotName;
538
539 try
540 {
541 snapshotInterfacePrx =
542 longtermMemoryPrx->getWorkingMemorySnapshotListSegment()->openSnapshot(
543 snapshotName);
544 if (getProperty<bool>("LoadSnapshotToWorkingMemory").getValue())
545 {
546 if (snapshotInterfacePrx)
547 {
548 longtermMemoryPrx->loadWorkingMemorySnapshot(snapshotName, memoryPrx);
549 }
550 else
551 {
552 ARMARX_ERROR << "Could not get snapshot segment from longterm memory...";
553 }
554 }
555 }
556 catch (memoryx::SnapshotNotFoundException&)
557 {
558 ARMARX_ERROR << "Could not find snapshot: " << snapshotName;
559 }
560 catch (...)
561 {
562 ARMARX_ERROR << "Failed to load snapshot with name:" << snapshotName;
563 }
564 }
565 else
566 {
567 ARMARX_ERROR << "Could not get PriorKnowledge/LongtermMemory/WorkingMemory Proxy";
568 }
569
570 if (longtermMemoryPrx && priorKnowledgePrx && fileManager && snapshotInterfacePrx)
571 {
572 ARMARX_LOG << "Found and opened snapshot " << snapshotName;
573 addSnapshot(snapshotInterfacePrx);
574 }
575 else
576 {
577 ARMARX_ERROR << "Failed to open snapshot " << snapshotName;
578 }
579}
580
581void
582Simulator::addSceneFromSdfFile(const std::string& scenePath)
583{
584#ifdef ENABLE_SDF_FORMAT
585 std::string scenePackage = simox::alg::split(scenePath, "/").at(0);
586 CMakePackageFinder cmakeFinder(scenePackage);
587 if (!cmakeFinder.packageFound())
588 {
589 ARMARX_WARNING << "Could not find CMake package " << scenePackage << ".";
590 return;
591 }
592
593 std::filesystem::path dataDir = cmakeFinder.getDataDir();
594 std::filesystem::path path = dataDir / scenePath;
595
596
597 sdf::SDFPtr sdfFile(new sdf::SDF());
598 sdf::init(sdfFile);
599
600 std::filesystem::path modelDirectory = path.parent_path();
601
602 const std::string modelURI = "model://";
603
604 auto findFileCallback = [this, &modelURI](const std::string& uri) -> std::string
605 {
606 std::stringstream ss;
607 ss << "Find '" << uri << "' ... -> ";
608
609 const std::string classIDStr = simox::alg::remove_prefix(uri, modelURI);
610 const ObjectID classID = ObjectID::FromString(classIDStr);
611
612 if (std::optional<ObjectInfo> info = objectFinder.findObject(classID))
613 {
614 if (std::optional<PackageFileLocation> modelPath = info->getModel())
615 {
616 std::filesystem::path result = modelPath->absolutePath.parent_path();
617 ss << result;
618 ARMARX_VERBOSE << ss.str();
619
620 return result;
621 }
622 }
623 ss << uri;
624 ARMARX_VERBOSE << ss.str();
625
626 return uri;
627 };
628
629 sdf::ParserConfig parser;
630 parser.AddURIPath(modelURI, modelDirectory.string());
631 parser.SetFindCallback(findFileCallback);
632
633 sdf::Root root;
634 sdf::Errors errors = root.Load(path.string(), parser);
635
636 for (auto const& error : errors)
637 {
638 ARMARX_ERROR << "Error on reading SDF: " << error;
639 }
640
641 if (!errors.empty())
642 {
643 ARMARX_WARNING << "Could not load SDF from '" << path << "'";
644 return;
645 }
646
647 if (root.WorldCount() == 0)
648 {
649 ARMARX_WARNING << "SDF does not contain a world";
650 return;
651 }
652
653 if (root.WorldCount() > 1)
654 {
655 ARMARX_WARNING << "SDF contains multiple worlds";
656 return;
657 }
658
659 sdf::World* world = root.WorldByIndex(0);
660 auto addSceneObject = [&](sdf::Model* model)
661 {
662 const std::string name = model->Name();
663 if (physicsWorld->hasObject(name))
664 {
665 ARMARX_WARNING << "Object with name \"" << name << "\" already exists.";
666 return;
667 }
668
669 const std::string uri = model->Uri();
670 if (uri.empty())
671 {
672 ARMARX_WARNING << "No URI set for object \"" << name << "\" in SDF.";
673 return;
674 }
675
676
677 // Not clear where the result of the callback called during loading is stored.
678 const std::filesystem::path modelPath = findFileCallback(uri);
679
680 gz::math::Pose3d pose = model->RawPose();
681
682 const float meterToMillimeter = 1000.0F;
683
684 Eigen::Vector3f position;
685 position.x() = static_cast<float>(pose.Pos().X() * meterToMillimeter);
686 position.y() = static_cast<float>(pose.Pos().Y() * meterToMillimeter);
687 position.z() = static_cast<float>(pose.Pos().Z() * meterToMillimeter);
688
689 Eigen::Quaternionf orientation;
690 orientation.x() = static_cast<float>(pose.Rot().X());
691 orientation.y() = static_cast<float>(pose.Rot().Y());
692 orientation.z() = static_cast<float>(pose.Rot().Z());
693 orientation.w() = static_cast<float>(pose.Rot().W());
694
695 auto isStatic = model->Static();
696
697 std::string robotFilename = modelPath.filename().generic_string() + ".urdf";
698 std::filesystem::path robotPath = modelPath / robotFilename;
699
700 std::string xmlFilename = modelPath.filename().generic_string() + ".xml";
701 std::filesystem::path xmlPath = modelPath / xmlFilename;
702
703 if (std::filesystem::exists(xmlPath))
704 {
705 ARMARX_INFO << "Loading object '" << name << "' from object XML file " << xmlPath;
706 VirtualRobot::ManipulationObjectPtr simoxObject =
707 VirtualRobot::ObjectIO::loadManipulationObject(xmlPath.string());
708
709 simoxObject->setGlobalPose(simox::math::pose(position, orientation));
710
711 VirtualRobot::SceneObject::Physics::SimulationType simType =
712 isStatic ? VirtualRobot::SceneObject::Physics::eKinematic
713 : VirtualRobot::SceneObject::Physics::eDynamic;
714
715 simoxObject->setSimulationType(simType);
716 simoxObject->setFilename(xmlPath.string());
717 simoxObject->setName(name);
718
719 physicsWorld->addObstacle(
720 simoxObject, simType, xmlPath.string(), name, {}, scenePackage);
721 }
722 else if (std::filesystem::exists(robotPath))
723 {
724 ARMARX_INFO << "Loading object '" << name << "' from robot URDF file " << xmlPath;
725 VirtualRobot::RobotPtr robot = VirtualRobot::RobotIO::loadRobot(robotPath);
726
727 robot->setGlobalPose(simox::math::pose(position, orientation));
728
729 VirtualRobot::SceneObject::Physics::SimulationType simType =
730 isStatic ? VirtualRobot::SceneObject::Physics::eKinematic
731 : VirtualRobot::SceneObject::Physics::eDynamic;
732
733 robot->setSimulationType(simType);
734 robot->setFilename(robotPath.string());
735 robot->setName(name);
736
737 physicsWorld->addRobot(robot, 10.0, 0.0, 0.0, robotPath.string(), isStatic);
738 }
739 else
740 {
742 << "Not adding object '" << name
743 << "' because neither object XML nor robot URDF file exist. (Tried object XML = "
744 << xmlPath << " and robot URDF = " << robotPath << ")";
745 }
746 };
747
748 for (size_t index = 0; index < world->ModelCount(); index++)
749 {
750 addSceneObject(world->ModelByIndex(index));
751 }
752#else
753 ARMARX_ERROR << "Loading from SDF file was not compiled";
754#endif
755}
756
757void
758Simulator::addSceneFromJsonFile(const std::string& scenePath)
759{
760 std::string mutScenePath = scenePath;
761 if (!simox::alg::ends_with(mutScenePath, ".json"))
762 {
763 mutScenePath += ".json";
764 }
765
766 std::string scenePackage = simox::alg::split(scenePath, "/").at(0);
767 CMakePackageFinder cmakeFinder(scenePackage);
768 if (!cmakeFinder.packageFound())
769 {
770 ARMARX_WARNING << "Could not find CMake package " << scenePackage << ".";
771 return;
772 }
773
774 std::filesystem::path dataDir = cmakeFinder.getDataDir();
775 std::filesystem::path path = dataDir / scenePath;
776
777 armarx::objects::Scene scene;
778 try
779 {
780 scene = simox::json::read<armarx::objects::Scene>(path);
781 }
782 catch (const simox::json::error::JsonError& e)
783 {
784 ARMARX_WARNING << "Loading scene snapshot failed: \n" << e.what();
785 return;
786 }
787
788 std::map<ObjectID, int> idCounters;
789 for (const auto& object : scene.objects)
790 {
791 if (simox::alg::starts_with(object.className, "#"))
792 {
793 // we ignore stuff that is out commented in json
794 continue;
795 }
796
797 addJsonSceneObject(object, idCounters);
798 }
799}
800
801void
802Simulator::addJsonSceneObject(const armarx::objects::SceneObject object,
803 std::map<ObjectID, int>& idCounters)
804{
805 const ObjectID classID = object.getClassID();
806 const std::string name =
807 object.getObjectID()
808 .withInstanceName(object.instanceName.empty() ? std::to_string(idCounters[classID]++)
809 : object.instanceName)
810 .str();
811
812 if (physicsWorld->hasObject(name))
813 {
814 ARMARX_INFO << "Object with name \"" << name << "\" already exists.";
815 return;
816 }
817
818 ARMARX_INFO << "Adding object with name \"" << name << "\" to scene.";
819
820 std::optional<ObjectInfo> objectInfo = objectFinder.findObject(classID);
821 VirtualRobot::ManipulationObjectPtr simoxObject =
822 VirtualRobot::ObjectIO::loadManipulationObject(objectInfo->simoxXML().absolutePath);
823 simoxObject->setGlobalPose(simox::math::pose(object.position, object.orientation));
824
825 VirtualRobot::SceneObject::Physics::SimulationType simType;
826 if (object.isStatic.has_value())
827 {
828 simType = *object.isStatic ? VirtualRobot::SceneObject::Physics::eKinematic
829 : VirtualRobot::SceneObject::Physics::eDynamic;
830 }
831 else
832 {
833 simType = VirtualRobot::SceneObject::Physics::eKinematic;
834 }
835
836 PackageFileLocation simoxXml = objectInfo->simoxXML();
837 simoxObject->setSimulationType(simType);
838 simoxObject->setFilename(simoxXml.absolutePath);
839 simoxObject->setName(name);
840
841 physicsWorld->addObstacle(
842 simoxObject, simType, simoxXml.relativePath, object.className, {}, simoxXml.package);
843}
844
845void
846Simulator::fixateRobotNode(const std::string& robotName, const std::string& robotNodeName)
847{
848 ARMARX_VERBOSE << "Fixing robot node" << robotName << "." << robotNodeName;
849 physicsWorld->setRobotNodeSimType(
850 robotName, robotNodeName, VirtualRobot::SceneObject::Physics::eStatic);
851}
852
853void
854Simulator::fixateObject(const std::string& objectName)
855{
856 ARMARX_VERBOSE << "Fixing object" << objectName;
857 physicsWorld->setObjectSimType(objectName, VirtualRobot::SceneObject::Physics::eStatic);
858}
859
860void
862{
863 ARMARX_INFO << "Initializing simulator...";
864
865 addRobotsFromProperties();
866
867 std::string sceneFile = getProperty<std::string>("SimoxSceneFileName").getValue();
868 if (!sceneFile.empty())
869 {
870 addSceneFromFile(sceneFile);
871 }
872
873 std::string snapshotName = getProperty<std::string>("LongtermMemory.SnapshotName").getValue();
874 if (!snapshotName.empty())
875 {
876 addSceneFromMemorySnapshot(snapshotName);
877 }
878
879 std::string objectPackage = getProperty<std::string>("Scene.ObjectPackage").getValue();
880 objectFinder = ObjectFinder(objectPackage);
881
882 std::string scenePaths = getProperty<std::string>("Scene.Path").getValue();
883 if (!scenePaths.empty())
884 {
885 bool trim = true;
886 for (const std::string& scenePath : simox::alg::split(scenePaths, ";", trim))
887 {
888 std::filesystem::path path = scenePath;
889 std::string sdfExtension = ".sdf";
890
891 if (path.has_extension() && path.extension().string() == sdfExtension)
892 {
893 ARMARX_INFO << "Loading scene from SDF file '" << scenePath << "' ...";
894 addSceneFromSdfFile(scenePath);
895 }
896 else
897 {
898 ARMARX_INFO << "Loading scene from JSON file '" << scenePath << "' ...";
899 addSceneFromJsonFile(scenePath);
900 }
901 }
902 }
903
904 //check for fixed objects
905 std::string fixedObjects = getProperty<std::string>("FixedObjects").getValue();
906 if (!fixedObjects.empty())
907 {
908 std::vector<std::string> objects = Split(fixedObjects, ",;");
909 for (auto o : objects)
910 {
911 std::vector<std::string> rob = Split(o, ":");
912 if (rob.size() == 2)
913 {
914 // robot
915 fixateRobotNode(rob.at(0), rob.at(1));
916 }
917 else
918 {
919 // object
920 fixateObject(o);
921 }
922 }
923 }
924
925 physicsWorld->resetSimTime();
926}
927
928SimulatedRobotState
930{
931 SimulatedRobotState state;
932
933 state.hasRobot = true;
934 state.timestampInMicroSeconds = timestamp.toMicroSeconds();
935
936 state.jointAngles = std::move(r.jointAngles);
937 state.jointVelocities = std::move(r.jointVelocities);
938 state.jointTorques = std::move(r.jointTorques);
939
940 state.pose = new Pose(r.pose);
941 state.linearVelocity = new Vector3(r.linearVelocity);
942 state.angularVelocity = new Vector3(r.angularVelocity);
943
944 for (auto& forceTorqueSensor : r.forceTorqueSensors)
945 {
946 if (forceTorqueSensor.enable)
947 {
948 ForceTorqueData& ftData = state.forceTorqueValues.emplace_back();
949 ftData.force = new Vector3(forceTorqueSensor.currentForce);
950 ftData.torque = new Vector3(forceTorqueSensor.currentTorque);
951 ftData.sensorName = forceTorqueSensor.sensorName;
952 ftData.nodeName = forceTorqueSensor.robotNodeName;
953 }
954 }
955
956 return state;
957}
958
961{
962 if (fileManager)
963 {
965 << "Was able to find a reference to the CommonStorage. Continue with existing "
966 "connection to memory.";
967 return fileManager;
968 }
969 CommonStorageInterfacePrx commonStoragePrx =
971
972 if (commonStoragePrx)
973 {
975 << "Was able to find a reference to the CommonStorage. Reset GridFSManager and "
976 "continue with memory.";
977 fileManager.reset(new GridFileManager(commonStoragePrx));
978 }
979 else
980 {
982 << "Could not get CommonStorage Proxy - continuing without memory";
983 }
984 return fileManager;
985}
986
987void
989{
990 ARMARX_VERBOSE << "Connecting ArmarX Simulator";
991
992 getTopic(globalRobotLocalization, "GlobalRobotPoseLocalization");
993 getTopic(simulatorResetEventTopic, "SimulatorResetEvent");
994
996
997 int hzVisu = getProperty<int>("ReportVisuFrequency").getValue();
998 int hzData = getProperty<int>("ReportDataFrequency").getValue();
999 std::string top = getProperty<std::string>("ReportVisuTopicName").getValue();
1000
1002
1003 ARMARX_DEBUG << "Starting periodic simulation task in ArmarX Simulator";
1004
1006 start();
1007
1008 ARMARX_DEBUG << "Starting periodic visualization report task in ArmarX Simulator";
1009
1010 if (reportVisuTask)
1011 {
1012 reportVisuTask->stop();
1013 }
1014
1015 if (hzVisu > 0)
1016 {
1017 offeringTopic(top);
1018 ARMARX_INFO << "Connecting to topic " << top;
1020
1021 ARMARX_DEBUG << "Creating report visu task";
1022 int cycleTime = 1000 / hzVisu;
1024 this, &Simulator::reportVisuLoop, cycleTime, false, "ArmarXSimulatorReportVisuTask");
1025 reportVisuTask->start();
1026 reportVisuTask->setDelayWarningTolerance(100);
1027 }
1028
1029 ARMARX_DEBUG << "Starting periodic data report task in ArmarX Simulator";
1030
1031 if (reportDataTask)
1032 {
1033 reportDataTask->stop();
1034 }
1035
1036 if (hzData > 0)
1037 {
1038 int cycleTime = 1000 / hzData;
1040 this, &Simulator::reportDataLoop, cycleTime, false, "ArmarXSimulatorReportDataTask");
1041 reportDataTask->start();
1042 reportDataTask->setDelayWarningTolerance(100);
1043 }
1044
1045 ARMARX_DEBUG << "finished connection";
1046}
1047
1048void
1050{
1051 ARMARX_VERBOSE << "disconnecting Simulator";
1052
1053 if (reportDataTask)
1054 {
1055 reportDataTask->stop();
1056 }
1057
1058 if (reportVisuTask)
1059 {
1060 reportVisuTask->stop();
1061 }
1062
1064
1065 resetData();
1066}
1067
1068void
1070{
1071 ARMARX_VERBOSE << "exiting Simulator";
1072
1073 if (reportDataTask)
1074 {
1075 ARMARX_VERBOSE << "stopping report task";
1076 reportDataTask->stop();
1077 ARMARX_VERBOSE << "stopping report task...Done!";
1078 }
1079
1080 if (reportVisuTask)
1081 {
1082 ARMARX_VERBOSE << "stopping visu task";
1083 reportVisuTask->stop();
1084 ARMARX_VERBOSE << "stopping visu task...Done!";
1085 }
1086
1089 nullptr; // delete the timeserver proxy as it holds a handle to this object, preventing it from being deleted
1090 ARMARX_VERBOSE << "exiting Simulator...Done";
1091}
1092
1093void
1095{
1096 ARMARX_VERBOSE << "shutting down simulation loop";
1099 condSimulatorThreadRunning.notify_all();
1100 ARMARX_VERBOSE << "---- get thread control";
1101 IceUtil::ThreadControl threadControl = getThreadControl();
1102 ARMARX_VERBOSE << "---- get thread control...Done!";
1103 ARMARX_VERBOSE << "---- joining thread control";
1104 if (isAlive())
1105 {
1106 threadControl.join();
1107 }
1108 ARMARX_VERBOSE << "---- joining thread control...Done!";
1109 ARMARX_VERBOSE << "shutting down simulation loop...Done!";
1110}
1111
1112void
1113Simulator::resetData(bool clearWorkingMemory)
1114{
1115 ARMARX_INFO << "Deleting data";
1116
1117 auto lockEngine = physicsWorld->getScopedEngineLock(__FUNCTION__);
1118 auto lockData = physicsWorld->getScopedSyncLock(__FUNCTION__);
1119
1120 {
1121 ARMARX_INFO << "Clearing class map...";
1122 classInstanceMap.clear();
1123
1124 physicsWorld->resetData();
1125 }
1126
1127 if (clearWorkingMemory && memoryPrx)
1128 {
1129 ARMARX_INFO << "Clearing working memory...";
1130
1131 try
1132 {
1133 memoryPrx->clear();
1134 }
1135 catch (...)
1136 {
1137 ARMARX_WARNING << "Clearing working memory failed...";
1138 }
1139 }
1140 ARMARX_VERBOSE << "Deleting data...Done!";
1141}
1142
1143bool
1144Simulator::addSnapshot(WorkingMemorySnapshotInterfacePrx snapshotInterfacePrx)
1145{
1146 ARMARX_VERBOSE << "Adding snapshot from memory";
1147
1148 if (!snapshotInterfacePrx || !priorKnowledgePrx)
1149 {
1150 ARMARX_ERROR << "Null data?!";
1151 return false;
1152 }
1153
1154 const std::string segmentName = "objectInstances";
1155
1156 try
1157 {
1158 PersistentEntitySegmentBasePrx segInstances = snapshotInterfacePrx->getSegment(segmentName);
1159
1160 if (!segInstances)
1161 {
1162 ARMARX_ERROR << "Segment not found in snapshot: " << segmentName;
1163 return false;
1164 }
1165
1166 // get classes for IV file loading (instances refer to classes, and classes store IV files)
1167 PersistentObjectClassSegmentBasePrx classesSegmentPrx =
1168 priorKnowledgePrx->getObjectClassesSegment();
1169
1170 if (!classesSegmentPrx)
1171 {
1172 ARMARX_ERROR << "Classes Segment not found in PriorKnowledge";
1173 return false;
1174 }
1175
1176
1177 EntityIdList ids = segInstances->getAllEntityIds();
1178
1179 int c = 0;
1180
1181 for (EntityIdList::const_iterator it = ids.begin(); it != ids.end(); ++it)
1182 {
1183 EntityBasePtr snapEntity = segInstances->getEntityById(*it);
1184 ObjectInstancePtr snapInstance = ObjectInstancePtr::dynamicCast(snapEntity);
1185 std::string id = snapInstance->getId();
1186 bool ok = snapInstance->hasAttribute("classes");
1187
1188 if (!ok)
1189 {
1190 ARMARX_ERROR << "SnapInstance " << id
1191 << " has no classes attribute, could not load iv files, skipping";
1192 continue;
1193 }
1194
1195 std::string classesName = snapInstance->getAttributeValue("classes")->getString();
1196
1197 EntityBasePtr classesEntity = classesSegmentPrx->getEntityByName(classesName);
1198
1199 if (!classesEntity)
1200 {
1201 ARMARX_ERROR << "Classes Segment does not know class with name : " << classesName;
1202 continue;
1203 }
1204
1205 ObjectClassPtr objectClass = ObjectClassPtr::dynamicCast(classesEntity);
1206
1207 if (!objectClass)
1208 {
1209 ARMARX_ERROR << "Could not cast class entity : " << classesName;
1210 continue;
1211 }
1212
1213
1214 Eigen::Matrix4f m = Eigen::Matrix4f::Identity();
1215
1216 // Position
1217 FramedPositionPtr objPos = snapInstance->getPosition();
1218
1219 if (objPos)
1220 {
1221 m.block<3,1>(0, 3) = objPos->toEigen();
1222 }
1223
1224 // Orientation
1225 FramedOrientationPtr objOrient = snapInstance->getOrientation();
1226
1227 if (objOrient)
1228 {
1229 m.block<3,3>(0, 0) = objOrient->toEigen();
1230 }
1231
1232 PosePtr poseGlobal(new Pose(m));
1234 objectClass->addWrapper(new EntityWrappers::SimoxObjectWrapper(fileManager));
1235 VirtualRobot::ManipulationObjectPtr mo = sw->getManipulationObject()->clone(
1236 sw->getManipulationObject()
1237 ->getName()); // maybe not needed: cloning the object to avoid changing content of priorKnowledge
1238
1239 if (mo)
1240 {
1241 std::string instanceName = snapInstance->getName();
1242 int i = 2;
1243 while (hasObject(instanceName))
1244 {
1245 instanceName = snapInstance->getName() + "_" + to_string(i);
1246 i++;
1247 }
1248 if (instanceName != snapInstance->getName())
1249 {
1250 ARMARX_INFO << "Object instance with name '" << snapInstance->getName()
1251 << "'' already exists - using '" << instanceName << "'";
1252 }
1253 bool isStatic =
1254 mo->getSimulationType() == VirtualRobot::SceneObject::Physics::eStatic;
1255 addObject(objectClass, instanceName, poseGlobal, isStatic);
1256 }
1257 }
1258
1259 ARMARX_LOG << "Added " << c << " objects";
1260 }
1261 catch (...)
1262 {
1263 ARMARX_WARNING << "addSnapshot failed...";
1264 return false;
1265 }
1266 if (getProperty<bool>("LoadAgentsFromSnapshot").getValue())
1267 {
1268 return loadAgentsFromSnapshot(snapshotInterfacePrx);
1269 }
1270 else
1271 {
1272 return true;
1273 }
1274}
1275
1276bool
1277Simulator::loadAgentsFromSnapshot(WorkingMemorySnapshotInterfacePrx snapshotInterfacePrx)
1278{
1279 const std::string segmentName = "agentInstances";
1280 bool result = true;
1281 try
1282 {
1283 PersistentEntitySegmentBasePrx segInstances = snapshotInterfacePrx->getSegment(segmentName);
1284
1285 if (!segInstances)
1286 {
1287 ARMARX_ERROR << "Segment not found in snapshot: " << segmentName;
1288 return false;
1289 }
1290
1291 EntityIdList ids = segInstances->getAllEntityIds();
1292
1293
1294 for (EntityIdList::const_iterator it = ids.begin(); it != ids.end(); ++it)
1295 {
1296 EntityBasePtr snapEntity = segInstances->getEntityById(*it);
1297 AgentInstancePtr snapAgent = AgentInstancePtr::dynamicCast(snapEntity);
1298
1299 auto agentName = snapAgent->getName();
1300 std::string agentModelFile = snapAgent->getAgentFilePath();
1301 std::string absModelFile;
1302 if (hasRobot(agentName))
1303 {
1304 ARMARX_INFO << "Robot with name '" << agentName << "' already exists.";
1305 continue;
1306 }
1307 if (!ArmarXDataPath::getAbsolutePath(agentModelFile, absModelFile))
1308 {
1309 ARMARX_WARNING << "Could not load agent '" << agentName
1310 << "'- file not found: " << agentModelFile;
1311 result = false;
1312 continue;
1313 }
1314
1315
1316 if (addRobot(agentName, absModelFile, snapAgent->getPose()->toEigen(), agentModelFile)
1317 .empty())
1318 {
1319 result = false;
1320 }
1321 }
1322 }
1323 catch (...)
1324 {
1326 }
1327
1328 return result;
1329}
1330
1331void
1332Simulator::actuateRobotJoints(const std::string& robotName,
1333 const NameValueMap& angles,
1334 const NameValueMap& velocities,
1335 const Ice::Current&)
1336{
1337 physicsWorld->actuateRobotJoints(robotName, angles, velocities);
1338}
1339
1340void
1341Simulator::actuateRobotJointsPos(const std::string& robotName,
1342 const NameValueMap& angles,
1343 const Ice::Current&)
1344{
1345 physicsWorld->actuateRobotJointsPos(robotName, angles);
1346}
1347
1348void
1349Simulator::actuateRobotJointsVel(const std::string& robotName,
1350 const NameValueMap& velocities,
1351 const Ice::Current&)
1352{
1353 physicsWorld->actuateRobotJointsVel(robotName, velocities);
1354}
1355
1356void
1357Simulator::actuateRobotJointsTorque(const std::string& robotName,
1358 const NameValueMap& torques,
1359 const Ice::Current&)
1360{
1361 physicsWorld->actuateRobotJointsTorque(robotName, torques);
1362}
1363
1364void
1365Simulator::setRobotPose(const std::string& robotName,
1366 const PoseBasePtr& globalPose,
1367 const Ice::Current&)
1368{
1369 VirtualRobot::MathTools::Quaternion qa;
1370 qa.x = globalPose->orientation->qx;
1371 qa.y = globalPose->orientation->qy;
1372 qa.z = globalPose->orientation->qz;
1373 qa.w = globalPose->orientation->qw;
1374 Eigen::Matrix4f gp = VirtualRobot::MathTools::quat2eigen4f(qa);
1375 gp(0, 3) = globalPose->position->x;
1376 gp(1, 3) = globalPose->position->y;
1377 gp(2, 3) = globalPose->position->z;
1378 physicsWorld->setRobotPose(robotName, gp);
1379}
1380
1381void
1382Simulator::applyForceRobotNode(const std::string& robotName,
1383 const std::string& robotNodeName,
1384 const Vector3BasePtr& force,
1385 const Ice::Current&)
1386{
1387 Vector3Ptr v3p = Vector3Ptr::dynamicCast(force);
1388 physicsWorld->applyForceRobotNode(robotName, robotNodeName, v3p->toEigen());
1389}
1390
1391void
1392Simulator::applyTorqueRobotNode(const std::string& robotName,
1393 const std::string& robotNodeName,
1394 const Vector3BasePtr& torque,
1395 const Ice::Current&)
1396{
1397 Vector3Ptr v3p = Vector3Ptr::dynamicCast(torque);
1398 physicsWorld->applyTorqueRobotNode(robotName, robotNodeName, v3p->toEigen());
1399}
1400
1401void
1402Simulator::applyForceObject(const std::string& objectName,
1403 const Vector3BasePtr& force,
1404 const Ice::Current&)
1405{
1406 Vector3Ptr v3p = Vector3Ptr::dynamicCast(force);
1407 physicsWorld->applyForceObject(objectName, v3p->toEigen());
1408}
1409
1410void
1411Simulator::applyTorqueObject(const std::string& objectName,
1412 const Vector3BasePtr& torque,
1413 const Ice::Current&)
1414{
1415 Vector3Ptr v3p = Vector3Ptr::dynamicCast(torque);
1416 physicsWorld->applyTorqueObject(objectName, v3p->toEigen());
1417}
1418
1419void
1420Simulator::addObject(const memoryx::ObjectClassBasePtr& objectClassBase,
1421 const std::string& instanceName,
1422 const PoseBasePtr& globalPose,
1423 bool isStatic,
1424 const Ice::Current&)
1425{
1426 ARMARX_VERBOSE << "Add object from memory " << instanceName;
1427 if (!requestFileManager())
1428 {
1429 ARMARX_WARNING << "Cannot add object - no connection to common storage";
1430 return;
1431 }
1432 auto lockEngine = physicsWorld->getScopedEngineLock(__FUNCTION__);
1433 auto lockData = physicsWorld->getScopedSyncLock(__FUNCTION__);
1434
1435 try
1436 {
1437
1438 ObjectClassPtr objectClass = ObjectClassPtr::dynamicCast(objectClassBase);
1439
1440 if (physicsWorld->hasObject(instanceName))
1441 {
1442 ARMARX_ERROR << "Object with instance name \"" << instanceName << "\" already exists";
1443 return;
1444 }
1445
1446 if (!objectClass)
1447 {
1448 ARMARX_ERROR << "Invalid object class; could not create object with instance name "
1449 << instanceName;
1450 return;
1451 }
1452
1454 objectClass->addWrapper(new EntityWrappers::SimoxObjectWrapper(fileManager));
1455
1456 VirtualRobot::ManipulationObjectPtr mo =
1457 sw->getManipulationObject(); //->clone(sw->getManipulationObject()->getName()); // maybe not needed: cloning the object to avoid changing content of priorKnowledge
1458
1459 if (!mo)
1460 {
1461 ARMARX_ERROR << "Could not retrieve manipulation object of object class "
1462 << objectClass->getName();
1463 return;
1464 }
1465
1466 //ARMARX_INFO << "Filename mo:" << mo->getVisualization()->getFilename();
1467 //ARMARX_INFO << "Filename sw:" << sw->getManipulationObjectFileName();
1468
1469 mo->setName(instanceName);
1470
1471 ARMARX_LOG << "Adding manipulation object " << mo->getName() << " of class "
1472 << objectClass->getName();
1473 classInstanceMap[objectClass->getName()].push_back(instanceName);
1474
1475 VirtualRobot::MathTools::Quaternion qa;
1476 qa.x = globalPose->orientation->qx;
1477 qa.y = globalPose->orientation->qy;
1478 qa.z = globalPose->orientation->qz;
1479 qa.w = globalPose->orientation->qw;
1480 Eigen::Matrix4f gp = VirtualRobot::MathTools::quat2eigen4f(qa);
1481 gp(0, 3) = globalPose->position->x;
1482 gp(1, 3) = globalPose->position->y;
1483 gp(2, 3) = globalPose->position->z;
1484 mo->setGlobalPose(gp);
1485 VirtualRobot::SceneObject::Physics::SimulationType simType =
1486 (isStatic) ? VirtualRobot::SceneObject::Physics::eKinematic
1487 : VirtualRobot::SceneObject::Physics::eDynamic;
1488 physicsWorld->addObstacle(mo, simType, std::string(), objectClassBase->getName());
1489 }
1490 catch (...)
1491 {
1492 ARMARX_WARNING << "addObject failed: " << GetHandledExceptionString();
1493 }
1494}
1495
1496void
1497Simulator::addObjectFromFile(const armarx::data::PackagePath& packagePath,
1498 const std::string& instanceName,
1499 const PoseBasePtr& globalPose,
1500 bool isStatic,
1501 const Ice::Current&)
1502{
1503 ARMARX_INFO << "Add object from packagePath " << packagePath << ": " << instanceName;
1504 //if (!requestFileManager())
1505 //{
1506 // ARMARX_WARNING << "Cannot add object - no connection to common storage";
1507 // return;
1508 //}
1509 auto lockEngine = physicsWorld->getScopedEngineLock(__FUNCTION__);
1510 auto lockData = physicsWorld->getScopedSyncLock(__FUNCTION__);
1511
1512 ArmarXDataPath::FindPackageAndAddDataPath(packagePath.package);
1513 std::string filename;
1514 if (!ArmarXDataPath::SearchReadableFile(packagePath.path, filename))
1515 {
1516 ARMARX_ERROR << "Could not find file: \"" << packagePath.path << "\".";
1517 return;
1518 }
1519 // armarx::PackagePath boPackagePath(packagePath);
1520 // std::string filename = boPackagePath.toSystemPath();
1521
1522 try
1523 {
1524 if (physicsWorld->hasObject(instanceName))
1525 {
1526 ARMARX_ERROR << "Object with instance name \"" << instanceName << "\" already exists";
1527 return;
1528 }
1529
1530
1531 VirtualRobot::ManipulationObjectPtr mo =
1532 VirtualRobot::ObjectIO::loadManipulationObject(filename);
1533
1534 if (!mo)
1535 {
1536 ARMARX_ERROR << "Could not retrieve manipulation object from file " << filename;
1537 return;
1538 }
1539
1540 //ARMARX_INFO << "Filename mo:" << mo->getVisualization()->getFilename();
1541 //ARMARX_INFO << "Filename sw:" << sw->getManipulationObjectFileName();
1542
1543 mo->setName(instanceName);
1544
1545 // ARMARX_LOG << "Adding manipulation object " << mo->getName() << " of class " << objectClass->getName();
1546 // classInstanceMap[objectClass->getName()].push_back(instanceName);
1547
1548 VirtualRobot::MathTools::Quaternion qa;
1549 qa.x = globalPose->orientation->qx;
1550 qa.y = globalPose->orientation->qy;
1551 qa.z = globalPose->orientation->qz;
1552 qa.w = globalPose->orientation->qw;
1553 Eigen::Matrix4f gp = VirtualRobot::MathTools::quat2eigen4f(qa);
1554 gp(0, 3) = globalPose->position->x;
1555 gp(1, 3) = globalPose->position->y;
1556 gp(2, 3) = globalPose->position->z;
1557 mo->setGlobalPose(gp);
1558 VirtualRobot::SceneObject::Physics::SimulationType simType =
1559 (isStatic) ? VirtualRobot::SceneObject::Physics::eKinematic
1560 : VirtualRobot::SceneObject::Physics::eDynamic;
1561 physicsWorld->addObstacle(mo, simType, filename, instanceName, {}, packagePath.package);
1562 }
1563 catch (...)
1564 {
1565 ARMARX_WARNING << "addObject failed: " << GetHandledExceptionString();
1566 }
1567}
1568
1569void
1571 float height,
1572 float depth,
1573 float massKG,
1574 const DrawColor& color,
1575 const std::string& instanceName,
1576 const PoseBasePtr& globalPose,
1577 bool isStatic,
1578 const Ice::Current&)
1579{
1580 ARMARX_VERBOSE << "Add box " << instanceName;
1581
1582 auto lockEngine = physicsWorld->getScopedEngineLock(__FUNCTION__);
1583 auto lockData = physicsWorld->getScopedSyncLock(__FUNCTION__);
1584
1585 try
1586 {
1587
1588 if (physicsWorld->hasObject(instanceName))
1589 {
1590 ARMARX_ERROR << "Object with instance name \"" << instanceName << "\" already exists";
1591 return;
1592 }
1593
1594 if (depth <= 0 || width <= 0 || height <= 0)
1595 {
1596 ARMARX_ERROR << "Invalid properties; could not create object with instance name "
1597 << instanceName;
1598 return;
1599 }
1600
1601 VirtualRobot::VisualizationFactory::Color c;
1602 c.r = color.r;
1603 c.g = color.g;
1604 c.b = color.b;
1605 c.transparency = color.a;
1606 VirtualRobot::ObstaclePtr o = VirtualRobot::Obstacle::createBox(width, height, depth, c);
1607 o->setMass(massKG);
1608
1609
1610 if (!o)
1611 {
1612 ARMARX_ERROR << "Could not create box";
1613 return;
1614 }
1615
1616 o->setName(instanceName);
1617
1618 ARMARX_LOG << "Adding box object " << o->getName();
1619
1620 // not a memoryX object
1621 //classInstanceMap[objectClass->getName()].push_back(instanceName);
1622
1623 VirtualRobot::MathTools::Quaternion qa;
1624 qa.x = globalPose->orientation->qx;
1625 qa.y = globalPose->orientation->qy;
1626 qa.z = globalPose->orientation->qz;
1627 qa.w = globalPose->orientation->qw;
1628 Eigen::Matrix4f gp = VirtualRobot::MathTools::quat2eigen4f(qa);
1629 gp(0, 3) = globalPose->position->x;
1630 gp(1, 3) = globalPose->position->y;
1631 gp(2, 3) = globalPose->position->z;
1632 o->setGlobalPose(gp);
1633 VirtualRobot::SceneObject::Physics::SimulationType simType =
1634 (isStatic) ? VirtualRobot::SceneObject::Physics::eStatic
1635 : VirtualRobot::SceneObject::Physics::eDynamic;
1636
1637 BoxVisuPrimitivePtr bp(new BoxVisuPrimitive());
1638 bp->type = Box;
1639 bp->width = width;
1640 bp->height = height;
1641 bp->depth = depth;
1642 bp->massKG = massKG;
1643 bp->color = color;
1644
1645 physicsWorld->addObstacle(o, simType, std::string(), std::string(), bp);
1646 }
1647 catch (...)
1648 {
1649 ARMARX_WARNING << "addObject failed: " << GetHandledExceptionString();
1650 }
1651}
1652
1653Ice::StringSeq
1654Simulator::getRobotNames(const Ice::Current&)
1655{
1656 auto lockEngine =
1657 physicsWorld->getScopedEngineLock(__FUNCTION__); // we are accessing objects and robots
1658 auto lockData = physicsWorld->getScopedSyncLock(__FUNCTION__);
1659 return physicsWorld->getRobotNames();
1660}
1661
1662void
1663Simulator::removeObject(const std::string& instanceName, const Ice::Current&)
1664{
1665 ARMARX_VERBOSE << "Remove object " << instanceName;
1666
1667 auto lockEngine = physicsWorld->getScopedEngineLock(__FUNCTION__);
1668 auto lockData = physicsWorld->getScopedSyncLock(__FUNCTION__);
1669
1670 try
1671 {
1672 if (!physicsWorld->hasObject(instanceName))
1673 {
1674 ARMARX_ERROR << "Object with instance name \"" << instanceName << "\" does not exist";
1675 return;
1676 }
1677
1678 ARMARX_LOG << "Removing object " << instanceName;
1679
1680 if (!physicsWorld->removeObstacle(instanceName))
1681 {
1682 ARMARX_ERROR << "Could not remove object with instance name \"" << instanceName << "\"";
1683 return;
1684 }
1685 }
1686 catch (...)
1687 {
1688 ARMARX_WARNING << "removeObject failed...";
1689 }
1690}
1691
1692void
1693Simulator::setObjectPose(const std::string& objectName,
1694 const PoseBasePtr& globalPose,
1695 const Ice::Current&)
1696{
1697 VirtualRobot::MathTools::Quaternion q;
1698 q.x = globalPose->orientation->qx;
1699 q.y = globalPose->orientation->qy;
1700 q.z = globalPose->orientation->qz;
1701 q.w = globalPose->orientation->qw;
1702 Eigen::Matrix4f gp = VirtualRobot::MathTools::quat2eigen4f(q);
1703 gp(0, 3) = globalPose->position->x;
1704 gp(1, 3) = globalPose->position->y;
1705 gp(2, 3) = globalPose->position->z;
1706
1707 physicsWorld->setObjectPose(objectName, gp);
1708}
1709
1710void
1711Simulator::setObjectSimulationType(const std::string& objectName,
1712 SimulationType type,
1713 const Ice::Current&)
1714{
1715 VirtualRobot::SceneObject::Physics::SimulationType st =
1716 VirtualRobot::SceneObject::Physics::eDynamic;
1717 if (type == armarx::Kinematic)
1718 {
1719 st = VirtualRobot::SceneObject::Physics::eKinematic;
1720 }
1721 ARMARX_DEBUG << "setting simulation type of " << objectName << " to " << st;
1722 physicsWorld->setObjectSimType(objectName, st);
1723}
1724
1725void
1726Simulator::activateObject(const std::string& objectName, const Ice::Current&)
1727{
1728 physicsWorld->activateObject(objectName);
1729}
1730
1731int
1733{
1734 return physicsWorld->getFixedTimeStepMS();
1735}
1736
1737float
1738Simulator::getRobotMass(const std::string& robotName, const Ice::Current&)
1739{
1740 return physicsWorld->getRobotMass(robotName);
1741}
1742
1743NameValueMap
1744Simulator::getRobotJointAngles(const std::string& robotName, const Ice::Current&)
1745{
1746 return physicsWorld->getRobotJointAngles(robotName);
1747}
1748
1749float
1750Simulator::getRobotJointAngle(const std::string& robotName,
1751 const std::string& nodeName,
1752 const Ice::Current&)
1753{
1754 return physicsWorld->getRobotJointAngle(robotName, nodeName);
1755}
1756
1757NameValueMap
1758Simulator::getRobotJointVelocities(const std::string& robotName, const Ice::Current&)
1759{
1760 return physicsWorld->getRobotJointVelocities(robotName);
1761}
1762
1763float
1764Simulator::getRobotJointVelocity(const std::string& robotName,
1765 const std::string& nodeName,
1766 const Ice::Current&)
1767{
1768 return physicsWorld->getRobotJointVelocity(robotName, nodeName);
1769}
1770
1771NameValueMap
1772Simulator::getRobotJointTorques(const std::string& robotName, const Ice::Current&)
1773{
1774 return physicsWorld->getRobotJointTorques(robotName);
1775}
1776
1777ForceTorqueDataSeq
1778Simulator::getRobotForceTorqueSensors(const std::string& robotName, const Ice::Current&)
1779{
1780 return physicsWorld->getRobotForceTorqueSensors(robotName);
1781}
1782
1783float
1784Simulator::getRobotJointLimitLo(const std::string& robotName,
1785 const std::string& nodeName,
1786 const Ice::Current&)
1787{
1788 return physicsWorld->getRobotJointLimitLo(robotName, nodeName);
1789}
1790
1791float
1792Simulator::getRobotJointLimitHi(const std::string& robotName,
1793 const std::string& nodeName,
1794 const Ice::Current&)
1795{
1796 return physicsWorld->getRobotJointLimitHi(robotName, nodeName);
1797}
1798
1799PoseBasePtr
1800Simulator::getRobotPose(const std::string& robotName, const Ice::Current&)
1801{
1802 PosePtr p(new Pose(physicsWorld->getRobotPose(robotName)));
1803 return p;
1804}
1805
1806float
1807Simulator::getRobotMaxTorque(const std::string& robotName,
1808 const std::string& nodeName,
1809 const Ice::Current&)
1810{
1811 return physicsWorld->getRobotMaxTorque(robotName, nodeName);
1812}
1813
1814void
1815Simulator::setRobotMaxTorque(const std::string& robotName,
1816 const std::string& nodeName,
1817 float maxTorque,
1818 const Ice::Current&)
1819{
1820 physicsWorld->setRobotMaxTorque(robotName, nodeName, maxTorque);
1821}
1822
1823PoseBasePtr
1824Simulator::getRobotNodePose(const std::string& robotName,
1825 const std::string& robotNodeName,
1826 const Ice::Current&)
1827{
1828 PosePtr p(new Pose(physicsWorld->getRobotNodePose(robotName, robotNodeName)));
1829 return p;
1830}
1831
1832Vector3BasePtr
1833Simulator::getRobotLinearVelocity(const std::string& robotName,
1834 const std::string& nodeName,
1835 const Ice::Current&)
1836{
1837 Vector3Ptr v(new Vector3(physicsWorld->getRobotLinearVelocity(robotName, nodeName)));
1838 return v;
1839}
1840
1841Vector3BasePtr
1842Simulator::getRobotAngularVelocity(const std::string& robotName,
1843 const std::string& nodeName,
1844 const Ice::Current&)
1845{
1846 Vector3Ptr v(new Vector3(physicsWorld->getRobotAngularVelocity(robotName, nodeName)));
1847 return v;
1848}
1849
1850void
1851Simulator::setRobotLinearVelocity(const std::string& robotName,
1852 const std::string& robotNodeName,
1853 const Vector3BasePtr& vel,
1854 const Ice::Current&)
1855{
1856 Eigen::Vector3f newVel = Vector3Ptr::dynamicCast(vel)->toEigen();
1857 physicsWorld->setRobotLinearVelocity(robotName, robotNodeName, newVel);
1858}
1859
1860void
1861Simulator::setRobotAngularVelocity(const std::string& robotName,
1862 const std::string& robotNodeName,
1863 const Vector3BasePtr& vel,
1864 const Ice::Current&)
1865{
1866 Vector3Ptr newVel = Vector3Ptr::dynamicCast(vel);
1867 physicsWorld->setRobotAngularVelocity(robotName, robotNodeName, newVel->toEigen());
1868}
1869
1870void
1872 const std::string& robotNodeName,
1873 const Vector3BasePtr& vel,
1874 const Ice::Current&)
1875{
1876 Eigen::Vector3f newVel = Vector3Ptr::dynamicCast(vel)->toEigen();
1877 physicsWorld->setRobotLinearVelocityRobotRootFrame(robotName, robotNodeName, newVel);
1878}
1879
1880void
1882 const std::string& robotNodeName,
1883 const Vector3BasePtr& vel,
1884 const Ice::Current&)
1885{
1886 Eigen::Vector3f newVel = Vector3Ptr::dynamicCast(vel)->toEigen();
1887 physicsWorld->setRobotAngularVelocityRobotRootFrame(robotName, robotNodeName, newVel);
1888}
1889
1890bool
1891Simulator::hasRobot(const std::string& robotName, const Ice::Current&)
1892{
1893 return physicsWorld->hasRobot(robotName);
1894}
1895
1896bool
1897Simulator::hasRobotNode(const std::string& robotName,
1898 const std::string& robotNodeName,
1899 const Ice::Current&)
1900{
1901
1902 return physicsWorld->hasRobotNode(robotName, robotNodeName);
1903}
1904
1905PoseBasePtr
1906Simulator::getObjectPose(const std::string& objectName, const Ice::Current&)
1907{
1908 PosePtr p(new Pose(physicsWorld->getObjectPose(objectName)));
1909 return p;
1910}
1911
1912void
1913Simulator::objectReleased(const std::string& robotName,
1914 const std::string& robotNodeName,
1915 const std::string& objectName,
1916 const Ice::Current&)
1917{
1918 ARMARX_VERBOSE << "Object released " << robotName << "," << objectName;
1919 physicsWorld->objectReleased(robotName, robotNodeName, objectName);
1920}
1921
1922void
1923Simulator::objectGrasped(const std::string& robotName,
1924 const std::string& robotNodeName,
1925 const std::string& objectName,
1926 const Ice::Current&)
1927{
1928 ARMARX_VERBOSE << "Object grasped" << robotName << "," << objectName;
1929 physicsWorld->objectGrasped(robotName, robotNodeName, objectName);
1930}
1931
1932float
1933Simulator::getSimTime(const Ice::Current&)
1934{
1935 return static_cast<float>(physicsWorld->getCurrentSimTime());
1936}
1937
1938SceneVisuData
1939Simulator::getScene(const Ice::Current&)
1940{
1941 SceneVisuData res = physicsWorld->copySceneVisuData();
1942 res.priorKnowledgeName = priorKnowledgeName;
1943 res.commonStorageName = commonStorageName;
1944 return res;
1945}
1946
1947SimulatorInformation
1949{
1950 auto lockEngine =
1951 physicsWorld->getScopedEngineLock(__FUNCTION__); // we are accessing objects and robots
1952 auto lockData = physicsWorld->getScopedSyncLock(__FUNCTION__);
1953 SimulatorInformation res;
1954 res.comTimeMS = currentComTimeMS;
1955 // res.simTimeStepMeasuredMS = currentSimTimeMS; <-- this is wrong?!
1956 res.syncEngineTimeMS = currentSyncTimeMS;
1957
1958 std::vector<std::string> robNames = physicsWorld->getRobotNames();
1959 res.nrRobots = static_cast<int>(robNames.size());
1960
1961 res.nrActuatedJoints = physicsWorld->getRobotJointAngleCount();
1962 res.nrObjects = physicsWorld->getObjectCount();
1963 res.nrContacts = physicsWorld->getContactCount();
1964 res.currentSimulatorTimeSec = getSimTime();
1965 res.simTimeStepMeasuredMS = physicsWorld->getSimulationStepTimeMeasured();
1966 res.simTimeStepDurationMS = physicsWorld->getSimulationStepDuration();
1967
1968 res.simTimeFactor = 0;
1969 if (res.simTimeStepMeasuredMS > 0)
1970 {
1971 res.simTimeFactor = res.simTimeStepDurationMS / res.simTimeStepMeasuredMS;
1972 }
1973
1974 std::vector<VirtualRobot::SceneObjectPtr> objects = physicsWorld->getObjects();
1975
1976 for (VirtualRobot::SceneObjectPtr& o : objects)
1977 {
1978 //ARMARX_INFO << "Object " << o->getName() << ", pose:" << o->getSceneObject()->getGlobalPose();
1979 ObjectVisuData ovd;
1980 ovd.name = o->getName();
1981 PosePtr p(new Pose(o->getGlobalPose()));
1982 ovd.objectPoses[ovd.name] = p;
1983 VirtualRobot::Obstacle* ob = dynamic_cast<VirtualRobot::Obstacle*>(o.get());
1984
1985 if (ob)
1986 {
1987 ovd.filename = ob->getFilename();
1988 }
1989
1990 if (o->getSimulationType() == VirtualRobot::SceneObject::Physics::eStatic)
1991 {
1992 ovd.staticObject = true;
1993 }
1994 else
1995 {
1996 ovd.staticObject = false;
1997 }
1998
1999 res.objects.push_back(ovd);
2000 }
2001
2002 for (auto& r : robNames)
2003 {
2004 RobotVisuData ovd;
2005 ovd.name = r;
2006 VirtualRobot::RobotPtr rob = physicsWorld->getRobot(r);
2007 if (rob)
2008 {
2009 PosePtr p(new Pose(rob->getGlobalPose()));
2010 ovd.pose = p;
2011 ovd.robotFile = rob->getFilename();
2012 }
2013
2014 res.robots.push_back(ovd);
2015 }
2016
2017 return res;
2018}
2019
2020std::string
2021Simulator::addRobotFromFile(const armarx::data::PackagePath& packagePath, const Ice::Current& c)
2022{
2023 ArmarXDataPath::FindPackageAndAddDataPath(packagePath.package);
2024
2025 // legacy
2026 {
2027 std::string filename;
2028 if (ArmarXDataPath::SearchReadableFile(packagePath.path, filename))
2029 {
2030 return addRobot(filename);
2031 }
2032 }
2033
2034 const PackagePath pp(packagePath);
2035 if (std::filesystem::exists(pp.toSystemPath()))
2036 {
2037 return addRobot(pp.toSystemPath());
2038 }
2039
2040 ARMARX_ERROR << "Could not find file: \"" << packagePath.path << "\".";
2041 return "";
2042}
2043
2044std::string
2045Simulator::addRobot(std::string robotInstanceName,
2046 const std::string& robFileGlobal,
2047 Eigen::Matrix4f gp,
2048 const std::string& robFile,
2049 double pid_p,
2050 double pid_i,
2051 double pid_d,
2052 bool isStatic,
2053 float scaling,
2054 bool colModel,
2055 std::map<std::string, float> initConfig,
2056 bool selfCollisions)
2057{
2058 ARMARX_DEBUG << "Add robot from file " << robFileGlobal;
2059 auto lockEngine = physicsWorld->getScopedEngineLock(__FUNCTION__);
2060 auto lockData = physicsWorld->getScopedSyncLock(__FUNCTION__);
2061
2062 if (physicsWorld->addRobot(robotInstanceName,
2063 robFileGlobal,
2064 gp,
2065 robFile,
2066 pid_p,
2067 pid_i,
2068 pid_d,
2069 isStatic,
2070 scaling,
2071 colModel,
2072 initConfig,
2073 selfCollisions))
2074 {
2075 // update report topics
2076 if (!updateRobotTopics())
2077 {
2078 ARMARX_ERROR << "topic setup failed";
2079 }
2080 }
2081 else
2082 {
2083 ARMARX_WARNING << "addRobot failed";
2084 return "";
2085 }
2086
2087 return robotInstanceName;
2088}
2089
2090bool
2092{
2093 SimulatedWorldData& syncData = physicsWorld->getReportData();
2094
2095 try
2096 {
2097 for (auto& rob : syncData.robots)
2098 {
2099 // offer robot
2100 std::string top = rob.robotTopicName;
2101 ARMARX_INFO << "Offering topic " << top;
2102 offeringTopic(top);
2103 //if (this->getState() == eManagedIceObjectStarted)
2104 {
2105 ARMARX_INFO << "Connecting to topic " << top;
2106 rob.simulatorRobotListenerPrx = getTopic<SimulatorRobotListenerInterfacePrx>(top);
2107 }
2108
2109 for (auto& fti : rob.forceTorqueSensors)
2110 {
2111 ARMARX_INFO << "Offering topic " << fti.topicName;
2112 offeringTopic(fti.topicName);
2113
2114 //if (this->getState() == eManagedIceObjectStarted)
2115 {
2116 ARMARX_INFO << "Connecting to topic " << fti.topicName;
2118 }
2119 }
2120 }
2121 }
2122 catch (...)
2123 {
2124 ARMARX_WARNING << "failed: exception";
2125 return false;
2126 }
2127
2128 return true;
2129}
2130
2131void
2133{
2134 step();
2135}
2136
2137ObjectClassInformationSequence
2138Simulator::getObjectClassPoses(const std::string& robotName,
2139 const std::string& frameName,
2140 const std::string& className,
2141 const Ice::Current&)
2142{
2143 auto lockEngine = physicsWorld->getScopedEngineLock(__FUNCTION__);
2144 auto lockData = physicsWorld->getScopedSyncLock(__FUNCTION__);
2145
2146 ARMARX_DEBUG << "get object class poses";
2147
2148 ObjectClassInformationSequence result;
2149 std::vector<std::string> objects = classInstanceMap[className];
2150
2151 for (const auto& object : objects)
2152 {
2153 ObjectClassInformation inf;
2154 // Conversion from seconds to microseconds is 10^6 = 1.0e6 != 10e6 = 1.0e7!!!
2155 inf.timestampMicroSeconds =
2156 static_cast<Ice::Long>(physicsWorld->getCurrentSimTime() * 1.0e6);
2157 inf.className = className;
2158 inf.manipulationObjectName = object;
2159 Eigen::Matrix4f worldPose = physicsWorld->getObjectPose(object);
2160
2161 if (frameName == armarx::GlobalFrame)
2162 {
2163 inf.pose = new FramedPose(worldPose, armarx::GlobalFrame, "");
2164 }
2165 else
2166 {
2167 inf.pose = physicsWorld->toFramedPose(worldPose, robotName, frameName);
2168 }
2169
2170 result.push_back(inf);
2171 }
2172
2173 return result;
2174}
2175
2176DistanceInfo
2177Simulator::getDistance(const std::string& robotName,
2178 const std::string& robotNodeName,
2179 const std::string& worldObjectName,
2180 const Ice::Current&)
2181{
2182 return physicsWorld->getDistance(robotName, robotNodeName, worldObjectName);
2183}
2184
2185DistanceInfo
2186Simulator::getRobotNodeDistance(const std::string& robotName,
2187 const std::string& robotNodeName1,
2188 const std::string& robotNodeName2,
2189 const Ice::Current&)
2190{
2191 return physicsWorld->getRobotNodeDistance(robotName, robotNodeName1, robotNodeName2);
2192}
2193
2194void
2195Simulator::showContacts(bool enable, const std::string& layerName, const Ice::Current&)
2196{
2197 auto lockData = physicsWorld->getScopedSyncLock(__FUNCTION__);
2198 ARMARX_INFO << "showcontacts:" << enable;
2199 publishContacts = enable;
2200 physicsWorld->updateContacts(enable);
2201
2202 if (enable)
2203 {
2204 contactLayerName = layerName;
2205 }
2206 else
2207 {
2209
2210 try
2211 {
2212 entityDrawerPrx->clearLayer(layerName);
2213 entityDrawerPrx->removeLayer(layerName);
2214 }
2215 catch (...)
2216 {
2217 }
2218 }
2219}
2220
2221void
2222Simulator::reInitialize(const Ice::Current&)
2223{
2224 resetData(true);
2225
2227 simulatorResetEventTopic->simulatorWasReset();
2228}
2229
2230bool
2231Simulator::hasObject(const std::string& instanceName, const Ice::Current&)
2232{
2233 return physicsWorld->hasObject(instanceName);
2234}
2235
2236void
2237Simulator::start(const Ice::Current&)
2238{
2240 bool notify = !simulatorThreadRunning && this->isAlive();
2242
2243 if (notify)
2244 {
2245 condSimulatorThreadRunning.notify_all();
2246 }
2247
2248 if (!isAlive())
2249 {
2250 Thread::start();
2251 }
2252}
2253
2254void
2256{
2257 IceUtil::Time startTime;
2258 int sleepTimeMS;
2259 int loopTimeMS = physicsWorld->getFixedTimeStepMS();
2260
2261 std::unique_lock lock(simulatorRunningMutex);
2262
2264 {
2265 while (!simulatorThreadRunning)
2266 {
2267 condSimulatorThreadRunning.wait(lock);
2268 }
2269
2271 {
2272 startTime = IceUtil::Time::now();
2273 step();
2274 sleepTimeMS = static_cast<int>(
2275 loopTimeMS * (1 / timeServerSpeed) -
2276 static_cast<float>((IceUtil::Time::now() - startTime).toMilliSeconds()));
2277
2278 if (sleepTimeMS < 0)
2279 {
2280 ARMARX_DEBUG << deactivateSpam(5) << "Simulation step took " << -sleepTimeMS
2281 << " milliseconds too long!";
2282 }
2283 else
2284 {
2285 usleep(static_cast<unsigned int>(sleepTimeMS * 1000)); //TODO: check for EINTR?
2286 }
2287 }
2288 }
2289 ARMARX_VERBOSE << "Exiting Simulator::run()";
2290}
2291
2292void
2293Simulator::pause(const Ice::Current&)
2294{
2295 simulatorThreadRunning = false;
2296}
2297
2298void
2299Simulator::stop(const Ice::Current& c)
2300{
2301 pause(c);
2302}
2303
2304void
2305Simulator::setSpeed(Ice::Float newSpeed, const Ice::Current&)
2306{
2307 timeServerSpeed = static_cast<float>(newSpeed);
2308}
2309
2310Ice::Float
2311Simulator::getSpeed(const Ice::Current&)
2312{
2313 return Ice::Float(timeServerSpeed);
2314}
2315
2316Ice::Int
2317Simulator::getStepTimeMS(const ::Ice::Current&)
2318{
2319 return physicsWorld->getFixedTimeStepMS();
2320}
2321
2322Ice::Long
2323Simulator::getTime(const Ice::Current&)
2324{
2325 return static_cast<long>(physicsWorld->getCurrentSimTime() * 1000);
2326}
2327
2328void
2329Simulator::step(const Ice::Current&)
2330{
2331 IceUtil::Time startTime = IceUtil::Time::now();
2332
2333 if (getProperty<bool>("RealTimeMode"))
2334 {
2335 physicsWorld->stepPhysicsRealTime();
2336 }
2337 else
2338 {
2339 physicsWorld->stepPhysicsFixedTimeStep();
2340 }
2341
2342 IceUtil::Time durationSim = IceUtil::Time::now() - startTime;
2343
2344 if (durationSim.toMilliSecondsDouble() > MAX_SIM_TIME_WARNING)
2345 {
2346 ARMARX_INFO << deactivateSpam(5) << "*** Simulation slow !! Simulation time in ms:"
2347 << durationSim.toMilliSecondsDouble();
2348 }
2349
2350 ARMARX_DEBUG << "*** Step Physics, MS:" << durationSim.toMilliSecondsDouble();
2351
2352 startTime = IceUtil::Time::now();
2353 // copy bullet content to data objects
2354 physicsWorld->synchronizeSimulationData();
2355 IceUtil::Time durationSync = IceUtil::Time::now() - startTime;
2356
2357 {
2358 auto lockData = physicsWorld->getScopedSyncLock(__FUNCTION__);
2359 currentSimTimeMS = static_cast<float>(durationSim.toMilliSecondsDouble());
2360 currentSyncTimeMS = static_cast<float>(durationSync.toMilliSecondsDouble());
2361 }
2362 timeTopicPrx->reportTime(getTime());
2363}
2364
2365bool
2366Simulator::isRunning(const Ice::Current&)
2367{
2369}
2370
2371void
2373{
2374 ARMARX_DEBUG << "report visu updates";
2375
2376 try
2377 {
2378 IceUtil::Time startTime = IceUtil::Time::now();
2379
2380 SceneVisuData reportData = physicsWorld->copySceneVisuData();
2381 reportData.priorKnowledgeName = priorKnowledgeName;
2382 reportData.commonStorageName = commonStorageName;
2383
2385 {
2386 simulatorVisuUpdateListenerPrx->begin_reportSceneUpdated(reportData);
2387 }
2388 else
2389 {
2390 ARMARX_ERROR << deactivateSpam() << "No visu update proxy to send data (so far)";
2391 }
2392
2393 {
2394 //lock both here!
2395 //otherwise we have the lock order sync->engine which causes a deadlock!
2396 const auto lockEngine = physicsWorld->getScopedEngineLock(__FUNCTION__);
2397 const auto lockSync = physicsWorld->getScopedSyncLock(__FUNCTION__);
2398
2400 {
2401 //entityDrawerPrx->clearLayer(contactLayerName);
2402 std::vector<SimDynamics::DynamicsEngine::DynamicsContactInfo> contacts =
2403 physicsWorld->copyContacts();
2404 VirtualRobot::ColorMap cm(VirtualRobot::ColorMap::eHot);
2405 float maxImpulse = 2.0f;
2406 float arrowLength = 50.0f;
2407 int i = 0;
2408 DrawColor dc;
2409
2410 for (auto& c : contacts)
2411 {
2412 std::stringstream ss;
2413 ss << "Contact_" << i;
2414 /*if (c.objectA)
2415 ss << "_" << c.objectA->getName();
2416 if (c.objectB)
2417 ss << "_" << c.objectB->getName();*/
2418 std::string name = ss.str();
2419 std::string name2 = name + "_2";
2420 std::string objA;
2421
2422 if (!c.objectAName.empty())
2423 {
2424 objA = c.objectAName; //->getName();
2425 }
2426 else
2427 {
2428 objA = "<unknown>";
2429 }
2430
2431 std::string objB;
2432
2433 if (!c.objectBName.empty())
2434 {
2435 objB = c.objectBName; //->getName();
2436 }
2437 else
2438 {
2439 objB = "<unknown>";
2440 }
2441
2442 ARMARX_DEBUG << "CONTACT " << name << ", objects: " << objA << "-" << objB
2443 << ", impulse:" << c.appliedImpulse;
2444 float intensity = static_cast<float>(c.appliedImpulse);
2445
2446 if (intensity > maxImpulse)
2447 {
2448 intensity = maxImpulse;
2449 }
2450
2451 intensity /= maxImpulse;
2452 VirtualRobot::VisualizationFactory::Color colSimox = cm.getColor(intensity);
2453 dc.r = colSimox.r;
2454 dc.g = colSimox.g;
2455 dc.b = colSimox.b;
2456 dc.a = 1.0f;
2457 //Eigen::Vector3f posEndB = c.posGlobalB + c.normalGlobalB.normalized() * arrowLength;
2458 Vector3Ptr p1(new Vector3(c.posGlobalA));
2459 Eigen::Vector3f dir2 = -(c.normalGlobalB);
2460 Vector3Ptr d1(new Vector3(dir2));
2461 Vector3Ptr p2(new Vector3(c.posGlobalB));
2462 Vector3Ptr d2(new Vector3(c.normalGlobalB));
2463
2464 entityDrawerPrx->setArrowVisu(
2465 contactLayerName, name, p1, d1, dc, arrowLength, 5.0f);
2466 entityDrawerPrx->setArrowVisu(
2467 contactLayerName, name2, p2, d2, dc, arrowLength, 5.0f);
2468 i++;
2469 }
2470
2471 // remove old contacts
2472 for (int j = i; j < lastPublishedContacts; j++)
2473 {
2474 std::stringstream ss;
2475 ss << "Contact_" << j;
2476 std::string name = ss.str();
2477 std::string name2 = name + "_2";
2478 entityDrawerPrx->removeArrowVisu(contactLayerName, name);
2479 entityDrawerPrx->removeArrowVisu(contactLayerName, name2);
2480 }
2481
2483 }
2484
2485 if (getProperty<bool>("DrawCoMVisu"))
2486 {
2487 for (auto name : physicsWorld->getRobotNames())
2488 {
2489 auto pos = new Vector3(physicsWorld->getRobot(name)->getCoMGlobal());
2490 pos->z = 0.0f;
2491 entityDrawerPrx->setSphereVisu(
2492 "CoM", "GlobalCoM_" + name, pos, DrawColor{0.f, 0.f, 1.f, 0.5f}, 20);
2493 }
2494 }
2495 }
2496 IceUtil::Time duration = IceUtil::Time::now() - startTime;
2497 reportVisuTimeMS = static_cast<float>(duration.toMilliSecondsDouble());
2498 }
2499 catch (...)
2500 {
2501 ARMARX_WARNING << "report updates failed";
2503 return;
2504 }
2505
2506 ARMARX_DEBUG << "report visu updates done, time (ms):" << reportVisuTimeMS;
2507 if (reportVisuTimeMS > 5)
2508 {
2510 << "report visu updates took long, time (ms):" << reportVisuTimeMS;
2511 }
2512}
2513
2514void
2516{
2517 ARMARX_DEBUG_S << "report data updates";
2518
2519 try
2520 {
2521 IceUtil::Time startTime = IceUtil::Time::now();
2522
2523 SimulatedWorldData reportData = physicsWorld->copyReportData();
2524
2525 for (RobotInfo& r : reportData.robots)
2526 {
2527 SimulatedRobotState state = stateFromRobotInfo(r, reportData.timestamp);
2528
2529 if (reportRobotPose)
2530 {
2531 Ice::Context ctx;
2532 ctx["origin"] = "simulation";
2533
2534 FrameHeader header;
2535 header.parentFrame = GlobalFrame;
2536 header.frame = physicsWorld->getRobot(r.robotName)->getRootNode()->getName();
2537 header.agent = r.robotName;
2538 header.timestampInMicroSeconds = reportData.timestamp.toMicroSeconds();
2539
2540 TransformStamped globalRobotPose;
2541 globalRobotPose.header = header;
2542 globalRobotPose.transform = r.pose;
2543
2545 {
2546 globalRobotLocalization->reportGlobalRobotPose(globalRobotPose, ctx);
2547 }
2548 }
2549
2551 {
2552 r.simulatorRobotListenerPrx->reportState(state);
2553 }
2554 }
2555
2556 // report world objects
2557 // todo...
2558
2559 IceUtil::Time duration = IceUtil::Time::now() - startTime;
2560 currentComTimeMS = static_cast<float>(duration.toMilliSecondsDouble());
2561 }
2562 catch (...)
2563 {
2564 ARMARX_WARNING_S << "report updates failed";
2566 return;
2567 }
2568
2569 ARMARX_DEBUG_S << "report data updates done, time (ms):" << currentComTimeMS;
2570}
2571
2572ContactInfoSequence
2573Simulator::getContacts(const Ice::Current&)
2574{
2575 ContactInfoSequence result;
2576 auto contacts = this->physicsWorld->copyContacts();
2577 for (auto& contact : contacts)
2578 {
2579 ContactInformation contactInfo;
2580 contactInfo.objectNameA = contact.objectAName;
2581 contactInfo.objectNameB = contact.objectBName;
2582 contactInfo.posGlobalA = new Vector3(contact.posGlobalA);
2583 contactInfo.posGlobalB = new Vector3(contact.posGlobalB);
2584 result.push_back(contactInfo);
2585 }
2586 return result;
2587}
2588
2589void
2590Simulator::updateContacts(bool enable, const Ice::Current&)
2591{
2592 this->physicsWorld->updateContacts(enable);
2593}
2594
2595std::string
2596Simulator::addScaledRobot(const std::string& filename, float scaling, const Ice::Current&)
2597{
2599 std::string instanceName;
2600 this->physicsWorld->addRobot(
2601 instanceName, filename, Eigen::Matrix4f::Identity(), "", 10.0, 0, 0, false, scaling);
2602 return instanceName;
2603}
2604
2605std::string
2606Simulator::addScaledRobotName(const std::string& instanceName,
2607 const std::string& filename,
2608 float scaling,
2609 const Ice::Current&)
2610{
2612 std::string name = instanceName;
2613 this->physicsWorld->addRobot(
2614 name, filename, Eigen::Matrix4f::Identity(), "", 10.0, 0, 0, false, scaling);
2615 return name;
2616}
2617
2618bool
2619Simulator::removeRobot(const std::string& robotName, const Ice::Current&)
2620{
2621 return this->physicsWorld->removeRobot(robotName);
2622}
2623
2624std::string
2625Simulator::addRobot(const std::string& filename, const Ice::Current&)
2626{
2628 std::string instanceName;
2629 this->physicsWorld->addRobot(
2630 instanceName, filename, Eigen::Matrix4f::Identity(), "", 10.0, 0, 0, false, 1.0f);
2631 return instanceName;
2632}
2633
2634SimulatedRobotState
2635armarx::Simulator::getRobotState(const std::string& robotName, const Ice::Current&)
2636{
2637 SimulatedWorldData report = physicsWorld->getReportData();
2638 for (auto& robot : report.robots)
2639 {
2640 if (robot.robotName == robotName)
2641 {
2642 return stateFromRobotInfo(robot, report.timestamp);
2643 }
2644 }
2645
2646 return SimulatedRobotState();
2647}
std::string timestamp()
uint8_t index
#define ARMARX_CHECK_NOT_EMPTY(c)
#define MAX_SIM_TIME_WARNING
#define MAX_INITIAL_ROBOT_COUNT
Definition Simulator.h:61
#define QUOTED(x)
constexpr T c
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
static bool SearchReadableFile(const std::string &querryFileName, std::string &resultFileName, bool verbose=true)
static bool FindPackageAndAddDataPath(const std::string &packageName)
Search for the package and add its data path if it was found.
The BulletPhysicsWorld class encapsulates the whole physics simulation and the corresponding data.
ComponentPropertyDefinitions(std::string prefix, bool hasObjectNameParameter=true)
Definition Component.cpp:46
Component()
Protected default constructor. Used for virtual inheritance. Use createManagedIceObject() instead.
Definition Component.cpp:66
Property< PropertyType > getProperty(const std::string &name)
The FramedPose class.
Definition FramedPose.h:281
The KinematicsWorld class encapsulates the kinemtics simulation and the corresponding data....
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition Logging.cpp:99
void offeringTopic(const std::string &name)
Registers a topic for retrival after initialization.
TopicProxyType getTopic(const std::string &name)
Returns a proxy of the specified topic.
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
The MujocoPhysicsWorld class encapsulates the whole physics simulation and the corresponding data.
Used to find objects in the ArmarX objects repository [1] (formerly [2]).
static ObjectID FromString(const std::string &idString)
Construct from a string produced by str(), e.g. ("mydataset/myobject", "mydataset/myclass/myinstance"...
Definition ObjectID.cpp:34
ObjectID withInstanceName(const std::string &instanceName) const
Definition ObjectID.cpp:83
ObjectID getClassID() const
Return just the class ID without an intance name.
Definition ObjectID.cpp:71
std::string str() const
Return "dataset/className" or "dataset/className/instanceName".
Definition ObjectID.cpp:60
static std::filesystem::path toSystemPath(const data::PackagePath &pp)
The periodic task executes one thread method repeatedly using the time period specified in the constr...
The Pose class.
Definition Pose.h:243
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
PropertyDefinition< PropertyType > & defineOptionalProperty(const std::string &name, PropertyType defaultValue, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
Property< PropertyType > getProperty(const std::string &name)
Property creation and retrieval.
The SimulatedWorldData class This data is queried by the simulated in order to offer it via topics.
EIGEN_MAKE_ALIGNED_OPERATOR_NEW std::vector< RobotInfo > robots
SimulatorPropertyDefinitions(std::string prefix)
Definition Simulator.cpp:75
The SimulatorTimeServerProxy class forwards TimeserverInterface calls to the simulator This is a hack...
std::mutex simulatorRunningMutex
Definition Simulator.h:447
memoryx::LongtermMemoryInterfacePrx longtermMemoryPrx
Definition Simulator.h:476
void applyForceObject(const std::string &objectName, const Vector3BasePtr &force, const Ice::Current &c=Ice::emptyCurrent) override
void setRobotLinearVelocity(const std::string &robotName, const std::string &robotNodeName, const Vector3BasePtr &vel, const Ice::Current &c=Ice::emptyCurrent) override
std::string addScaledRobot(const std::string &filename, float scale, const Ice::Current &c=Ice::emptyCurrent) override
void onInitComponent() override
Pure virtual hook for the subclass.
memoryx::WorkingMemoryInterfacePrx memoryPrx
Definition Simulator.h:474
void setObjectSimulationType(const std::string &objectName, armarx::SimulationType type, const Ice::Current &c=Ice::emptyCurrent) override
SimulatorTimeServerProxyPtr timeserverProxy
Proxy object to offer the Timeserver proxy.
Definition Simulator.h:498
Ice::Long getTime(const Ice::Current &c=Ice::emptyCurrent) override
void showContacts(bool enable, const std::string &layerName, const Ice::Current &c=Ice::emptyCurrent) override
Vector3BasePtr getRobotAngularVelocity(const std::string &robotName, const std::string &nodeName, const Ice::Current &c=Ice::emptyCurrent) override
void start(const Ice::Current &c=Ice::emptyCurrent) override
void addBox(float width, float height, float depth, float massKG, const DrawColor &color, const std::string &instanceName, const PoseBasePtr &globalPose, bool isStatic=false, const Ice::Current &c=Ice::emptyCurrent) override
float getRobotJointAngle(const std::string &robotName, const std::string &nodeName, const Ice::Current &c=Ice::emptyCurrent) override
void actuateRobotJointsTorque(const std::string &robotName, const NameValueMap &torques, const Ice::Current &c=Ice::emptyCurrent) override
~Simulator() override
SimulatorInformation getSimulatorInformation(const ::Ice::Current &=Ice::emptyCurrent) override
void resetData(bool clearWorkingMemory=false)
resetData Clears all data
bool hasRobotNode(const std::string &robotName, const std::string &robotNodeName, const Ice::Current &c=Ice::emptyCurrent) override
PoseBasePtr getRobotPose(const std::string &robotName, const Ice::Current &c=Ice::emptyCurrent) override
ContactInfoSequence getContacts(const Ice::Current &c=Ice::emptyCurrent) override
Returns a list of all contacts. Note that you must call updateContacts() first to enable contacts han...
Ice::Int getStepTimeMS(const ::Ice::Current &=Ice::emptyCurrent) override
void shutdownSimulationLoop()
stop the simulation and join the simulation thread
GlobalRobotPoseLocalizationListenerPrx globalRobotLocalization
Definition Simulator.h:465
void onDisconnectComponent() override
Hook for subclass.
SimulatorResetEventPrx simulatorResetEventTopic
Definition Simulator.h:499
void applyTorqueRobotNode(const std::string &robotName, const std::string &robotNodeName, const Vector3BasePtr &torque, const Ice::Current &c=Ice::emptyCurrent) override
float timeServerSpeed
Scaling factor for the passing of time.
Definition Simulator.h:461
PoseBasePtr getObjectPose(const std::string &objectName, const Ice::Current &c=Ice::emptyCurrent) override
void reInitialize(const Ice::Current &c=Ice::emptyCurrent) override
reInitialize Re-initializes the scene. Removes all robots and objects (and, in case the scene was loa...
float currentComTimeMS
Stores the time that was needed for communictaion.
Definition Simulator.h:454
void applyForceRobotNode(const std::string &robotName, const std::string &robotNodeName, const Vector3BasePtr &force, const Ice::Current &c=Ice::emptyCurrent) override
float getRobotJointVelocity(const std::string &robotName, const std::string &nodeName, const Ice::Current &c=Ice::emptyCurrent) override
void addObjectFromFile(const armarx::data::PackagePath &packagePath, const std::string &instanceName, const PoseBasePtr &globalPose, bool isStatic=false, const Ice::Current &c=Ice::emptyCurrent) override
NameValueMap getRobotJointAngles(const std::string &robotName, const Ice::Current &c=Ice::emptyCurrent) override
void step(const Ice::Current &c=Ice::emptyCurrent) override
void setRobotAngularVelocityRobotRootFrame(const std::string &robotName, const std::string &robotNodeName, const Vector3BasePtr &vel, const Ice::Current &c=Ice::emptyCurrent) override
std::string addRobotFromFile(const armarx::data::PackagePath &packagePath, const Ice::Current &c=Ice::emptyCurrent) override
memoryx::GridFileManagerPtr fileManager
Definition Simulator.h:477
memoryx::PriorKnowledgeInterfacePrx priorKnowledgePrx
Definition Simulator.h:475
SimulatorListenerInterfacePrx simulatorVisuUpdateListenerPrx
Definition Simulator.h:468
std::condition_variable condSimulatorThreadRunning
Definition Simulator.h:448
bool hasObject(const std::string &instanceName, const Ice::Current &c=Ice::emptyCurrent) override
Ice::Float getSpeed(const Ice::Current &c=Ice::emptyCurrent) override
NameValueMap getRobotJointTorques(const std::string &robotName, const Ice::Current &c=Ice::emptyCurrent) override
bool loadAgentsFromSnapshot(memoryx::WorkingMemorySnapshotInterfacePrx snapshotInterfacePrx)
void removeObject(const std::string &instanceName, const Ice::Current &) override
DistanceInfo getDistance(const std::string &robotName, const std::string &robotNodeName, const std::string &worldObjectName, const Ice::Current &c=Ice::emptyCurrent) override
float getSimTime(const Ice::Current &c=Ice::emptyCurrent) override
void stop(const Ice::Current &c=Ice::emptyCurrent) override
NameValueMap getRobotJointVelocities(const std::string &robotName, const Ice::Current &c=Ice::emptyCurrent) override
PeriodicTask< Simulator >::pointer_type reportVisuTask
The report visu task.
Definition Simulator.h:440
bool addSnapshot(memoryx::WorkingMemorySnapshotInterfacePrx snapshotInterfacePrx)
float getRobotJointLimitHi(const std::string &robotName, const std::string &nodeName, const Ice::Current &c=Ice::emptyCurrent) override
bool hasRobot(const std::string &robotName, const Ice::Current &c=Ice::emptyCurrent) override
std::string contactLayerName
Definition Simulator.h:486
void pause(const Ice::Current &c=Ice::emptyCurrent) override
void setRobotAngularVelocity(const std::string &robotName, const std::string &robotNodeName, const Vector3BasePtr &vel, const Ice::Current &c=Ice::emptyCurrent) override
PeriodicTask< Simulator >::pointer_type reportDataTask
The report data task.
Definition Simulator.h:442
void setRobotLinearVelocityRobotRootFrame(const std::string &robotName, const std::string &robotNodeName, const Vector3BasePtr &vel, const Ice::Current &c=Ice::emptyCurrent) override
float currentSimTimeMS
Stores the time that was needed to perform the last simulation loop.
Definition Simulator.h:456
Vector3BasePtr getRobotLinearVelocity(const std::string &robotName, const std::string &nodeName, const Ice::Current &c=Ice::emptyCurrent) override
SimulatedWorldPtr physicsWorld
Definition Simulator.h:450
void setSpeed(Ice::Float newSpeed, const Ice::Current &c=Ice::emptyCurrent) override
setSpeed sets the scaling factor for the speed of passing of time e.g.
std::string addScaledRobotName(const std::string &instanceName, const std::string &filename, float scale, const Ice::Current &c=Ice::emptyCurrent) override
ObjectFinder objectFinder
Constructed once based on the ObjectPackage property.
Definition Simulator.h:480
void onConnectComponent() override
Pure virtual hook for the subclass.
void objectReleased(const std::string &robotName, const std::string &robotNodeName, const std::string &objectName, const Ice::Current &c=Ice::emptyCurrent) override
remove a joint
bool isRunning(const Ice::Current &c=Ice::emptyCurrent) override
std::atomic< float > reportVisuTimeMS
Definition Simulator.h:470
float getRobotMaxTorque(const std::string &robotName, const std::string &nodeName, const Ice::Current &c=Ice::emptyCurrent) override
void updateContacts(bool enable, const Ice::Current &c=Ice::emptyCurrent) override
Enables the handling of contacts. If you intend to use getContacts(), call this method with enabled =...
memoryx::GridFileManagerPtr requestFileManager()
float currentSyncTimeMS
stores the time that was needed to sync the data
Definition Simulator.h:458
SimulatedRobotState getRobotState(const std::string &robotName, const Ice::Current &) override
bool removeRobot(const std::string &robotName, const Ice::Current &c=Ice::emptyCurrent)
float getRobotMass(const std::string &robotName, const Ice::Current &c=Ice::emptyCurrent) override
bool simulatorThreadShutdown
Definition Simulator.h:446
SceneVisuData getScene(const Ice::Current &c=Ice::emptyCurrent) override
float getRobotJointLimitLo(const std::string &robotName, const std::string &nodeName, const Ice::Current &c=Ice::emptyCurrent) override
void setObjectPose(const std::string &objectName, const PoseBasePtr &globalPose, const Ice::Current &c=Ice::emptyCurrent) override
DistanceInfo getRobotNodeDistance(const std::string &robotName, const std::string &robotNodeName1, const std::string &robotNodeName2, const Ice::Current &c=Ice::emptyCurrent) override
void objectGrasped(const std::string &robotName, const std::string &robotNodeName, const std::string &objectName, const Ice::Current &c=Ice::emptyCurrent) override
create a joint
TimeServerListenerPrx timeTopicPrx
Definition Simulator.h:463
void setRobotPose(const std::string &robotName, const PoseBasePtr &globalPose, const Ice::Current &c=Ice::emptyCurrent) override
std::string addRobot(const std::string &filename, const Ice::Current &c=Ice::emptyCurrent) override
void run() override
void onExitComponent() override
Hook for subclass.
void addObject(const memoryx::ObjectClassBasePtr &objectClassBase, const std::string &instanceName, const PoseBasePtr &globalPose, bool isStatic=false, const Ice::Current &c=Ice::emptyCurrent) override
SimulatedRobotState stateFromRobotInfo(RobotInfo const &robot, IceUtil::Time timestamp)
void actuateRobotJoints(const std::string &robotName, const NameValueMap &angles, const NameValueMap &velocities, const Ice::Current &c=Ice::emptyCurrent) override
ForceTorqueDataSeq getRobotForceTorqueSensors(const std::string &robotName, const Ice::Current &c=Ice::emptyCurrent) override
void setRobotMaxTorque(const std::string &robotName, const std::string &nodeName, float maxTorque, const Ice::Current &c=Ice::emptyCurrent) override
ObjectClassInformationSequence getObjectClassPoses(const std::string &robotName, const std::string &frameName, const std::string &className, const Ice::Current &c=Ice::emptyCurrent) override
void actuateRobotJointsPos(const std::string &robotName, const NameValueMap &angles, const Ice::Current &c=Ice::emptyCurrent) override
PoseBasePtr getRobotNodePose(const std::string &robotName, const std::string &robotNodeName, const Ice::Current &c=Ice::emptyCurrent) override
void actuateRobotJointsVel(const std::string &robotName, const NameValueMap &velocities, const Ice::Current &c=Ice::emptyCurrent) override
std::string commonStorageName
Definition Simulator.h:473
void activateObject(const std::string &objectName, const Ice::Current &c=Ice::emptyCurrent) override
bool simulatorThreadRunning
Definition Simulator.h:445
std::string priorKnowledgeName
Definition Simulator.h:472
Ice::StringSeq getRobotNames(const Ice::Current &) override
memoryx::EntityDrawerInterfacePrx entityDrawerPrx
Drawing contacts.
Definition Simulator.h:483
std::map< std::string, std::vector< std::string > > classInstanceMap
Stores all instances that belong to a class.
Definition Simulator.h:491
std::string getDefaultName() const override
Retrieve default name of component.
int getFixedTimeStepMS(const Ice::Current &c=Ice::emptyCurrent) override
void applyTorqueObject(const std::string &objectName, const Vector3BasePtr &torque, const Ice::Current &c=Ice::emptyCurrent) override
The Vector3 class.
Definition Pose.h:113
SimoxObjectWrapper offers a simplified access to the Simox ManipulationObject (i.e visualization,...
GridFileManager provides utility functions for working with files in Mongo GridFS and links to them s...
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
#define ARMARX_CHECK_NONNEGATIVE(number)
Check whether number is nonnegative (>= 0).
#define ARMARX_DEBUG_S
The logging level for output that is only interesting while debugging.
Definition Logging.h:205
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_LOG
Definition Logging.h:165
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
std::string const GlobalFrame
Variable of the global coordinate system.
Definition FramedPose.h:65
#define q
Quaternion< float, 0 > Quaternionf
Parser * parser
Definition Parser.cpp:34
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
armem::MemoryID ObjectID
Definition types.h:79
T getValue(nlohmann::json &userConfig, nlohmann::json &defaultConfig, const std::string &entryName)
Definition utils.h:80
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< Vector3 > Vector3Ptr
Definition Pose.h:165
std::string GetHandledExceptionString()
void handleExceptions()
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
IceInternal::Handle< Pose > PosePtr
Definition Pose.h:306
std::shared_ptr< KinematicsWorld > KinematicsWorldPtr
SimulatorType
Definition Simulator.h:70
IceInternal::Handle< FramedPosition > FramedPositionPtr
Definition FramedPose.h:149
IceInternal::Handle< FramedOrientation > FramedOrientationPtr
Definition FramedPose.h:207
std::shared_ptr< MujocoPhysicsWorld > MujocoPhysicsWorldPtr
const std::string & to_string(const std::string &s)
std::string ValueToString(const T &value)
std::shared_ptr< BulletPhysicsWorld > BulletPhysicsWorldPtr
IceInternal::Handle< SimoxObjectWrapper > SimoxObjectWrapperPtr
VirtualRobot headers.
IceInternal::Handle< AgentInstance > AgentInstancePtr
Typedef of AgentEntityPtr as IceInternal::Handle<AgentEntity> for convenience.
IceInternal::Handle< ObjectInstance > ObjectInstancePtr
IceInternal::Handle< ObjectClass > ObjectClassPtr
Definition ObjectClass.h:35
std::shared_ptr< GridFileManager > GridFileManagerPtr
std::filesystem::path absolutePath
The absolute path (in the host's file system).
Definition ObjectInfo.h:30
std::string package
Name of the ArmarX package.
Definition ObjectInfo.h:25
std::string relativePath
Relative to the package's data directory.
Definition ObjectInfo.h:28
NameValueMap jointVelocities
Eigen::Matrix4f pose
std::vector< ForceTorqueInfo > forceTorqueSensors
NameValueMap jointAngles
SimulatorRobotListenerInterfacePrx simulatorRobotListenerPrx
Eigen::Vector3f angularVelocity
Eigen::Vector3f linearVelocity
std::string robotName
NameValueMap jointTorques
std::vector< SceneObject > objects
Definition Scene.h:57
#define ARMARX_TRACE
Definition trace.h:77