diff --git a/source/RobotAPI/components/units/RobotUnit/LVL1Controllers/LVL1Controller.cpp b/source/RobotAPI/components/units/RobotUnit/LVL1Controllers/LVL1Controller.cpp
index 9e77d64f87c9eeb12a8f99c5ba87d92b025a3b75..0a4303248b60a0f4c094c32aee55cb540dd968f7 100644
--- a/source/RobotAPI/components/units/RobotUnit/LVL1Controllers/LVL1Controller.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/LVL1Controllers/LVL1Controller.cpp
@@ -41,6 +41,10 @@ bool LVL1Controller::isControllerRequested(const Ice::Current&) const
 {
     return isRequested;
 }
+bool LVL1Controller::isDeletable(const Ice::Current&) const
+{
+    return deletable;
+}
 
 bool LVL1Controller::hasControllerError(const Ice::Current&) const
 {
@@ -60,6 +64,7 @@ LVL1ControllerDescription LVL1Controller::getControllerDescription(const Ice::Cu
     d.controller = LVL1ControllerInterfacePrx::uncheckedCast(getProxy(-1));
     d.controlModeAssignment = controlDeviceControlModeMap;
     d.instanceName = getInstanceName();
+    d.deletable = deletable;
     return d;
 }
 
@@ -115,27 +120,34 @@ RobotUnitInterfacePrx LVL1Controller::getRobotUnit(const Ice::Current&) const
 void LVL1Controller::activateController(const Ice::Current&) const
 {
     ARMARX_CHECK_EXPRESSION(robotUnit);
-    robotUnit->activateController(getInstanceName());
+    robotUnit->activateLVL1Controller(getInstanceName());
 }
 
 void LVL1Controller::deactivateController(const Ice::Current&) const
 {
     ARMARX_CHECK_EXPRESSION(robotUnit);
-    robotUnit->deactivateController(getInstanceName());
+    robotUnit->deactivateLVL1Controller(getInstanceName());
+}
+
+void LVL1Controller::deleteController(const Ice::Current&) const
+{
+    ARMARX_CHECK_EXPRESSION(robotUnit);
+    robotUnit->deleteLVL1Controller(getInstanceName());
 }
 
 void LVL1Controller::publish(const SensorAndControl& sac, const DebugDrawerInterfacePrx& draw, const DebugObserverInterfacePrx& observer)
 {
     const bool active = isActive;
-    if (publishActive != active)
+    if (publishActive.exchange(active) != active)
     {
-        publishActive = active;
         if (active)
         {
+            ARMARX_DEBUG << "activating publishing for " << getInstanceName();
             onPublishActivation(draw, observer);
         }
         else
         {
+            ARMARX_DEBUG << "deactivating publishing for " << getInstanceName();
             onPublishDeactivation(draw, observer);
         }
     }
@@ -145,6 +157,15 @@ void LVL1Controller::publish(const SensorAndControl& sac, const DebugDrawerInter
     }
 }
 
+void LVL1Controller::deactivatePublish(const DebugDrawerInterfacePrx& draw, const DebugObserverInterfacePrx& observer)
+{
+    if (publishActive.exchange(false))
+    {
+        ARMARX_DEBUG << "forced deactivation of publishing for " << getInstanceName();
+        onPublishDeactivation(draw, observer);
+    }
+}
+
 void LVL1Controller::rtActivateController()
 {
     if (!isActive)
@@ -180,7 +201,13 @@ void LVL1Controller::rtDeactivateControllerBecauseOfError()
     rtDeactivateController();
 }
 
-void LVL1Controller::robotUnitInit(RobotUnit* ru, std::size_t ctrlId, StringStringDictionary ctrlDeviceControlModeMap, std::vector<char> ctrlDeviceUsedBitmap, std::vector<std::size_t> ctrlDeviceUsedIndices)
+void LVL1Controller::robotUnitInit(
+    RobotUnit* ru,
+    std::size_t ctrlId,
+    StringStringDictionary ctrlDeviceControlModeMap,
+    std::vector<char> ctrlDeviceUsedBitmap,
+    std::vector<std::size_t> ctrlDeviceUsedIndices,
+    bool ctrlDeletable)
 {
     ARMARX_CHECK_EXPRESSION(ru);
     ARMARX_CHECK_EXPRESSION(ctrlDeviceControlModeMap.size());
@@ -195,5 +222,6 @@ void LVL1Controller::robotUnitInit(RobotUnit* ru, std::size_t ctrlId, StringStri
     controlDeviceControlModeMap = std::move(ctrlDeviceControlModeMap);
     controlDeviceUsedBitmap     = std::move(ctrlDeviceUsedBitmap);
     controlDeviceUsedIndices    = std::move(ctrlDeviceUsedIndices);
+    deletable = ctrlDeletable;
 }
 
diff --git a/source/RobotAPI/components/units/RobotUnit/LVL1Controllers/LVL1Controller.h b/source/RobotAPI/components/units/RobotUnit/LVL1Controllers/LVL1Controller.h
index 9ac907a6342aa65a23c0d959bf547cd34367a3ab..80c86881585348a9b33c99d7af531bfe87d99cc6 100644
--- a/source/RobotAPI/components/units/RobotUnit/LVL1Controllers/LVL1Controller.h
+++ b/source/RobotAPI/components/units/RobotUnit/LVL1Controllers/LVL1Controller.h
@@ -197,6 +197,7 @@ namespace armarx
         //ice interface (must not be called in the rt thread)
         virtual bool isControllerActive(const Ice::Current& = GlobalIceCurrent) const final;
         virtual bool isControllerRequested(const Ice::Current& = GlobalIceCurrent) const final;
+        virtual bool isDeletable(const Ice::Current& = GlobalIceCurrent) const final;
         virtual bool hasControllerError(const Ice::Current& = GlobalIceCurrent) const final;
 
         virtual std::string getClassName(const Ice::Current& = GlobalIceCurrent) const override  = 0;
@@ -209,6 +210,7 @@ namespace armarx
 
         virtual void activateController(const Ice::Current& = GlobalIceCurrent) const final;
         virtual void deactivateController(const Ice::Current& = GlobalIceCurrent) const final;
+        virtual void deleteController(const Ice::Current& = GlobalIceCurrent) const final;
 
         virtual WidgetDescription::StringWidgetDictionary getFunctionDescriptions(const Ice::Current& = GlobalIceCurrent) const override
         {
@@ -275,13 +277,14 @@ namespace armarx
 
         template<class ItT>
         static boost::optional<std::vector<char>> AreNotInConflict(ItT first, ItT last);
-
+    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);
 
         void rtActivateController();
         void rtDeactivateController();
@@ -290,13 +293,12 @@ namespace armarx
         //firends
         friend class RobotUnitLVL1ControllerAccess;
 
-        void robotUnitInit(
-            RobotUnit* ru,
-            std::size_t ctrlId,
-            StringStringDictionary ctrlDeviceControlModeMap,
-            std::vector<char> ctrlDeviceUsedBitmap,
-            std::vector<std::size_t> ctrlDeviceUsedIndices
-        );
+        void robotUnitInit(RobotUnit* ru,
+                           std::size_t ctrlId,
+                           StringStringDictionary ctrlDeviceControlModeMap,
+                           std::vector<char> ctrlDeviceUsedBitmap,
+                           std::vector<std::size_t> ctrlDeviceUsedIndices,
+                           bool ctrlDeletable);
 
         RobotUnit* robotUnit;
         std::size_t id = std::numeric_limits<std::size_t>::max();
@@ -308,11 +310,12 @@ namespace armarx
         std::atomic_bool isActive {false};
         std::atomic_bool isRequested {false};
         std::atomic_bool deactivatedBecauseOfError {false};
+        bool deletable {false};
 
-        bool publishActive {false};
+        std::atomic_bool publishActive {false};
 
-        bool statusReportedActive {false};
-        bool statusReportedRequested {false};
+        std::atomic_bool statusReportedActive {false};
+        std::atomic_bool statusReportedRequested {false};
 
         // ManagedIceObject interface
     protected:
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnit.cpp b/source/RobotAPI/components/units/RobotUnit/RobotUnit.cpp
index 1c463396e2d4089733c63614369062a72520894d..7918cf272d78688183c0b9a0f031c6274d3f7d26 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnit.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnit.cpp
@@ -416,11 +416,11 @@ namespace armarx
             LVL1KinematicUnitPassThroughControllerConfigPtr config = new LVL1KinematicUnitPassThroughControllerConfig;  \
             config->controlMode=controlMode;                                                                            \
             config->deviceName=controlDeviceName;                                                                       \
-            LVL1ControllerPtr lvl1 = createController(                                                                  \
+            LVL1ControllerPtr lvl1 = createLVL1Controller(                                                                  \
                                      "LVL1KinematicUnitPassThroughController",                                          \
                                      "LVL1KU_PTCtrl_"+controlDeviceName+"_"+controlMode,                                \
-                                     config                                                                             \
-                                                     );                                                                 \
+                                     config,                                                                            \
+                                     false           );                                                                 \
             pt = LVL1KinematicUnitPassThroughControllerPtr::dynamicCast(lvl1);                                          \
             ARMARX_CHECK_EXPRESSION(pt);                                                                                \
         }                                                                                                               \
@@ -499,7 +499,7 @@ namespace armarx
         config->initialVelocityRotation = 0;
         config->platformName = robotPlatformName;
         auto ctrl = LVL1HolonomicPlatformUnitVelocityPassThroughControllerPtr::dynamicCast(
-                        createController("LVL1HolonomicPlatformUnitVelocityPassThroughController", configName + "_VelPTContoller", config)
+                        createLVL1Controller("LVL1HolonomicPlatformUnitVelocityPassThroughController", configName + "_VelPTContoller", config, false)
                     );
         ARMARX_CHECK_EXPRESSION(ctrl);
         unit->pt = ctrl;
@@ -884,13 +884,13 @@ namespace armarx
         return controlDevice->getLVL0Controller(controlMode)->getControlTarget();
     }
 
