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  {
62  friend class ControllerManagement;
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
176  ControllerManagement::createNJointController(const std::string& className,
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  }
211  return createNJointController(
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  {
224  ARMARX_TRACE;
225  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
226  {
227  ARMARX_TRACE;
228  auto guard = getGuard();
229  if (getNJointController(instanceName))
230  {
231  ARMARX_TRACE;
233  }
234  }
235  ARMARX_TRACE;
236  while (getNJointController(instanceName))
237  {
238  ARMARX_TRACE;
239  if (isShuttingDown())
240  {
241  ARMARX_TRACE;
242  return nullptr;
243  }
244  ARMARX_INFO << "wiating until controller '" << instanceName << "' is deleted";
245  }
246  while (getArmarXManager()->getIceManager()->isObjectReachable(instanceName))
247  {
248  ARMARX_TRACE;
249  if (isShuttingDown())
250  {
251  ARMARX_TRACE;
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&
262  ControllerManagement::createNJointController(const std::string& className,
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
292  ARMARX_CHECK_EXPRESSION(factory);
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 
833  {
834  }
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
armarx::RobotUnitModule::ControllerManagement::getNJointControllerClassDescription
NJointControllerClassDescription getNJointControllerClassDescription(const std::string &className, const Ice::Current &=Ice::emptyCurrent) const override
getNJointControllerClassDescription
Definition: RobotUnitModuleControllerManagement.cpp:607
armarx::RobotUnitModule::ModuleBase::isShuttingDown
bool isShuttingDown() const
Returns whether the RobotUnit is shutting down.
Definition: RobotUnitModuleBase.h:647
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::RobotUnitModule::ControllerManagement::deactivateAndDeleteNJointControllers
void deactivateAndDeleteNJointControllers(const Ice::StringSeq &names, const Ice::Current &) override
Queues the given NJointControllers for deletion and deactivates them if necessary.
Definition: RobotUnitModuleControllerManagement.cpp:566
armarx::ManagedIceObject::getIceManager
IceManagerPtr getIceManager() const
Returns the IceManager.
Definition: ManagedIceObject.cpp:353
ARMARX_CHECK_NOT_EQUAL
#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...
Definition: ExpressionException.h:137
RobotUnitModuleControllerManagement.h
armarx::RobotUnitModule::ControllerManagement::~ControllerManagement
~ControllerManagement()
Definition: RobotUnitModuleControllerManagement.cpp:832
algorithm.h
armarx::Registrar::get
static const RegisteredType & get(const KeyType &key)
Returns the registered object for the given key.
Definition: Registrar.h:84
armarx::RobotUnitModule::ControllerManagement::getNJointControllerClassNames
Ice::StringSeq getNJointControllerClassNames(const Ice::Current &=Ice::emptyCurrent) const override
Returns the names of all available classes of NJointControllerBase.
Definition: RobotUnitModuleControllerManagement.cpp:306
armarx::StringVariantBaseMap
std::map< std::string, VariantBasePtr > StringVariantBaseMap
Definition: ManagedIceObject.h:111
NJointControllerBase.h
armarx::Registrar::has
static bool has(const KeyType &key)
Definition: Registrar.h:94
OnScopeExit.h
ArmarXManager.h
armarx::RobotUnitModule::ControllerManagement::getNJointControllerDescription
NJointControllerDescription getNJointControllerDescription(const std::string &name, const Ice::Current &=Ice::emptyCurrent) const override
Returns the description of the NJointControllerBase.
Definition: RobotUnitModuleControllerManagement.cpp:705
armarx::RobotUnitModule::ControllerManagement::deactivateAndDeleteNJointController
void deactivateAndDeleteNJointController(const std::string &name, const Ice::Current &=Ice::emptyCurrent) override
Queues the given NJointControllerBase for deletion and deactivates it if necessary.
Definition: RobotUnitModuleControllerManagement.cpp:558
armarx::RobotUnitModule::ControllerManagement::deleteNJointControllers
void deleteNJointControllers(const Ice::StringSeq &names, const Ice::Current &=Ice::emptyCurrent) override
Queues the given NJointControllers for deletion.
Definition: RobotUnitModuleControllerManagement.cpp:501
armarx::ManagedIceObject::getArmarXManager
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Definition: ManagedIceObject.cpp:348
trace.h
armarx::RobotUnitModule::ControllerManagement::getNJointControllerStatuses
NJointControllerStatusSeq getNJointControllerStatuses(const Ice::Current &=Ice::emptyCurrent) const override
Returns the status of all NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:687
armarx::RobotUnitModule::NJointControllerAttorneyForControllerManagement
This class allows minimal access to private members of NJointControllerBase in a sane fashion for Con...
Definition: RobotUnitModuleControllerManagement.cpp:60
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::RobotUnitModule::ControllerManagement::deleteNJointController
void deleteNJointController(const std::string &name, const Ice::Current &=Ice::emptyCurrent) override
Queues the given NJointControllerBase for deletion.
Definition: RobotUnitModuleControllerManagement.cpp:494
armarx::RobotUnitModule::ControllerManagement::switchNJointControllerSetup
void switchNJointControllerSetup(const Ice::StringSeq &newSetup, const Ice::Current &=Ice::emptyCurrent) override
Changes the set of requested NJointControllers to the given set.
Definition: RobotUnitModuleControllerManagement.cpp:508
armarx::RobotUnitModule::ControllerManagement::getNJointControllerDescriptions
NJointControllerDescriptionSeq getNJointControllerDescriptions(const Ice::Current &=Ice::emptyCurrent) const override
Returns the description of all NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:719
armarx::RobotUnitModule::ControllerManagement::deactivateNJointController
void deactivateNJointController(const std::string &name, const Ice::Current &=Ice::emptyCurrent) override
Requests deactivation for the given NJointControllerBase.
Definition: RobotUnitModuleControllerManagement.cpp:446
armarx::RobotUnitModule::ControllerManagement::deactivateNJointControllers
void deactivateNJointControllers(const Ice::StringSeq &names, const Ice::Current &=Ice::emptyCurrent) override
Requests deactivation for the given NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:453
armarx::RobotUnitModule::ControllerManagement::createNJointController
NJointControllerInterfacePrx createNJointController(const std::string &className, const std::string &instanceName, const NJointControllerConfigPtr &config, const Ice::Current &=Ice::emptyCurrent) override
Cretes a NJointControllerBase.
Definition: RobotUnitModuleControllerManagement.cpp:176
armarx::RobotUnitModule::ModuleBase::getRobotUnitState
RobotUnitState getRobotUnitState() const
Returns the RobotUnit's State.
Definition: RobotUnitModuleBase.ipp:29
armarx::RobotUnitModule::ControllerManagement::createNJointControllerFromVariantConfig
NJointControllerInterfacePrx createNJointControllerFromVariantConfig(const std::string &className, const std::string &instanceName, const StringVariantBaseMap &variants, const Ice::Current &=Ice::emptyCurrent) override
Cretes a NJointControllerBase.
Definition: RobotUnitModuleControllerManagement.cpp:189
ARMARX_FATAL
#define ARMARX_FATAL
Definition: Logging.h:192
RobotUnitModuleRobotData.h
armarx::RobotUnitModule::ControllerManagement::activateNJointController
void activateNJointController(const std::string &name, const Ice::Current &=Ice::emptyCurrent) override
Requests activation for the given NJointControllerBase.
Definition: RobotUnitModuleControllerManagement.cpp:338
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:69
armarx::Registrar::getKeys
static std::vector< KeyType > getKeys()
Retrieves the list of all registered elements.
Definition: Registrar.h:115
RobotUnitModulePublisher.h
armarx::RobotUnitModule::ControllerManagement::getAllNJointControllers
StringNJointControllerPrxDictionary getAllNJointControllers(const Ice::Current &=Ice::emptyCurrent) const override
Returns proxies to all NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:157
RobotUnitModuleDevices.h
armarx::flush
const LogSender::manipulator flush
Definition: LogSender.h:251
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::RobotUnitModule::ControllerManagement::getNJointControllerNotNull
const NJointControllerBasePtr & getNJointControllerNotNull(const std::string &name) const
Returns a pointer to the NJointControllerBase.
Definition: RobotUnitModuleControllerManagement.cpp:124
RobotUnitModuleControlThreadDataBuffer.h
armarx::RobotUnitModule::ModuleBase::getGuard
GuardType getGuard() const
Returns a guard to the RobotUnits mutex.
Definition: RobotUnitModuleBase.cpp:430
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::RobotUnitModule::ControllerManagement::getRequestedNJointControllerNames
Ice::StringSeq getRequestedNJointControllerNames(const Ice::Current &=Ice::emptyCurrent) const override
Returns the names of all requested NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:75
armarx::RobotUnitModule::ControllerManagement::getNJointControllerClassDescriptions
NJointControllerClassDescriptionSeq getNJointControllerClassDescriptions(const Ice::Current &=Ice::emptyCurrent) const override
getNJointControllerClassDescriptions
Definition: RobotUnitModuleControllerManagement.cpp:634
armarx::RobotUnitModule::ControllerManagement::createOrReplaceNJointController
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.
Definition: RobotUnitModuleControllerManagement.cpp:219
armarx::RobotUnitModule::ControllerManagement::getNJointController
NJointControllerInterfacePrx getNJointController(const std::string &name, const Ice::Current &=Ice::emptyCurrent) const override
Returns a proxy to the NJointControllerBase.
Definition: RobotUnitModuleControllerManagement.cpp:660
armarx::RobotUnitModule::ControllerManagement::getNJointControllerStatus
NJointControllerStatus getNJointControllerStatus(const std::string &name, const Ice::Current &=Ice::emptyCurrent) const override
Returns the status of the NJointControllerBase.
Definition: RobotUnitModuleControllerManagement.cpp:677
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
armarx::viz::data::ElementFlags::names
const simox::meta::IntEnumNames names
Definition: json_elements.cpp:14
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::RobotUnitModule::ModuleBase::areDevicesReady
bool areDevicesReady() const
Returns whether Devices are ready.
Definition: RobotUnitModuleBase.cpp:403
armarx::RobotUnitState::InitializingDevices
@ InitializingDevices
armarx::RobotUnitModule::ControllerManagement
This Module manages NJointControllers.
Definition: RobotUnitModuleControllerManagement.h:39
armarx::RobotUnitState::InitializingComponent
@ InitializingComponent
armarx::RobotUnitModule::ModuleBase::throwIfInControlThread
void throwIfInControlThread(const std::string &fnc) const
Throws if the current thread is the ControlThread.
Definition: RobotUnitModuleBase.cpp:416
armarx::RobotUnitModule::ModuleBase::throwIfDevicesNotReady
void throwIfDevicesNotReady(const std::string &fnc) const
Throws if the Devices are not ready.
Definition: RobotUnitModuleBase.cpp:530
armarx::RobotUnitModule::ControllerManagement::getNJointControllersNotNull
std::vector< armarx::NJointControllerBasePtr > getNJointControllersNotNull(const std::vector< std::string > &names) const
Returns pointers to the NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:109
armarx::RobotUnitModule
Definition: ControlDevice.h:34
armarx::RobotUnitModule::ControllerManagement::getNJointControllerDescriptionWithStatus
NJointControllerDescriptionWithStatus getNJointControllerDescriptionWithStatus(const std::string &name, const Ice::Current &=Ice::emptyCurrent) const override
Returns the status and description of the NJointControllerBase.
Definition: RobotUnitModuleControllerManagement.cpp:741
armarx::RobotUnitModule::ControllerManagement::getActivatedNJointControllerNames
Ice::StringSeq getActivatedNJointControllerNames(const Ice::Current &=Ice::emptyCurrent) const override
Returns the names of all activated NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:83
armarx::ManagedIceObject::getProxy
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
Definition: ManagedIceObject.cpp:393
armarx::RobotUnitModule::ControllerManagement::getNJointControllerNames
Ice::StringSeq getNJointControllerNames(const Ice::Current &=Ice::emptyCurrent) const override
Returns the names of all NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:313
armarx::NJointControllerBase::AreNotInConflict
static std::optional< std::vector< char > > AreNotInConflict(ItT first, ItT last)
Definition: NJointControllerBase.h:1036
armarx::getMapKeys
void getMapKeys(const MapType &map, OutputIteratorType it)
Definition: algorithm.h:157
NJointControllerRegistry.h
armarx::RobotUnitModule::ControllerManagement::activateNJointControllers
void activateNJointControllers(const Ice::StringSeq &names, const Ice::Current &=Ice::emptyCurrent) override
Requests activation for the given NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:345
armarx::RobotUnitModule::ControllerManagement::getNJointControllerDescriptionsWithStatuses
NJointControllerDescriptionWithStatusSeq getNJointControllerDescriptionsWithStatuses(const Ice::Current &=Ice::emptyCurrent) const override
Returns the status and description of all NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:755
ARMARX_STREAM_PRINTER
#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:304