diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.cpp
index fa21a0fcecea44d404c180fc373fc9f1708d9605..61622e70524f2cc8285aa131ace437f80ce6aab9 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.cpp
@@ -35,6 +35,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             if (!controlDevices.has(name))
             {
                 std::stringstream ss;
@@ -52,12 +53,14 @@ namespace armarx
             {
                 return {};
             }
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             ControlDeviceDescriptionSeq r;
             r.reserve(getNumberOfControlDevices());
             for (auto idx : getIndices(controlDevices.values()))
             {
                 r.emplace_back(getControlDeviceDescription(idx));
             }
+            throwIfDevicesNotReady(__FUNCTION__);
             return r;
         }
 
@@ -65,6 +68,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             return controlDevices.size();
         }
 
@@ -72,6 +76,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {sensorDevicesMutex};
             return sensorDevices.size();
         }
 
@@ -79,6 +84,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {sensorDevicesMutex};
             ARMARX_CHECK_EXPRESSION(sensorDevices.has(deviceName));
             return sensorDevices.index(deviceName);
         }
@@ -86,6 +92,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             ARMARX_CHECK_EXPRESSION(controlDevices.has(deviceName));
             return controlDevices.index(deviceName);
         }
@@ -94,6 +101,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {sensorDevicesMutex};
             return sensorDevices.at(sensorDeviceName, SensorDevice::NullPtr);
         }
 
@@ -101,6 +109,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             return controlDevices.at(deviceName, ControlDevice::NullPtr);
         }
 
@@ -108,6 +117,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             return controlDevices.keys();
         }
 
@@ -115,6 +125,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             const ControlDevicePtr& controlDevice = controlDevices.at(idx);
             ControlDeviceDescription data;
             data.deviceName = controlDevice->getDeviceName();
@@ -124,13 +135,14 @@ namespace armarx
                 data.contolModeToTargetType[jointCtrl->getControlMode()].targetType = jointCtrl->getControlTarget()->getControlTargetType();
                 data.contolModeToTargetType[jointCtrl->getControlMode()].hardwareControlMode = jointCtrl->getHardwareControlMode();
             }
+            throwIfDevicesNotReady(__FUNCTION__);
             return data;
         }
 
         ControlDeviceStatus Devices::getControlDeviceStatus(std::size_t idx) const
         {
-            auto guard = getGuard();
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             const ControlDevicePtr& controlDevice = controlDevices.at(idx);
             ControlDeviceStatus status;
             const auto activeJointCtrl = _module<ControlThreadDataBuffer>().getActivatedJointControllers().at(idx);
@@ -144,6 +156,7 @@ namespace armarx
                 status.controlTargetValues[targ->getControlMode()] = targ->toVariants(_module<ControlThreadDataBuffer>().getSensorAndControlBuffer().sensorValuesTimestamp);
             }
             status.timestampUSec = MicroNow().count();
+            throwIfDevicesNotReady(__FUNCTION__);
             return status;
         }
 
@@ -151,6 +164,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             if (!controlDevices.has(name))
             {
                 std::stringstream ss;
@@ -168,12 +182,14 @@ namespace armarx
             {
                 return {};
             }
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             ControlDeviceStatusSeq r;
             r.reserve(getNumberOfControlDevices());
             for (auto idx : getIndices(controlDevices.values()))
             {
                 r.emplace_back(getControlDeviceStatus(idx));
             }
+            throwIfDevicesNotReady(__FUNCTION__);
             return r;
         }
 
@@ -181,6 +197,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {sensorDevicesMutex};
             return sensorDevices.keys();
         }
 
@@ -188,23 +205,26 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {sensorDevicesMutex};
             const SensorDevicePtr& sensorDevice = sensorDevices.at(idx);
             SensorDeviceDescription data;
             data.deviceName = sensorDevice->getDeviceName();
             data.tags.assign(sensorDevice->getTags().begin(), sensorDevice->getTags().end());
             data.sensorValueType = sensorDevice->getSensorValueType();
+            throwIfDevicesNotReady(__FUNCTION__);
             return data;
         }
 
         SensorDeviceStatus Devices::getSensorDeviceStatus(std::size_t idx) const
         {
-            auto guard = getGuard();
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {sensorDevicesMutex};
             const SensorDevicePtr& sensorDevice = sensorDevices.at(idx);
             SensorDeviceStatus status;
             status.deviceName = sensorDevice->getDeviceName();
             status.sensorValue = _module<ControlThreadDataBuffer>().getSensorAndControlBuffer().sensors.at(idx)->toVariants(_module<ControlThreadDataBuffer>().getSensorAndControlBuffer().sensorValuesTimestamp);
             status.timestampUSec = MicroNow().count();
+            throwIfDevicesNotReady(__FUNCTION__);
             return status;
         }
 
