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