diff --git a/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.cpp b/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.cpp
index 7c466cdacab7c4a95862d2a7e9508d2d8dda450f..0e2ae813fbef99c1ce24e35c8be0be63deeeff8b 100644
--- a/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.cpp
+++ b/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.cpp
@@ -110,7 +110,7 @@ namespace armarx::viz::coin
                            << "\nFilename: " << element.filename;
             return true;
         }
-        IceUtil::Time time_load = IceUtil::Time::now();
+        //IceUtil::Time time_load = IceUtil::Time::now();
 
         bool drawStyleChanged = loadedDrawStyle != element.drawStyle;
         if (robotChanged || drawStyleChanged)
@@ -118,7 +118,7 @@ namespace armarx::viz::coin
             recreateVisualizationNodes(element.drawStyle);
             loadedDrawStyle = element.drawStyle;
         }
-        IceUtil::Time time_style = IceUtil::Time::now();
+        //IceUtil::Time time_style = IceUtil::Time::now();
 
         // Set pose, configuration and so on
 
@@ -132,33 +132,40 @@ namespace armarx::viz::coin
         // robot.setGlobalPose(pose, false);
 
         robot.setJointValues(element.jointValues);
-        IceUtil::Time time_set = IceUtil::Time::now();
+        //IceUtil::Time time_set = IceUtil::Time::now();
 
         if (loadedDrawStyle & data::ModelDrawStyle::OVERRIDE_COLOR)
         {
-            int numChildren = node->getNumChildren();
-            for (int i = 0; i < numChildren; i++)
+            if (loadedColor.r != element.color.r
+                    || loadedColor.g != element.color.g
+                    || loadedColor.b != element.color.b
+                    || loadedColor.a != element.color.a)
             {
-                SoSeparator* nodeSep = static_cast<SoSeparator*>(node->getChild(i));
-                // The first entry must be a SoMaterial (see recreateVisualizationNodes)
-                SoMaterial* m = dynamic_cast<SoMaterial*>(nodeSep->getChild(0));
-                if (!m)
+                int numChildren = node->getNumChildren();
+                for (int i = 0; i < numChildren; i++)
                 {
-                    ARMARX_WARNING << "Error at node with index: " << i;
-                    continue;
+                    SoSeparator* nodeSep = static_cast<SoSeparator*>(node->getChild(i));
+                    // The first entry must be a SoMaterial (see recreateVisualizationNodes)
+                    SoMaterial* m = dynamic_cast<SoMaterial*>(nodeSep->getChild(0));
+                    if (!m)
+                    {
+                        ARMARX_WARNING << "Error at node with index: " << i;
+                        continue;
+                    }
+
+                    auto color = element.color;
+                    const float conv = 1.0f / 255.0f;
+                    float a = color.a * conv;
+                    SbColor coinColor(conv * color.r, conv * color.g, conv * color.b);
+                    m->diffuseColor = coinColor;
+                    m->ambientColor = coinColor;
+                    m->transparency = 1.0f - a;
+                    m->setOverride(true);
                 }
-
-                auto color = element.color;
-                const float conv = 1.0f / 255.0f;
-                float a = color.a * conv;
-                SbColor coinColor(conv * color.r, conv * color.g, conv * color.b);
-                m->diffuseColor = coinColor;
-                m->ambientColor = coinColor;
-                m->transparency = 1.0f - a;
-                m->setOverride(true);
+                loadedColor = element.color;
             }
         }
-        IceUtil::Time time_color = IceUtil::Time::now();
+        //IceUtil::Time time_color = IceUtil::Time::now();
 
         // Setting the joint angles takes > 0.5 ms! This is unexpected...
         //        ARMARX_INFO << "Total:   " << (time_color - time_start).toMilliSecondsDouble()
diff --git a/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.h b/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.h
index cb6699735a40b1783bb0e09270891910514278da..63aa3f1f8cabf92029b1d1b763d808f9b2123d77 100644
--- a/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.h
+++ b/source/RobotAPI/components/ArViz/Coin/VisualizationRobot.h
@@ -25,6 +25,7 @@ namespace armarx::viz::coin
 
         LoadedRobot loaded;
         int loadedDrawStyle = data::ModelDrawStyle::ORIGINAL;
+        armarx::viz::data::Color loadedColor{0, 0, 0, 0};
     };
 
     void clearRobotCache();
