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()};
290 if (nJointControllersToBeDeleted.count(instanceName))
292 std::stringstream ss;
293 ss <<
"The controller instance '" << instanceName
294 <<
"' is still pending deletion. Retry later or use a different name.";
296 throw InvalidArgumentException{ss.str()};
301 NJointControllerBasePtr nJointCtrl =
302 factory->create(
this, config, controllerCreateRobot, deletable,
internal, instanceName);
304 <<
"The NJointControllerBase '" << nJointCtrl->getName()
305 <<
"' uses no ControlDevice! (It has to use at least one)";
308 nJointControllers[instanceName] = std::move(nJointCtrl);
309 _module<Publisher>().getRobotUnitListenerProxy()->nJointControllerCreated(instanceName);
310 return nJointControllers.at(instanceName);
328 std::vector<std::string>
330 const std::vector<NJointControllerBasePtr>& ctrls)
const
333 std::vector<std::string> result;
334 result.reserve(ctrls.size());
335 for (
const auto& ctrl : ctrls)
339 result.emplace_back(ctrl->getInstanceName());
369 const std::vector<NJointControllerBasePtr>& ctrlsToActVec)
372 if (ctrlsToActVec.empty())
379 std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>> ctrlsToAct{
380 ctrlsToActVec.begin(), ctrlsToActVec.end()};
383 if (std::all_of(ctrlsToActVec.begin(),
385 [](
const NJointControllerBasePtr& ctrl)
386 { return ctrl->isControllerActive(); }))
392 std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>>
393 ctrlsAlreadyRequested{ctrlVector.begin(), ctrlVector.end()};
394 ctrlsAlreadyRequested.erase(
nullptr);
396 std::vector<char> inuse;
402 std::stringstream ss;
403 ss <<
"activateNJointControllers: requested controllers are in "
404 "conflict!\ncontrollers:\n"
407 throw InvalidArgumentException{ss.str()};
409 inuse = std::move(*r);
411 ARMARX_DEBUG <<
"all requested controllers are conflict free" << std::flush;
414 for (
const auto c : inuse)
419 ARMARX_DEBUG <<
"inuse field (request)\n" << printInUse;
422 if (ctrlsAlreadyRequested.empty())
424 ARMARX_DEBUG <<
"no already requested NJointControllers";
426 for (
const NJointControllerBasePtr& nJointCtrl : ctrlsAlreadyRequested)
428 if (ctrlsToAct.count(nJointCtrl))
432 auto r = nJointCtrl->isNotInConflictWith(inuse);
435 ARMARX_DEBUG <<
"keeping already requested NJointControllerBase '"
436 << nJointCtrl->getInstanceName()
437 <<
"' in list of requested controllers";
438 ctrlsToAct.insert(nJointCtrl);
439 inuse = std::move(*r);
443 ARMARX_INFO <<
"removing already requested NJointControllerBase '"
444 << nJointCtrl->getInstanceName()
445 <<
"' from list of requested controllers";
477 const std::vector<NJointControllerBasePtr>& ctrlsDeacVec)
482 if (ctrlsDeacVec.empty())
487 std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>> ctrls{
488 ctrlVector.begin(), ctrlVector.end()};
489 const std::size_t ctrlsNum = ctrls.size();
490 for (
const auto& nJointCtrlToDeactivate : ctrlsDeacVec)
492 ctrls.erase(nJointCtrlToDeactivate);
494 if (ctrls.size() == ctrlsNum)
525 {ctrlsToActVec.begin(), ctrlsToActVec.end()});
530 const std::vector<NJointControllerBasePtr>& ctrlsToDelVec)
535 if (ctrlsToDelVec.empty())
540 for (
const auto& nJointCtrl : ctrlsToDelVec)
542 if (!nJointCtrl->isDeletable())
544 throw LogicError{
"The NJointControllerBase '" + nJointCtrl->getInstanceName() +
545 "' can't be deleted since this operation is not allowed for this "
546 "controller! (no NJointControllerBase was deleted)"};
548 if (nJointCtrl->isControllerActive() || nJointCtrl->isControllerRequested())
550 throw LogicError{
"The NJointControllerBase '" + nJointCtrl->getInstanceName() +
551 "' can't be deleted since it is active or requested! (no "
552 "NJointControllerBase was deleted)"};
555 for (
const auto& nJointCtrl : ctrlsToDelVec)
557 const auto name = nJointCtrl->getInstanceName();
560 <<
"The controller '" << name <<
"' is already pending deletion";
561 nJointControllersToBeDeleted[name] = std::move(nJointCtrl);
562 nJointControllers.erase(name);
563 ARMARX_VERBOSE <<
"added NJointControllerBase '" << name <<
"' to be deleted";
592 const std::vector<NJointControllerBasePtr>& ctrlsToDelVec)
597 if (ctrlsToDelVec.empty())
602 while (std::any_of(ctrlsToDelVec.begin(),
604 [](
const NJointControllerBasePtr& ctrl)
605 { return ctrl->isControllerActive(); }))
611 std::this_thread::sleep_for(std::chrono::microseconds{100});
616 NJointControllerClassDescription
618 const Ice::Current&)
const
625 std::this_thread::sleep_for(std::chrono::milliseconds(50));
629 checkNJointControllerClassName(className);
630 NJointControllerClassDescription
data;
631 data.className = className;
634 data.configDescription =
636 controllerCreateRobot,
643 NJointControllerClassDescriptionSeq
647 std::size_t tries = 200;
652 std::this_thread::sleep_for(std::chrono::milliseconds(50));
655 throw RuntimeError{
"RobotUnit::getNJointControllerClassDescriptions: it took too "
656 "long to for the unit to get in a valid state"};
660 NJointControllerClassDescriptionSeq r;
669 NJointControllerInterfacePrx
673 NJointControllerBasePtr ctrl;
676 auto it = nJointControllers.find(name);
677 if (it == nJointControllers.end())
683 return NJointControllerInterfacePrx::uncheckedCast(ctrl->getProxy(-1,
true));
686 NJointControllerStatus
688 const Ice::Current&)
const
696 NJointControllerStatusSeq
705 NJointControllerStatusSeq r;
706 r.reserve(nJointControllers.size());
707 for (
const auto& nJointCtrl : nJointControllers)
709 r.emplace_back(nJointCtrl.second->getControllerStatus());
714 NJointControllerDescription
716 const Ice::Current&)
const
719 NJointControllerBasePtr nJointCtrl;
725 return nJointCtrl->getControllerDescription();
728 NJointControllerDescriptionSeq
732 std::map<std::string, NJointControllerBasePtr> nJointControllersCopy;
739 nJointControllersCopy = nJointControllers;
741 NJointControllerDescriptionSeq r;
742 r.reserve(nJointControllersCopy.size());
743 for (
const auto& nJointCtrl : nJointControllersCopy)
745 r.emplace_back(nJointCtrl.second->getControllerDescription());
750 NJointControllerDescriptionWithStatus
752 const Ice::Current&)
const
755 NJointControllerBasePtr nJointCtrl;
761 return nJointCtrl->getControllerDescriptionWithStatus();
764 NJointControllerDescriptionWithStatusSeq
768 std::map<std::string, NJointControllerBasePtr> nJointControllersCopy;
775 nJointControllersCopy = nJointControllers;
777 NJointControllerDescriptionWithStatusSeq r;
778 r.reserve(nJointControllersCopy.size());
779 for (
const auto& nJointCtrl : nJointControllersCopy)
781 r.emplace_back(nJointCtrl.second->getControllerDescriptionWithStatus());
787 ControllerManagement::removeNJointControllers(
788 std::map<std::string, NJointControllerBasePtr>& ctrls,
790 RobotUnitListenerPrx l)
793 for (
auto& n2NJointCtrl : ctrls)
795 NJointControllerBasePtr& nJointCtrl = n2NJointCtrl.second;
798 ARMARX_VERBOSE <<
"deleted NJointControllerBase " << n2NJointCtrl.first;
803 ARMARX_VERBOSE <<
"deleted NJointControllerBase " << n2NJointCtrl.first;
808 l->nJointControllerDeleted(n2NJointCtrl.first);
815 ControllerManagement::removeNJointControllersToBeDeleted(
bool blocking, RobotUnitListenerPrx l)
818 removeNJointControllers(nJointControllersToBeDeleted, blocking, l);
822 ControllerManagement::_preFinishRunning()
826 ARMARX_DEBUG <<
"remove NJointControllers queued for deletion";
827 removeNJointControllersToBeDeleted();
828 ARMARX_DEBUG <<
"remove NJointControllers queued for deletion...done";
831 removeNJointControllers(nJointControllers);
836 ControllerManagement::_postFinishRunning()
839 nJointControllers.clear();
847 ControllerManagement::_preOnInitRobotUnit()
854 ControllerManagement::updateNJointControllerRequestedState(
855 const std::set<NJointControllerBasePtr>& request)
858 ARMARX_DEBUG <<
"set requested state for NJoint controllers";
859 for (
const auto& name2NJoint : nJointControllers)
861 NJointControllerAttorneyForControllerManagement::SetRequested(
862 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_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#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)