-    LVL1ControllerInterfacePrx RobotUnit::createController(const std::string& className, const std::string& instanceName, const LVL1ControllerConfigPtr& config, const Ice::Current&)
+    LVL1ControllerInterfacePrx RobotUnit::createLVL1Controller(const std::string& className, const std::string& instanceName, const LVL1ControllerConfigPtr& config, const Ice::Current&)
     {
         //no lock required
-        return LVL1ControllerInterfacePrx::uncheckedCast(createController(className, instanceName, config)->getProxy(-1, true));
+        return LVL1ControllerInterfacePrx::uncheckedCast(createLVL1Controller(className, instanceName, config, true)->getProxy(-1, true));
     }
 
-    LVL1ControllerInterfacePrx RobotUnit::createControllerFromVariantConfig(const std::string& className, const std::string& instanceName, const StringVariantBaseMap& variants, const Ice::Current&)
+    LVL1ControllerInterfacePrx RobotUnit::createLVL1ControllerFromVariantConfig(const std::string& className, const std::string& instanceName, const StringVariantBaseMap& variants, const Ice::Current&)
     {
         //no lock required
         checkLVL1ControllerClassName(className);
@@ -903,10 +903,10 @@ namespace armarx
             ARMARX_ERROR << ss.str();
             throw InvalidArgumentException {ss.str()};
         }
-        return createController(className, instanceName, LVL1ControllerRegistry::get(className)->GenerateConfigFromVariants(variants), GlobalIceCurrent/*to select ice overload*/);
+        return createLVL1Controller(className, instanceName, LVL1ControllerRegistry::get(className)->GenerateConfigFromVariants(variants), GlobalIceCurrent/*to select ice overload*/);
     }
 
-    LVL1ControllerPtr RobotUnit::createController(const std::string& className, const std::string& instanceName, const LVL1ControllerConfigPtr& config)
+    LVL1ControllerPtr RobotUnit::createLVL1Controller(const std::string& className, const std::string& instanceName, const LVL1ControllerConfigPtr& config, bool deletable)
     {
         auto guard = getGuard();
         throwIfDevicesNotReady(__FUNCTION__);
@@ -947,10 +947,17 @@ namespace armarx
             ctrlDeviceUsedBitmap.at(idx) = true;
             ctrlDeviceUsedIndices.emplace_back(idx);
         }
-        InitLVL1Controler(lvl1, this, lvl1ControllerNextId++, initLVL1UsedControlTargets, std::move(ctrlDeviceUsedBitmap), std::move(ctrlDeviceUsedIndices));
+        InitLVL1Controler(
+            lvl1,
+            this,
+            lvl1ControllerNextId++,
+            initLVL1UsedControlTargets,
+            std::move(ctrlDeviceUsedBitmap),
+            std::move(ctrlDeviceUsedIndices),
+            deletable);
         getArmarXManager()->addObjectAsync(lvl1, instanceName);
         lvl1Controllers[instanceName] = lvl1;
-        listenerPrx->lvl1ControllerAdded(instanceName);
+        listenerPrx->lvl1ControllerCreated(instanceName);
         return lvl1;
     }
 
@@ -1012,14 +1019,55 @@ namespace armarx
         ARMARX_INFO << "requested controllers:\n" << getRequestedLVL1ControllerNames();
     }
 
-    void RobotUnit::activateController(const std::string& name, const Ice::Current&)
+    void RobotUnit::deleteLVL1Controller(const std::string& name, const Ice::Current&)
     {
-        activateControllers({name});
+        deleteLVL1Controllers({name});
     }
 