diff --git a/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp b/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
index f11c7aa9de6672cafcda2bbcfdb2e5114eb2be69..692800bc7d85488b4af3dc7090c6efabde509911 100644
--- a/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
+++ b/source/RobotAPI/components/ArViz/Coin/Visualizer.cpp
@@ -143,8 +143,8 @@ namespace armarx::viz
             layerIt = layers.emplace(layerID, CoinLayer(coinNode)).first;
         }
 
-        IceUtil::Time time_start1 = IceUtil::Time::now();
-        IceUtil::Time time_start = IceUtil::Time::now();
+        //IceUtil::Time time_start1 = IceUtil::Time::now();
+        //IceUtil::Time time_start = IceUtil::Time::now();
 
         // Add or update the elements in the update
         CoinLayer& layer = layerIt->second;
@@ -171,10 +171,10 @@ namespace armarx::viz
                 continue;
             }
             coin::ElementVisualizer* visualizer = elementVisualizers[visuIndex].get();
-            IceUtil::Time time_findVisu = IceUtil::Time::now();
+            //IceUtil::Time time_findVisu = IceUtil::Time::now();
 
             auto oldElementIter = layer.elements.find(updatedElement.id);
-            IceUtil::Time time_findElement = IceUtil::Time::now();
+            //IceUtil::Time time_findElement = IceUtil::Time::now();
             if (oldElementIter != layer.elements.end())
             {
                 // Element already exists
@@ -238,7 +238,7 @@ namespace armarx::viz
                 iter = layer.elements.erase(iter);
             }
         }
-        IceUtil::Time time_remove = IceUtil::Time::now();
+        //IceUtil::Time time_remove = IceUtil::Time::now();
 
         //        if (update.name == "Example")
         //        {