@@ -212,6 +232,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {sensorDevicesMutex};
             if (!sensorDevices.has(name))
             {
                 std::stringstream ss;
@@ -225,6 +246,7 @@ namespace armarx
         SensorDeviceDescriptionSeq Devices::getSensorDeviceDescriptions(const Ice::Current&) const
         {
             throwIfInControlThread(__FUNCTION__);
+            std::lock_guard<MutexType> guard {sensorDevicesMutex};
             if (!areDevicesReady())
             {
                 return {};
@@ -242,6 +264,7 @@ namespace armarx
         {
             throwIfInControlThread(__FUNCTION__);
             throwIfDevicesNotReady(__FUNCTION__);
+            std::lock_guard<MutexType> guard {sensorDevicesMutex};
             if (!sensorDevices.has(name))
             {
                 std::stringstream ss;
@@ -259,72 +282,103 @@ namespace armarx
             {
                 return {};
             }
+            std::lock_guard<MutexType> guard {sensorDevicesMutex};
             SensorDeviceStatusSeq r;
             r.reserve(getNumberOfSensorDevices());
             for (auto idx : getIndices(sensorDevices.values()))
             {
                 r.emplace_back(getSensorDeviceStatus(idx));
             }
+            throwIfDevicesNotReady(__FUNCTION__);
             return r;
         }
 
         void Devices::addControlDevice(const ControlDevicePtr& cd)
         {
-            throwIfInControlThread(__FUNCTION__);
-            //this guards prevents the RobotUnitState to change
-            auto guard = getGuard();
-            ARMARX_DEBUG << "Check RobotUnit State";
+            ARMARX_DEBUG << "ControlDevice "  << &cd;
             throwIfStateIsNot(RobotUnitState::InitializingDevices, __FUNCTION__);
-            ARMARX_DEBUG << "Adding the ControlDevice "  << cd->getDeviceName() << " " << &cd ;
-            controlDevices.add(cd->getDeviceName(), cd);
+            {
+                std::lock_guard<MutexType> guard {controlDevicesMutex};
+                //check it
+                if (!cd)
+                {
+                    std::stringstream ss;
+                    ss << "armarx::RobotUnit::addControlDevice: ControlDevice is nullptr";
+                    ARMARX_ERROR << ss.str();
+                    throw InvalidArgumentException {ss.str()};
+                }
+                if (!cd->getJointEmergencyStopController())
+                {
+                    std::stringstream ss;
+                    ss << "armarx::RobotUnit::addControlDevice: ControlDevice " << cd->getDeviceName()
+                       << " has null JointEmergencyStopController (this is not allowed)";
+                    ARMARX_ERROR << ss.str();
+                    throw InvalidArgumentException {ss.str()};
+                }
+                if (!cd->getJointStopMovementController())
+                {
+                    std::stringstream ss;
+                    ss << "armarx::RobotUnit::addControlDevice: ControlDevice " << cd->getDeviceName()
+                       << " has null getJointStopMovementController (this is not allowed)";
+                    ARMARX_ERROR << ss.str();
+                    throw InvalidArgumentException {ss.str()};
+                }
+                //add it
+                ARMARX_DEBUG << "Adding the ControlDevice "  << cd->getDeviceName() << " " << &cd ;
+                controlDevices.add(cd->getDeviceName(), cd);
+                ARMARX_INFO << "added ControlDevice " << cd->getDeviceName();
+            }
             ARMARX_INFO << "added ControlDevice " << cd->getDeviceName();
+            throwIfStateIsNot(RobotUnitState::InitializingDevices, __FUNCTION__);
         }
 
         void Devices::addSensorDevice(const SensorDevicePtr& sd)
         {
             ARMARX_DEBUG << "SensorDevice "  << &sd;
-            throwIfInControlThread(__FUNCTION__);
-            //this guards prevents the RobotUnitState to change
-            auto guard = getGuard();
-            ARMARX_DEBUG << "Check RobotUnit State";
             throwIfStateIsNot(RobotUnitState::InitializingDevices, __FUNCTION__);
-            if (!sd)
-            {
-                std::stringstream ss;
-                ss << "armarx::RobotUnit::addSensorDevice: SensorDevice is nullptr";
-                ARMARX_ERROR << ss.str();
-                throw InvalidArgumentException {ss.str()};
-            }
-            if (!sd->getSensorValue())
-            {
-                std::stringstream ss;
-                ss << "armarx::RobotUnit::addSensorDevice: SensorDevice " << sd->getDeviceName()
-                   << " has null SensorValue (this is not allowed)";
-                ARMARX_ERROR << ss.str();
-                throw InvalidArgumentException {ss.str()};
-            }
-            if (sd->getDeviceName() == rtThreadTimingsSensorDeviceName)
             {
-                ARMARX_DEBUG << "Device is the "  << rtThreadTimingsSensorDeviceName;
-                if (!std::dynamic_pointer_cast<RTThreadTimingsSensorDevice>(sd))
+                std::lock_guard<MutexType> guard {sensorDevicesMutex};
+                //check it
+                if (!sd)
                 {
-                    throw InvalidArgumentException
+                    std::stringstream ss;
+                    ss << "armarx::RobotUnit::addSensorDevice: SensorDevice is nullptr";
+                    ARMARX_ERROR << ss.str();
+                    throw InvalidArgumentException {ss.str()};
+                }
+                if (!sd->getSensorValue())
+                {
+                    std::stringstream ss;
+                    ss << "armarx::RobotUnit::addSensorDevice: SensorDevice " << sd->getDeviceName()
+                       << " has null SensorValue (this is not allowed)";
+                    ARMARX_ERROR << ss.str();
+                    throw InvalidArgumentException {ss.str()};
+                }
+                //add it
+                if (sd->getDeviceName() == rtThreadTimingsSensorDeviceName)
+                {
+                    ARMARX_DEBUG << "Device is the "  << rtThreadTimingsSensorDeviceName;
+                    if (!std::dynamic_pointer_cast<RTThreadTimingsSensorDevice>(sd))
                     {
-                        "You tried to add a SensorDevice with the name " + sd->getDeviceName() +
-                        " which does not derive from RTThreadTimingsSensorDevice. (Don't do this)"
-                    };
+                        throw InvalidArgumentException
+                        {
+                            "You tried to add a SensorDevice with the name " + sd->getDeviceName() +
+                            " which does not derive from RTThreadTimingsSensorDevice. (Don't do this)"
+                        };
+                    }
+                    //this checks if we already added such a device (do this before setting timingSensorDevice)
+                    ARMARX_DEBUG << "Adding the SensorDevice "  << sd->getDeviceName() << " " << &sd ;
+                    sensorDevices.add(sd->getDeviceName(), sd);
+                    rtThreadTimingsSensorDevice = std::dynamic_pointer_cast<RTThreadTimingsSensorDevice>(sd);
+                }
+                else
+                {
+                    ARMARX_DEBUG << "Adding the SensorDevice "  << sd->getDeviceName() << " " << &sd ;
+                    sensorDevices.add(sd->getDeviceName(), sd);
                 }
-                //this checks if we already added such a device (do this before setting timingSensorDevice)
-                ARMARX_DEBUG << "Adding the SensorDevice "  << sd->getDeviceName() << " " << &sd ;
-                sensorDevices.add(sd->getDeviceName(), sd);
-                rtThreadTimingsSensorDevice = std::dynamic_pointer_cast<RTThreadTimingsSensorDevice>(sd);
-            }
-            else
-            {
-                ARMARX_DEBUG << "Adding the SensorDevice "  << sd->getDeviceName() << " " << &sd ;
-                sensorDevices.add(sd->getDeviceName(), sd);
             }
             ARMARX_INFO << "added SensorDevice " << sd->getDeviceName() << " (valuetype = " << sd->getSensorValueType() << ")";
+            throwIfStateIsNot(RobotUnitState::InitializingDevices, __FUNCTION__);
         }
 
         RTThreadTimingsSensorDevicePtr Devices::createRTThreadTimingSensorDevice() const
@@ -336,6 +390,8 @@ namespace armarx
         void Devices::_postFinishRunning()
         {
             throwIfInControlThread(__FUNCTION__);
+            std::lock_guard<MutexType> guardS {sensorDevicesMutex};
+            std::lock_guard<MutexType> guardC {controlDevicesMutex};
             controlDevicesConstPtr.clear();
             sensorDevicesConstPtr.clear();
             sensorDevices.clear();
@@ -346,7 +402,7 @@ namespace armarx
         {
             throwIfDevicesNotReady(__FUNCTION__);
             throwIfInControlThread(__FUNCTION__);
-
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             std::vector<JointController*> controllers;
             controllers.reserve(controlDevices.values().size());
             for (const ControlDevicePtr& dev : controlDevices.values())
@@ -356,6 +412,7 @@ namespace armarx
                 ARMARX_CHECK_NOT_NULL(controllers.back());
             }
             ARMARX_CHECK_EQUAL(controlDevices.size(), controllers.size());
+            throwIfDevicesNotReady(__FUNCTION__);
             return controllers;
         }
 
@@ -363,7 +420,7 @@ namespace armarx
         {
             throwIfDevicesNotReady(__FUNCTION__);
             throwIfInControlThread(__FUNCTION__);
-
+            std::lock_guard<MutexType> guard {controlDevicesMutex};
             std::vector<JointController*> controllers;
             controllers.reserve(controlDevices.values().size());
             for (const ControlDevicePtr& dev : controlDevices.values())
@@ -373,12 +430,15 @@ namespace armarx
                 ARMARX_CHECK_NOT_NULL(controllers.back());
             }
             ARMARX_CHECK_EQUAL(controlDevices.size(), controllers.size());
+            throwIfDevicesNotReady(__FUNCTION__);
             return controllers;
         }
 
         void Devices::_preFinishDeviceInitialization()
         {
             throwIfInControlThread(__FUNCTION__);
+            std::lock_guard<MutexType> guardS {sensorDevicesMutex};
+            std::lock_guard<MutexType> guardC {controlDevicesMutex};
             if (!sensorDevices.has(rtThreadTimingsSensorDeviceName))
             {
                 addSensorDevice(createRTThreadTimingSensorDevice());
@@ -388,6 +448,8 @@ namespace armarx
         void Devices::_postFinishDeviceInitialization()
         {
             throwIfInControlThread(__FUNCTION__);
+            std::lock_guard<MutexType> guardS {sensorDevicesMutex};
+            std::lock_guard<MutexType> guardC {controlDevicesMutex};
             ARMARX_DEBUG << "checking " << controlDevices.size() << " ControlDevices:";
             {
                 for (const ControlDevicePtr& controlDevice : controlDevices.values())
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.h b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.h
index 0872a2be7a9d1a6a5378baf6d4c237b347d3d945..b4f2368d55dc62f957a14c1b8fff0200f7d39e66 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.h
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnitModules/RobotUnitModuleDevices.h
@@ -403,18 +403,24 @@ namespace armarx
                 std::vector<std::size_t> groupIndices;
             };
         private:
+            //ctrl dev
+            /// @brief \ref ControlDevice "ControlDevices" added to this unit (data may only be added during and only be used after \ref  State::InitializingDevices)
+            KeyValueVector<std::string, ControlDevicePtr> controlDevices;
+            /// @brief const pointer to all ControlDevices (passed to GenerateConfigDescription of a NJointController)
+            std::map<std::string, ConstControlDevicePtr> controlDevicesConstPtr;
+            /// @brief Guards access to all \ref ControlDevice "ControlDevices"
+            mutable MutexType controlDevicesMutex;
+
             /// @brief Device groups requiring the same hardware control mode.
             ControlDeviceHardwareControlModeGroups ctrlModeGroups;
 
-            /// @brief ControlDevices added to this unit (data may only be added during and only be used after State::InitializingDevices)
-            KeyValueVector<std::string, ControlDevicePtr> controlDevices;
-            /// @brief SensorDevices added to this unit (data may only be added during and only be used after State::InitializingDevices)
+            //sens dev
+            /// @brief \ref SensorDevice "SensorDevices" added to this unit (data may only be added during and only be used after \ref State::InitializingDevices)
             KeyValueVector<std::string, SensorDevicePtr > sensorDevices;
-
-            /// @brief const pointer to all ControlDevices (passed to GenerateConfigDescription of a NJointController)
-            std::map<std::string, ConstControlDevicePtr> controlDevicesConstPtr;
             /// @brief const pointer to all SensorDevices (passed to GenerateConfigDescription of a NJointController)
             std::map<std::string, ConstSensorDevicePtr> sensorDevicesConstPtr;
+            /// @brief Guards access to all \ref SensorDevice "SensorDevices"
+            mutable MutexType sensorDevicesMutex;
 
             /// @brief a pointer to the RTThreadTimingsSensorDevice used to meassure timings in the rt loop
             RTThreadTimingsSensorDevicePtr rtThreadTimingsSensorDevice;