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