@@ -290,7 +290,7 @@ namespace armarx::viz
         {
             case CoinVisualizerUpdateResult::SUCCESS:
             {
-                IceUtil::Time time_start = IceUtil::Time::now();
+                //IceUtil::Time time_start = IceUtil::Time::now();
 
                 // We should restart the pull for updates so it can run in parallel
                 data::LayerUpdates currentUpdates = pulledUpdates;
@@ -299,20 +299,20 @@ namespace armarx::viz
 
                 auto layerIDsBefore = getLayerIDs();
 
-                IceUtil::Time time_afterPull = IceUtil::Time::now();
+                //IceUtil::Time time_afterPull = IceUtil::Time::now();
 
                 for (data::LayerUpdate const& update : currentUpdates.updates)
                 {
                     apply(update);
                 }
-                IceUtil::Time time_afterApply = IceUtil::Time::now();
+                //IceUtil::Time time_afterApply = IceUtil::Time::now();
 
                 auto layerIDsAfter = getLayerIDs();
                 if (layerIDsAfter != layerIDsBefore)
                 {
                     emitLayersChanged(layerIDsAfter);
                 }
-                IceUtil::Time time_afterLayersChanged = IceUtil::Time::now();
+                //IceUtil::Time time_afterLayersChanged = IceUtil::Time::now();
 
                 // Most of the time is spent in apply
                 //                ARMARX_INFO << "Updates:  " << pulledUpdates.updates.size()
diff --git a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidget.ui b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidget.ui
index 8d4e7919a123d4fe736a68de36dc19a10f6daa84..8b4af8524ff6102e7230794f12fdaac64b07a876 100644
--- a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidget.ui
+++ b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidget.ui
@@ -14,12 +14,6 @@
    <string>RobotUnitPluginWidget</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
-   <property name="topMargin">
-    <number>0</number>
-   </property>
-   <property name="bottomMargin">
-    <number>0</number>
-   </property>
    <item>
     <widget class="QSplitter" name="splitter">
      <property name="orientation">
@@ -101,6 +95,116 @@
        </property>
       </layout>
      </widget>
+     <widget class="QGroupBox" name="groupBoxLogging">
+      <property name="title">
+       <string>Logging</string>
+      </property>
+      <layout class="QGridLayout" name="gridLayout">
+       <item row="0" column="0" colspan="2">
+        <layout class="QHBoxLayout" name="horizontalLayout">
+         <item>
+          <widget class="QLabel" name="label">
+           <property name="text">
+            <string>Filter</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="lineEditLoggingFilter"/>
+         </item>
+        </layout>
+       </item>
+       <item row="1" column="0" colspan="2">
+        <widget class="QTreeWidget" name="treeWidgetLoggingNames">
+         <column>
+          <property name="text">
+           <string/>
+          </property>
+         </column>
+        </widget>
+       </item>
+       <item row="3" column="0" colspan="2">
+        <layout class="QHBoxLayout" name="horizontalLayout_2">
+         <item>
+          <widget class="QLabel" name="label_2">
+           <property name="text">
+            <string>Save path</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="lineEditLoggingPath">
+           <property name="toolTip">
+            <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Accepts patterns:&lt;/p&gt;&lt;p&gt;{LEFT&lt;span style=&quot; color:#c0c0c0;&quot;/&gt;CURLY}&lt;span style=&quot; color:#c0c0c0;&quot;/&gt;-&amp;gt;&lt;span style=&quot; color:#c0c0c0;&quot;/&gt;{&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{RIGHT&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;CURLY}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{year&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;/&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;Year}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;year&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;(&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#000080;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;/&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#000080;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;digits)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{month}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{day}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{hour}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{minute}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{second}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{Date}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;YYYY-MM-DD&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{Time}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;HH-MM-SS&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{DateTime}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{Date}_{Time}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{time-since-epoch}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;nanoseconds&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;since&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;epoch&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;(can&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;be&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;used&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;as&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;uuid)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{PackageDir:...}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;Directory&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;of&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;the&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;given&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;package&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{ScenarioDir:...}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;Scenario&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;Directory&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;of&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;the&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;given&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;package&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{DataDir:...}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;Data&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;Directory&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;of&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;the&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;given&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;package&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{BinaryeDir:...}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;Binary&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;Directory&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;of&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;the&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;given&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;package&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{CMakeDir:...}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;CMake&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;Directory&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;of&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;the&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;given&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;package&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;{BuildDir:...}&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;Build&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;Directory&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;of&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;the&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;given&lt;/span&gt;&lt;span style=&quot; font-family:'monospace'; color:#c0c0c0;&quot;/&gt;&lt;span style=&quot; font-family:'monospace';&quot;&gt;package&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+           </property>
+           <property name="text">
+            <string>/tmp/logging/{DateTime}.csv</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="pushButtonLoggingStart">
+           <property name="text">
+            <string>Start</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="pushButtonLoggingStop">
+           <property name="enabled">
+            <bool>false</bool>
+           </property>
+           <property name="text">
+            <string>Stop</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item row="5" column="0" colspan="2">
+        <layout class="QGridLayout" name="gridLayout_2">
+         <item row="0" column="0">
+          <widget class="QLineEdit" name="lineEditLoggingMark1">
+           <property name="text">
+            <string>Start</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLineEdit" name="lineEditLoggingMark2">
+           <property name="text">
+            <string>Stop</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLineEdit" name="lineEditLoggingMark3"/>
+         </item>
+         <item row="1" column="1">
+          <widget class="QPushButton" name="pushButtonLoggingMark2">
+           <property name="text">
+            <string>Set Mark</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
+          <widget class="QPushButton" name="pushButtonLoggingMark1">
+           <property name="text">
+            <string>Set Mark</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QPushButton" name="pushButtonLoggingMark3">
+           <property name="text">
+            <string>Set Mark</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
     </widget>
    </item>
   </layout>
diff --git a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.cpp b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.cpp
index 076dfbbcebef9b02331fe6943fb7ba18943aa6c3..9f6229c5105a523109babbc9f2b7121ace039e42 100644
--- a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.cpp
+++ b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.cpp
@@ -24,13 +24,14 @@
 #include "../QWidgets/StyleSheets.h"
 
 #include <string>
-
+#include <regex>
 #include <filesystem>
 
 #include <QDir>
 #include <QSortFilterProxyModel>
 #include <QAction>
 
+#include <ArmarXCore/util/CPPUtility/Iterator.h>
 #include <ArmarXCore/core/system/cmake/CMakePackageFinder.h>
 #include <ArmarXCore/core/exceptions/local/ExpressionException.h>
 
@@ -72,6 +73,21 @@ RobotUnitPluginWidgetController::RobotUnitPluginWidgetController()
         nJointControllerClasses->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
         nJointControllerClasses->setVisible(false);
     }
+    //update logging
+    {
+        widget.groupBoxLogging->setVisible(false);
+        widget.groupBoxLogging->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
+
+        connect(widget.pushButtonLoggingStart, SIGNAL(clicked()), this, SLOT(on_pushButtonLoggingStart_clicked()));
+        connect(widget.pushButtonLoggingStop, SIGNAL(clicked()), this, SLOT(on_pushButtonLoggingStop_clicked()));
+        connect(widget.pushButtonLoggingMark1, SIGNAL(clicked()), this, SLOT(on_pushButtonLoggingMark1_clicked()));
+        connect(widget.pushButtonLoggingMark2, SIGNAL(clicked()), this, SLOT(on_pushButtonLoggingMark2_clicked()));
+        connect(widget.pushButtonLoggingMark3, SIGNAL(clicked()), this, SLOT(on_pushButtonLoggingMark3_clicked()));
+        connect(widget.lineEditLoggingFilter, SIGNAL(textChanged(const QString&)),
+                this, SLOT(on_lineEditLoggingFilter_textChanged(const QString&)));
+        connect(widget.treeWidgetLoggingNames, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
+                this, SLOT(on_treeWidgetLoggingNames_itemChanged(QTreeWidgetItem*, int)));
+    }
     updateToolBarActionCheckedState();
 }
 
@@ -195,6 +211,14 @@ QPointer<QWidget> RobotUnitPluginWidgetController::getCustomTitlebarWidget(QWidg
         customToolbar->addAction(showNJointClasses);
         customToolbar->addSeparator();
 
+        customToolbar->addAction(QIcon(":/icons/view-refresh-7.png"), "", this, SLOT(refreshLogging()));
+        showLogging = new QAction {"Logging", customToolbar};
+        showLogging->setCheckable(true);
+        showLogging->setToolTip("Hide/Show the logging pane");
+        connect(showLogging, SIGNAL(toggled(bool)), widget.groupBoxLogging, SLOT(setVisible(bool)));
+        customToolbar->addAction(showLogging);
+        customToolbar->addSeparator();
+
         customToolbar->addAction(QIcon(":/icons/document-save.svg"), "Write log", this, SLOT(writeLogClicked()))
         ->setToolTip("Writes the log to /tmp/");
     }
@@ -285,6 +309,263 @@ void armarx::RobotUnitPluginWidgetController::timerEvent(QTimerEvent*)
         refreshNJointControllerClassesClicked();
         refreshControlDevicesClicked();
         refreshSensorDevicesClicked();
+        refreshLogging();
         killTimer(onConnectTimerId);
     }
 }
