42 GetNonNullNames(
const Cont&
c)
44 Ice::StringSeq result;
45 result.reserve(
c.size());
46 for (
const auto& e :
c)
50 result.emplace_back(e->getName());
65 SetRequested(
const NJointControllerBasePtr& nJointCtrl,
bool requested)
67 nJointCtrl->isRequested = requested;
90 ControllerManagement::checkNJointControllerClassName(
const std::string& className)
const
96 ss <<
"Requested controller class '" << className
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/-/"
104 throw InvalidArgumentException{ss.str()};
108 std::vector<NJointControllerBasePtr>
114 std::vector<NJointControllerBasePtr> ctrl;
115 ctrl.reserve(names.size());
116 for (
const auto& name : names)
123 const NJointControllerBasePtr&
129 auto it = nJointControllers.find(name);
130 if (it == nJointControllers.end())
132 std::stringstream ss;
133 ss <<
"RobotUnit: there is no NJointControllerBase with name '" << name
135 throw InvalidArgumentException{ss.str()};
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;
144 throw InvalidArgumentException{ss.str()};
156 StringNJointControllerPrxDictionary
160 std::map<std::string, NJointControllerBasePtr> nJointControllersCopy;
164 nJointControllersCopy = nJointControllers;
166 StringNJointControllerPrxDictionary result;
167 for (
const auto& pair : nJointControllersCopy)
170 NJointControllerInterfacePrx::uncheckedCast(pair.second->getProxy(-1,
true));
175 NJointControllerInterfacePrx
177 const std::string& instanceName,
178 const NJointControllerConfigPtr& config,
183 return NJointControllerInterfacePrx::uncheckedCast(
188 NJointControllerInterfacePrx
190 const std::string& className,
191 const std::string& instanceName,
197 checkNJointControllerClassName(className);
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 "
209 throw InvalidArgumentException{ss.str()};
218 NJointControllerInterfacePrx
220 const std::string& instanceName,
221 const NJointControllerConfigPtr& config,
244 ARMARX_INFO <<
"wiating until controller '" << instanceName <<
"' is deleted";
254 ARMARX_INFO <<
"wiating until controller '" << instanceName <<
"' is removed from ice";
256 return NJointControllerInterfacePrx::uncheckedCast(
261 const NJointControllerBasePtr&
263 const std::string& instanceName,
264 const NJointControllerConfigPtr& config,
271 if (instanceName.empty())
273 ARMARX_ERROR <<
"The instance name is empty! (give a unique name)";
274 throw InvalidArgumentException{
"The instance name is empty! (give a unique name)"};
277 checkNJointControllerClassName(className);
281 if (nJointControllers.count(instanceName))
283 std::stringstream ss;
284 ss <<
"There already is a controller instance with the name '" << instanceName
285 <<
"'. Use a different instance name instead."
288 throw InvalidArgumentException{ss.str()};
293 NJointControllerBasePtr nJointCtrl =
294 factory->create(
this, config, controllerCreateRobot, deletable,
internal, instanceName);
296 <<
"The NJointControllerBase '" << nJointCtrl->getName()
297 <<
"' uses no ControlDevice! (It has to use at least one)";
300 nJointControllers[instanceName] = std::move(nJointCtrl);
301 _module<Publisher>().getRobotUnitListenerProxy()->nJointControllerCreated(instanceName);
302 return nJointControllers.at(instanceName);
320 std::vector<std::string>
322 const std::vector<NJointControllerBasePtr>& ctrls)
const
325 std::vector<std::string> result;
326 result.reserve(ctrls.size());
327 for (
const auto& ctrl : ctrls)
331 result.emplace_back(ctrl->getInstanceName());
361 const std::vector<NJointControllerBasePtr>& ctrlsToActVec)
364 if (ctrlsToActVec.empty())
371 std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>> ctrlsToAct{
372 ctrlsToActVec.begin(), ctrlsToActVec.end()};
375 if (std::all_of(ctrlsToActVec.begin(),
377 [](
const NJointControllerBasePtr& ctrl)
378 { return ctrl->isControllerActive(); }))
384 std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>>
385 ctrlsAlreadyRequested{ctrlVector.begin(), ctrlVector.end()};
386 ctrlsAlreadyRequested.erase(
nullptr);
388 std::vector<char> inuse;
394 std::stringstream ss;
395 ss <<
"activateNJointControllers: requested controllers are in "
396 "conflict!\ncontrollers:\n"
399 throw InvalidArgumentException{ss.str()};
401 inuse = std::move(*r);
403 ARMARX_DEBUG <<
"all requested controllers are conflict free" << std::flush;
406 for (
const auto c : inuse)
411 ARMARX_DEBUG <<
"inuse field (request)\n" << printInUse;
414 if (ctrlsAlreadyRequested.empty())
416 ARMARX_DEBUG <<
"no already requested NJointControllers";
418 for (
const NJointControllerBasePtr& nJointCtrl : ctrlsAlreadyRequested)
420 if (ctrlsToAct.count(nJointCtrl))
424 auto r = nJointCtrl->isNotInConflictWith(inuse);
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);
435 ARMARX_INFO <<
"removing already requested NJointControllerBase '"
436 << nJointCtrl->getInstanceName()
437 <<
"' from list of requested controllers";
469 const std::vector<NJointControllerBasePtr>& ctrlsDeacVec)
474 if (ctrlsDeacVec.empty())
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)
484 ctrls.erase(nJointCtrlToDeactivate);
486 if (ctrls.size() == ctrlsNum)
517 {ctrlsToActVec.begin(), ctrlsToActVec.end()});
522 const std::vector<NJointControllerBasePtr>& ctrlsToDelVec)
527 if (ctrlsToDelVec.empty())
532 for (
const auto& nJointCtrl : ctrlsToDelVec)
534 if (!nJointCtrl->isDeletable())
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)"};
540 if (nJointCtrl->isControllerActive() || nJointCtrl->isControllerRequested())
542 throw LogicError{
"The NJointControllerBase '" + nJointCtrl->getInstanceName() +
543 "' can't be deleted since it is active or requested! (no "
544 "NJointControllerBase was deleted)"};
547 for (
const auto& nJointCtrl : ctrlsToDelVec)
549 const auto name = nJointCtrl->getInstanceName();
551 nJointControllersToBeDeleted[name] = std::move(nJointCtrl);
552 nJointControllers.erase(name);
553 ARMARX_VERBOSE <<
"added NJointControllerBase '" << name <<
"' to be deleted";
582 const std::vector<NJointControllerBasePtr>& ctrlsToDelVec)
587 if (ctrlsToDelVec.empty())
592 while (std::any_of(ctrlsToDelVec.begin(),
594 [](
const NJointControllerBasePtr& ctrl)
595 { return ctrl->isControllerActive(); }))
601 std::this_thread::sleep_for(std::chrono::microseconds{100});
606 NJointControllerClassDescription
608 const Ice::Current&)
const
615 std::this_thread::sleep_for(std::chrono::milliseconds(50));
619 checkNJointControllerClassName(className);
620 NJointControllerClassDescription
data;
621 data.className = className;
624 data.configDescription =
626 controllerCreateRobot,
633 NJointControllerClassDescriptionSeq
637 std::size_t tries = 200;
642 std::this_thread::sleep_for(std::chrono::milliseconds(50));
645 throw RuntimeError{
"RobotUnit::getNJointControllerClassDescriptions: it took too "
646 "long to for the unit to get in a valid state"};
650 NJointControllerClassDescriptionSeq r;
659 NJointControllerInterfacePrx
663 NJointControllerBasePtr ctrl;
666 auto it = nJointControllers.find(name);
667 if (it == nJointControllers.end())
673 return NJointControllerInterfacePrx::uncheckedCast(ctrl->getProxy(-1,
true));
676 NJointControllerStatus
678 const Ice::Current&)
const
686 NJointControllerStatusSeq
695 NJointControllerStatusSeq r;
696 r.reserve(nJointControllers.size());
697 for (
const auto& nJointCtrl : nJointControllers)
699 r.emplace_back(nJointCtrl.second->getControllerStatus());
704 NJointControllerDescription
706 const Ice::Current&)
const
709 NJointControllerBasePtr nJointCtrl;
715 return nJointCtrl->getControllerDescription();
718 NJointControllerDescriptionSeq
722 std::map<std::string, NJointControllerBasePtr> nJointControllersCopy;
729 nJointControllersCopy = nJointControllers;
731 NJointControllerDescriptionSeq r;
732 r.reserve(nJointControllersCopy.size());
733 for (
const auto& nJointCtrl : nJointControllersCopy)
735 r.emplace_back(nJointCtrl.second->getControllerDescription());
740 NJointControllerDescriptionWithStatus
742 const Ice::Current&)
const
745 NJointControllerBasePtr nJointCtrl;
751 return nJointCtrl->getControllerDescriptionWithStatus();
754 NJointControllerDescriptionWithStatusSeq
758 std::map<std::string, NJointControllerBasePtr> nJointControllersCopy;
765 nJointControllersCopy = nJointControllers;
767 NJointControllerDescriptionWithStatusSeq r;
768 r.reserve(nJointControllersCopy.size());
769 for (
const auto& nJointCtrl : nJointControllersCopy)
771 r.emplace_back(nJointCtrl.second->getControllerDescriptionWithStatus());
777 ControllerManagement::removeNJointControllers(
778 std::map<std::string, NJointControllerBasePtr>& ctrls,
780 RobotUnitListenerPrx l)
783 for (
auto& n2NJointCtrl : ctrls)
785 NJointControllerBasePtr& nJointCtrl = n2NJointCtrl.second;
788 ARMARX_VERBOSE <<
"deleted NJointControllerBase " << n2NJointCtrl.first;
793 ARMARX_VERBOSE <<
"deleted NJointControllerBase " << n2NJointCtrl.first;
798 l->nJointControllerDeleted(n2NJointCtrl.first);
805 ControllerManagement::removeNJointControllersToBeDeleted(
bool blocking, RobotUnitListenerPrx l)
808 removeNJointControllers(nJointControllersToBeDeleted, blocking, l);
812 ControllerManagement::_preFinishRunning()
816 ARMARX_DEBUG <<
"remove NJointControllers queued for deletion";
817 removeNJointControllersToBeDeleted();
818 ARMARX_DEBUG <<
"remove NJointControllers queued for deletion...done";
821 removeNJointControllers(nJointControllers);
826 ControllerManagement::_postFinishRunning()
829 nJointControllers.clear();
837 ControllerManagement::_preOnInitRobotUnit()
844 ControllerManagement::updateNJointControllerRequestedState(
845 const std::set<NJointControllerBasePtr>& request)
848 ARMARX_DEBUG <<
"set requested state for NJoint controllers";
849 for (
const auto& name2NJoint : nJointControllers)
851 NJointControllerAttorneyForControllerManagement::SetRequested(
852 name2NJoint.second, request.count(name2NJoint.second));
#define ARMARX_STREAM_PRINTER
use this macro to write output code that is executed when printed and thus not executed if the debug ...
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 bool has(const std::string &key)
static const std::unique_ptr< NJointControllerRegistryEntry > & get(const std::string &key)
static std::vector< std::string > getKeys()
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...
friend class ControllerManagement
#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.
#define ARMARX_FATAL
The logging level for unexpected behaviour, that will lead to a seriously malfunctioning program and ...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
#define ARMARX_VERBOSE
The logging level for verbose information.
std::map< std::string, VariantBasePtr > StringVariantBaseMap
void getMapKeys(const MapType &map, OutputIteratorType it)