-    void RobotUnit::activateControllers(const Ice::StringSeq& names, const Ice::Current&)
+    void RobotUnit::deleteLVL1Controllers(const Ice::StringSeq& names, const Ice::Current&)
     {
-        ARMARX_DEBUG << "requesting controller activation for:\n" << names;
+        ARMARX_VERBOSE << "requesting controller deletion for:\n" << names;
+        if (names.empty())
+        {
+            return;
+        }
+        auto guard = getGuard();
+        throwIfDevicesNotReady(__FUNCTION__);
+        auto ctrlsToActVec = getLVL1ControllersNotNull(names); //also checks if these controllers exist
+        ARMARX_DEBUG << "all controllers requested to delete exist" << std::flush;
+        //check if all can be deleted
+        for (const auto& lvl1 : ctrlsToActVec)
+        {
+            if (!lvl1->isDeletable())
+            {
+                throw LogicError {"The LVL1Controller '" + lvl1->getInstanceName() + "' can't be deleted since this operation is not allowed for this controller! (no LVL1Controller was deleted)"};
+            }
+        }
+        for (const auto& lvl1 : ctrlsToActVec)
+        {
+            if (lvl1->isControllerActive() || lvl1->isControllerRequested())
+            {
+                throw LogicError {"The LVL1Controller '" + lvl1->getInstanceName() + "' can't be deleted since it is active or requested! (no LVL1Controller was deleted)"};
+            }
+        }
+        for (const auto& lvl1 : ctrlsToActVec)
+        {
+            const auto name = lvl1->getInstanceName();
+            //deletion is done in a different thread since this call may be done by the controller (protection against use after free)
+            lvl1ControllersToBeDeleted[name] = std::move(lvl1);
+            lvl1Controllers.erase(name);
+            ARMARX_VERBOSE << "added LVL1Controller '" << name << "' to be deleted";
+        }
+    }
+
+    void RobotUnit::activateLVL1Controller(const std::string& name, const Ice::Current&)
+    {
+        activateLVL1Controllers({name});
+    }
+
+    void RobotUnit::activateLVL1Controllers(const Ice::StringSeq& names, const Ice::Current&)
+    {
+        ARMARX_VERBOSE << "requesting controller activation for:\n" << names;
         if (names.empty())
         {
             return;
@@ -1040,7 +1088,7 @@ namespace armarx
             if (!r)
             {
                 std::stringstream ss;
-                ss << "RobotUnit::activateControllers: requested controllers are in conflict!\ncontrollers:\n" << names;
+                ss << "RobotUnit::activateLVL1Controllers: requested controllers are in conflict!\ncontrollers:\n" << names;
                 ARMARX_ERROR << ss.str();
                 throw InvalidArgumentException {ss.str()};
             }
@@ -1077,13 +1125,14 @@ namespace armarx
         setActivateControllersRequest(std::move(ctrlsToAct));
     }
 
-    void RobotUnit::deactivateController(const std::string& name, const Ice::Current&)
+    void RobotUnit::deactivateLVL1Controller(const std::string& name, const Ice::Current&)
     {
-        deactivateControllers(Ice::StringSeq {name});
+        deactivateLVL1Controllers(Ice::StringSeq {name});
     }
 
-    void RobotUnit::deactivateControllers(const Ice::StringSeq& names, const Ice::Current&)
+    void RobotUnit::deactivateLVL1Controllers(const Ice::StringSeq& names, const Ice::Current&)
     {
+        ARMARX_VERBOSE << "requesting controller deactivation for:\n" << names;
         if (names.empty())
         {
             return;
@@ -1099,7 +1148,7 @@ namespace armarx
         setActivateControllersRequest(std::move(ctrls));
     }
 
-    void RobotUnit::switchControllerSetup(const Ice::StringSeq& newSetup, const Ice::Current&)
+    void RobotUnit::switchLVL1ControllerSetup(const Ice::StringSeq& newSetup, const Ice::Current&)
     {
         auto guard = getGuard();
         throwIfDevicesNotReady(__FUNCTION__);
@@ -1116,7 +1165,8 @@ namespace armarx
             RobotUnitState::PreComponentInitialization,
             RobotUnitState::InitializingDevices,
             RobotUnitState::InitializingUnits,
-            RobotUnitState::WaitingForRTThreadInitialization
+            RobotUnitState::WaitingForRTThreadInitialization,
+            RobotUnitState::Exiting
         };
         if (skipStates.count(state))
         {
@@ -1124,8 +1174,25 @@ namespace armarx
             return;
         }
         auto guard = getGuard();
+        if (skipStates.count(state))
+        {
+            ARMARX_DEBUG << deactivateSpam(spamdelay) << "skipping publishing in state " << state;
+            return;
+        }
         throwIfStateIsNot(RobotUnitState::Running, __FUNCTION__);
+        //get batch proxies
         auto debugObserverBatchPrx = debugObserverPrx->ice_batchOneway();
+        auto listenerBatchPrx = listenerPrx->ice_batchOneway();
+        //delete lvl1 queued for deletion
+        {
+            for (auto& pair : lvl1ControllersToBeDeleted)
+            {
+                listenerBatchPrx->lvl1ControllerDeleted(pair.first);
+                getArmarXManager()->removeObjectNonBlocking(pair.second);
+                ARMARX_VERBOSE << "deleted LVL1Controller " << pair.first;
+            }
+            lvl1ControllersToBeDeleted.clear();
+        }
         //swap buffers in
         const bool haveActivatedControllersChanged = activatedControllersChanged();
         const bool haveSensorAndControlValsChanged = sensorAndControlBufferChanged();
@@ -1139,7 +1206,6 @@ namespace armarx
         const auto numSensorDevices  = getNumberOfSensorDevices();
         const auto numControlDevices = getNumberOfControlDevices();
 
-        auto listenerBatchPrx = listenerPrx->ice_batchOneway();
         const bool publishDebugObserver = !(publishIterationCount % debugObserverSkipIterations);
         const bool debugObserverPublishControlTargetsThisIteration = debugObserverPublishControlTargets;
         const bool debugObserverPublishSensorValuesThisIteration = debugObserverPublishSensorValues;
@@ -1358,25 +1424,49 @@ namespace armarx
         controlDevicesConstPtr.clear();
         sensorDevicesConstPtr.clear();
         //publisher
-        publisherTask->stop();
-        while (publisherTask->isFunctionExecuting() || publisherTask->isRunning())
         {
-            ARMARX_FATAL << deactivateSpam(0.1) << "PUBLISHER TASK IS RUNNING EVEN AFTER IT WAS STOPPED!";
+            publisherTask->stop();
+            auto tPublisherStopped = Now();
+            while (publisherTask->isFunctionExecuting() || publisherTask->isRunning())
+            {
+                ARMARX_FATAL << deactivateSpam(0.1) << "PUBLISHER TASK IS RUNNING EVEN AFTER IT WAS STOPPED!";
+            }
+            checkRefCountIsOne(publisherTask, "publisherTask");
+            publisherTask = nullptr;
+            //since the drawer queues draw events and we want to clear the layers, we have to sleep here
+            std::this_thread::sleep_until(tPublisherStopped + std::chrono::milliseconds {100});
         }
-        checkRefCountIsOne(publisherTask, "publisherTask");
-        publisherTask = nullptr;
+
         //RT
         joinRTThread();
+        //call deac publishing of all active lvl1
+        for (const auto& pair : lvl1Controllers)
+        {
+            ARMARX_DEBUG << "forcing deactivation of publishing for " << pair.first;
+            DeactivateLVL1ControllerPublishing(pair.second, debugDrawerPrx, debugObserverPrx);
+        }
         //units
         removeAllUnits();
+        //lvl1 queued for deletion (some could still be in the queue)
+        {
+            for (auto& n2lvl1 : lvl1ControllersToBeDeleted)
+            {
+                LVL1ControllerPtr& lvl1 = n2lvl1.second;
+                getArmarXManager()->removeObjectBlocking(lvl1);
+                checkRefCountIsOne(lvl1, lvl1->getName());
+            }
+            lvl1ControllersToBeDeleted.clear();
+        }
         //lvl1
-        for (auto& n2lvl1 : lvl1Controllers)
         {
-            LVL1ControllerPtr& lvl1 = n2lvl1.second;
-            getArmarXManager()->removeObjectBlocking(lvl1);
-            checkRefCountIsOne(lvl1, lvl1->getName());
+            for (auto& n2lvl1 : lvl1Controllers)
+            {
+                LVL1ControllerPtr& lvl1 = n2lvl1.second;
+                getArmarXManager()->removeObjectBlocking(lvl1);
+                checkRefCountIsOne(lvl1, lvl1->getName());
+            }
+            lvl1Controllers.clear();
         }
-        lvl1Controllers.clear();
         //clear devices
         sensorDevices.clear();
         controlDevices.clear();
diff --git a/source/RobotAPI/components/units/RobotUnit/RobotUnit.h b/source/RobotAPI/components/units/RobotUnit/RobotUnit.h
index 1a6cb422be393fd558149d5cfad773f753a1957e..3416ca4257c545713e18c66dff3785e8e8283344 100644
--- a/source/RobotAPI/components/units/RobotUnit/RobotUnit.h
+++ b/source/RobotAPI/components/units/RobotUnit/RobotUnit.h
@@ -169,10 +169,11 @@ namespace armarx
             std::size_t ctrlId,
             StringStringDictionary ctrlDeviceControlModeMap,
             std::vector<char> ctrlDeviceUsedBitmap,
-            std::vector<std::size_t> ctrlDeviceUsedIndices
+            std::vector<std::size_t> ctrlDeviceUsedIndices,
+            bool deletable
         )
         {
-            lvl1->robotUnitInit(ru, ctrlId, std::move(ctrlDeviceControlModeMap), std::move(ctrlDeviceUsedBitmap), std::move(ctrlDeviceUsedIndices));
+            lvl1->robotUnitInit(ru, ctrlId, std::move(ctrlDeviceControlModeMap), std::move(ctrlDeviceUsedBitmap), std::move(ctrlDeviceUsedIndices), deletable);
         }
         static void PublishLVL1Controller(
             LVL1ControllerPtr lvl1,
@@ -193,13 +194,21 @@ namespace armarx
         }
         void UpdateLVL1ControllerStatusReported(LVL1ControllerPtr lvl1)
         {
-            lvl1->statusReportedActive = lvl1->isActive;
-            lvl1->statusReportedRequested = lvl1->isRequested;
+            lvl1->statusReportedActive = lvl1->isActive.load();
+            lvl1->statusReportedRequested = lvl1->isRequested.load();
         }
         void SetLVL1ControllerRequested(LVL1ControllerPtr lvl1, bool requested)
         {
             lvl1->isRequested = requested;
         }
+
+        void DeactivateLVL1ControllerPublishing(
+            LVL1ControllerPtr lvl1,
+            const DebugDrawerInterfacePrx& draw,
+            const DebugObserverInterfacePrx& observer)
+        {
+            lvl1->deactivatePublish(draw, observer);
+        }
     };
 
     class RobotUnit :
