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 and
115 {
116 setEmergencyStopState(targetState);
117 }
118
119 return getEmergencyStopState();
120 }
121
122 EmergencyStopState
123 getEmergencyStopState(const Ice::Current& = Ice::emptyCurrent) const final override
124 {
125 const std::shared_lock lock{ss2StateMutex};
126 return controlThreadModule->getEmergencyStopState();
127 }
128
129 protected:
130 void
135
136 void
137 onConnectComponent() final override
138 {
141 setEmergencyStopState(EmergencyStopState::eEmergencyStopInactive);
142 }
143
144 std::string
145 getDefaultName() const final override
146 {
147 return "EmergencyStopMaster";
148 }
149
150 protected:
152 const std::string emergencyStopTopicName;
153 EmergencyStopListenerPrx emergencyStopTopic;
154 mutable std::shared_mutex ss2StateMutex;
156 };
157} // namespace armarx::RobotUnitModule
158
160{
161 Ice::ObjectProxySeq
162 Units::getUnits(const Ice::Current&) const
163 {
164 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
165 std::vector<ManagedIceObjectPtr> unitsCopy;
166 {
167 auto guard = getGuard();
168 //copy to keep lock retention time low
169 unitsCopy = units;
170 }
171 Ice::ObjectProxySeq r;
172 r.reserve(unitsCopy.size());
173 for (const ManagedIceObjectPtr& unit : unitsCopy)
174 {
175 r.emplace_back(unit->getProxy(-1, true));
176 }
177 return r;
178 }
179
180 Ice::ObjectPrx
181 Units::getUnit(const std::string& staticIceId, const Ice::Current&) const
182 {
183 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
184 //no lock required
185 ManagedIceObjectPtr unit = getUnit(staticIceId);
186 if (unit)
187 {
188 return unit->getProxy(-1, true);
189 }
190 return nullptr;
191 }
192
193 const EmergencyStopMasterInterfacePtr&
195 {
196 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
197 return emergencyStopMaster;
198 }
199
200 void
202 {
204 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
205 auto beg = TimeUtil::GetTime(true);
206 {
208 auto guard = getGuard();
209
212 ARMARX_INFO << "initializing default units";
213
216 ARMARX_DEBUG << "Diagnostics unit initialized.";
217
220 ARMARX_DEBUG << "KinematicUnit initialized";
221
223 if (_module<RobotData>().arePlatformAndLocalizationUnitsEnabled())
224 {
225 ARMARX_DEBUG << "initializing LocalizationUnit";
227 ARMARX_DEBUG << "LocalizationUnit initialized";
228 }
229
231 if (_module<RobotData>().arePlatformAndLocalizationUnitsEnabled())
232 {
233 ARMARX_DEBUG << "initializing PlatformUnit";
235 ARMARX_DEBUG << "PlatformUnit initialized";
236 }
237
240 ARMARX_DEBUG << "ForceTorqueUnit initialized";
241
244 ARMARX_DEBUG << "InertialMeasurementUnit initialized";
245
248 ARMARX_DEBUG << "TrajectoryControllerUnit initialized";
249
252 ARMARX_DEBUG << "TcpControllerUnit initialized";
253
255 }
256 ARMARX_INFO << "initializing default units...done! "
257 << (TimeUtil::GetTime(true) - beg).toMicroSeconds() << " us";
258 }
259
260 void
262 {
263 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
264 using UnitT = DiagnosticsSubUnit;
265 using IfaceT = DiagnosticsUnitInterface;
266
267 auto guard = getGuard();
269 // Check if unit is already added.
270 if (getUnit(IfaceT::ice_staticId()))
271 {
272 return;
273 }
274
275 // Check if it is required.
276 std::map<std::string, std::size_t> batteryDevs;
277 for (auto i : getIndices(_module<Devices>().getSensorDevices().keys()))
278 {
279 const SensorDevicePtr& sensorDevice = _module<Devices>().getSensorDevices().at(i);
280 if (sensorDevice->getSensorValue()->isA<SensorValueBattery>())
281 {
282 batteryDevs[sensorDevice->getDeviceName()] = i;
283 }
284 }
285
286 const std::string configName = getProperty<std::string>("DiagnosticsUnitName");
287 const std::string confPre = getConfigDomain() + "." + configName + ".";
288 Ice::PropertiesPtr properties = getIceProperties()->clone();
289
290 // Create and add unit.
292 Component::create<UnitT>(properties, configName, getConfigDomain());
293 unit->setBatteryManagementDevices(batteryDevs);
294 addUnit(std::move(unit));
295 }
296
297 void
299 {
300 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
301 using IfaceT = KinematicUnitInterface;
302
303 auto guard = getGuard();
305 //check if unit is already added
306 if (getUnit(IfaceT::ice_staticId()))
307 {
308 return;
309 }
310 auto unit = createKinematicSubUnit(getIceProperties()->clone());
311 //add
312 if (unit)
313 {
314 addUnit(std::move(unit));
315 }
316 }
317
320 const std::string& positionControlMode,
321 const std::string& velocityControlMode,
322 const std::string& torqueControlMode,
323 const std::string& pwmControlMode)
324 {
326 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
327 /// TODO move init code to Kinematic sub unit
328 using UnitT = KinematicSubUnit;
329
330 //add ctrl et al
331 ARMARX_DEBUG << "createKinematicSubUnit...";
332 std::map<std::string, UnitT::ActuatorData> devs;
333 for (const ControlDevicePtr& controlDevice :
334 _module<Devices>().getControlDevices().values())
335 {
336 ARMARX_CHECK_NOT_NULL(controlDevice);
337 const auto& controlDeviceName = controlDevice->getDeviceName();
338 ARMARX_DEBUG << "looking at device " << controlDeviceName
339 << controlDevice->getJointControllerToTargetTypeNameMap();
340 if (!controlDevice->hasTag(ControlDeviceTags::CreateNoDefaultController))
341 {
342 UnitT::ActuatorData ad;
343 ad.name = controlDeviceName;
344 ARMARX_DEBUG << "has sensor device: "
345 << _module<Devices>().getSensorDevices().has(controlDeviceName);
346 ad.sensorDeviceIndex =
347 _module<Devices>().getSensorDevices().has(controlDeviceName)
348 ? _module<Devices>().getSensorDevices().index(controlDeviceName)
349 : std::numeric_limits<std::size_t>::max();
350
351 const auto init_controller =
352 [&](const std::string& requestedControlMode, auto& ctrl, const auto* tpptr)
353 {
354 auto controlMode = requestedControlMode;
355 using CtargT = std::remove_const_t<std::remove_reference_t<decltype(*tpptr)>>;
356 NJointKinematicUnitPassThroughControllerPtr& pt = ctrl;
357
358 auto testMode = [&](const auto& m)
359 {
360 JointController* jointCtrl = controlDevice->getJointController(m);
361 return jointCtrl && jointCtrl->getControlTarget()->isA<CtargT>();
362 };
363
364 if (!testMode(controlMode))
365 {
366 controlMode = "";
367 //try to find the correct mode (maybe the specified target was derived!
368 //this only works, if exactly one controller provides this mode
369 const JointController* selected_ctrl{nullptr};
370 auto jointControllers = controlDevice->getJointControllers();
371 for (const auto* jointController : jointControllers)
372 {
373 if (jointController->getControlTarget()->isA<CtargT>())
374 {
375 if (selected_ctrl)
376 {
377 selected_ctrl = nullptr;
378 ARMARX_INFO << "Autodetected two controllers supporting "
379 << requestedControlMode << "! autoselection failed";
380 break;
381 }
382 selected_ctrl = jointController;
383 }
384 }
385 if (selected_ctrl)
386 {
387 controlMode = selected_ctrl->getControlMode();
388 ARMARX_INFO << "Autodetected controller with mode " << controlMode
389 << "(the requested mode was " << requestedControlMode
390 << ")";
391 }
392 }
393
394 if (!controlMode.empty())
395 {
396 NJointKinematicUnitPassThroughControllerConfigPtr config =
398 config->controlMode = controlMode;
399 config->deviceName = controlDeviceName;
400 auto ctrl_name = getName() + "_" + "NJointKU_PTCtrl_" + controlDeviceName +
401 "_" + controlMode;
402 std::replace(ctrl_name.begin(), ctrl_name.end(), '.', '_');
403 std::replace(ctrl_name.begin(), ctrl_name.end(), '-', '_');
404 std::replace(ctrl_name.begin(), ctrl_name.end(), ':', '_');
405 const NJointControllerBasePtr& nJointCtrl =
406 _module<ControllerManagement>().createNJointController(
407 "NJointKinematicUnitPassThroughController",
408 ctrl_name,
409 config,
410 false,
411 true);
412 pt = NJointKinematicUnitPassThroughControllerPtr::dynamicCast(nJointCtrl);
414 }
415 };
416 init_controller(
417 positionControlMode, ad.ctrlPos, (ControlTarget1DoFActuatorPosition*)0);
418 init_controller(
419 velocityControlMode, ad.ctrlVel, (ControlTarget1DoFActuatorVelocity*)0);
420 init_controller(torqueControlMode, ad.ctrlTor, (ControlTarget1DoFActuatorTorque*)0);
421 if (!ad.ctrlTor)
422 {
423 init_controller(pwmControlMode, ad.ctrlTor, (ControlTarget1DoFActuatorPWM*)0);
424 }
425
426 if (ad.ctrlPos || ad.ctrlTor || ad.ctrlVel)
427 {
428 ARMARX_DEBUG << "created controllers for " << controlDeviceName
429 << " pos/tor/vel " << ad.ctrlPos.get() << " / " << ad.ctrlTor.get()
430 << " / " << ad.ctrlVel.get();
431 devs[controlDeviceName] = std::move(ad);
432 }
433 }
434 }
435 if (devs.empty())
436 {
437 ARMARX_IMPORTANT << "No joint devices found - skipping adding of KinematicUnit";
438 return nullptr;
439 }
440 ARMARX_IMPORTANT << "Found " << devs.size() << " joint devices - adding KinematicUnit";
441 ARMARX_CHECK_EXPRESSION(!devs.empty())
442 << "no 1DoF ControlDevice found with matching SensorDevice";
443 //add it
444 const std::string configName = getProperty<std::string>("KinematicUnitName");
445 const std::string confPre = getConfigDomain() + "." + configName + ".";
446 //properties->setProperty(confPre + "MinimumLoggingLevel", getProperty<std::string>("MinimumLoggingLevel").getValue());
447 //fill properties
448 properties->setProperty(confPre + "RobotNodeSetName",
449 _module<RobotData>().getRobotNodetSeName());
450 properties->setProperty(confPre + "RobotFileName", _module<RobotData>().getRobotFileName());
451 properties->setProperty(confPre + "RobotFileNameProject",
452 _module<RobotData>().getRobotProjectName());
453 properties->setProperty(confPre + "TopicPrefix",
454 getProperty<std::string>("KinematicUnitNameTopicPrefix"));
455
456 ARMARX_DEBUG << "creating unit " << configName
457 << " using these properties: " << properties->getPropertiesForPrefix("");
459 Component::create<UnitT>(properties, configName, getConfigDomain());
460
461 //fill devices (sensor + controller)
462 unit->setupData(getProperty<std::string>("RobotFileName").getValue(),
463 _module<RobotData>().cloneRobot(),
464 std::move(devs),
465 _module<Devices>().getControlModeGroups().groups,
466 _module<Devices>().getControlModeGroups().groupsMerged,
467 dynamic_cast<RobotUnit*>(this));
468 return unit;
469 }
470
471 void
473 {
474 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
475 using UnitT = PlatformSubUnit;
476 using IfaceT = PlatformUnitInterface;
477
479
480 auto guard = getGuard();
482 //check if unit is already added
483 if (getUnit(IfaceT::ice_staticId()))
484 {
485 return;
486 }
488 //is there a platform dev?
489 if (_module<RobotData>().getRobotPlatformName().empty())
490 {
491 ARMARX_INFO << "no platform unit created since no platform name was given";
492 return;
493 }
495 if (!_module<Devices>().getControlDevices().has(
496 _module<RobotData>().getRobotPlatformName()))
497 {
499 << "no platform unit created since the platform control device with name '"
500 << _module<RobotData>().getRobotPlatformName() << "' was not found";
501 return;
502 }
504 const ControlDevicePtr& controlDevice =
505 _module<Devices>().getControlDevices().at(_module<RobotData>().getRobotPlatformName());
506 const SensorDevicePtr& sensorDevice =
507 _module<Devices>().getSensorDevices().at(_module<RobotData>().getRobotPlatformName());
508 JointController* jointVel =
509 controlDevice->getJointController(ControlModes::HolonomicPlatformVelocity);
511 ARMARX_CHECK_EXPRESSION(jointVel);
513 sensorDevice->getSensorValue()->asA<SensorValueHolonomicPlatform>());
514 //add it
516 const std::string configName = getProperty<std::string>("PlatformUnitName");
517 const std::string confPre = getConfigDomain() + "." + configName + ".";
518 Ice::PropertiesPtr properties = getIceProperties()->clone();
519 //properties->setProperty(confPre + "MinimumLoggingLevel", getProperty<std::string>("MinimumLoggingLevel").getValue());
520 //fill properties
521 properties->setProperty(confPre + "PlatformName",
522 _module<RobotData>().getRobotPlatformInstanceName());
523 ARMARX_DEBUG << "creating unit " << configName
524 << " using these properties: " << properties->getPropertiesForPrefix("");
527 Component::create<UnitT>(properties, configName, getConfigDomain());
528 //config
530 const NJointHolonomicPlatformVelocityControllerTypes platformControllerType =
532 "PlatformUnitVelocityControllerType");
533 if (platformControllerType ==
535 {
536 NJointHolonomicPlatformUnitVelocityPassThroughControllerConfigPtr config =
538 config->initialVelocityX = 0;
539 config->initialVelocityY = 0;
540 config->initialVelocityRotation = 0;
541 config->platformName = _module<RobotData>().getRobotPlatformName();
542
543 auto ctrl = NJointHolonomicPlatformUnitVelocityPassThroughControllerPtr::dynamicCast(
544 _module<ControllerManagement>().createNJointController(
545 "NJointHolonomicPlatformUnitVelocityPassThroughController",
546 getName() + "_" + configName + "_VelPTContoller",
547 config,
548 false,
549 true));
552 unit->pt = ctrl;
554 }
555 else if (platformControllerType ==
557 {
558 NJointHolonomicPlatformVelocityControllerWithRampConfigPtr config =
560 config->platformName = _module<RobotData>().getRobotPlatformName();
561
562 config->maxPositionAcceleration =
563 getProperty<float>("PlatformUnitMaximumPositionAcceleration");
564 config->maxOrientationAcceleration =
565 getProperty<float>("PlatformUnitMaximumOrientationAcceleration");
566
567 auto ctrl = NJointHolonomicPlatformVelocityControllerWithRampPtr::dynamicCast(
568 _module<ControllerManagement>().createNJointController(
569 "NJointHolonomicPlatformVelocityControllerWithRamp",
570 getName() + "_" + configName + "_VelPTContoller",
571 config,
572 false,
573 true));
576 unit->pt = ctrl;
578 }
579 else
580 {
581 ARMARX_ERROR << "Invalid Platform velocity controller specified '"
583 platformControllerType)
584 << "'";
585 }
586
587 NJointHolonomicPlatformRelativePositionControllerConfigPtr configRelativePositionCtrlCfg =
589 configRelativePositionCtrlCfg->platformName = _module<RobotData>().getRobotPlatformName();
590 auto ctrlRelativePosition =
591 NJointHolonomicPlatformRelativePositionControllerPtr::dynamicCast(
592 _module<ControllerManagement>().createNJointController(
593 "NJointHolonomicPlatformRelativePositionController",
594 getName() + "_" + configName + "_RelativePositionContoller",
595 configRelativePositionCtrlCfg,
596 false,
597 true));
598 ARMARX_CHECK_EXPRESSION(ctrlRelativePosition);
599 unit->relativePosCtrl = ctrlRelativePosition;
600
601 // unit->platformSensorIndex = _module<Devices>().getSensorDevices().index(_module<RobotData>().getRobotPlatformName());
602
603 NJointHolonomicPlatformGlobalPositionControllerConfigPtr configGlobalPositionCtrlCfg =
605 configGlobalPositionCtrlCfg->platformName = _module<RobotData>().getRobotPlatformName();
606 auto ctrlGlobalPosition = NJointHolonomicPlatformGlobalPositionControllerPtr::dynamicCast(
607 _module<ControllerManagement>().createNJointController(
608 "NJointHolonomicPlatformGlobalPositionController",
609 getName() + "_" + configName + "_GlobalPositionContoller",
610 configGlobalPositionCtrlCfg,
611 false,
612 true));
614 ARMARX_CHECK_EXPRESSION(ctrlGlobalPosition);
615 unit->globalPosCtrl = ctrlGlobalPosition;
617
618 unit->platformSensorIndex = _module<Devices>().getSensorDevices().index(
619 _module<RobotData>().getRobotPlatformName());
620 //add
621 addUnit(std::move(unit));
622 }
623
624 void
626 {
628 ARMARX_DEBUG << "initializeLocalizationUnit";
629
630 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
631 using UnitT = LocalizationSubUnit;
632 using IfaceT = LocalizationUnitInterface;
633
635 auto guard = getGuard();
637 //check if unit is already added
638 if (getUnit(IfaceT::ice_staticId()))
639 {
640 return;
641 }
643
644 if (_module<Devices>().getSensorDevices().count(
645 _module<RobotData>().getRobotPlatformName()) == 0)
646 {
647 ARMARX_WARNING << "No sensor devices found for robot platform `"
648 << _module<RobotData>().getRobotPlatformName() << "`.";
649 return;
650 }
651
652 ARMARX_DEBUG << "Getting device SensorValueHolonomicPlatformRelativePosition";
654 _module<Devices>().getSensorDevices().has(_module<RobotData>().getRobotPlatformName()))
655 << _module<RobotData>().getRobotPlatformName();
656 const SensorDevicePtr& sensorDeviceRelativePosition =
657 _module<Devices>().getSensorDevices().at(_module<RobotData>().getRobotPlatformName());
658 ARMARX_CHECK_EXPRESSION(sensorDeviceRelativePosition->getSensorValue()
660
662 // const SensorDevicePtr& sensorDevicePoseCorrection = _module<Devices>().getSensorDevices().at(GlobalRobotPoseCorrectionSensorDevice::DeviceName());
663 // ARMARX_CHECK_EXPRESSION(sensorDeviceRelativePosition->getSensorValue()->asA<SensorValueGlobalPoseCorrection>());
664
665
666 //add it
667 const std::string configName = "LocalizationUnit";
668 const std::string confPre = getConfigDomain() + "." + configName + ".";
669 Ice::PropertiesPtr properties = getIceProperties()->clone();
670 //properties->setProperty(confPre + "MinimumLoggingLevel", getProperty<std::string>("MinimumLoggingLevel").getValue());
671 //fill properties
672 // properties->setProperty(confPre + "PlatformName", _module<RobotData>().getRobotPlatformInstanceName());
673 ARMARX_DEBUG << "creating unit " << configName
674 << " using these properties: " << properties->getPropertiesForPrefix("");
676 Component::create<UnitT>(properties, configName, getConfigDomain());
677 //config
678
679 ARMARX_DEBUG << "Setting device GlobalRobotPoseCorrectionSensorDevice";
680 unit->globalPositionCorrectionSensorDevice =
681 dynamic_cast<decltype(unit->globalPositionCorrectionSensorDevice)>(
683 .getSensorDevices()
685 .get());
686
687
688 const SensorDevicePtr& sensorDeviceGlobalRobotLocalization =
689 _module<Devices>().getSensorDevices().at(
691 ARMARX_CHECK_EXPRESSION(sensorDeviceGlobalRobotLocalization->getSensorValue()
693
694 dynamic_cast<GlobalRobotLocalizationSensorDevice&>(*sensorDeviceGlobalRobotLocalization)
695 .sensorRelativePosition = sensorDeviceRelativePosition->getSensorValue()
697 dynamic_cast<GlobalRobotLocalizationSensorDevice&>(*sensorDeviceGlobalRobotLocalization)
699 unit->globalPositionCorrectionSensorDevice->getSensorValue()
701
702 //add
703 addUnit(unit);
704 }
705
706 void
708 {
709 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
710 using UnitT = ForceTorqueSubUnit;
711 using IfaceT = ForceTorqueUnitInterface;
712
713 auto guard = getGuard();
715 //check if unit is already added
716 if (getUnit(IfaceT::ice_staticId()))
717 {
718 return;
719 }
720 //check if it is required
721 std::vector<ForceTorqueSubUnit::DeviceData> ftdevs;
722 for (const SensorDevicePtr& ftSensorDevice : _module<Devices>().getSensorDevices().values())
723 {
724 if (ftSensorDevice->getSensorValue()->isA<SensorValueForceTorque>())
725 {
727 ftSensorData.sensorIndex =
728 _module<Devices>().getSensorDevices().index(ftSensorDevice->getDeviceName());
729 ftSensorData.deviceName = ftSensorDevice->getDeviceName();
730 ftSensorData.frame = ftSensorDevice->getReportingFrame();
731 ARMARX_CHECK_EXPRESSION(!ftSensorData.frame.empty())
732 << "The sensor device '" << ftSensorData.deviceName
733 << "' (index: " << ftSensorData.sensorIndex
734 << ") reports force torque values but returns an empty string as reporting "
735 "frame";
736 ARMARX_CHECK_EXPRESSION(unitCreateRobot->hasRobotNode(ftSensorData.frame))
737 << "The sensor device '" << ftSensorData.deviceName
738 << "' (index: " << ftSensorData.sensorIndex
739 << ") reports force torque values but returns a reporting frame '"
740 << ftSensorData.frame << "' which is not present in the robot '"
741 << _module<RobotData>().getRobotName() << "'";
742 ftdevs.emplace_back(std::move(ftSensorData));
743 }
744 }
745 if (ftdevs.empty())
746 {
748 << "no force torque unit created since there are no force torque sensor devices";
749 return;
750 }
751 //add it
752 const std::string configName = getProperty<std::string>("ForceTorqueUnitName");
753 const std::string confPre = getConfigDomain() + "." + configName + ".";
754 Ice::PropertiesPtr properties = getIceProperties()->clone();
755 //properties->setProperty(confPre + "MinimumLoggingLevel", getProperty<std::string>("MinimumLoggingLevel").getValue());
756 //fill properties
757 properties->setProperty(confPre + "AgentName", _module<RobotData>().getRobotName());
758 properties->setProperty(confPre + "ForceTorqueTopicName",
759 getProperty<std::string>("ForceTorqueTopicName").getValue());
760 ARMARX_DEBUG << "creating unit " << configName
761 << " using these properties: " << properties->getPropertiesForPrefix("");
763 Component::create<UnitT>(properties, configName, getConfigDomain());
764 unit->devs = ftdevs;
765 //add
766 addUnit(std::move(unit));
767 }
768
769 void
771 {
772 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
773 using UnitT = InertialMeasurementSubUnit;
774 using IfaceT = InertialMeasurementUnitInterface;
775
776 auto guard = getGuard();
778 //check if unit is already added
779 if (getUnit(IfaceT::ice_staticId()))
780 {
781 return;
782 }
783 //check if it is required
784 std::map<std::string, std::size_t> imudevs;
785 for (auto i : getIndices(_module<Devices>().getSensorDevices().keys()))
786 {
787 const SensorDevicePtr& sensorDevice = _module<Devices>().getSensorDevices().at(i);
788 if (sensorDevice->getSensorValue()->isA<SensorValueIMU>())
789 {
790 imudevs[sensorDevice->getDeviceName()] = i;
791 }
792 }
793 if (imudevs.empty())
794 {
796 << "no inertial measurement unit created since there are no imu sensor devices";
797 return;
798 }
799 //add it
800 const std::string configName = getProperty<std::string>("InertialMeasurementUnitName");
801 const std::string confPre = getConfigDomain() + "." + configName + ".";
802 Ice::PropertiesPtr properties = getIceProperties()->clone();
803 //properties->setProperty(confPre + "MinimumLoggingLevel", getProperty<std::string>("MinimumLoggingLevel").getValue());
804 //fill properties
805 properties->setProperty(confPre + "IMUTopicName",
806 getProperty<std::string>("IMUTopicName").getValue());
808 Component::create<UnitT>(properties, configName, getConfigDomain());
809 unit->devs = imudevs;
810 //add
811 addUnit(std::move(unit));
812 }
813
814 void
816 {
817 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
818 auto guard = getGuard();
820 using UnitT = TrajectoryControllerSubUnit;
821 if (!getProperty<bool>("CreateTrajectoryPlayer").getValue())
822 {
823 return;
824 }
825
826 //check if unit is already added
827 if (getUnit(UnitT::ice_staticId()) || !trajectoryControllerSubUnit)
828 {
829 return;
830 }
831 (TrajectoryControllerSubUnitPtr::dynamicCast(trajectoryControllerSubUnit))
832 ->setup(_modulePtr<RobotUnit>());
833 addUnit(trajectoryControllerSubUnit);
834 trajectoryControllerSubUnit = nullptr;
835 }
836
837 void
839 {
840 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
841 auto guard = getGuard();
843
844 if (!getProperty<bool>("CreateTCPControlUnit").getValue())
845 {
846 return;
847 }
848 using UnitT = TCPControllerSubUnit;
849
850 //check if unit is already added
851 if (getUnit(UnitT::ice_staticId()))
852 {
853 return;
854 }
855 (TCPControllerSubUnitPtr::dynamicCast(tcpControllerSubUnit))
856 ->setup(_modulePtr<RobotUnit>(), _module<RobotData>().cloneRobot());
857 addUnit(tcpControllerSubUnit);
858 tcpControllerSubUnit = nullptr;
859 }
860
861 void
863 {
864 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
866 auto guard = getGuard();
868 getArmarXManager()->addObjectAsync(unit, "", true, false);
869 //maybe add it to the sub units
870 RobotUnitSubUnitPtr rsu = RobotUnitSubUnitPtr::dynamicCast(unit);
871 if (rsu)
872 {
873 subUnits.emplace_back(std::move(rsu));
874 }
875 units.emplace_back(std::move(unit));
876 }
877
878 void
879 Units::_icePropertiesInitialized()
880 {
881 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
882 Ice::PropertiesPtr properties = getIceProperties()->clone();
883 const std::string& configDomain = "ArmarX";
884 // create TCPControlSubUnit
885
886 {
887 const std::string configNameTCPControlUnit =
888 getProperty<std::string>("TCPControlUnitName");
890 properties, configNameTCPControlUnit, configDomain);
891 addPropertyUser(PropertyUserPtr::dynamicCast(tcpControllerSubUnit));
892 }
893
894 // create TrajectoryControllerSubUnit
895
896 {
897 const std::string configNameTrajectoryControllerUnit =
898 getProperty<std::string>("TrajectoryControllerUnitName");
899 const std::string confPre =
900 configDomain + "." + configNameTrajectoryControllerUnit + ".";
901 properties->setProperty(confPre + "KinematicUnitName",
902 getProperty<std::string>("KinematicUnitName").getValue());
903 trajectoryControllerSubUnit =
905 properties, configNameTrajectoryControllerUnit, configDomain);
906 addPropertyUser(PropertyUserPtr::dynamicCast(trajectoryControllerSubUnit));
907 }
908 }
909
910 void
911 Units::_preFinishRunning()
912 {
913 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
914 //remove all units
915 subUnits.clear();
916 for (ManagedIceObjectPtr& unit : units)
917 {
918 getArmarXManager()->removeObjectBlocking(unit->getName());
919 }
920 units.clear();
921 }
922
923 void
924 Units::_preOnInitRobotUnit()
925 {
926 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
927 unitCreateRobot = _module<RobotData>().cloneRobot();
928 ARMARX_DEBUG << "add emergency stop master";
929 {
930 emergencyStopMaster = new RobotUnitEmergencyStopMaster{
932 getProperty<std::string>("EmergencyStopTopic").getValue()};
933 ManagedIceObjectPtr obj = ManagedIceObjectPtr::dynamicCast(emergencyStopMaster);
934 ARMARX_CHECK_EXPRESSION(obj) << "RobotUnitEmergencyStopMaster";
935 getArmarXManager()->addObject(
936 obj, getProperty<std::string>("EmergencyStopMasterName").getValue(), true);
937 auto prx = obj->getProxy(-1);
938 try
939 {
940 getArmarXManager()->getIceManager()->getIceGridSession()->getAdmin()->addObject(
941 prx);
942 }
943 catch (const IceGrid::ObjectExistsException&)
944 {
945 getArmarXManager()->getIceManager()->getIceGridSession()->getAdmin()->updateObject(
946 prx);
947 }
948 catch (std::exception& e)
949 {
950 ARMARX_WARNING << "add the robot unit as emergency stop master to the ice grid "
951 "admin!\nThere was an exception:\n"
952 << e.what();
953 }
954 }
955 ARMARX_DEBUG << "add emergency stop master...done!";
956 }
957
958 void
959 Units::_postOnExitRobotUnit()
960 {
961 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
962 ARMARX_DEBUG << "remove EmergencyStopMaster";
963 try
964 {
965 getArmarXManager()->removeObjectBlocking(
966 ManagedIceObjectPtr::dynamicCast(emergencyStopMaster));
967 getArmarXManager()->getIceManager()->removeObject(
968 getProperty<std::string>("EmergencyStopMasterName").getValue());
969 }
970 catch (...)
971 {
972 }
973 ARMARX_DEBUG << "remove EmergencyStopMaster...done!";
974 }
975
977 Units::getUnit(const std::string& staticIceId) const
978 {
979 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
980 auto guard = getGuard();
981 for (const ManagedIceObjectPtr& unit : units)
982 {
983 if (unit->ice_isA(staticIceId))
984 {
985 return unit;
986 }
987 }
989 }
990} // 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