RobotUnitModuleControlThread.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 
24 
25 #include <SimoxUtility/math/convert/pos_rpy_to_mat4f.h>
26 #include <VirtualRobot/XML/RobotIO.h>
27 
32 
43 
44 #include "../Devices/RTThreadTimingsSensorDevice.h"
45 
47 {
48  /**
49  * \brief This class allows minimal access to private members of \ref NJointControllerBase in a sane fashion for \ref ControlThread.
50  * \warning !! DO NOT ADD ANYTHING IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !!
51  */
53  {
54  friend class ControlThread;
55 
56  static void
57  RtDeactivateController(const NJointControllerBasePtr& nJointCtrl)
58  {
59  nJointCtrl->rtDeactivateController();
60  }
61 
62  static void
63  RtActivateController(const NJointControllerBasePtr& nJointCtrl)
64  {
65  nJointCtrl->rtActivateController();
66  }
67 
68  static void
69  RtDeactivateControllerBecauseOfError(const NJointControllerBasePtr& nJointCtrl)
70  {
71  nJointCtrl->rtDeactivateControllerBecauseOfError();
72  }
73  };
74 
75  /**
76  * \brief This class allows minimal access to private members of \ref ControlThreadDataBuffer in a sane fashion for \ref ControlThread.
77  * \warning !! DO NOT ADD ANYTHING IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !!
78  */
80  {
81  friend class ControlThread;
82 
83  static std::vector<JointController*>&
84  GetActivatedJointControllers(ControlThread* p)
85  {
86  return p->_module<ControlThreadDataBuffer>()
87  .controllersActivated.getWriteBuffer()
88  .jointControllers;
89  }
90 
91  static std::vector<NJointControllerBase*>&
92  GetActivatedNJointControllers(ControlThread* p)
93  {
94  return p->_module<ControlThreadDataBuffer>()
95  .controllersActivated.getWriteBuffer()
96  .nJointControllers;
97  }
98 
99  static std::vector<std::size_t>&
100  GetActivatedJointToNJointControllerAssignement(ControlThread* p)
101  {
102  return p->_module<ControlThreadDataBuffer>()
103  .controllersActivated.getWriteBuffer()
104  .jointToNJointControllerAssignement;
105  }
106 
107  static const std::vector<JointController*>&
108  GetActivatedJointControllers(const ControlThread* p)
109  {
110  return p->_module<ControlThreadDataBuffer>()
111  .controllersActivated.getWriteBuffer()
112  .jointControllers;
113  }
114 
115  static const std::vector<NJointControllerBase*>&
116  GetActivatedNJointControllers(const ControlThread* p)
117  {
118  return p->_module<ControlThreadDataBuffer>()
119  .controllersActivated.getWriteBuffer()
120  .nJointControllers;
121  }
122 
123  static const std::vector<std::size_t>&
124  GetActivatedJointToNJointControllerAssignement(const ControlThread* p)
125  {
126  return p->_module<ControlThreadDataBuffer>()
127  .controllersActivated.getWriteBuffer()
128  .jointToNJointControllerAssignement;
129  }
130 
131  static void
132  AcceptRequestedJointToNJointControllerAssignement(ControlThread* p)
133  {
134  p->_module<ControlThreadDataBuffer>()
135  .controllersActivated.getWriteBuffer()
136  .jointToNJointControllerAssignement = p->_module<ControlThreadDataBuffer>()
137  .controllersRequested.getReadBuffer()
138  .jointToNJointControllerAssignement;
139  }
140 
141  static void
142  CommitActivatedControllers(ControlThread* p)
143  {
144  return p->_module<ControlThreadDataBuffer>().controllersActivated.commitWrite();
145  }
146 
147  static void
148  ResetActivatedControllerAssignement(ControlThread* p)
149  {
150  return p->_module<ControlThreadDataBuffer>()
151  .controllersActivated.getWriteBuffer()
152  .resetAssignement();
153  }
154 
155  static const std::vector<JointController*>&
156  GetRequestedJointControllers(const ControlThread* p)
157  {
158  //do NOT update here!
159  return p->_module<ControlThreadDataBuffer>()
160  .controllersRequested.getReadBuffer()
161  .jointControllers;
162  }
163 
164  static const std::vector<NJointControllerBase*>&
165  GetRequestedNJointControllers(const ControlThread* p)
166  {
167  //do NOT update here!
168  return p->_module<ControlThreadDataBuffer>()
169  .controllersRequested.getReadBuffer()
170  .nJointControllers;
171  }
172 
173  static const std::vector<std::size_t>&
174  GetRequestedJointToNJointControllerAssignement(const ControlThread* p)
175  {
176  //do NOT update here!
177  return p->_module<ControlThreadDataBuffer>()
178  .controllersRequested.getReadBuffer()
179  .jointToNJointControllerAssignement;
180  }
181 
182  static bool
183  RequestedControllersChanged(const ControlThread* p)
184  {
185  //only place allowed to update this buffer!
186  return p->_module<ControlThreadDataBuffer>().controllersRequested.updateReadBuffer();
187  }
188 
189  /// Activate a joint controller from the rt loop (only works in switch mode RTThread)
190  static void
191  RTSetJointController(ControlThread* p, JointController* c, std::size_t index)
192  {
194  //do NOT update here!
195  auto& readbuf =
196  p->_module<ControlThreadDataBuffer>().controllersRequested._getNonConstReadBuffer();
197  auto& j = readbuf.jointControllers;
198  auto& assig = readbuf.jointToNJointControllerAssignement;
199  auto& nj = readbuf.nJointControllers;
200  ARMARX_CHECK_LESS(index, j.size());
201  const auto assigNJ = assig.at(index);
202  if (assigNJ != JointAndNJointControllers::Sentinel())
203  {
204  //an NJointController is activated! Deactivate it and reset all joit devs
205  nj.at(assigNJ) = nullptr;
206  for (std::size_t i = 0; i < assig.size(); ++i)
207  {
208  if (assig.at(i) == assigNJ)
209  {
210  j.at(i) = j.at(i)->rtGetParent().rtGetJointStopMovementController();
211  }
212  }
213  }
214  j.at(index) = c;
215  }
216  };
217 
218  /**
219  * \brief This class allows minimal access to private members of \ref Devices in a sane fashion for \ref ControlThread.
220  * \warning !! DO NOT ADD ANYTHING IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !!
221  */
223  {
224  friend class ControlThread;
225 
226  static const std::vector<ControlDevicePtr>&
227  GetControlDevices(const ControlThread* p)
228  {
229  return p->_module<Devices>().controlDevices.values();
230  }
231 
232  static const std::vector<SensorDevicePtr>&
233  GetSensorDevices(const ControlThread* p)
234  {
235  return p->_module<Devices>().sensorDevices.values();
236  }
237 
238  static const std::vector<const SensorValueBase*>&
239  GetSensorValues(const ControlThread* p)
240  {
241  return p->_module<Devices>().sensorValues;
242  }
243 
244  static const std::vector<std::vector<PropagateConst<ControlTargetBase*>>>&
245  GetControlTargets(const ControlThread* p)
246  {
247  return p->_module<Devices>().controlTargets;
248  }
249 
250  static RTThreadTimingsSensorDevice&
251  GetThreadTimingsSensorDevice(const ControlThread* p)
252  {
253  return *(p->_module<Devices>().rtThreadTimingsSensorDevice);
254  }
255 
256  static void
257  UpdateRobotWithSensorValues(const ControlThread* p,
258  const VirtualRobot::RobotPtr& robot,
259  const std::vector<VirtualRobot::RobotNodePtr>& robotNodes)
260  {
261  p->_module<Devices>().updateVirtualRobotFromSensorValues(
262  robot, robotNodes, p->_module<Devices>().sensorValues);
263  }
264  };
265 
266  /**
267  * \brief This class allows minimal access to private members of \ref Devices in a sane fashion for \ref ControlThread.
268  * \warning !! DO NOT ADD ANYTHING IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !!
269  */
271  {
272  friend class ControlThread;
273 
274  static bool
275  HeartbeatMissing(const ControlThread* p)
276  {
277  const Management& m = p->_module<Management>();
278  long now = TimeUtil::GetTime(true).toMilliSeconds();
279  if (!m.heartbeatRequired || now < m.controlLoopStartTime + m.heartbeatStartupMarginMS)
280  {
281  return false;
282  }
283  return (now - m.lastHeartbeat) > m.heartbeatMaxCycleMS;
284  }
285  };
286 } // namespace armarx::RobotUnitModule
287 
288 namespace armarx::RobotUnitModule
289 {
290  bool
292  {
295  {
297  };
298 
299  //store controllers activated before switching controllers
300  {
301  preSwitchSetup_ActivatedJointControllers = rtGetActivatedJointControllers();
302  preSwitchSetup_ActivatedJointToNJointControllerAssignement =
303  rtGetActivatedJointToNJointControllerAssignement();
304  preSwitchSetup_ActivatedNJointControllers = rtGetActivatedNJointControllers();
305  }
306 
308  {
309  const auto& actJC = rtGetActivatedJointControllers();
310  const auto& assig = rtGetActivatedJointToNJointControllerAssignement();
311  const auto& actNJC = rtGetActivatedNJointControllers();
312 
313  //store controllers activated after switching controllers
314  {
315  postSwitchSetup_ActivatedJointControllers = actJC;
316  postSwitchSetup_ActivatedJointToNJointControllerAssignement = assig;
317  postSwitchSetup_ActivatedNJointControllers = actNJC;
318  }
319 
320  std::size_t numSyncNj = 0;
321  std::size_t numAsyncNj = 0;
322 
323  for (std::size_t i = 0; i < actJC.size(); ++i)
324  {
325  if (actNJC.at(i) == nullptr)
326  {
327  continue;
328  }
329  if (dynamic_cast<SynchronousNJointController*>(actNJC.at(i)))
330  {
331  _activatedSynchronousNJointControllersIdx.at(numSyncNj++) = i;
332  }
333  else if (dynamic_cast<AsynchronousNJointController*>(actNJC.at(i)))
334  {
335  _activatedAsynchronousNJointControllersIdx.at(numAsyncNj++) = i;
336  }
337  else
338  {
340  "NJoint controller that is neither SynchronousNJointController"
341  " nor AsynchronousNJointController: %s",
342  actNJC.at(i)->rtGetClassName().c_str());
343  // Throwing exceptions in a destructor causes std::abort to be called
344  //throw std::logic_error{};
345  }
346  }
347  for (std::size_t i = numSyncNj;
348  i < _maxControllerCount &&
349  _activatedSynchronousNJointControllersIdx.at(i) != _maxControllerCount;
350  ++i)
351  {
352  _activatedSynchronousNJointControllersIdx.at(i) = _maxControllerCount;
353  }
354  for (std::size_t i = numAsyncNj;
355  i < _maxControllerCount &&
356  _activatedAsynchronousNJointControllersIdx.at(i) != _maxControllerCount;
357  ++i)
358  {
359  _activatedAsynchronousNJointControllersIdx.at(i) = _maxControllerCount;
360  }
361  };
362 
363 
364  rtSwitchControllerSetupChangedControllers = false;
365 
366  // a missing heartbeat (if required by the config) is interpreted as emergencyStop == true
367  if (!emergencyStop && ManagementAttorneyForControlThread::HeartbeatMissing(this))
368  {
369  rtSetEmergencyStopState(EmergencyStopState::eEmergencyStopActive);
370  ARMARX_RT_LOGF_ERROR("Emergency Stop was activated because heartbeat is missing!")
371  .deactivateSpam(1);
372  }
373 
374  const bool rtThreadOverridesControl = mode != SwitchControllerMode::IceRequests;
375  // mode == RTThread -> control flow in hand of rt thread (ignoring estop)
376  // !emergencyStop && !rtIsInEmergencyStop() -> normal control flow
377  // !emergencyStop && rtIsInEmergencyStop() -> force switch to reactivate old ( + reset flag)
378  // emergencyStop && !rtIsInEmergencyStop() -> deactivate all + set flag
379  // emergencyStop && rtIsInEmergencyStop() -> nothing to do
380  if (emergencyStop && !rtThreadOverridesControl)
381  {
382  if (rtIsInEmergencyStop())
383  {
384  return false;
385  }
386  rtIsInEmergencyStop_ = true;
387  //deactivate all nJointCtrl
388  for (auto& nJointCtrl : rtGetActivatedNJointControllers())
389  {
390  if (nJointCtrl)
391  {
392  NJointControllerAttorneyForControlThread::RtDeactivateController(nJointCtrl);
393  nJointCtrl = nullptr;
394  rtSwitchControllerSetupChangedControllers = true;
395  }
396  }
397  //set all JointCtrl to emergency stop (except stop movement)
398  for (std::size_t i = 0; i < rtGetControlDevices().size(); ++i)
399  {
400  const ControlDevicePtr& controlDevice = rtGetControlDevices().at(i);
401  const auto active = controlDevice->rtGetActiveJointController();
402  const auto stopMov = controlDevice->rtGetJointStopMovementController();
403  const auto emergency = controlDevice->rtGetJointEmergencyStopController();
404  if (active != stopMov && active != emergency)
405  {
406  controlDevice->rtSetActiveJointController(emergency);
407  rtGetActivatedJointControllers().at(i) = emergency;
408  rtSwitchControllerSetupChangedControllers = true;
409  }
410  }
411  if (rtSwitchControllerSetupChangedControllers)
412  {
413  ControlThreadDataBufferAttorneyForControlThread::
414  ResetActivatedControllerAssignement(this);
415  // the activated controllers are committed in rtUpdateSensorAndControlBuffer(...)
416  }
417  return rtSwitchControllerSetupChangedControllers;
418  }
419 
420  if (!rtThreadOverridesControl &&
421  !ControlThreadDataBufferAttorneyForControlThread::RequestedControllersChanged(this) &&
423  {
424  return false;
425  }
426  rtIsInEmergencyStop_ = false;
427 
428  //handle nJointCtrl
429  {
430  const auto& allReqNJ = rtGetRequestedNJointControllers();
431  auto& allActdNJ = rtGetActivatedNJointControllers();
432  //"merge"
433  std::size_t n = rtGetControlDevices().size();
434  std::size_t idxAct = 0;
435  std::size_t idxReq = 0;
436  for (std::size_t i = 0; i < 2 * n; ++i)
437  {
438  //skip nullptrs in act
439  while (idxAct < n && !allActdNJ.at(idxAct))
440  {
441  ++idxAct;
442  }
443  const NJointControllerBasePtr& req =
444  idxReq < n ? allReqNJ.at(idxReq) : nullptr; //may be null
445  const NJointControllerBasePtr& act =
446  idxAct < n ? allActdNJ.at(idxAct) : nullptr; //may be null if it is the last
447  const auto reqId = reinterpret_cast<std::uintptr_t>(req.get());
448  const auto actId = reinterpret_cast<std::uintptr_t>(act.get());
449 
450  if (reqId > actId)
451  {
452  //new ctrl
453  rtSyncNJointControllerRobot(req.get());
454  NJointControllerAttorneyForControlThread::RtActivateController(req);
455  ++idxReq;
456  rtSwitchControllerSetupChangedControllers = true;
457  }
458  else if (reqId < actId)
459  {
460  NJointControllerAttorneyForControlThread::RtDeactivateController(act);
461  rtSwitchControllerSetupChangedControllers = true;
462  ++idxAct;
463  }
464  else //if(reqId == actId)
465  {
466  //same ctrl or both null ctrl
467  ++idxReq;
468  ++idxAct;
469  }
470  if (idxAct >= n && !req)
471  {
472  break;
473  }
474  }
475  allActdNJ = allReqNJ;
476  }
477 
478  //handle Joint Ctrl
479  {
480  const auto& allReqJ = rtGetRequestedJointControllers();
481  auto& allActdJ = rtGetActivatedJointControllers();
482  ARMARX_CHECK_EQUAL(allReqJ.size(), rtGetControlDevices().size());
483  for (std::size_t i = 0; i < rtGetControlDevices().size(); ++i)
484  {
485  auto& controlDevice = rtGetControlDevices().at(i);
486  const auto requestedJointCtrl = allReqJ.at(i);
487  controlDevice->rtSetActiveJointController(requestedJointCtrl);
488  allActdJ.at(i) = requestedJointCtrl;
489  }
490  }
491  ControlThreadDataBufferAttorneyForControlThread::
492  AcceptRequestedJointToNJointControllerAssignement(this);
493  // the activated controllers are committed in rtUpdateSensorAndControlBuffer(...)
494  return true;
495  }
496 
497  void
499  {
501  for (const ControlDevicePtr& controlDev : rtGetControlDevices())
502  {
503  controlDev->rtGetActiveJointController()->rtResetTarget();
504  }
506  }
507 
508  void
510  {
512  numberOfInvalidTargetsInThisIteration = 0;
513  const auto& cdevs = rtGetControlDevices();
514  for (std::size_t i = 0; i < cdevs.size(); ++i)
515  {
516  if (!rtGetActivatedJointControllers().at(i)->rtIsTargetValid())
517  {
518  ARMARX_RT_LOGF_ERROR("INVALID TARGET for JointController (idx = %lu) '%s'",
519  i,
520  cdevs.at(i)->rtGetDeviceName());
521  ARMARX_ERROR << ">>>INVALID TARGET for JointController (idx = " << i << ") '"
522  << cdevs.at(i)->getDeviceName() << "'";
524  ++numberOfInvalidTargetsInThisIteration;
525  }
526  }
527  // the activated controllers are committed in rtUpdateSensorAndControlBuffer(...)
529  }
530 
531  void
533  const IceUtil::Time& timeSinceLastIteration)
534  {
536  for (const SensorDevicePtr& device : rtGetSensorDevices())
537  {
538  device->rtReadSensorValues(sensorValuesTimestamp, timeSinceLastIteration);
539  }
540  DevicesAttorneyForControlThread::UpdateRobotWithSensorValues(this, rtRobot, rtRobotNodes);
541  rtPostReadSensorDeviceValues(sensorValuesTimestamp, timeSinceLastIteration);
543  }
544 
545  void
547  const IceUtil::Time& timeSinceLastIteration)
548  {
549  if (dynamicsHelpers)
550  {
551  // auto start = IceUtil::Time::now();
552  dynamicsHelpers->update(sensorValuesTimestamp, timeSinceLastIteration);
553  // auto end = IceUtil::Time::now();
554  // ARMARX_INFO << "Dynamics duration: " << (end-start).toMicroSeconds();
555  }
556  }
557 
558  void
560  const IceUtil::Time& timeSinceLastIteration)
561  {
563  for (const ControlDevicePtr& device : rtGetControlDevices())
564  {
565  device->rtRun(sensorValuesTimestamp, timeSinceLastIteration);
566  }
568  }
569 
570  void
572  const IceUtil::Time& timeSinceLastIteration)
573  {
575  // bool activeControllersChanged = false;
576  auto activatedNjointCtrls = rtGetActivatedNJointControllers();
577  //start async
578  for (std::size_t nJointCtrlIndex : _activatedAsynchronousNJointControllersIdx)
579  {
580  if (nJointCtrlIndex == _maxControllerCount)
581  {
582  break;
583  }
584  auto nJointCtrl = static_cast<AsynchronousNJointController*>(
585  activatedNjointCtrls.at(nJointCtrlIndex));
586  if (!nJointCtrl)
587  {
588  continue;
589  }
590  try
591  {
592  if (nJointCtrl->rtGetErrorState())
593  {
595  "NJointControllerBase '%s' requested deactivation while activating it",
596  nJointCtrl->rtGetInstanceName().c_str());
598  }
599  auto start = TimeUtil::GetTime(true);
600  rtSyncNJointControllerRobot(nJointCtrl);
601  nJointCtrl->rtRunIterationBegin(sensorValuesTimestamp, timeSinceLastIteration);
602  auto duration = TimeUtil::GetTime(true) - start;
603  if (nJointCtrl->rtGetErrorState())
604  {
606  "NJointControllerBase '%s' requested deactivation while running it",
607  nJointCtrl->rtGetInstanceName().c_str());
609  }
610  if (static_cast<std::size_t>(duration.toMicroSeconds()) >
611  nJointCtrl->rtGetNumberOfUsedControlDevices() * usPerDevUntilError)
612  {
613  ARMARX_RT_LOGF_ERROR("The NJointControllerBase '%s' took %ld µs to run!",
614  nJointCtrl->rtGetInstanceName().c_str(),
615  duration.toMicroSeconds())
616  .deactivateSpam(5);
617  }
618  else if (static_cast<std::size_t>(duration.toMicroSeconds()) >
619  nJointCtrl->rtGetNumberOfUsedControlDevices() * usPerDevUntilWarn)
620  {
621  ARMARX_RT_LOGF_WARNING("The NJointControllerBase '%s' took %ld µs to run!",
622  nJointCtrl->rtGetInstanceName().c_str(),
623  duration.toMicroSeconds())
624  .deactivateSpam(5);
625  }
626  }
627  catch (...)
628  {
629  ARMARX_ERROR << "NJoint Controller " << nJointCtrl->getInstanceName()
630  << " threw an exception and is now deactivated: "
633  }
634  }
635 
636  //start sync
637  for (std::size_t nJointCtrlIndex : _activatedSynchronousNJointControllersIdx)
638  {
639  if (nJointCtrlIndex == _maxControllerCount)
640  {
641  break;
642  }
643  auto nJointCtrl =
644  static_cast<SynchronousNJointController*>(activatedNjointCtrls.at(nJointCtrlIndex));
645  try
646  {
647  if (nJointCtrl)
648  {
649  if (nJointCtrl->rtGetErrorState())
650  {
652  "NJointControllerBase '%s' requested deactivation while activating it",
653  nJointCtrl->rtGetInstanceName().c_str());
655  // activeControllersChanged = true;
656  }
657 
658  auto start = TimeUtil::GetTime(true);
659  rtSyncNJointControllerRobot(nJointCtrl);
660  nJointCtrl->rtSwapBufferAndRun(sensorValuesTimestamp, timeSinceLastIteration);
661  auto duration = TimeUtil::GetTime(true) - start;
662  if (nJointCtrl->rtGetErrorState())
663  {
665  "NJointControllerBase '%s' requested deactivation while running it",
666  nJointCtrl->rtGetInstanceName().c_str());
668  // activeControllersChanged = true;
669  }
670  if (static_cast<std::size_t>(duration.toMicroSeconds()) >
671  nJointCtrl->rtGetNumberOfUsedControlDevices() * usPerDevUntilError)
672  {
673  ARMARX_RT_LOGF_ERROR("The NJointControllerBase '%s' took %ld µs to run!",
674  nJointCtrl->rtGetInstanceName().c_str(),
675  duration.toMicroSeconds())
676  .deactivateSpam(5);
677  }
678  else if (static_cast<std::size_t>(duration.toMicroSeconds()) >
679  nJointCtrl->rtGetNumberOfUsedControlDevices() * usPerDevUntilWarn)
680  {
681  ARMARX_RT_LOGF_WARNING("The NJointControllerBase '%s' took %ld µs to run!",
682  nJointCtrl->rtGetInstanceName().c_str(),
683  duration.toMicroSeconds())
684  .deactivateSpam(5);
685  }
686  }
687  }
688  catch (...)
689  {
690  ARMARX_ERROR << "NJoint Controller " << nJointCtrl->getInstanceName()
691  << " threw an exception and is now deactivated: "
694  // activeControllersChanged = true;
695  }
696  }
697  //stop async
698  for (std::size_t nJointCtrlIndex : _activatedAsynchronousNJointControllersIdx)
699  {
700  if (nJointCtrlIndex == _maxControllerCount)
701  {
702  break;
703  }
704  auto nJointCtrl = static_cast<AsynchronousNJointController*>(
705  activatedNjointCtrls.at(nJointCtrlIndex));
706  if (!nJointCtrl)
707  {
708  continue;
709  }
710  try
711  {
712  if (nJointCtrl->rtGetErrorState())
713  {
715  "NJointControllerBase '%s' requested deactivation while activating it",
716  nJointCtrl->rtGetInstanceName().c_str());
718  }
719  auto start = TimeUtil::GetTime(true);
720  rtSyncNJointControllerRobot(nJointCtrl);
721  nJointCtrl->rtRunIterationEnd(sensorValuesTimestamp, timeSinceLastIteration);
722  auto duration = TimeUtil::GetTime(true) - start;
723  if (nJointCtrl->rtGetErrorState())
724  {
726  "NJointControllerBase '%s' requested deactivation while running it",
727  nJointCtrl->rtGetInstanceName().c_str());
729  }
730  if (static_cast<std::size_t>(duration.toMicroSeconds()) >
731  nJointCtrl->rtGetNumberOfUsedControlDevices() * usPerDevUntilError)
732  {
733  ARMARX_RT_LOGF_ERROR("The NJointControllerBase '%s' took %ld µs to run!",
734  nJointCtrl->rtGetInstanceName().c_str(),
735  duration.toMicroSeconds())
736  .deactivateSpam(5);
737  }
738  else if (static_cast<std::size_t>(duration.toMicroSeconds()) >
739  nJointCtrl->rtGetNumberOfUsedControlDevices() * usPerDevUntilWarn)
740  {
741  ARMARX_RT_LOGF_WARNING("The NJointControllerBase '%s' took %ld µs to run!",
742  nJointCtrl->rtGetInstanceName().c_str(),
743  duration.toMicroSeconds())
744  .deactivateSpam(5);
745  }
746  }
747  catch (...)
748  {
749  ARMARX_ERROR << "NJoint Controller " << nJointCtrl->getInstanceName()
750  << " threw an exception and is now deactivated: "
753  }
754  }
755  // the activated controllers are committed in rtUpdateSensorAndControlBuffer(...)
757  }
758 
759  void
761  {
762  const NJointControllerBasePtr& nJointCtrl =
763  rtGetActivatedNJointControllers().at(nJointCtrlIndex);
764  NJointControllerAttorneyForControlThread::RtDeactivateControllerBecauseOfError(nJointCtrl);
765  for (auto ctrlDevIdx : nJointCtrl->rtGetControlDeviceUsedIndices())
766  {
767  const ControlDevicePtr& controlDevice = rtGetControlDevices().at(ctrlDevIdx);
768  JointController* es = controlDevice->rtGetJointEmergencyStopController();
769 
770  ARMARX_CHECK_EQUAL(rtGetActivatedJointToNJointControllerAssignement().at(ctrlDevIdx),
771  nJointCtrlIndex)
772  << VAROUT(ctrlDevIdx) << "\n"
773  << VAROUT(controlDevice->getDeviceName()) << "\n"
774  << dumpRtState();
775 
776  controlDevice->rtSetActiveJointController(es);
777  rtGetActivatedJointControllers().at(ctrlDevIdx) = es;
778  rtGetActivatedJointToNJointControllerAssignement().at(ctrlDevIdx) = IndexSentinel();
779  }
780  rtGetActivatedNJointControllers().at(nJointCtrlIndex) = nullptr;
781  //check ControlDeviceHardwareControlModeGroups
782  {
783  for (auto ctrlDevIdx : nJointCtrl->rtGetControlDeviceUsedIndices())
784  {
785  const auto& ctrlModeGroups = _module<Devices>().getControlModeGroups();
786  const auto groupIdx = ctrlModeGroups.groupIndices.at(ctrlDevIdx);
787  if (groupIdx == IndexSentinel())
788  {
789  continue;
790  }
791  ControlDevice* const dev = rtGetControlDevices().at(ctrlDevIdx).get();
792  JointController* const jointCtrl = dev->rtGetActiveJointController();
793  const auto hwModeHash = jointCtrl->rtGetHardwareControlModeHash();
794  //this device is in a group!
795  // -> check all other devices
796  for (const auto otherIdx : ctrlModeGroups.deviceIndices.at(groupIdx))
797  {
798  ControlDevice* const otherDev = rtGetControlDevices().at(otherIdx).get();
799  JointController* const otherJointCtrl = otherDev->rtGetActiveJointController();
800  const auto otherHwModeHash = otherJointCtrl->rtGetHardwareControlModeHash();
801  if (hwModeHash == otherHwModeHash)
802  {
803  //the assigend ctrl has the same hwMode -> don't do anything
804  continue;
805  }
806  const auto otherNJointCtrl1Idx =
807  rtGetActivatedJointToNJointControllerAssignement().at(otherIdx);
808  if (otherNJointCtrl1Idx == IndexSentinel())
809  {
810  //the hwmodes are different! (hence the other ctrl must be in stop movement
811  ARMARX_CHECK_EXPRESSION(otherJointCtrl ==
813  //we need to activate the es contoller
814  JointController* const es = otherDev->rtGetJointEmergencyStopController();
815  otherDev->rtSetActiveJointController(es);
817  rtGetActivatedJointControllers().at(otherIdx) = es;
818  continue;
819  }
820  //the devs NJoint controller needs to be deactivated
822  }
823  }
824  }
826  }
827 
828  void
830  {
831  std::size_t nJointCtrlIndex =
832  rtGetActivatedJointToNJointControllerAssignement().at(ctrlDevIndex);
833  ARMARX_CHECK_LESS(nJointCtrlIndex, rtGetControlDevices().size())
834  << "no NJoint controller controls this device (name = "
835  << rtGetControlDevices().at(ctrlDevIndex)->getDeviceName() << ", ControlMode = "
836  << rtGetActivatedJointControllers().at(ctrlDevIndex)->getControlMode() << ")!"
837  << "\n"
838  << "This means an invariant is violated! Dumping data for debugging:\n"
839  << VAROUT(ctrlDevIndex) << "\n"
840  << dumpRtState();
841 
843  }
844 
845  void
847  const IceUtil::Time& timeSinceLastIteration)
848  {
850  //commit all changes to activated controllers (joint, njoint, assignement)
851  {
852  ControlThreadDataBufferAttorneyForControlThread::CommitActivatedControllers(this);
853  }
854 
855  SensorAndControl& sc = _module<ControlThreadDataBuffer>().rtGetSensorAndControlBuffer();
856  sc.writeTimestamp = armarx::rtNow(); // this has to be in real time
857  sc.sensorValuesTimestamp = sensorValuesTimestamp;
858  sc.timeSinceLastIteration = timeSinceLastIteration;
859  ARMARX_CHECK_EQUAL(rtGetSensorDevices().size(), sc.sensors.size());
860  for (std::size_t sensIdx = 0; sensIdx < rtGetSensorDevices().size(); ++sensIdx)
861  {
862  rtGetSensorDevices().at(sensIdx)->getSensorValue()->_copyTo(sc.sensors.at(sensIdx));
863  }
864 
865  ARMARX_CHECK_EQUAL(rtGetControlDevices().size(), sc.control.size());
866  for (std::size_t ctrlIdx = 0; ctrlIdx < rtGetControlDevices().size(); ++ctrlIdx)
867  {
868  ControlDevice& controlDevice = *rtGetControlDevices().at(ctrlIdx);
869  ARMARX_CHECK_EQUAL(controlDevice.rtGetJointControllers().size(),
870  sc.control.at(ctrlIdx).size());
871  for (std::size_t targIdx = 0; targIdx < controlDevice.rtGetJointControllers().size();
872  ++targIdx)
873  {
874  JointController& jointCtrl = *controlDevice.rtGetJointControllers().at(targIdx);
875  jointCtrl.getControlTarget()->_copyTo(sc.control.at(ctrlIdx).at(targIdx));
876  }
877  }
878  _module<ControlThreadDataBuffer>().rtSensorAndControlBufferCommitWrite();
879 
880 
882  }
883 
884  const std::vector<ControlDevicePtr>&
886  {
887  return DevicesAttorneyForControlThread::GetControlDevices(this);
888  }
889 
890  const std::vector<SensorDevicePtr>&
892  {
893  return DevicesAttorneyForControlThread::GetSensorDevices(this);
894  }
895 
898  {
899  return DevicesAttorneyForControlThread::GetThreadTimingsSensorDevice(this);
900  }
901 
902  void
903  ControlThread::rtSetEmergencyStopState(EmergencyStopState state)
904  {
905  if (state == EmergencyStopState::eEmergencyStopActive)
906  {
907  emergencyStopStateRequest = EmergencyStopStateRequest::RequestActive;
908  }
909  else
910  {
911  emergencyStopStateRequest = EmergencyStopStateRequest::RequestInactive;
912  }
913  }
914 
915  void
916  ControlThread::_preFinishControlThreadInitialization()
917  {
918  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
919  controlThreadId = std::this_thread::get_id();
920 
921  _maxControllerCount = rtGetActivatedJointControllers().size();
922 
923  ARMARX_CHECK_EQUAL(_maxControllerCount,
924  rtGetActivatedJointToNJointControllerAssignement().size());
925  ARMARX_CHECK_EQUAL(_maxControllerCount, rtGetActivatedNJointControllers().size());
926  //resize buffers used for error oputput
927  preSwitchSetup_ActivatedJointControllers.resize(_maxControllerCount);
928  postSwitchSetup_ActivatedJointControllers.resize(_maxControllerCount);
929 
930  preSwitchSetup_ActivatedJointToNJointControllerAssignement.resize(_maxControllerCount);
931  postSwitchSetup_ActivatedJointToNJointControllerAssignement.resize(_maxControllerCount);
932 
933  preSwitchSetup_ActivatedNJointControllers.resize(_maxControllerCount);
934  postSwitchSetup_ActivatedNJointControllers.resize(_maxControllerCount);
935 
936  _activatedSynchronousNJointControllersIdx.resize(_maxControllerCount, _maxControllerCount);
937  _activatedAsynchronousNJointControllersIdx.resize(_maxControllerCount, _maxControllerCount);
938 
939  // setup inverse dynamics
940  if (getProperty<bool>("EnableInverseDynamics").getValue())
941  {
942  RobotUnit* robotUnit = dynamic_cast<RobotUnit*>(this);
943  ARMARX_CHECK_EXPRESSION(robotUnit);
944  std::shared_ptr<DynamicsHelper> dynamicsHelpers(new DynamicsHelper(robotUnit));
945  auto bodySetName = getProperty<std::string>("InverseDynamicsRobotBodySet").getValue();
946  auto rtRobotBodySet = rtGetRobot()->getRobotNodeSet(bodySetName);
947  ARMARX_CHECK_EXPRESSION(rtRobotBodySet)
948  << "could not find robot node set with name: " << bodySetName
949  << " - Check property InverseDynamicsRobotBodySet";
950  // rtfilters::RTFilterBasePtr accFilter(new rtfilters::ButterworthFilter(100, 1000, Lowpass, 1));
951  // rtfilters::RTFilterBasePtr velFilter(new rtfilters::ButterworthFilter(100, 1000, Lowpass, 1));
954 
955  auto setList =
956  armarx::Split(getProperty<std::string>("InverseDynamicsRobotJointSets").getValue(),
957  ",",
958  true,
959  true);
960  for (auto& set : setList)
961  {
962  auto rns = rtGetRobot()->getRobotNodeSet(set);
963  ARMARX_CHECK_EXPRESSION(rns) << "could not find robot node set with name: " << set
964  << " - Check property InverseDynamicsRobotJointSets";
965  dynamicsHelpers->addRobotPart(rns, rtRobotBodySet, velFilter, accFilter);
966  ARMARX_VERBOSE << "Added nodeset " << set << " for inverse dynamics";
967  }
968 
969  this->dynamicsHelpers = dynamicsHelpers;
970  }
971  }
972 
973  void
974  ControlThread::_preOnInitRobotUnit()
975  {
976  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
977  try
978  {
979  rtRobot = VirtualRobot::RobotIO::loadRobot(_module<RobotData>().getRobotFileName(),
980  VirtualRobot::RobotIO::eStructure);
981  rtRobot->setUpdateCollisionModel(false);
982  rtRobot->setUpdateVisualization(false);
983  rtRobot->setThreadsafe(false);
984  rtRobotNodes = rtRobot->getRobotNodes();
985  }
986  catch (VirtualRobot::VirtualRobotException& e)
987  {
988  throw UserException(e.what());
989  }
990  usPerDevUntilWarn = getProperty<std::size_t>(
991  "NjointController_AllowedExecutionTimePerControlDeviceUntilWarning")
992  .getValue();
993  usPerDevUntilError = getProperty<std::size_t>(
994  "NjointController_AllowedExecutionTimePerControlDeviceUntilError")
995  .getValue();
996  }
997 
998  void
999  ControlThread::setEmergencyStopState(EmergencyStopState state, const Ice::Current&)
1000  {
1001  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
1002  _module<Units>().getEmergencyStopMaster()->setEmergencyStopState(state);
1003  }
1004 
1005  EmergencyStopState
1006  ControlThread::getEmergencyStopState(const Ice::Current&) const
1007  {
1008  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
1009  return emergencyStop ? EmergencyStopState::eEmergencyStopActive
1010  : EmergencyStopState::eEmergencyStopInactive;
1011  }
1012 
1013  EmergencyStopState
1014  ControlThread::getRtEmergencyStopState(const Ice::Current&) const
1015  {
1016  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
1017  return rtIsInEmergencyStop() ? EmergencyStopState::eEmergencyStopActive
1018  : EmergencyStopState::eEmergencyStopInactive;
1019  }
1020 
1021  void
1022  ControlThread::setEmergencyStopStateNoReportToTopic(EmergencyStopState state)
1023  {
1024  throwIfInControlThread(BOOST_CURRENT_FUNCTION);
1025  emergencyStop = (state == EmergencyStopState::eEmergencyStopActive);
1026  }
1027 
1028  void
1029  ControlThread::processEmergencyStopRequest()
1030  {
1031  const auto state =
1032  emergencyStopStateRequest.exchange(EmergencyStopStateRequest::RequestNone);
1033  switch (state)
1034  {
1035  case EmergencyStopStateRequest::RequestActive:
1036  setEmergencyStopState(EmergencyStopState::eEmergencyStopActive);
1037  break;
1038  case EmergencyStopStateRequest::RequestInactive:
1039  setEmergencyStopState(EmergencyStopState::eEmergencyStopInactive);
1040  break;
1041  case EmergencyStopStateRequest::RequestNone:
1042  break;
1043  default:
1044  ARMARX_CHECK_EXPRESSION(!static_cast<int>(state))
1045  << "Unkown value for EmergencyStopStateRequest";
1046  }
1047  }
1048 
1049  const std::vector<JointController*>&
1050  ControlThread::rtGetActivatedJointControllers() const
1051  {
1052  return ControlThreadDataBufferAttorneyForControlThread::GetActivatedJointControllers(this);
1053  }
1054 
1055  const std::vector<NJointControllerBase*>&
1056  ControlThread::rtGetActivatedNJointControllers() const
1057  {
1058  return ControlThreadDataBufferAttorneyForControlThread::GetActivatedNJointControllers(this);
1059  }
1060 
1061  const std::vector<std::size_t>&
1062  ControlThread::rtGetActivatedJointToNJointControllerAssignement() const
1063  {
1064  return ControlThreadDataBufferAttorneyForControlThread::
1065  GetActivatedJointToNJointControllerAssignement(this);
1066  }
1067 
1068  std::vector<JointController*>&
1069  ControlThread::rtGetActivatedJointControllers()
1070  {
1071  return ControlThreadDataBufferAttorneyForControlThread::GetActivatedJointControllers(this);
1072  }
1073 
1074  std::vector<NJointControllerBase*>&
1075  ControlThread::rtGetActivatedNJointControllers()
1076  {
1077  return ControlThreadDataBufferAttorneyForControlThread::GetActivatedNJointControllers(this);
1078  }
1079 
1080  std::vector<std::size_t>&
1081  ControlThread::rtGetActivatedJointToNJointControllerAssignement()
1082  {
1083  return ControlThreadDataBufferAttorneyForControlThread::
1084  GetActivatedJointToNJointControllerAssignement(this);
1085  }
1086 
1087  const std::vector<JointController*>&
1088  ControlThread::rtGetRequestedJointControllers() const
1089  {
1090  return ControlThreadDataBufferAttorneyForControlThread::GetRequestedJointControllers(this);
1091  }
1092 
1093  const std::vector<NJointControllerBase*>&
1094  ControlThread::rtGetRequestedNJointControllers() const
1095  {
1096  return ControlThreadDataBufferAttorneyForControlThread::GetRequestedNJointControllers(this);
1097  }
1098 
1099  const std::vector<std::size_t>&
1100  ControlThread::rtGetRequestedJointToNJointControllerAssignement() const
1101  {
1102  return ControlThreadDataBufferAttorneyForControlThread::
1103  GetRequestedJointToNJointControllerAssignement(this);
1104  }
1105 
1106  void
1107  ControlThread::rtSyncNJointControllerRobot(NJointControllerBase* njctrl)
1108  {
1109  if (njctrl->rtGetRobot())
1110  {
1111  // update joints / nodes
1112  auto& from = rtRobotNodes;
1113  auto& to = njctrl->rtGetRobotNodes();
1114  for (std::size_t i = 0; i < from.size(); ++i)
1115  {
1116  to.at(i)->copyPoseFrom(from.at(i));
1117  }
1118 
1119  // update global root pose
1120  njctrl->rtGetRobot()->setGlobalPose(rtRobot->getGlobalPose(), false);
1121  }
1122  }
1123 
1124  void
1125  ControlThread::dumpRtControllerSetup(
1126  std::ostream& out,
1127  const std::string& indent,
1128  const std::vector<JointController*>& activeJCtrls,
1129  const std::vector<std::size_t>& assignement,
1130  const std::vector<NJointControllerBase*>& activeNJCtrls) const
1131  {
1132  out << indent << "JointControllers:\n";
1133  {
1134  const auto& cdevs = rtGetControlDevices();
1135  for (std::size_t i = 0; i < cdevs.size(); ++i)
1136  {
1137  const JointController* jctrl = activeJCtrls.at(i);
1138  out << indent << "\t(" << i << ")\t" << cdevs.at(i)->getDeviceName() << ":\n"
1139  << indent << "\t\t Controller: " << jctrl->getControlMode() << " (" << jctrl
1140  << ")\n"
1141  << indent << "\t\t Assigned NJoint: " << assignement.at(i) << "\n";
1142  }
1143  }
1144  out << indent << "NJointControllers:\n";
1145  {
1146  for (std::size_t i = 0; i < activeNJCtrls.size(); ++i)
1147  {
1148  const auto* njctrl = activeNJCtrls.at(i);
1149  out << indent << "\t(" << i << ")\t";
1150  if (njctrl)
1151  {
1152  out << njctrl->rtGetInstanceName() << " (" << njctrl << "):"
1153  << "\t Class: " << njctrl->rtGetClassName() << "\n";
1154  }
1155  else
1156  {
1157  out << " (" << njctrl << ")\n";
1158  }
1159  }
1160  }
1161  }
1162 
1163  std::string
1164  ControlThread::dumpRtState() const
1165  {
1166  std::stringstream str;
1167  str << "state requested\n";
1168  dumpRtControllerSetup(str,
1169  "\t",
1170  rtGetRequestedJointControllers(),
1171  rtGetRequestedJointToNJointControllerAssignement(),
1172  rtGetRequestedNJointControllers());
1173 
1174  str << "state before rtSwitchControllerSetup() was called\n";
1175  dumpRtControllerSetup(str,
1176  "\t",
1177  preSwitchSetup_ActivatedJointControllers,
1178  preSwitchSetup_ActivatedJointToNJointControllerAssignement,
1179  preSwitchSetup_ActivatedNJointControllers);
1180 
1181  str << "state after rtSwitchControllerSetup() was called\n";
1182  dumpRtControllerSetup(str,
1183  "\t",
1184  postSwitchSetup_ActivatedJointControllers,
1185  postSwitchSetup_ActivatedJointToNJointControllerAssignement,
1186  postSwitchSetup_ActivatedNJointControllers);
1187 
1188  str << "state now\n";
1189  dumpRtControllerSetup(str,
1190  "\t",
1191  rtGetActivatedJointControllers(),
1192  rtGetActivatedJointToNJointControllerAssignement(),
1193  rtGetActivatedNJointControllers());
1194 
1195  str << VAROUT(rtSwitchControllerSetupChangedControllers) << "\n";
1196  str << VAROUT(numberOfInvalidTargetsInThisIteration) << "\n";
1197  return str.str();
1198  }
1199 
1200  void
1202  {
1203  const ConstSensorDevicePtr globalPoseSensorDevice =
1204  _module<Devices>().getSensorDevice(GlobalRobotPoseSensorDevice::DeviceName());
1205  if (not globalPoseSensorDevice)
1206  {
1207  return;
1208  }
1209 
1210  const auto* const sensorValue =
1211  globalPoseSensorDevice->getSensorValue()->asA<SensorValueGlobalRobotPose>();
1212  if (sensorValue == nullptr)
1213  {
1214  return;
1215  }
1216 
1217  const auto global_T_robot = sensorValue->global_T_root;
1218  rtSetRobotGlobalPose(global_T_robot, false);
1219  }
1220 
1221  void
1223  {
1224  rtRobot->setGlobalPose(gp, updateRobot);
1225  }
1226 
1227  void
1229  {
1230  ControlThreadDataBufferAttorneyForControlThread::RTSetJointController(this, c, index);
1231  }
1232 } // namespace armarx::RobotUnitModule
armarx::SensorValueGlobalRobotPose
Definition: GlobalRobotPoseSensorDevice.h:41
armarx::RobotUnitModule::ControlThread::setEmergencyStopState
void setEmergencyStopState(EmergencyStopState state, const Ice::Current &=Ice::emptyCurrent) override
Sets the EmergencyStopState.
Definition: RobotUnitModuleControlThread.cpp:999
armarx::RTThreadTimingsSensorDevice::rtMarkRtRunNJointControllersStart
virtual void rtMarkRtRunNJointControllersStart()=0
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::GlobalRobotPoseSensorDevice::DeviceName
static std::string DeviceName()
Definition: GlobalRobotPoseSensorDevice.cpp:80
RobotUnitModuleUnits.h
str
std::string str(const T &t)
Definition: UserAssistedSegmenterGuiWidgetController.cpp:42
armarx::ControlDevice::rtGetJointStopMovementController
JointController * rtGetJointStopMovementController()
Definition: ControlDevice.h:163
armarx::DynamicsHelper
Definition: DynamicsHelper.h:42
AverageFilter.h
armarx::RobotUnitModule::ControlThread::rtRunNJointControllers
void rtRunNJointControllers(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration)
Runs NJoint controllers.
Definition: RobotUnitModuleControlThread.cpp:571
armarx::rtfilters::RTFilterBasePtr
std::shared_ptr< RTFilterBase > RTFilterBasePtr
Definition: RTFilterBase.h:34
NJointControllerBase.h
ARMARX_RT_LOGF_WARNING
#define ARMARX_RT_LOGF_WARNING(...)
Definition: ControlThreadOutputBuffer.h:343
OnScopeExit.h
SensorValueHolonomicPlatform.h
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::RobotUnitModule::ControlThread::rtGetThreadTimingsSensorDevice
RTThreadTimingsSensorDevice & rtGetThreadTimingsSensorDevice()
Returns the RTThreadTimingsSensorDevice.
Definition: RobotUnitModuleControlThread.cpp:897
RobotUnit.h
armarx::SynchronousNJointController
Definition: NJointControllerBase.h:1145
armarx::ControlDevice
The ControlDevice class represents a logical unit accepting commands via its JointControllers.
Definition: ControlDevice.h:63
armarx::RobotUnitModule::DevicesAttorneyForControlThread
This class allows minimal access to private members of Devices in a sane fashion for ControlThread.
Definition: RobotUnitModuleControlThread.cpp:222
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
armarx::RTThreadTimingsSensorDevice::rtMarkRtResetAllTargetsEnd
virtual void rtMarkRtResetAllTargetsEnd()=0
DynamicsHelper.h
armarx::Split
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelperTemplates.h:35
armarx::detail::ControlThreadOutputBufferEntry::sensors
std::vector< PropagateConst< SensorValueBase * > > sensors
Definition: ControlThreadOutputBuffer.h:203
armarx::RobotUnitModule::Management
This Module handles some general management tasks. It implements the RobotUnitManagementInterface.
Definition: RobotUnitModuleManagement.h:56
armarx::RTThreadTimingsSensorDevice::rtMarkRtHandleInvalidTargetsStart
virtual void rtMarkRtHandleInvalidTargetsStart()=0
armarx::RTThreadTimingsSensorDevice::rtMarkRtSwitchControllerSetupStart
virtual void rtMarkRtSwitchControllerSetupStart()=0
armarx::RobotUnitModule::ControlThread::rtDeactivatedNJointControllerBecauseOfError
virtual void rtDeactivatedNJointControllerBecauseOfError(const NJointControllerBasePtr &)
Hook for deriving classes (called AFTER a NJointControllerBase is deactivated due to an error)
Definition: RobotUnitModuleControlThread.h:249
armarx::JointController
The JointController class represents one joint in one control mode.
Definition: JointController.h:51
armarx::RTThreadTimingsSensorDevice::rtMarkRtRunJointControllersStart
virtual void rtMarkRtRunJointControllersStart()=0
armarx::rtfilters::AverageFilter
Definition: AverageFilter.h:32
ARMARX_CHECK_LESS
#define ARMARX_CHECK_LESS(lhs, rhs)
This macro evaluates whether lhs is less (<) than rhs and if it turns out to be false it will throw a...
Definition: ExpressionException.h:102
armarx::RobotUnitModule::ControlThread::rtGetControlDevices
const std::vector< ControlDevicePtr > & rtGetControlDevices() const
Returns all ControlDevices.
Definition: RobotUnitModuleControlThread.cpp:885
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
ARMARX_ON_SCOPE_EXIT
#define ARMARX_ON_SCOPE_EXIT
Executes given code when the enclosing scope is left.
Definition: OnScopeExit.h:112
armarx::JointAndNJointControllers::Sentinel
static constexpr std::size_t Sentinel()
Definition: JointAndNJointControllers.h:53
armarx::RobotUnitModule::ControlThread::rtReadSensorDeviceValues
void rtReadSensorDeviceValues(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration)
Calls SensorDevice::rtReadSensorValues for all SensorDevices.
Definition: RobotUnitModuleControlThread.cpp:532
armarx::RobotUnitModule::DevicesAttorneyForControlThread::ControlThread
friend class ControlThread
Definition: RobotUnitModuleControlThread.cpp:224
armarx::detail::ControlThreadOutputBufferEntry::writeTimestamp
IceUtil::Time writeTimestamp
Timestamp in wall time (never use the virtual time for this)
Definition: ControlThreadOutputBuffer.h:200
armarx::SensorValueGlobalRobotPose::global_T_root
Transformation global_T_root
Definition: GlobalRobotPoseSensorDevice.h:45
armarx::RobotUnitModule::ControlThread::rtSetRobotGlobalPose
void rtSetRobotGlobalPose(const Eigen::Matrix4f &gp, bool updateRobot=true)
Definition: RobotUnitModuleControlThread.cpp:1222
armarx::RobotUnitModule::ControlThread::SwitchControllerMode
SwitchControllerMode
Definition: RobotUnitModuleControlThread.h:94
armarx::ControlDevice::rtGetJointControllers
const std::vector< JointController * > & rtGetJointControllers()
Definition: ControlDevice.h:175
armarx::RTThreadTimingsSensorDevice::rtMarkRtHandleInvalidTargetsEnd
virtual void rtMarkRtHandleInvalidTargetsEnd()=0
armarx::RTThreadTimingsSensorDevice
Definition: RTThreadTimingsSensorDevice.h:38
RobotUnitModuleRobotData.h
armarx::ControlDevice::rtSetActiveJointController
virtual void rtSetActiveJointController(JointController *jointCtrl)
Activates the given JointController for this device.
Definition: ControlDevice.cpp:56
armarx::detail::ControlThreadOutputBufferEntry
Definition: ControlThreadOutputBuffer.h:177
armarx::RobotUnitModule::ControlThreadDataBufferAttorneyForControlThread
This class allows minimal access to private members of ControlThreadDataBuffer in a sane fashion for ...
Definition: RobotUnitModuleControlThread.cpp:79
armarx::RobotUnitModule::NJointControllerAttorneyForControlThread
This class allows minimal access to private members of NJointControllerBase in a sane fashion for Con...
Definition: RobotUnitModuleControlThread.cpp:52
armarx::GetHandledExceptionString
std::string GetHandledExceptionString()
Definition: Exception.cpp:147
armarx::JointController::rtGetHardwareControlModeHash
std::size_t rtGetHardwareControlModeHash() const
Definition: JointController.h:193
armarx::RobotUnitModule::ControlThread::rtRunJointControllers
void rtRunJointControllers(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration)
Runs Joint controllers and writes target values to ControlDevices.
Definition: RobotUnitModuleControlThread.cpp:559
armarx::RobotUnitModule::ControlThread
This Module manages the ControlThread.
Definition: RobotUnitModuleControlThread.h:83
armarx::RobotUnitModule::ControlThread::getEmergencyStopState
EmergencyStopState getEmergencyStopState(const Ice::Current &=Ice::emptyCurrent) const override
Returns the ControlThread's target EmergencyStopState.
Definition: RobotUnitModuleControlThread.cpp:1006
armarx::RobotUnitModule::ControlThread::rtSetJointController
void rtSetJointController(JointController *c, std::size_t index)
Activate a joint controller from the rt loop (only works in switch mode RTThread)
Definition: RobotUnitModuleControlThread.cpp:1228
armarx::RobotUnitModule::ControlThread::rtUpdateRobotGlobalPose
void rtUpdateRobotGlobalPose()
Definition: RobotUnitModuleControlThread.cpp:1201
ButterworthFilter.h
armarx::RTThreadTimingsSensorDevice::rtMarkRtReadSensorDeviceValuesStart
virtual void rtMarkRtReadSensorDeviceValuesStart()=0
RobotUnitModuleDevices.h
armarx::RobotUnitModule::ControlThread::rtGetRobot
const VirtualRobot::RobotPtr & rtGetRobot() const
Returns the simox robot used in the control thread.
Definition: RobotUnitModuleControlThread.h:182
armarx::RobotUnitModule::ModuleBase::IndexSentinel
static constexpr std::size_t IndexSentinel()
Returns a sentinel value for an index (std::numeric_limits<std::size_t>::max())
Definition: RobotUnitModuleBase.h:720
RobotUnitModuleControlThread.h
armarx::ControlDevice::rtGetJointEmergencyStopController
JointController * rtGetJointEmergencyStopController()
Definition: ControlDevice.h:157
armarx::RobotUnitModule::ControlThread::rtGetSensorDevices
const std::vector< SensorDevicePtr > & rtGetSensorDevices()
Returns all SensorDevices.
Definition: RobotUnitModuleControlThread.cpp:891
armarx::RobotUnitModule::ControlThread::rtIsInEmergencyStop
bool rtIsInEmergencyStop() const
Returns whether the rt thread is in emergency stop.
Definition: RobotUnitModuleControlThread.h:283
armarx::RTThreadTimingsSensorDevice::rtMarkRtResetAllTargetsStart
virtual void rtMarkRtResetAllTargetsStart()=0
RobotUnitModuleControlThreadDataBuffer.h
armarx::RobotUnitModule::ControlThread::rtSwitchControllerSetup
bool rtSwitchControllerSetup(SwitchControllerMode mode=SwitchControllerMode::IceRequests)
Changes the set of active controllers.
Definition: RobotUnitModuleControlThread.cpp:291
armarx::AsynchronousNJointController
Definition: NJointControllerBase.h:1159
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
ARMARX_RT_LOGF_ERROR
#define ARMARX_RT_LOGF_ERROR(...)
Definition: ControlThreadOutputBuffer.h:347
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::RobotUnitModule::ControlThread::rtPostReadSensorDeviceValues
virtual void rtPostReadSensorDeviceValues(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration)
Execute code after updating the sensor values.
Definition: RobotUnitModuleControlThread.cpp:546
armarx::RobotUnitModule::ControlThread::rtHandleInvalidTargets
void rtHandleInvalidTargets()
Deactivates all NJointControllers generating invalid targets.
Definition: RobotUnitModuleControlThread.cpp:509
armarx::TimeUtil::GetTime
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
Definition: TimeUtil.cpp:42
armarx::RobotUnitModule::Devices
This Module manages sensor and control devices for a RobotUnit and only allows save and sane access.
Definition: RobotUnitModuleDevices.h:67
armarx::detail::ControlThreadOutputBufferEntry::sensorValuesTimestamp
IceUtil::Time sensorValuesTimestamp
Definition: ControlThreadOutputBuffer.h:201
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
armarx::RobotUnitModule::ControlThread::rtResetAllTargets
void rtResetAllTargets()
Calls JointController::rtResetTarget for all active Joint controllers.
Definition: RobotUnitModuleControlThread.cpp:498
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::RobotUnitModule::ControlThreadDataBufferAttorneyForControlThread::ControlThread
friend class ControlThread
Definition: RobotUnitModuleControlThread.cpp:81
TimeUtil.h
armarx::RTThreadTimingsSensorDevice::rtMarkRtReadSensorDeviceValuesEnd
virtual void rtMarkRtReadSensorDeviceValuesEnd()=0
armarx::RTThreadTimingsSensorDevice::rtMarkRtRunNJointControllersEnd
virtual void rtMarkRtRunNJointControllersEnd()=0
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
set
set(LIBS ArmarXCoreInterfaces ${CMAKE_THREAD_LIBS_INIT} ${dl_LIBRARIES} ${rt_LIBRARIES} ${QT_LIBRARIES} ${Boost_LIBRARIES} BoostAssertionHandler ArmarXCPPUtility SimoxUtility) set(LIB_FILES ArmarXManager.cpp ArmarXMultipleObjectsScheduler.cpp ArmarXObjectScheduler.cpp ManagedIceObject.cpp ManagedIceObjectPlugin.cpp Component.cpp ComponentPlugin.cpp IceGridAdmin.cpp ArmarXObjectObserver.cpp IceManager.cpp PackagePath.cpp RemoteReferenceCount.cpp logging/LoggingUtil.cpp logging/Logging.cpp logging/LogSender.cpp logging/ArmarXLogBuf.cpp system/ArmarXDataPath.cpp system/DynamicLibrary.cpp system/ProcessWatcher.cpp system/FactoryCollectionBase.cpp system/cmake/CMakePackageFinder.cpp system/cmake/CMakePackageFinderCache.cpp system/cmake/ArmarXPackageToolInterface.cpp system/RemoteObjectNode.cpp services/sharedmemory/HardwareId.cpp services/tasks/RunningTask.cpp services/tasks/ThreadList.cpp services/tasks/ThreadPool.cpp services/profiler/Profiler.cpp services/profiler/FileLoggingStrategy.cpp services/profiler/IceLoggingStrategy.cpp application/Application.cpp application/ApplicationOptions.cpp application/ApplicationProcessFacet.cpp application/ApplicationNetworkStats.cpp application/properties/PropertyUser.cpp application/properties/Property.cpp application/properties/PropertyDefinition.cpp application/properties/PropertyDefinitionContainer.cpp application/properties/PropertyDefinitionHelpFormatter.cpp application/properties/PropertyDefinitionConfigFormatter.cpp application/properties/PropertyDefinitionBriefHelpFormatter.cpp application/properties/PropertyDefinitionXmlFormatter.cpp application/properties/PropertyDefinitionDoxygenFormatter.cpp application/properties/PropertyDefinitionDoxygenComponentPagesFormatter.cpp application/properties/PropertyDefinitionContainerBriefHelpFormatter.cpp application/properties/IceProperties.cpp exceptions/Exception.cpp exceptions/local/UnexpectedEnumValueException.cpp util/FileSystemPathBuilder.cpp util/StringHelpers.cpp util/IceReportSkipper.cpp util/Throttler.cpp util/distributed/AMDCallbackCollection.cpp util/distributed/RemoteHandle/ClientSideRemoteHandleControlBlock.cpp util/distributed/RemoteHandle/RemoteHandle.cpp util/distributed/RemoteHandle/RemoteHandleControlBlock.cpp time/ice_conversions.cpp time/json_conversions.cpp time/CallbackWaitLock.cpp time/Clock.cpp time/ClockType.cpp time/ClockTypeNames.cpp time/CycleUtil.cpp time/DateTime.cpp time/Duration.cpp time/Frequency.cpp time/LocalTimeServer.cpp time/Metronome.cpp time/ScopedStopWatch.cpp time/StopWatch.cpp time/Timer.cpp time/TimeKeeper.cpp time/TimeUtil.cpp csv/CsvWriter.cpp csv/CsvReader.cpp eigen/conversions.cpp eigen/ice_conversions.cpp) set(LIB_HEADERS ArmarXManager.h ArmarXDummyManager.h ArmarXMultipleObjectsScheduler.h ArmarXObjectObserver.h ArmarXObjectScheduler.h ArmarXFwd.h Component.h ComponentPlugin.h ComponentFactories.h CoreObjectFactories.h IceGridAdmin.h IceManager.h IceManagerImpl.h json_conversions.h ManagedIceObject.h ManagedIceObjectPlugin.h ManagedIceObjectImpl.h ManagedIceObjectDependency.h ManagedIceObjectRegistryInterface.h PackagePath.h RemoteReferenceCount.h system/ImportExport.h system/ImportExportComponent.h system/AbstractFactoryMethod.h system/FactoryCollectionBase.h system/Synchronization.h system/ArmarXDataPath.h system/DynamicLibrary.h system/ProcessWatcher.h system/ConditionSynchronization.h system/cmake/CMakePackageFinder.h system/cmake/CMakePackageFinderCache.h system/cmake/FindPackageX.cmake system/cmake/ArmarXPackageToolInterface.h system/RemoteObjectNode.h logging/LoggingUtil.h logging/LogSender.h logging/Logging.h logging/ArmarXLogBuf.h logging/SpamFilterData.h services/tasks/RunningTask.h services/tasks/PeriodicTask.h services/tasks/ThreadList.h services/tasks/TaskUtil.h services/tasks/ThreadPool.h services/sharedmemory/SharedMemoryProvider.h services/sharedmemory/SharedMemoryConsumer.h services/sharedmemory/IceSharedMemoryProvider.h services/sharedmemory/IceSharedMemoryConsumer.h services/sharedmemory/HardwareIdentifierProvider.h services/sharedmemory/HardwareId.h services/sharedmemory/exceptions/SharedMemoryExceptions.h services/profiler/Profiler.h services/profiler/LoggingStrategy.h services/profiler/FileLoggingStrategy.h services/profiler/IceLoggingStrategy.h application/Application.h application/ApplicationOptions.h application/ApplicationProcessFacet.h application/ApplicationNetworkStats.h application/properties/forward_declarations.h application/properties/Properties.h application/properties/Property.h application/properties/PluginEigen.h application/properties/PluginEnumNames.h application/properties/PluginCfgStruct.h application/properties/PluginAll.h application/properties/PropertyUser.h application/properties/PropertyDefinition.h application/properties/PropertyDefinition.hpp application/properties/PropertyDefinitionInterface.h application/properties/PropertyDefinitionContainer.h application/properties/PropertyDefinitionFormatter.h application/properties/PropertyDefinitionContainerFormatter.h application/properties/PropertyDefinitionConfigFormatter.h application/properties/PropertyDefinitionHelpFormatter.h application/properties/PropertyDefinitionBriefHelpFormatter.h application/properties/PropertyDefinitionXmlFormatter.h application/properties/PropertyDefinitionDoxygenFormatter.h application/properties/PropertyDefinitionDoxygenComponentPagesFormatter.h application/properties/PropertyDefinitionContainerBriefHelpFormatter.h application/properties/ProxyPropertyDefinition.h application/properties/IceProperties.h exceptions/Exception.h exceptions/LocalException.h exceptions/local/DynamicLibraryException.h exceptions/local/ExpressionException.h exceptions/local/FileIOException.h exceptions/local/InvalidPropertyValueException.h exceptions/local/MissingRequiredPropertyException.h exceptions/local/PropertyInheritanceCycleException.h exceptions/local/ProxyNotInitializedException.h exceptions/local/UnexpectedEnumValueException.h exceptions/local/UnmappedValueException.h exceptions/local/ValueRangeExceededException.h exceptions/user/NotImplementedYetException.h rapidxml/rapidxml.hpp rapidxml/rapidxml_print.hpp rapidxml/rapidxml_iterators.hpp rapidxml/rapidxml_utils.hpp rapidxml/wrapper/RapidXmlReader.h rapidxml/wrapper/RapidXmlWriter.h rapidxml/wrapper/DefaultRapidXmlReader.h rapidxml/wrapper/MultiNodeRapidXMLReader.h util/IceBlobToObject.h util/ObjectToIceBlob.h util/FileSystemPathBuilder.h util/FiniteStateMachine.h util/StringHelpers.h util/StringHelperTemplates.h util/algorithm.h util/OnScopeExit.h util/Predicates.h util/Preprocessor.h util/PropagateConst.h util/Registrar.h util/TemplateMetaProgramming.h util/TripleBuffer.h util/IceReportSkipper.h util/Throttler.h util/distributed/AMDCallbackCollection.h util/distributed/RemoteHandle/ClientSideRemoteHandleControlBlock.h util/distributed/RemoteHandle/RemoteHandle.h util/distributed/RemoteHandle/RemoteHandleControlBlock.h util/SimpleStatemachine.h time.h time_minimal.h time/forward_declarations.h time/ice_conversions.h time/json_conversions.h time/CallbackWaitLock.h time/Clock.h time/ClockType.h time/ClockTypeNames.h time/CycleUtil.h time/DateTime.h time/Duration.h time/Frequency.h time/LocalTimeServer.h time/Metronome.h time/ScopedStopWatch.h time/StopWatch.h time/Timer.h time/TimeUtil.h time/TimeKeeper.h csv/CsvWriter.h csv/CsvReader.h eigen/conversions.h eigen/ice_conversions.h ice_conversions.h ice_conversions/ice_conversions_boost_templates.h ice_conversions/ice_conversions_templates.h ice_conversions/ice_conversions_templates.tpp $
Definition: CMakeLists.txt:12
armarx::RobotUnit
The RobotUnit class manages a robot and its controllers.
Definition: RobotUnit.h:180
armarx::ControlTargetBase::_copyTo
void _copyTo(std::unique_ptr< T > &target) const
Definition: ControlTargetBase.h:110
armarx::RobotUnitModule::ControlThread::SwitchControllerMode::IceRequests
@ IceRequests
armarx::RobotUnitModule::ModuleBase::_module
T & _module()
Returns this as ref to the given type.
Definition: RobotUnitModuleBase.h:249
armarx::RobotUnitModule::ModuleBase::throwIfInControlThread
void throwIfInControlThread(const std::string &fnc) const
Throws if the current thread is the ControlThread.
Definition: RobotUnitModuleBase.cpp:416
GlobalRobotPoseSensorDevice.h
armarx::ConstSensorDevicePtr
std::shared_ptr< const class SensorDevice > ConstSensorDevicePtr
Definition: NJointControllerBase.h:77
armarx::RobotUnitModule::ControlThread::rtUpdateSensorAndControlBuffer
void rtUpdateSensorAndControlBuffer(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration)
Updates the current SensorValues and ControlTargets for code running outside of the ControlThread.
Definition: RobotUnitModuleControlThread.cpp:846
armarx::detail::ControlThreadOutputBufferEntry::control
std::vector< std::vector< PropagateConst< ControlTargetBase * > > > control
Definition: ControlThreadOutputBuffer.h:204
armarx::RTThreadTimingsSensorDevice::rtMarkRtRunJointControllersEnd
virtual void rtMarkRtRunJointControllersEnd()=0
armarx::RobotUnitModule::ControlThread::rtSetEmergencyStopState
void rtSetEmergencyStopState(EmergencyStopState state)
Set an EmergencyStopState request.
Definition: RobotUnitModuleControlThread.cpp:903
armarx::RobotUnitModule
Definition: ControlDevice.h:34
armarx::JointController::getControlTarget
virtual ControlTargetBase * getControlTarget()=0
Definition: JointController.h:144
ARMARX_CHECK_EQUAL
#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...
Definition: ExpressionException.h:130
armarx::RobotUnitModule::ControlThread::rtDeactivateAssignedNJointControllerBecauseOfError
void rtDeactivateAssignedNJointControllerBecauseOfError(std::size_t ctrlDevIndex)
Searches for the NJointControllerBase responsible for the given JointController and deactivates it.
Definition: RobotUnitModuleControlThread.cpp:829
armarx::RobotUnitModule::ControlThread::rtDeactivateNJointControllerBecauseOfError
void rtDeactivateNJointControllerBecauseOfError(std::size_t nJointCtrlIndex)
Deactivates a NJointControllerBase and sets all used ControlDevices to EmergencyStop.
Definition: RobotUnitModuleControlThread.cpp:760
armarx::ControlDevice::rtGetActiveJointController
JointController * rtGetActiveJointController()
Definition: ControlDevice.h:169
armarx::RobotUnitModule::ControlThread::getRtEmergencyStopState
EmergencyStopState getRtEmergencyStopState(const Ice::Current &=Ice::emptyCurrent) const override
Returns the ControlThread's EmergencyStopState.
Definition: RobotUnitModuleControlThread.cpp:1014
armarx::RTThreadTimingsSensorDevice::rtMarkRtUpdateSensorAndControlBufferEnd
virtual void rtMarkRtUpdateSensorAndControlBufferEnd()=0
armarx::RTThreadTimingsSensorDevice::rtMarkRtSwitchControllerSetupEnd
virtual void rtMarkRtSwitchControllerSetupEnd()=0
armarx::RobotUnitModule::ManagementAttorneyForControlThread
This class allows minimal access to private members of Devices in a sane fashion for ControlThread.
Definition: RobotUnitModuleControlThread.cpp:270
RobotUnitModuleManagement.h
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:18
armarx::detail::ControlThreadOutputBufferEntry::timeSinceLastIteration
IceUtil::Time timeSinceLastIteration
Definition: ControlThreadOutputBuffer.h:202
armarx::RobotUnitModule::ControlThreadDataBuffer
This Module manages all communication into and out of the ControlThread.
Definition: RobotUnitModuleControlThreadDataBuffer.h:79
armarx::RTThreadTimingsSensorDevice::rtMarkRtUpdateSensorAndControlBufferStart
virtual void rtMarkRtUpdateSensorAndControlBufferStart()=0
armarx::rtNow
IceUtil::Time rtNow()
Definition: RtTiming.h:40