@@ -262,6 +271,7 @@ namespace armarx
         std::map<std::string, std::string> initLVL1UsedControlTargets;
         /// @brief Holds all currently loaded LVL1 controllers (index: [instancename])(May not be accessed in rt.)
         std::map<std::string, LVL1ControllerPtr> lvl1Controllers;
+        std::map<std::string, LVL1ControllerPtr> lvl1ControllersToBeDeleted;
         /// @brief the id of the next LVL1Controller instance that is created
         std::size_t lvl1ControllerNextId {0};
 
@@ -455,20 +465,22 @@ namespace armarx
         virtual ConstSensorDevicePtr   getSensorDevice(const std::string& sensorDeviceName) const;
         virtual ConstControlDevicePtr  getControlDevice(const std::string& deviceName);
         virtual ControlTargetBase* getControlTarget(const std::string& deviceName, const std::string& controlMode) override;
-        virtual LVL1ControllerInterfacePrx createController(const std::string& className, const std::string& instanceName, const LVL1ControllerConfigPtr& config, const Ice::Current&) override;
-        virtual LVL1ControllerInterfacePrx createControllerFromVariantConfig(const std::string& className, const std::string& instanceName, const StringVariantBaseMap& variants, const Ice::Current&) override;
-        LVL1ControllerPtr createController(const std::string& className, const std::string& instanceName, const LVL1ControllerConfigPtr& config);
-
+        virtual LVL1ControllerInterfacePrx createLVL1Controller(const std::string& className, const std::string& instanceName, const LVL1ControllerConfigPtr& config, const Ice::Current&) override;
+        virtual LVL1ControllerInterfacePrx createLVL1ControllerFromVariantConfig(const std::string& className, const std::string& instanceName, const StringVariantBaseMap& variants, const Ice::Current&) override;
+        LVL1ControllerPtr createLVL1Controller(const std::string& className, const std::string& instanceName, const LVL1ControllerConfigPtr& config, bool deletable);
+        //deleting lvl1 controllers
+        virtual void deleteLVL1Controller(const std::string& name, const Ice::Current& = GlobalIceCurrent) override;
+        virtual void deleteLVL1Controllers(const Ice::StringSeq& names, const Ice::Current& = GlobalIceCurrent) override;
         // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //
         // State: Running (NON RT)
         // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //
     public:
         //switching
