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  bool
306  ControllerManagement::loadLibFromPath(const std::string& path, const Ice::Current&)
307  {
308  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
309  ARMARX_WARNING << "Do not use this function as it has implications on the RT thread (see "
310  "https://git.h2t.iar.kit.edu/sw/armarx-integration/robots/armar7/"
311  "documentation/-/issues/85)";
312  const bool result = getArmarXManager()->loadLibFromPath(path);
313  ARMARX_INFO << "loadLibFromPath('" << path << "') -> " << result;
314  return result;
315  }
316 
317  bool
318  ControllerManagement::loadLibFromPackage(const std::string& package,
319  const std::string& lib,
320  const Ice::Current&)
321  {
322  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
323  ARMARX_WARNING << "Do not use this function as it has implications on the RT thread (see "
324  "https://git.h2t.iar.kit.edu/sw/armarx-integration/robots/armar7/"
325  "documentation/-/issues/85)";
326  const bool result = getArmarXManager()->loadLibFromPackage(package, lib);
327  ARMARX_INFO << "loadLibFromPackage('" << package << "', '" << lib << "') -> " << result;
328  return result;
329  }
330 
331  Ice::StringSeq
333  {
334  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
336  }
337 
338  Ice::StringSeq
340  {
341  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
342  auto guard = getGuard();
343  return getMapKeys(nJointControllers);
344  }
345 
346  std::vector<std::string>
348  const std::vector<NJointControllerBasePtr>& ctrls) const
349  {
350  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
351  std::vector<std::string> result;
352  result.reserve(ctrls.size());
353  for (const auto& ctrl : ctrls)
354  {
355  if (ctrl)
356  {
357  result.emplace_back(ctrl->getInstanceName());
358  }
359  }
360  return result;
361  }
362 
363  void
364  ControllerManagement::activateNJointController(const std::string& name, const Ice::Current&)
365  {
366  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
368  }
369 
370  void
372  const Ice::Current&)
373  {
374  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
376  }
377 
378  void
379  ControllerManagement::activateNJointController(const NJointControllerBasePtr& ctrl)
380  {
381  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
382  activateNJointControllers(std::vector<NJointControllerBasePtr>{ctrl});
383  }
384 
385  void
387  const std::vector<NJointControllerBasePtr>& ctrlsToActVec)
388  {
389  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
390  if (ctrlsToActVec.empty())
391  {
392  return;
393  }
394  auto guard = getGuard();
395  throwIfDevicesNotReady(__FUNCTION__);
396  //if not activate them
397  std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>> ctrlsToAct{
398  ctrlsToActVec.begin(), ctrlsToActVec.end()};
399  ARMARX_CHECK_EXPRESSION(!ctrlsToAct.count(nullptr));
400  //check if all already active
401  if (std::all_of(ctrlsToActVec.begin(),
402  ctrlsToActVec.end(),
403  [](const NJointControllerBasePtr& ctrl)
404  { return ctrl->isControllerActive(); }))
405  {
406  return;
407  }
408  //get already requested
409  const auto ctrlVector = _module<ControlThreadDataBuffer>().copyRequestedNJointControllers();
410  std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>>
411  ctrlsAlreadyRequested{ctrlVector.begin(), ctrlVector.end()};
412  ctrlsAlreadyRequested.erase(nullptr);
413  //check for conflict
414  std::vector<char> inuse;
415  //check requested controllers
416  {
417  auto r = NJointControllerBase::AreNotInConflict(ctrlsToAct.begin(), ctrlsToAct.end());
418  if (!r)
419  {
420  std::stringstream ss;
421  ss << "activateNJointControllers: requested controllers are in "
422  "conflict!\ncontrollers:\n"
423  << getNJointControllerNames(ctrlsToActVec);
424  ARMARX_ERROR << ss.str();
425  throw InvalidArgumentException{ss.str()};
426  }
427  inuse = std::move(*r);
428  }
429  ARMARX_DEBUG << "all requested controllers are conflict free" << std::flush;
430  auto printInUse = ARMARX_STREAM_PRINTER
431  {
432  for (const auto c : inuse)
433  {
434  out << (c ? 1 : 0);
435  }
436  };
437  ARMARX_DEBUG << "inuse field (request)\n" << printInUse;
438  //add already active controllers if they are conflict free
439  {
440  if (ctrlsAlreadyRequested.empty())
441  {
442  ARMARX_DEBUG << "no already requested NJointControllers";
443  }
444  for (const NJointControllerBasePtr& nJointCtrl : ctrlsAlreadyRequested)
445  {
446  if (ctrlsToAct.count(nJointCtrl))
447  {
448  continue;
449  }
450  auto r = nJointCtrl->isNotInConflictWith(inuse);
451  if (r)
452  {
453  ARMARX_DEBUG << "keeping already requested NJointControllerBase '"
454  << nJointCtrl->getInstanceName()
455  << "' in list of requested controllers";
456  ctrlsToAct.insert(nJointCtrl);
457  inuse = std::move(*r);
458  }
459  else
460  {
461  ARMARX_INFO << "removing already requested NJointControllerBase '"
462  << nJointCtrl->getInstanceName()
463  << "' from list of requested controllers";
464  }
465  }
466  ARMARX_DEBUG << "inuse field (all)\n" << printInUse;
467  }
468  _module<ControlThreadDataBuffer>().setActivateControllersRequest(ctrlsToAct);
469  }
470 
471  void
472  ControllerManagement::deactivateNJointController(const std::string& name, const Ice::Current&)
473  {
474  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
476  }
477 
478  void
480  const Ice::Current&)
481  {
482  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
484  }
485 
486  void
487  ControllerManagement::deactivateNJointController(const NJointControllerBasePtr& ctrl)
488  {
489  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
490  deactivateNJointControllers(std::vector<NJointControllerBasePtr>{ctrl});
491  }
492 
493  void
495  const std::vector<NJointControllerBasePtr>& ctrlsDeacVec)
496  {
497  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
498  auto guard = getGuard();
499  throwIfDevicesNotReady(__FUNCTION__);
500  if (ctrlsDeacVec.empty())
501  {
502  return;
503  }
504  const auto ctrlVector = _module<ControlThreadDataBuffer>().copyRequestedNJointControllers();
505  std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>> ctrls{
506  ctrlVector.begin(), ctrlVector.end()};
507  const std::size_t ctrlsNum = ctrls.size();
508  for (const auto& nJointCtrlToDeactivate : ctrlsDeacVec)
509  {
510  ctrls.erase(nJointCtrlToDeactivate);
511  }
512  if (ctrls.size() == ctrlsNum)
513  {
514  return;
515  }
516  _module<ControlThreadDataBuffer>().setActivateControllersRequest(ctrls);
517  }
518 
519  void
520  ControllerManagement::deleteNJointController(const std::string& name, const Ice::Current&)
521  {
522  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
524  }
525 
526  void
527  ControllerManagement::deleteNJointControllers(const Ice::StringSeq& names, const Ice::Current&)
528  {
529  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
531  }
532 
533  void
535  const Ice::Current&)
536  {
537  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
538  auto guard = getGuard();
539  throwIfDevicesNotReady(__FUNCTION__);
540  auto ctrlsToActVec =
541  getNJointControllersNotNull(newSetup); //also checks if these controllers exist
542  _module<ControlThreadDataBuffer>().setActivateControllersRequest(
543  {ctrlsToActVec.begin(), ctrlsToActVec.end()});
544  }
545 
546  void
548  const std::vector<NJointControllerBasePtr>& ctrlsToDelVec)
549  {
550  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
551  auto guard = getGuard();
552  throwIfDevicesNotReady(__FUNCTION__);
553  if (ctrlsToDelVec.empty())
554  {
555  return;
556  }
557  //check if all can be deleted
558  for (const auto& nJointCtrl : ctrlsToDelVec)
559  {
560  if (!nJointCtrl->isDeletable())
561  {
562  throw LogicError{"The NJointControllerBase '" + nJointCtrl->getInstanceName() +
563  "' can't be deleted since this operation is not allowed for this "
564  "controller! (no NJointControllerBase was deleted)"};
565  }
566  if (nJointCtrl->isControllerActive() || nJointCtrl->isControllerRequested())
567  {
568  throw LogicError{"The NJointControllerBase '" + nJointCtrl->getInstanceName() +
569  "' can't be deleted since it is active or requested! (no "
570  "NJointControllerBase was deleted)"};
571  }
572  }
573  for (const auto& nJointCtrl : ctrlsToDelVec)
574  {
575  const auto name = nJointCtrl->getInstanceName();
576  //deletion is done in a different thread since this call may be done by the controller (protection against use after free)
577  nJointControllersToBeDeleted[name] = std::move(nJointCtrl);
578  nJointControllers.erase(name);
579  ARMARX_VERBOSE << "added NJointControllerBase '" << name << "' to be deleted";
580  }
581  }
582 
583  void
585  const Ice::Current&)
586  {
587  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
589  }
590 
591  void
593  const Ice::Current&)
594  {
595  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
597  }
598 
599  void
601  {
602  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
604  }
605 
606  void
608  const std::vector<NJointControllerBasePtr>& ctrlsToDelVec)
609  {
610  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
611  auto guard = getGuard();
612  throwIfDevicesNotReady(__FUNCTION__);
613  if (ctrlsToDelVec.empty())
614  {
615  return;
616  }
617  deactivateNJointControllers(ctrlsToDelVec);
618  while (std::any_of(ctrlsToDelVec.begin(),
619  ctrlsToDelVec.end(),
620  [](const NJointControllerBasePtr& ctrl)
621  { return ctrl->isControllerActive(); }))
622  {
623  if (isShuttingDown())
624  {
625  return;
626  }
627  std::this_thread::sleep_for(std::chrono::microseconds{100});
628  }
629  deleteNJointControllers(ctrlsToDelVec);
630  }
631 
632  NJointControllerClassDescription
634  const Ice::Current&) const
635  {
636  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
639  {
640  //this phase should only last short so busy waiting is ok
641  std::this_thread::sleep_for(std::chrono::milliseconds(50));
642  }
643  auto guard = getGuard();
644  throwIfDevicesNotReady(__FUNCTION__);
645  checkNJointControllerClassName(className);
646  NJointControllerClassDescription data;
647  data.className = className;
648  if (NJointControllerRegistry::get(className)->hasRemoteConfiguration())
649  {
650  data.configDescription =
651  NJointControllerRegistry::get(className)->GenerateConfigDescription(
652  controllerCreateRobot,
653  _module<Devices>().getControlDevicesConstPtr(),
654  _module<Devices>().getSensorDevicesConstPtr());
655  }
656  return data;
657  }
658 
659  NJointControllerClassDescriptionSeq
661  {
662  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
663  std::size_t tries = 200;
666  {
667  //this phase should only last short so busy waiting is ok
668  std::this_thread::sleep_for(std::chrono::milliseconds(50));
669  if (!--tries)
670  {
671  throw RuntimeError{"RobotUnit::getNJointControllerClassDescriptions: it took too "
672  "long to for the unit to get in a valid state"};
673  }
674  }
675  auto guard = getGuard();
676  NJointControllerClassDescriptionSeq r;
677  r.reserve(NJointControllerRegistry::getKeys().size());
678  for (const auto& key : NJointControllerRegistry::getKeys())
679  {
680  r.emplace_back(getNJointControllerClassDescription(key));
681  }
682  return r;
683  }
684 
685  NJointControllerInterfacePrx
686  ControllerManagement::getNJointController(const std::string& name, const Ice::Current&) const
687  {
688  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
689  NJointControllerBasePtr ctrl;
690  {
691  auto guard = getGuard();
692  auto it = nJointControllers.find(name);
693  if (it == nJointControllers.end())
694  {
695  return nullptr;
696  }
697  ctrl = it->second;
698  }
699  return NJointControllerInterfacePrx::uncheckedCast(ctrl->getProxy(-1, true));
700  }
701 
702  NJointControllerStatus
704  const Ice::Current&) const
705  {
706  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
707  auto guard = getGuard();
708  throwIfDevicesNotReady(__FUNCTION__);
709  return getNJointControllerNotNull(name)->getControllerStatus();
710  }
711 
712  NJointControllerStatusSeq
714  {
715  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
716  auto guard = getGuard();
717  if (!areDevicesReady())
718  {
719  return {};
720  }
721  NJointControllerStatusSeq r;
722  r.reserve(nJointControllers.size());
723  for (const auto& nJointCtrl : nJointControllers)
724  {
725  r.emplace_back(nJointCtrl.second->getControllerStatus());
726  }
727  return r;
728  }
729 
730  NJointControllerDescription
732  const Ice::Current&) const
733  {
734  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
735  NJointControllerBasePtr nJointCtrl;
736  {
737  auto guard = getGuard();
738  throwIfDevicesNotReady(__FUNCTION__);
739  nJointCtrl = getNJointControllerNotNull(name);
740  }
741  return nJointCtrl->getControllerDescription();
742  }
743 
744  NJointControllerDescriptionSeq
746  {
747  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
748  std::map<std::string, NJointControllerBasePtr> nJointControllersCopy;
749  {
750  auto guard = getGuard();
751  if (!areDevicesReady())
752  {
753  return {};
754  }
755  nJointControllersCopy = nJointControllers;
756  }
757  NJointControllerDescriptionSeq r;
758  r.reserve(nJointControllersCopy.size());
759  for (const auto& nJointCtrl : nJointControllersCopy)
760  {
761  r.emplace_back(nJointCtrl.second->getControllerDescription());
762  }
763  return r;
764  }
765 
766  NJointControllerDescriptionWithStatus
768  const Ice::Current&) const
769  {
770  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
771  NJointControllerBasePtr nJointCtrl;
772  {
773  auto guard = getGuard();
774  throwIfDevicesNotReady(__FUNCTION__);
775  nJointCtrl = getNJointControllerNotNull(name);
776  }
777  return nJointCtrl->getControllerDescriptionWithStatus();
778  }
779 
780  NJointControllerDescriptionWithStatusSeq
782  {
783  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
784  std::map<std::string, NJointControllerBasePtr> nJointControllersCopy;
785  {
786  auto guard = getGuard();
787  if (!areDevicesReady())
788  {
789  return {};
790  }
791  nJointControllersCopy = nJointControllers;
792  }
793  NJointControllerDescriptionWithStatusSeq r;
794  r.reserve(nJointControllersCopy.size());
795  for (const auto& nJointCtrl : nJointControllersCopy)
796  {
797  r.emplace_back(nJointCtrl.second->getControllerDescriptionWithStatus());
798  }
799  return r;
800  }
801 
802  void
803  ControllerManagement::removeNJointControllers(
804  std::map<std::string, NJointControllerBasePtr>& ctrls,
805  bool blocking,
806  RobotUnitListenerPrx l)
807  {
808  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
809  for (auto& n2NJointCtrl : ctrls)
810  {
811  NJointControllerBasePtr& nJointCtrl = n2NJointCtrl.second;
812  if (blocking)
813  {
814  ARMARX_VERBOSE << "deleted NJointControllerBase " << n2NJointCtrl.first;
815  getArmarXManager()->removeObjectBlocking(nJointCtrl->getName());
816  }
817  else
818  {
819  ARMARX_VERBOSE << "deleted NJointControllerBase " << n2NJointCtrl.first;
820  getArmarXManager()->removeObjectBlocking(nJointCtrl->getName());
821  }
822  if (l)
823  {
824  l->nJointControllerDeleted(n2NJointCtrl.first);
825  }
826  }
827  ctrls.clear();
828  }
829 
830  void
831  ControllerManagement::removeNJointControllersToBeDeleted(bool blocking, RobotUnitListenerPrx l)
832  {
833  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
834  removeNJointControllers(nJointControllersToBeDeleted, blocking, l);
835  }
836 
837  void
838  ControllerManagement::_preFinishRunning()
839  {
840  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
841  //NJoint queued for deletion (some could still be in the queue)
842  ARMARX_DEBUG << "remove NJointControllers queued for deletion";
843  removeNJointControllersToBeDeleted();
844  ARMARX_DEBUG << "remove NJointControllers queued for deletion...done";
845  //NJoint
846  ARMARX_DEBUG << "remove NJointControllers";
847  removeNJointControllers(nJointControllers);
848  ARMARX_DEBUG << "remove NJointControllers...done";
849  }
850 
851  void
852  ControllerManagement::_postFinishRunning()
853  {
854  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
855  nJointControllers.clear();
856  }
857 
859  {
860  }
861 
862  void
863  ControllerManagement::_preOnInitRobotUnit()
864  {
865  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
866  controllerCreateRobot = _module<RobotData>().cloneRobot();
867  }
868 
869  void
870  ControllerManagement::updateNJointControllerRequestedState(
871  const std::set<NJointControllerBasePtr>& request)
872  {
873  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
874  ARMARX_DEBUG << "set requested state for NJoint controllers";
875  for (const auto& name2NJoint : nJointControllers)
876  {
877  NJointControllerAttorneyForControllerManagement::SetRequested(
878  name2NJoint.second, request.count(name2NJoint.second));
879  }
880  }
881 } // namespace armarx::RobotUnitModule
armarx::RobotUnitModule::ControllerManagement::getNJointControllerClassDescription
NJointControllerClassDescription getNJointControllerClassDescription(const std::string &className, const Ice::Current &=Ice::emptyCurrent) const override
getNJointControllerClassDescription
Definition: RobotUnitModuleControllerManagement.cpp:633
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:592
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:858
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:332
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:731
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:584
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:527
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:713
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:520
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:534
armarx::RobotUnitModule::ControllerManagement::getNJointControllerDescriptions
NJointControllerDescriptionSeq getNJointControllerDescriptions(const Ice::Current &=Ice::emptyCurrent) const override
Returns the description of all NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:745
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:472
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:479
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
armarx::RobotUnitModule::ControllerManagement::loadLibFromPackage
bool loadLibFromPackage(const std::string &package, const std::string &lib, const Ice::Current &=Ice::emptyCurrent) override
Loads the given lib.
Definition: RobotUnitModuleControllerManagement.cpp:318
RobotUnitModuleRobotData.h
armarx::RobotUnitModule::ControllerManagement::loadLibFromPath
bool loadLibFromPath(const std::string &path, const Ice::Current &=Ice::emptyCurrent) override
Loads the given lib.
Definition: RobotUnitModuleControllerManagement.cpp:306
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:364
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:660
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:686
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:703
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:767
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_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
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:339
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:371
armarx::RobotUnitModule::ControllerManagement::getNJointControllerDescriptionsWithStatuses
NJointControllerDescriptionWithStatusSeq getNJointControllerDescriptionsWithStatuses(const Ice::Current &=Ice::emptyCurrent) const override
Returns the status and description of all NJointControllers.
Definition: RobotUnitModuleControllerManagement.cpp:781
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