diff --git a/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt b/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt
index c33e816f5fc871710c8c45c44742da32a55a14c6..bcbf667a05a4bf246cc074c2f253ed2f08f56810 100755
--- a/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt
+++ b/source/RobotAPI/components/units/RobotUnit/CMakeLists.txt
@@ -111,7 +111,9 @@ set(LIB_HEADERS
     JointControllers/JointController.h
 
     NJointControllers/NJointController.h
-    NJointControllers/NJointController.ipp
+    NJointControllers/NJointControllerBase.h
+    NJointControllers/NJointControllerRegistry.h
+    NJointControllers/NJointControllerWithTripleBuffer.h
     NJointControllers/NJointTrajectoryController.h
     NJointControllers/NJointKinematicUnitPassThroughController.h
     NJointControllers/NJointHolonomicPlatformUnitVelocityPassThroughController.h
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianNaturalPositionController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianNaturalPositionController.cpp
index 28bc1e4819946d6734110fa3831e33f4bc1009b0..fd692bfe221cace409b6999790ac094c1f016c64 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianNaturalPositionController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianNaturalPositionController.cpp
@@ -4,6 +4,8 @@
 #include <RobotAPI/components/units/RobotUnit/ControlTargets/ControlTarget1DoFActuator.h>
 #include <RobotAPI/components/units/RobotUnit/SensorValues/SensorValue1DoFActuator.h>
 #include <RobotAPI/components/units/RobotUnit/SensorValues/SensorValueForceTorque.h>
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+#include <RobotAPI/components/units/RobotUnit/util/ControlThreadOutputBuffer.h>
 
 #include <VirtualRobot/math/Helpers.h>
 
@@ -59,7 +61,7 @@ namespace armarx
     }
 
     NJointCartesianNaturalPositionController::NJointCartesianNaturalPositionController(
-        RobotUnitPtr,
+        RobotUnit*,
         const NJointCartesianNaturalPositionControllerConfigPtr& config,
         const VirtualRobot::RobotPtr&)
     {
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianNaturalPositionController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianNaturalPositionController.h
index 2a59d6d7dd6481df81fe6299e7ab2d9d598f9e7c..41276169749fe1156623f14bf4a8589c500b2266 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianNaturalPositionController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianNaturalPositionController.h
@@ -1,13 +1,13 @@
 #pragma once
 
-#include <VirtualRobot/Robot.h>
-#include <VirtualRobot/RobotNodeSet.h>
-
-#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.h>
-
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerBase.h>
 #include <RobotAPI/libraries/core/CartesianNaturalPositionController.h>
 #include <RobotAPI/interface/units/RobotUnit/NJointCartesianNaturalPositionController.h>
 
+#include <ArmarXCore/util/CPPUtility/TripleBuffer.h>
+
+#include <VirtualRobot/VirtualRobot.h>
+
 namespace armarx
 {
 
@@ -24,7 +24,7 @@ namespace armarx
     public:
         using ConfigPtrT = NJointCartesianNaturalPositionControllerConfigPtr;
         NJointCartesianNaturalPositionController(
-            RobotUnitPtr robotUnit,
+            RobotUnit* robotUnit,
             const NJointCartesianNaturalPositionControllerConfigPtr& config,
             const VirtualRobot::RobotPtr&);
 
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianTorqueController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianTorqueController.cpp
index cb488380e67ad03f0245ea270061870528ceb086..78f0447f752a1cfef771d9ed7ff8ad42ff98c1be 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianTorqueController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianTorqueController.cpp
@@ -22,9 +22,13 @@
  *             GNU General Public License
  */
 #include "NJointCartesianTorqueController.h"
-#include <VirtualRobot/RobotNodeSet.h>
 #include "../RobotUnit.h"
 
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+
+#include <VirtualRobot/RobotNodeSet.h>
+
+
 #define DEFAULT_TCP_STRING "default TCP"
 
 namespace armarx
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianTorqueController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianTorqueController.h
index 2615b64cd005a228a351200c9b1d4e7e43749a41..0f5dcaef0ac6bce390cdd5160040edc9d943d710 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianTorqueController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianTorqueController.h
@@ -24,7 +24,7 @@
 #pragma once
 
 
-#include "NJointController.h"
+#include "NJointControllerWithTripleBuffer.h"
 #include <VirtualRobot/Robot.h>
 #include "../RobotUnit.h"
 #include "../ControlTargets/ControlTarget1DoFActuator.h"
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityController.cpp
index eede99223f70e52f7d1a8ab1ed4e9b101901caa1..88ac3ec398a3ad691f21890369f07aa9448e4d14 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityController.cpp
@@ -22,9 +22,12 @@
  *             GNU General Public License
  */
 #include "NJointCartesianVelocityController.h"
-#include <VirtualRobot/RobotNodeSet.h>
 #include "../RobotUnit.h"
 
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+
+#include <VirtualRobot/RobotNodeSet.h>
+
 #define DEFAULT_TCP_STRING "default TCP"
 
 namespace armarx
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityController.h
index 7afd5493e7dcf8f0d11cb898e29c22d09293e490..470be6138ac240deb5182981b3b595fea08d1b9f 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityController.h
@@ -24,7 +24,7 @@
 #pragma once
 
 
-#include "NJointController.h"
+#include "NJointControllerWithTripleBuffer.h"
 #include <VirtualRobot/Robot.h>
 #include "../RobotUnit.h"
 #include "../ControlTargets/ControlTarget1DoFActuator.h"
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityControllerWithRamp.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityControllerWithRamp.cpp
index 24cafe472b7c53b0548c8221f03206b13534f597..321bea4a97384d1d8aa83c34051b8a92bb68e8ba 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityControllerWithRamp.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityControllerWithRamp.cpp
@@ -22,9 +22,13 @@
  *             GNU General Public License
  */
 #include "NJointCartesianVelocityControllerWithRamp.h"
-#include <VirtualRobot/RobotNodeSet.h>
+
 #include "../RobotUnit.h"
 
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+
+#include <VirtualRobot/RobotNodeSet.h>
+
 #define DEFAULT_TCP_STRING "default TCP"
 
 namespace armarx
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityControllerWithRamp.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityControllerWithRamp.h
index 7b9994929a379228956f72a0f6de7f8efbdcf474..d85cad7d1faa6ad1a67037d48fe7cbaed41ab8de 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityControllerWithRamp.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianVelocityControllerWithRamp.h
@@ -24,7 +24,7 @@
 #pragma once
 
 
-#include "NJointController.h"
+#include "NJointControllerWithTripleBuffer.h"
 #include <VirtualRobot/Robot.h>
 #include "../RobotUnit.h"
 #include "../ControlTargets/ControlTarget1DoFActuator.h"
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.cpp
index bd02cd045bb37da2a51156a60fec1b35b61a2dbf..5e80b3642507feb335287f2437b238f186cd5e13 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.cpp
@@ -4,6 +4,9 @@
 #include <RobotAPI/components/units/RobotUnit/ControlTargets/ControlTarget1DoFActuator.h>
 #include <RobotAPI/components/units/RobotUnit/SensorValues/SensorValue1DoFActuator.h>
 #include <RobotAPI/components/units/RobotUnit/SensorValues/SensorValueForceTorque.h>
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+#include <RobotAPI/components/units/RobotUnit/Devices/SensorDevice.h>
+#include <RobotAPI/components/units/RobotUnit/util/ControlThreadOutputBuffer.h>
 
 #include "NJointCartesianWaypointController.h"
 
@@ -43,7 +46,7 @@ namespace armarx
     }
 
     NJointCartesianWaypointController::NJointCartesianWaypointController(
-        RobotUnitPtr,
+        RobotUnit*,
         const NJointCartesianWaypointControllerConfigPtr& config,
         const VirtualRobot::RobotPtr&)
     {
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.h
index 22440abdc4123b86e5ec28e07bfb396b6102dfe2..affada4d1467a0c313a1d32b708469a5c703ca50 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointCartesianWaypointController.h
@@ -1,13 +1,14 @@
 #pragma once
 
-#include <VirtualRobot/Robot.h>
-#include <VirtualRobot/RobotNodeSet.h>
-
-#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.h>
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerBase.h>
 
 #include <RobotAPI/libraries/core/CartesianWaypointController.h>
 #include <RobotAPI/interface/units/RobotUnit/NJointCartesianWaypointController.h>
 
+#include <ArmarXCore/util/CPPUtility/TripleBuffer.h>
+
+#include <VirtualRobot/VirtualRobot.h>
+
 namespace armarx
 {
 
@@ -24,7 +25,7 @@ namespace armarx
     public:
         using ConfigPtrT = NJointCartesianWaypointControllerConfigPtr;
         NJointCartesianWaypointController(
-            RobotUnitPtr robotUnit,
+            RobotUnit* robotUnit,
             const NJointCartesianWaypointControllerConfigPtr& config,
             const VirtualRobot::RobotPtr&);
 
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.cpp
index 4a603b481ecee7da16744165688a26ce346f99fb..5d34536c610128cb23086e8c782249fe9a41e706 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.cpp
@@ -20,7 +20,8 @@
  *             GNU General Public License
  */
 
-#include "NJointController.h"
+#include "NJointControllerBase.h"
+#include "NJointControllerRegistry.h"
 
 #include <ArmarXCore/core/util/algorithm.h>
 #include <ArmarXCore/core/application/Application.h>
@@ -29,6 +30,14 @@
 
 #include <atomic>
 
+namespace armarx
+{
+    RobotUnit* getRobotUnit(RobotUnitModule::ControllerManagement* cmngr)
+    {
+        return cmngr->_modulePtr<RobotUnit>();
+    }
+}
+
 namespace armarx::RobotUnitModule
 {
 
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.h
index 057e069963abd69c62f7da0a54c86c7628b34654..f00b35bdbcabc38ece77e4e3514ad62a640d80c7 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.h
@@ -22,943 +22,6 @@
 
 #pragma once
 
-#include <map>
-#include <atomic>
-#include <mutex>
-#include <functional>
-#include <unordered_set>
-
-#include <ArmarXCore/core/Component.h>
-#include <ArmarXCore/core/util/Registrar.h>
-#include <ArmarXCore/core/util/TripleBuffer.h>
-#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
-#include <ArmarXCore/interface/core/ManagedIceObjectDefinitions.h>
-#include <ArmarXCore/core/services/tasks/ThreadPool.h>
-
-#include <ArmarXGui/interface/WidgetDescription.h>
-
-#include <RobotAPI/interface/units/RobotUnit/NJointController.h>
-#include <RobotAPI/interface/visualization/DebugDrawerInterface.h>
-#include <RobotAPI/interface/units/RobotUnit/RobotUnitInterface.h>
-
-#include "../ControlTargets/ControlTargetBase.h"
-
-//units
-#include "../Devices/ControlDevice.h"
-#include "../Devices/SensorDevice.h"
-
-#include "../util.h"
-#include "../util/JointAndNJointControllers.h"
-#include "../util/ControlThreadOutputBuffer.h"
-
-#include <VirtualRobot/VirtualRobot.h>
-#include <optional>
-
-namespace armarx::RobotUnitModule
-{
-    class NJointControllerAttorneyForPublisher;
-    class NJointControllerAttorneyForControlThread;
-    class NJointControllerAttorneyForControllerManagement;
-}
-
-namespace armarx::detail
-{
-    template<class> class NJointControllerRegistryEntryHelper;
-}
-
-namespace armarx
-{
-    using ThreadPoolPtr = std::shared_ptr<class ThreadPool>;
-
-    TYPEDEF_PTRS_HANDLE(NJointControllerBase);
-    TYPEDEF_PTRS_HANDLE(SynchronousNJointController);
-    TYPEDEF_PTRS_HANDLE(AsynchronousNJointController);
-
-    TYPEDEF_PTRS_HANDLE(RobotUnit);
-
-    /**
-     * @defgroup Library-RobotUnit-NJointControllers NJointControllers
-     * @ingroup Library-RobotUnit
-     */
-
-    /**
-    * @ingroup Library-RobotUnit-NJointControllers
-    * @brief A high level controller writing its results into \ref ControlTargetBase "ControlTargets".
-    *
-    * This is the abstract base class for all NJointControllers.
-    * It implements basic management routines required by the RobotUnit and some basic ice calls.
-    * \ref NJointControllerBase "NJointControllers" are instantiated and managed by the \ref RobotUnit.
-    *
-    * A \ref NJointControllerBase calculates \ref ControlTargetBase "ControlTargets" for a set of
-    * \ref ControlDevice "ControlDevices" in a specific ControlMode.
-    * This ControlMode is defined for each \ref ControlDevice during construction.
-    *
-    * \section nj-state Requested and Active
-    * A \ref NJointControllerBase can is requested / not requested and active / inactive.
-    * All four combinations are possible.
-    *
-    * \subsection nj-state-req Requested / Not Requested
-    * If the user wants this \ref NJointControllerBase to be executed it is in a requested state (see \ref isControllerRequested).
-    * Otherwise the controler is not requested.
-    *
-    * Calling \ref activateController sets the state to requested.
-    * Calling \ref deactivateController sets the state to not requested.
-    * If the \ref NJointControllerBase causes an error or a different \ref NJointControllerBase using one or more of the same
-    * \ref ControlDevice's is requested, this \ref NJointControllerBase is deactivated.
-    *
-    *
-    * \subsection nj-state-act Active / Inactive
-    * Is the \ref NJointControllerBase executed by the \ref RobotUnitModules::ControlThread "ControlThread" it is active
-    * (see \ref isControllerActive).
-    *
-    * To be executed by the \ref RobotUnitModules::ControlThread "ControlThread", the \ref NJointControllerBase has to be
-    * requested at some point in the past.
-    *
-    * If a controller is active, it has to write a valid \ref ControlTargetBase "ControlTarget"
-    * for each of its \ref ControlDevice "ControlDevicea" (if it fails, it will be deactivated).
-    *
-    * \section Constructor
-    * In the Constructor, a \ref NJointControllerBase has to declare all \ref ControlDevice "ControlDevices" it uses.
-    *
-    * The constructor takes a pointer to a configuration structure of the type \ref NJointControllerBase::ConfigPtrT.
-    * If an implementation requires a special configuration structure (e.g.: SomeOtherCfg), it has to override this type by calling adding
-    * \code{.cpp}
-    * using ConfigPtrT = SomeOtherCfgPtr;
-    * \endcode
-    * to it's clas definition.
-    * The type SomeOtherCfg has to derive \ref NJointControllerConfigPtr.
-    *
-    * There is a way to generate a small gui widget for controller construction (see this \ref nj-ctor-gui "section").
-    *
-    * \subsection nj-ctor-req-ctrl Using ControlTargets
-    * A \ref NJointControllerBase can use \ref peekControlDevice to examine a \ref ControlDevice before using it
-    * (e.g.: checking the supported \ref ControlTargetBase "ControlTargets").
-    *
-    * If a \ref ControlDevice should be used by this \ref NJointControllerBase, it has to call \ref useControlDevice.
-    * This sets the ControlMode for the \ref ControlDevice and returns a pointer to the \ref ControlTargetBase "ControlTarget".
-    * This pointer has to be used to send commands in each iteration of \ref rtRun.
-    * The ControlMode can't be changed afterwards (A new \ref NJointControllerBase has to be created).
-    *
-    *
-    * \subsection nj-ctor-req-sens Using SensorValues
-    * A \ref NJointControllerBase can use \ref peekSensorDevice to examine a \ref SensorDevice before using it.
-    *
-    * If a \ref SensorDevice should be used by this \ref NJointControllerBase, it has to call \ref useSensorDevice.
-    * This returns a pointer to the \ref SensorValueBase "SensorValue".
-    *
-    * \subsection nj-ctor-rob A synchronized Virtualrobot
-    * If the controller needs a simox robot in \ref rtRun, it should call \ref useSynchronizedRtRobot.
-    * This will provide a simoxRobot via \ref rtGetRobot.
-    * This robot is synchronized with the real robots state before calling \ref rtRun
-    *
-    * \section nj-parts Rt and non Rt
-    * Each \ref NJointControllerBase has two parts:
-    * \li The RT controll loop
-    * \li The NonRT ice communication
-    *
-    * \subsection rtcontrollloop The Rt controll loop (\ref rtRun)
-    * \warning This part has to satisfy realtime conditions!
-    * All realtime functions of \ref NJointControllerBase have the 'rt' prefix.
-    *
-    * Here the \ref NJointControllerBase has access to the robot's current state
-    * and has to write results into \ref ControlTargetBase "ControlTargets".
-    *
-    * It must not:
-    * \li call any blocking operation
-    * \li allocate ram on the heap (since this is a blocking operation)
-    * \li resize any datastructure (e.g. vector::resize) (this sometimes allocates ram on the heap)
-    * \li insert new datafields into datastructures (e.g. vector::push_back) (this sometimes allocates ram on the heap)
-    * \li write to any stream (e.g. ARMARX_VERBOSE, std::cout, print, filestreams) (this sometimes blocks/allocates ram on the heap)
-    * \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)
-    * \li do any expensive calculations (e.g. calculate IK, run some solver, invert big matrices)
-    *
-    * \subsection nonrtpart The NonRT ice communication
-    * This part consits of any ice communication.
-    * Here the \ref NJointControllerBase can get new controll parameters or targets from other components.
-    *
-    * \section rtnrtcomm Communication between RT and NonRT
-    * All communication between RT and NonRT has to be lockfree.
-    * The \ref NJointControllerBase has to use constructs like atomics or
-    * \ref TripleBuffer "TripleBuffers" (See \ref armarx::NJointControllerWithTripleBuffer).
-    *
-    * \image html NJointControllerGeneralDataFlow.svg "General Dataflow in a NJointControllerBase"
-    *
-    * \image html NJointControllerAtomicDataFlow.svg "Dataflow in a NJointControllerBase using atomics for communication between RT and NonRT"
-    *
-    * \image html NJointControllerTripleBufferDataFlow.svg "Dataflow in a NJointControllerBase using a triple buffer for communication between RT and NonRT"
-    *
-    *
-    * \image html NJointControllerDataFlow_Graph.svg "Dataflow in a NJointControllerBase as a Graph of the two participating domains"
-    * The above image shows the two participating domains: one RT thread and multiple ICE threads.
-    * If data has to flow along an arrow, you need some construct for non blocking message passing.
-    *
-    * \warning If you use \ref TrippleBuffer "TrippleBuffers" or \ref WriteBufferedTrippleBuffer "WriteBufferedTrippleBuffers" you need a separate one for each arrow.
-    *
-    * \section expensivework How to do expensive calculations
-    * You have to execute expensive calculations in a different worker thread.
-    * This thread could calculate target values at its own speed (e.g. 100 Hz).
-    *
-    * While rtRun runs at a higher frequency (e.g. 1000 Hz) and:
-    * \li reads target values
-    * \li optionally passes the target values to a PID controller
-    * \li writes them to the targets
-    * \li sends the sensor values to the worker thread.
-    *
-    * If you do some additional calculation in rtRun, you maybe need to pass config parameters from NonRT to RT using a nonblocking method.
-    *
-    * \image html NJointControllerWorkerThreadDataFlow.svg "Dataflow in a NJointControllerBase using a worker thread"
-    *
-    * \image html NJointControllerWorkerThreadDataFlow_Graph.svg "Dataflow in a NJointControllerBase using a worker thread as a Graph of the three participating domains"
-    * The above image shows the three participating domains: one RT thread, one worker trhead and multiple ICE threads.
-    * If data has to flow along an arrow, you need some construct for non blocking message passing.
-    *
-    * \warning If you use \ref TrippleBuffer "TrippleBuffers" or \ref WriteBufferedTrippleBuffer "WriteBufferedTrippleBuffers" you need a separate one for each arrow.
-    *
-    * \section nj-ctor-gui Providing a gui for controller construction.
-    * By implementing these functions:
-    * \code{.cpp}
-     static WidgetDescription::WidgetPtr GenerateConfigDescription
-     (
-        const VirtualRobot::RobotPtr& robot,
-        const std::map<std::string, ConstControlDevicePtr>& controlDevices,
-        const std::map<std::string, ConstSensorDevicePtr>& sensorDevices
-     ); //describes how the widget is supposed to look
-     static ConfigPtrT GenerateConfigFromVariants(const StringVariantBaseMap&); // turns the resulting variants into a config
-    * \endcode
-    *
-    * The \ref RobotUnitGui will provide a widget to configure and construct a \ref NJointControllerBase of this type.
-    *
-    * \section Examples
-    *
-    * More examples can be found in the Tutorials Package
-    *
-    * \subsection nj-example-1 A simple pass Position controller
-    * \note The code can be found in the Tutorial package
-    *
-    * \subsection nj-example-1-h Header
-    * Include headers
-    * \code{.cpp}
-        #include <RobotAPI/components/units/RobotUnit/RobotUnit.h>
-        #include <RobotAPI/components/units/RobotUnit/ControlTargets/ControlTarget1DoFActuator.h>
-        #include <RobotAPI/components/units/RobotUnit/SensorValues/SensorValue1DoFActuator.h>
-    * \endcode
-    *
-    * Open the namespace
-    * \code{.cpp}
-        namespace armarx
-        {
-    * \endcode
-    *
-    * Typedef some pointers
-    * \code{.cpp}
-            TYPEDEF_PTRS_HANDLE(NJointPositionPassThroughController);
-            TYPEDEF_PTRS_HANDLE(NJointPositionPassThroughControllerConfig);
-    * \endcode
-    *
-    * The config has to inherit \ref NJointControllerConfig and consists only of the joint name
-    * \code{.cpp}
-            class NJointPositionPassThroughControllerConfig : virtual public NJointControllerConfig
-            {
-            public:
-                NJointPositionPassThroughControllerConfig(const std::string& name): deviceName {name} {}
-                std::string deviceName;
-            };
-    * \endcode
-    *
-    * The controller class has to inherit \ref NJointControllerBase
-    * \code{.cpp}
-            class NJointPositionPassThroughController: public NJointControllerBase
-            {
-            public:
-    * \endcode
-    *
-    * The \ref NJointControllerBase provides a config widget for the \ref RobotUnitGuiPlugin
-    * \code{.cpp}
-                static WidgetDescription::WidgetPtr GenerateConfigDescription
-                (
-                    const VirtualRobot::RobotPtr&,
-                    const std::map<std::string, ConstControlDevicePtr>& controlDevices,
-                    const std::map<std::string, ConstSensorDevicePtr>& sensorDevices
-                );
-                static NJointControllerConfigPtr GenerateConfigFromVariants(const StringVariantBaseMap& values);
-    * \endcode
-    *
-    * The ctor receives a pointer to the \ref RobotUnit, a pointer to the config and a pointer to a VirtualRobot model.
-    * \code{.cpp}
-                NJointPositionPassThroughController(
-                    const RobotUnitPtr& prov,
-                    NJointControllerConfigPtr config,
-                    const VirtualRobot::RobotPtr& r
-                );
-    * \endcode
-    *
-    * The function to provide the class name.
-    * \code{.cpp}
-                std::string getClassName(const Ice::Current&) const override;
-    * \endcode
-    *
-    * This controller provides widgets for function calls.
-    * \code{.cpp}
-                WidgetDescription::StringWidgetDictionary getFunctionDescriptions(const Ice::Current&) const override;
-                void callDescribedFunction(const std::string& name, const StringVariantBaseMap& value, const Ice::Current&) override;
-    * \endcode
-    *
-    * The run function executed to calculate new targets
-    * \code{.cpp}
-                void rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) override;
-    * \endcode
-    *
-    * Hooks for this \ref NJointControllerBase to execute code during publishing.
-    * \code{.cpp}
-                void onPublishActivation(const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&) override;
-                void onPublishDeactivation(const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&) override;
-                void onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&) override;
-    * \endcode
-    *
-    * This \ref NJointControllerBase uses one position \ref SensorValue1DoFActuatorPosition "SensorValue", calculates one
-    * position \ref ControlTarget1DoFActuatorPosition "ControlTarget" and stores the current position target and position value in atomics.
-    * \code{.cpp}
-                const SensorValue1DoFActuatorPosition* sensor;
-                ControlTarget1DoFActuatorPosition* target;
-                std::atomic<float> targetPos {0};
-                std::atomic<float> currentPos {0};
-    * \endcode
-    *
-    * Close the class and the namespace
-    * \code{.cpp}
-            };
-        }
-    * \endcode
-    *
-    * \subsection nj-example-1-c Source file
-    *
-    * Include the required headers.
-    * \code{.cpp}
-        #include "NJointPositionPassThroughController.h"
-        #include <RobotAPI/libraries/core/Pose.h>
-    * \endcode
-    *
-    * Open the namespace
-    * \code{.cpp}
-        namespace armarx
-        {
-    * \endcode
-    *
-    * This generates a config widget used to display a config gui in \ref RobotUnitGui.
-    * It consist out of a \ref HBoxLayout containing a \ref Label and a \ref StringComboBox
-    * \code{.cpp}
-            WidgetDescription::WidgetPtr NJointPositionPassThroughController::GenerateConfigDescription(const VirtualRobot::RobotPtr&, const std::map<std::string, ConstControlDevicePtr>& controlDevices, const std::map<std::string, ConstSensorDevicePtr>& sensorDevices)
-            {
-                using namespace armarx::WidgetDescription;
-                HBoxLayoutPtr layout = new HBoxLayout;
-                LabelPtr label = new Label;
-                label->text = "control device name";
-                layout->children.emplace_back(label);
-                StringComboBoxPtr box = new StringComboBox;
-                box->defaultIndex = 0;
-    * \endcode
-    *
-    * The \ref StringComboBox only contains the names of \ref ControlDevice "ControlDevices" accepting
-    * a position \ref ControlTarget1DoFActuatorPosition "ControlTarget" and providing a position
-    * \ref SensorValue1DoFActuatorPosition "SensorValue"
-    * \code{.cpp}
-                //filter control devices
-                for (const auto& name2dev : controlDevices)
-                {
-                    const ConstControlDevicePtr& dev = name2dev.second;
-                    const auto& name = name2dev.first;
-                    if (
-                        dev->hasJointController(ControlModes::Position1DoF) &&
-                        dev->getJointController(ControlModes::Position1DoF)->getControlTarget()->isA<ControlTarget1DoFActuatorPosition>() &&
-                        sensorDevices.count(name) &&
-                        sensorDevices.at(name)->getSensorValue()->isA<SensorValue1DoFActuatorPosition>()
-                    )
-                    {
-                        box->options.emplace_back(name);
-                    }
-                }
-                box->name = "name";
-                layout->children.emplace_back(box);
-                return layout;
-            }
-    * \endcode
-    *
-    * This turns a map of variants into the config required by this \ref NJointControllerBase.
-    * The \ref Variant for the key 'name' defines the \ref ControlDevice.
-    * \code{.cpp}
-            NJointControllerConfigPtr NJointPositionPassThroughController::GenerateConfigFromVariants(const StringVariantBaseMap& values)
-            {
-                //you should check here for types null additional params etc
-                return new NJointPositionPassThroughControllerConfig {values.at("name")->getString()};
-            }
-    * \endcode
-    *
-    * The constructors implementation.
-    * \code{.cpp}
-            NJointPositionPassThroughController::NJointPositionPassThroughController(
-                const RobotUnitPtr& ru,
-                NJointControllerConfigPtr config,
-                const VirtualRobot::RobotPtr&
-            )
-            {
-                ARMARX_CHECK_EXPRESSION(ru);
-    * \endcode
-    *
-    * It checks whether the provided config has the correct type.
-    * \code{.cpp}
-                NJointPositionPassThroughControllerConfigPtr cfg = NJointPositionPassThroughControllerConfigPtr::dynamicCast(config);
-                ARMARX_CHECK_EXPRESSION(cfg) << "The provided config has the wrong type! The type is " << config->ice_id();
-    * \endcode
-    *
-    * Then it retrieves the \ref SensorValue1DoFActuatorPosition "SensorValue" and
-    * \ref ControlTarget1DoFActuatorPosition "ControlTarget", casts then to the required types and stores them to the member variables.
-    * \code{.cpp}
-                const SensorValueBase* sv = useSensorValue(cfg->deviceName);
-                ControlTargetBase* ct = useControlTarget(cfg->deviceName, ControlModes::Position1DoF);
-                ARMARX_CHECK_EXPRESSION(sv->asA<SensorValue1DoFActuatorPosition>());
-                ARMARX_CHECK_EXPRESSION(ct->asA<ControlTarget1DoFActuatorPosition>());
-                sensor = sv->asA<SensorValue1DoFActuatorPosition>();
-                target = ct->asA<ControlTarget1DoFActuatorPosition>();
-            }
-    * \endcode
-    *
-    * The class name has to be unique, hence the c++ class name should be used.
-    * \code{.cpp}
-            std::string NJointPositionPassThroughController::getClassName(const Ice::Current&) const
-            {
-                return "NJointPositionPassThroughController";
-            }
-
-    * \endcode
-    *
-    * This \ref NJointControllerBase provides two widgets for function calls.
-    * \code{.cpp}
-            WidgetDescription::StringWidgetDictionary NJointPositionPassThroughController::getFunctionDescriptions(const Ice::Current&) const
-            {
-                using namespace armarx::WidgetDescription;
-    * \endcode
-    *
-    * The first widget has a \ref Label and a \ref FloatSpinBox.
-    * \code{.cpp}
-                HBoxLayoutPtr layoutSetPos = new HBoxLayout;
-                {
-                    LabelPtr label = new Label;
-                    label->text = "positiontarget";
-                    layoutSetPos->children.emplace_back(label);
-                    FloatSpinBoxPtr spin = new FloatSpinBox;
-                    spin->defaultValue = 0;
-                    spin->max = 1;
-                    spin->min = -1;
-    * \endcode
-    *
-    * The \ref FloatSpinBox creates a variant called 'spinmearound'
-    * \code{.cpp}
-                    spin->name = "spinmearound";
-                    layoutSetPos->children.emplace_back(spin);
-                }
-    * \endcode
-    *
-    * The second widget also has a \ref Label and a \ref FloatSpinBox.
-    * \code{.cpp}
-                VBoxLayoutPtr layoutSetHalfPos = new VBoxLayout;
-                {
-                    LabelPtr label = new Label;
-                    label->text = "positiontarget / 2";
-                    layoutSetHalfPos->children.emplace_back(label);
-                    FloatSpinBoxPtr spin = new FloatSpinBox;
-                    spin->defaultValue = 0;
-                    spin->max = 0.5;
-                    spin->min = -0.5;
-                    spin->name = "spinmehalfaround";
-                    layoutSetHalfPos->children.emplace_back(spin);
-                }
-    * \endcode
-    *
-    * This returns a map of boths widgets.
-    * The keys will be used to identify the called function.
-    * \code{.cpp}
-                return {{"SetPosition", layoutSetPos}, {"SetPositionHalf", layoutSetHalfPos}};
-            }
-    * \endcode
-    *
-    * This function is called from the \ref RobotUnitGuiPlugin when the prior defined functions are called.
-    * Both functions set the target position.
-    * \code{.cpp}
-            void NJointPositionPassThroughController::callDescribedFunction(const std::string& name, const StringVariantBaseMap& value, const Ice::Current&)
-            {
-                if (name == "SetPosition")
-                {
-                    //you should check here for types null additional params etc
-                    targetPos = value.at("spinmearound")->getFloat();
-                }
-                else if (name == "SetPositionHalf")
-                {
-                    //you should check here for types null additional params etc
-                    targetPos = value.at("spinmehalfaround")->getFloat() * 2;
-                }
-                else
-                {
-                    ARMARX_ERROR << "CALLED UNKNOWN REMOTE FUNCTION: " << name;
-                }
-            }
-    * \endcode
-    *
-    * The \ref rtRun function sets the \ref ControlTarget1DoFActuatorPosition "ControlTarget" to the
-    * target value set via the atomic and stores the current
-    * \ref SensorValue1DoFActuatorPosition "SensorValue" to the other atomic.
-    * \code{.cpp}
-            void NJointPositionPassThroughController::rtRun(const IceUtil::Time& t, const IceUtil::Time&)
-            {
-                ARMARX_RT_LOGF_ERROR("A MESSAGE PARAMETER %f", t.toSecondsDouble()).deactivateSpam(1);
-                ARMARX_RT_LOGF_IMPORTANT("A MESSAGE WITHOUT PARAMETERS").deactivateSpam(1);
-                target->position = targetPos;
-                currentPos = sensor->position;
-            }
-    * \endcode
-    *
-    * The publish activation \ref onPublishActivation "hook" does nothing, but could be used to call
-    * \ref DebugDraver::setRobotVisu.
-    * \code{.cpp}
-            void NJointPositionPassThroughController::onPublishActivation(const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&)
-            {
-                //we could do some setup for the drawer here. e.g. add a robot
-            }
-
-    * \endcode
-    *
-    * The publish deactivation \ref onPublishDeactivation "hook" clears the \ref DebugDrawer layer
-    * \code{.cpp}
-            void NJointPositionPassThroughController::onPublishDeactivation(const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&)
-            {
-                drawer->removeLayer("Layer_" + getInstanceName());
-            }
-
-    * \endcode
-    *
-    * The publish \ref onPublish "hook" draws a sphere with radius of the position stored in the atomic times 2000 to the \ref DebugDrawer.
-    * \code{.cpp}
-            void NJointPositionPassThroughController::onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&)
-            {
-                drawer->setSphereVisu("Layer_" + getInstanceName(), "positionball", new Vector3, armarx::DrawColor {1, 1, 1, 1}, currentPos * 2000);
-            }
-    * \endcode
-    *
-    * This registers a factory for this \ref NJointControllerBase.
-    * This factory is used by the \ref RobotUnit to create the \ref NJointControllerBase.
-    * The passed name has to match the name returned by \ref getClassName.
-    * \code{.cpp}
-            NJointControllerRegistration<NJointPositionPassThroughController> registrationControllerNJointPositionPassThroughController("NJointPositionPassThroughController");
-    * \endcode
-    *
-    * This statically asserts a factory for the type NJointPositionPassThroughController is present.
-    * \code{.cpp}
-            ARMARX_ASSERT_NJOINTCONTROLLER_HAS_CONSTRUCTION_GUI(NJointPositionPassThroughController);
-    * \endcode
-    * Close the namespace
-    * \code{.cpp}
-        }
-    * \endcode
-    */
-    class NJointControllerBase:
-        virtual public NJointControllerInterface,
-        virtual public ManagedIceObject
-    {
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-        // /////////////////////////////////////// typedefs /////////////////////////////////////// //
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-    public:
-        using ConfigPtrT = NJointControllerConfigPtr;
-        using GenerateConfigDescriptionFunctionSignature = WidgetDescription::WidgetPtr(*)
-                (
-                    const VirtualRobot::RobotPtr&,
-                    const std::map<std::string, ConstControlDevicePtr>& controlDevices,
-                    const std::map<std::string, ConstSensorDevicePtr>& sensorDevices
-                );
-        template<class ConfigPrtType>
-        using GenerateConfigFromVariantsFunctionSignature = ConfigPrtType(*)(const StringVariantBaseMap&);
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-        // ///////////////////////////// constructor setup functions ////////////////////////////// //
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-    public:
-        /**
-         * @brief Get a const ptr to the given \ref SensorDevice
-         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
-         * @param deviceName The \ref SensorDevice's name
-         * @return A const ptr to the given \ref SensorDevice
-         */
-        ConstSensorDevicePtr   peekSensorDevice(const std::string& deviceName) const;
-        /**
-         * @brief Get a const ptr to the given \ref ControlDevice
-         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
-         * @param deviceName The \ref ControlDevice's name
-         * @return A const ptr to the given \ref ControlDevice
-         */
-        ConstControlDevicePtr peekControlDevice(const std::string& deviceName) const;
-
-        /**
-         * @brief Declares to calculate the \ref ControlTargetBase "ControlTarget"
-         * for the given \ref ControlDevice in the given ControlMode when \ref rtRun is called
-         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
-         * @param deviceName The \ref ControlDevice's name
-         * @param controlMode The \ref ControlTargetBase "ControlTarget's" ControlMode
-         * @return A ptr to the given \ref ControlDevice's \ref ControlTargetBase "ControlTarget"in the given ControlMode
-         */
-        ControlTargetBase* useControlTarget(const std::string& deviceName, const std::string& controlMode);
-        /**
-         * @brief Declares to calculate the \ref ControlTargetBase "ControlTarget"
-         * for the given \ref ControlDevice in the given ControlMode when \ref rtRun is called
-         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
-         * @param deviceName The \ref ControlDevice's name
-         * @param controlMode The \ref ControlTargetBase "ControlTarget's" ControlMode
-         * @return A ptr to the given \ref ControlDevice's \ref ControlTargetBase "ControlTarget"in the given ControlMode
-         */
-        template<class T>
-        T* useControlTarget(const std::string& deviceName, const std::string& controlMode);
-
-        /**
-         * @brief Get a const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
-         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
-         * @param deviceName The \ref SensorDevice's name
-         * @return A const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
-         */
-        const SensorValueBase* useSensorValue(const std::string& sensorDeviceName) const;
-        /**
-         * @brief Get a const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
-         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
-         * @param deviceName The \ref SensorDevice's name
-         * @return A const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
-         */
-        template<class T>
-        const T* useSensorValue(const std::string& deviceName) const;
-
-        /**
-         * @brief Requests a VirtualRobot for use in \ref rtRun
-         *          *
-         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
-         *
-         * The robot is updated before \ref rtRun is called and can be accessed via \rtGetRobot
-         * @param updateCollisionModel Whether the robot's collision model should be updated
-         * @see rtGetRobot
-         */
-        const VirtualRobot::RobotPtr& useSynchronizedRtRobot(bool updateCollisionModel = false);
-
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-        // ////////////////////////////////// Component interface ///////////////////////////////// //
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-    protected:
-        /// @see Component::getDefaultName
-        std::string getDefaultName() const override;
-        /// @see Component::onInitComponent
-        void onInitComponent() final;
-        /// @see Component::onConnectComponent
-        void onConnectComponent() final;
-        /// @see Component::onDisconnectComponent
-        void onDisconnectComponent() final;
-        /// @see Component::onExitComponent
-        void onExitComponent() final;
-
-
-        virtual void onInitNJointController() {}
-        virtual void onConnectNJointController() {}
-        virtual void onDisconnectNJointController() {}
-        virtual void onExitNJointController() {}
-
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-        // ////////////////////////////////// ThreadPool functionality///////////////////////////// //
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-    protected:
-        ThreadPoolPtr getThreadPool() const;
-
-        /**
-         * @brief Executes a given task in a separate thread from the Application ThreadPool.
-         * @param taskName Descriptive name of this task to identify it on errors.
-         * @param task std::function object (or lambda) that is to be executed.
-         * @note This task will be joined in onExitComponent of the NJointControllerBase. So make sure it terminates, when the
-         * controller is deactivated or removed!
-         *
-         * @code{.cpp}
-         *  runTask("PlotterTask", [&]
-                {
-                    CycleUtil c(30);
-                    getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted);
-                    while (getState() == eManagedIceObjectStarted)
-                    {
-                        if (isControllerActive())
-                        {
-                            StringVariantBaseMap errors;
-                            for (size_t i = 0; i < sensors.size(); i++)
-                            {
-                                errors[cfg->jointNames.at(i)] = new Variant(currentError(i));
-                            }
-                            dbgObs->setDebugChannel("TrajectoryController", errors);
-                        }
-                        c.waitForCycleDuration();
-                    }
-                });
-         * @endcode
-         */
-        template < typename Task >
-        void runTask(const std::string& taskName, Task&& task)
-        {
-            std::unique_lock lock(threadHandlesMutex);
-            ARMARX_CHECK_EXPRESSION(!taskName.empty());
-            ARMARX_CHECK_EXPRESSION(!threadHandles.count(taskName));
-            ARMARX_CHECK_EXPRESSION(getState() < eManagedIceObjectExiting);
-            ARMARX_VERBOSE << "Adding NJointControllerBase task named '" << taskName << "' - current available thread count: " << getThreadPool()->getAvailableTaskCount();
-            auto handlePtr = std::make_shared<ThreadPool::Handle>(getThreadPool()->runTask(task));
-            ARMARX_CHECK_EXPRESSION(handlePtr->isValid()) << "Could not add task (" << taskName << " - " << GetTypeString(task) << " ) - available threads: " << getThreadPool()->getAvailableTaskCount();
-            threadHandles[taskName] = handlePtr;
-        }
-        std::map<std::string, std::shared_ptr<ThreadPool::Handle>> threadHandles;
-        std::mutex threadHandlesMutex;
-
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-        // ///////////////////////////////////// ice interface //////////////////////////////////// //
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-    public:
-        bool isControllerActive(const Ice::Current& = Ice::emptyCurrent) const final override;
-        bool isControllerRequested(const Ice::Current& = Ice::emptyCurrent) const final override;
-        bool isDeletable(const Ice::Current& = Ice::emptyCurrent) const final override;
-        bool hasControllerError(const Ice::Current& = Ice::emptyCurrent) const final override;
-
-        std::string getClassName(const Ice::Current& = Ice::emptyCurrent) const override  = 0;
-        std::string getInstanceName(const Ice::Current& = Ice::emptyCurrent) const final override;
-
-        NJointControllerDescription getControllerDescription(const Ice::Current& = Ice::emptyCurrent) const final override;
-        NJointControllerStatus getControllerStatus(const Ice::Current& = Ice::emptyCurrent) const final override;
-        NJointControllerDescriptionWithStatus getControllerDescriptionWithStatus(const Ice::Current& = Ice::emptyCurrent) const final override;
-        RobotUnitInterfacePrx getRobotUnit(const Ice::Current& = Ice::emptyCurrent) const final override;
-
-        void activateController(const Ice::Current& = Ice::emptyCurrent) final override;
-        void deactivateController(const Ice::Current& = Ice::emptyCurrent) final override;
-        void deleteController(const Ice::Current& = Ice::emptyCurrent) final override;
-        void deactivateAndDeleteController(const Ice::Current& = Ice::emptyCurrent) final override;
-
-        WidgetDescription::StringWidgetDictionary getFunctionDescriptions(const Ice::Current& = Ice::emptyCurrent) const override;
-        void callDescribedFunction(const std::string&, const StringVariantBaseMap&, const Ice::Current& = Ice::emptyCurrent) override;
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-        // ///////////////////////////////////// rt interface ///////////////////////////////////// //
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-    public: ///TODO make protected and use attorneys
-
-        /**
-         * @brief Returns the virtual robot used by this \ref NJointControllerBase in the \ref rtRun
-         * @return The virtual robot used by this \ref NJointControllerBase in the \ref rtRun
-         * @see useSynchronizedRtRobot
-         * @see rtGetRobotNodes
-         */
-        const VirtualRobot::RobotPtr& rtGetRobot()
-        {
-            return rtRobot;
-        }
-        /**
-         * @brief Returns the nodes of the virtual robot used by this \ref NJointControllerBase in the \ref rtRun
-         * @return The nodes of the virtual robot used by this \ref NJointControllerBase in the \ref rtRun
-         * @see useSynchronizedRtRobot
-         * @see rtGetRobot
-         */
-        const std::vector<VirtualRobot::RobotNodePtr>& rtGetRobotNodes()
-        {
-            return rtRobotNodes;
-        }
-        /**
-         * @brief Returns whether this \ref NJointControllerBase calculates a \ref ControlTargetBase "ControlTarget"
-         * for the given \ref ControlDevice
-         * @param deviceIndex The \ref ControlDevice's index
-         * @return Whether this \ref NJointControllerBase calculates a \ref ControlTargetBase "ControlTarget"
-         * for the given \ref ControlDevice
-         */
-        bool rtUsesControlDevice(std::size_t deviceIndex) const;
-        /**
-         * @brief Returns the indices of all \ref ControlDevice's this \ref NJointControllerBase
-         * calculates a \ref ControlTargetBase "ControlTarget" for.
-         * @return The indices of all \ref ControlDevice's this \ref NJointControllerBase
-         * calculates a \ref ControlTargetBase "ControlTarget" for.
-         */
-        const std::vector<std::size_t>& rtGetControlDeviceUsedIndices() const;
-
-        /**
-         * @brief Sets the error state to true. This will deactivate this controller!
-         */
-        bool rtGetErrorState() const;
-
-        /**
-         * @brief Returns the number of used \ref ControlDevice "ControlDevices"
-         * @return The number of used \ref ControlDevice "ControlDevices"
-         */
-        std::size_t rtGetNumberOfUsedControlDevices() const;
-
-        /**
-         * @brief Returns the class name. (the c-string may be used for rt message logging)
-         * @return The class name. (the c-string may be used for rt message logging)
-         */
-        const std::string& rtGetClassName() const;
-
-        /**
-         * @brief Returns the instance name. (the c-string may be used for rt message logging)
-         * @return The instance name. (the c-string may be used for rt message logging)
-         */
-        const std::string& rtGetInstanceName() const;
-
-    protected:
-        /**
-         * @brief This function is called before the controller is activated.
-         * You can use it to activate a thread again (DO NOT SPAWN NEW THREADS!) e.g. via a std::atomic_bool.
-         */
-        virtual void rtPreActivateController() {}
-        /**
-         * @brief This function is called after the controller is deactivated.
-         * You can use it to deactivate a thread (DO NOT JOIN THREADS!) e.g. via a std::atomic_bool.
-         */
-        virtual void rtPostDeactivateController() {}
-
-        /**
-         * @brief Sets the error state to true. This will deactivate this controller!
-         */
-        void rtSetErrorState();
-    private:
-        /**
-         * @brief Activates this controller in the \ref RobotUnitModules::ControlThread "ControlThread".
-         *
-         * Calls \ref rtPreActivateController
-         * @see rtDeactivateController
-         * @see rtDeactivateControllerBecauseOfError
-         * @see rtPreActivateController
-         */
-        void rtActivateController();
-        /**
-         * @brief Deactivates this controller in the \ref RobotUnitModules::ControlThread "ControlThread".
-         *
-         * Calls \ref rtPostDeactivateController
-         * @see rtActivateController
-         * @see rtDeactivateControllerBecauseOfError
-         * @see rtPostDeactivateController
-         */
-        void rtDeactivateController();
-        /**
-         * @brief Deactivates this controller in the \ref RobotUnitModules::ControlThread "ControlThread"
-         * and sets the error flag.
-         *
-         * Calls \ref rtPostDeactivateController
-         * This function is called when this \ref NJointControllerBase produces an error
-         * (e.g.: calculates an invalid \ref ControlTargetBase "ControlTarget", throws an exception)
-         * @see rtActivateController
-         * @see rtDeactivateController
-         * @see rtPostDeactivateController
-         */
-        void rtDeactivateControllerBecauseOfError();
-
-    public:
-
-        static const NJointControllerBasePtr NullPtr;
-
-        NJointControllerBase();
-
-        ~NJointControllerBase() override;
-        //ice interface (must not be called in the rt thread)
-
-        //c++ interface (local calls) (must be called in the rt thread)
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-        // ///////////////////////////////////// used targets ///////////////////////////////////// //
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-    public:
-        //used control devices
-        StringStringDictionary getControlDeviceUsedControlModeMap(const Ice::Current& = Ice::emptyCurrent) const final override;
-        const std::vector<char>& getControlDeviceUsedBitmap() const;
-        const std::vector<std::size_t>& getControlDeviceUsedIndices() const;
-
-        const std::map<std::string, const JointController*>& getControlDevicesUsedJointController();
-
-        //check for conflict
-        std::optional<std::vector<char>> isNotInConflictWith(const NJointControllerBasePtr& other) const;
-        std::optional<std::vector<char>> isNotInConflictWith(const std::vector<char>& used) const;
-
-        template<class ItT>
-        static std::optional<std::vector<char>> AreNotInConflict(ItT first, ItT last);
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-        // ////////////////////////////////////// publishing ////////////////////////////////////// //
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-    protected:
-        //publish thread hooks
-        virtual void onPublishActivation(const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&) {}
-        virtual void onPublishDeactivation(const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&) {}
-        virtual void onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&) {}
-    private:
-        void publish(const SensorAndControl& sac, const DebugDrawerInterfacePrx& draw, const DebugObserverInterfacePrx& observer);
-        void deactivatePublish(const DebugDrawerInterfacePrx& draw, const DebugObserverInterfacePrx& observer);
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-        // ///////////////////////////////////////// data ///////////////////////////////////////// //
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-    private:
-        /// @brief reference to the owning \ref RobotUnit
-        RobotUnit& robotUnit;
-        /// @brief Maps names of used \ref ControlDevice "ControlDevices" to the \ref JointController "JointController's" control mode
-        StringStringDictionary controlDeviceControlModeMap;
-        /// @brief Maps names of used \ref ControlDevice "ControlDevices" to the used \ref JointController for this \ref ControlDevice
-        std::map<std::string, const JointController*> controlDeviceUsedJointController;
-        /// @brief Bitmap of used \ref ControlDevice "ControlDevices" (1 == used, 0 == not used)
-        std::vector<char> controlDeviceUsedBitmap;
-        /// @brief Indices of used \ref ControlDevice "ControlDevices"
-        std::vector<std::size_t> controlDeviceUsedIndices;
-
-        std::string rtClassName_;
-        std::string instanceName_;
-
-        //this data is filled by the robot unit to provide convenience functions
-        std::atomic_bool isActive {false};
-        std::atomic_bool isRequested {false};
-        std::atomic_bool deactivatedBecauseOfError {false};
-        std::atomic_bool errorState {false};
-        bool deletable {false};
-        bool internal {false};
-
-        std::atomic_bool publishActive {false};
-
-        std::atomic_bool statusReportedActive {false};
-        std::atomic_bool statusReportedRequested {false};
-
-        VirtualRobot::RobotPtr rtRobot;
-        std::vector<VirtualRobot::RobotNodePtr> rtRobotNodes;
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-        // /////////////////////////////////////// friends //////////////////////////////////////// //
-        // //////////////////////////////////////////////////////////////////////////////////////// //
-    private:
-        /**
-        * \brief This class allows minimal access to private members of \ref NJointControllerBase in a sane fashion for \ref RobotUnitModule::ControllerManagement.
-        * \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 !!
-        */
-        friend class RobotUnitModule::NJointControllerAttorneyForControllerManagement;
-        /**
-        * \brief This class allows minimal access to private members of \ref NJointControllerBase in a sane fashion for \ref RobotUnitModule::ControlThread.
-        * \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 !!
-        */
-        friend class RobotUnitModule::NJointControllerAttorneyForControlThread;
-        /**
-        * \brief This class allows minimal access to private members of \ref NJointControllerBase in a sane fashion for \ref RobotUnitModule::Publisher.
-        * \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 !!
-        */
-        friend class RobotUnitModule::NJointControllerAttorneyForPublisher;
-        /**
-        * \brief This is required for the factory
-        * \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 !!
-        */
-        template<class> friend class detail::NJointControllerRegistryEntryHelper;
-    };
-
-    class SynchronousNJointController : public NJointControllerBase
-    {
-    public: ///TODO make protected and use attorneys
-        virtual void rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) = 0;
-        virtual void rtSwapBufferAndRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration);
-    };
-    class AsynchronousNJointController : public NJointControllerBase
-    {
-    public: ///TODO make protected and use attorneys
-        virtual void rtRunIterationBegin(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) = 0;
-        virtual void rtRunIterationEnd(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) = 0;
-    };
-    using NJointController = SynchronousNJointController;
-    using NJointControllerPtr = SynchronousNJointControllerPtr;
-}
-
-#include "NJointController.ipp"
+#include "NJointControllerBase.h"
+#include "NJointControllerRegistry.h"
+#include "NJointControllerWithTripleBuffer.h"
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.ipp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.ipp
deleted file mode 100644
index 4a147cf86218c9c5035ca27474472bca1bf23c54..0000000000000000000000000000000000000000
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.ipp
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * This file is part of ArmarX.
- *
- * ArmarX is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * ArmarX is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * @package    RobotAPI::ArmarXObjects::NJointController
- * @author     Raphael Grimm ( raphael dot grimm at kit dot edu )
- * @date       2017
- * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
- *             GNU General Public License
- */
-
-#ifndef _ARMARX_LIB_RobotAPI_NJointController_HPP
-#define _ARMARX_LIB_RobotAPI_NJointController_HPP
-
-#include <ArmarXCore/core/util/OnScopeExit.h>
-#include <ArmarXCore/core/util/TemplateMetaProgramming.h>
-
-#include "../RobotUnit.h"
-#include "NJointController.h"
-
-namespace armarx::RobotUnitModule
-{
-    class ControllerManagement;
-}
-namespace armarx
-{
-    class NJointControllerRegistryEntry
-    {
-    private:
-        friend class RobotUnitModule::ControllerManagement;
-        virtual NJointControllerBasePtr create(RobotUnitModule::ControllerManagement* cmngr,
-                                               const NJointControllerConfigPtr&,
-                                               const VirtualRobot::RobotPtr&,
-                                               bool deletable,
-                                               bool internal,
-                                               const std::string& instanceName) const = 0;
-        virtual WidgetDescription::WidgetPtr
-        GenerateConfigDescription(const VirtualRobot::RobotPtr&,
-                                  const std::map<std::string, ConstControlDevicePtr>&,
-                                  const std::map<std::string, ConstSensorDevicePtr>&) const = 0;
-        virtual NJointControllerConfigPtr
-        GenerateConfigFromVariants(const StringVariantBaseMap&) const = 0;
-        virtual bool hasRemoteConfiguration() const = 0;
-
-    protected:
-        static thread_local bool ConstructorIsRunning_;
-
-    public:
-        virtual ~NJointControllerRegistryEntry() = default;
-        static bool
-        ConstructorIsRunning()
-        {
-            return ConstructorIsRunning_;
-        }
-    };
-    using NJointControllerRegistry = Registrar<std::unique_ptr<NJointControllerRegistryEntry>>;
-
-    template <class ControllerType>
-    struct NJointControllerRegistration;
-
-    template <typename ControlDataStruct>
-    class NJointControllerWithTripleBuffer : public SynchronousNJointController
-    {
-    public:
-        using MutexType = std::recursive_mutex;
-        using LockGuardType = std::lock_guard<std::recursive_mutex>;
-
-        NJointControllerWithTripleBuffer(
-            const ControlDataStruct& initialCommands = ControlDataStruct()) :
-            controlDataTripleBuffer{initialCommands}
-        {
-        }
-
-        void rtSwapBufferAndRun(const IceUtil::Time& sensorValuesTimestamp,
-                                const IceUtil::Time& timeSinceLastIteration) override;
-
-    protected:
-        const ControlDataStruct& rtGetControlStruct() const;
-        bool rtUpdateControlStruct();
-
-        void writeControlStruct();
-        ControlDataStruct& getWriterControlStruct();
-
-        void setControlStruct(const ControlDataStruct& newStruct);
-
-        void reinitTripleBuffer(const ControlDataStruct& initial);
-
-        mutable MutexType controlDataMutex;
-
-    private:
-        WriteBufferedTripleBuffer<ControlDataStruct> controlDataTripleBuffer;
-    };
-
-    template <typename ControlDataStruct>
-    using NJointControllerWithTripleBufferPtr =
-        IceInternal::Handle<NJointControllerWithTripleBuffer<ControlDataStruct>>;
-} // namespace armarx
-
-//inline functions
-namespace armarx
-{
-    template <class T>
-    inline T*
-    NJointControllerBase::useControlTarget(const std::string& deviceName,
-                                           const std::string& controlMode)
-    {
-        static_assert(std::is_base_of<ControlTargetBase, T>::value,
-                      "The given type does not derive ControlTargetBase");
-        ControlTargetBase* const ptr = useControlTarget(deviceName, controlMode);
-        return ptr ? ptr->asA<T>() : nullptr;
-    }
-    template <class T>
-    inline const T*
-    NJointControllerBase::useSensorValue(const std::string& deviceName) const
-    {
-        static_assert(std::is_base_of<SensorValueBase, T>::value,
-                      "The given type does not derive SensorValueBase");
-        const SensorValueBase* const ptr = useSensorValue(deviceName);
-        return ptr ? ptr->asA<T>() : nullptr;
-    }
-
-    inline void
-    SynchronousNJointController::rtSwapBufferAndRun(const IceUtil::Time& sensorValuesTimestamp,
-                                                    const IceUtil::Time& timeSinceLastIteration)
-    {
-        rtRun(sensorValuesTimestamp, timeSinceLastIteration);
-    }
-
-    inline bool
-    NJointControllerBase::rtUsesControlDevice(std::size_t deviceIndex) const
-    {
-        return controlDeviceUsedBitmap.at(deviceIndex);
-    }
-
-    inline StringStringDictionary
-    NJointControllerBase::getControlDeviceUsedControlModeMap(const Ice::Current&) const
-    {
-        return controlDeviceControlModeMap;
-    }
-
-    inline const std::vector<char>&
-    NJointControllerBase::getControlDeviceUsedBitmap() const
-    {
-        return controlDeviceUsedBitmap;
-    }
-
-    inline const std::vector<std::size_t>&
-    NJointControllerBase::rtGetControlDeviceUsedIndices() const
-    {
-        return controlDeviceUsedIndices;
-    }
-
-    inline const std::vector<std::size_t>&
-    NJointControllerBase::getControlDeviceUsedIndices() const
-    {
-        return controlDeviceUsedIndices;
-    }
-
-    inline const std::map<std::string, const JointController*>&
-    NJointControllerBase::getControlDevicesUsedJointController()
-    {
-        return controlDeviceUsedJointController;
-    }
-
-    inline std::optional<std::vector<char>>
-    NJointControllerBase::isNotInConflictWith(const NJointControllerBasePtr& other) const
-    {
-        return isNotInConflictWith(other->getControlDeviceUsedBitmap());
-    }
-
-    inline std::string
-    NJointControllerBase::getDefaultName() const
-    {
-        return getClassName();
-    }
-
-    inline bool
-    NJointControllerBase::isControllerActive(const Ice::Current&) const
-    {
-        return isActive;
-    }
-
-    inline bool
-    NJointControllerBase::isControllerRequested(const Ice::Current&) const
-    {
-        return isRequested;
-    }
-
-    inline bool
-    NJointControllerBase::isDeletable(const Ice::Current&) const
-    {
-        return deletable;
-    }
-
-    inline bool
-    NJointControllerBase::hasControllerError(const Ice::Current&) const
-    {
-        return deactivatedBecauseOfError;
-    }
-
-    inline std::string
-    NJointControllerBase::getInstanceName(const Ice::Current&) const
-    {
-        return instanceName_;
-    }
-
-    inline WidgetDescription::StringWidgetDictionary
-    NJointControllerBase::getFunctionDescriptions(const Ice::Current&) const
-    {
-        return {};
-    }
-
-    inline void
-    NJointControllerBase::callDescribedFunction(const std::string&,
-                                                const StringVariantBaseMap&,
-                                                const Ice::Current&)
-    {
-    }
-
-    inline void
-    NJointControllerBase::rtSetErrorState()
-    {
-        errorState.store(true);
-    }
-
-    inline bool
-    NJointControllerBase::rtGetErrorState() const
-    {
-        return errorState;
-    }
-
-    inline std::size_t
-    NJointControllerBase::rtGetNumberOfUsedControlDevices() const
-    {
-        return controlDeviceUsedIndices.size();
-    }
-
-    inline const std::string&
-    NJointControllerBase::rtGetClassName() const
-    {
-        return rtClassName_;
-    }
-    inline const std::string&
-    NJointControllerBase::rtGetInstanceName() const
-    {
-        return instanceName_;
-    }
-
-    //NJointControllerWithTripleBuffer<ControlDataStruct>
-    template <typename ControlDataStruct>
-    inline void
-    NJointControllerWithTripleBuffer<ControlDataStruct>::rtSwapBufferAndRun(
-        const IceUtil::Time& sensorValuesTimestamp,
-        const IceUtil::Time& timeSinceLastIteration)
-    {
-        rtUpdateControlStruct();
-        rtRun(sensorValuesTimestamp, timeSinceLastIteration);
-    }
-
-    template <typename ControlDataStruct>
-    inline const ControlDataStruct&
-    NJointControllerWithTripleBuffer<ControlDataStruct>::rtGetControlStruct() const
-    {
-        return controlDataTripleBuffer.getReadBuffer();
-    }
-
-    template <typename ControlDataStruct>
-    inline bool
-    NJointControllerWithTripleBuffer<ControlDataStruct>::rtUpdateControlStruct()
-    {
-        return controlDataTripleBuffer.updateReadBuffer();
-    }
-
-    template <typename ControlDataStruct>
-    inline void
-    NJointControllerWithTripleBuffer<ControlDataStruct>::writeControlStruct()
-    {
-        //just lock to be save and reduce the impact of an error
-        //also this allows code to unlock the mutex before calling this function
-        //(can happen if some lockguard in a scope is used)
-        LockGuardType lock(controlDataMutex);
-        controlDataTripleBuffer.commitWrite();
-    }
-
-    template <typename ControlDataStruct>
-    inline ControlDataStruct&
-    NJointControllerWithTripleBuffer<ControlDataStruct>::getWriterControlStruct()
-    {
-        return controlDataTripleBuffer.getWriteBuffer();
-    }
-
-    template <typename ControlDataStruct>
-    inline void
-    NJointControllerWithTripleBuffer<ControlDataStruct>::setControlStruct(
-        const ControlDataStruct& newStruct)
-    {
-        LockGuardType lock{controlDataMutex};
-        getWriterControlStruct() = newStruct;
-        writeControlStruct();
-    }
-
-    template <typename ControlDataStruct>
-    inline void
-    NJointControllerWithTripleBuffer<ControlDataStruct>::reinitTripleBuffer(
-        const ControlDataStruct& initial)
-    {
-        controlDataTripleBuffer.reinitAllBuffers(initial);
-    }
-} // namespace armarx
-
-namespace armarx
-{
-    template <class ItT>
-    inline std::optional<std::vector<char>>
-    NJointControllerBase::AreNotInConflict(ItT first, ItT last)
-    {
-        if (first == last)
-        {
-            return std::vector<char>{};
-        }
-        std::size_t n = (*first)->getControlDeviceUsedBitmap().size();
-        std::vector<char> inuse(n, false);
-        while (first != last)
-        {
-            auto r = (*first)->isNotInConflictWith(inuse);
-            if (!r)
-            {
-                return r;
-            }
-            inuse = std::move(*r);
-            ++first;
-        }
-        return inuse;
-    }
-} // namespace armarx
-namespace armarx::detail
-{
-    ARMARX_META_MAKE_HAS_MEMBER_FNC_CHECK(
-        hasGenerateConfigDescription,
-        GenerateConfigDescription,
-        NJointControllerBase::GenerateConfigDescriptionFunctionSignature);
-    ARMARX_META_MAKE_HAS_MEMBER_FNC_CHECK(
-        hasGenerateConfigFromVariants,
-        GenerateConfigFromVariants,
-        NJointControllerBase::GenerateConfigFromVariantsFunctionSignature<typename T::ConfigPtrT>);
-
-    template <class NJointControllerT>
-    class NJointControllerRegistryEntryHelper : public NJointControllerRegistryEntry
-    {
-        static_assert(hasGenerateConfigDescription<NJointControllerT>::value ==
-                          hasGenerateConfigFromVariants<NJointControllerT>::value,
-                      "Either overload both GenerateConfigDescription and "
-                      "GenerateConfigFromVariants, or none!");
-        static constexpr bool hasRemoteConfiguration_ =
-            hasGenerateConfigDescription<NJointControllerT>::value;
-
-        NJointControllerBasePtr
-        create(RobotUnitModule::ControllerManagement* cmngr,
-               const NJointControllerConfigPtr& config,
-               const VirtualRobot::RobotPtr& rob,
-               bool deletable,
-               bool internal,
-               const std::string& instanceName) const final override
-        {
-            ARMARX_CHECK_EXPRESSION(cmngr) << "ControllerManagement module is NULL!";
-
-            using ConfigPtrT = typename NJointControllerT::ConfigPtrT;
-            ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
-            ARMARX_CHECK_EXPRESSION(cfg)
-                << "The configuration is of the wrong type! it has to be an instance of: "
-                << GetTypeString<ConfigPtrT>();
-
-            ARMARX_CHECK_EXPRESSION(!ConstructorIsRunning())
-                << "Two NJointControllers are created at the same time";
-            NJointControllerBasePtr ptr;
-            {
-                ConstructorIsRunning_ = true;
-                ARMARX_ON_SCOPE_EXIT
-                {
-                    ConstructorIsRunning_ = false;
-                };
-                ptr = new NJointControllerT(cmngr->_modulePtr<RobotUnit>(), cfg, rob);
-            }
-            ptr->deletable = deletable;
-            ptr->internal = internal;
-            ptr->rtClassName_ = ptr->getClassName(Ice::emptyCurrent);
-            ptr->instanceName_ = instanceName;
-            return ptr;
-        }
-
-        WidgetDescription::WidgetPtr
-        GenerateConfigDescription(
-            const VirtualRobot::RobotPtr& robot,
-            const std::map<std::string, ConstControlDevicePtr>& controlDevices,
-            const std::map<std::string, ConstSensorDevicePtr>& sensorDevices) const final override
-        {
-            if constexpr (hasRemoteConfiguration_)
-            {
-                try
-                {
-                    return NJointControllerT::GenerateConfigDescription(
-                        robot, controlDevices, sensorDevices);
-                }
-                catch (Ice::UserException& e)
-                {
-                    ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
-                                 << "::GenerateConfigDescription'"
-                                 << "\n---- file = " << e.ice_file()
-                                 << "\n---- line = " << e.ice_line()
-                                 << "\n---- id   = " << e.ice_id() << "\n---- what:\n"
-                                 << e.what() << "\n---- stacktrace:\n"
-                                 << e.ice_stackTrace();
-                    throw;
-                }
-                catch (std::exception& e)
-                {
-                    ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
-                                 << "::GenerateConfigDescription'"
-                                 << "\n---- what:\n"
-                                 << e.what();
-                    throw;
-                }
-                catch (...)
-                {
-                    ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
-                                 << "::GenerateConfigDescription'";
-                    throw;
-                }
-            }
-            else
-            {
-                ARMARX_CHECK_EXPRESSION(!"This function should never be called");
-            }
-        }
-
-        NJointControllerConfigPtr
-        GenerateConfigFromVariants(const StringVariantBaseMap& variants) const final override
-        {
-            if constexpr (hasRemoteConfiguration_)
-            {
-                try
-                {
-                    return NJointControllerT::GenerateConfigFromVariants(variants);
-                }
-                catch (Ice::UserException& e)
-                {
-                    ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
-                                 << "::GenerateConfigFromVariants'"
-                                 << "\n---- file = " << e.ice_file()
-                                 << "\n---- line = " << e.ice_line()
-                                 << "\n---- id   = " << e.ice_id() << "\n---- what:\n"
-                                 << e.what() << "\n---- stacktrace:\n"
-                                 << e.ice_stackTrace();
-                    throw;
-                }
-                catch (std::exception& e)
-                {
-                    ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
-                                 << "::GenerateConfigFromVariants'"
-                                 << "\n---- what:\n"
-                                 << e.what();
-                    throw;
-                }
-                catch (...)
-                {
-                    ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
-                                 << "::GenerateConfigFromVariants'";
-                    throw;
-                }
-            }
-            else
-            {
-                ARMARX_CHECK_EXPRESSION(!"This function should never be called");
-            }
-        }
-
-        bool
-        hasRemoteConfiguration() const final override
-        {
-            return hasRemoteConfiguration_;
-        }
-    };
-} // namespace armarx::detail
-namespace armarx
-{
-    using NJointControllerRegistry = Registrar<std::unique_ptr<NJointControllerRegistryEntry>>;
-    template <class ControllerType>
-    struct NJointControllerRegistration
-    {
-        NJointControllerRegistration(const std::string& name)
-        {
-            NJointControllerRegistry::registerElement(
-                name,
-                std::unique_ptr<NJointControllerRegistryEntry>(
-                    new detail::NJointControllerRegistryEntryHelper<ControllerType>));
-        }
-    };
-} // namespace armarx
-#define ARMARX_ASSERT_NJOINTCONTROLLER_HAS_CONSTRUCTION_GUI(T)                                     \
-    static_assert(                                                                                 \
-        ::armarx::detail::hasGenerateConfigDescription<T>::value,                                  \
-        #T " does not offer a construction gui (missing: static GenerateConfigDescription)");      \
-    static_assert(                                                                                 \
-        ::armarx::detail::hasGenerateConfigFromVariants<T>::value,                                 \
-        #T " does not offer a construction gui (missing: static GenerateConfigFromVariants)")
-
-
-#endif
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerBase.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerBase.h
new file mode 100644
index 0000000000000000000000000000000000000000..cad19193568ecff7c8e97766b89036d0b88b8e26
--- /dev/null
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerBase.h
@@ -0,0 +1,1061 @@
+/*
+ * This file is part of ArmarX.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @package    RobotAPI::ArmarXObjects::NJointController
+ * @author     Raphael Grimm ( raphael dot grimm at kit dot edu )
+ * @date       2017
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+#pragma once
+
+#include <RobotAPI/interface/units/RobotUnit/NJointController.h>
+
+#include <ArmarXCore/core/ManagedIceObject.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h> // for ARMARX_CHECK
+#include <ArmarXCore/interface/core/ManagedIceObjectDefinitions.h>
+#include <ArmarXCore/core/services/tasks/ThreadPool.h>
+
+#include <VirtualRobot/VirtualRobot.h>
+
+#include <functional>
+#include <optional>
+#include <atomic>
+#include <mutex>
+#include <map>
+
+namespace IceProxy::armarx
+{
+    class DebugDrawerInterface;
+    class RobotUnitInterface;
+}
+
+namespace armarx
+{
+    namespace RobotUnitModule
+    {
+        class NJointControllerAttorneyForPublisher;
+        class NJointControllerAttorneyForControlThread;
+        class NJointControllerAttorneyForControllerManagement;
+    }
+    namespace detail
+    {
+        template<class> class NJointControllerRegistryEntryHelper;
+        class ControlThreadOutputBufferEntry;
+    }
+    namespace WidgetDescription
+    {
+        class Widget;
+        typedef ::IceInternal::Handle< ::armarx::WidgetDescription::Widget> WidgetPtr;
+        typedef ::std::map< ::std::string, ::armarx::WidgetDescription::WidgetPtr> StringWidgetDictionary;
+    }
+    using SensorAndControl = detail::ControlThreadOutputBufferEntry;
+    class JointController;
+    class SensorValueBase;
+    class ControlTargetBase;
+    using ConstControlDevicePtr = std::shared_ptr<const class ControlDevice>;
+    using ConstSensorDevicePtr = std::shared_ptr<const class SensorDevice>;
+
+    typedef ::IceInternal::ProxyHandle< ::IceProxy::armarx::DebugDrawerInterface> DebugDrawerInterfacePrx;
+    typedef ::IceInternal::ProxyHandle< ::IceProxy::armarx::RobotUnitInterface> RobotUnitInterfacePrx;
+
+    using ThreadPoolPtr = std::shared_ptr<class ThreadPool>;
+
+    TYPEDEF_PTRS_HANDLE(NJointControllerBase);
+    TYPEDEF_PTRS_HANDLE(SynchronousNJointController);
+    TYPEDEF_PTRS_HANDLE(AsynchronousNJointController);
+
+    TYPEDEF_PTRS_HANDLE(RobotUnit);
+
+    /**
+     * @defgroup Library-RobotUnit-NJointControllers NJointControllers
+     * @ingroup Library-RobotUnit
+     */
+
+    /**
+    * @ingroup Library-RobotUnit-NJointControllers
+    * @brief A high level controller writing its results into \ref ControlTargetBase "ControlTargets".
+    *
+    * This is the abstract base class for all NJointControllers.
+    * It implements basic management routines required by the RobotUnit and some basic ice calls.
+    * \ref NJointControllerBase "NJointControllers" are instantiated and managed by the \ref RobotUnit.
+    *
+    * A \ref NJointControllerBase calculates \ref ControlTargetBase "ControlTargets" for a set of
+    * \ref ControlDevice "ControlDevices" in a specific ControlMode.
+    * This ControlMode is defined for each \ref ControlDevice during construction.
+    *
+    * \section nj-state Requested and Active
+    * A \ref NJointControllerBase can is requested / not requested and active / inactive.
+    * All four combinations are possible.
+    *
+    * \subsection nj-state-req Requested / Not Requested
+    * If the user wants this \ref NJointControllerBase to be executed it is in a requested state (see \ref isControllerRequested).
+    * Otherwise the controler is not requested.
+    *
+    * Calling \ref activateController sets the state to requested.
+    * Calling \ref deactivateController sets the state to not requested.
+    * If the \ref NJointControllerBase causes an error or a different \ref NJointControllerBase using one or more of the same
+    * \ref ControlDevice's is requested, this \ref NJointControllerBase is deactivated.
+    *
+    *
+    * \subsection nj-state-act Active / Inactive
+    * Is the \ref NJointControllerBase executed by the \ref RobotUnitModules::ControlThread "ControlThread" it is active
+    * (see \ref isControllerActive).
+    *
+    * To be executed by the \ref RobotUnitModules::ControlThread "ControlThread", the \ref NJointControllerBase has to be
+    * requested at some point in the past.
+    *
+    * If a controller is active, it has to write a valid \ref ControlTargetBase "ControlTarget"
+    * for each of its \ref ControlDevice "ControlDevicea" (if it fails, it will be deactivated).
+    *
+    * \section Constructor
+    * In the Constructor, a \ref NJointControllerBase has to declare all \ref ControlDevice "ControlDevices" it uses.
+    *
+    * The constructor takes a pointer to a configuration structure of the type \ref NJointControllerBase::ConfigPtrT.
+    * If an implementation requires a special configuration structure (e.g.: SomeOtherCfg), it has to override this type by calling adding
+    * \code{.cpp}
+    * using ConfigPtrT = SomeOtherCfgPtr;
+    * \endcode
+    * to it's clas definition.
+    * The type SomeOtherCfg has to derive \ref NJointControllerConfigPtr.
+    *
+    * There is a way to generate a small gui widget for controller construction (see this \ref nj-ctor-gui "section").
+    *
+    * \subsection nj-ctor-req-ctrl Using ControlTargets
+    * A \ref NJointControllerBase can use \ref peekControlDevice to examine a \ref ControlDevice before using it
+    * (e.g.: checking the supported \ref ControlTargetBase "ControlTargets").
+    *
+    * If a \ref ControlDevice should be used by this \ref NJointControllerBase, it has to call \ref useControlDevice.
+    * This sets the ControlMode for the \ref ControlDevice and returns a pointer to the \ref ControlTargetBase "ControlTarget".
+    * This pointer has to be used to send commands in each iteration of \ref rtRun.
+    * The ControlMode can't be changed afterwards (A new \ref NJointControllerBase has to be created).
+    *
+    *
+    * \subsection nj-ctor-req-sens Using SensorValues
+    * A \ref NJointControllerBase can use \ref peekSensorDevice to examine a \ref SensorDevice before using it.
+    *
+    * If a \ref SensorDevice should be used by this \ref NJointControllerBase, it has to call \ref useSensorDevice.
+    * This returns a pointer to the \ref SensorValueBase "SensorValue".
+    *
+    * \subsection nj-ctor-rob A synchronized Virtualrobot
+    * If the controller needs a simox robot in \ref rtRun, it should call \ref useSynchronizedRtRobot.
+    * This will provide a simoxRobot via \ref rtGetRobot.
+    * This robot is synchronized with the real robots state before calling \ref rtRun
+    *
+    * \section nj-parts Rt and non Rt
+    * Each \ref NJointControllerBase has two parts:
+    * \li The RT controll loop
+    * \li The NonRT ice communication
+    *
+    * \subsection rtcontrollloop The Rt controll loop (\ref rtRun)
+    * \warning This part has to satisfy realtime conditions!
+    * All realtime functions of \ref NJointControllerBase have the 'rt' prefix.
+    *
+    * Here the \ref NJointControllerBase has access to the robot's current state
+    * and has to write results into \ref ControlTargetBase "ControlTargets".
+    *
+    * It must not:
+    * \li call any blocking operation
+    * \li allocate ram on the heap (since this is a blocking operation)
+    * \li resize any datastructure (e.g. vector::resize) (this sometimes allocates ram on the heap)
+    * \li insert new datafields into datastructures (e.g. vector::push_back) (this sometimes allocates ram on the heap)
+    * \li write to any stream (e.g. ARMARX_VERBOSE, std::cout, print, filestreams) (this sometimes blocks/allocates ram on the heap)
+    * \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)
+    * \li do any expensive calculations (e.g. calculate IK, run some solver, invert big matrices)
+    *
+    * \subsection nonrtpart The NonRT ice communication
+    * This part consits of any ice communication.
+    * Here the \ref NJointControllerBase can get new controll parameters or targets from other components.
+    *
+    * \section rtnrtcomm Communication between RT and NonRT
+    * All communication between RT and NonRT has to be lockfree.
+    * The \ref NJointControllerBase has to use constructs like atomics or
+    * \ref TripleBuffer "TripleBuffers" (See \ref armarx::NJointControllerWithTripleBuffer).
+    *
+    * \image html NJointControllerGeneralDataFlow.svg "General Dataflow in a NJointControllerBase"
+    *
+    * \image html NJointControllerAtomicDataFlow.svg "Dataflow in a NJointControllerBase using atomics for communication between RT and NonRT"
+    *
+    * \image html NJointControllerTripleBufferDataFlow.svg "Dataflow in a NJointControllerBase using a triple buffer for communication between RT and NonRT"
+    *
+    *
+    * \image html NJointControllerDataFlow_Graph.svg "Dataflow in a NJointControllerBase as a Graph of the two participating domains"
+    * The above image shows the two participating domains: one RT thread and multiple ICE threads.
+    * If data has to flow along an arrow, you need some construct for non blocking message passing.
+    *
+    * \warning If you use \ref TrippleBuffer "TrippleBuffers" or \ref WriteBufferedTrippleBuffer "WriteBufferedTrippleBuffers" you need a separate one for each arrow.
+    *
+    * \section expensivework How to do expensive calculations
+    * You have to execute expensive calculations in a different worker thread.
+    * This thread could calculate target values at its own speed (e.g. 100 Hz).
+    *
+    * While rtRun runs at a higher frequency (e.g. 1000 Hz) and:
+    * \li reads target values
+    * \li optionally passes the target values to a PID controller
+    * \li writes them to the targets
+    * \li sends the sensor values to the worker thread.
+    *
+    * If you do some additional calculation in rtRun, you maybe need to pass config parameters from NonRT to RT using a nonblocking method.
+    *
+    * \image html NJointControllerWorkerThreadDataFlow.svg "Dataflow in a NJointControllerBase using a worker thread"
+    *
+    * \image html NJointControllerWorkerThreadDataFlow_Graph.svg "Dataflow in a NJointControllerBase using a worker thread as a Graph of the three participating domains"
+    * The above image shows the three participating domains: one RT thread, one worker trhead and multiple ICE threads.
+    * If data has to flow along an arrow, you need some construct for non blocking message passing.
+    *
+    * \warning If you use \ref TrippleBuffer "TrippleBuffers" or \ref WriteBufferedTrippleBuffer "WriteBufferedTrippleBuffers" you need a separate one for each arrow.
+    *
+    * \section nj-ctor-gui Providing a gui for controller construction.
+    * By implementing these functions:
+    * \code{.cpp}
+     static WidgetDescription::WidgetPtr GenerateConfigDescription
+     (
+        const VirtualRobot::RobotPtr& robot,
+        const std::map<std::string, ConstControlDevicePtr>& controlDevices,
+        const std::map<std::string, ConstSensorDevicePtr>& sensorDevices
+     ); //describes how the widget is supposed to look
+     static ConfigPtrT GenerateConfigFromVariants(const StringVariantBaseMap&); // turns the resulting variants into a config
+    * \endcode
+    *
+    * The \ref RobotUnitGui will provide a widget to configure and construct a \ref NJointControllerBase of this type.
+    *
+    * \section Examples
+    *
+    * More examples can be found in the Tutorials Package
+    *
+    * \subsection nj-example-1 A simple pass Position controller
+    * \note The code can be found in the Tutorial package
+    *
+    * \subsection nj-example-1-h Header
+    * Include headers
+    * \code{.cpp}
+        #include <RobotAPI/components/units/RobotUnit/RobotUnit.h>
+        #include <RobotAPI/components/units/RobotUnit/ControlTargets/ControlTarget1DoFActuator.h>
+        #include <RobotAPI/components/units/RobotUnit/SensorValues/SensorValue1DoFActuator.h>
+    * \endcode
+    *
+    * Open the namespace
+    * \code{.cpp}
+        namespace armarx
+        {
+    * \endcode
+    *
+    * Typedef some pointers
+    * \code{.cpp}
+            TYPEDEF_PTRS_HANDLE(NJointPositionPassThroughController);
+            TYPEDEF_PTRS_HANDLE(NJointPositionPassThroughControllerConfig);
+    * \endcode
+    *
+    * The config has to inherit \ref NJointControllerConfig and consists only of the joint name
+    * \code{.cpp}
+            class NJointPositionPassThroughControllerConfig : virtual public NJointControllerConfig
+            {
+            public:
+                NJointPositionPassThroughControllerConfig(const std::string& name): deviceName {name} {}
+                std::string deviceName;
+            };
+    * \endcode
+    *
+    * The controller class has to inherit \ref NJointControllerBase
+    * \code{.cpp}
+            class NJointPositionPassThroughController: public NJointControllerBase
+            {
+            public:
+    * \endcode
+    *
+    * The \ref NJointControllerBase provides a config widget for the \ref RobotUnitGuiPlugin
+    * \code{.cpp}
+                static WidgetDescription::WidgetPtr GenerateConfigDescription
+                (
+                    const VirtualRobot::RobotPtr&,
+                    const std::map<std::string, ConstControlDevicePtr>& controlDevices,
+                    const std::map<std::string, ConstSensorDevicePtr>& sensorDevices
+                );
+                static NJointControllerConfigPtr GenerateConfigFromVariants(const StringVariantBaseMap& values);
+    * \endcode
+    *
+    * The ctor receives a pointer to the \ref RobotUnit, a pointer to the config and a pointer to a VirtualRobot model.
+    * \code{.cpp}
+                NJointPositionPassThroughController(
+                    const RobotUnitPtr& prov,
+                    NJointControllerConfigPtr config,
+                    const VirtualRobot::RobotPtr& r
+                );
+    * \endcode
+    *
+    * The function to provide the class name.
+    * \code{.cpp}
+                std::string getClassName(const Ice::Current&) const override;
+    * \endcode
+    *
+    * This controller provides widgets for function calls.
+    * \code{.cpp}
+                WidgetDescription::StringWidgetDictionary getFunctionDescriptions(const Ice::Current&) const override;
+                void callDescribedFunction(const std::string& name, const StringVariantBaseMap& value, const Ice::Current&) override;
+    * \endcode
+    *
+    * The run function executed to calculate new targets
+    * \code{.cpp}
+                void rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) override;
+    * \endcode
+    *
+    * Hooks for this \ref NJointControllerBase to execute code during publishing.
+    * \code{.cpp}
+                void onPublishActivation(const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&) override;
+                void onPublishDeactivation(const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&) override;
+                void onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&) override;
+    * \endcode
+    *
+    * This \ref NJointControllerBase uses one position \ref SensorValue1DoFActuatorPosition "SensorValue", calculates one
+    * position \ref ControlTarget1DoFActuatorPosition "ControlTarget" and stores the current position target and position value in atomics.
+    * \code{.cpp}
+                const SensorValue1DoFActuatorPosition* sensor;
+                ControlTarget1DoFActuatorPosition* target;
+                std::atomic<float> targetPos {0};
+                std::atomic<float> currentPos {0};
+    * \endcode
+    *
+    * Close the class and the namespace
+    * \code{.cpp}
+            };
+        }
+    * \endcode
+    *
+    * \subsection nj-example-1-c Source file
+    *
+    * Include the required headers.
+    * \code{.cpp}
+        #include "NJointPositionPassThroughController.h"
+        #include <RobotAPI/libraries/core/Pose.h>
+    * \endcode
+    *
+    * Open the namespace
+    * \code{.cpp}
+        namespace armarx
+        {
+    * \endcode
+    *
+    * This generates a config widget used to display a config gui in \ref RobotUnitGui.
+    * It consist out of a \ref HBoxLayout containing a \ref Label and a \ref StringComboBox
+    * \code{.cpp}
+            WidgetDescription::WidgetPtr NJointPositionPassThroughController::GenerateConfigDescription(const VirtualRobot::RobotPtr&, const std::map<std::string, ConstControlDevicePtr>& controlDevices, const std::map<std::string, ConstSensorDevicePtr>& sensorDevices)
+            {
+                using namespace armarx::WidgetDescription;
+                HBoxLayoutPtr layout = new HBoxLayout;
+                LabelPtr label = new Label;
+                label->text = "control device name";
+                layout->children.emplace_back(label);
+                StringComboBoxPtr box = new StringComboBox;
+                box->defaultIndex = 0;
+    * \endcode
+    *
+    * The \ref StringComboBox only contains the names of \ref ControlDevice "ControlDevices" accepting
+    * a position \ref ControlTarget1DoFActuatorPosition "ControlTarget" and providing a position
+    * \ref SensorValue1DoFActuatorPosition "SensorValue"
+    * \code{.cpp}
+                //filter control devices
+                for (const auto& name2dev : controlDevices)
+                {
+                    const ConstControlDevicePtr& dev = name2dev.second;
+                    const auto& name = name2dev.first;
+                    if (
+                        dev->hasJointController(ControlModes::Position1DoF) &&
+                        dev->getJointController(ControlModes::Position1DoF)->getControlTarget()->isA<ControlTarget1DoFActuatorPosition>() &&
+                        sensorDevices.count(name) &&
+                        sensorDevices.at(name)->getSensorValue()->isA<SensorValue1DoFActuatorPosition>()
+                    )
+                    {
+                        box->options.emplace_back(name);
+                    }
+                }
+                box->name = "name";
+                layout->children.emplace_back(box);
+                return layout;
+            }
+    * \endcode
+    *
+    * This turns a map of variants into the config required by this \ref NJointControllerBase.
+    * The \ref Variant for the key 'name' defines the \ref ControlDevice.
+    * \code{.cpp}
+            NJointControllerConfigPtr NJointPositionPassThroughController::GenerateConfigFromVariants(const StringVariantBaseMap& values)
+            {
+                //you should check here for types null additional params etc
+                return new NJointPositionPassThroughControllerConfig {values.at("name")->getString()};
+            }
+    * \endcode
+    *
+    * The constructors implementation.
+    * \code{.cpp}
+            NJointPositionPassThroughController::NJointPositionPassThroughController(
+                const RobotUnitPtr& ru,
+                NJointControllerConfigPtr config,
+                const VirtualRobot::RobotPtr&
+            )
+            {
+                ARMARX_CHECK_EXPRESSION(ru);
+    * \endcode
+    *
+    * It checks whether the provided config has the correct type.
+    * \code{.cpp}
+                NJointPositionPassThroughControllerConfigPtr cfg = NJointPositionPassThroughControllerConfigPtr::dynamicCast(config);
+                ARMARX_CHECK_EXPRESSION(cfg) << "The provided config has the wrong type! The type is " << config->ice_id();
+    * \endcode
+    *
+    * Then it retrieves the \ref SensorValue1DoFActuatorPosition "SensorValue" and
+    * \ref ControlTarget1DoFActuatorPosition "ControlTarget", casts then to the required types and stores them to the member variables.
+    * \code{.cpp}
+                const SensorValueBase* sv = useSensorValue(cfg->deviceName);
+                ControlTargetBase* ct = useControlTarget(cfg->deviceName, ControlModes::Position1DoF);
+                ARMARX_CHECK_EXPRESSION(sv->asA<SensorValue1DoFActuatorPosition>());
+                ARMARX_CHECK_EXPRESSION(ct->asA<ControlTarget1DoFActuatorPosition>());
+                sensor = sv->asA<SensorValue1DoFActuatorPosition>();
+                target = ct->asA<ControlTarget1DoFActuatorPosition>();
+            }
+    * \endcode
+    *
+    * The class name has to be unique, hence the c++ class name should be used.
+    * \code{.cpp}
+            std::string NJointPositionPassThroughController::getClassName(const Ice::Current&) const
+            {
+                return "NJointPositionPassThroughController";
+            }
+
+    * \endcode
+    *
+    * This \ref NJointControllerBase provides two widgets for function calls.
+    * \code{.cpp}
+            WidgetDescription::StringWidgetDictionary NJointPositionPassThroughController::getFunctionDescriptions(const Ice::Current&) const
+            {
+                using namespace armarx::WidgetDescription;
+    * \endcode
+    *
+    * The first widget has a \ref Label and a \ref FloatSpinBox.
+    * \code{.cpp}
+                HBoxLayoutPtr layoutSetPos = new HBoxLayout;
+                {
+                    LabelPtr label = new Label;
+                    label->text = "positiontarget";
+                    layoutSetPos->children.emplace_back(label);
+                    FloatSpinBoxPtr spin = new FloatSpinBox;
+                    spin->defaultValue = 0;
+                    spin->max = 1;
+                    spin->min = -1;
+    * \endcode
+    *
+    * The \ref FloatSpinBox creates a variant called 'spinmearound'
+    * \code{.cpp}
+                    spin->name = "spinmearound";
+                    layoutSetPos->children.emplace_back(spin);
+                }
+    * \endcode
+    *
+    * The second widget also has a \ref Label and a \ref FloatSpinBox.
+    * \code{.cpp}
+                VBoxLayoutPtr layoutSetHalfPos = new VBoxLayout;
+                {
+                    LabelPtr label = new Label;
+                    label->text = "positiontarget / 2";
+                    layoutSetHalfPos->children.emplace_back(label);
+                    FloatSpinBoxPtr spin = new FloatSpinBox;
+                    spin->defaultValue = 0;
+                    spin->max = 0.5;
+                    spin->min = -0.5;
+                    spin->name = "spinmehalfaround";
+                    layoutSetHalfPos->children.emplace_back(spin);
+                }
+    * \endcode
+    *
+    * This returns a map of boths widgets.
+    * The keys will be used to identify the called function.
+    * \code{.cpp}
+                return {{"SetPosition", layoutSetPos}, {"SetPositionHalf", layoutSetHalfPos}};
+            }
+    * \endcode
+    *
+    * This function is called from the \ref RobotUnitGuiPlugin when the prior defined functions are called.
+    * Both functions set the target position.
+    * \code{.cpp}
+            void NJointPositionPassThroughController::callDescribedFunction(const std::string& name, const StringVariantBaseMap& value, const Ice::Current&)
+            {
+                if (name == "SetPosition")
+                {
+                    //you should check here for types null additional params etc
+                    targetPos = value.at("spinmearound")->getFloat();
+                }
+                else if (name == "SetPositionHalf")
+                {
+                    //you should check here for types null additional params etc
+                    targetPos = value.at("spinmehalfaround")->getFloat() * 2;
+                }
+                else
+                {
+                    ARMARX_ERROR << "CALLED UNKNOWN REMOTE FUNCTION: " << name;
+                }
+            }
+    * \endcode
+    *
+    * The \ref rtRun function sets the \ref ControlTarget1DoFActuatorPosition "ControlTarget" to the
+    * target value set via the atomic and stores the current
+    * \ref SensorValue1DoFActuatorPosition "SensorValue" to the other atomic.
+    * \code{.cpp}
+            void NJointPositionPassThroughController::rtRun(const IceUtil::Time& t, const IceUtil::Time&)
+            {
+                ARMARX_RT_LOGF_ERROR("A MESSAGE PARAMETER %f", t.toSecondsDouble()).deactivateSpam(1);
+                ARMARX_RT_LOGF_IMPORTANT("A MESSAGE WITHOUT PARAMETERS").deactivateSpam(1);
+                target->position = targetPos;
+                currentPos = sensor->position;
+            }
+    * \endcode
+    *
+    * The publish activation \ref onPublishActivation "hook" does nothing, but could be used to call
+    * \ref DebugDraver::setRobotVisu.
+    * \code{.cpp}
+            void NJointPositionPassThroughController::onPublishActivation(const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&)
+            {
+                //we could do some setup for the drawer here. e.g. add a robot
+            }
+
+    * \endcode
+    *
+    * The publish deactivation \ref onPublishDeactivation "hook" clears the \ref DebugDrawer layer
+    * \code{.cpp}
+            void NJointPositionPassThroughController::onPublishDeactivation(const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&)
+            {
+                drawer->removeLayer("Layer_" + getInstanceName());
+            }
+
+    * \endcode
+    *
+    * The publish \ref onPublish "hook" draws a sphere with radius of the position stored in the atomic times 2000 to the \ref DebugDrawer.
+    * \code{.cpp}
+            void NJointPositionPassThroughController::onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx& drawer, const DebugObserverInterfacePrx&)
+            {
+                drawer->setSphereVisu("Layer_" + getInstanceName(), "positionball", new Vector3, armarx::DrawColor {1, 1, 1, 1}, currentPos * 2000);
+            }
+    * \endcode
+    *
+    * This registers a factory for this \ref NJointControllerBase.
+    * This factory is used by the \ref RobotUnit to create the \ref NJointControllerBase.
+    * The passed name has to match the name returned by \ref getClassName.
+    * \code{.cpp}
+            NJointControllerRegistration<NJointPositionPassThroughController> registrationControllerNJointPositionPassThroughController("NJointPositionPassThroughController");
+    * \endcode
+    *
+    * This statically asserts a factory for the type NJointPositionPassThroughController is present.
+    * \code{.cpp}
+            ARMARX_ASSERT_NJOINTCONTROLLER_HAS_CONSTRUCTION_GUI(NJointPositionPassThroughController);
+    * \endcode
+    * Close the namespace
+    * \code{.cpp}
+        }
+    * \endcode
+    */
+    class NJointControllerBase:
+        virtual public NJointControllerInterface,
+        virtual public ManagedIceObject
+    {
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+        // /////////////////////////////////////// typedefs /////////////////////////////////////// //
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+    public:
+        using ConfigPtrT = NJointControllerConfigPtr;
+        using GenerateConfigDescriptionFunctionSignature = WidgetDescription::WidgetPtr(*)
+                (
+                    const VirtualRobot::RobotPtr&,
+                    const std::map<std::string, ConstControlDevicePtr>& controlDevices,
+                    const std::map<std::string, ConstSensorDevicePtr>& sensorDevices
+                );
+        template<class ConfigPrtType>
+        using GenerateConfigFromVariantsFunctionSignature = ConfigPrtType(*)(const StringVariantBaseMap&);
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+        // ///////////////////////////// constructor setup functions ////////////////////////////// //
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+    public:
+        /**
+         * @brief Get a const ptr to the given \ref SensorDevice
+         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
+         * @param deviceName The \ref SensorDevice's name
+         * @return A const ptr to the given \ref SensorDevice
+         */
+        ConstSensorDevicePtr   peekSensorDevice(const std::string& deviceName) const;
+        /**
+         * @brief Get a const ptr to the given \ref ControlDevice
+         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
+         * @param deviceName The \ref ControlDevice's name
+         * @return A const ptr to the given \ref ControlDevice
+         */
+        ConstControlDevicePtr peekControlDevice(const std::string& deviceName) const;
+
+        /**
+         * @brief Declares to calculate the \ref ControlTargetBase "ControlTarget"
+         * for the given \ref ControlDevice in the given ControlMode when \ref rtRun is called
+         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
+         * @param deviceName The \ref ControlDevice's name
+         * @param controlMode The \ref ControlTargetBase "ControlTarget's" ControlMode
+         * @return A ptr to the given \ref ControlDevice's \ref ControlTargetBase "ControlTarget"in the given ControlMode
+         */
+        ControlTargetBase* useControlTarget(const std::string& deviceName, const std::string& controlMode);
+        /**
+         * @brief Declares to calculate the \ref ControlTargetBase "ControlTarget"
+         * for the given \ref ControlDevice in the given ControlMode when \ref rtRun is called
+         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
+         * @param deviceName The \ref ControlDevice's name
+         * @param controlMode The \ref ControlTargetBase "ControlTarget's" ControlMode
+         * @return A ptr to the given \ref ControlDevice's \ref ControlTargetBase "ControlTarget"in the given ControlMode
+         */
+        template<class T>
+        T* useControlTarget(const std::string& deviceName, const std::string& controlMode)
+        {
+            static_assert(std::is_base_of<ControlTargetBase, T>::value,
+                          "The given type does not derive ControlTargetBase");
+            ControlTargetBase* const ptr = useControlTarget(deviceName, controlMode);
+            return dynamic_cast<T*>(ptr);
+        }
+
+        /**
+         * @brief Get a const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
+         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
+         * @param deviceName The \ref SensorDevice's name
+         * @return A const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
+         */
+        const SensorValueBase* useSensorValue(const std::string& sensorDeviceName) const;
+        /**
+         * @brief Get a const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
+         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
+         * @param deviceName The \ref SensorDevice's name
+         * @return A const ptr to the given \ref SensorDevice's \ref SensorValueBase "SensorValue"
+         */
+        template<class T>
+        const T* useSensorValue(const std::string& deviceName) const
+        {
+            static_assert(std::is_base_of<SensorValueBase, T>::value,
+                          "The given type does not derive SensorValueBase");
+            const SensorValueBase* const ptr = useSensorValue(deviceName);
+            return dynamic_cast<const T*>(ptr);
+        }
+
+        /**
+         * @brief Requests a VirtualRobot for use in \ref rtRun
+         *          *
+         * \warning This function can only be called in a \ref NJointControllerBase's ctor (or functions called in it)
+         *
+         * The robot is updated before \ref rtRun is called and can be accessed via \rtGetRobot
+         * @param updateCollisionModel Whether the robot's collision model should be updated
+         * @see rtGetRobot
+         */
+        const VirtualRobot::RobotPtr& useSynchronizedRtRobot(bool updateCollisionModel = false);
+
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+        // ////////////////////////////////// Component interface ///////////////////////////////// //
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+    protected:
+        /// @see Component::getDefaultName
+        std::string getDefaultName() const override
+        {
+            return getClassName();
+        }
+        /// @see Component::onInitComponent
+        void onInitComponent() final;
+        /// @see Component::onConnectComponent
+        void onConnectComponent() final;
+        /// @see Component::onDisconnectComponent
+        void onDisconnectComponent() final;
+        /// @see Component::onExitComponent
+        void onExitComponent() final;
+
+
+        virtual void onInitNJointController() {}
+        virtual void onConnectNJointController() {}
+        virtual void onDisconnectNJointController() {}
+        virtual void onExitNJointController() {}
+
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+        // ////////////////////////////////// ThreadPool functionality///////////////////////////// //
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+    protected:
+        ThreadPoolPtr getThreadPool() const;
+
+        /**
+         * @brief Executes a given task in a separate thread from the Application ThreadPool.
+         * @param taskName Descriptive name of this task to identify it on errors.
+         * @param task std::function object (or lambda) that is to be executed.
+         * @note This task will be joined in onExitComponent of the NJointControllerBase. So make sure it terminates, when the
+         * controller is deactivated or removed!
+         *
+         * @code{.cpp}
+         *  runTask("PlotterTask", [&]
+                {
+                    CycleUtil c(30);
+                    getObjectScheduler()->waitForObjectStateMinimum(eManagedIceObjectStarted);
+                    while (getState() == eManagedIceObjectStarted)
+                    {
+                        if (isControllerActive())
+                        {
+                            StringVariantBaseMap errors;
+                            for (size_t i = 0; i < sensors.size(); i++)
+                            {
+                                errors[cfg->jointNames.at(i)] = new Variant(currentError(i));
+                            }
+                            dbgObs->setDebugChannel("TrajectoryController", errors);
+                        }
+                        c.waitForCycleDuration();
+                    }
+                });
+         * @endcode
+         */
+        template < typename Task >
+        void runTask(const std::string& taskName, Task&& task)
+        {
+            std::unique_lock lock(threadHandlesMutex);
+            ARMARX_CHECK_EXPRESSION(!taskName.empty());
+            ARMARX_CHECK_EXPRESSION(!threadHandles.count(taskName));
+            ARMARX_CHECK_EXPRESSION(getState() < eManagedIceObjectExiting);
+            ARMARX_VERBOSE << "Adding NJointControllerBase task named '" << taskName << "' - current available thread count: " << getThreadPool()->getAvailableTaskCount();
+            auto handlePtr = std::make_shared<ThreadPool::Handle>(getThreadPool()->runTask(task));
+            ARMARX_CHECK_EXPRESSION(handlePtr->isValid()) << "Could not add task (" << taskName << " - " << GetTypeString(task) << " ) - available threads: " << getThreadPool()->getAvailableTaskCount();
+            threadHandles[taskName] = handlePtr;
+        }
+        std::map<std::string, std::shared_ptr<ThreadPool::Handle>> threadHandles;
+        std::mutex threadHandlesMutex;
+
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+        // ///////////////////////////////////// ice interface //////////////////////////////////// //
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+    public:
+        bool isControllerActive(const Ice::Current& = Ice::emptyCurrent) const final override
+        {
+            return isActive;
+        }
+        bool isControllerRequested(const Ice::Current& = Ice::emptyCurrent) const final override
+        {
+            return isRequested;
+        }
+        bool isDeletable(const Ice::Current& = Ice::emptyCurrent) const final override
+        {
+            return deletable;
+        }
+        bool hasControllerError(const Ice::Current& = Ice::emptyCurrent) const final override
+        {
+            return deactivatedBecauseOfError;
+        }
+
+        std::string getClassName(const Ice::Current& = Ice::emptyCurrent) const override  = 0;
+        std::string getInstanceName(const Ice::Current& = Ice::emptyCurrent) const final override
+        {
+            return instanceName_;
+        }
+
+        NJointControllerDescription getControllerDescription(const Ice::Current& = Ice::emptyCurrent) const final override;
+        NJointControllerStatus getControllerStatus(const Ice::Current& = Ice::emptyCurrent) const final override;
+        NJointControllerDescriptionWithStatus getControllerDescriptionWithStatus(const Ice::Current& = Ice::emptyCurrent) const final override;
+        RobotUnitInterfacePrx getRobotUnit(const Ice::Current& = Ice::emptyCurrent) const final override;
+
+        void activateController(const Ice::Current& = Ice::emptyCurrent) final override;
+        void deactivateController(const Ice::Current& = Ice::emptyCurrent) final override;
+        void deleteController(const Ice::Current& = Ice::emptyCurrent) final override;
+        void deactivateAndDeleteController(const Ice::Current& = Ice::emptyCurrent) final override;
+
+        WidgetDescription::StringWidgetDictionary getFunctionDescriptions(const Ice::Current& = Ice::emptyCurrent) const override
+        {
+            return {};
+        }
+        void callDescribedFunction(const std::string&, const StringVariantBaseMap&, const Ice::Current& = Ice::emptyCurrent) override
+        {
+
+        }
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+        // ///////////////////////////////////// rt interface ///////////////////////////////////// //
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+    public: ///TODO make protected and use attorneys
+
+        /**
+         * @brief Returns the virtual robot used by this \ref NJointControllerBase in the \ref rtRun
+         * @return The virtual robot used by this \ref NJointControllerBase in the \ref rtRun
+         * @see useSynchronizedRtRobot
+         * @see rtGetRobotNodes
+         */
+        const VirtualRobot::RobotPtr& rtGetRobot()
+        {
+            return rtRobot;
+        }
+        /**
+         * @brief Returns the nodes of the virtual robot used by this \ref NJointControllerBase in the \ref rtRun
+         * @return The nodes of the virtual robot used by this \ref NJointControllerBase in the \ref rtRun
+         * @see useSynchronizedRtRobot
+         * @see rtGetRobot
+         */
+        const std::vector<VirtualRobot::RobotNodePtr>& rtGetRobotNodes()
+        {
+            return rtRobotNodes;
+        }
+        /**
+         * @brief Returns whether this \ref NJointControllerBase calculates a \ref ControlTargetBase "ControlTarget"
+         * for the given \ref ControlDevice
+         * @param deviceIndex The \ref ControlDevice's index
+         * @return Whether this \ref NJointControllerBase calculates a \ref ControlTargetBase "ControlTarget"
+         * for the given \ref ControlDevice
+         */
+        bool rtUsesControlDevice(std::size_t deviceIndex) const
+        {
+            return controlDeviceUsedBitmap.at(deviceIndex);
+        }
+
+        /**
+         * @brief Returns the indices of all \ref ControlDevice's this \ref NJointControllerBase
+         * calculates a \ref ControlTargetBase "ControlTarget" for.
+         * @return The indices of all \ref ControlDevice's this \ref NJointControllerBase
+         * calculates a \ref ControlTargetBase "ControlTarget" for.
+         */
+        const std::vector<std::size_t>& rtGetControlDeviceUsedIndices() const
+        {
+            return controlDeviceUsedIndices;
+        }
+
+        /**
+         * @brief Sets the error state to true. This will deactivate this controller!
+         */
+        bool rtGetErrorState() const
+        {
+            return errorState;
+        }
+
+        /**
+         * @brief Returns the number of used \ref ControlDevice "ControlDevices"
+         * @return The number of used \ref ControlDevice "ControlDevices"
+         */
+        std::size_t rtGetNumberOfUsedControlDevices() const
+        {
+            return controlDeviceUsedIndices.size();
+        }
+
+        /**
+         * @brief Returns the class name. (the c-string may be used for rt message logging)
+         * @return The class name. (the c-string may be used for rt message logging)
+         */
+        const std::string& rtGetClassName() const
+        {
+            return rtClassName_;
+        }
+
+        /**
+         * @brief Returns the instance name. (the c-string may be used for rt message logging)
+         * @return The instance name. (the c-string may be used for rt message logging)
+         */
+        const std::string& rtGetInstanceName() const
+        {
+            return instanceName_;
+        }
+
+    protected:
+        /**
+         * @brief This function is called before the controller is activated.
+         * You can use it to activate a thread again (DO NOT SPAWN NEW THREADS!) e.g. via a std::atomic_bool.
+         */
+        virtual void rtPreActivateController() {}
+        /**
+         * @brief This function is called after the controller is deactivated.
+         * You can use it to deactivate a thread (DO NOT JOIN THREADS!) e.g. via a std::atomic_bool.
+         */
+        virtual void rtPostDeactivateController() {}
+
+        /**
+         * @brief Sets the error state to true. This will deactivate this controller!
+         */
+        void rtSetErrorState()
+        {
+            errorState.store(true);
+        }
+    private:
+        /**
+         * @brief Activates this controller in the \ref RobotUnitModules::ControlThread "ControlThread".
+         *
+         * Calls \ref rtPreActivateController
+         * @see rtDeactivateController
+         * @see rtDeactivateControllerBecauseOfError
+         * @see rtPreActivateController
+         */
+        void rtActivateController();
+        /**
+         * @brief Deactivates this controller in the \ref RobotUnitModules::ControlThread "ControlThread".
+         *
+         * Calls \ref rtPostDeactivateController
+         * @see rtActivateController
+         * @see rtDeactivateControllerBecauseOfError
+         * @see rtPostDeactivateController
+         */
+        void rtDeactivateController();
+        /**
+         * @brief Deactivates this controller in the \ref RobotUnitModules::ControlThread "ControlThread"
+         * and sets the error flag.
+         *
+         * Calls \ref rtPostDeactivateController
+         * This function is called when this \ref NJointControllerBase produces an error
+         * (e.g.: calculates an invalid \ref ControlTargetBase "ControlTarget", throws an exception)
+         * @see rtActivateController
+         * @see rtDeactivateController
+         * @see rtPostDeactivateController
+         */
+        void rtDeactivateControllerBecauseOfError();
+
+    public:
+
+        static const NJointControllerBasePtr NullPtr;
+
+        NJointControllerBase();
+
+        ~NJointControllerBase() override;
+        //ice interface (must not be called in the rt thread)
+
+        //c++ interface (local calls) (must be called in the rt thread)
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+        // ///////////////////////////////////// used targets ///////////////////////////////////// //
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+    public:
+        //used control devices
+        StringStringDictionary getControlDeviceUsedControlModeMap(const Ice::Current& = Ice::emptyCurrent) const final override
+        {
+            return controlDeviceControlModeMap;
+        }
+        const std::vector<char>& getControlDeviceUsedBitmap() const
+        {
+            return controlDeviceUsedBitmap;
+        }
+        const std::vector<std::size_t>& getControlDeviceUsedIndices() const
+        {
+            return controlDeviceUsedIndices;
+        }
+
+        const std::map<std::string, const JointController*>& getControlDevicesUsedJointController()
+        {
+            return controlDeviceUsedJointController;
+        }
+
+        //check for conflict
+        std::optional<std::vector<char>> isNotInConflictWith(const NJointControllerBasePtr& other) const
+        {
+            return isNotInConflictWith(other->getControlDeviceUsedBitmap());
+        }
+        std::optional<std::vector<char>> isNotInConflictWith(const std::vector<char>& used) const;
+
+        template<class ItT>
+        static std::optional<std::vector<char>> AreNotInConflict(ItT first, ItT last)
+        {
+            if (first == last)
+            {
+                return std::vector<char>{};
+            }
+            std::size_t n = (*first)->getControlDeviceUsedBitmap().size();
+            std::vector<char> inuse(n, false);
+            while (first != last)
+            {
+                auto r = (*first)->isNotInConflictWith(inuse);
+                if (!r)
+                {
+                    return r;
+                }
+                inuse = std::move(*r);
+                ++first;
+            }
+            return inuse;
+        }
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+        // ////////////////////////////////////// publishing ////////////////////////////////////// //
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+    protected:
+        //publish thread hooks
+        virtual void onPublishActivation(const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&) {}
+        virtual void onPublishDeactivation(const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&) {}
+        virtual void onPublish(const SensorAndControl&, const DebugDrawerInterfacePrx&, const DebugObserverInterfacePrx&) {}
+    private:
+        void publish(const SensorAndControl& sac, const DebugDrawerInterfacePrx& draw, const DebugObserverInterfacePrx& observer);
+        void deactivatePublish(const DebugDrawerInterfacePrx& draw, const DebugObserverInterfacePrx& observer);
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+        // ///////////////////////////////////////// data ///////////////////////////////////////// //
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+    private:
+        /// @brief reference to the owning \ref RobotUnit
+        RobotUnit& robotUnit;
+        /// @brief Maps names of used \ref ControlDevice "ControlDevices" to the \ref JointController "JointController's" control mode
+        StringStringDictionary controlDeviceControlModeMap;
+        /// @brief Maps names of used \ref ControlDevice "ControlDevices" to the used \ref JointController for this \ref ControlDevice
+        std::map<std::string, const JointController*> controlDeviceUsedJointController;
+        /// @brief Bitmap of used \ref ControlDevice "ControlDevices" (1 == used, 0 == not used)
+        std::vector<char> controlDeviceUsedBitmap;
+        /// @brief Indices of used \ref ControlDevice "ControlDevices"
+        std::vector<std::size_t> controlDeviceUsedIndices;
+
+        std::string rtClassName_;
+        std::string instanceName_;
+
+        //this data is filled by the robot unit to provide convenience functions
+        std::atomic_bool isActive {false};
+        std::atomic_bool isRequested {false};
+        std::atomic_bool deactivatedBecauseOfError {false};
+        std::atomic_bool errorState {false};
+        bool deletable {false};
+        bool internal {false};
+
+        std::atomic_bool publishActive {false};
+
+        std::atomic_bool statusReportedActive {false};
+        std::atomic_bool statusReportedRequested {false};
+
+        VirtualRobot::RobotPtr rtRobot;
+        std::vector<VirtualRobot::RobotNodePtr> rtRobotNodes;
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+        // /////////////////////////////////////// friends //////////////////////////////////////// //
+        // //////////////////////////////////////////////////////////////////////////////////////// //
+    private:
+        /**
+        * \brief This class allows minimal access to private members of \ref NJointControllerBase in a sane fashion for \ref RobotUnitModule::ControllerManagement.
+        * \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 !!
+        */
+        friend class RobotUnitModule::NJointControllerAttorneyForControllerManagement;
+        /**
+        * \brief This class allows minimal access to private members of \ref NJointControllerBase in a sane fashion for \ref RobotUnitModule::ControlThread.
+        * \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 !!
+        */
+        friend class RobotUnitModule::NJointControllerAttorneyForControlThread;
+        /**
+        * \brief This class allows minimal access to private members of \ref NJointControllerBase in a sane fashion for \ref RobotUnitModule::Publisher.
+        * \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 !!
+        */
+        friend class RobotUnitModule::NJointControllerAttorneyForPublisher;
+        /**
+        * \brief This is required for the factory
+        * \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 !!
+        */
+        template<class> friend class detail::NJointControllerRegistryEntryHelper;
+    };
+
+    class SynchronousNJointController : public NJointControllerBase
+    {
+    public: ///TODO make protected and use attorneys
+        virtual void rtRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) = 0;
+        virtual void rtSwapBufferAndRun(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration)
+        {
+            rtRun(sensorValuesTimestamp, timeSinceLastIteration);
+        }
+    };
+    class AsynchronousNJointController : public NJointControllerBase
+    {
+    public: ///TODO make protected and use attorneys
+        virtual void rtRunIterationBegin(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) = 0;
+        virtual void rtRunIterationEnd(const IceUtil::Time& sensorValuesTimestamp, const IceUtil::Time& timeSinceLastIteration) = 0;
+    };
+    using NJointController = SynchronousNJointController;
+    using NJointControllerPtr = SynchronousNJointControllerPtr;
+}
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h
new file mode 100644
index 0000000000000000000000000000000000000000..9a5454ee5b50e911395703c407a8139878c86f86
--- /dev/null
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h
@@ -0,0 +1,245 @@
+/*
+ * This file is part of ArmarX.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @package    RobotAPI::ArmarXObjects::NJointController
+ * @author     Raphael Grimm ( raphael dot grimm at kit dot edu )
+ * @date       2017
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+
+#pragma once
+
+#include "NJointControllerBase.h"
+
+#include <ArmarXCore/core/util/OnScopeExit.h>
+#include <ArmarXCore/core/util/TemplateMetaProgramming.h>
+#include <ArmarXCore/core/util/Registrar.h>
+
+namespace armarx::RobotUnitModule
+{
+    class ControllerManagement;
+}
+
+namespace armarx
+{
+    RobotUnit* getRobotUnit(RobotUnitModule::ControllerManagement* cmgr);
+
+    class NJointControllerRegistryEntry
+    {
+    private:
+        friend class RobotUnitModule::ControllerManagement;
+        virtual NJointControllerBasePtr create(RobotUnitModule::ControllerManagement* cmngr,
+                                               const NJointControllerConfigPtr&,
+                                               const VirtualRobot::RobotPtr&,
+                                               bool deletable,
+                                               bool internal,
+                                               const std::string& instanceName) const = 0;
+        virtual WidgetDescription::WidgetPtr
+        GenerateConfigDescription(const VirtualRobot::RobotPtr&,
+                                  const std::map<std::string, ConstControlDevicePtr>&,
+                                  const std::map<std::string, ConstSensorDevicePtr>&) const = 0;
+        virtual NJointControllerConfigPtr
+        GenerateConfigFromVariants(const StringVariantBaseMap&) const = 0;
+        virtual bool hasRemoteConfiguration() const = 0;
+
+    protected:
+        static thread_local bool ConstructorIsRunning_;
+
+    public:
+        virtual ~NJointControllerRegistryEntry() = default;
+        static bool
+        ConstructorIsRunning()
+        {
+            return ConstructorIsRunning_;
+        }
+    };
+    using NJointControllerRegistry = Registrar<std::unique_ptr<NJointControllerRegistryEntry>>;
+
+    template <class ControllerType>
+    struct NJointControllerRegistration;
+
+    namespace detail
+    {
+        ARMARX_META_MAKE_HAS_MEMBER_FNC_CHECK(
+            hasGenerateConfigDescription,
+            GenerateConfigDescription,
+            NJointControllerBase::GenerateConfigDescriptionFunctionSignature);
+        ARMARX_META_MAKE_HAS_MEMBER_FNC_CHECK(
+            hasGenerateConfigFromVariants,
+            GenerateConfigFromVariants,
+            NJointControllerBase::GenerateConfigFromVariantsFunctionSignature<typename T::ConfigPtrT>);
+
+        template <class NJointControllerT>
+        class NJointControllerRegistryEntryHelper : public NJointControllerRegistryEntry
+        {
+            static_assert(hasGenerateConfigDescription<NJointControllerT>::value ==
+                              hasGenerateConfigFromVariants<NJointControllerT>::value,
+                          "Either overload both GenerateConfigDescription and "
+                          "GenerateConfigFromVariants, or none!");
+            static constexpr bool hasRemoteConfiguration_ =
+                hasGenerateConfigDescription<NJointControllerT>::value;
+
+            NJointControllerBasePtr
+            create(RobotUnitModule::ControllerManagement* cmngr,
+                   const NJointControllerConfigPtr& config,
+                   const VirtualRobot::RobotPtr& rob,
+                   bool deletable,
+                   bool internal,
+                   const std::string& instanceName) const final override
+            {
+                ARMARX_CHECK_EXPRESSION(cmngr) << "ControllerManagement module is NULL!";
+
+                using ConfigPtrT = typename NJointControllerT::ConfigPtrT;
+                ConfigPtrT cfg = ConfigPtrT::dynamicCast(config);
+                ARMARX_CHECK_EXPRESSION(cfg)
+                    << "The configuration is of the wrong type! it has to be an instance of: "
+                    << GetTypeString<ConfigPtrT>();
+
+                ARMARX_CHECK_EXPRESSION(!ConstructorIsRunning())
+                    << "Two NJointControllers are created at the same time";
+                NJointControllerBasePtr ptr;
+                {
+                    ConstructorIsRunning_ = true;
+                    ARMARX_ON_SCOPE_EXIT
+                    {
+                        ConstructorIsRunning_ = false;
+                    };
+                    ptr = new NJointControllerT(getRobotUnit(cmngr), cfg, rob);
+                }
+                ptr->deletable = deletable;
+                ptr->internal = internal;
+                ptr->rtClassName_ = ptr->getClassName(Ice::emptyCurrent);
+                ptr->instanceName_ = instanceName;
+                return ptr;
+            }
+
+            WidgetDescription::WidgetPtr
+            GenerateConfigDescription(
+                const VirtualRobot::RobotPtr& robot,
+                const std::map<std::string, ConstControlDevicePtr>& controlDevices,
+                const std::map<std::string, ConstSensorDevicePtr>& sensorDevices) const final override
+            {
+                if constexpr (hasRemoteConfiguration_)
+                {
+                    try
+                    {
+                        return NJointControllerT::GenerateConfigDescription(
+                            robot, controlDevices, sensorDevices);
+                    }
+                    catch (Ice::UserException& e)
+                    {
+                        ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
+                                     << "::GenerateConfigDescription'"
+                                     << "\n---- file = " << e.ice_file()
+                                     << "\n---- line = " << e.ice_line()
+                                     << "\n---- id   = " << e.ice_id() << "\n---- what:\n"
+                                     << e.what() << "\n---- stacktrace:\n"
+                                     << e.ice_stackTrace();
+                        throw;
+                    }
+                    catch (std::exception& e)
+                    {
+                        ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
+                                     << "::GenerateConfigDescription'"
+                                     << "\n---- what:\n"
+                                     << e.what();
+                        throw;
+                    }
+                    catch (...)
+                    {
+                        ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
+                                     << "::GenerateConfigDescription'";
+                        throw;
+                    }
+                }
+                else
+                {
+                    ARMARX_CHECK_EXPRESSION(!"This function should never be called");
+                }
+            }
+
+            NJointControllerConfigPtr
+            GenerateConfigFromVariants(const StringVariantBaseMap& variants) const final override
+            {
+                if constexpr (hasRemoteConfiguration_)
+                {
+                    try
+                    {
+                        return NJointControllerT::GenerateConfigFromVariants(variants);
+                    }
+                    catch (Ice::UserException& e)
+                    {
+                        ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
+                                     << "::GenerateConfigFromVariants'"
+                                     << "\n---- file = " << e.ice_file()
+                                     << "\n---- line = " << e.ice_line()
+                                     << "\n---- id   = " << e.ice_id() << "\n---- what:\n"
+                                     << e.what() << "\n---- stacktrace:\n"
+                                     << e.ice_stackTrace();
+                        throw;
+                    }
+                    catch (std::exception& e)
+                    {
+                        ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
+                                     << "::GenerateConfigFromVariants'"
+                                     << "\n---- what:\n"
+                                     << e.what();
+                        throw;
+                    }
+                    catch (...)
+                    {
+                        ARMARX_ERROR << "Exception calling '" << GetTypeString<NJointControllerT>()
+                                     << "::GenerateConfigFromVariants'";
+                        throw;
+                    }
+                }
+                else
+                {
+                    ARMARX_CHECK_EXPRESSION(!"This function should never be called");
+                }
+            }
+
+            bool
+            hasRemoteConfiguration() const final override
+            {
+                return hasRemoteConfiguration_;
+            }
+        };
+    } // namespace detail
+
+    using NJointControllerRegistry = Registrar<std::unique_ptr<NJointControllerRegistryEntry>>;
+    template <class ControllerType>
+    struct NJointControllerRegistration
+    {
+        NJointControllerRegistration(const std::string& name)
+        {
+            NJointControllerRegistry::registerElement(
+                name,
+                std::unique_ptr<NJointControllerRegistryEntry>(
+                    new detail::NJointControllerRegistryEntryHelper<ControllerType>));
+        }
+    };
+} // namespace armarx
+
+#define ARMARX_ASSERT_NJOINTCONTROLLER_HAS_CONSTRUCTION_GUI(T)                                     \
+    static_assert(                                                                                 \
+        ::armarx::detail::hasGenerateConfigDescription<T>::value,                                  \
+        #T " does not offer a construction gui (missing: static GenerateConfigDescription)");      \
+    static_assert(                                                                                 \
+        ::armarx::detail::hasGenerateConfigFromVariants<T>::value,                                 \
+        #T " does not offer a construction gui (missing: static GenerateConfigFromVariants)")
+
+
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerWithTripleBuffer.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerWithTripleBuffer.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd6befc54b45193149ce7106be84fb644599a8cf
--- /dev/null
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerWithTripleBuffer.h
@@ -0,0 +1,75 @@
+#pragma once
+
+#include "NJointControllerBase.h"
+
+#include <ArmarXCore/util/CPPUtility/TripleBuffer.h>
+
+
+namespace armarx
+{
+    template <typename ControlDataStruct>
+    class NJointControllerWithTripleBuffer : public SynchronousNJointController
+    {
+    public:
+        using MutexType = std::recursive_mutex;
+        using LockGuardType = std::lock_guard<std::recursive_mutex>;
+
+        NJointControllerWithTripleBuffer(
+                const ControlDataStruct& initialCommands = ControlDataStruct()) :
+            controlDataTripleBuffer{initialCommands}
+        {
+        }
+
+        void rtSwapBufferAndRun(const IceUtil::Time& sensorValuesTimestamp,
+                                const IceUtil::Time& timeSinceLastIteration) override
+        {
+            rtUpdateControlStruct();
+            rtRun(sensorValuesTimestamp, timeSinceLastIteration);
+        }
+
+    protected:
+        const ControlDataStruct& rtGetControlStruct() const
+        {
+            return controlDataTripleBuffer.getReadBuffer();
+        }
+        bool rtUpdateControlStruct()
+        {
+            return controlDataTripleBuffer.updateReadBuffer();
+        }
+
+        void writeControlStruct()
+        {
+            //just lock to be save and reduce the impact of an error
+            //also this allows code to unlock the mutex before calling this function
+            //(can happen if some lockguard in a scope is used)
+            LockGuardType lock(controlDataMutex);
+            controlDataTripleBuffer.commitWrite();
+        }
+        ControlDataStruct& getWriterControlStruct()
+        {
+            return controlDataTripleBuffer.getWriteBuffer();
+        }
+
+        void setControlStruct(const ControlDataStruct& newStruct)
+        {
+            LockGuardType lock{controlDataMutex};
+            getWriterControlStruct() = newStruct;
+            writeControlStruct();
+        }
+
+        void reinitTripleBuffer(const ControlDataStruct& initial)
+        {
+            controlDataTripleBuffer.reinitAllBuffers(initial);
+        }
+
+        mutable MutexType controlDataMutex;
+
+    private:
+        WriteBufferedTripleBuffer<ControlDataStruct> controlDataTripleBuffer;
+    };
+
+    template <typename ControlDataStruct>
+    using NJointControllerWithTripleBufferPtr =
+    IceInternal::Handle<NJointControllerWithTripleBuffer<ControlDataStruct>>;
+
+} // namespace armarx
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.cpp
index 06513b41621db1af829262b95c79c6c4634276ec..ee21ebea9ae3ba743bbea9e25f5725c4c7959042 100755
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.cpp
@@ -23,9 +23,10 @@
  */
 #include "NJointHolonomicPlatformGlobalPositionController.h"
 
-#include <cmath>
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
 
 #include <SimoxUtility/math/periodic/periodic_clamp.h>
+#include <cmath>
 
 namespace armarx
 {
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.h
index bf4d338d0e642a870c91fe86772d64371e65f1ce..d8f6cc66e62d2287b3de297f80bb2b5b2067a04d 100755
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformGlobalPositionController.h
@@ -30,7 +30,7 @@
 
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
-#include "NJointController.h"
+#include "NJointControllerWithTripleBuffer.h"
 #include "../RobotUnit.h"
 #include "../SensorValues/SensorValueHolonomicPlatform.h"
 
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.cpp
index f5ca656188153d623bd57dee0640c6f842b03e84..7324764d1666cb0210b26deb3a2d4c6141df3c70 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.cpp
@@ -23,6 +23,8 @@
  */
 #include "NJointHolonomicPlatformRelativePositionController.h"
 
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+
 namespace armarx
 {
     NJointControllerRegistration<NJointHolonomicPlatformRelativePositionController>
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.h
index abbd25d999ae85f7ba500e49f13479d0a4688700..54f2a8e7f560efe74dfe53bfdb98625be9217e91 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformRelativePositionController.h
@@ -30,7 +30,7 @@
 
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
-#include "NJointController.h"
+#include "NJointControllerWithTripleBuffer.h"
 #include "../RobotUnit.h"
 #include "../SensorValues/SensorValueHolonomicPlatform.h"
 
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformUnitVelocityPassThroughController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformUnitVelocityPassThroughController.cpp
index 35fd7551d0f4dfd9b33de0b2cac71ee427ef5f35..fa4b4ad337ed17d35b464a6485ecf45c81f63960 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformUnitVelocityPassThroughController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformUnitVelocityPassThroughController.cpp
@@ -22,12 +22,14 @@
 
 #include "NJointHolonomicPlatformUnitVelocityPassThroughController.h"
 
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
 namespace armarx
 {
     NJointHolonomicPlatformUnitVelocityPassThroughController::NJointHolonomicPlatformUnitVelocityPassThroughController(
-        RobotUnitPtr prov,
+        RobotUnit* prov,
         NJointHolonomicPlatformUnitVelocityPassThroughControllerConfigPtr
         cfg, const VirtualRobot::RobotPtr&) :
         maxCommandDelay(IceUtil::Time::milliSeconds(500))
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformUnitVelocityPassThroughController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformUnitVelocityPassThroughController.h
index 3c793d040a30b463b4419a3f168d389fa03b2f83..e2c4a3aa4146a573c7fe4e92239272fd02d0372c 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformUnitVelocityPassThroughController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointHolonomicPlatformUnitVelocityPassThroughController.h
@@ -24,7 +24,7 @@
 
 #include <VirtualRobot/Robot.h>
 
-#include "NJointController.h"
+#include "NJointControllerWithTripleBuffer.h"
 #include "../ControlTargets/ControlTargetHolonomicPlatformVelocity.h"
 #include "../util.h"
 
@@ -63,7 +63,7 @@ namespace armarx
         using ConfigPtrT = NJointHolonomicPlatformUnitVelocityPassThroughControllerConfigPtr;
 
         NJointHolonomicPlatformUnitVelocityPassThroughController(
-            RobotUnitPtr prov,
+            RobotUnit* prov,
             NJointHolonomicPlatformUnitVelocityPassThroughControllerConfigPtr config,
             const VirtualRobot::RobotPtr&);
 
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKinematicUnitPassThroughController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKinematicUnitPassThroughController.cpp
index fab7cb647930e4ea2fa71c6ad14c52927e43139c..f85806eda4386d35940f9f850055241c7dd4bab3 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKinematicUnitPassThroughController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKinematicUnitPassThroughController.cpp
@@ -21,6 +21,9 @@
  */
 
 #include "NJointKinematicUnitPassThroughController.h"
+
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+
 namespace armarx
 {
     NJointControllerRegistration<NJointKinematicUnitPassThroughController> registrationControllerNJointKinematicUnitPassThroughController("NJointKinematicUnitPassThroughController");
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKinematicUnitPassThroughController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKinematicUnitPassThroughController.h
index a0fe164c4803ceb322c451b464c0c6acdc48bebf..43f520fae9d83e81ff82172ba7b66af956bbb446 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKinematicUnitPassThroughController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointKinematicUnitPassThroughController.h
@@ -28,7 +28,7 @@
 
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
-#include "NJointController.h"
+#include "NJointControllerBase.h"
 #include "../RobotUnit.h"
 #include "../SensorValues/SensorValue1DoFActuator.h"
 
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTCPController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTCPController.cpp
index c67b41d1985b7bcfc2f9404a09878424302da9a3..2f8fdd4341220145814a5af671061e59175e83e1 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTCPController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTCPController.cpp
@@ -22,9 +22,13 @@
  *             GNU General Public License
  */
 #include "NJointTCPController.h"
-#include <VirtualRobot/RobotNodeSet.h>
 #include "../RobotUnit.h"
 
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+
+#include <VirtualRobot/RobotNodeSet.h>
+
+
 #define DEFAULT_TCP_STRING "default TCP"
 
 namespace armarx
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTCPController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTCPController.h
index 57d2f88812ca75e364ae18f3360bda90063e93c4..43f4246c5a0280e8aa4f5f29d7be1572bab080c2 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTCPController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTCPController.h
@@ -24,7 +24,7 @@
 #pragma once
 
 
-#include "NJointController.h"
+#include "NJointControllerWithTripleBuffer.h"
 #include <VirtualRobot/Robot.h>
 #include "../RobotUnit.h"
 #include "../ControlTargets/ControlTarget1DoFActuator.h"
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTaskSpaceImpedanceController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTaskSpaceImpedanceController.cpp
index d2d10aee0d547b4341c343d368e9c518de86b501..124d66adbc8b24f176cdb7d6acf5df4d3815eccc 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTaskSpaceImpedanceController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTaskSpaceImpedanceController.cpp
@@ -22,6 +22,8 @@
 
 #include "NJointTaskSpaceImpedanceController.h"
 
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+
 #include <SimoxUtility/math/convert/mat4f_to_pos.h>
 #include <SimoxUtility/math/convert/mat4f_to_quat.h>
 
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTaskSpaceImpedanceController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTaskSpaceImpedanceController.h
index f23c8a04945858b9efdb071f1c5215b719073be0..06d725f856583029d4c99a781b4832a3ee4f3c80 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTaskSpaceImpedanceController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTaskSpaceImpedanceController.h
@@ -22,7 +22,7 @@
 
 #pragma once
 
-#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointController.h>
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerWithTripleBuffer.h>
 #include <VirtualRobot/Robot.h>
 #include <RobotAPI/components/units/RobotUnit/RobotUnit.h>
 #include <RobotAPI/components/units/RobotUnit/ControlTargets/ControlTarget1DoFActuator.h>
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.cpp b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.cpp
index fa0c743d77a225270c44e767c7e1b0843c7601e3..297841f70b8f67c56b7bb86cd54486301d30b23c 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.cpp
@@ -1,13 +1,18 @@
 #include "NJointTrajectoryController.h"
+
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+#include <RobotAPI/components/units/RobotUnit/util/RtLogging.h>
+#include <RobotAPI/libraries/core/math/MathUtils.h>
+
 #include <ArmarXCore/core/time/TimeUtil.h>
+
 #include <VirtualRobot/TimeOptimalTrajectory/TimeOptimalTrajectory.h>
-#include <RobotAPI/libraries/core/math/MathUtils.h>
-#include <RobotAPI/components/units/RobotUnit/util/RtLogging.h>
+
 namespace armarx
 {
     NJointControllerRegistration<NJointTrajectoryController> registrationControllerNJointTrajectoryController("NJointTrajectoryController");
 
-    NJointTrajectoryController::NJointTrajectoryController(RobotUnitPtr prov, const NJointControllerConfigPtr& config, const VirtualRobot::RobotPtr& robot)
+    NJointTrajectoryController::NJointTrajectoryController(RobotUnit* prov, const NJointControllerConfigPtr& config, const VirtualRobot::RobotPtr& robot)
     {
         cfg = NJointTrajectoryControllerConfigPtr::dynamicCast(config);
         ARMARX_CHECK_EXPRESSION(cfg) << "Needed type: NJointTrajectoryControllerConfigPtr";
diff --git a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.h b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.h
index 560f33100464eb9e2994069059f0262925579e88..060c918b8238d94c89315f0176ee84d6ceef8c22 100644
--- a/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.h
+++ b/source/RobotAPI/components/units/RobotUnit/NJointControllers/NJointTrajectoryController.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "NJointController.h"
+#include "NJointControllerWithTripleBuffer.h"
 #include <VirtualRobot/Robot.h>
 #include <RobotAPI/interface/units/RobotUnit/NJointTrajectoryController.h>
 #include <RobotAPI/libraries/core/TrajectoryController.h>
@@ -28,7 +28,7 @@ namespace armarx
         public NJointTrajectoryControllerInterface
     {
     public:
-        NJointTrajectoryController(RobotUnitPtr prov, const NJointControllerConfigPtr& config, const VirtualRobot::RobotPtr&);
+        NJointTrajectoryController(RobotUnit* prov, const NJointControllerConfigPtr& config, const VirtualRobot::RobotPtr&);
 
         // NJointControllerInterface interface
         std::string getClassName(const Ice::Current&) const override;
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnit.h b/source/RobotAPI/components/units/RobotUnit/RobotUnit.h
index dc96e422a047fcdfcc5ebe97d14885191e28b857..6024c0dbbf0a48509afc455922a1dab9ec8103d0 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnit.h
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnit.h
@@ -23,7 +23,7 @@
 #pragma once
 
 #include "RobotUnitModules/RobotUnitModules.h"
-#include "NJointControllers/NJointController.h"
+//#include "NJointControllers/NJointControllerBase.h"
 
 /**
 * @defgroup Library-RobotUnit RobotUnit
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleBase.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleBase.cpp
index 557f293e3ccb818d63e4fa1918664306c60ac61f..90910c9f28b246abac25b5b15f0c609bdf33fe3e 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleBase.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleBase.cpp
@@ -26,7 +26,6 @@
 #include <ArmarXCore/core/util/Preprocessor.h>
 #include <ArmarXCore/util/CPPUtility/trace.h>
 
-#include "../NJointControllers/NJointController.h"
 #include "RobotUnitModuleBase.h"
 #include "RobotUnitModules.h"
 
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControlThread.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControlThread.cpp
index 6b251b9cbaa0db977e102580deeb17b4b0d2165e..a3269b4d0e11cb792f639e4c477218dcb58183e8 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControlThread.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControlThread.cpp
@@ -29,9 +29,15 @@
 #include <ArmarXCore/observers/filters/rtfilters/AverageFilter.h>
 #include <ArmarXCore/observers/filters/rtfilters/ButterworthFilter.h>
 #include <RobotAPI/components/units/RobotUnit/util/DynamicsHelper.h>
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerBase.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControlThreadDataBuffer.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleRobotData.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleUnits.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleManagement.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnit.h>
 
 #include "../Devices/RTThreadTimingsSensorDevice.h"
-#include "../NJointControllers/NJointController.h"
 
 namespace armarx::RobotUnitModule
 {
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControllerManagement.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControllerManagement.cpp
index f03a527d7a2b87c5c5752e2f16cdaa0baaee13c4..871d8427eb59e673ec1070c7aafda9fdcad2c2b9 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControllerManagement.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControllerManagement.cpp
@@ -20,11 +20,20 @@
  *             GNU General Public License
  */
 
-#include <ArmarXCore/core/util/OnScopeExit.h>
-#include <ArmarXCore/util/CPPUtility/trace.h>
 
 #include "RobotUnitModuleControllerManagement.h"
-#include "../NJointControllers/NJointController.h"
+
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerBase.h>
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
+
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControlThreadDataBuffer.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleRobotData.h>
+
+#include <ArmarXCore/core/ArmarXManager.h>
+#include <ArmarXCore/core/util/OnScopeExit.h>
+#include <ArmarXCore/util/CPPUtility/trace.h>
 
 namespace armarx::RobotUnitModule
 {
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.cpp
index 4c6de078b00ae810a846c68e829a3da136a6ed79..4e38d6ab344958c06fa6775f2ac24843ceb55a6a 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModulePublisher.cpp
@@ -22,8 +22,14 @@
 
 #include "RobotUnitModulePublisher.h"
 
-#include "../NJointControllers/NJointController.h"
-#include "../Units/RobotUnitSubUnit.h"
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerBase.h>
+#include <RobotAPI/components/units/RobotUnit/Units/RobotUnitSubUnit.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleUnits.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControllerManagement.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControlThread.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControlThreadDataBuffer.h>
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerRegistry.h>
 
 #include <ArmarXCore/core/ArmarXObjectScheduler.h>
 
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleSelfCollisionChecker.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleSelfCollisionChecker.cpp
index a9d2e8de69625147071a2e2aaa650d43de40cdb9..09b19d38a9ede50f8e7f167aad5aee2681bf30e3 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleSelfCollisionChecker.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleSelfCollisionChecker.cpp
@@ -26,8 +26,12 @@
 
 #include "RobotUnitModuleSelfCollisionChecker.h"
 #include "RobotUnitModuleRobotData.h"
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControlThreadDataBuffer.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleControlThread.h>
+#include <RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleUnits.h>
 
-#include "../NJointControllers/NJointController.h"
+#include <RobotAPI/components/units/RobotUnit/NJointControllers/NJointControllerBase.h>
+#include <ArmarXCore/core/util/OnScopeExit.h>
 
 #include <SimoxUtility/algorithm/string/string_tools.h>