-        virtual void activateController(const std::string& name, const Ice::Current& = GlobalIceCurrent) override;
-        virtual void activateControllers(const Ice::StringSeq& names, const Ice::Current& = GlobalIceCurrent) override;
-        virtual void deactivateController(const std::string& name, const Ice::Current& = GlobalIceCurrent) override;
-        virtual void deactivateControllers(const Ice::StringSeq& names, const Ice::Current& = GlobalIceCurrent) override;
-        virtual void switchControllerSetup(const Ice::StringSeq& newSetup, const Ice::Current& = GlobalIceCurrent) override;
+        virtual void activateLVL1Controller(const std::string& name, const Ice::Current& = GlobalIceCurrent) override;
+        virtual void activateLVL1Controllers(const Ice::StringSeq& names, const Ice::Current& = GlobalIceCurrent) override;
+        virtual void deactivateLVL1Controller(const std::string& name, const Ice::Current& = GlobalIceCurrent) override;
+        virtual void deactivateLVL1Controllers(const Ice::StringSeq& names, const Ice::Current& = GlobalIceCurrent) override;
+        virtual void switchLVL1ControllerSetup(const Ice::StringSeq& newSetup, const Ice::Current& = GlobalIceCurrent) override;
     protected:
         void setActivateControllersRequest(std::set<LVL1ControllerPtr, LVL1Controller::IdComp>&& ctrls);
         /**
diff --git a/source/RobotAPI/components/units/RobotUnit/Units/KinematicSubUnit.cpp b/source/RobotAPI/components/units/RobotUnit/Units/KinematicSubUnit.cpp
index c595351fe68783c91840329ad49bb22f01fe25af..dffcd51c327ffaae41900f45781d6a494edb52b7 100644
--- a/source/RobotAPI/components/units/RobotUnit/Units/KinematicSubUnit.cpp
+++ b/source/RobotAPI/components/units/RobotUnit/Units/KinematicSubUnit.cpp
@@ -43,13 +43,13 @@ void armarx::KinematicSubUnit::setupData(std::string relRobFile, VirtualRobot::R
 
 void armarx::KinematicSubUnit::update(const armarx::SensorAndControl& sc, const armarx::LVL0AndLVL1Controllers& c)
 {
-    if(!getProxy())
+    if (!getProxy())
     {
         //this unit is not initialized yet
         ARMARX_IMPORTANT << deactivateSpam(1) << "not initialized yet";
         return;
     }
-    if(!listenerPrx)
+    if (!listenerPrx)
     {
         ARMARX_IMPORTANT << deactivateSpam(1) << "listener is not set";
         return;
@@ -129,12 +129,12 @@ void armarx::KinematicSubUnit::update(const armarx::SensorAndControl& sc, const
     prx->ice_flushBatchRequests();
 }
 
-void armarx::KinematicSubUnit::requestJoints(const Ice::StringSeq &, const Ice::Current &)
+void armarx::KinematicSubUnit::requestJoints(const Ice::StringSeq&, const Ice::Current&)
 {
     ARMARX_WARNING << "NYI";
 }
 
-void armarx::KinematicSubUnit::releaseJoints(const Ice::StringSeq &, const Ice::Current &)
+void armarx::KinematicSubUnit::releaseJoints(const Ice::StringSeq&, const Ice::Current&)
 {
     ARMARX_WARNING << "NYI";
 }
@@ -196,15 +196,15 @@ void armarx::KinematicSubUnit::switchControlMode(const armarx::NameControlModeMa
         ARMARX_VERBOSE << "switching control modes activates these LVL1Controllers:\n" << toActivate << std::flush;
         ARMARX_CHECK_EXPRESSION(robotUnit);
     }
-    robotUnit->activateControllers(toActivate);
+    robotUnit->activateLVL1Controllers(toActivate);
 }
 
-void armarx::KinematicSubUnit::setJointAccelerations(const armarx::NameValueMap &, const Ice::Current &)
+void armarx::KinematicSubUnit::setJointAccelerations(const armarx::NameValueMap&, const Ice::Current&)
 {
     ARMARX_WARNING << "NYI";
 }
 
-void armarx::KinematicSubUnit::setJointDecelerations(const armarx::NameValueMap &, const Ice::Current &)
+void armarx::KinematicSubUnit::setJointDecelerations(const armarx::NameValueMap&, const Ice::Current&)
 {
     ARMARX_WARNING << "NYI";
 }
diff --git a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllerClassesWidget.cpp b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllerClassesWidget.cpp
index e3ab6528a867c8ff96d4adb702e0a4e91c002f06..484160ea5425f5e0e5817cdd4e0019ec836c86ff 100644
--- a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllerClassesWidget.cpp
+++ b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllerClassesWidget.cpp
@@ -64,7 +64,7 @@ namespace armarx
             QGridLayout* l = new QGridLayout;
             w->setLayout(l);
             l->setContentsMargins(0, 0, 0, 0);
-            l->addItem(new QSpacerItem {0, 0, QSizePolicy::MinimumExpanding},0,3);
+            l->addItem(new QSpacerItem {0, 0, QSizePolicy::MinimumExpanding}, 0, 3);
             l->addWidget(new QLabel {"Combine filters with"}, 0, 0, 1, 1);
             filterCombination = new QComboBox;
             filterCombination->addItem("Or");
@@ -171,15 +171,15 @@ namespace armarx
     }
 
     RobotUnitLVL1ControllerClassesWidgetEntry::RobotUnitLVL1ControllerClassesWidgetEntry(
-            RobotUnitLVL1ControllerClassesWidget& parent,
-            QTreeWidget& treeWidget,
-            const LVL1ControllerClassDescription& desc,
-            RobotUnitInterfacePrx robotUnit
+        RobotUnitLVL1ControllerClassesWidget& parent,
+        QTreeWidget& treeWidget,
+        const LVL1ControllerClassDescription& desc,
+        RobotUnitInterfacePrx robotUnit
     ) :
         QObject {&parent},
-        className {desc.className},
-        classNameQStr{QString::fromStdString(className)},
-        robotUnit {robotUnit}
+            className {desc.className},
+            classNameQStr {QString::fromStdString(className)},
+    robotUnit {robotUnit}
     {
         header = new QTreeWidgetItem {{QString::fromStdString(desc.className)}};
         treeWidget.addTopLevelItem(header);
@@ -273,7 +273,7 @@ namespace armarx
             }
             ARMARX_INFO << ss.str();
         }
-        robotUnit->createControllerFromVariantConfig(className, instanceName, variants);
+        robotUnit->createLVL1ControllerFromVariantConfig(className, instanceName, variants);
     }
 
 }
diff --git a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllersWidget.cpp b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllersWidget.cpp
index 6076bfc5cf387ade3c3bbd97dd93a931b2ac2ff5..61d4a7d68909a6c293ac077cc7597e9792317060 100644
--- a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllersWidget.cpp
+++ b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllersWidget.cpp
@@ -30,7 +30,7 @@ namespace armarx
         ui(new Ui::RobotUnitLVL1ControllersWidget)
     {
         ui->setupUi(this);
-        ui->treeWidget->setColumnCount(9);
+        ui->treeWidget->setColumnCount(10);
         QTreeWidgetItem* head = ui->treeWidget->headerItem();
 
         head->setText(idxName, "Name");
@@ -42,6 +42,7 @@ namespace armarx
         head->setText(idxCtrlMode, "Modes");
         head->setText(idxActivate, "");
         head->setText(idxDeactivate, "");
+        head->setText(idxDelete, "");
 
         head->setToolTip(idxName, "The controllers instance name (green: ok, red: active and requested state missmatch or there is an error)");
         head->setToolTip(idxClass, "The controllers class name");
@@ -52,6 +53,7 @@ namespace armarx
         head->setToolTip(idxCtrlMode, "The controll mode for the control devices used by this controller");
         head->setToolTip(idxActivate, "Button to activate the Controller");
         head->setToolTip(idxDeactivate, "Button to deactivate the Controller");
+        head->setToolTip(idxDelete, "Button to delete the Controller");
 
         ui->treeWidget->setColumnWidth(idxName, 400);
         ui->treeWidget->setColumnWidth(idxClass, 200);
@@ -59,6 +61,7 @@ namespace armarx
         ui->treeWidget->setColumnWidth(idxCtrlMode, 150);
         ui->treeWidget->setColumnWidth(idxActivate, 40);
         ui->treeWidget->setColumnWidth(idxDeactivate, 40);
+        ui->treeWidget->setColumnWidth(idxDelete, 40);
         ui->treeWidget->setColumnWidth(idxRequested, 40);
         ui->treeWidget->setColumnWidth(idxActive, 40);
         ui->treeWidget->setColumnWidth(idxError, 40);
@@ -66,6 +69,7 @@ namespace armarx
         //        QHeaderView* headerv = ui->treeWidget->header();
         //        headerv->setSectionResizeMode(idxActivate, QHeaderView::Fixed);
         //        headerv->setSectionResizeMode(idxDeactivate, QHeaderView::Fixed);
+        //        headerv->setSectionResizeMode(idxDelete, QHeaderView::Fixed);
         //        headerv->setSectionResizeMode(idxRequested, QHeaderView::Fixed);
         //        headerv->setSectionResizeMode(idxActive, QHeaderView::Fixed);
         //        headerv->setSectionResizeMode(idxError, QHeaderView::Fixed);
@@ -91,13 +95,13 @@ namespace armarx
         std::lock_guard<std::recursive_mutex> guard {statusUpdatesMutex};
         for (const auto& pair : statusUpdates)
         {
-            lvl1ControllerAdded(pair.second.instanceName);
+            lvl1ControllerCreated(pair.second.instanceName);
             entries.at(pair.second.instanceName)->update(pair.second);
         }
         statusUpdates.clear();
     }
 
-    void RobotUnitLVL1ControllersWidget::lvl1ControllerAdded(std::string name)
+    void RobotUnitLVL1ControllersWidget::lvl1ControllerCreated(std::string name)
     {
         std::lock_guard<std::recursive_mutex> guard {mutex};
         if (!entries.count(name))
@@ -107,6 +111,17 @@ namespace armarx
         }
     }
 
+    void RobotUnitLVL1ControllersWidget::lvl1ControllerDeleted(std::string name)
+    {
+        std::lock_guard<std::recursive_mutex> guard {mutex};
+        if (entries.count(name))
+        {
+            entries.at(name)->deleteContent();
+            entries.at(name)->deleteLater();
+            entries.erase(name);
+        }
+    }
+
     void RobotUnitLVL1ControllersWidget::reset(RobotUnitInterfacePrx ru)
     {
         std::lock_guard<std::recursive_mutex> guard {mutex};
@@ -176,13 +191,23 @@ namespace armarx
         treeWidget.setItemWidget(header, RobotUnitLVL1ControllersWidget::idxActivate, act);
         treeWidget.setItemWidget(header, RobotUnitLVL1ControllersWidget::idxDeactivate, dec);
         act->setIcon(QIcon {QString{":/icons/media-playback-start.ico"}});
-        dec->setIcon(QIcon {QString{":/icons/dialog-close.ico"}});
+        dec->setIcon(QIcon {QString{":/icons/media-playback-pause.ico"}});
         act->setFixedWidth(40);
         dec->setFixedWidth(40);
         act->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
         dec->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
         connect(act, SIGNAL(clicked(bool)), this , SLOT(activateController()));
         connect(dec, SIGNAL(clicked(bool)), this , SLOT(deactivateController()));
+        if (desc.deletable)
+        {
+            QPushButton* del = new QPushButton;
+            treeWidget.setItemWidget(header, RobotUnitLVL1ControllersWidget::idxDelete, del);
+            del->setToolTip("Delete the Controller");
+            del->setIcon(QIcon {QString{":/icons/Trash.svg"}});
+            del->setFixedWidth(40);
+            del->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
+            connect(del, SIGNAL(clicked(bool)), this , SLOT(deleteController()));
+        }
 
         //remote functions
         {
@@ -214,36 +239,36 @@ namespace armarx
         header->setBackground(RobotUnitLVL1ControllersWidget::idxName, {status.error ? red() : acReqColor});
     }
 
-    bool RobotUnitLVL1ControllersWidgetEntry::matchName(const QString &name)
+    bool RobotUnitLVL1ControllersWidgetEntry::matchName(const QString& name)
     {
-        return header->text(RobotUnitLVL1ControllersWidget::idxName).contains(name,Qt::CaseInsensitive);
+        return header->text(RobotUnitLVL1ControllersWidget::idxName).contains(name, Qt::CaseInsensitive);
     }
 
-    bool RobotUnitLVL1ControllersWidgetEntry::matchClass(const QString &name)
+    bool RobotUnitLVL1ControllersWidgetEntry::matchClass(const QString& name)
     {
-        return header->text(RobotUnitLVL1ControllersWidget::idxClass).contains(name,Qt::CaseInsensitive);
+        return header->text(RobotUnitLVL1ControllersWidget::idxClass).contains(name, Qt::CaseInsensitive);
     }
 
-    bool RobotUnitLVL1ControllersWidgetEntry::isActiveState(const QString &state)
+    bool RobotUnitLVL1ControllersWidgetEntry::isActiveState(const QString& state)
     {
-        return header->text(RobotUnitLVL1ControllersWidget::idxActive).contains(state,Qt::CaseInsensitive);
+        return header->text(RobotUnitLVL1ControllersWidget::idxActive).contains(state, Qt::CaseInsensitive);
     }
 
-    bool RobotUnitLVL1ControllersWidgetEntry::isRequestedState(const QString &state)
+    bool RobotUnitLVL1ControllersWidgetEntry::isRequestedState(const QString& state)
     {
-        return header->text(RobotUnitLVL1ControllersWidget::idxRequested).contains(state,Qt::CaseInsensitive);
+        return header->text(RobotUnitLVL1ControllersWidget::idxRequested).contains(state, Qt::CaseInsensitive);
     }
 
-    bool RobotUnitLVL1ControllersWidgetEntry::isErrorState(const QString &state)
+    bool RobotUnitLVL1ControllersWidgetEntry::isErrorState(const QString& state)
     {
-        return header->text(RobotUnitLVL1ControllersWidget::idxError).contains(state,Qt::CaseInsensitive);
+        return header->text(RobotUnitLVL1ControllersWidget::idxError).contains(state, Qt::CaseInsensitive);
     }
 
-    bool RobotUnitLVL1ControllersWidgetEntry::matchDevice(const QString &dev)
+    bool RobotUnitLVL1ControllersWidgetEntry::matchDevice(const QString& dev)
     {
-        for(const auto& elem:devsToModes)
+        for (const auto& elem : devsToModes)
         {
-            if(elem->text(RobotUnitLVL1ControllersWidget::idxCtrlDev).contains(dev,Qt::CaseInsensitive))
+            if (elem->text(RobotUnitLVL1ControllersWidget::idxCtrlDev).contains(dev, Qt::CaseInsensitive))
             {
                 return true;
             }
@@ -251,11 +276,11 @@ namespace armarx
         return false;
     }
 
-    bool RobotUnitLVL1ControllersWidgetEntry::matchMode(const QString &mode)
+    bool RobotUnitLVL1ControllersWidgetEntry::matchMode(const QString& mode)
     {
-        for(const auto& elem:devsToModes)
+        for (const auto& elem : devsToModes)
         {
-            if(elem->text(RobotUnitLVL1ControllersWidget::idxCtrlMode).contains(mode,Qt::CaseInsensitive))
+            if (elem->text(RobotUnitLVL1ControllersWidget::idxCtrlMode).contains(mode, Qt::CaseInsensitive))
             {
                 return true;
             }
@@ -263,6 +288,15 @@ namespace armarx
         return false;
     }
 
+    void RobotUnitLVL1ControllersWidgetEntry::deleteContent()
+    {
+        for (auto item : devsToModes)
+        {
+            delete item;
+        }
+        delete header;
+    }
+
     void RobotUnitLVL1ControllersWidgetEntry::setVisible(bool vis)
     {
         setDeviceListVisible(vis);
@@ -281,6 +315,12 @@ namespace armarx
         controller->deactivateController();
     }
 
+    void RobotUnitLVL1ControllersWidgetEntry::deleteController()
+    {
+        ARMARX_CHECK_EXPRESSION(controller);
+        controller->deleteController();
+    }
+
     void RobotUnitLVL1ControllersWidgetEntry::hideDeviceList()
     {
         QCheckBox* box = dynamic_cast<QCheckBox*>(sender());
diff --git a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllersWidget.h b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllersWidget.h
index 0cca7d5cfe92464bdec20411cd453a03d49c0a66..c00b3173fa781f172ccfad13a7272e8dad8365cf 100644
--- a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllersWidget.h
+++ b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitLVL1ControllersWidget.h
@@ -61,7 +61,8 @@ namespace armarx
         ~RobotUnitLVL1ControllersWidget();
         void lVl1ControllerStatusChanged(const LVL1ControllerStatus& status);
     public slots:
-        virtual void lvl1ControllerAdded(std::string name);
+        virtual void lvl1ControllerCreated(std::string name);
+        virtual void lvl1ControllerDeleted(std::string name);
         void reset(RobotUnitInterfacePrx ru);
     private slots:
         void lVl1ControllerStatusChanged();
@@ -75,15 +76,16 @@ namespace armarx
         std::map<std::string, LVL1ControllerStatus> statusUpdates;
 
     public:
-        static constexpr int idxName      = 0;
-        static constexpr int idxClass     = 1;
-        static constexpr int idxActive    = 2;
-        static constexpr int idxRequested = 3;
-        static constexpr int idxError     = 4;
-        static constexpr int idxCtrlDev     = 5;
-        static constexpr int idxCtrlMode     = 6;
-        static constexpr int idxActivate     = 7;
-        static constexpr int idxDeactivate     = 8;
+        static constexpr int idxName       = 0;
+        static constexpr int idxClass      = 1;
+        static constexpr int idxActive     = 2;
+        static constexpr int idxRequested  = 3;
+        static constexpr int idxError      = 4;
+        static constexpr int idxCtrlDev    = 5;
+        static constexpr int idxCtrlMode   = 6;
+        static constexpr int idxActivate   = 7;
+        static constexpr int idxDeactivate = 8;
+        static constexpr int idxDelete     = 9;
     };
 
     class RobotUnitLVL1ControllersWidgetEntry : public QObject
@@ -98,18 +100,22 @@ namespace armarx
 
         void update(const LVL1ControllerStatus& status);
 
-        bool matchName(const QString &name);
-        bool matchClass(const QString &name);
-        bool isActiveState(const QString &state);
-        bool isRequestedState(const QString &state);
-        bool isErrorState(const QString &state);
-        bool matchDevice(const QString &dev);
-        bool matchMode(const QString &mode);
+        bool matchName(const QString& name);
+        bool matchClass(const QString& name);
+        bool isActiveState(const QString& state);
+        bool isRequestedState(const QString& state);
+        bool isErrorState(const QString& state);
+        bool matchDevice(const QString& dev);
+        bool matchMode(const QString& mode);
+        void deleteContent();
+
     public slots:
         void setVisible(bool vis);
     private slots:
         void activateController();
         void deactivateController();
+        void deleteController();
+
         void hideDeviceList();
 
         void setDeviceListVisible(bool vis);
diff --git a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPluginWidgetController.cpp b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPluginWidgetController.cpp
index 34f0bb7c60ae04270fdcc0d4db2f47975c35a3cd..f675b207d7f83191666d395d3bd06cdd5629d463 100644
--- a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPluginWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPluginWidgetController.cpp
@@ -109,7 +109,6 @@ RobotUnitPluginWidgetController::RobotUnitPluginWidgetController()
             for (const path & entry : boost::make_iterator_range(directory_iterator(p), {}))
             {
                 const std::string pkg = entry.filename().string();
-                ARMARX_INFO << "Checking " << pkg;
                 if (CMakePackageFinder {pkg, "", true} .packageFound())
                 {
                     widget.comboBoxPackage->addItem(QString::fromStdString(pkg));
@@ -203,9 +202,14 @@ void RobotUnitPluginWidgetController::lvl1ControllerClassAdded(const std::string
     QMetaObject::invokeMethod(lvl1ControllerClasses, "lvl1ControllerClassAdded", Qt::QueuedConnection, Q_ARG(std::string, name));
 }
 
-void RobotUnitPluginWidgetController::lvl1ControllerAdded(const std::string& name, const Ice::Current&)
+void RobotUnitPluginWidgetController::lvl1ControllerCreated(const std::string& name, const Ice::Current&)
 {
-    QMetaObject::invokeMethod(lvl1Controllers, "lvl1ControllerAdded", Qt::QueuedConnection , Q_ARG(std::string, name));
+    QMetaObject::invokeMethod(lvl1Controllers, "lvl1ControllerCreated", Qt::QueuedConnection , Q_ARG(std::string, name));
+}
+
+void RobotUnitPluginWidgetController::lvl1ControllerDeleted(const std::string& name, const Ice::Current&)
+{
+    QMetaObject::invokeMethod(lvl1Controllers, "lvl1ControllerDeleted", Qt::QueuedConnection , Q_ARG(std::string, name));
 }
 
 void RobotUnitPluginWidgetController::refreshLVL1ControllersClicked()
diff --git a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPluginWidgetController.h b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPluginWidgetController.h
index 76b86901e6dfd5d79f89292f60432191d3c091ae..6c9b5d45e402848a2c4bdbc02fc0b31698869f78 100644
--- a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPluginWidgetController.h
+++ b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPluginWidgetController.h
@@ -117,7 +117,8 @@ namespace armarx
         virtual void controlDeviceStatusChanged(const ControlDeviceStatus& status, const Ice::Current&) override;
         virtual void sensorDeviceStatusChanged(const SensorDeviceStatus& status, const Ice::Current&) override;
         virtual void lvl1ControllerClassAdded(const std::string& name, const Ice::Current&) override;
-        virtual void lvl1ControllerAdded(const std::string& name, const Ice::Current&) override;
+        virtual void lvl1ControllerCreated(const std::string& name, const Ice::Current&) override;
+        virtual void lvl1ControllerDeleted(const std::string& name, const Ice::Current&) override;
 
     private slots:
         void refreshLVL1ControllersClicked();
diff --git a/source/RobotAPI/interface/units/RobotUnit/LVL1Controller.ice b/source/RobotAPI/interface/units/RobotUnit/LVL1Controller.ice
index a2e0f286a83b2e34cf9d9a60fea37b5991b67113..e454ef7109f85566f23d4593228672e2d9ea3625 100644
--- a/source/RobotAPI/interface/units/RobotUnit/LVL1Controller.ice
+++ b/source/RobotAPI/interface/units/RobotUnit/LVL1Controller.ice
@@ -40,6 +40,7 @@ module armarx
         string className;
         LVL1ControllerInterface* controller;
         StringStringDictionary controlModeAssignment;
+        bool deletable;
     };
     sequence<LVL1ControllerDescription> LVL1ControllerDescriptionSeq;
 
@@ -67,6 +68,7 @@ module armarx
         ["cpp:const"] idempotent StringStringDictionary getControlDeviceUsedControlModeMap();
         ["cpp:const"] idempotent bool isControllerActive();
         ["cpp:const"] idempotent bool isControllerRequested();
+        ["cpp:const"] idempotent bool isDeletable();
         ["cpp:const"] idempotent bool hasControllerError();
         ["cpp:const"] idempotent LVL1ControllerStatus getControllerStatus();
         ["cpp:const"] idempotent LVL1ControllerDescription getControllerDescription();
@@ -75,6 +77,7 @@ module armarx
 
         ["cpp:const"] void activateController();
         ["cpp:const"] void deactivateController();
+        ["cpp:const"] void deleteController() throws LogicError;
 
         ["cpp:const"] idempotent WidgetDescription::StringWidgetDictionary getFunctionDescriptions();
         void callDescribedFunction(string fuinctionName, StringVariantBaseMap values) throws InvalidArgumentException;
diff --git a/source/RobotAPI/interface/units/RobotUnit/RobotUnitInterface.ice b/source/RobotAPI/interface/units/RobotUnit/RobotUnitInterface.ice
index 01db232c7530b245c841c575f0b1f2183e16e96e..0e418ca270a9128327a1476bf21191f25849943e 100644
--- a/source/RobotAPI/interface/units/RobotUnit/RobotUnitInterface.ice
+++ b/source/RobotAPI/interface/units/RobotUnit/RobotUnitInterface.ice
@@ -120,17 +120,19 @@ module armarx
         ["cpp:const"] idempotent LVL1ControllerClassDescriptionSeq      getLVL1ControllerClassDescriptions();
 
         //switching
-        void switchControllerSetup(Ice::StringSeq newSetup) throws InvalidArgumentException, LogicError;
+        void switchLVL1ControllerSetup(Ice::StringSeq newSetup) throws InvalidArgumentException, LogicError;
 
-        void activateController(string controllerInstanceName) throws InvalidArgumentException, LogicError;
-        void activateControllers(Ice::StringSeq controllerInstanceNames) throws InvalidArgumentException, LogicError;
-        void deactivateController(string controllerInstanceName)throws InvalidArgumentException, LogicError;
-        void deactivateControllers(Ice::StringSeq controllerInstanceNames)throws InvalidArgumentException, LogicError;
+        void activateLVL1Controller(string controllerInstanceName) throws InvalidArgumentException, LogicError;
+        void activateLVL1Controllers(Ice::StringSeq controllerInstanceNames) throws InvalidArgumentException, LogicError;
+        void deactivateLVL1Controller(string controllerInstanceName)throws InvalidArgumentException, LogicError;
+        void deactivateLVL1Controllers(Ice::StringSeq controllerInstanceNames)throws InvalidArgumentException, LogicError;
 
         //creting controllers
-        LVL1ControllerInterface* createController(string className, string instanceName, LVL1ControllerConfig config) throws InvalidArgumentException, LogicError;
-        LVL1ControllerInterface* createControllerFromVariantConfig(string className, string instanceName, StringVariantBaseMap config) throws InvalidArgumentException, LogicError;
-
+        LVL1ControllerInterface* createLVL1Controller(string className, string instanceName, LVL1ControllerConfig config) throws InvalidArgumentException, LogicError;
+        LVL1ControllerInterface* createLVL1ControllerFromVariantConfig(string className, string instanceName, StringVariantBaseMap config) throws InvalidArgumentException, LogicError;
+        //deleting controllers
+        void deleteLVL1Controller(string controllerInstanceName)throws InvalidArgumentException, LogicError;
+        void deleteLVL1Controllers(Ice::StringSeq controllerInstanceNames)throws InvalidArgumentException, LogicError;
         //loading
         bool loadLibFromPath(string path);
         bool loadLibFromPackage(string package, string libname);
@@ -153,7 +155,8 @@ module armarx
         void controlDeviceStatusChanged(ControlDeviceStatus status);
         void sensorDeviceStatusChanged(SensorDeviceStatus status);
         void lvl1ControllerClassAdded(string className);
-        void lvl1ControllerAdded(string instanceName);
+        void lvl1ControllerCreated(string instanceName);
+        void lvl1ControllerDeleted(string instanceName);
     };
 };
 
diff --git a/source/RobotAPI/statecharts/TrajectoryExecutionCode/PlayTrajectory.cpp b/source/RobotAPI/statecharts/TrajectoryExecutionCode/PlayTrajectory.cpp
index c5744b396c367efbc95320a2652873d47405f36d..e777649ec3a7df216ef18f0b13480f2d71b61b0b 100644
--- a/source/RobotAPI/statecharts/TrajectoryExecutionCode/PlayTrajectory.cpp
+++ b/source/RobotAPI/statecharts/TrajectoryExecutionCode/PlayTrajectory.cpp
@@ -48,7 +48,7 @@ void PlayTrajectory::onEnter()
     LVL1TrajectoryControllerInterfacePrx prx = LVL1TrajectoryControllerInterfacePrx::checkedCast(getRobotUnit()->getLVL1Controller("ActorLVL1TrajectoryController"));
     if (!prx)
     {
-        prx = LVL1TrajectoryControllerInterfacePrx::checkedCast(getRobotUnit()->createController("LVL1TrajectoryController", "ActorLVL1TrajectoryController", cfg));
+        prx = LVL1TrajectoryControllerInterfacePrx::checkedCast(getRobotUnit()->createLVL1Controller("LVL1TrajectoryController", "ActorLVL1TrajectoryController", cfg));
 
     }
     else
@@ -62,7 +62,7 @@ void PlayTrajectory::onEnter()
     Ice::DoubleSeq sr = {0, 1, 1.6, 1, 0};
     t->addDimension(sr, {}, "Hip Yaw");
     prx->setTrajectory(t);
-    getRobotUnit()->activateController("ActorLVL1TrajectoryController");
+    getRobotUnit()->activateLVL1Controller("ActorLVL1TrajectoryController");
 }
 
 //void PlayTrajectory::run()