28 #include <VirtualRobot/MathTools.h>
29 #include <VirtualRobot/Nodes/ForceTorqueSensor.h>
30 #include <VirtualRobot/RobotNodeSet.h>
45 synchronizedSimulation = getProperty<bool>(
"SynchronizedSimulation").getValue();
46 simulatorRobotListenerInterfaceTopic =
47 getProperty<std::string>(
"SimulatorRobotListenerInterfaceTopic").getValue();
48 if (simulatorRobotListenerInterfaceTopic.empty())
50 simulatorRobotListenerInterfaceTopic =
"Simulator_Robot_" +
getRobotName();
52 simulatorForceTorqueListenerInterfaceTopic =
53 getProperty<std::string>(
"SimulatorForceTorqueListenerInterfaceTopic").getValue();
54 std::size_t controlIterationMsProp = getProperty<std::size_t>(
"ControlIterationMs").getValue();
55 if (!controlIterationMsProp)
57 ARMARX_WARNING <<
"the controll iteration was set to 0ms. detting it to 1ms";
58 controlIterationMsProp = 1;
60 controlIterationMs = IceUtil::Time::milliSeconds(controlIterationMsProp);
61 usingTopic(simulatorRobotListenerInterfaceTopic);
62 usingTopic(simulatorForceTorqueListenerInterfaceTopic);
66 const std::string mappingStr = getProperty<std::string>(
"ForceTorqueSensorMapping");
67 std::vector<std::string>
entries;
70 bool trimEntries =
true;
73 for (std::string entry :
entries)
76 <<
"empty entry in ForceTorqueSensorMapping! entries:\n"
78 bool trimFields =
true;
79 std::vector<std::string> fields =
Split(entry,
":", trimFields);
81 <<
"invalid entry in ForceTorqueSensorMapping! invalid entry:\n"
82 << fields <<
"\nall entries:\n"
84 for (
auto& field : fields)
87 <<
"empty field in ForceTorqueSensorMapping entry! invalid entry:\n"
88 << fields <<
"\nall entries:\n"
91 const VirtualRobot::ForceTorqueSensorPtr ftsensor =
92 robot->getSensor<
typename VirtualRobot::ForceTorqueSensor>(fields.at(0));
95 ARMARX_WARNING <<
"the robot has not ft sensor of name '" << fields.at(0)
96 <<
"' this ForceTorqueSensorMapping entry has no effect: " << entry;
100 <<
VAROUT(fields.size()) <<
" "
101 << (fields.size() != 2 ?
VAROUT(fields.at(2)) : std::string{});
103 FTMappingData& mapping = ftMappings[fields.at(0)];
104 mapping.originalReportFrame = ftsensor->getRobotNode()->getName();
105 mapping.reportFrame = mapping.originalReportFrame;
107 mapping.sensorName = fields.at(1);
108 if (fields.size() == 3)
110 mapping.reportFrame = fields.at(2);
112 const auto orig =
robot->getRobotNode(mapping.originalReportFrame)->getGlobalPose();
113 const auto targ =
robot->getRobotNode(mapping.reportFrame)->getGlobalPose();
114 mapping.reportTransformation =
115 (targ.block<3, 3>(0, 0).inverse() * orig.block<3, 3>(0, 0));
167 for (
const VirtualRobot::RobotNodePtr& node : *(
robot->getRobotNodeSet(
168 getProperty<std::string>(
"RobotNodeSetName").getValue())))
172 JointSimulationDevicePtr jdev = std::make_shared<JointSimulationDevice>(
173 node->getName(), anglesCtrl, velocitiesCtrl, torquesCtrl);
174 jointDevs.
add(jdev->getDeviceName(), jdev);
190 <<
"No platform device will be created since platform name was given";
205 "' so no platform device will be created";
208 ARMARX_INFO <<
"adding devices for the platform done ("
214 ARMARX_INFO <<
"adding devices for force torque sensors:";
215 for (
const auto& ft :
robot->getSensors<VirtualRobot::ForceTorqueSensor>())
217 ForceTorqueSimulationSensorDevicePtr ftdev =
218 std::make_shared<ForceTorqueSimulationSensorDevice>(
219 getMappedFTName(ft->getName()),
220 getMappedFTReportingFrame(ft->getName(),
221 ft->getRobotNode()->getName()),
222 getMappedFTReportingTransformation(ft->getName()));
224 forceTorqueDevs.
add(ftdev->getDeviceName(), ftdev);
226 ARMARX_INFO <<
"adding devices for force torque done ("
247 torquesTB.
reinit(std::vector<float>(jointDevs.
size(), 0));
248 anglesTB.
reinit(std::vector<float>(jointDevs.
size(), 0));
249 velocitiesTB.
reinit(std::vector<float>(jointDevs.
size(), 0));
250 forceTorqueTB.
reinit(std::vector<FT>(forceTorqueDevs.
size(), FT{}));
251 forceTorqueTimes.clear();
252 forceTorqueTimes.resize(forceTorqueDevs.
size(), 0);
267 gotSensorData =
false;
269 rtUpdateSensors(
true);
273 const float absolutePositionX = robPoseTB.
getReadBuffer()(0, 3);
274 const float absolutePositionY = robPoseTB.
getReadBuffer()(1, 3);
275 const float absolutePositionRotation =
276 VirtualRobot::MathTools::eigen4f2rpy(robPoseTB.
getReadBuffer())(2);
278 platformDev->initAbsolutePositionX = absolutePositionX;
279 platformDev->initAbsolutePositionY = absolutePositionY;
280 platformDev->initAbsolutePositionRotation = absolutePositionRotation;
287 if (synchronizedSimulation)
314 timeSinceLastIteration = currentIterationStart - lastIterationStart;
315 lastIterationStart = currentIterationStart;
320 timeSinceLastIteration);
323 timeSinceLastIteration);
333 if (synchronizedSimulation)
335 gotSensorData =
false;
338 rtUpdateSensors(synchronizedSimulation);
341 sensorValuesTimestamp,
342 timeSinceLastIteration);
348 const IceUtil::Time sleepUntil = currentIterationStart + controlIterationMs;
350 while (currentTime < sleepUntil)
356 if (currentTime < currentIterationStart)
362 std::this_thread::sleep_for(
363 std::chrono::microseconds{100});
368 catch (Ice::Exception& e)
371 << e.what() <<
"\n\tname: " << e.ice_id() <<
"\n\tfile: " << e.ice_file()
372 <<
"\n\tline: " << e.ice_line() <<
"\n\tstack: " << e.ice_stackTrace()
376 catch (std::exception& e)
402 fillTB(anglesTB, state.jointAngles,
"JointAngles");
403 fillTB(velocitiesTB, state.jointVelocities,
"JointVelocities");
404 fillTB(torquesTB, state.jointTorques,
"JointTorques");
406 for (ForceTorqueData
const& ftData : state.forceTorqueValues)
418 auto g = robPoseTB.
guard();
420 <<
"Robot Pose is not allowed to be NULL. Maybe no state was reported from Simulator!";
421 robPoseTB.
getWriteBuffer() = PosePtr::dynamicCast(state.pose)->toEigen();
433 auto& trans = state.linearVelocity;
434 auto& rotat = state.angularVelocity;
436 auto g = robVelTB.
guard();
451 gotSensorData =
true;
457 auto& sensorName = ftData.sensorName;
458 auto& nodeName = ftData.nodeName;
460 const std::string sensname =
461 ftMappings.count(sensorName) ? ftMappings.at(sensorName).sensorName : sensorName;
462 if (ftMappings.count(sensorName) && ftMappings.at(sensorName).originalReportFrame != nodeName)
465 << sensname <<
"') are reported in frame '" << nodeName <<
"' instead of '"
466 << ftMappings.at(sensorName).originalReportFrame
467 <<
"' as defined during setup! (this value is skipped!)";
473 <<
"Skipped all sensor values for force torque of sensor " << sensname
474 <<
" (node = " << nodeName <<
")";
477 auto g = forceTorqueTB.
guard();
478 if (!forceTorqueDevs.
has(sensname))
482 << forceTorqueDevs.
keys();
485 auto i = forceTorqueDevs.
index(sensname);
488 auto& force = ftData.force;
489 auto& torque = ftData.torque;
498 Eigen::Vector3f filteredTorque;
499 Eigen::Vector3f filteredForce;
509 forceTorqueTB.
write();
510 forceTorqueTimes.at(i) =
timestamp.toMicroSeconds() * 1000;
512 <<
"Got new sensor values for force torque of sensor " << sensname
513 <<
" (node = " << nodeName <<
")";
519 const std::string name)
const
527 std::stringstream ignored;
528 bool someWereIgnored =
false;
529 for (
const auto&
a : nv)
531 if (jointDevs.
has(
a.first))
533 b.getWriteBuffer().at(jointDevs.
index(
a.first)) =
a.second;
537 ignored <<
a.first <<
" -> " <<
a.second <<
"\n";
538 someWereIgnored =
true;
551 RobotUnitSimulation::rtSendCommands()
557 if (!velocitiesCtrl.empty())
559 prx->actuateRobotJointsVel(
robotName, velocitiesCtrl);
561 if (!anglesCtrl.empty())
563 prx->actuateRobotJointsPos(
robotName, anglesCtrl);
565 if (!torquesCtrl.empty())
567 prx->actuateRobotJointsTorque(
robotName, torquesCtrl);
572 Eigen::Vector3f translationVel;
573 translationVel(0) =
std::clamp(platformDev->target.velocityX,
576 translationVel(1) =
std::clamp(platformDev->target.velocityY,
579 translationVel(2) = 0;
580 translationVel /= 1000;
582 Eigen::Vector3f rotationVel(0.f,
584 std::clamp(platformDev->target.velocityRotation,
588 prx->setRobotLinearVelocityRobotRootFrame(
590 prx->setRobotAngularVelocityRobotRootFrame(
593 <<
"setting platform vel ang: " << rotationVel.transpose();
595 <<
"setting platform vel lin: " << translationVel.transpose();
597 prx->ice_flushBatchRequests();
599 catch (Ice::ConnectionRefusedException&)
606 <<
"Ice::ConnectionRefusedException when sending commands to the simulator";
609 catch (Ice::NotRegisteredException&)
615 ARMARX_WARNING <<
"Ice::NotRegisteredException when sending commands to the simulator";
621 RobotUnitSimulation::skipReport()
const
623 static const std::set<RobotUnitState> reportAcceptingStates{
629 RobotUnitSimulation::rtPollRobotState()
631 if (!isPolling.exchange(
true))
638 auto rootname =
robot->getRootNode()->getName();
643 catch (Ice::Exception& e)
646 << e.what() <<
"\n\tname: " << e.ice_id()
647 <<
"\n\tfile: " << e.ice_file()
648 <<
"\n\tline: " << e.ice_line()
649 <<
"\n\tstack: " << e.ice_stackTrace() <<
std::flush;
652 catch (std::exception& e)
673 if (changedProperties.count(
"SynchronizedSimulation"))
675 synchronizedSimulation = getProperty<bool>(
"SynchronizedSimulation").getValue();
679 if (synchronizedSimulation)
693 RobotUnitSimulation::rtUpdateSensors(
bool wait)
699 std::unique_lock<std::mutex> dummlock{dummy};
700 std::size_t fails = 0;
701 while (!gotSensorData)
704 <<
"waiting for up to date sensor values (iteration " << iterationCount
706 cvGotSensorData.wait_for(dummlock, std::chrono::milliseconds{10});
722 const IceUtil::Time timeSinceLastIteration = now - sensorValuesTimestamp;
723 const float dt =
static_cast<float>(timeSinceLastIteration.toSecondsDouble());
724 sensorValuesTimestamp = now;
730 forceTorqueTB.
read();
732 for (std::size_t i = 0; i < jointDevs.
size(); ++i)
743 for (std::size_t i = 0; i < forceTorqueDevs.
size(); ++i)
752 auto&
s = platformDev->sensorValue;
754 const float absolutePositionX = robPoseTB.
getReadBuffer()(0, 3);
755 const float absolutePositionY = robPoseTB.
getReadBuffer()(1, 3);
756 const float absolutePositionRotation =
757 VirtualRobot::MathTools::eigen4f2rpy(robPoseTB.
getReadBuffer())(2);
759 Eigen::Vector2f relativePositionGlobalFrame;
760 relativePositionGlobalFrame << absolutePositionX - platformDev->initAbsolutePositionX,
761 absolutePositionY - platformDev->initAbsolutePositionY;
762 s.relativePositionRotation =
763 absolutePositionRotation - platformDev->initAbsolutePositionRotation;
765 Eigen::Vector2f relativePosition =
766 Eigen::Rotation2Df(-platformDev->initAbsolutePositionRotation) *
767 relativePositionGlobalFrame;
768 s.relativePositionX = relativePosition(0);
769 s.relativePositionY = relativePosition(1);
772 s.setVelocitiesAndDeriveAcceleration(
v.lin(0) / 3.f,
v.lin(1) / 3.f,
v.ang(2) / 5.0f,
dt);