+
+void armarx::RobotUnitPluginWidgetController::refreshLogging()
+{
+    on_pushButtonLoggingStop_clicked();
+
+    widget.treeWidgetLoggingNames->clear();
+    loggingData.allItems.clear();
+
+    const auto allLoggingNames = robotUnitPrx->getLoggingNames();
+
+    std::map<std::string, QTreeWidgetItem*> separators;
+    auto add = [&](const std::string & name, const std::string & display, auto parent)
+    {
+        QTreeWidgetItem* i = new QTreeWidgetItem(parent);
+        i->setText(0, QString::fromStdString(display) + "*");
+        i->setData(0, Qt::ToolTipRole, QString::fromStdString(name));
+        separators[name] = i;
+        loggingData.allItems.emplace_back(i);
+        i->setCheckState(0, Qt::Unchecked);
+    };
+    add("", "", widget.treeWidgetLoggingNames);
+    loggingData.top = loggingData.allItems.front();
+
+    for (const auto& name : allLoggingNames)
+    {
+        const auto parts = Split(name, ".", true, true);
+        std::string reassembled;
+        for (const auto& p : parts)
+        {
+            ARMARX_CHECK_EXPRESSION(separators.count(reassembled));
+            auto parent = separators.at(reassembled);
+            reassembled += (reassembled.empty() ? p : "." + p) ;
+            if (!separators.count(reassembled))
+            {
+                add(reassembled, p, parent);
+            }
+        }
+        loggingData.allItems.back()->setText(0, QString::fromStdString(parts.back()));
+    }
+
+}
+
+void armarx::RobotUnitPluginWidgetController::on_pushButtonLoggingStart_clicked()
+{
+    if (!robotUnitPrx || loggingData.handle)
+    {
+        return;
+    }
+    std::vector<std::string> loggingNames;
+    std::function<void(QTreeWidgetItem*)> recurseChildren = [&](auto it)
+    {
+        switch (it->checkState(0))
+        {
+            case Qt::Checked:
+                loggingNames.emplace_back(it->data(0, Qt::ToolTipRole).toString().toStdString());
+                break;
+            case Qt::Unchecked:
+                break;
+            case Qt::PartiallyChecked:
+                for (int  i = 0; i < it->childCount(); ++i)
+                {
+                    recurseChildren(it->child(i));
+                }
+                break;
+        }
+    };
+    recurseChildren(loggingData.top);
+    ARMARX_INFO << "start logging " << loggingNames;
+
+    loggingData.handle = robotUnitPrx->startRtLogging(
+                             widget.lineEditLoggingPath->text().toStdString(),
+                             loggingNames);
+    widget.pushButtonLoggingStart->setEnabled(false);
+    widget.pushButtonLoggingStop->setEnabled(true);
+    widget.pushButtonLoggingMark1->setEnabled(true);
+    widget.pushButtonLoggingMark2->setEnabled(true);
+    widget.pushButtonLoggingMark3->setEnabled(true);
+}
+
+void armarx::RobotUnitPluginWidgetController::on_pushButtonLoggingStop_clicked()
+{
+    widget.pushButtonLoggingStart->setEnabled(true);
+    widget.pushButtonLoggingStop->setEnabled(false);
+    widget.pushButtonLoggingMark1->setEnabled(false);
+    widget.pushButtonLoggingMark2->setEnabled(false);
+    widget.pushButtonLoggingMark3->setEnabled(false);
+    if (!loggingData.handle)
+    {
+        return;
+    }
+    robotUnitPrx->stopRtLogging(loggingData.handle);
+    loggingData.handle = nullptr;
+}
+
+void armarx::RobotUnitPluginWidgetController::on_lineEditLoggingFilter_textChanged(const QString& arg1)
+{
+    std::regex reg;
+    try
+    {
+        reg = std::regex{arg1.toStdString()};
+    }
+    catch (...)
+    {
+        //broken regex
+        widget.lineEditLoggingFilter->setStyleSheet("QLineEdit { background: rgb(255, 150, 150); selection-background-color: rgb(255, 0, 0); }");
+        return;
+    }
+    widget.lineEditLoggingFilter->setStyleSheet("QLineEdit {}");
+
+    std::function<void(QTreeWidgetItem* item)> setVisible = [&](auto it)
+    {
+        it->setHidden(false);
+        auto parent = it->parent();
+        //set parent state depending on its childrens state
+        if (!parent)
+        {
+            return;
+        }
+        setVisible(parent);
+    };
+    for (auto item : loggingData.allItems)
+    {
+        item->setHidden(true);
+    }
+    for (auto item : loggingData.allItems)
+    {
+        const auto str = item->data(0, Qt::ToolTipRole).toString().toStdString();
+        std::smatch match;
+        if (std::regex_search(str, match, reg))
+        {
+            setVisible(item);
+        }
+    }
+    widget.treeWidgetLoggingNames->blockSignals(true);
+    for (auto item : MakeReversedRange(loggingData.allItems))
+    {
+        loggingData.updateCheckStateUpward(item, false);
+    }
+    widget.treeWidgetLoggingNames->blockSignals(false);
+}
+
+void armarx::RobotUnitPluginWidgetController::on_treeWidgetLoggingNames_itemChanged(QTreeWidgetItem* item, int)
+{
+    widget.treeWidgetLoggingNames->blockSignals(true);
+    loggingData.updateCheckStateDownward(item, item->checkState(0), true);
+    loggingData.updateCheckStateUpward(item->parent(), true);
+    widget.treeWidgetLoggingNames->blockSignals(false);
+}
+
+void armarx::RobotUnitPluginWidgetController::on_pushButtonLoggingMark1_clicked()
+{
+    if (!loggingData.handle)
+    {
+        return;
+    }
+    const auto mark = widget.lineEditLoggingMark1->text().toStdString();
+    ARMARX_INFO << "set mark " << mark;
+    robotUnitPrx->addMarkerToRtLog(loggingData.handle, mark);
+}
+
+void armarx::RobotUnitPluginWidgetController::on_pushButtonLoggingMark2_clicked()
+{
+    if (!loggingData.handle)
+    {
+        return;
+    }
+    const auto mark = widget.lineEditLoggingMark2->text().toStdString();
+    ARMARX_INFO << "set mark " << mark;
+    robotUnitPrx->addMarkerToRtLog(loggingData.handle, mark);
+}
+
+void armarx::RobotUnitPluginWidgetController::on_pushButtonLoggingMark3_clicked()
+{
+    if (!loggingData.handle)
+    {
+        return;
+    }
+    const auto mark = widget.lineEditLoggingMark3->text().toStdString();
+    ARMARX_INFO << "set mark " << mark;
+    robotUnitPrx->addMarkerToRtLog(loggingData.handle, mark);
+}
+
+void RobotUnitPluginWidgetController::LoggingData::updateCheckStateUpward(QTreeWidgetItem* item, bool recurseParents)
+{
+    //set item state depending on its childrens state and maybe recurse parent
+    for (; item; item = recurseParents ? item->parent() : nullptr)
+    {
+        if (item->isHidden())
+        {
+            continue;
+        }
+        bool anyChecked = false;
+        bool anyUnchecked = false;
+        bool anyTri = false;
+        for (int  i = 0; i < item->childCount(); ++i)
+        {
+            auto c = item->child(i);
+            if (c->isHidden())
+            {
+                continue;
+            }
+            switch (c->checkState(0))
+            {
+                case Qt::Checked:
+                    anyChecked = true;
+                    break;
+                case Qt::Unchecked:
+                    anyUnchecked = true;
+                    break;
+                case Qt::PartiallyChecked:
+                    anyTri = true;
+                    break;
+            }
+            if (anyChecked + anyUnchecked + anyTri > 1 || anyTri)
+            {
+                item->setCheckState(0, Qt::PartiallyChecked);
+            }
+            else if (anyChecked)
+            {
+                item->setCheckState(0, Qt::Checked);
+            }
+            else if (anyUnchecked)
+            {
+                item->setCheckState(0, Qt::Unchecked);
+            }
+            //case all false -> leaf -> do nothing
+        }
+    }
+}
+
+void RobotUnitPluginWidgetController::LoggingData::updateCheckStateDownward(
+    QTreeWidgetItem* item,
+    Qt::CheckState state,
+    bool recurseChildren)
+{
+    if (item->isHidden())
+    {
+        return;
+    }
+    item->setCheckState(0, state);
+
+    if (!recurseChildren)
+    {
+        return;
+    }
+    for (int  i = 0; i < item->childCount(); ++i)
+    {
+        auto c = item->child(i);
+        if (c->isHidden())
+        {
+            continue;
+        }
+        c->setCheckState(0, state);
+        updateCheckStateDownward(c, state, true);
+    }
+}
diff --git a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.h b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.h
index 9b57ef2d510a9c2ce896e86a36dbab461e9e7a12..06270ecbc7e9c7280fac72f6dac959e504db26bd 100644
--- a/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.h
+++ b/source/RobotAPI/gui-plugins/RobotUnitPlugin/RobotUnitPlugin/RobotUnitPluginWidgetController.h
@@ -132,11 +132,21 @@ namespace armarx
         void refreshNJointControllerClassesClicked();
         void refreshControlDevicesClicked();
         void refreshSensorDevicesClicked();
