35 const std::string Devices::rtThreadTimingsSensorDeviceName =
"RTThreadTimings";
37 ControlDeviceDescription
42 std::lock_guard<MutexType> guard{controlDevicesMutex};
43 if (!controlDevices.
has(name))
46 ss <<
"getControlDeviceDescription: There is no ControlDevice '" << name
47 <<
"'. There are these ControlDevices: " << controlDevices.
keys();
48 throw InvalidArgumentException{ss.str()};
53 ControlDeviceDescriptionSeq
61 std::lock_guard<MutexType> guard{controlDevicesMutex};
62 ControlDeviceDescriptionSeq r;
77 return controlDevices.
size();
85 return sensorDevices.
size();
93 std::lock_guard<MutexType> guard{sensorDevicesMutex};
95 return sensorDevices.
index(deviceName);
103 std::lock_guard<MutexType> guard{controlDevicesMutex};
105 return controlDevices.
index(deviceName);
113 std::lock_guard<MutexType> guard{sensorDevicesMutex};
122 std::lock_guard<MutexType> guard{controlDevicesMutex};
131 std::lock_guard<MutexType> guard{controlDevicesMutex};
132 return controlDevices.
keys();
135 ControlDeviceDescription
140 std::lock_guard<MutexType> guard{controlDevicesMutex};
141 const ControlDevicePtr& controlDevice = controlDevices.
at(idx);
142 ControlDeviceDescription
data;
143 data.deviceName = controlDevice->getDeviceName();
144 data.tags.assign(controlDevice->getTags().begin(), controlDevice->getTags().end());
145 for (
const auto& jointCtrl : controlDevice->getJointControllers())
147 data.contolModeToTargetType[jointCtrl->getControlMode()].targetType =
148 jointCtrl->getControlTarget()->getControlTargetType();
149 data.contolModeToTargetType[jointCtrl->getControlMode()].hardwareControlMode =
150 jointCtrl->getHardwareControlMode();
161 std::lock_guard<MutexType> guard{controlDevicesMutex};
162 const ControlDevicePtr& controlDevice = controlDevices.
at(idx);
163 ControlDeviceStatus
status;
164 const auto activeJointCtrl =
165 _module<ControlThreadDataBuffer>().getActivatedJointControllers().at(idx);
166 status.activeControlMode = activeJointCtrl ? activeJointCtrl->getControlMode()
167 : std::string{
"!!JointController is nullptr!!"};
168 status.deviceName = controlDevice->getDeviceName();
169 const auto requestedJointControllers =
170 _module<ControlThreadDataBuffer>().copyRequestedJointControllers();
172 status.requestedControlMode = requestedJointControllers.at(idx)->getControlMode();
173 for (
const auto& targ :
174 _module<ControlThreadDataBuffer>().getSensorAndControlBuffer().
control.at(idx))
176 status.controlTargetValues[targ->getControlMode()] =
177 targ->toVariants(_module<ControlThreadDataBuffer>()
178 .getSensorAndControlBuffer()
179 .sensorValuesTimestamp);
191 std::lock_guard<MutexType> guard{controlDevicesMutex};
192 if (!controlDevices.
has(name))
194 std::stringstream ss;
195 ss <<
"getControlDeviceStatus: There is no ControlDevice '" << name
196 <<
"'. There are these ControlDevices: " << controlDevices.
keys();
197 throw InvalidArgumentException{ss.str()};
202 ControlDeviceStatusSeq
210 std::lock_guard<MutexType> guard{controlDevicesMutex};
211 ControlDeviceStatusSeq r;
226 std::lock_guard<MutexType> guard{sensorDevicesMutex};
227 return sensorDevices.
keys();
230 SensorDeviceDescription
235 std::lock_guard<MutexType> guard{sensorDevicesMutex};
236 const SensorDevicePtr& sensorDevice = sensorDevices.
at(idx);
237 SensorDeviceDescription
data;
238 data.deviceName = sensorDevice->getDeviceName();
239 data.tags.assign(sensorDevice->getTags().begin(), sensorDevice->getTags().end());
240 data.sensorValueType = sensorDevice->getSensorValueType();
250 std::lock_guard<MutexType> guard{sensorDevicesMutex};
251 const SensorDevicePtr& sensorDevice = sensorDevices.
at(idx);
252 SensorDeviceStatus
status;
253 status.deviceName = sensorDevice->getDeviceName();
254 status.sensorValue = _module<ControlThreadDataBuffer>()
255 .getSensorAndControlBuffer()
257 ->toVariants(_module<ControlThreadDataBuffer>()
258 .getSensorAndControlBuffer()
259 .sensorValuesTimestamp);
265 SensorDeviceDescription
270 std::lock_guard<MutexType> guard{sensorDevicesMutex};
271 if (!sensorDevices.
has(name))
273 std::stringstream ss;
274 ss <<
"getSensorDeviceDescription: There is no SensorDevice '" << name
275 <<
"'. There are these SensorDevices: " << sensorDevices.
keys();
276 throw InvalidArgumentException{ss.str()};
281 SensorDeviceDescriptionSeq
285 std::lock_guard<MutexType> guard{sensorDevicesMutex};
290 SensorDeviceDescriptionSeq r;
304 std::lock_guard<MutexType> guard{sensorDevicesMutex};
305 if (!sensorDevices.
has(name))
307 std::stringstream ss;
308 ss <<
"getSensorDeviceStatus: There is no SensorDevice '" << name
309 <<
"'. There are these SensorDevices: " << sensorDevices.
keys();
310 throw InvalidArgumentException{ss.str()};
315 SensorDeviceStatusSeq
323 std::lock_guard<MutexType> guard{sensorDevicesMutex};
324 SensorDeviceStatusSeq r;
341 std::lock_guard<MutexType> guard{controlDevicesMutex};
345 std::stringstream ss;
346 ss <<
"armarx::RobotUnit::addControlDevice: ControlDevice is nullptr";
348 throw InvalidArgumentException{ss.str()};
350 if (!cd->getJointEmergencyStopController())
352 std::stringstream ss;
353 ss <<
"armarx::RobotUnit::addControlDevice: ControlDevice " << cd->getDeviceName()
354 <<
" has null JointEmergencyStopController (this is not allowed)";
356 throw InvalidArgumentException{ss.str()};
358 if (!cd->getJointStopMovementController())
360 std::stringstream ss;
361 ss <<
"armarx::RobotUnit::addControlDevice: ControlDevice " << cd->getDeviceName()
362 <<
" has null getJointStopMovementController (this is not allowed)";
364 throw InvalidArgumentException{ss.str()};
367 ARMARX_DEBUG <<
"Adding the ControlDevice " << cd->getDeviceName() <<
" " << &cd;
368 controlDevices.
add(cd->getDeviceName(), cd);
370 ARMARX_INFO <<
"added ControlDevice " << cd->getDeviceName();
372 ARMARX_INFO <<
"added ControlDevice " << cd->getDeviceName();
383 std::lock_guard<MutexType> guard{sensorDevicesMutex};
387 std::stringstream ss;
388 ss <<
"armarx::RobotUnit::addSensorDevice: SensorDevice is nullptr";
390 throw InvalidArgumentException{ss.str()};
392 if (!sd->getSensorValue())
394 std::stringstream ss;
395 ss <<
"armarx::RobotUnit::addSensorDevice: SensorDevice " << sd->getDeviceName()
396 <<
" has null SensorValue (this is not allowed)";
398 throw InvalidArgumentException{ss.str()};
401 if (sd->getDeviceName() == rtThreadTimingsSensorDeviceName)
403 ARMARX_DEBUG <<
"Device is the " << rtThreadTimingsSensorDeviceName;
404 if (!std::dynamic_pointer_cast<RTThreadTimingsSensorDevice>(sd))
406 throw InvalidArgumentException{
407 "You tried to add a SensorDevice with the name " + sd->getDeviceName() +
408 " which does not derive from RTThreadTimingsSensorDevice. (Don't do this)"};
411 ARMARX_DEBUG <<
"Adding the SensorDevice " << sd->getDeviceName() <<
" " << &sd;
412 sensorDevices.
add(sd->getDeviceName(), sd);
414 rtThreadTimingsSensorDevice =
415 std::dynamic_pointer_cast<RTThreadTimingsSensorDevice>(sd);
419 ARMARX_DEBUG <<
"Device is the " << sd->getDeviceName();
420 if (!std::dynamic_pointer_cast<GlobalRobotLocalizationSensorDevice>(sd))
422 throw InvalidArgumentException{
423 "You tried to add a SensorDevice with the name " + sd->getDeviceName() +
424 " which does not derive from GlobalRobotLocalizationSensorDevice. (Don't "
428 ARMARX_DEBUG <<
"Adding the SensorDevice " << sd->getDeviceName() <<
" " << &sd;
429 sensorDevices.
add(sd->getDeviceName(), sd);
431 globalRobotLocalizationSensorDevice =
436 ARMARX_DEBUG <<
"Adding the SensorDevice " << sd->getDeviceName() <<
" " << &sd;
437 sensorDevices.
add(sd->getDeviceName(), sd);
441 ARMARX_INFO <<
"added SensorDevice " << sd->getDeviceName()
442 <<
" (valuetype = " << sd->getSensorValueType() <<
")";
446 RTThreadTimingsSensorDevicePtr
450 return std::make_shared<RTThreadTimingsSensorDeviceImpl<>>(rtThreadTimingsSensorDeviceName);
454 Devices::_postFinishRunning()
457 std::lock_guard<MutexType> guardS{sensorDevicesMutex};
458 std::lock_guard<MutexType> guardC{controlDevicesMutex};
459 controlDevicesConstPtr.clear();
460 sensorDevicesConstPtr.clear();
461 sensorDevices.
clear();
462 controlDevices.
clear();
465 std::vector<JointController*>
466 Devices::getStopMovementJointControllers()
const
470 std::lock_guard<MutexType> guard{controlDevicesMutex};
471 std::vector<JointController*> controllers;
472 controllers.reserve(controlDevices.
values().size());
473 for (
const ControlDevicePtr& dev : controlDevices.
values())
476 controllers.emplace_back(dev->rtGetJointStopMovementController());
484 std::vector<JointController*>
485 Devices::getEmergencyStopJointControllers()
const
489 std::lock_guard<MutexType> guard{controlDevicesMutex};
490 std::vector<JointController*> controllers;
491 controllers.reserve(controlDevices.
values().size());
492 for (
const ControlDevicePtr& dev : controlDevices.
values())
495 controllers.emplace_back(dev->rtGetJointEmergencyStopController());
504 Devices::_preFinishDeviceInitialization()
507 std::lock_guard<MutexType> guardS{sensorDevicesMutex};
508 std::lock_guard<MutexType> guardC{controlDevicesMutex};
509 if (!sensorDevices.
has(rtThreadTimingsSensorDeviceName))
516 if (getProperty<bool>(
"GlobalPoseCorrectionAndLocalizationSensorEnabled").
getValue())
518 addSensorDevice(std::make_shared<GlobalRobotPoseCorrectionSensorDevice>());
519 addSensorDevice(std::make_shared<GlobalRobotLocalizationSensorDevice>());
524 Devices::_postFinishDeviceInitialization()
528 std::lock_guard<MutexType> guardS{sensorDevicesMutex};
529 std::lock_guard<MutexType> guardC{controlDevicesMutex};
533 for (
const ControlDevicePtr& controlDevice : controlDevices.
values())
536 ARMARX_DEBUG <<
"----" << controlDevice->getDeviceName();
537 if (!controlDevice->hasJointController(ControlModes::EmergencyStop))
540 s <<
"ControlDevice " << controlDevice->getDeviceName()
541 <<
" has no JointController with ControlMode " << ControlModes::EmergencyStop
542 <<
" (to fix this, add a JointController with this ControlMode to the "
543 "ControlDevice).\nAvailable controllers: "
544 << controlDevice->getControlModes();
546 throw LogicError{
s.str()};
548 if (!controlDevice->hasJointController(ControlModes::StopMovement))
551 s <<
"ControlDevice " << controlDevice->getDeviceName()
552 <<
" has no JointController with ControlMode \"" << ControlModes::StopMovement
553 <<
"\" (to fix this, add a JointController with this ControlMode to the "
554 "ControlDevice) \nAvailable controllers: "
555 << controlDevice->getControlModes();
557 throw LogicError{
s.str()};
564 for (
const SensorDevicePtr& sensorDevice : sensorDevices.
values())
567 ARMARX_DEBUG <<
"----" << sensorDevice->getDeviceName();
568 if (!sensorDevice->getSensorValue())
571 s <<
"SensorDevice " << sensorDevice->getSensorValue()
572 <<
" has null SensorValue";
574 throw LogicError{
s.str()};
582 for (
const auto& dev : controlDevices.
values())
584 controlDevicesConstPtr[dev->getDeviceName()] = dev;
586 for (
const auto& dev : sensorDevices.
values())
588 sensorDevicesConstPtr[dev->getDeviceName()] = dev;
595 sensorValues.reserve(sensorDevices.
values().size());
596 for (
const SensorDevicePtr& dev : sensorDevices.
values())
599 sensorValues.emplace_back(dev->getSensorValue());
607 controlTargets.reserve(controlDevices.
values().size());
608 for (
const ControlDevicePtr& dev : controlDevices.
values())
611 controlTargets.emplace_back();
612 controlTargets.back().reserve(dev->rtGetJointControllers().size());
613 for (JointController* ctrl : dev->rtGetJointControllers())
616 controlTargets.back().emplace_back(ctrl->getControlTarget());
621 ARMARX_DEBUG <<
"setup ControlDeviceHardwareControlModeGroups";
628 ARMARX_DEBUG <<
"Remove control devs from ControlDeviceHardwareControlModeGroups ("
629 << ctrlModeGroups.
groups.size() <<
")";
631 for (
const auto& dev : groupsMerged)
633 if (controlDevices.
has(dev))
638 for (
auto& group : ctrlModeGroups.
groups)
642 ARMARX_DEBUG <<
"----removing nonexistent device: " << dev;
645 std::vector<std::set<std::string>> cleanedGroups;
646 cleanedGroups.reserve(ctrlModeGroups.
groups.size());
647 for (
auto& group : ctrlModeGroups.
groups)
649 const auto sz = group.size();
652 ARMARX_DEBUG <<
"----removing group with one dev: " << *group.begin();
656 cleanedGroups.emplace_back(std::move(group));
659 ctrlModeGroups.
groups = cleanedGroups;
665 <<
"Checking control modes for ControlDeviceHardwareControlModeGroups ("
666 << ctrlModeGroups.
groups.size() <<
")";
669 for (std::size_t groupIdx = 0; groupIdx < ctrlModeGroups.
groups.size(); ++groupIdx)
671 const std::set<std::string>& group = ctrlModeGroups.
groups.at(groupIdx);
672 ctrlModeGroups.
deviceIndices.at(groupIdx).reserve(group.size());
674 ARMARX_DEBUG <<
"----Group " << groupIdx <<
" size: " << group.size();
676 const auto getControlModeToHWControlMode = [&](
const std::string& devname)
678 std::map<std::string, std::string> controlModeToHWControlMode;
679 const ControlDevicePtr& cd = controlDevices.
at(devname);
680 for (
const auto& jointCtrl : cd->getJointControllers())
682 controlModeToHWControlMode[jointCtrl->getControlMode()] =
683 jointCtrl->getHardwareControlMode();
685 return controlModeToHWControlMode;
688 const auto controlModeToHWControlMode =
689 getControlModeToHWControlMode(*group.begin());
691 for (
const auto& devname : group)
694 <<
"The ControlDeviceHardwareControlModeGroups property contains "
695 "device names not existent in the robot: "
696 << devname <<
"\navailable:\n"
697 << controlDevices.
keys();
699 const auto controlModeToHWControlModeForDevice =
700 getControlModeToHWControlMode(devname);
702 controlModeToHWControlMode)
703 <<
"Error for control modes of device '" << devname <<
"'\n"
704 <<
"it has the modes: " << controlModeToHWControlModeForDevice
705 <<
"\n but should have the modes: " << controlModeToHWControlMode;
707 const auto devIdx = controlDevices.
index(devname);
708 ctrlModeGroups.
deviceIndices.at(groupIdx).emplace_back(devIdx);
719 ARMARX_DEBUG <<
"create mapping from sensor values to robot nodes";
724 const auto nodes = r->getRobotNodes();
725 for (std::size_t idxRobot = 0; idxRobot < nodes.size(); ++idxRobot)
727 const VirtualRobot::RobotNodePtr& node = nodes.at(idxRobot);
730 const auto& name = node->getName();
731 if (sensorDevices.
has(name))
733 const auto& dev = sensorDevices.
at(name);
734 if (dev->getSensorValue()->isA<SensorValue1DoFActuatorPosition>())
736 SimoxRobotSensorValueMapping m;
737 m.idxRobot = idxRobot;
738 m.idxSens = sensorDevices.
index(name);
739 simoxRobotSensorValueMapping.emplace_back(m);
744 <<
"SensorValue for SensorDevice " << name <<
" is of type "
745 << dev->getSensorValueType()
746 <<
" which does not derive SensorValue1DoFActuatorPosition";
751 ARMARX_INFO <<
"No SensorDevice for RobotNode: " << name;
762 Devices::_preOnInitRobotUnit()
766 const std::string controlDeviceHardwareControlModeGroupsStr =
767 getProperty<std::string>(
"ControlDevices_HardwareControlModeGroups").getValue();
768 if (!controlDeviceHardwareControlModeGroupsStr.empty())
770 const auto numGroups = std::count(controlDeviceHardwareControlModeGroupsStr.begin(),
771 controlDeviceHardwareControlModeGroupsStr.end(),
774 ctrlModeGroups.
groups.reserve(numGroups);
775 std::vector<std::string> strGroups =
776 Split(controlDeviceHardwareControlModeGroupsStr,
";");
777 for (
const auto& gstr : strGroups)
779 bool trimDeviceNames =
true;
780 std::vector<std::string> strElems =
Split(gstr,
",", trimDeviceNames);
781 std::set<std::string> group;
782 for (
auto& device : strElems)
785 <<
"The ControlDeviceHardwareControlModeGroups property contains empty "
788 <<
"The ControlDeviceHardwareControlModeGroups property contains duplicate "
792 group.emplace(std::move(device));
798 for (
const auto& elem : group)
800 out <<
" " << elem <<
"\n";
803 ctrlModeGroups.
groups.emplace_back(std::move(group));