NJointControllerBase.h
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::NJointController
17  * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
18  * @date 2017
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #pragma once
24 
25 #include <atomic>
26 #include <map>
27 #include <mutex>
28 #include <optional>
29 
30 #include <VirtualRobot/VirtualRobot.h>
31 
33 #include <ArmarXCore/core/exceptions/local/ExpressionException.h> // for ARMARX_CHECK
35 #include <ArmarXCore/interface/core/ManagedIceObjectDefinitions.h>
36 
37 // #include <RobotAPI/components/units/RobotUnit/RobotUnit.h>
38 
39 #include <RobotAPI/interface/units/RobotUnit/NJointController.h>
40 #include <RobotAPI/interface/units/RobotUnit/RobotUnitInterface.h>
41 
42 namespace IceProxy::armarx
43 {
44  class DebugDrawerInterface;
45  class DebugObserverInterface;
46  class RobotUnitInterface;
47 } // namespace IceProxy::armarx
48 
49 namespace armarx
50 {
51  namespace RobotUnitModule
52  {
53  class NJointControllerAttorneyForPublisher;
54  class NJointControllerAttorneyForControlThread;
55  class NJointControllerAttorneyForControllerManagement;
56  } // namespace RobotUnitModule
57 
58  namespace detail
59  {
60  template <class>
63  } // namespace detail
64 
65  namespace WidgetDescription
66  {
67  class Widget;
68  typedef ::IceInternal::Handle<::armarx::WidgetDescription::Widget> WidgetPtr;
69  typedef ::std::map<::std::string, ::armarx::WidgetDescription::WidgetPtr>
71  } // namespace WidgetDescription
72 
74  class JointController;
75  class SensorValueBase;
76  class ControlTargetBase;
77  using ConstControlDevicePtr = std::shared_ptr<const class ControlDevice>;
78  using ConstSensorDevicePtr = std::shared_ptr<const class SensorDevice>;
79 
80  typedef ::IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface>
82  typedef ::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface>
84  typedef ::IceInternal::ProxyHandle<::IceProxy::armarx::RobotUnitInterface>
86 
87  using ThreadPoolPtr = std::shared_ptr<class ThreadPool>;
88 
92 
94 
95  /**
96  * @defgroup Library-RobotUnit-NJointControllers NJointControllers
97  * @ingroup Library-RobotUnit
98  */
99 
100  /**
101  * @ingroup Library-RobotUnit-NJointControllers
102  * @brief A high level controller writing its results into \ref ControlTargetBase "ControlTargets".
103  *
104  * This is the abstract base class for all NJointControllers.
105  * It implements basic management routines required by the RobotUnit and some basic ice calls.
106  * \ref NJointControllerBase "NJointControllers" are instantiated and managed by the \ref RobotUnit.
107  *
108  * A \ref NJointControllerBase calculates \ref ControlTargetBase "ControlTargets" for a set of
109  * \ref ControlDevice "ControlDevices" in a specific ControlMode.
110  * This ControlMode is defined for each \ref ControlDevice during construction.
111  *
112  * \section nj-state Requested and Active
113  * A \ref NJointControllerBase can is requested / not requested and active / inactive.
114  * All four combinations are possible.
115  *
116  * \subsection nj-state-req Requested / Not Requested
117  * If the user wants this \ref NJointControllerBase to be executed it is in a requested state (see \ref isControllerRequested).
118  * Otherwise the controler is not requested.
119  *
120  * Calling \ref activateController sets the state to requested.
121  * Calling \ref deactivateController sets the state to not requested.
122  * If the \ref NJointControllerBase causes an error or a different \ref NJointControllerBase using one or more of the same
123  * \ref ControlDevice's is requested, this \ref NJointControllerBase is deactivated.
124  *
125  *
126  * \subsection nj-state-act Active / Inactive
127  * Is the \ref NJointControllerBase executed by the \ref RobotUnitModules::ControlThread "ControlThread" it is active
128  * (see \ref isControllerActive).
129  *
130  * To be executed by the \ref RobotUnitModules::ControlThread "ControlThread", the \ref NJointControllerBase has to be
131  * requested at some point in the past.
132  *
133  * If a controller is active, it has to write a valid \ref ControlTargetBase "ControlTarget"
134  * for each of its \ref ControlDevice "ControlDevicea" (if it fails, it will be deactivated).
135  *
136  * \section Constructor
137  * In the Constructor, a \ref NJointControllerBase has to declare all \ref ControlDevice "ControlDevices" it uses.
138  *
139  * The constructor takes a pointer to a configuration structure of the type \ref NJointControllerBase::ConfigPtrT.
140  * If an implementation requires a special configuration structure (e.g.: SomeOtherCfg), it has to override this type by calling adding
141  * \code{.cpp}
142  * using ConfigPtrT = SomeOtherCfgPtr;
143  * \endcode
144  * to it's clas definition.
145  * The type SomeOtherCfg has to derive \ref NJointControllerConfigPtr.
146  *
147  * There is a way to generate a small gui widget for controller construction (see this \ref nj-ctor-gui "section").
148  *
149  * \subsection nj-ctor-req-ctrl Using ControlTargets
150  * A \ref NJointControllerBase can use \ref peekControlDevice to examine a \ref ControlDevice before using it
151  * (e.g.: checking the supported \ref ControlTargetBase "ControlTargets").
152  *
153  * If a \ref ControlDevice should be used by this \ref NJointControllerBase, it has to call \ref useControlDevice.
154  * This sets the ControlMode for the \ref ControlDevice and returns a pointer to the \ref ControlTargetBase "ControlTarget".
155  * This pointer has to be used to send commands in each iteration of \ref rtRun.
156  * The ControlMode can't be changed afterwards (A new \ref NJointControllerBase has to be created).
157  *
158  *
159  * \subsection nj-ctor-req-sens Using SensorValues
160  * A \ref NJointControllerBase can use \ref peekSensorDevice to examine a \ref SensorDevice before using it.
161  *
162  * If a \ref SensorDevice should be used by this \ref NJointControllerBase, it has to call \ref useSensorDevice.
163  * This returns a pointer to the \ref SensorValueBase "SensorValue".
164  *
165  * \subsection nj-ctor-rob A synchronized Virtualrobot
166  * If the controller needs a simox robot in \ref rtRun, it should call \ref useSynchronizedRtRobot.
167  * This will provide a simoxRobot via \ref rtGetRobot.
168  * This robot is synchronized with the real robots state before calling \ref rtRun
169  *
170  * \section nj-parts Rt and non Rt
171  * Each \ref NJointControllerBase has two parts:
172  * \li The RT controll loop
173  * \li The NonRT ice communication
174  *
175  * \subsection rtcontrollloop The Rt controll loop (\ref rtRun)
176  * \warning This part has to satisfy realtime conditions!
177  * All realtime functions of \ref NJointControllerBase have the 'rt' prefix.
178  *
179  * Here the \ref NJointControllerBase has access to the robot's current state
180  * and has to write results into \ref ControlTargetBase "ControlTargets".
181  *
182  * It must not:
183  * \li call any blocking operation
184  * \li allocate ram on the heap (since this is a blocking operation)
185  * \li resize any datastructure (e.g. vector::resize) (this sometimes allocates ram on the heap)
186  * \li insert new datafields into datastructures (e.g. vector::push_back) (this sometimes allocates ram on the heap)
187  * \li write to any stream (e.g. ARMARX_VERBOSE, std::cout, print, filestreams) (this sometimes blocks/allocates ram on the heap)
188  * \li make network calls (e.g. through ice) (this blocks/allocates ram on the heap) (using begin_... end_... version of ice calls IS NO SOLUTION)
189  * \li do any expensive calculations (e.g. calculate IK, run some solver, invert big matrices)
190  *
191  * \subsection nonrtpart The NonRT ice communication
192  * This part consits of any ice communication.
193  * Here the \ref NJointControllerBase can get new controll parameters or targets from other components.
194  *
195  * \section rtnrtcomm Communication between RT and NonRT
196  * All communication between RT and NonRT has to be lockfree.
197  * The \ref NJointControllerBase has to use constructs like atomics or
198  * \ref TripleBuffer "TripleBuffers" (See \ref armarx::NJointControllerWithTripleBuffer).
199  *
200  * \image html NJointControllerGeneralDataFlow.svg "General Dataflow in a NJointControllerBase"
201  *
202  * \image html NJointControllerAtomicDataFlow.svg "Dataflow in a NJointControllerBase using atomics for communication between RT and NonRT"
203  *
204  * \image html NJointControllerTripleBufferDataFlow.svg "Dataflow in a NJointControllerBase using a triple buffer for communication between RT and NonRT"
205  *
206  *
207  * \image html NJointControllerDataFlow_Graph.svg "Dataflow in a NJointControllerBase as a Graph of the two participating domains"
208  * The above image shows the two participating domains: one RT thread and multiple ICE threads.
209  * If data has to flow along an arrow, you need some construct for non blocking message passing.
210  *
211  * \warning If you use \ref TrippleBuffer "TrippleBuffers" or \ref WriteBufferedTrippleBuffer "WriteBufferedTrippleBuffers" you need a separate one for each arrow.
212  *
213  * \section expensivework How to do expensive calculations
214  * You have to execute expensive calculations in a different worker thread.
215  * This thread could calculate target values at its own speed (e.g. 100 Hz).
216  *
217  * While rtRun runs at a higher frequency (e.g. 1000 Hz) and:
218  * \li reads target values
219  * \li optionally passes the target values to a PID controller
220  * \li writes them to the targets
221  * \li sends the sensor values to the worker thread.
222  *
223  * If you do some additional calculation in rtRun, you maybe need to pass config parameters from NonRT to RT using a nonblocking method.
224  *
225  * \image html NJointControllerWorkerThreadDataFlow.svg "Dataflow in a NJointControllerBase using a worker thread"
226  *
227  * \image html NJointControllerWorkerThreadDataFlow_Graph.svg "Dataflow in a NJointControllerBase using a worker thread as a Graph of the three participating domains"
228  * The above image shows the three participating domains: one RT thread, one worker trhead and multiple ICE threads.
229  * If data has to flow along an arrow, you need some construct for non blocking message passing.
230  *
231  * \warning If you use \ref TrippleBuffer "TrippleBuffers" or \ref WriteBufferedTrippleBuffer "WriteBufferedTrippleBuffers" you need a separate one for each arrow.
232  *
233  * \section nj-ctor-gui Providing a gui for controller construction.
234  * By implementing these functions:
235  * \code{.cpp}
236  static WidgetDescription::WidgetPtr GenerateConfigDescription
237  (
238  const VirtualRobot::RobotPtr& robot,
239  const std::map<std::string, ConstControlDevicePtr>& controlDevices,
240  const std::map<std::string, ConstSensorDevicePtr>& sensorDevices
241  ); //describes how the widget is supposed to look
242  static ConfigPtrT GenerateConfigFromVariants(const StringVariantBaseMap&); // turns the resulting variants into a config
243  * \endcode
244  *
245  * The \ref RobotUnitGui will provide a widget to configure and construct a \ref NJointControllerBase of this type.
246  *
247  * \section Examples
248  *
249  * More examples can be found in the Tutorials Package
250  *
251  * \subsection nj-example-1 A simple pass Position controller
252  * \note The code can be found in the Tutorial package
253  *
254  * \subsection nj-example-1-h Header
255  * Include headers
256  * \code{.cpp}
257  #include <RobotAPI/components/units/RobotUnit/ControlTargets/ControlTarget1DoFActuator.h>
258  #include <RobotAPI/components/units/RobotUnit/RobotUnit.h>
259  #include <RobotAPI/components/units/RobotUnit/SensorValues/SensorValue1DoFActuator.h>
260  * \endcode
261  *
262  * Open the namespace
263  * \code{.cpp}
264  namespace armarx
265  {
266  * \endcode
267  *
268  * Typedef some pointers
269  * \code{.cpp}
270  TYPEDEF_PTRS_HANDLE(NJointPositionPassThroughController);
271  TYPEDEF_PTRS_HANDLE(NJointPositionPassThroughControllerConfig);
272  * \endcode
273  *
274  * The config has to inherit \ref NJointControllerConfig and consists only of the joint name
275  * \code{.cpp}
276  class NJointPositionPassThroughControllerConfig : virtual public NJointControllerConfig
277  {
278  public:
279  NJointPositionPassThroughControllerConfig(const std::string& name): deviceName {name} {}
280  std::string deviceName;
281  };
282  * \endcode
283  *
284  * The controller class has to inherit \ref NJointControllerBase
285  * \code{.cpp}
286  class NJointPositionPassThroughController: public NJointControllerBase
287  {
288  public:
289  * \endcode
290  *
291  * The \ref NJointControllerBase provides a config widget for the \ref RobotUnitGuiPlugin
292  * \code{.cpp}
293  static WidgetDescription::WidgetPtr GenerateConfigDescription
294  (
295  const VirtualRobot::RobotPtr&,
296  const std::map<std::string, ConstControlDevicePtr>& controlDevices,
297  const std::map<std::string, ConstSensorDevicePtr>& sensorDevices
298  );
299  static NJointControllerConfigPtr GenerateConfigFromVariants(const StringVariantBaseMap& values);
300  * \endcode
301  *
302  * The ctor receives a pointer to the \ref RobotUnit, a pointer to the config and a pointer to a VirtualRobot model.
303  * \code{.cpp}
304  NJointPositionPassThroughController(
305  const RobotUnitPtr& prov,
306  NJointControllerConfigPtr config,
307  const VirtualRobot::RobotPtr& r
308  );
309  * \endcode
310  *
311  * The function to provide the class name.
312  * \code{.cpp}
313  std::string getClassName(const Ice::Current&) const override;
314  * \endcode
315  *
316  * This controller provides widgets for function calls.
317  * \code{.cpp}
318  WidgetDescription::StringWidgetDictionary getFunctionDescriptions(const Ice::Current&) const override;
319  void callDescribedFunction(const std::string& name, const StringVariantBaseMap& value, const Ice::Current&) override;
320  * \endcode
321  *
322  * The run function executed to calculate new targets
323  * \code{.cpp}
324  void rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) override;
325  * \endcode
326  *
327  * Hooks for this \ref NJointControllerBase to execute code during publishing.
328  * \code{.cpp}
329  void onPublishActivation(const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&) override;
330  void onPublishDeactivation(const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&) override;
331  void onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&) override;
332  * \endcode
333  *
334  * This \ref NJointControllerBase uses one position \ref SensorValue1DoFActuatorPosition "SensorValue", calculates one
335  * position \ref ControlTarget1DoFActuatorPosition "ControlTarget" and stores the current position target and position value in atomics.
336  * \code{.cpp}
337  const SensorValue1DoFActuatorPosition* sensor;
338  ControlTarget1DoFActuatorPosition* target;
339  std::atomic<float> targetPos {0};
340  std::atomic<float> currentPos {0};
341  * \endcode
342  *
343  * Close the class and the namespace
344  * \code{.cpp}
345  };
346  }
347  * \endcode
348  *
349  * \subsection nj-example-1-c Source file
350  *
351  * Include the required headers.
352  * \code{.cpp}
353  #include <RobotAPI/libraries/core/Pose.h>
354 
355  #include "NJointPositionPassThroughController.h"
356  * \endcode
357  *
358  * Open the namespace
359  * \code{.cpp}
360  namespace armarx
361  {
362  * \endcode
363  *
364  * This generates a config widget used to display a config gui in \ref RobotUnitGui.
365  * It consist out of a \ref HBoxLayout containing a \ref Label and a \ref StringComboBox
366  * \code{.cpp}
367  WidgetDescription::WidgetPtr NJointPositionPassThroughController::GenerateConfigDescription(const VirtualRobot::RobotPtr&, const std::map<std::string, ConstControlDevicePtr>& controlDevices, const std::map<std::string, ConstSensorDevicePtr>& sensorDevices)
368  {
369  using namespace armarx::WidgetDescription;
370  HBoxLayoutPtr layout = new HBoxLayout;
371  LabelPtr label = new Label;
372  label->text = "control device name";
373  layout->children.emplace_back(label);
374  StringComboBoxPtr box = new StringComboBox;
375  box->defaultIndex = 0;
376  * \endcode
377  *
378  * The \ref StringComboBox only contains the names of \ref ControlDevice "ControlDevices" accepting
379  * a position \ref ControlTarget1DoFActuatorPosition "ControlTarget" and providing a position
380  * \ref SensorValue1DoFActuatorPosition "SensorValue"
381  * \code{.cpp}
382  //filter control devices
383  for (const auto& name2dev : controlDevices)
384  {
385  const ConstControlDevicePtr& dev = name2dev.second;
386  const auto& name = name2dev.first;
387  if (
388  dev->hasJointController(ControlModes::Position1DoF) &&
389  dev->getJointController(ControlModes::Position1DoF)->getControlTarget()->isA<ControlTarget1DoFActuatorPosition>() &&
390  sensorDevices.count(name) &&
391  sensorDevices.at(name)->getSensorValue()->isA<SensorValue1DoFActuatorPosition>()
392  )
393  {
394  box->options.emplace_back(name);
395  }
396  }
397  box->name = "name";
398  layout->children.emplace_back(box);
399  return layout;
400  }
401  * \endcode
402  *
403  * This turns a map of variants into the config required by this \ref NJointControllerBase.
404  * The \ref Variant for the key 'name' defines the \ref ControlDevice.
405  * \code{.cpp}
406  NJointControllerConfigPtr NJointPositionPassThroughController::GenerateConfigFromVariants(const StringVariantBaseMap& values)
407  {
408  //you should check here for types null additional params etc
409  return new NJointPositionPassThroughControllerConfig {values.at("name")->getString()};
410  }
411  * \endcode
412  *
413  * The constructors implementation.
414  * \code{.cpp}
415  NJointPositionPassThroughController::NJointPositionPassThroughController(
416  const RobotUnitPtr& ru,
417  NJointControllerConfigPtr config,
418  const VirtualRobot::RobotPtr&
419  )
420  {
421  ARMARX_CHECK_EXPRESSION(ru);
422  * \endcode
423  *
424  * It checks whether the provided config has the correct type.
425  * \code{.cpp}
426  NJointPositionPassThroughControllerConfigPtr cfg = NJointPositionPassThroughControllerConfigPtr::dynamicCast(config);
427  ARMARX_CHECK_EXPRESSION(cfg) << "The provided config has the wrong type! The type is " << config->ice_id();
428  * \endcode
429  *
430  * Then it retrieves the \ref SensorValue1DoFActuatorPosition "SensorValue" and
431  * \ref ControlTarget1DoFActuatorPosition "ControlTarget", casts then to the required types and stores them to the member variables.
432  * \code{.cpp}
433  const SensorValueBase* sv = useSensorValue(cfg->deviceName);
434  ControlTargetBase* ct = useControlTarget(cfg->deviceName, ControlModes::Position1DoF);
435  ARMARX_CHECK_EXPRESSION(sv->asA<SensorValue1DoFActuatorPosition>());
436  ARMARX_CHECK_EXPRESSION(ct->asA<ControlTarget1DoFActuatorPosition>());
437  sensor = sv->asA<SensorValue1DoFActuatorPosition>();
438  target = ct->asA<ControlTarget1DoFActuatorPosition>();
439  }
440  * \endcode
441  *
442  * The class name has to be unique, hence the c++ class name should be used.
443  * \code{.cpp}
444  std::string NJointPositionPassThroughController::getClassName(const Ice::Current&) const
445  {
446  return "NJointPositionPassThroughController";
447  }
448 
449  * \endcode
450  *
451  * This \ref NJointControllerBase provides two widgets for function calls.
452  * \code{.cpp}
453  WidgetDescription::StringWidgetDictionary NJointPositionPassThroughController::getFunctionDescriptions(const Ice::Current&) const
454  {
455  using namespace armarx::WidgetDescription;
456  * \endcode
457  *
458  * The first widget has a \ref Label and a \ref FloatSpinBox.
459  * \code{.cpp}
460  HBoxLayoutPtr layoutSetPos = new HBoxLayout;
461  {
462  LabelPtr label = new Label;
463  label->text = "positiontarget";
464  layoutSetPos->children.emplace_back(label);
465  FloatSpinBoxPtr spin = new FloatSpinBox;
466  spin->defaultValue = 0;
467  spin->max = 1;
468  spin->min = -1;
469  * \endcode
470  *
471  * The \ref FloatSpinBox creates a variant called 'spinmearound'
472  * \code{.cpp}
473  spin->name = "spinmearound";
474  layoutSetPos->children.emplace_back(spin);
475  }
476  * \endcode
477  *
478  * The second widget also has a \ref Label and a \ref FloatSpinBox.
479  * \code{.cpp}
480  VBoxLayoutPtr layoutSetHalfPos = new VBoxLayout;
481  {
482  LabelPtr label = new Label;
483  label->text = "positiontarget / 2";
484  layoutSetHalfPos->children.emplace_back(label);
485  FloatSpinBoxPtr spin = new FloatSpinBox;
486  spin->defaultValue = 0;
487  spin->max = 0.5;
488  spin->min = -0.5;
489  spin->name = "spinmehalfaround";
490  layoutSetHalfPos->children.emplace_back(spin);
491  }
492  * \endcode
493  *
494  * This returns a map of boths widgets.
495  * The keys will be used to identify the called function.
496  * \code{.cpp}
497  return {{"SetPosition", layoutSetPos}, {"SetPositionHalf", layoutSetHalfPos}};
498  }
499  * \endcode
500  *
501  * This function is called from the \ref RobotUnitGuiPlugin when the prior defined functions are called.
502  * Both functions set the target position.
503  * \code{.cpp}
504  void NJointPositionPassThroughController::callDescribedFunction(const std::string& name, const StringVariantBaseMap& value, const Ice::Current&)
505  {
506  if (name == "SetPosition")
507  {
508  //you should check here for types null additional params etc
509  targetPos = value.at("spinmearound")->getFloat();
510  }
511  else if (name == "SetPositionHalf")
512  {
513  //you should check here for types null additional params etc
514  targetPos = value.at("spinmehalfaround")->getFloat() * 2;
515  }
516  else
517  {
518  ARMARX_ERROR << "CALLED UNKNOWN REMOTE FUNCTION: " << name;
519  }
520  }
521  * \endcode
522  *
523  * The \ref rtRun function sets the \ref ControlTarget1DoFActuatorPosition "ControlTarget" to the
524  * target value set via the atomic and stores the current
525  * \ref SensorValue1DoFActuatorPosition "SensorValue" to the other atomic.
526  * \code{.cpp}
527  void NJointPositionPassThroughController::rtRun(const IceUtil::Time& t, const IceUtil::Time&)
528  {
529  ARMARX_RT_LOGF_ERROR("A MESSAGE PARAMETER %f", t.toSecondsDouble()).deactivateSpam(1);
530  ARMARX_RT_LOGF_IMPORTANT("A MESSAGE WITHOUT PARAMETERS").deactivateSpam(1);
531  target->position = targetPos;
532  currentPos = sensor->position;
533  }
534  * \endcode
535  *
536  * The publish activation \ref onPublishActivation "hook" does nothing, but could be used to call
537  * \ref DebugDraver::setRobotVisu.
538  * \code{.cpp}
539  void NJointPositionPassThroughController::onPublishActivation(const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&)
540  {
541  //we could do some setup for the drawer here. e.g. add a robot
542  }
543 
544  * \endcode
545  *
546  * The publish deactivation \ref onPublishDeactivation "hook" clears the \ref DebugDrawer layer
547  * \code{.cpp}
548  void NJointPositionPassThroughController::onPublishDeactivation(const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&)
549  {
550  drawer->removeLayer("Layer_" + getInstanceName());
551  }
552 
553  * \endcode
554  *
555  * The publish \ref onPublish "hook" draws a sphere with radius of the position stored in the atomic times 2000 to the \ref DebugDrawer.
556  * \code{.cpp}
557  void NJointPositionPassThroughController::onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&)
558  {
559  drawer->setSphereVisu("Layer_" + getInstanceName(), "positionball", new Vector3, armarx::DrawColor {1, 1, 1, 1}, currentPos * 2000);
560  }
561  * \endcode
562  *
563  * This registers a factory for this \ref NJointControllerBase.
564  * This factory is used by the \ref RobotUnit to create the \ref NJointControllerBase.
565  * The passed name has to match the name returned by \ref getClassName.
566  * \code{.cpp}
567  NJointControllerRegistration<NJointPositionPassThroughController> registrationControllerNJointPositionPassThroughController("NJointPositionPassThroughController");
568  * \endcode
569  *
570  * This statically asserts a factory for the type NJointPositionPassThroughController is present.
571  * \code{.cpp}
572  ARMARX_ASSERT_NJOINTCONTROLLER_HAS_CONSTRUCTION_GUI(NJointPositionPassThroughController);
573  * \endcode
574  * Close the namespace
575  * \code{.cpp}
576  }
577  * \endcode
578  */
580  virtual public NJointControllerInterface,
581  virtual public ManagedIceObject
582  {
583  // //////////////////////////////////////////////////////////////////////////////////////// //
584  // /////////////////////////////////////// typedefs /////////////////////////////////////// //
585  // //////////////////////////////////////////////////////////////////////////////////////// //
586  public:
587  using ConfigPtrT = NJointControllerConfigPtr;
589  const VirtualRobot::RobotPtr&,
590  const std::map<std::string, ConstControlDevicePtr>& controlDevices,
591  const std::map<std::string, ConstSensorDevicePtr>& sensorDevices);
592  template <class ConfigPrtType>
594  ConfigPrtType (*)(const StringVariantBaseMap&);
595  // //////////////////////////////////////////////////////////////////////////////////////// //
596  // ///////////////////////////// constructor setup functions ////////////////////////////// //
597  // //////////////////////////////////////////////////////////////////////////////////////// //
598  public:
599  /**
600  * @brief Get a const ptr to the given \ref SensorDevice
601  * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
602  * @param deviceName The \ref SensorDevice's name
603  * @return A const ptr to the given \ref SensorDevice
604  */
605  ConstSensorDevicePtr peekSensorDevice(const std::string& deviceName) const;
606  /**
607  * @brief Get a const ptr to the given \ref ControlDevice
608  * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
609  * @param deviceName The \ref ControlDevice's name
610  * @return A const ptr to the given \ref ControlDevice
611  */
612  ConstControlDevicePtr peekControlDevice(const std::string& deviceName) const;
613 
614  /**
615  * @brief Declares to calculate the \ref ControlTargetBase "ControlTarget"
616  * for the given \ref ControlDevice in the given ControlMode when \ref rtRun is called
617  * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
618  * @param deviceName The \ref ControlDevice's name
619  * @param controlMode The \ref ControlTargetBase "ControlTarget's" ControlMode
620  * @return A ptr to the given \ref ControlDevice's \ref ControlTargetBase "ControlTarget"in the given ControlMode
621  */
622  ControlTargetBase* useControlTarget(const std::string& deviceName,
623  const std::string& controlMode);
624 
625  /**
626  * @brief Declares to calculate the \ref ControlTargetBase "ControlTarget"
627  * for the given \ref ControlDevice in the given ControlMode when \ref rtRun is called
628  * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
629  * @param deviceName The \ref ControlDevice's name
630  * @param controlMode The \ref ControlTargetBase "ControlTarget's" ControlMode
631  * @return A ptr to the given \ref ControlDevice's \ref ControlTargetBase "ControlTarget"in the given ControlMode
632  */
633  template <class T>
634  T*
635  useControlTarget(const std::string& deviceName, const std::string& controlMode)
636  {
638  "The given type does not derive ControlTargetBase");
639  ControlTargetBase* const ptr = useControlTarget(deviceName, controlMode);
640  return dynamic_cast<T*>(ptr);
641  }
642 
643  /**
644  * @brief Get a const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
645  * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
646  * @param deviceName The \ref SensorDevice's name
647  * @return A const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
648  */
649  const SensorValueBase* useSensorValue(const std::string& sensorDeviceName) const;
650 
651  /**
652  * @brief Get a const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
653  * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
654  * @param deviceName The \ref SensorDevice's name
655  * @return A const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
656  */
657  template <class T>
658  const T*
659  useSensorValue(const std::string& deviceName) const
660  {
662  "The given type does not derive SensorValueBase");
663  const SensorValueBase* const ptr = useSensorValue(deviceName);
664  return dynamic_cast<const T*>(ptr);
665  }
666 
667  /**
668  * @brief Requests a VirtualRobot for use in \ref rtRun
669  * *
670  * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
671  *
672  * The robot is updated before \ref rtRun is called and can be accessed via \rtGetRobot
673  * @param updateCollisionModel Whether the robot's collision model should be updated
674  * @see rtGetRobot
675  */
676  const VirtualRobot::RobotPtr& useSynchronizedRtRobot(bool updateCollisionModel = false);
677 
678  // //////////////////////////////////////////////////////////////////////////////////////// //
679  // ////////////////////////////////// Component interface ///////////////////////////////// //
680  // //////////////////////////////////////////////////////////////////////////////////////// //
681  protected:
682  /// @see Component::getDefaultName
683  std::string
684  getDefaultName() const override
685  {
686  return getClassName();
687  }
688 
689  /// @see Component::onInitComponent
690  void onInitComponent() final;
691  /// @see Component::onConnectComponent
692  void onConnectComponent() final;
693  /// @see Component::onDisconnectComponent
694  void onDisconnectComponent() final;
695  /// @see Component::onExitComponent
696  void onExitComponent() final;
697 
698  virtual void
700  {
701  }
702 
703  virtual void
705  {
706  }
707 
708  virtual void
710  {
711  }
712 
713  virtual void
715  {
716  }
717 
718  // //////////////////////////////////////////////////////////////////////////////////////// //
719  // ////////////////////////////////// ThreadPool functionality///////////////////////////// //
720  // //////////////////////////////////////////////////////////////////////////////////////// //
721  protected:
723 
724  /**
725  * @brief Executes a given task in a separate thread from the Application ThreadPool.
726  * @param taskName Descriptive name of this task to identify it on errors.
727  * @param task std::function object (or lambda) that is to be executed.
728  * @note This task will be joined in onExitComponent of the NJointControllerBase. So make sure it terminates, when the
729  * controller is deactivated or removed!
730  *
731  * @code{.cpp}
732  * runTask("PlotterTask", [&]
733  {
734  CycleUtil c(30);
735  getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted);
736  while (getState() == eManagedIceObjectStarted)
737  {
738  if (isControllerActive())
739  {
740  StringVariantBaseMap errors;
741  for (size_t i = 0; i < sensors.size(); i++)
742  {
743  errors[cfg->jointNames.at(i)] = new Variant(currentError(i));
744  }
745  dbgObs->setDebugChannel("TrajectoryController", errors);
746  }
747  c.waitForCycleDuration();
748  }
749  });
750  * @endcode
751  */
752  template <typename Task>
753  void
754  runTask(const std::string& taskName, Task&& task)
755  {
756  std::unique_lock lock(threadHandlesMutex);
757  ARMARX_CHECK_EXPRESSION(!taskName.empty());
758  ARMARX_CHECK_EXPRESSION(!threadHandles.count(taskName));
759  ARMARX_CHECK_EXPRESSION(getState() < eManagedIceObjectExiting);
760  ARMARX_VERBOSE << "Adding NJointControllerBase task named '" << taskName
761  << "' - current available thread count: "
762  << getThreadPool()->getAvailableTaskCount();
763  auto handlePtr = std::make_shared<ThreadPool::Handle>(getThreadPool()->runTask(task));
764  ARMARX_CHECK_EXPRESSION(handlePtr->isValid())
765  << "Could not add task (" << taskName << " - " << GetTypeString(task)
766  << " ) - available threads: " << getThreadPool()->getAvailableTaskCount();
767  threadHandles[taskName] = handlePtr;
768  }
769 
770  std::map<std::string, std::shared_ptr<ThreadPool::Handle>> threadHandles;
771  std::mutex threadHandlesMutex;
772 
773  // //////////////////////////////////////////////////////////////////////////////////////// //
774  // ///////////////////////////////////// ice interface //////////////////////////////////// //
775  // //////////////////////////////////////////////////////////////////////////////////////// //
776  public:
777  bool
778  isControllerActive(const Ice::Current& = Ice::emptyCurrent) const final override
779  {
780  return isActive;
781  }
782 
783  bool
784  isControllerRequested(const Ice::Current& = Ice::emptyCurrent) const final override
785  {
786  return isRequested;
787  }
788 
789  bool
790  isDeletable(const Ice::Current& = Ice::emptyCurrent) const final override
791  {
792  return deletable;
793  }
794 
795  bool
796  hasControllerError(const Ice::Current& = Ice::emptyCurrent) const final override
797  {
798  return deactivatedBecauseOfError;
799  }
800 
801  std::string getClassName(const Ice::Current& = Ice::emptyCurrent) const override = 0;
802 
803  std::string
804  getInstanceName(const Ice::Current& = Ice::emptyCurrent) const final override
805  {
806  return instanceName_;
807  }
808 
809  NJointControllerDescription
810  getControllerDescription(const Ice::Current& = Ice::emptyCurrent) const final override;
811  NJointControllerStatus
812  getControllerStatus(const Ice::Current& = Ice::emptyCurrent) const final override;
813  NJointControllerDescriptionWithStatus getControllerDescriptionWithStatus(
814  const Ice::Current& = Ice::emptyCurrent) const final override;
815  //RobotUnitInterfacePrx getRobotUnit(const Ice::Current& = Ice::emptyCurrent) const final override;
816 
817  void activateController(const Ice::Current& = Ice::emptyCurrent) final override;
818  void deactivateController(const Ice::Current& = Ice::emptyCurrent) final override;
819  void deleteController(const Ice::Current& = Ice::emptyCurrent) final override;
820  void deactivateAndDeleteController(const Ice::Current& = Ice::emptyCurrent) final override;
821 
823  getFunctionDescriptions(const Ice::Current& = Ice::emptyCurrent) const override
824  {
825  return {};
826  }
827 
828  void
829  callDescribedFunction(const std::string&,
830  const StringVariantBaseMap&,
831  const Ice::Current& = Ice::emptyCurrent) override
832  {
833  }
834 
835  // //////////////////////////////////////////////////////////////////////////////////////// //
836  // ///////////////////////////////////// rt interface ///////////////////////////////////// //
837  // //////////////////////////////////////////////////////////////////////////////////////// //
838  public: ///TODO make protected and use attorneys
839  /**
840  * @brief Returns the virtual robot used by this \ref NJointControllerBase in the \ref rtRun
841  * @return The virtual robot used by this \ref NJointControllerBase in the \ref rtRun
842  * @see useSynchronizedRtRobot
843  * @see rtGetRobotNodes
844  */
847  {
848  return rtRobot;
849  }
850 
851  /**
852  * @brief Returns the nodes of the virtual robot used by this \ref NJointControllerBase in the \ref rtRun
853  * @return The nodes of the virtual robot used by this \ref NJointControllerBase in the \ref rtRun
854  * @see useSynchronizedRtRobot
855  * @see rtGetRobot
856  */
857  const std::vector<VirtualRobot::RobotNodePtr>&
859  {
860  return rtRobotNodes;
861  }
862 
863  /**
864  * @brief Returns whether this \ref NJointControllerBase calculates a \ref ControlTargetBase "ControlTarget"
865  * for the given \ref ControlDevice
866  * @param deviceIndex The \ref ControlDevice's index
867  * @return Whether this \ref NJointControllerBase calculates a \ref ControlTargetBase "ControlTarget"
868  * for the given \ref ControlDevice
869  */
870  bool
871  rtUsesControlDevice(std::size_t deviceIndex) const
872  {
873  return controlDeviceUsedBitmap.at(deviceIndex);
874  }
875 
876  /**
877  * @brief Returns the indices of all \ref ControlDevice's this \ref NJointControllerBase
878  * calculates a \ref ControlTargetBase "ControlTarget" for.
879  * @return The indices of all \ref ControlDevice's this \ref NJointControllerBase
880  * calculates a \ref ControlTargetBase "ControlTarget" for.
881  */
882  const std::vector<std::size_t>&
884  {
885  return controlDeviceUsedIndices;
886  }
887 
888  /**
889  * @brief Sets the error state to true. This will deactivate this controller!
890  */
891  bool
893  {
894  return errorState;
895  }
896 
897  /**
898  * @brief Returns the number of used \ref ControlDevice "ControlDevices"
899  * @return The number of used \ref ControlDevice "ControlDevices"
900  */
901  std::size_t
903  {
904  return controlDeviceUsedIndices.size();
905  }
906 
907  /**
908  * @brief Returns the class name. (the c-string may be used for rt message logging)
909  * @return The class name. (the c-string may be used for rt message logging)
910  */
911  const std::string&
913  {
914  return rtClassName_;
915  }
916 
917  /**
918  * @brief Returns the instance name. (the c-string may be used for rt message logging)
919  * @return The instance name. (the c-string may be used for rt message logging)
920  */
921  const std::string&
923  {
924  return instanceName_;
925  }
926 
927  protected:
928  /**
929  * @brief This function is called before the controller is activated.
930  * You can use it to activate a thread again (DO NOT SPAWN NEW THREADS!) e.g. via a std::atomic_bool.
931  */
932  virtual void
934  {
935  }
936 
937  /**
938  * @brief This function is called after the controller is deactivated.
939  * You can use it to deactivate a thread (DO NOT JOIN THREADS!) e.g. via a std::atomic_bool.
940  */
941  virtual void
943  {
944  }
945 
946  /**
947  * @brief Sets the error state to true. This will deactivate this controller!
948  */
949  void
951  {
952  errorState.store(true);
953  }
954 
955  private:
956  /**
957  * @brief Activates this controller in the \ref RobotUnitModules::ControlThread "ControlThread".
958  *
959  * Calls \ref rtPreActivateController
960  * @see rtDeactivateController
961  * @see rtDeactivateControllerBecauseOfError
962  * @see rtPreActivateController
963  */
964  void rtActivateController();
965  /**
966  * @brief Deactivates this controller in the \ref RobotUnitModules::ControlThread "ControlThread".
967  *
968  * Calls \ref rtPostDeactivateController
969  * @see rtActivateController
970  * @see rtDeactivateControllerBecauseOfError
971  * @see rtPostDeactivateController
972  */
973  void rtDeactivateController();
974  /**
975  * @brief Deactivates this controller in the \ref RobotUnitModules::ControlThread "ControlThread"
976  * and sets the error flag.
977  *
978  * Calls \ref rtPostDeactivateController
979  * This function is called when this \ref NJointControllerBase produces an error
980  * (e.g.: calculates an invalid \ref ControlTargetBase "ControlTarget", throws an exception)
981  * @see rtActivateController
982  * @see rtDeactivateController
983  * @see rtPostDeactivateController
984  */
985  void rtDeactivateControllerBecauseOfError();
986 
987  public:
988  static const NJointControllerBasePtr NullPtr;
989 
991 
992  ~NJointControllerBase() override;
993  //ice interface (must not be called in the rt thread)
994 
995  //c++ interface (local calls) (must be called in the rt thread)
996  // //////////////////////////////////////////////////////////////////////////////////////// //
997  // ///////////////////////////////////// used targets ///////////////////////////////////// //
998  // //////////////////////////////////////////////////////////////////////////////////////// //
999  public:
1000  //used control devices
1001  StringStringDictionary
1003  const Ice::Current& = Ice::emptyCurrent) const final override
1004  {
1005  return controlDeviceControlModeMap;
1006  }
1007 
1008  const std::vector<char>&
1010  {
1011  return controlDeviceUsedBitmap;
1012  }
1013 
1014  const std::vector<std::size_t>&
1016  {
1017  return controlDeviceUsedIndices;
1018  }
1019 
1020  const std::map<std::string, const JointController*>&
1022  {
1023  return controlDeviceUsedJointController;
1024  }
1025 
1026  //check for conflict
1027  std::optional<std::vector<char>>
1028  isNotInConflictWith(const NJointControllerBasePtr& other) const
1029  {
1030  return isNotInConflictWith(other->getControlDeviceUsedBitmap());
1031  }
1032 
1033  std::optional<std::vector<char>> isNotInConflictWith(const std::vector<char>& used) const;
1034 
1035  template <class ItT>
1036  static std::optional<std::vector<char>>
1037  AreNotInConflict(ItT first, ItT last)
1038  {
1039  if (first == last)
1040  {
1041  return std::vector<char>{};
1042  }
1043  std::size_t n = (*first)->getControlDeviceUsedBitmap().size();
1044  std::vector<char> inuse(n, false);
1045  while (first != last)
1046  {
1047  auto r = (*first)->isNotInConflictWith(inuse);
1048  if (!r)
1049  {
1050  return r;
1051  }
1052  inuse = std::move(*r);
1053  ++first;
1054  }
1055  return inuse;
1056  }
1057 
1058  // //////////////////////////////////////////////////////////////////////////////////////// //
1059  // ////////////////////////////////////// publishing ////////////////////////////////////// //
1060  // //////////////////////////////////////////////////////////////////////////////////////// //
1061  protected:
1062  //publish thread hooks
1063  virtual void
1065  {
1066  }
1067 
1068  virtual void
1070  {
1071  }
1072 
1073  virtual void
1075  const DebugDrawerInterfacePrx&,
1077  {
1078  }
1079 
1080  private:
1081  void publish(const SensorAndControl& sac,
1082  const DebugDrawerInterfacePrx& draw,
1083  const DebugObserverInterfacePrx& observer);
1084  void deactivatePublish(const DebugDrawerInterfacePrx& draw,
1085  const DebugObserverInterfacePrx& observer);
1086  // //////////////////////////////////////////////////////////////////////////////////////// //
1087  // ///////////////////////////////////////// data ///////////////////////////////////////// //
1088  // //////////////////////////////////////////////////////////////////////////////////////// //
1089  private:
1090  /// @brief reference to the owning \ref RobotUnit
1091  RobotUnit& robotUnit;
1092  /// @brief Maps names of used \ref ControlDevice "ControlDevices" to the \ref JointController "JointController's" control mode
1093  StringStringDictionary controlDeviceControlModeMap;
1094  /// @brief Maps names of used \ref ControlDevice "ControlDevices" to the used \ref JointController for this \ref ControlDevice
1095  std::map<std::string, const JointController*> controlDeviceUsedJointController;
1096  /// @brief Bitmap of used \ref ControlDevice "ControlDevices" (1 == used, 0 == not used)
1097  std::vector<char> controlDeviceUsedBitmap;
1098  /// @brief Indices of used \ref ControlDevice "ControlDevices"
1099  std::vector<std::size_t> controlDeviceUsedIndices;
1100 
1101  std::string rtClassName_;
1102  std::string instanceName_;
1103 
1104  //this data is filled by the robot unit to provide convenience functions
1105  std::atomic_bool isActive{false};
1106  std::atomic_bool isRequested{false};
1107  std::atomic_bool deactivatedBecauseOfError{false};
1108  std::atomic_bool errorState{false};
1109  bool deletable{false};
1110  bool internal{false};
1111 
1112  std::atomic_bool publishActive{false};
1113 
1114  std::atomic_bool statusReportedActive{false};
1115  std::atomic_bool statusReportedRequested{false};
1116 
1117  VirtualRobot::RobotPtr rtRobot;
1118  std::vector<VirtualRobot::RobotNodePtr> rtRobotNodes;
1119  // //////////////////////////////////////////////////////////////////////////////////////// //
1120  // /////////////////////////////////////// friends //////////////////////////////////////// //
1121  // //////////////////////////////////////////////////////////////////////////////////////// //
1122  private:
1123  /**
1124  * \brief This class allows minimal access to private members of \ref NJointControllerBase in a sane fashion for \ref RobotUnitModule::ControllerManagement.
1125  * \warning !! DO NOT ADD ADDITIONAL FRIENDS IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !!
1126  */
1128  /**
1129  * \brief This class allows minimal access to private members of \ref NJointControllerBase in a sane fashion for \ref RobotUnitModule::ControlThread.
1130  * \warning !! DO NOT ADD ADDITIONAL FRIENDS IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !!
1131  */
1133  /**
1134  * \brief This class allows minimal access to private members of \ref NJointControllerBase in a sane fashion for \ref RobotUnitModule::Publisher.
1135  * \warning !! DO NOT ADD ADDITIONAL FRIENDS IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !!
1136  */
1138  /**
1139  * \brief This is required for the factory
1140  * \warning !! DO NOT ADD ADDITIONAL FRIENDS IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !!
1141  */
1142  template <class>
1144  };
1145 
1147  {
1148  public: ///TODO make protected and use attorneys
1149  virtual void rtRun(const IceUtil::Time& sensorValuesTimestamp,
1150  const IceUtil::Time& timeSinceLastIteration) = 0;
1151 
1152  virtual void
1153  rtSwapBufferAndRun(const IceUtil::Time& sensorValuesTimestamp,
1154  const IceUtil::Time& timeSinceLastIteration)
1155  {
1156  rtRun(sensorValuesTimestamp, timeSinceLastIteration);
1157  }
1158  };
1159 
1161  {
1162  public: ///TODO make protected and use attorneys
1163  virtual void rtRunIterationBegin(const IceUtil::Time& sensorValuesTimestamp,
1164  const IceUtil::Time& timeSinceLastIteration) = 0;
1165  virtual void rtRunIterationEnd(const IceUtil::Time& sensorValuesTimestamp,
1166  const IceUtil::Time& timeSinceLastIteration) = 0;
1167  };
1168 
1170  using NJointControllerPtr = SynchronousNJointControllerPtr;
1171 } // namespace armarx
armarx::NJointControllerBase::useControlTarget
T * useControlTarget(const std::string &deviceName, const std::string &controlMode)
Declares to calculate the ControlTarget for the given ControlDevice in the given ControlMode when rtR...
Definition: NJointControllerBase.h:635
armarx::AsynchronousNJointController::rtRunIterationBegin
virtual void rtRunIterationBegin(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration)=0
TODO make protected and use attorneys.
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
armarx::NJointControllerBase::peekSensorDevice
ConstSensorDevicePtr peekSensorDevice(const std::string &deviceName) const
Get a const ptr to the given SensorDevice.
Definition: NJointController.cpp:275
armarx::NJointControllerBase::rtGetInstanceName
const std::string & rtGetInstanceName() const
Returns the instance name.
Definition: NJointControllerBase.h:922
armarx::NJointControllerBase::~NJointControllerBase
~NJointControllerBase() override
Definition: NJointController.cpp:405
armarx::NJointControllerBase::getInstanceName
std::string getInstanceName(const Ice::Current &=Ice::emptyCurrent) const final override
Definition: NJointControllerBase.h:804
armarx::NJointControllerBase::useSynchronizedRtRobot
const VirtualRobot::RobotPtr & useSynchronizedRtRobot(bool updateCollisionModel=false)
Requests a VirtualRobot for use in rtRun *.
Definition: NJointController.cpp:293
armarx::NJointControllerBase::deactivateController
void deactivateController(const Ice::Current &=Ice::emptyCurrent) final override
Definition: NJointController.cpp:149
armarx::StringVariantBaseMap
std::map< std::string, VariantBasePtr > StringVariantBaseMap
Definition: ManagedIceObject.h:110
armarx::TYPEDEF_PTRS_HANDLE
TYPEDEF_PTRS_HANDLE(NJointCartesianNaturalPositionController)
IceProxy::armarx
Definition: LogSender.h:38
armarx::SensorValueBase
The SensorValueBase class.
Definition: SensorValueBase.h:40
armarx::NJointControllerBase::activateController
void activateController(const Ice::Current &=Ice::emptyCurrent) final override
Definition: NJointController.cpp:143
armarx::NJointControllerBase::onInitComponent
void onInitComponent() final
Definition: NJointController.cpp:305
armarx::ControlTargetBase
Brief description of class JointControlTargetBase.
Definition: ControlTargetBase.h:47
armarx::NJointControllerBase::threadHandles
std::map< std::string, std::shared_ptr< ThreadPool::Handle > > threadHandles
Definition: NJointControllerBase.h:770
armarx::WidgetDescription::StringWidgetDictionary
::std::map<::std::string, ::armarx::WidgetDescription::WidgetPtr > StringWidgetDictionary
Definition: NJointControllerBase.h:70
armarx::SynchronousNJointController
Definition: NJointControllerBase.h:1146
armarx::NJointControllerBase::useControlTarget
ControlTargetBase * useControlTarget(const std::string &deviceName, const std::string &controlMode)
Declares to calculate the ControlTarget for the given ControlDevice in the given ControlMode when rtR...
Definition: NJointController.cpp:410
armarx::NJointControllerBase::getControlDevicesUsedJointController
const std::map< std::string, const JointController * > & getControlDevicesUsedJointController()
Definition: NJointControllerBase.h:1021
armarx::NJointControllerBase::rtGetRobotNodes
const std::vector< VirtualRobot::RobotNodePtr > & rtGetRobotNodes()
Returns the nodes of the virtual robot used by this NJointControllerBase in the rtRun.
Definition: NJointControllerBase.h:858
armarx::NJointControllerBase::getClassName
std::string getClassName(const Ice::Current &=Ice::emptyCurrent) const override=0
armarx::NJointControllerBase::onDisconnectNJointController
virtual void onDisconnectNJointController()
Definition: NJointControllerBase.h:709
armarx::NJointControllerBase::onDisconnectComponent
void onDisconnectComponent() final
Definition: NJointController.cpp:319
armarx::NJointControllerBase::threadHandlesMutex
std::mutex threadHandlesMutex
Definition: NJointControllerBase.h:771
armarx::detail::NJointControllerRegistryEntryHelper
Definition: NJointControllerBase.h:61
armarx::ManagedIceObject::getState
int getState() const
Retrieve current state of the ManagedIceObject.
Definition: ManagedIceObject.cpp:769
armarx::DebugObserverInterfacePrx
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface > DebugObserverInterfacePrx
Definition: JointController.h:44
armarx::NJointControllerBase::getControlDeviceUsedControlModeMap
StringStringDictionary getControlDeviceUsedControlModeMap(const Ice::Current &=Ice::emptyCurrent) const final override
Definition: NJointControllerBase.h:1002
armarx::NJointControllerBase::onExitComponent
void onExitComponent() final
Definition: NJointController.cpp:326
detail
Definition: OpenCVUtil.cpp:128
armarx::JointController
The JointController class represents one joint in one control mode.
Definition: JointController.h:51
armarx::NJointControllerBase::getControllerDescription
NJointControllerDescription getControllerDescription(const Ice::Current &=Ice::emptyCurrent) const final override
Definition: NJointController.cpp:79
armarx::RobotUnitModule::NJointControllerAttorneyForControllerManagement
This class allows minimal access to private members of NJointControllerBase in a sane fashion for Con...
Definition: RobotUnitModuleControllerManagement.cpp:60
armarx::NJointControllerBase::onPublishDeactivation
virtual void onPublishDeactivation(const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &)
Definition: NJointControllerBase.h:1069
armarx::NJointControllerBase::onConnectNJointController
virtual void onConnectNJointController()
Definition: NJointControllerBase.h:704
armarx::NJointControllerBase::ConfigPtrT
NJointControllerConfigPtr ConfigPtrT
Definition: NJointControllerBase.h:587
armarx::NJointControllerBase::callDescribedFunction
void callDescribedFunction(const std::string &, const StringVariantBaseMap &, const Ice::Current &=Ice::emptyCurrent) override
Definition: NJointControllerBase.h:829
armarx::NJointControllerBase::GenerateConfigFromVariantsFunctionSignature
ConfigPrtType(*)(const StringVariantBaseMap &) GenerateConfigFromVariantsFunctionSignature
Definition: NJointControllerBase.h:594
armarx::NJointControllerBase::isNotInConflictWith
std::optional< std::vector< char > > isNotInConflictWith(const NJointControllerBasePtr &other) const
Definition: NJointControllerBase.h:1028
armarx::NJointControllerBase::rtGetNumberOfUsedControlDevices
std::size_t rtGetNumberOfUsedControlDevices() const
Returns the number of used ControlDevices.
Definition: NJointControllerBase.h:902
armarx::NJointControllerBase::rtGetClassName
const std::string & rtGetClassName() const
Returns the class name.
Definition: NJointControllerBase.h:912
armarx::NJointControllerBase::NullPtr
static const NJointControllerBasePtr NullPtr
Definition: NJointControllerBase.h:988
armarx::SynchronousNJointController::rtRun
virtual void rtRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration)=0
TODO make protected and use attorneys.
armarx::ThreadPoolPtr
std::shared_ptr< ThreadPool > ThreadPoolPtr
Definition: Application.h:76
armarx::NJointControllerBase::onPublishActivation
virtual void onPublishActivation(const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &)
Definition: NJointControllerBase.h:1064
armarx::NJointControllerBase::getControllerDescriptionWithStatus
NJointControllerDescriptionWithStatus getControllerDescriptionWithStatus(const Ice::Current &=Ice::emptyCurrent) const final override
Definition: NJointController.cpp:129
armarx::NJointControllerBase::onConnectComponent
void onConnectComponent() final
Definition: NJointController.cpp:312
armarx::NJointControllerBase::rtGetRobot
const VirtualRobot::RobotPtr & rtGetRobot()
TODO make protected and use attorneys.
Definition: NJointControllerBase.h:846
armarx::detail::ControlThreadOutputBufferEntry
Definition: ControlThreadOutputBuffer.h:182
armarx::RobotUnitModule::NJointControllerAttorneyForControlThread
This class allows minimal access to private members of NJointControllerBase in a sane fashion for Con...
Definition: RobotUnitModuleControlThread.cpp:54
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::RemoteGui::Client::Widget
Definition: Widgets.h:21
armarx::NJointControllerBase::deactivateAndDeleteController
void deactivateAndDeleteController(const Ice::Current &=Ice::emptyCurrent) final override
Definition: NJointController.cpp:161
armarx::SynchronousNJointController::rtSwapBufferAndRun
virtual void rtSwapBufferAndRun(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration)
Definition: NJointControllerBase.h:1153
armarx::NJointControllerBase::rtPostDeactivateController
virtual void rtPostDeactivateController()
This function is called after the controller is deactivated.
Definition: NJointControllerBase.h:942
ManagedIceObject.h
ThreadPool.h
armarx::NJointControllerBase::rtUsesControlDevice
bool rtUsesControlDevice(std::size_t deviceIndex) const
Returns whether this NJointControllerBase calculates a ControlTarget for the given ControlDevice.
Definition: NJointControllerBase.h:871
armarx::RobotUnitModule::NJointControllerAttorneyForPublisher
This class allows minimal access to private members of NJointControllerBase in a sane fashion for Pub...
Definition: RobotUnitModulePublisher.cpp:46
armarx::NJointControllerBase::isControllerActive
bool isControllerActive(const Ice::Current &=Ice::emptyCurrent) const final override
Definition: NJointControllerBase.h:778
armarx::NJointControllerBase::useSensorValue
const T * useSensorValue(const std::string &deviceName) const
Get a const ptr to the given SensorDevice's SensorValue.
Definition: NJointControllerBase.h:659
armarx::NJointControllerBase::isDeletable
bool isDeletable(const Ice::Current &=Ice::emptyCurrent) const final override
Definition: NJointControllerBase.h:790
armarx::NJointControllerBase::getThreadPool
ThreadPoolPtr getThreadPool() const
Definition: NJointController.cpp:376
armarx::NJointControllerBase::runTask
void runTask(const std::string &taskName, Task &&task)
Executes a given task in a separate thread from the Application ThreadPool.
Definition: NJointControllerBase.h:754
armarx::NJointControllerBase::getFunctionDescriptions
WidgetDescription::StringWidgetDictionary getFunctionDescriptions(const Ice::Current &=Ice::emptyCurrent) const override
Definition: NJointControllerBase.h:823
armarx::NJointControllerBase::getControllerStatus
NJointControllerStatus getControllerStatus(const Ice::Current &=Ice::emptyCurrent) const final override
Definition: NJointController.cpp:114
armarx::NJointControllerBase::onPublish
virtual void onPublish(const SensorAndControl &, const DebugDrawerInterfacePrx &, const DebugObserverInterfacePrx &)
Definition: NJointControllerBase.h:1074
armarx::AsynchronousNJointController
Definition: NJointControllerBase.h:1160
armarx::NJointControllerBase::rtGetErrorState
bool rtGetErrorState() const
Sets the error state to true.
Definition: NJointControllerBase.h:892
armarx::NJointControllerBase::onExitNJointController
virtual void onExitNJointController()
Definition: NJointControllerBase.h:714
armarx::NJointControllerBase::NJointControllerBase
NJointControllerBase()
Definition: NJointController.cpp:398
armarx::NJointControllerBase::peekControlDevice
ConstControlDevicePtr peekControlDevice(const std::string &deviceName) const
Get a const ptr to the given ControlDevice.
Definition: NJointController.cpp:284
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::NJointControllerBase::deleteController
void deleteController(const Ice::Current &=Ice::emptyCurrent) final override
Definition: NJointController.cpp:155
armarx::GetTypeString
std::string GetTypeString(const std::type_info &tinf, bool withoutNamespaceSpecifier=false)
Definition: GetTypeString.h:38
armarx::AsynchronousNJointController::rtRunIterationEnd
virtual void rtRunIterationEnd(const IceUtil::Time &sensorValuesTimestamp, const IceUtil::Time &timeSinceLastIteration)=0
armarx::WidgetDescription::WidgetPtr
::IceInternal::Handle<::armarx::WidgetDescription::Widget > WidgetPtr
Definition: NJointControllerBase.h:67
ExpressionException.h
armarx::NJointControllerBase::GenerateConfigDescriptionFunctionSignature
WidgetDescription::WidgetPtr(*)(const VirtualRobot::RobotPtr &, const std::map< std::string, ConstControlDevicePtr > &controlDevices, const std::map< std::string, ConstSensorDevicePtr > &sensorDevices) GenerateConfigDescriptionFunctionSignature
Definition: NJointControllerBase.h:591
armarx::ManagedIceObject
The ManagedIceObject is the base class for all ArmarX objects.
Definition: ManagedIceObject.h:162
armarx::NJointControllerBase::rtPreActivateController
virtual void rtPreActivateController()
This function is called before the controller is activated.
Definition: NJointControllerBase.h:933
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::NJointControllerPtr
SynchronousNJointControllerPtr NJointControllerPtr
Definition: NJointControllerBase.h:1170
armarx::NJointControllerBase
A high level controller writing its results into ControlTargets.
Definition: NJointControllerBase.h:579
armarx::RobotUnit
The RobotUnit class manages a robot and its controllers.
Definition: RobotUnit.h:180
IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface >
armarx::NJointControllerBase::rtSetErrorState
void rtSetErrorState()
Sets the error state to true.
Definition: NJointControllerBase.h:950
armarx::NJointControllerBase::rtGetControlDeviceUsedIndices
const std::vector< std::size_t > & rtGetControlDeviceUsedIndices() const
Returns the indices of all ControlDevice's this NJointControllerBase calculates a ControlTarget for.
Definition: NJointControllerBase.h:883
armarx::NJointControllerBase::onInitNJointController
virtual void onInitNJointController()
Definition: NJointControllerBase.h:699
armarx::ConstSensorDevicePtr
std::shared_ptr< const class SensorDevice > ConstSensorDevicePtr
Definition: NJointControllerBase.h:78
armarx::RobotUnitInterfacePrx
::IceInternal::ProxyHandle<::IceProxy::armarx::RobotUnitInterface > RobotUnitInterfacePrx
Definition: NJointControllerBase.h:85
armarx::NJointControllerBase::hasControllerError
bool hasControllerError(const Ice::Current &=Ice::emptyCurrent) const final override
Definition: NJointControllerBase.h:796
T
float T
Definition: UnscentedKalmanFilterTest.cpp:38
armarx::DebugDrawerInterfacePrx
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugDrawerInterface > DebugDrawerInterfacePrx
Definition: JointController.h:40
armarx::NJointControllerBase::AreNotInConflict
static std::optional< std::vector< char > > AreNotInConflict(ItT first, ItT last)
Definition: NJointControllerBase.h:1037
armarx::NJointControllerBase::getControlDeviceUsedIndices
const std::vector< std::size_t > & getControlDeviceUsedIndices() const
Definition: NJointControllerBase.h:1015
armarx::ConstControlDevicePtr
std::shared_ptr< const class ControlDevice > ConstControlDevicePtr
Definition: NJointControllerBase.h:77
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::NJointControllerBase::useSensorValue
const SensorValueBase * useSensorValue(const std::string &sensorDeviceName) const
Get a const ptr to the given SensorDevice's SensorValue.
Definition: NJointController.cpp:383
VirtualRobot::RobotPtr
std::shared_ptr< class Robot > RobotPtr
Definition: Bus.h:19
armarx::NJointControllerBase::getDefaultName
std::string getDefaultName() const override
Definition: NJointControllerBase.h:684
armarx::NJointControllerBase::isControllerRequested
bool isControllerRequested(const Ice::Current &=Ice::emptyCurrent) const final override
Definition: NJointControllerBase.h:784
armarx::NJointControllerBase::getControlDeviceUsedBitmap
const std::vector< char > & getControlDeviceUsedBitmap() const
Definition: NJointControllerBase.h:1009