+        void refreshLogging();
 
         void writeLogClicked();
 
         void startOnConnectTimer();
 
+        //logging
+        void on_lineEditLoggingFilter_textChanged(const QString& arg1);
+        void on_pushButtonLoggingStop_clicked();
+        void on_pushButtonLoggingStart_clicked();
+        void on_treeWidgetLoggingNames_itemChanged(QTreeWidgetItem* item, int column);
+        void on_pushButtonLoggingMark1_clicked();
+        void on_pushButtonLoggingMark2_clicked();
+        void on_pushButtonLoggingMark3_clicked();
+
     private:
         void timerEvent(QTimerEvent*) override;
         void updateToolBarActionCheckedState();
@@ -162,6 +172,17 @@ namespace armarx
         QPointer<QAction> showSDevs;
         QPointer<QAction> showNJoint;
         QPointer<QAction> showNJointClasses;
+        QPointer<QAction> showLogging;
+
+        struct LoggingData
+        {
+            QTreeWidgetItem* top;
+            std::vector<QTreeWidgetItem*> allItems;
+            RemoteReferenceCounterBasePtr handle;
+            static void updateCheckStateUpward(QTreeWidgetItem* item, bool recurseParents);
+            static void updateCheckStateDownward(QTreeWidgetItem* item, Qt::CheckState state, bool recurseChildren);
+        };
+        LoggingData loggingData;
 
         int onConnectTimerId;
     };