RobotUnitModuleControllerManagement.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
23
25
30
37
39{
40 template <class Cont>
41 static Ice::StringSeq
42 GetNonNullNames(const Cont& c)
43 {
44 Ice::StringSeq result;
45 result.reserve(c.size());
46 for (const auto& e : c)
47 {
48 if (e)
49 {
50 result.emplace_back(e->getName());
51 }
52 }
53 return result;
54 }
55
56 /**
57 * \brief This class allows minimal access to private members of \ref NJointControllerBase in a sane fashion for \ref ControllerManagement.
58 * \warning !! DO NOT ADD ANYTHING IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !!
59 */
61 {
63
64 static void
65 SetRequested(const NJointControllerBasePtr& nJointCtrl, bool requested)
66 {
67 nJointCtrl->isRequested = requested;
68 }
69 };
70} // namespace armarx::RobotUnitModule
71
73{
74 Ice::StringSeq
76 {
78 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
79 return GetNonNullNames(_module<ControlThreadDataBuffer>().copyRequestedNJointControllers());
80 }
81
82 Ice::StringSeq
84 {
85 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
86 return GetNonNullNames(_module<ControlThreadDataBuffer>().getActivatedNJointControllers());
87 }
88
89 void
90 ControllerManagement::checkNJointControllerClassName(const std::string& className) const
91 {
92 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
93 if (!NJointControllerRegistry::has(className))
94 {
95 std::stringstream ss;
96 ss << "Requested controller class '" << className
97 << "' unknown! Known classes:" << NJointControllerRegistry::getKeys()
98 << " (If this class exists in a different lib then load it in the property "
99 "definitions of the RT-unit. DO NOT load it via "
100 "loadLibFromPath(path) or loadLibFromPackage(package, lib)) (see "
101 "https://git.h2t.iar.kit.edu/sw/armarx-integration/robots/armar7/documentation/-/"
102 "issues/85)";
103 ARMARX_ERROR << ss.str();
104 throw InvalidArgumentException{ss.str()};
105 }
106 }
107
108 std::vector<NJointControllerBasePtr>
109 ControllerManagement::getNJointControllersNotNull(const std::vector<std::string>& names) const
110 {
111 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
112 auto guard = getGuard();
113 throwIfDevicesNotReady(__FUNCTION__);
114 std::vector<NJointControllerBasePtr> ctrl;
115 ctrl.reserve(names.size());
116 for (const auto& name : names)
117 {
118 ctrl.emplace_back(getNJointControllerNotNull(name));
119 }
120 return ctrl;
121 }
122
123 const NJointControllerBasePtr&
125 {
126 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
127 auto guard = getGuard();
128 throwIfDevicesNotReady(__FUNCTION__);
129 auto it = nJointControllers.find(name);
130 if (it == nJointControllers.end())
131 {
132 std::stringstream ss;
133 ss << "RobotUnit: there is no NJointControllerBase with name '" << name
134 << "'. Existing NJointControllers are: " << getNJointControllerNames();
135 throw InvalidArgumentException{ss.str()};
136 }
137 if (!it->second)
138 {
139 std::stringstream ss;
140 ss << "RobotUnit: The NJointControllerBase with name '" << name
141 << "'. Is a nullptr! This should never be the case (invariant)! \nMap:\n"
142 << nJointControllers;
143 ARMARX_FATAL << ss.str();
144 throw InvalidArgumentException{ss.str()};
145 }
146 return it->second;
147 }
148
149 void
150 ControllerManagement::deleteNJointController(const NJointControllerBasePtr& ctrl)
151 {
152 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
153 deleteNJointControllers(std::vector<NJointControllerBasePtr>{ctrl});
154 }
155
156 StringNJointControllerPrxDictionary
158 {
159 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
160 std::map<std::string, NJointControllerBasePtr> nJointControllersCopy;
161 {
162 auto guard = getGuard();
163 //copy to keep lock retention time low
164 nJointControllersCopy = nJointControllers;
165 }
166 StringNJointControllerPrxDictionary result;
167 for (const auto& pair : nJointControllersCopy)
168 {
169 result[pair.first] =
170 NJointControllerInterfacePrx::uncheckedCast(pair.second->getProxy(-1, true));
171 }
172 return result;
173 }
174
175 NJointControllerInterfacePrx
177 const std::string& instanceName,
178 const NJointControllerConfigPtr& config,
179 const Ice::Current&)
180 {
181 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
182 //no lock required
183 return NJointControllerInterfacePrx::uncheckedCast(
184 createNJointController(className, instanceName, config, true, false)
185 ->getProxy(-1, true));
186 }
187
188 NJointControllerInterfacePrx
190 const std::string& className,
191 const std::string& instanceName,
192 const StringVariantBaseMap& variants,
193 const Ice::Current&)
194 {
195 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
196 //no lock required
197 checkNJointControllerClassName(className);
198 if (!NJointControllerRegistry::get(className)->hasRemoteConfiguration())
199 {
200 std::stringstream ss;
201 ss << "Requested controller class '" << className << "' allows no remote configuration"
203 << " (Implement 'static WidgetDescription::WidgetPtr " << className
204 << "::GenerateConfigDescription()'"
205 << " and 'static NJointControllerConfigPtr " << className
206 << "::GenerateConfigFromVariants(const StringVariantBaseMap&)' to allow remote "
207 "configuration";
208 ARMARX_ERROR << ss.str();
209 throw InvalidArgumentException{ss.str()};
210 }
212 className,
213 instanceName,
214 NJointControllerRegistry::get(className)->GenerateConfigFromVariants(variants),
215 Ice::emptyCurrent /*to select ice overload*/);
216 }
217
218 NJointControllerInterfacePrx
220 const std::string& instanceName,
221 const NJointControllerConfigPtr& config,
222 const Ice::Current&)
223 {
225 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
226 {
228 auto guard = getGuard();
229 if (getNJointController(instanceName))
230 {
233 }
234 }
236 while (getNJointController(instanceName))
237 {
239 if (isShuttingDown())
240 {
242 return nullptr;
243 }
244 ARMARX_INFO << "wiating until controller '" << instanceName << "' is deleted";
245 }
246 while (getArmarXManager()->getIceManager()->isObjectReachable(instanceName))
247 {
249 if (isShuttingDown())
250 {
252 return nullptr;
253 }
254 ARMARX_INFO << "wiating until controller '" << instanceName << "' is removed from ice";
255 }
256 return NJointControllerInterfacePrx::uncheckedCast(
257 createNJointController(className, instanceName, config, true, false)
258 ->getProxy(-1, true));
259 }
260
261 const NJointControllerBasePtr&
263 const std::string& instanceName,
264 const NJointControllerConfigPtr& config,
265 bool deletable,
266 bool internal)
267 {
268 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
269 auto guard = getGuard();
270 throwIfDevicesNotReady(__FUNCTION__);
271 if (instanceName.empty())
272 {
273 ARMARX_ERROR << "The instance name is empty! (give a unique name)";
274 throw InvalidArgumentException{"The instance name is empty! (give a unique name)"};
275 }
276 //check if we would be able to create the class
277 checkNJointControllerClassName(className);
278 auto& factory = NJointControllerRegistry::get(className);
279
280 //check if the instance name is already in use
281 if (nJointControllers.count(instanceName))
282 {
283 std::stringstream ss;
284 ss << "There already is a controller instance with the name '" << instanceName
285 << "'. Use a different instance name instead."
286 << " Other used instance names are " << getNJointControllerNames();
287 ARMARX_ERROR << ss.str();
288 throw InvalidArgumentException{ss.str()};
289 }
290
291 //create the controller
293 NJointControllerBasePtr nJointCtrl =
294 factory->create(this, config, controllerCreateRobot, deletable, internal, instanceName);
295 ARMARX_CHECK_NOT_EQUAL(nJointCtrl->getControlDeviceUsedIndices().size(), 0)
296 << "The NJointControllerBase '" << nJointCtrl->getName()
297 << "' uses no ControlDevice! (It has to use at least one)";
298
299 getArmarXManager()->addObject(nJointCtrl, instanceName, false, false);
300 nJointControllers[instanceName] = std::move(nJointCtrl);
301 _module<Publisher>().getRobotUnitListenerProxy()->nJointControllerCreated(instanceName);
302 return nJointControllers.at(instanceName);
303 }
304
305 Ice::StringSeq
307 {
308 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
310 }
311
312 Ice::StringSeq
314 {
315 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
316 auto guard = getGuard();
317 return getMapKeys(nJointControllers);
318 }
319
320 std::vector<std::string>
322 const std::vector<NJointControllerBasePtr>& ctrls) const
323 {
324 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
325 std::vector<std::string> result;
326 result.reserve(ctrls.size());
327 for (const auto& ctrl : ctrls)
328 {
329 if (ctrl)
330 {
331 result.emplace_back(ctrl->getInstanceName());
332 }
333 }
334 return result;
335 }
336
337 void
338 ControllerManagement::activateNJointController(const std::string& name, const Ice::Current&)
339 {
340 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
342 }
343
344 void
346 const Ice::Current&)
347 {
348 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
350 }
351
352 void
353 ControllerManagement::activateNJointController(const NJointControllerBasePtr& ctrl)
354 {
355 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
356 activateNJointControllers(std::vector<NJointControllerBasePtr>{ctrl});
357 }
358
359 void
361 const std::vector<NJointControllerBasePtr>& ctrlsToActVec)
362 {
363 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
364 if (ctrlsToActVec.empty())
365 {
366 return;
367 }
368 auto guard = getGuard();
369 throwIfDevicesNotReady(__FUNCTION__);
370 //if not activate them
371 std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>> ctrlsToAct{
372 ctrlsToActVec.begin(), ctrlsToActVec.end()};
373 ARMARX_CHECK_EXPRESSION(!ctrlsToAct.count(nullptr));
374 //check if all already active
375 if (std::all_of(ctrlsToActVec.begin(),
376 ctrlsToActVec.end(),
377 [](const NJointControllerBasePtr& ctrl)
378 { return ctrl->isControllerActive(); }))
379 {
380 return;
381 }
382 //get already requested
383 const auto ctrlVector = _module<ControlThreadDataBuffer>().copyRequestedNJointControllers();
384 std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>>
385 ctrlsAlreadyRequested{ctrlVector.begin(), ctrlVector.end()};
386 ctrlsAlreadyRequested.erase(nullptr);
387 //check for conflict
388 std::vector<char> inuse;
389 //check requested controllers
390 {
391 auto r = NJointControllerBase::AreNotInConflict(ctrlsToAct.begin(), ctrlsToAct.end());
392 if (!r)
393 {
394 std::stringstream ss;
395 ss << "activateNJointControllers: requested controllers are in "
396 "conflict!\ncontrollers:\n"
397 << getNJointControllerNames(ctrlsToActVec);
398 ARMARX_ERROR << ss.str();
399 throw InvalidArgumentException{ss.str()};
400 }
401 inuse = std::move(*r);
402 }
403 ARMARX_DEBUG << "all requested controllers are conflict free" << std::flush;
404 auto printInUse = ARMARX_STREAM_PRINTER
405 {
406 for (const auto c : inuse)
407 {
408 out << (c ? 1 : 0);
409 }
410 };
411 ARMARX_DEBUG << "inuse field (request)\n" << printInUse;
412 //add already active controllers if they are conflict free
413 {
414 if (ctrlsAlreadyRequested.empty())
415 {
416 ARMARX_DEBUG << "no already requested NJointControllers";
417 }
418 for (const NJointControllerBasePtr& nJointCtrl : ctrlsAlreadyRequested)
419 {
420 if (ctrlsToAct.count(nJointCtrl))
421 {
422 continue;
423 }
424 auto r = nJointCtrl->isNotInConflictWith(inuse);
425 if (r)
426 {
427 ARMARX_DEBUG << "keeping already requested NJointControllerBase '"
428 << nJointCtrl->getInstanceName()
429 << "' in list of requested controllers";
430 ctrlsToAct.insert(nJointCtrl);
431 inuse = std::move(*r);
432 }
433 else
434 {
435 ARMARX_INFO << "removing already requested NJointControllerBase '"
436 << nJointCtrl->getInstanceName()
437 << "' from list of requested controllers";
438 }
439 }
440 ARMARX_DEBUG << "inuse field (all)\n" << printInUse;
441 }
442 _module<ControlThreadDataBuffer>().setActivateControllersRequest(ctrlsToAct);
443 }
444
445 void
446 ControllerManagement::deactivateNJointController(const std::string& name, const Ice::Current&)
447 {
448 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
450 }
451
452 void
454 const Ice::Current&)
455 {
456 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
458 }
459
460 void
461 ControllerManagement::deactivateNJointController(const NJointControllerBasePtr& ctrl)
462 {
463 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
464 deactivateNJointControllers(std::vector<NJointControllerBasePtr>{ctrl});
465 }
466
467 void
469 const std::vector<NJointControllerBasePtr>& ctrlsDeacVec)
470 {
471 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
472 auto guard = getGuard();
473 throwIfDevicesNotReady(__FUNCTION__);
474 if (ctrlsDeacVec.empty())
475 {
476 return;
477 }
478 const auto ctrlVector = _module<ControlThreadDataBuffer>().copyRequestedNJointControllers();
479 std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>> ctrls{
480 ctrlVector.begin(), ctrlVector.end()};
481 const std::size_t ctrlsNum = ctrls.size();
482 for (const auto& nJointCtrlToDeactivate : ctrlsDeacVec)
483 {
484 ctrls.erase(nJointCtrlToDeactivate);
485 }
486 if (ctrls.size() == ctrlsNum)
487 {
488 return;
489 }
490 _module<ControlThreadDataBuffer>().setActivateControllersRequest(ctrls);
491 }
492
493 void
494 ControllerManagement::deleteNJointController(const std::string& name, const Ice::Current&)
495 {
496 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
498 }
499
500 void
501 ControllerManagement::deleteNJointControllers(const Ice::StringSeq& names, const Ice::Current&)
502 {
503 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
505 }
506
507 void
509 const Ice::Current&)
510 {
511 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
512 auto guard = getGuard();
513 throwIfDevicesNotReady(__FUNCTION__);
514 auto ctrlsToActVec =
515 getNJointControllersNotNull(newSetup); //also checks if these controllers exist
516 _module<ControlThreadDataBuffer>().setActivateControllersRequest(
517 {ctrlsToActVec.begin(), ctrlsToActVec.end()});
518 }
519
520 void
522 const std::vector<NJointControllerBasePtr>& ctrlsToDelVec)
523 {
524 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
525 auto guard = getGuard();
526 throwIfDevicesNotReady(__FUNCTION__);
527 if (ctrlsToDelVec.empty())
528 {
529 return;
530 }
531 //check if all can be deleted
532 for (const auto& nJointCtrl : ctrlsToDelVec)
533 {
534 if (!nJointCtrl->isDeletable())
535 {
536 throw LogicError{"The NJointControllerBase '" + nJointCtrl->getInstanceName() +
537 "' can't be deleted since this operation is not allowed for this "
538 "controller! (no NJointControllerBase was deleted)"};
539 }
540 if (nJointCtrl->isControllerActive() || nJointCtrl->isControllerRequested())
541 {
542 throw LogicError{"The NJointControllerBase '" + nJointCtrl->getInstanceName() +
543 "' can't be deleted since it is active or requested! (no "
544 "NJointControllerBase was deleted)"};
545 }
546 }
547 for (const auto& nJointCtrl : ctrlsToDelVec)
548 {
549 const auto name = nJointCtrl->getInstanceName();
550 //deletion is done in a different thread since this call may be done by the controller (protection against use after free)
551 nJointControllersToBeDeleted[name] = std::move(nJointCtrl);
552 nJointControllers.erase(name);
553 ARMARX_VERBOSE << "added NJointControllerBase '" << name << "' to be deleted";
554 }
555 }
556
557 void
559 const Ice::Current&)
560 {
561 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
563 }
564
565 void
567 const Ice::Current&)
568 {
569 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
571 }
572
573 void
575 {
576 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
578 }
579
580 void
582 const std::vector<NJointControllerBasePtr>& ctrlsToDelVec)
583 {
584 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
585 auto guard = getGuard();
586 throwIfDevicesNotReady(__FUNCTION__);
587 if (ctrlsToDelVec.empty())
588 {
589 return;
590 }
591 deactivateNJointControllers(ctrlsToDelVec);
592 while (std::any_of(ctrlsToDelVec.begin(),
593 ctrlsToDelVec.end(),
594 [](const NJointControllerBasePtr& ctrl)
595 { return ctrl->isControllerActive(); }))
596 {
597 if (isShuttingDown())
598 {
599 return;
600 }
601 std::this_thread::sleep_for(std::chrono::microseconds{100});
602 }
603 deleteNJointControllers(ctrlsToDelVec);
604 }
605
606 NJointControllerClassDescription
608 const Ice::Current&) const
609 {
610 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
613 {
614 //this phase should only last short so busy waiting is ok
615 std::this_thread::sleep_for(std::chrono::milliseconds(50));
616 }
617 auto guard = getGuard();
618 throwIfDevicesNotReady(__FUNCTION__);
619 checkNJointControllerClassName(className);
620 NJointControllerClassDescription data;
621 data.className = className;
622 if (NJointControllerRegistry::get(className)->hasRemoteConfiguration())
623 {
624 data.configDescription =
625 NJointControllerRegistry::get(className)->GenerateConfigDescription(
626 controllerCreateRobot,
627 _module<Devices>().getControlDevicesConstPtr(),
628 _module<Devices>().getSensorDevicesConstPtr());
629 }
630 return data;
631 }
632
633 NJointControllerClassDescriptionSeq
635 {
636 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
637 std::size_t tries = 200;
640 {
641 //this phase should only last short so busy waiting is ok
642 std::this_thread::sleep_for(std::chrono::milliseconds(50));
643 if (!--tries)
644 {
645 throw RuntimeError{"RobotUnit::getNJointControllerClassDescriptions: it took too "
646 "long to for the unit to get in a valid state"};
647 }
648 }
649 auto guard = getGuard();
650 NJointControllerClassDescriptionSeq r;
651 r.reserve(NJointControllerRegistry::getKeys().size());
652 for (const auto& key : NJointControllerRegistry::getKeys())
653 {
654 r.emplace_back(getNJointControllerClassDescription(key));
655 }
656 return r;
657 }
658
659 NJointControllerInterfacePrx
660 ControllerManagement::getNJointController(const std::string& name, const Ice::Current&) const
661 {
662 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
663 NJointControllerBasePtr ctrl;
664 {
665 auto guard = getGuard();
666 auto it = nJointControllers.find(name);
667 if (it == nJointControllers.end())
668 {
669 return nullptr;
670 }
671 ctrl = it->second;
672 }
673 return NJointControllerInterfacePrx::uncheckedCast(ctrl->getProxy(-1, true));
674 }
675
676 NJointControllerStatus
678 const Ice::Current&) const
679 {
680 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
681 auto guard = getGuard();
682 throwIfDevicesNotReady(__FUNCTION__);
683 return getNJointControllerNotNull(name)->getControllerStatus();
684 }
685
686 NJointControllerStatusSeq
688 {
689 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
690 auto guard = getGuard();
691 if (!areDevicesReady())
692 {
693 return {};
694 }
695 NJointControllerStatusSeq r;
696 r.reserve(nJointControllers.size());
697 for (const auto& nJointCtrl : nJointControllers)
698 {
699 r.emplace_back(nJointCtrl.second->getControllerStatus());
700 }
701 return r;
702 }
703
704 NJointControllerDescription
706 const Ice::Current&) const
707 {
708 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
709 NJointControllerBasePtr nJointCtrl;
710 {
711 auto guard = getGuard();
712 throwIfDevicesNotReady(__FUNCTION__);
713 nJointCtrl = getNJointControllerNotNull(name);
714 }
715 return nJointCtrl->getControllerDescription();
716 }
717
718 NJointControllerDescriptionSeq
720 {
721 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
722 std::map<std::string, NJointControllerBasePtr> nJointControllersCopy;
723 {
724 auto guard = getGuard();
725 if (!areDevicesReady())
726 {
727 return {};
728 }
729 nJointControllersCopy = nJointControllers;
730 }
731 NJointControllerDescriptionSeq r;
732 r.reserve(nJointControllersCopy.size());
733 for (const auto& nJointCtrl : nJointControllersCopy)
734 {
735 r.emplace_back(nJointCtrl.second->getControllerDescription());
736 }
737 return r;
738 }
739
740 NJointControllerDescriptionWithStatus
742 const Ice::Current&) const
743 {
744 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
745 NJointControllerBasePtr nJointCtrl;
746 {
747 auto guard = getGuard();
748 throwIfDevicesNotReady(__FUNCTION__);
749 nJointCtrl = getNJointControllerNotNull(name);
750 }
751 return nJointCtrl->getControllerDescriptionWithStatus();
752 }
753
754 NJointControllerDescriptionWithStatusSeq
756 {
757 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
758 std::map<std::string, NJointControllerBasePtr> nJointControllersCopy;
759 {
760 auto guard = getGuard();
761 if (!areDevicesReady())
762 {
763 return {};
764 }
765 nJointControllersCopy = nJointControllers;
766 }
767 NJointControllerDescriptionWithStatusSeq r;
768 r.reserve(nJointControllersCopy.size());
769 for (const auto& nJointCtrl : nJointControllersCopy)
770 {
771 r.emplace_back(nJointCtrl.second->getControllerDescriptionWithStatus());
772 }
773 return r;
774 }
775
776 void
777 ControllerManagement::removeNJointControllers(
778 std::map<std::string, NJointControllerBasePtr>& ctrls,
779 bool blocking,
780 RobotUnitListenerPrx l)
781 {
782 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
783 for (auto& n2NJointCtrl : ctrls)
784 {
785 NJointControllerBasePtr& nJointCtrl = n2NJointCtrl.second;
786 if (blocking)
787 {
788 ARMARX_VERBOSE << "deleted NJointControllerBase " << n2NJointCtrl.first;
789 getArmarXManager()->removeObjectBlocking(nJointCtrl->getName());
790 }
791 else
792 {
793 ARMARX_VERBOSE << "deleted NJointControllerBase " << n2NJointCtrl.first;
794 getArmarXManager()->removeObjectBlocking(nJointCtrl->getName());
795 }
796 if (l)
797 {
798 l->nJointControllerDeleted(n2NJointCtrl.first);
799 }
800 }
801 ctrls.clear();
802 }
803
804 void
805 ControllerManagement::removeNJointControllersToBeDeleted(bool blocking, RobotUnitListenerPrx l)
806 {
807 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
808 removeNJointControllers(nJointControllersToBeDeleted, blocking, l);
809 }
810
811 void
812 ControllerManagement::_preFinishRunning()
813 {
814 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
815 //NJoint queued for deletion (some could still be in the queue)
816 ARMARX_DEBUG << "remove NJointControllers queued for deletion";
817 removeNJointControllersToBeDeleted();
818 ARMARX_DEBUG << "remove NJointControllers queued for deletion...done";
819 //NJoint
820 ARMARX_DEBUG << "remove NJointControllers";
821 removeNJointControllers(nJointControllers);
822 ARMARX_DEBUG << "remove NJointControllers...done";
823 }
824
825 void
826 ControllerManagement::_postFinishRunning()
827 {
828 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
829 nJointControllers.clear();
830 }
831
835
836 void
837 ControllerManagement::_preOnInitRobotUnit()
838 {
839 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
840 controllerCreateRobot = _module<RobotData>().cloneRobot();
841 }
842
843 void
844 ControllerManagement::updateNJointControllerRequestedState(
845 const std::set<NJointControllerBasePtr>& request)
846 {
847 throwIfInControlThread(BOOST_CURRENT_FUNCTION);
848 ARMARX_DEBUG << "set requested state for NJoint controllers";
849 for (const auto& name2NJoint : nJointControllers)
850 {
851 NJointControllerAttorneyForControllerManagement::SetRequested(
852 name2NJoint.second, request.count(name2NJoint.second));
853 }
854 }
855} // namespace armarx::RobotUnitModule
#define ARMARX_STREAM_PRINTER
use this macro to write output code that is executed when printed and thus not executed if the debug ...
Definition Logging.h:310
constexpr T c
IceManagerPtr getIceManager() const
Returns the IceManager.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
static std::optional< std::vector< char > > AreNotInConflict(ItT first, ItT last)
static const std::unique_ptr< NJointControllerRegistryEntry > & get(const std::string &key)
Definition Registrar.h:85
NJointControllerDescriptionWithStatusSeq getNJointControllerDescriptionsWithStatuses(const Ice::Current &=Ice::emptyCurrent) const override
Returns the status and description of all NJointControllers.
NJointControllerClassDescription getNJointControllerClassDescription(const std::string &className, const Ice::Current &=Ice::emptyCurrent) const override
getNJointControllerClassDescription
NJointControllerDescription getNJointControllerDescription(const std::string &name, const Ice::Current &=Ice::emptyCurrent) const override
Returns the description of the NJointControllerBase.
const NJointControllerBasePtr & getNJointControllerNotNull(const std::string &name) const
Returns a pointer to the NJointControllerBase.
StringNJointControllerPrxDictionary getAllNJointControllers(const Ice::Current &=Ice::emptyCurrent) const override
Returns proxies to all NJointControllers.
void activateNJointControllers(const Ice::StringSeq &names, const Ice::Current &=Ice::emptyCurrent) override
Requests activation for the given NJointControllers.
void deactivateNJointController(const std::string &name, const Ice::Current &=Ice::emptyCurrent) override
Requests deactivation for the given NJointControllerBase.
NJointControllerStatusSeq getNJointControllerStatuses(const Ice::Current &=Ice::emptyCurrent) const override
Returns the status of all NJointControllers.
NJointControllerClassDescriptionSeq getNJointControllerClassDescriptions(const Ice::Current &=Ice::emptyCurrent) const override
getNJointControllerClassDescriptions
NJointControllerDescriptionWithStatus getNJointControllerDescriptionWithStatus(const std::string &name, const Ice::Current &=Ice::emptyCurrent) const override
Returns the status and description of the NJointControllerBase.
NJointControllerInterfacePrx createOrReplaceNJointController(const std::string &className, const std::string &instanceName, const NJointControllerConfigPtr &config, const Ice::Current &=Ice::emptyCurrent) override
Deletes any NJointControllerBase with the given name and creates a new one.
Ice::StringSeq getActivatedNJointControllerNames(const Ice::Current &=Ice::emptyCurrent) const override
Returns the names of all activated NJointControllers.
void deactivateAndDeleteNJointControllers(const Ice::StringSeq &names, const Ice::Current &) override
Queues the given NJointControllers for deletion and deactivates them if necessary.
void activateNJointController(const std::string &name, const Ice::Current &=Ice::emptyCurrent) override
Requests activation for the given NJointControllerBase.
NJointControllerDescriptionSeq getNJointControllerDescriptions(const Ice::Current &=Ice::emptyCurrent) const override
Returns the description of all NJointControllers.
NJointControllerStatus getNJointControllerStatus(const std::string &name, const Ice::Current &=Ice::emptyCurrent) const override
Returns the status of the NJointControllerBase.
Ice::StringSeq getNJointControllerNames(const Ice::Current &=Ice::emptyCurrent) const override
Returns the names of all NJointControllers.
void deactivateNJointControllers(const Ice::StringSeq &names, const Ice::Current &=Ice::emptyCurrent) override
Requests deactivation for the given NJointControllers.
std::vector< armarx::NJointControllerBasePtr > getNJointControllersNotNull(const std::vector< std::string > &names) const
Returns pointers to the NJointControllers.
void switchNJointControllerSetup(const Ice::StringSeq &newSetup, const Ice::Current &=Ice::emptyCurrent) override
Changes the set of requested NJointControllers to the given set.
Ice::StringSeq getNJointControllerClassNames(const Ice::Current &=Ice::emptyCurrent) const override
Returns the names of all available classes of NJointControllerBase.
void deactivateAndDeleteNJointController(const std::string &name, const Ice::Current &=Ice::emptyCurrent) override
Queues the given NJointControllerBase for deletion and deactivates it if necessary.
Ice::StringSeq getRequestedNJointControllerNames(const Ice::Current &=Ice::emptyCurrent) const override
Returns the names of all requested NJointControllers.
void deleteNJointController(const std::string &name, const Ice::Current &=Ice::emptyCurrent) override
Queues the given NJointControllerBase for deletion.
NJointControllerInterfacePrx getNJointController(const std::string &name, const Ice::Current &=Ice::emptyCurrent) const override
Returns a proxy to the NJointControllerBase.
NJointControllerInterfacePrx createNJointController(const std::string &className, const std::string &instanceName, const NJointControllerConfigPtr &config, const Ice::Current &=Ice::emptyCurrent) override
Cretes a NJointControllerBase.
NJointControllerInterfacePrx createNJointControllerFromVariantConfig(const std::string &className, const std::string &instanceName, const StringVariantBaseMap &variants, const Ice::Current &=Ice::emptyCurrent) override
Cretes a NJointControllerBase.
void deleteNJointControllers(const Ice::StringSeq &names, const Ice::Current &=Ice::emptyCurrent) override
Queues the given NJointControllers for deletion.
RobotUnitState getRobotUnitState() const
Returns the RobotUnit's State.
T & _module()
Returns this as ref to the given type.
bool areDevicesReady() const
Returns whether Devices are ready.
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.
bool isShuttingDown() const
Returns whether the RobotUnit is shutting down.
void throwIfDevicesNotReady(const std::string &fnc) const
Throws if the Devices are not ready.
This class allows minimal access to private members of NJointControllerBase in a sane fashion for Con...
#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_NOT_EQUAL(lhs, rhs)
This macro evaluates whether lhs is inequal (!=) rhs and if it turns out to be false it will throw an...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_FATAL
The logging level for unexpected behaviour, that will lead to a seriously malfunctioning program and ...
Definition Logging.h:199
#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_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
std::map< std::string, VariantBasePtr > StringVariantBaseMap
void getMapKeys(const MapType &map, OutputIteratorType it)
Definition algorithm.h:173
#define ARMARX_TRACE
Definition trace.h:77