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 addSensorDevice(std::make_shared<GlobalRobotPoseCorrectionSensorDevice>());
517 addSensorDevice(std::make_shared<GlobalRobotLocalizationSensorDevice>());
521 Devices::_postFinishDeviceInitialization()
525 std::lock_guard<MutexType> guardS{sensorDevicesMutex};
526 std::lock_guard<MutexType> guardC{controlDevicesMutex};
530 for (
const ControlDevicePtr& controlDevice : controlDevices.
values())
533 ARMARX_DEBUG <<
"----" << controlDevice->getDeviceName();
534 if (!controlDevice->hasJointController(ControlModes::EmergencyStop))
537 s <<
"ControlDevice " << controlDevice->getDeviceName()
538 <<
" has no JointController with ControlMode " << ControlModes::EmergencyStop
539 <<
" (to fix this, add a JointController with this ControlMode to the "
540 "ControlDevice).\nAvailable controllers: "
541 << controlDevice->getControlModes();
543 throw LogicError{
s.str()};
545 if (!controlDevice->hasJointController(ControlModes::StopMovement))
548 s <<
"ControlDevice " << controlDevice->getDeviceName()
549 <<
" has no JointController with ControlMode \"" << ControlModes::StopMovement
550 <<
"\" (to fix this, add a JointController with this ControlMode to the "
551 "ControlDevice) \nAvailable controllers: "
552 << controlDevice->getControlModes();
554 throw LogicError{
s.str()};
561 for (
const SensorDevicePtr& sensorDevice : sensorDevices.
values())
564 ARMARX_DEBUG <<
"----" << sensorDevice->getDeviceName();
565 if (!sensorDevice->getSensorValue())
568 s <<
"SensorDevice " << sensorDevice->getSensorValue()
569 <<
" has null SensorValue";
571 throw LogicError{
s.str()};
579 for (
const auto& dev : controlDevices.
values())
581 controlDevicesConstPtr[dev->getDeviceName()] = dev;
583 for (
const auto& dev : sensorDevices.
values())
585 sensorDevicesConstPtr[dev->getDeviceName()] = dev;
592 sensorValues.reserve(sensorDevices.
values().size());
593 for (
const SensorDevicePtr& dev : sensorDevices.
values())
596 sensorValues.emplace_back(dev->getSensorValue());
604 controlTargets.reserve(controlDevices.
values().size());
605 for (
const ControlDevicePtr& dev : controlDevices.
values())
608 controlTargets.emplace_back();
609 controlTargets.back().reserve(dev->rtGetJointControllers().size());
610 for (JointController* ctrl : dev->rtGetJointControllers())
613 controlTargets.back().emplace_back(ctrl->getControlTarget());
618 ARMARX_DEBUG <<
"setup ControlDeviceHardwareControlModeGroups";
625 ARMARX_DEBUG <<
"Remove control devs from ControlDeviceHardwareControlModeGroups ("
626 << ctrlModeGroups.
groups.size() <<
")";
628 for (
const auto& dev : groupsMerged)
630 if (controlDevices.
has(dev))
635 for (
auto& group : ctrlModeGroups.
groups)
639 ARMARX_DEBUG <<
"----removing nonexistent device: " << dev;
642 std::vector<std::set<std::string>> cleanedGroups;
643 cleanedGroups.reserve(ctrlModeGroups.
groups.size());
644 for (
auto& group : ctrlModeGroups.
groups)
646 const auto sz = group.size();
649 ARMARX_DEBUG <<
"----removing group with one dev: " << *group.begin();
653 cleanedGroups.emplace_back(std::move(group));
656 ctrlModeGroups.
groups = cleanedGroups;
662 <<
"Checking control modes for ControlDeviceHardwareControlModeGroups ("
663 << ctrlModeGroups.
groups.size() <<
")";
666 for (std::size_t groupIdx = 0; groupIdx < ctrlModeGroups.
groups.size(); ++groupIdx)
668 const std::set<std::string>& group = ctrlModeGroups.
groups.at(groupIdx);
669 ctrlModeGroups.
deviceIndices.at(groupIdx).reserve(group.size());
671 ARMARX_DEBUG <<
"----Group " << groupIdx <<
" size: " << group.size();
673 const auto getControlModeToHWControlMode = [&](
const std::string& devname)
675 std::map<std::string, std::string> controlModeToHWControlMode;
676 const ControlDevicePtr& cd = controlDevices.
at(devname);
677 for (
const auto& jointCtrl : cd->getJointControllers())
679 controlModeToHWControlMode[jointCtrl->getControlMode()] =
680 jointCtrl->getHardwareControlMode();
682 return controlModeToHWControlMode;
685 const auto controlModeToHWControlMode =
686 getControlModeToHWControlMode(*group.begin());
688 for (
const auto& devname : group)
691 <<
"The ControlDeviceHardwareControlModeGroups property contains "
692 "device names not existent in the robot: "
693 << devname <<
"\navailable:\n"
694 << controlDevices.
keys();
696 const auto controlModeToHWControlModeForDevice =
697 getControlModeToHWControlMode(devname);
699 controlModeToHWControlMode)
700 <<
"Error for control modes of device '" << devname <<
"'\n"
701 <<
"it has the modes: " << controlModeToHWControlModeForDevice
702 <<
"\n but should have the modes: " << controlModeToHWControlMode;
704 const auto devIdx = controlDevices.
index(devname);
705 ctrlModeGroups.
deviceIndices.at(groupIdx).emplace_back(devIdx);
716 ARMARX_DEBUG <<
"create mapping from sensor values to robot nodes";
721 const auto nodes = r->getRobotNodes();
722 for (std::size_t idxRobot = 0; idxRobot < nodes.size(); ++idxRobot)
724 const VirtualRobot::RobotNodePtr& node = nodes.at(idxRobot);
727 const auto& name = node->getName();
728 if (sensorDevices.
has(name))
730 const auto& dev = sensorDevices.
at(name);
731 if (dev->getSensorValue()->isA<SensorValue1DoFActuatorPosition>())
733 SimoxRobotSensorValueMapping m;
734 m.idxRobot = idxRobot;
735 m.idxSens = sensorDevices.
index(name);
736 simoxRobotSensorValueMapping.emplace_back(m);
741 <<
"SensorValue for SensorDevice " << name <<
" is of type "
742 << dev->getSensorValueType()
743 <<
" which does not derive SensorValue1DoFActuatorPosition";
748 ARMARX_INFO <<
"No SensorDevice for RobotNode: " << name;
759 Devices::_preOnInitRobotUnit()
763 const std::string controlDeviceHardwareControlModeGroupsStr =
764 getProperty<std::string>(
"ControlDevices_HardwareControlModeGroups").getValue();
765 if (!controlDeviceHardwareControlModeGroupsStr.empty())
767 const auto numGroups = std::count(controlDeviceHardwareControlModeGroupsStr.begin(),
768 controlDeviceHardwareControlModeGroupsStr.end(),
771 ctrlModeGroups.
groups.reserve(numGroups);
772 std::vector<std::string> strGroups =
773 Split(controlDeviceHardwareControlModeGroupsStr,
";");
774 for (
const auto& gstr : strGroups)
776 bool trimDeviceNames =
true;
777 std::vector<std::string> strElems =
Split(gstr,
",", trimDeviceNames);
778 std::set<std::string> group;
779 for (
auto& device : strElems)
782 <<
"The ControlDeviceHardwareControlModeGroups property contains empty "
785 <<
"The ControlDeviceHardwareControlModeGroups property contains duplicate "
789 group.emplace(std::move(device));
795 for (
const auto& elem : group)
797 out <<
" " << elem <<
"\n";
800 ctrlModeGroups.
groups.emplace_back(std::move(group));