28 #include <VirtualRobot/MathTools.h>
29 #include <VirtualRobot/RobotNodeSet.h>
30 #include <VirtualRobot/Nodes/ForceTorqueSensor.h>
44 synchronizedSimulation = getProperty<bool>(
"SynchronizedSimulation").getValue();
45 simulatorRobotListenerInterfaceTopic = getProperty<std::string>(
"SimulatorRobotListenerInterfaceTopic").getValue();
46 if (simulatorRobotListenerInterfaceTopic.empty())
48 simulatorRobotListenerInterfaceTopic =
"Simulator_Robot_" +
getRobotName();
50 simulatorForceTorqueListenerInterfaceTopic = getProperty<std::string>(
"SimulatorForceTorqueListenerInterfaceTopic").getValue();
51 std::size_t controlIterationMsProp = getProperty<std::size_t>(
"ControlIterationMs").getValue();
52 if (!controlIterationMsProp)
54 ARMARX_WARNING <<
"the controll iteration was set to 0ms. detting it to 1ms";
55 controlIterationMsProp = 1;
57 controlIterationMs = IceUtil::Time::milliSeconds(controlIterationMsProp);
58 usingTopic(simulatorRobotListenerInterfaceTopic);
59 usingTopic(simulatorForceTorqueListenerInterfaceTopic);
63 const std::string mappingStr = getProperty<std::string>(
"ForceTorqueSensorMapping");
64 std::vector<std::string> entries;
67 bool trimEntries =
true;
68 entries =
Split(mappingStr,
",", trimEntries);
70 for (std::string entry : entries)
73 bool trimFields =
true;
74 std::vector<std::string> fields =
Split(entry,
":", trimFields);
76 fields.size() == 2 || fields.size() == 3) <<
77 "invalid entry in ForceTorqueSensorMapping! invalid entry:\n" << fields <<
"\nall entries:\n" << entries;
78 for (
auto& field : fields)
82 "empty field in ForceTorqueSensorMapping entry! invalid entry:\n" << fields <<
"\nall entries:\n" << entries;
84 const VirtualRobot::ForceTorqueSensorPtr ftsensor =
robot->getSensor<
typename VirtualRobot::ForceTorqueSensor>(fields.at(0));
87 ARMARX_WARNING <<
"the robot has not ft sensor of name '" << fields.at(0)
88 <<
"' this ForceTorqueSensorMapping entry has no effect: " << entry;
92 fields.size() == 2 ||
robot->hasRobotNode(fields.at(2))) <<
93 VAROUT(fields.size()) <<
" " << (fields.size() != 2 ?
VAROUT(fields.at(2)) : std::string {});
95 FTMappingData& mapping = ftMappings[fields.at(0)];
96 mapping.originalReportFrame = ftsensor->getRobotNode()->getName();
97 mapping.reportFrame = mapping.originalReportFrame;
99 mapping.sensorName = fields.at(1);
100 if (fields.size() == 3)
102 mapping.reportFrame = fields.at(2);
104 const auto orig =
robot->getRobotNode(mapping.originalReportFrame)->getGlobalPose();
105 const auto targ =
robot->getRobotNode(mapping.reportFrame)->getGlobalPose();
106 mapping.reportTransformation = (targ.block<3, 3>(0, 0).inverse() * orig.block<3, 3>(0, 0));
152 for (
const VirtualRobot::RobotNodePtr& node : * (
robot->getRobotNodeSet(getProperty<std::string>(
"RobotNodeSetName").getValue())))
156 JointSimulationDevicePtr jdev = std::make_shared<JointSimulationDevice>(node->getName(), anglesCtrl, velocitiesCtrl, torquesCtrl);
157 jointDevs.
add(jdev->getDeviceName(), jdev);
171 ARMARX_INFO <<
"No platform device will be created since platform name was given";
191 ARMARX_INFO <<
"adding devices for force torque sensors:";
192 for (
const auto& ft :
robot->getSensors<VirtualRobot::ForceTorqueSensor>())
194 ForceTorqueSimulationSensorDevicePtr ftdev = std::make_shared<ForceTorqueSimulationSensorDevice>(
195 getMappedFTName(ft->getName()),
196 getMappedFTReportingFrame(ft->getName(), ft->getRobotNode()->getName()),
197 getMappedFTReportingTransformation(ft->getName())
200 forceTorqueDevs.
add(ftdev->getDeviceName(), ftdev);
221 torquesTB.
reinit(std::vector<float>(jointDevs.
size(), 0));
222 anglesTB.
reinit(std::vector<float>(jointDevs.
size(), 0));
223 velocitiesTB.
reinit(std::vector<float>(jointDevs.
size(), 0));
224 forceTorqueTB.
reinit(std::vector<FT>(forceTorqueDevs.
size(), FT {}));
225 forceTorqueTimes.clear();
226 forceTorqueTimes.resize(forceTorqueDevs.
size(), 0);
238 gotSensorData =
false;
240 rtUpdateSensors(
true);
244 const float absolutePositionX = robPoseTB.
getReadBuffer()(0, 3);
245 const float absolutePositionY = robPoseTB.
getReadBuffer()(1, 3);
246 const float absolutePositionRotation = VirtualRobot::MathTools::eigen4f2rpy(robPoseTB.
getReadBuffer())(2);
248 platformDev->initAbsolutePositionX = absolutePositionX;
249 platformDev->initAbsolutePositionY = absolutePositionY;
250 platformDev->initAbsolutePositionRotation = absolutePositionRotation;
256 if (synchronizedSimulation)
281 timeSinceLastIteration = currentIterationStart - lastIterationStart;
282 lastIterationStart = currentIterationStart;
295 if (synchronizedSimulation)
297 gotSensorData =
false;
300 rtUpdateSensors(synchronizedSimulation);
308 const IceUtil::Time sleepUntil = currentIterationStart + controlIterationMs;
310 while (currentTime < sleepUntil)
316 if (currentTime < currentIterationStart)
322 std::this_thread::sleep_for(std::chrono::microseconds {100});
327 catch (Ice::Exception& e)
331 <<
"\n\tname: " << e.ice_id()
332 <<
"\n\tfile: " << e.ice_file()
333 <<
"\n\tline: " << e.ice_line()
334 <<
"\n\tstack: " << e.ice_stackTrace()
338 catch (std::exception& e)
352 IceUtil::Time timestamp = IceUtil::Time::microSeconds(state.timestampInMicroSeconds);
363 fillTB(anglesTB, state.jointAngles,
"JointAngles");
364 fillTB(velocitiesTB, state.jointVelocities,
"JointVelocities");
365 fillTB(torquesTB, state.jointTorques,
"JointTorques");
367 for (ForceTorqueData
const& ftData : state.forceTorqueValues)
369 updateForceTorque(ftData, timestamp);
379 auto g = robPoseTB.
guard();
380 ARMARX_CHECK_NOT_NULL(state.pose) <<
"Robot Pose is not allowed to be NULL. Maybe no state was reported from Simulator!";
381 robPoseTB.
getWriteBuffer() = PosePtr::dynamicCast(state.pose)->toEigen();
393 auto& trans = state.linearVelocity;
394 auto& rotat = state.angularVelocity;
396 auto g = robVelTB.
guard();
409 gotSensorData =
true;
412 void RobotUnitSimulation::updateForceTorque(
const ForceTorqueData& ftData,
IceUtil::Time timestamp)
414 auto& sensorName = ftData.sensorName;
415 auto& nodeName = ftData.nodeName;
417 const std::string sensname = ftMappings.count(sensorName) ? ftMappings.at(sensorName).sensorName : sensorName;
418 if (ftMappings.count(sensorName) && ftMappings.at(sensorName).originalReportFrame != nodeName)
420 ARMARX_ERROR <<
deactivateSpam(0.25) <<
"Sensor values for sensor '" << sensorName <<
"' ('" << sensname <<
"') are reported in frame '" << nodeName
421 <<
"' instead of '" << ftMappings.at(sensorName).originalReportFrame <<
"' as defined during setup! (this value is skipped!)";
426 ARMARX_DEBUG <<
deactivateSpam(10, sensname) <<
"Skipped all sensor values for force torque of sensor " << sensname <<
" (node = " << nodeName <<
")";
429 auto g = forceTorqueTB.
guard();
430 if (!forceTorqueDevs.
has(sensname))
435 auto i = forceTorqueDevs.
index(sensname);
437 auto& force = ftData.force;
438 auto& torque = ftData.torque;
447 Eigen::Vector3f filteredTorque;
448 Eigen::Vector3f filteredForce;
458 forceTorqueTB.
write();
459 forceTorqueTimes.at(i) = timestamp.toMicroSeconds() * 1000;
460 ARMARX_DEBUG <<
deactivateSpam(10, sensname) <<
"Got new sensor values for force torque of sensor " << sensname <<
" (node = " << nodeName <<
")";
471 std::stringstream ignored;
472 bool someWereIgnored =
false;
473 for (
const auto&
a : nv)
475 if (jointDevs.
has(
a.first))
477 b.getWriteBuffer().at(jointDevs.
index(
a.first)) =
a.second;
481 ignored <<
a.first <<
" -> " <<
a.second <<
"\n";
482 someWereIgnored =
true;
493 void RobotUnitSimulation::rtSendCommands()
499 if (!velocitiesCtrl.empty())
501 prx->actuateRobotJointsVel(
robotName, velocitiesCtrl);
503 if (!anglesCtrl.empty())
505 prx->actuateRobotJointsPos(
robotName, anglesCtrl);
507 if (!torquesCtrl.empty())
509 prx->actuateRobotJointsTorque(
robotName, torquesCtrl);
514 Eigen::Vector3f translationVel;
517 translationVel(2) = 0;
518 translationVel /= 1000;
522 prx->setRobotLinearVelocityRobotRootFrame(
robotName, platformDev->getDeviceName(),
new Vector3(translationVel));
523 prx->setRobotAngularVelocityRobotRootFrame(
robotName, platformDev->getDeviceName(),
new Vector3(rotationVel));
527 prx->ice_flushBatchRequests();
529 catch (Ice::ConnectionRefusedException&)
535 ARMARX_WARNING <<
"Ice::ConnectionRefusedException when sending commands to the simulator";
538 catch (Ice::NotRegisteredException&)
544 ARMARX_WARNING <<
"Ice::NotRegisteredException when sending commands to the simulator";
549 bool RobotUnitSimulation::skipReport()
const
551 static const std::set<RobotUnitState> reportAcceptingStates
559 void RobotUnitSimulation::rtPollRobotState()
561 if (!isPolling.exchange(
true))
570 auto rootname =
robot->getRootNode()->getName();
575 catch (Ice::Exception& e)
579 <<
"\n\tname: " << e.ice_id()
580 <<
"\n\tfile: " << e.ice_file()
581 <<
"\n\tline: " << e.ice_line()
582 <<
"\n\tstack: " << e.ice_stackTrace()
586 catch (std::exception& e)
605 if (changedProperties.count(
"SynchronizedSimulation"))
607 synchronizedSimulation = getProperty<bool>(
"SynchronizedSimulation").getValue();
611 if (synchronizedSimulation)
624 void RobotUnitSimulation::rtUpdateSensors(
bool wait)
630 std::unique_lock<std::mutex> dummlock {dummy};
631 std::size_t fails = 0;
632 while (!gotSensorData)
635 cvGotSensorData.wait_for(dummlock, std::chrono::milliseconds {10});
651 const IceUtil::Time timeSinceLastIteration = now - sensorValuesTimestamp;
652 const float dt =
static_cast<float>(timeSinceLastIteration.toSecondsDouble());
653 sensorValuesTimestamp = now;
659 forceTorqueTB.
read();
661 for (std::size_t i = 0; i < jointDevs.
size(); ++i)
672 for (std::size_t i = 0; i < forceTorqueDevs.
size(); ++i)
681 auto&
s = platformDev->sensorValue;
683 const float absolutePositionX = robPoseTB.
getReadBuffer()(0, 3);
684 const float absolutePositionY = robPoseTB.
getReadBuffer()(1, 3);
685 const float absolutePositionRotation = VirtualRobot::MathTools::eigen4f2rpy(robPoseTB.
getReadBuffer())(2);
687 Eigen::Vector2f relativePositionGlobalFrame;
688 relativePositionGlobalFrame << absolutePositionX - platformDev->initAbsolutePositionX,
689 absolutePositionY - platformDev->initAbsolutePositionY;
690 s.relativePositionRotation = absolutePositionRotation - platformDev->initAbsolutePositionRotation;
692 Eigen::Vector2f relativePosition = Eigen::Rotation2Df(-platformDev->initAbsolutePositionRotation) * relativePositionGlobalFrame;
693 s.relativePositionX = relativePosition(0);
694 s.relativePositionY = relativePosition(1);
697 s.setVelocitiesAndDeriveAcceleration(
v.lin(0) / 3.f,
v.lin(1) / 3.f,
v.ang(2) / 5.0f,
dt);