RobotUnitModuleUnits.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package RobotAPI::ArmarXObjects::RobotUnit
17 * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
18 * @date 2018
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
28
44
46{
47 /**
48 * \brief This class allows minimal access to private members of \ref ControlThread in a sane fashion for \ref RobotUnitEmergencyStopMaster.
49 * \warning !! DO NOT ADD ADDITIONAL FRIENDS IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !!
50 */
52 {
54
55 static void
56 SetEmergencyStopStateNoReportToTopic(ControlThread* controlThreadModule,
57 EmergencyStopState state)
58 {
59 controlThreadModule->setEmergencyStopStateNoReportToTopic(state);
60 }
61 };
62} // namespace armarx::RobotUnitModule
63
65{
67 virtual public ManagedIceObject,
68 virtual public EmergencyStopMasterInterface
69 {
70 public:
78
79 void
80 setEmergencyStopState(EmergencyStopState state,
81 const Ice::Current& = Ice::emptyCurrent) final override
82 {
83 EmergencyStopState currentState = getEmergencyStopState();
84
85 const std::unique_lock lock{ss2StateMutex};
86
87 if (currentState == state)
88 {
89 return;
90 }
91
92 currentState = state;
93
94 if (currentState == EmergencyStopState::eEmergencyStopActive)
95 {
97 }
98
99 ControlThreadAttorneyForRobotUnitEmergencyStopMaster::
100 SetEmergencyStopStateNoReportToTopic(controlThreadModule, currentState);
101 emergencyStopTopic->reportEmergencyStopState(currentState);
102 }
103
104 EmergencyStopState
105 trySetEmergencyStopState(EmergencyStopState targetState,
106 const ::Ice::Current&) final override
107 {
108 armarx::core::time::Duration safeDuration =
110
111 // If the SS2 should be released (target state = inactive) we check whether the last
112 // activation happened at least before safeDuration.
113 if (targetState == EmergencyStopState::eEmergencyStopInactive)
114 {
116 {
117 setEmergencyStopState(targetState);
118 }
119 }
120 else
121 {
122 setEmergencyStopState(targetState);
123 }
124
125 return getEmergencyStopState();
126 }
127
128 EmergencyStopState
129 getEmergencyStopState(const Ice::Current& = Ice::emptyCurrent) const final override
130 {
131 const std::shared_lock lock{ss2StateMutex};
132 return controlThreadModule->getEmergencyStopState();
133 }
134
135 protected:
136 void
141
142 void
143 onConnectComponent() final override
144 {
147 setEmergencyStopState(EmergencyStopState::eEmergencyStopInactive);
148 }
149
150 std::string
151 getDefaultName() const final override
152 {
153 return "EmergencyStopMaster";
154 }
155
156 protected:
158 const std::string emergencyStopTopicName;
159 EmergencyStopListenerPrx emergencyStopTopic;
160 mutable std::shared_mutex ss2StateMutex;
162 };
163} // namespace armarx::RobotUnitModule
164
166{
167 Ice::ObjectProxySeq
168 Units::getUnits(const Ice::Current&) const
169 {
170 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
171 std::vector<ManagedIceObjectPtr> unitsCopy;
172 {
173 auto guard = getGuard();
174 //copy to keep lock retention time low
175 unitsCopy = units;
176 }
177 Ice::ObjectProxySeq r;
178 r.reserve(unitsCopy.size());
179 for (const ManagedIceObjectPtr& unit : unitsCopy)
180 {
181 r.emplace_back(unit->getProxy(-1, true));
182 }
183 return r;
184 }
185
186 Ice::ObjectPrx
187 Units::getUnit(const std::string& staticIceId, const Ice::Current&) const
188 {
189 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
190 //no lock required
191 ManagedIceObjectPtr unit = getUnit(staticIceId);
192 if (unit)
193 {
194 return unit->getProxy(-1, true);
195 }
196 return nullptr;
197 }
198
199 const EmergencyStopMasterInterfacePtr&
201 {
202 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
203 return emergencyStopMaster;
204 }
205
206 void
208 {
210 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
211 auto beg = TimeUtil::GetTime(true);
212 {
214 auto guard = getGuard();
215
218 ARMARX_INFO << "initializing default units";
219
222 ARMARX_DEBUG << "Diagnostics unit initialized.";
223
226 ARMARX_DEBUG << "KinematicUnit initialized";
227
229 if (_module<RobotData>().arePlatformAndLocalizationUnitsEnabled())
230 {
231 ARMARX_DEBUG << "initializing LocalizationUnit";
233 ARMARX_DEBUG << "LocalizationUnit initialized";
234 }
235
237 if (_module<RobotData>().arePlatformAndLocalizationUnitsEnabled())
238 {
239 ARMARX_DEBUG << "initializing PlatformUnit";
241 ARMARX_DEBUG << "PlatformUnit initialized";
242 }
243
246 ARMARX_DEBUG << "ForceTorqueUnit initialized";
247
250 ARMARX_DEBUG << "InertialMeasurementUnit initialized";
251
254 ARMARX_DEBUG << "TrajectoryControllerUnit initialized";
255
258 ARMARX_DEBUG << "TcpControllerUnit initialized";
259
261 }
262 ARMARX_INFO << "initializing default units...done! "
263 << (TimeUtil::GetTime(true) - beg).toMicroSeconds() << " us";
264 }
265
266 void
268 {
269 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
270 using UnitT = DiagnosticsSubUnit;
271 using IfaceT = DiagnosticsUnitInterface;
272
273 auto guard = getGuard();
275 // Check if unit is already added.
276 if (getUnit(IfaceT::ice_staticId()))
277 {
278 return;
279 }
280
281 // Check if it is required.
282 std::map<std::string, std::size_t> batteryDevs;
283 for (auto i : getIndices(_module<Devices>().getSensorDevices().keys()))
284 {
285 const SensorDevicePtr& sensorDevice = _module<Devices>().getSensorDevices().at(i);
286 if (sensorDevice->getSensorValue()->isA<SensorValueBattery>())
287 {
288 batteryDevs[sensorDevice->getDeviceName()] = i;
289 }
290 }
291
292 const std::string configName = getProperty<std::string>("DiagnosticsUnitName");
293 const std::string confPre = getConfigDomain() + "." + configName + ".";
294 Ice::PropertiesPtr properties = getIceProperties()->clone();
295
296 // Create and add unit.
298 Component::create<UnitT>(properties, configName, getConfigDomain());
299 unit->setBatteryManagementDevices(batteryDevs);
300 addUnit(std::move(unit));
301 }
302
303 void
305 {
306 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
307 using IfaceT = KinematicUnitInterface;
308
309 auto guard = getGuard();
311 //check if unit is already added
312 if (getUnit(IfaceT::ice_staticId()))
313 {
314 return;
315 }
316 auto unit = createKinematicSubUnit(getIceProperties()->clone());
317 //add
318 if (unit)
319 {
320 addUnit(std::move(unit));
321 }
322 }
323
326 const std::string& positionControlMode,
327 const std::string& velocityControlMode,
328 const std::string& torqueControlMode,
329 const std::string& pwmControlMode)
330 {
332 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
333 /// TODO move init code to Kinematic sub unit
334 using UnitT = KinematicSubUnit;
335
336 //add ctrl et al
337 ARMARX_DEBUG << "createKinematicSubUnit...";
338 std::map<std::string, UnitT::ActuatorData> devs;
339 for (const ControlDevicePtr& controlDevice :
340 _module<Devices>().getControlDevices().values())
341 {
342 ARMARX_CHECK_NOT_NULL(controlDevice);
343 const auto& controlDeviceName = controlDevice->getDeviceName();
344 ARMARX_DEBUG << "looking at device " << controlDeviceName
345 << controlDevice->getJointControllerToTargetTypeNameMap();
346 if (!controlDevice->hasTag(ControlDeviceTags::CreateNoDefaultController))
347 {
348 UnitT::ActuatorData ad;
349 ad.name = controlDeviceName;
350 ARMARX_DEBUG << "has sensor device: "
351 << _module<Devices>().getSensorDevices().has(controlDeviceName);
352 ad.sensorDeviceIndex =
353 _module<Devices>().getSensorDevices().has(controlDeviceName)
354 ? _module<Devices>().getSensorDevices().index(controlDeviceName)
355 : std::numeric_limits<std::size_t>::max();
356
357 const auto init_controller =
358 [&](const std::string& requestedControlMode, auto& ctrl, const auto* tpptr)
359 {
360 auto controlMode = requestedControlMode;
361 using CtargT = std::remove_const_t<std::remove_reference_t<decltype(*tpptr)>>;
362 NJointKinematicUnitPassThroughControllerPtr& pt = ctrl;
363
364 auto testMode = [&](const auto& m)
365 {
366 JointController* jointCtrl = controlDevice->getJointController(m);
367 return jointCtrl && jointCtrl->getControlTarget()->isA<CtargT>();
368 };
369
370 if (!testMode(controlMode))
371 {
372 controlMode = "";
373 //try to find the correct mode (maybe the specified target was derived!
374 //this only works, if exactly one controller provides this mode
375 const JointController* selected_ctrl{nullptr};
376 auto jointControllers = controlDevice->getJointControllers();
377 for (const auto* jointController : jointControllers)
378 {
379 if (jointController->getControlTarget()->isA<CtargT>())
380 {
381 if (selected_ctrl)
382 {
383 selected_ctrl = nullptr;
384 ARMARX_INFO << "Autodetected two controllers supporting "
385 << requestedControlMode << "! autoselection failed";
386 break;
387 }
388 selected_ctrl = jointController;
389 }
390 }
391 if (selected_ctrl)
392 {
393 controlMode = selected_ctrl->getControlMode();
394 ARMARX_INFO << "Autodetected controller with mode " << controlMode
395 << "(the requested mode was " << requestedControlMode
396 << ")";
397 }
398 }
399
400 if (!controlMode.empty())
401 {
402 NJointKinematicUnitPassThroughControllerConfigPtr config =
404 config->controlMode = controlMode;
405 config->deviceName = controlDeviceName;
406 auto ctrl_name = getName() + "_" + "NJointKU_PTCtrl_" + controlDeviceName +
407 "_" + controlMode;
408 std::replace(ctrl_name.begin(), ctrl_name.end(), '.', '_');
409 std::replace(ctrl_name.begin(), ctrl_name.end(), '-', '_');
410 std::replace(ctrl_name.begin(), ctrl_name.end(), ':', '_');
411 const NJointControllerBasePtr& nJointCtrl =
412 _module<ControllerManagement>().createNJointController(
413 "NJointKinematicUnitPassThroughController",
414 ctrl_name,
415 config,
416 false,
417 true);
418 pt = NJointKinematicUnitPassThroughControllerPtr::dynamicCast(nJointCtrl);
420 }
421 };
422 init_controller(
423 positionControlMode, ad.ctrlPos, (ControlTarget1DoFActuatorPosition*)0);
424 init_controller(
425 velocityControlMode, ad.ctrlVel, (ControlTarget1DoFActuatorVelocity*)0);
426 init_controller(torqueControlMode, ad.ctrlTor, (ControlTarget1DoFActuatorTorque*)0);
427 if (!ad.ctrlTor)
428 {
429 init_controller(pwmControlMode, ad.ctrlTor, (ControlTarget1DoFActuatorPWM*)0);
430 }
431
432 if (ad.ctrlPos || ad.ctrlTor || ad.ctrlVel)
433 {
434 ARMARX_DEBUG << "created controllers for " << controlDeviceName
435 << " pos/tor/vel " << ad.ctrlPos.get() << " / " << ad.ctrlTor.get()
436 << " / " << ad.ctrlVel.get();
437 devs[controlDeviceName] = std::move(ad);
438 }
439 }
440 }
441 if (devs.empty())
442 {
443 ARMARX_IMPORTANT << "No joint devices found - skipping adding of KinematicUnit";
444 return nullptr;
445 }
446 ARMARX_IMPORTANT << "Found " << devs.size() << " joint devices - adding KinematicUnit";
447 ARMARX_CHECK_EXPRESSION(!devs.empty())
448 << "no 1DoF ControlDevice found with matching SensorDevice";
449 //add it
450 const std::string configName = getProperty<std::string>("KinematicUnitName");
451 const std::string confPre = getConfigDomain() + "." + configName + ".";
452 //properties->setProperty(confPre + "MinimumLoggingLevel", getProperty<std::string>("MinimumLoggingLevel").getValue());
453 //fill properties
454 properties->setProperty(confPre + "RobotNodeSetName",
455 _module<RobotData>().getRobotNodetSeName());
456 properties->setProperty(confPre + "RobotFileName", _module<RobotData>().getRobotFileName());
457 properties->setProperty(confPre + "RobotFileNameProject",
458 _module<RobotData>().getRobotProjectName());
459 properties->setProperty(confPre + "TopicPrefix",
460 getProperty<std::string>("KinematicUnitNameTopicPrefix"));
461
462 ARMARX_DEBUG << "creating unit " << configName
463 << " using these properties: " << properties->getPropertiesForPrefix("");
465 Component::create<UnitT>(properties, configName, getConfigDomain());
466
467 //fill devices (sensor + controller)
468 unit->setupData(getProperty<std::string>("RobotFileName").getValue(),
469 _module<RobotData>().cloneRobot(),
470 std::move(devs),
471 _module<Devices>().getControlModeGroups().groups,
472 _module<Devices>().getControlModeGroups().groupsMerged,
473 dynamic_cast<RobotUnit*>(this));
474 return unit;
475 }
476
477 void
479 {
480 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
481 using UnitT = PlatformSubUnit;
482 using IfaceT = PlatformUnitInterface;
483
485
486 auto guard = getGuard();
488 //check if unit is already added
489 if (getUnit(IfaceT::ice_staticId()))
490 {
491 return;
492 }
494 //is there a platform dev?
495 if (_module<RobotData>().getRobotPlatformName().empty())
496 {
497 ARMARX_INFO << "no platform unit created since no platform name was given";
498 return;
499 }
501 if (!_module<Devices>().getControlDevices().has(
502 _module<RobotData>().getRobotPlatformName()))
503 {
505 << "no platform unit created since the platform control device with name '"
506 << _module<RobotData>().getRobotPlatformName() << "' was not found";
507 return;
508 }
510 const ControlDevicePtr& controlDevice =
511 _module<Devices>().getControlDevices().at(_module<RobotData>().getRobotPlatformName());
512 const SensorDevicePtr& sensorDevice =
513 _module<Devices>().getSensorDevices().at(_module<RobotData>().getRobotPlatformName());
514 JointController* jointVel =
515 controlDevice->getJointController(ControlModes::HolonomicPlatformVelocity);
517 ARMARX_CHECK_EXPRESSION(jointVel);
519 sensorDevice->getSensorValue()->asA<SensorValueHolonomicPlatform>());
520 //add it
522 const std::string configName = getProperty<std::string>("PlatformUnitName");
523 const std::string confPre = getConfigDomain() + "." + configName + ".";
524 Ice::PropertiesPtr properties = getIceProperties()->clone();
525 //properties->setProperty(confPre + "MinimumLoggingLevel", getProperty<std::string>("MinimumLoggingLevel").getValue());
526 //fill properties
527 properties->setProperty(confPre + "PlatformName",
528 _module<RobotData>().getRobotPlatformInstanceName());
529 ARMARX_DEBUG << "creating unit " << configName
530 << " using these properties: " << properties->getPropertiesForPrefix("");
533 Component::create<UnitT>(properties, configName, getConfigDomain());
534 //config
536 const NJointHolonomicPlatformVelocityControllerTypes platformControllerType =
538 "PlatformUnitVelocityControllerType");
539 if (platformControllerType ==
541 {
542 NJointHolonomicPlatformUnitVelocityPassThroughControllerConfigPtr config =
544 config->initialVelocityX = 0;
545 config->initialVelocityY = 0;
546 config->initialVelocityRotation = 0;
547 config->platformName = _module<RobotData>().getRobotPlatformName();
548
549 auto ctrl = NJointHolonomicPlatformUnitVelocityPassThroughControllerPtr::dynamicCast(
550 _module<ControllerManagement>().createNJointController(
551 "NJointHolonomicPlatformUnitVelocityPassThroughController",
552 getName() + "_" + configName + "_VelPTContoller",
553 config,
554 false,
555 true));
558 unit->pt = ctrl;
560 }
561 else if (platformControllerType ==
563 {
564 NJointHolonomicPlatformVelocityControllerWithRampConfigPtr config =
566 config->platformName = _module<RobotData>().getRobotPlatformName();
567
568 config->maxPositionAcceleration =
569 getProperty<float>("PlatformUnitMaximumPositionAcceleration");
570 config->maxOrientationAcceleration =
571 getProperty<float>("PlatformUnitMaximumOrientationAcceleration");
572
573 auto ctrl = NJointHolonomicPlatformVelocityControllerWithRampPtr::dynamicCast(
574 _module<ControllerManagement>().createNJointController(
575 "NJointHolonomicPlatformVelocityControllerWithRamp",
576 getName() + "_" + configName + "_VelPTContoller",
577 config,
578 false,
579 true));
582 unit->pt = ctrl;
584 }
585 else
586 {
587 ARMARX_ERROR << "Invalid Platform velocity controller specified '"
589 platformControllerType)
590 << "'";
591 }
592
593 NJointHolonomicPlatformRelativePositionControllerConfigPtr configRelativePositionCtrlCfg =
595 configRelativePositionCtrlCfg->platformName = _module<RobotData>().getRobotPlatformName();
596 auto ctrlRelativePosition =
597 NJointHolonomicPlatformRelativePositionControllerPtr::dynamicCast(
598 _module<ControllerManagement>().createNJointController(
599 "NJointHolonomicPlatformRelativePositionController",
600 getName() + "_" + configName + "_RelativePositionContoller",
601 configRelativePositionCtrlCfg,
602 false,
603 true));
604 ARMARX_CHECK_EXPRESSION(ctrlRelativePosition);
605 unit->relativePosCtrl = ctrlRelativePosition;
606
607 // unit->platformSensorIndex = _module<Devices>().getSensorDevices().index(_module<RobotData>().getRobotPlatformName());
608
609 NJointHolonomicPlatformGlobalPositionControllerConfigPtr configGlobalPositionCtrlCfg =
611 configGlobalPositionCtrlCfg->platformName = _module<RobotData>().getRobotPlatformName();
612 auto ctrlGlobalPosition = NJointHolonomicPlatformGlobalPositionControllerPtr::dynamicCast(
613 _module<ControllerManagement>().createNJointController(
614 "NJointHolonomicPlatformGlobalPositionController",
615 getName() + "_" + configName + "_GlobalPositionContoller",
616 configGlobalPositionCtrlCfg,
617 false,
618 true));
620 ARMARX_CHECK_EXPRESSION(ctrlGlobalPosition);
621 unit->globalPosCtrl = ctrlGlobalPosition;
623
624 unit->platformSensorIndex = _module<Devices>().getSensorDevices().index(
625 _module<RobotData>().getRobotPlatformName());
626 //add
627 addUnit(std::move(unit));
628 }
629
630 void
632 {
634 ARMARX_DEBUG << "initializeLocalizationUnit";
635
636 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
637 using UnitT = LocalizationSubUnit;
638 using IfaceT = LocalizationUnitInterface;
639
641 auto guard = getGuard();
643 //check if unit is already added
644 if (getUnit(IfaceT::ice_staticId()))
645 {
646 return;
647 }
649
650 if (_module<Devices>().getSensorDevices().count(
651 _module<RobotData>().getRobotPlatformName()) == 0)
652 {
653 ARMARX_WARNING << "No sensor devices found for robot platform `"
654 << _module<RobotData>().getRobotPlatformName() << "`.";
655 return;
656 }
657
658 ARMARX_DEBUG << "Getting device SensorValueHolonomicPlatformRelativePosition";
660 _module<Devices>().getSensorDevices().has(_module<RobotData>().getRobotPlatformName()))
661 << _module<RobotData>().getRobotPlatformName();
662 const SensorDevicePtr& sensorDeviceRelativePosition =
663 _module<Devices>().getSensorDevices().at(_module<RobotData>().getRobotPlatformName());
664 ARMARX_CHECK_EXPRESSION(sensorDeviceRelativePosition->getSensorValue()
666
668 // const SensorDevicePtr& sensorDevicePoseCorrection = _module<Devices>().getSensorDevices().at(GlobalRobotPoseCorrectionSensorDevice::DeviceName());
669 // ARMARX_CHECK_EXPRESSION(sensorDeviceRelativePosition->getSensorValue()->asA<SensorValueGlobalPoseCorrection>());
670
671
672 //add it
673 const std::string configName = "LocalizationUnit";
674 const std::string confPre = getConfigDomain() + "." + configName + ".";
675 Ice::PropertiesPtr properties = getIceProperties()->clone();
676 //properties->setProperty(confPre + "MinimumLoggingLevel", getProperty<std::string>("MinimumLoggingLevel").getValue());
677 //fill properties
678 // properties->setProperty(confPre + "PlatformName", _module<RobotData>().getRobotPlatformInstanceName());
679 ARMARX_DEBUG << "creating unit " << configName
680 << " using these properties: " << properties->getPropertiesForPrefix("");
682 Component::create<UnitT>(properties, configName, getConfigDomain());
683 //config
684
685 ARMARX_DEBUG << "Setting device GlobalRobotPoseCorrectionSensorDevice";
686 unit->globalPositionCorrectionSensorDevice =
687 dynamic_cast<decltype(unit->globalPositionCorrectionSensorDevice)>(
689 .getSensorDevices()
691 .get());
692
693
694 const SensorDevicePtr& sensorDeviceGlobalRobotLocalization =
695 _module<Devices>().getSensorDevices().at(
697 ARMARX_CHECK_EXPRESSION(sensorDeviceGlobalRobotLocalization->getSensorValue()
699
700 dynamic_cast<GlobalRobotLocalizationSensorDevice&>(*sensorDeviceGlobalRobotLocalization)
701 .sensorRelativePosition = sensorDeviceRelativePosition->getSensorValue()
703 dynamic_cast<GlobalRobotLocalizationSensorDevice&>(*sensorDeviceGlobalRobotLocalization)
705 unit->globalPositionCorrectionSensorDevice->getSensorValue()
707
708 //add
709 addUnit(unit);
710 }
711
712 void
714 {
715 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
716 using UnitT = ForceTorqueSubUnit;
717 using IfaceT = ForceTorqueUnitInterface;
718
719 auto guard = getGuard();
721 //check if unit is already added
722 if (getUnit(IfaceT::ice_staticId()))
723 {
724 return;
725 }
726 //check if it is required
727 std::vector<ForceTorqueSubUnit::DeviceData> ftdevs;
728 for (const SensorDevicePtr& ftSensorDevice : _module<Devices>().getSensorDevices().values())
729 {
730 if (ftSensorDevice->getSensorValue()->isA<SensorValueForceTorque>())
731 {
733 ftSensorData.sensorIndex =
734 _module<Devices>().getSensorDevices().index(ftSensorDevice->getDeviceName());
735 ftSensorData.deviceName = ftSensorDevice->getDeviceName();
736 ftSensorData.frame = ftSensorDevice->getReportingFrame();
737 ARMARX_CHECK_EXPRESSION(!ftSensorData.frame.empty())
738 << "The sensor device '" << ftSensorData.deviceName
739 << "' (index: " << ftSensorData.sensorIndex
740 << ") reports force torque values but returns an empty string as reporting "
741 "frame";
742 ARMARX_CHECK_EXPRESSION(unitCreateRobot->hasRobotNode(ftSensorData.frame))
743 << "The sensor device '" << ftSensorData.deviceName
744 << "' (index: " << ftSensorData.sensorIndex
745 << ") reports force torque values but returns a reporting frame '"
746 << ftSensorData.frame << "' which is not present in the robot '"
747 << _module<RobotData>().getRobotName() << "'";
748 ftdevs.emplace_back(std::move(ftSensorData));
749 }
750 }
751 if (ftdevs.empty())
752 {
754 << "no force torque unit created since there are no force torque sensor devices";
755 return;
756 }
757 //add it
758 const std::string configName = getProperty<std::string>("ForceTorqueUnitName");
759 const std::string confPre = getConfigDomain() + "." + configName + ".";
760 Ice::PropertiesPtr properties = getIceProperties()->clone();
761 //properties->setProperty(confPre + "MinimumLoggingLevel", getProperty<std::string>("MinimumLoggingLevel").getValue());
762 //fill properties
763 properties->setProperty(confPre + "AgentName", _module<RobotData>().getRobotName());
764 properties->setProperty(confPre + "ForceTorqueTopicName",
765 getProperty<std::string>("ForceTorqueTopicName").getValue());
766 ARMARX_DEBUG << "creating unit " << configName
767 << " using these properties: " << properties->getPropertiesForPrefix("");
769 Component::create<UnitT>(properties, configName, getConfigDomain());
770 unit->devs = ftdevs;
771 //add
772 addUnit(std::move(unit));
773 }
774
775 void
777 {
778 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
779 using UnitT = InertialMeasurementSubUnit;
780 using IfaceT = InertialMeasurementUnitInterface;
781
782 auto guard = getGuard();
784 //check if unit is already added
785 if (getUnit(IfaceT::ice_staticId()))
786 {
787 return;
788 }
789 //check if it is required
790 std::map<std::string, std::size_t> imudevs;
791 for (auto i : getIndices(_module<Devices>().getSensorDevices().keys()))
792 {
793 const SensorDevicePtr& sensorDevice = _module<Devices>().getSensorDevices().at(i);
794 if (sensorDevice->getSensorValue()->isA<SensorValueIMU>())
795 {
796 imudevs[sensorDevice->getDeviceName()] = i;
797 }
798 }
799 if (imudevs.empty())
800 {
802 << "no inertial measurement unit created since there are no imu sensor devices";
803 return;
804 }
805 //add it
806 const std::string configName = getProperty<std::string>("InertialMeasurementUnitName");
807 const std::string confPre = getConfigDomain() + "." + configName + ".";
808 Ice::PropertiesPtr properties = getIceProperties()->clone();
809 //properties->setProperty(confPre + "MinimumLoggingLevel", getProperty<std::string>("MinimumLoggingLevel").getValue());
810 //fill properties
811 properties->setProperty(confPre + "IMUTopicName",
812 getProperty<std::string>("IMUTopicName").getValue());
814 Component::create<UnitT>(properties, configName, getConfigDomain());
815 unit->devs = imudevs;
816 //add
817 addUnit(std::move(unit));
818 }
819
820 void
822 {
823 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
824 auto guard = getGuard();
826 using UnitT = TrajectoryControllerSubUnit;
827 if (!getProperty<bool>("CreateTrajectoryPlayer").getValue())
828 {
829 return;
830 }
831
832 //check if unit is already added
833 if (getUnit(UnitT::ice_staticId()) || !trajectoryControllerSubUnit)
834 {
835 return;
836 }
837 (TrajectoryControllerSubUnitPtr::dynamicCast(trajectoryControllerSubUnit))
838 ->setup(_modulePtr<RobotUnit>());
839 addUnit(trajectoryControllerSubUnit);
840 trajectoryControllerSubUnit = nullptr;
841 }
842
843 void
845 {
846 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
847 auto guard = getGuard();
849
850 if (!getProperty<bool>("CreateTCPControlUnit").getValue())
851 {
852 return;
853 }
854 using UnitT = TCPControllerSubUnit;
855
856 //check if unit is already added
857 if (getUnit(UnitT::ice_staticId()))
858 {
859 return;
860 }
861 (TCPControllerSubUnitPtr::dynamicCast(tcpControllerSubUnit))
862 ->setup(_modulePtr<RobotUnit>(), _module<RobotData>().cloneRobot());
863 addUnit(tcpControllerSubUnit);
864 tcpControllerSubUnit = nullptr;
865 }
866
867 void
869 {
870 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
872 auto guard = getGuard();
874 getArmarXManager()->addObjectAsync(unit, "", true, false);
875 //maybe add it to the sub units
876 RobotUnitSubUnitPtr rsu = RobotUnitSubUnitPtr::dynamicCast(unit);
877 if (rsu)
878 {
879 subUnits.emplace_back(std::move(rsu));
880 }
881 units.emplace_back(std::move(unit));
882 }
883
884 void
885 Units::_icePropertiesInitialized()
886 {
887 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
888 Ice::PropertiesPtr properties = getIceProperties()->clone();
889 const std::string& configDomain = "ArmarX";
890 // create TCPControlSubUnit
891
892 {
893 const std::string configNameTCPControlUnit =
894 getProperty<std::string>("TCPControlUnitName");
896 properties, configNameTCPControlUnit, configDomain);
897 addPropertyUser(PropertyUserPtr::dynamicCast(tcpControllerSubUnit));
898 }
899
900 // create TrajectoryControllerSubUnit
901
902 {
903 const std::string configNameTrajectoryControllerUnit =
904 getProperty<std::string>("TrajectoryControllerUnitName");
905 const std::string confPre =
906 configDomain + "." + configNameTrajectoryControllerUnit + ".";
907 properties->setProperty(confPre + "KinematicUnitName",
908 getProperty<std::string>("KinematicUnitName").getValue());
909 trajectoryControllerSubUnit =
911 properties, configNameTrajectoryControllerUnit, configDomain);
912 addPropertyUser(PropertyUserPtr::dynamicCast(trajectoryControllerSubUnit));
913 }
914 }
915
916 void
917 Units::_preFinishRunning()
918 {
919 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
920 //remove all units
921 subUnits.clear();
922 for (ManagedIceObjectPtr& unit : units)
923 {
924 getArmarXManager()->removeObjectBlocking(unit->getName());
925 }
926 units.clear();
927 }
928
929 void
930 Units::_preOnInitRobotUnit()
931 {
932 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
933 unitCreateRobot = _module<RobotData>().cloneRobot();
934 ARMARX_DEBUG << "add emergency stop master";
935 {
936 emergencyStopMaster = new RobotUnitEmergencyStopMaster{
938 getProperty<std::string>("EmergencyStopTopic").getValue()};
939 ManagedIceObjectPtr obj = ManagedIceObjectPtr::dynamicCast(emergencyStopMaster);
940 ARMARX_CHECK_EXPRESSION(obj) << "RobotUnitEmergencyStopMaster";
941 getArmarXManager()->addObject(
942 obj, getProperty<std::string>("EmergencyStopMasterName").getValue(), true);
943 auto prx = obj->getProxy(-1);
944 try
945 {
946 getArmarXManager()->getIceManager()->getIceGridSession()->getAdmin()->addObject(
947 prx);
948 }
949 catch (const IceGrid::ObjectExistsException&)
950 {
951 getArmarXManager()->getIceManager()->getIceGridSession()->getAdmin()->updateObject(
952 prx);
953 }
954 catch (std::exception& e)
955 {
956 ARMARX_WARNING << "add the robot unit as emergency stop master to the ice grid "
957 "admin!\nThere was an exception:\n"
958 << e.what();
959 }
960 }
961 ARMARX_DEBUG << "add emergency stop master...done!";
962 }
963
964 void
965 Units::_postOnExitRobotUnit()
966 {
967 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
968 ARMARX_DEBUG << "remove EmergencyStopMaster";
969 try
970 {
971 getArmarXManager()->removeObjectBlocking(
972 ManagedIceObjectPtr::dynamicCast(emergencyStopMaster));
973 getArmarXManager()->getIceManager()->removeObject(
974 getProperty<std::string>("EmergencyStopMasterName").getValue());
975 }
976 catch (...)
977 {
978 }
979 ARMARX_DEBUG << "remove EmergencyStopMaster...done!";
980 }
981
983 Units::getUnit(const std::string& staticIceId) const
984 {
985 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
986 auto guard = getGuard();
987 for (const ManagedIceObjectPtr& unit : units)
988 {
989 if (unit->ice_isA(staticIceId))
990 {
991 return unit;
992 }
993 }
995 }
996} // namespace armarx::RobotUnitModule
static TPtr create(Ice::PropertiesPtr properties=Ice::createProperties(), const std::string &configName="", const std::string &configDomain="ArmarX")
Factory method for a component.
Definition Component.h:116
std::string getConfigDomain()
Retrieve config domain for this component as set in constructor.
Definition Component.cpp:76
void addPropertyUser(const PropertyUserPtr &subPropertyUser)
Add additional property users here that should show up in the application help text.
Property< PropertyType > getProperty(const std::string &name)
const SensorValueGlobalPoseCorrection * sensorGlobalPositionCorrection
const SensorValueHolonomicPlatformRelativePosition * sensorRelativePosition
The JointController class represents one joint in one control mode.
virtual ControlTargetBase * getControlTarget()=0
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.
static const ManagedIceObjectPtr NullPtr
A nullptr to be used when a const ref to a nullptr is required.
ManagedIceObject(ManagedIceObject const &other)
std::string getName() const
Retrieve name of object.
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Ice::PropertiesPtr getIceProperties() const
Returns the set of Ice properties.
Property< PropertyType > getProperty(const std::string &name)
Property creation and retrieval.
This class allows minimal access to private members of ControlThread in a sane fashion for RobotUnitE...
This Module manages the ControlThread.
T & _module()
Returns this as ref to the given type.
GuardType getGuard() const
Returns a guard to the RobotUnits mutex.
void throwIfInControlThread(const std::string &fnc) const
Throws if the current thread is the ControlThread.
void throwIfStateIsNot(const std::set< RobotUnitState > &stateSet, const std::string &fnc, bool onlyWarn=false) const
Throws an exception if the current state is not in.
T * _modulePtr()
Returns this as ptr to the given type.
void onConnectComponent() final override
Pure virtual hook for the subclass.
std::string getDefaultName() const final override
Retrieve default name of component.
EmergencyStopState getEmergencyStopState(const Ice::Current &=Ice::emptyCurrent) const final override
RobotUnitEmergencyStopMaster(ControlThread *controlThreadModule, std::string emergencyStopTopicName)
void setEmergencyStopState(EmergencyStopState state, const Ice::Current &=Ice::emptyCurrent) final override
void onInitComponent() final override
Pure virtual hook for the subclass.
EmergencyStopState trySetEmergencyStopState(EmergencyStopState targetState, const ::Ice::Current &) final override
virtual void initializeForceTorqueUnit()
Initializes the ForceTorqueUnit.
T::PointerType getUnit() const
Returns a pointer to the Unit for the given type (or null if there is none)
virtual void initializeTrajectoryControllerUnit()
Initializes the TrajectoryControllerUnit.
void addUnit(ManagedIceObjectPtr unit)
Registers a unit for management (the Unit is added and removed to the ArmarXManager and updated with ...
virtual void initializeDiagnosticsUnit()
Initialize the diagnostics unit.
virtual void initializeTcpControllerUnit()
Initializes the TcpControllerUnit.
virtual void initializeInertialMeasurementUnit()
Initializes the InertialMeasurementUnit.
virtual void initializePlatformUnit()
Initializes the PlatformUnit.
virtual void initializeLocalizationUnit()
Initializes the TcpControllerUnit.
virtual void initializeDefaultUnits()
Calls all init hooks for all managed Units.
ManagedIceObjectPtr createKinematicSubUnit(const Ice::PropertiesPtr &properties, const std::string &positionControlMode=ControlModes::Position1DoF, const std::string &velocityControlMode=ControlModes::Velocity1DoF, const std::string &torqueControlMode=ControlModes::Torque1DoF, const std::string &pwmControlMode=ControlModes::PWM1DoF)
Create the KinematicUnit (this function should be called in initializeKinematicUnit)
Ice::ObjectProxySeq getUnits(const Ice::Current &) const override
Returns proxies to all units.
virtual void initializeKinematicUnit()
Initializes the KinematicUnit.
const EmergencyStopMasterInterfacePtr & getEmergencyStopMaster() const
Returns a pointer to the EmergencyStopMaster.
The RobotUnit class manages a robot and its controllers.
Definition RobotUnit.h:192
const T * asA() const
The pose correction to obtain the robot's global pose.
The robot's position relative to its initial pose when starting the robot unit based on odometry info...
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition TimeUtil.cpp:42
Represents a point in time.
Definition DateTime.h:25
static DateTime Now()
Definition DateTime.cpp:51
Represents a duration.
Definition Duration.h:17
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#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_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#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
::IceInternal::Handle<::Ice::Properties > PropertiesPtr
T getValue(nlohmann::json &userConfig, nlohmann::json &defaultConfig, const std::string &entryName)
Definition utils.h:80
std::vector< KeyT > getIndices(const std::map< KeyT, ValT > &c)
Definition algorithm.h:307
const simox::meta::EnumNames< NJointHolonomicPlatformVelocityControllerTypes > NJointHolonomicPlatformVelocityControllerTypesNames
IceInternal::Handle< ManagedIceObject > ManagedIceObjectPtr
Definition ArmarXFwd.h:42
#define ARMARX_TRACE
Definition trace.h:77