diff --git a/source/RobotAPI/libraries/armem_robot_state/server/common/Visu.cpp b/source/RobotAPI/libraries/armem_robot_state/server/common/Visu.cpp
index be19db6355d9c21e0b9a7e287e5889024a0c408c..c5f3fe36a067f6969e2c09b238ac1ed473422c2b 100644
--- a/source/RobotAPI/libraries/armem_robot_state/server/common/Visu.cpp
+++ b/source/RobotAPI/libraries/armem_robot_state/server/common/Visu.cpp
@@ -9,7 +9,6 @@
 #include <SimoxUtility/algorithm/get_map_keys_values.h>
 #include <SimoxUtility/math/pose.h>
 #include <SimoxUtility/math/rescale.h>
-
 #include <VirtualRobot/XML/RobotIO.h>
 
 #include <ArmarXCore/core/logging/Logging.h>
@@ -17,10 +16,8 @@
 #include <ArmarXCore/core/time/TimeUtil.h>
 #include <ArmarXCore/interface/core/PackagePath.h>
 
-#include <RobotAPI/libraries/armem/core/Time.h>
-
 #include <RobotAPI/components/ArViz/Client/Elements.h>
-
+#include <RobotAPI/libraries/armem/core/Time.h>
 #include <RobotAPI/libraries/armem_robot_state/server/description/Segment.h>
 #include <RobotAPI/libraries/armem_robot_state/server/localization/Segment.h>
 #include <RobotAPI/libraries/armem_robot_state/server/proprioception/Segment.h>
@@ -28,40 +25,43 @@
 
 #include "combine.h"
 
-
 namespace armarx::armem::server::robot_state
 {
 
-    Visu::Visu(
-        const description::Segment& descriptionSegment,
-        const proprioception::Segment& proprioceptionSegment,
-        const localization::Segment& localizationSegment)
-        : descriptionSegment(descriptionSegment),
-          proprioceptionSegment(proprioceptionSegment),
-          localizationSegment(localizationSegment)
+    Visu::Visu(const description::Segment& descriptionSegment,
+               const proprioception::Segment& proprioceptionSegment,
+               const localization::Segment& localizationSegment) :
+        descriptionSegment(descriptionSegment),
+        proprioceptionSegment(proprioceptionSegment),
+        localizationSegment(localizationSegment)
     {
         Logging::setTag("Visu");
     }
 
-
-    void Visu::defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix)
+    void
+    Visu::defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix)
     {
-        defs->optional(p.enabled, prefix + "enabled", "Enable or disable visualization of objects.");
+        defs->optional(
+            p.enabled, prefix + "enabled", "Enable or disable visualization of objects.");
         defs->optional(p.frequencyHz, prefix + "frequenzyHz", "Frequency of visualization.");
-        defs->optional(p.framesEnabled, prefix + "framesEnabled", "Enable or disable visualization of frames.");
-        defs->optional(p.forceTorque.enabled, prefix + "forceTorque.enabled",
+        defs->optional(p.framesEnabled,
+                       prefix + "framesEnabled",
+                       "Enable or disable visualization of frames.");
+        defs->optional(p.forceTorque.enabled,
+                       prefix + "forceTorque.enabled",
                        "Enable or disable visualization of force torque sensors.");
-        defs->optional(p.forceTorque.forceScale, prefix + "forceTorque.forceScale",
+        defs->optional(p.forceTorque.forceScale,
+                       prefix + "forceTorque.forceScale",
                        "Scaling of force arrows.");
     }
 
-
-    void Visu::init()
+    void
+    Visu::init()
     {
     }
 
-
-    void Visu::connect(const viz::Client& arviz, DebugObserverInterfacePrx debugObserver)
+    void
+    Visu::connect(const viz::Client& arviz, DebugObserverInterfacePrx debugObserver)
     {
         this->arviz = arviz;
         if (debugObserver)
@@ -76,15 +76,12 @@ namespace armarx::armem::server::robot_state
             updateTask->join();
             updateTask = nullptr;
         }
-        updateTask = new SimpleRunningTask<>([this]()
-        {
-            this->visualizeRun();
-        });
+        updateTask = new SimpleRunningTask<>([this]() { this->visualizeRun(); });
         updateTask->start();
     }
 
-
-    void Visu::visualizeRobots(viz::Layer& layer, const robot::Robots& robots)
+    void
+    Visu::visualizeRobots(viz::Layer& layer, const robot::Robots& robots)
     {
         for (const robot::Robot& robot : robots)
         {
@@ -103,8 +100,8 @@ namespace armarx::armem::server::robot_state
         }
     }
 
-
-    void Visu::visualizeFrames(
+    void
+    Visu::visualizeFrames(
         viz::Layer& layerFrames,
         const std::unordered_map<std::string, std::vector<Eigen::Affine3f>>& frames)
     {
@@ -120,12 +117,14 @@ namespace armarx::armem::server::robot_state
 
                 pose = to;
 
-                layerFrames.add(viz::Arrow(robotName + std::to_string(++i)).fromTo(from.translation(), to.translation()));
+                layerFrames.add(viz::Arrow(robotName + std::to_string(++i))
+                                    .fromTo(from.translation(), to.translation()));
             }
         }
     }
 
-    void Visu::visualizeFramesIndividual(
+    void
+    Visu::visualizeFramesIndividual(
         viz::Layer& layerFrames,
         const std::unordered_map<std::string, std::vector<Eigen::Affine3f>>& frames)
     {
@@ -137,14 +136,14 @@ namespace armarx::armem::server::robot_state
             int i = 0;
             for (const auto& frame : robotFrames)
             {
-                layerFrames.add(viz::Pose(robotName + FRAME_NAMES.at(i++)).pose(frame.matrix()).scale(3));
+                layerFrames.add(
+                    viz::Pose(robotName + FRAME_NAMES.at(i++)).pose(frame.matrix()).scale(3));
             }
         }
     }
 
-
-
-    void Visu::visualizeRun()
+    void
+    Visu::visualizeRun()
     {
         CycleUtil cycle(static_cast<int>(1000 / p.frequencyHz));
         while (updateTask and not updateTask->isStopped())
@@ -158,6 +157,11 @@ namespace armarx::armem::server::robot_state
                 {
                     visualizeOnce(timestamp);
                 }
+                catch (const std::out_of_range& e)
+                {
+                    ARMARX_WARNING << "Caught std::out_of_range while visualizing robots: \n"
+                                   << e.what();
+                }
                 catch (const std::exception& e)
                 {
                     ARMARX_WARNING << "Caught exception while visualizing robots: \n" << e.what();
@@ -176,8 +180,8 @@ namespace armarx::armem::server::robot_state
         }
     }
 
-
-    void Visu::visualizeOnce(const Time& timestamp)
+    void
+    Visu::visualizeOnce(const Time& timestamp)
     {
         TIMING_START(tVisuTotal);
 
@@ -200,9 +204,9 @@ namespace armarx::armem::server::robot_state
         TIMING_END_STREAM(tRobotFramePoses, ARMARX_DEBUG);
 
         TIMING_START(tSensorValues);
-        const auto sensorValues =
-            proprioceptionSegment.getSensorValuesLocking(
-                timestamp, debugObserver ? &*debugObserver : nullptr);
+        const proprioception::SensorValuesMap sensorValues =
+            proprioceptionSegment.getSensorValuesLocking(timestamp,
+                                                         debugObserver ? &*debugObserver : nullptr);
         TIMING_END_STREAM(tSensorValues, ARMARX_DEBUG);
 
         TIMING_END_STREAM(tVisuGetData, ARMARX_DEBUG);
@@ -225,83 +229,51 @@ namespace armarx::armem::server::robot_state
             combine(robotDescriptions, globalPoses, sensorValues, timestamp);
 
         ARMARX_DEBUG << "Visualize " << robots.size() << " robots ...";
-        viz::Layer layer = arviz.layer("Robots");
-        visualizeRobots(layer, robots);
-        std::vector layers{layer};
+        std::vector<viz::Layer> layers;
+
+        {
+            viz::Layer& layer = layers.emplace_back(arviz.layer("Robots"));
+            visualizeRobots(layer, robots);
+        }
 
         ARMARX_DEBUG << "Visualize frames ...";
-        if(p.framesEnabled)
+        if (p.framesEnabled)
         {
-            viz::Layer layerFrames = arviz.layer("Frames");
-            visualizeFrames(layerFrames, frames);
-            layers.push_back(layerFrames);
+            viz::Layer& layer = layers.emplace_back(arviz.layer("Localization Frames"));
+            visualizeFrames(layer, frames);
         }
 
         TIMING_END_STREAM(tVisuBuildLayers, ARMARX_DEBUG);
 
         {
-            viz::Layer layerFrames = arviz.layer("FramesIndividual");
-            visualizeFramesIndividual(layerFrames, frames);
-            layers.push_back(layerFrames);
+            viz::Layer& layer = layers.emplace_back(arviz.layer("Localization Frames Individual"));
+            visualizeFramesIndividual(layer, frames);
         }
 
         if (p.forceTorque.enabled)
         {
-            viz::Layer layerFrames = arviz.layer("ForceTorque");
+            viz::Layer& layerForceTorque = layers.emplace_back(arviz.layer("Force Torque"));
+            std::stringstream log;
+
             for (const robot::Robot& robot : robots)
             {
-                const std::string& name = robot.description.name;
-                if (robotNameHelper.find(name) == robotNameHelper.end())
-                {
-                    const std::filesystem::path robotPath = robot.description.xml.toSystemPath();
-                    robotNameHelper[name] = RobotNameHelper::Create(robotPath);
-                    robotModels[name]
-                        = VirtualRobot::RobotIO::loadRobot(robotPath, VirtualRobot::RobotIO::eStructure);
-                }
-
-                auto model = robotModels.at(name);
-                model->setJointValues(robot.config.jointMap);
-                model->setGlobalPose(robot.config.globalPose.matrix());
+                const std::string& robotName = robot.description.name;
 
-                const proprioception::ForceTorqueValuesMap& forceTorques
-                    = sensorValues.at(name).forceTorqueValuesMap;
-
-                for (const auto& [side, ft] : forceTorques)
+                auto itSensorValues = sensorValues.find(robotName);
+                if (itSensorValues == sensorValues.end())
                 {
-                    ARMARX_CHECK(side == RobotNameHelper::LocationLeft or side == RobotNameHelper::LocationRight) << side;
-
-                    const std::string forceTorqueSensorName =
-                        robotNameHelper.at(name)->getArm(side).getForceTorqueSensor();
-
-                    const Eigen::Matrix4f forceTorqueSensorPose
-                        = model->getSensor(forceTorqueSensorName)->getGlobalPose();
-
-                    const std::string xyz = "XYZ";
-
-                    const Eigen::Vector3f from = simox::math::position(forceTorqueSensorPose);
-                    for (int i = 0; i < 3; ++i)
-                    {
-                        simox::Color color = simox::Color((255 * Eigen::Matrix3i::Identity().col(i)).eval());
-                        color.a = 128;
-
-                        // Force arrows.
-                        const float length = p.forceTorque.forceScale * ft.force(i);                        
-                        const float width = std::min(
-                            simox::math::rescale(std::abs(length), 0.F, 100.F, 1.F, 10.F),
-                            10.F);
-
-                        const Eigen::Vector3f to = from + length * simox::math::orientation(forceTorqueSensorPose).col(i);
-
-                        std::stringstream key;
-                        key << side << " Force " << xyz.at(i);
-                        layerFrames.add(viz::Arrow(key.str()).fromTo(from, to).color(color).width(width));
-
-                        // Torque circle arrows.
-                    }
+                    log << "\nNo robot '" << robotName << "' in sensor values. Available are: ";
+                    log << simox::alg::join(simox::alg::get_keys(sensorValues), ", ");
+                    continue;
                 }
 
+                visualizeForceTorque(layerForceTorque, robot, itSensorValues->second);
+            }
+
+            if (not log.str().empty())
+            {
+                ARMARX_INFO << "While visualizing robot force torques: " << log.str();
             }
-            layers.push_back(layerFrames);
         }
 
 
@@ -317,15 +289,99 @@ namespace armarx::armem::server::robot_state
         if (debugObserver.has_value())
         {
             const std::string p = "Visu | ";
-            debugObserver->setDebugObserverDatafield(p + "t Total (ms)", tVisuTotal.toMilliSecondsDouble());
-            debugObserver->setDebugObserverDatafield(p + "t 1 Get Data (ms)", tVisuGetData.toMilliSecondsDouble());
-            debugObserver->setDebugObserverDatafield(p + "t 1.1 Descriptions (ms)", tRobotDescriptions.toMilliSecondsDouble());
-            debugObserver->setDebugObserverDatafield(p + "t 1.2 Global Poses (ms)", tGlobalPoses.toMilliSecondsDouble());
-            debugObserver->setDebugObserverDatafield(p + "t 1.3 Frames (ms)", tRobotFramePoses.toMilliSecondsDouble());
-            debugObserver->setDebugObserverDatafield(p + "t 1.4 Sensor Values (ms)", tSensorValues.toMilliSecondsDouble());
-            debugObserver->setDebugObserverDatafield(p + "t 2 Build Layers (ms)", tVisuBuildLayers.toMilliSecondsDouble());
-            debugObserver->setDebugObserverDatafield(p + "t 3 Commit (ms)", tVisuCommit.toMilliSecondsDouble());
+            debugObserver->setDebugObserverDatafield(p + "t Total (ms)",
+                                                     tVisuTotal.toMilliSecondsDouble());
+            debugObserver->setDebugObserverDatafield(p + "t 1 Get Data (ms)",
+                                                     tVisuGetData.toMilliSecondsDouble());
+            debugObserver->setDebugObserverDatafield(p + "t 1.1 Descriptions (ms)",
+                                                     tRobotDescriptions.toMilliSecondsDouble());
+            debugObserver->setDebugObserverDatafield(p + "t 1.2 Global Poses (ms)",
+                                                     tGlobalPoses.toMilliSecondsDouble());
+            debugObserver->setDebugObserverDatafield(p + "t 1.3 Frames (ms)",
+                                                     tRobotFramePoses.toMilliSecondsDouble());
+            debugObserver->setDebugObserverDatafield(p + "t 1.4 Sensor Values (ms)",
+                                                     tSensorValues.toMilliSecondsDouble());
+            debugObserver->setDebugObserverDatafield(p + "t 2 Build Layers (ms)",
+                                                     tVisuBuildLayers.toMilliSecondsDouble());
+            debugObserver->setDebugObserverDatafield(p + "t 3 Commit (ms)",
+                                                     tVisuCommit.toMilliSecondsDouble());
+        }
+    }
+
+    void
+    Visu::visualizeForceTorque(viz::Layer& layer,
+                               const robot::Robot& robot,
+                               const proprioception::SensorValues& sensorValues)
+    {
+        const std::string& robotName = robot.description.name;
+
+        RobotModel* robotModel = nullptr;
+        if (auto it = models.find(robotName); it != models.end())
+        {
+            robotModel = &it->second;
+        }
+        else
+        {
+            const std::filesystem::path robotPath = robot.description.xml.toSystemPath();
+            ARMARX_INFO << "Loading robot model for '" << robotName << "' from " << robotPath
+                        << " for visualization.";
+            auto [it2, _] = models.emplace(robotName, robotPath);
+            robotModel = &it2->second;
         }
+
+        robotModel->model->setJointValues(robot.config.jointMap);
+        robotModel->model->setGlobalPose(robot.config.globalPose.matrix());
+
+        const proprioception::ForceTorqueValuesMap& forceTorques =
+            sensorValues.forceTorqueValuesMap;
+
+        for (const auto& [side, ft] : forceTorques)
+        {
+            ARMARX_CHECK(side == RobotNameHelper::LocationLeft or
+                         side == RobotNameHelper::LocationRight)
+                << side;
+
+            const std::string forceTorqueSensorName =
+                robotModel->nameHelper->getArm(side).getForceTorqueSensor();
+
+            const Eigen::Matrix4f forceTorqueSensorPose =
+                robotModel->model->getSensor(forceTorqueSensorName)->getGlobalPose();
+
+            const std::string xyz = "XYZ";
+
+            const Eigen::Vector3f from = simox::math::position(forceTorqueSensorPose);
+            for (int i = 0; i < 3; ++i)
+            {
+                simox::Color color =
+                    simox::Color((255 * Eigen::Matrix3i::Identity().col(i)).eval());
+                color.a = 128;
+
+                // Force arrows.
+                const float length = p.forceTorque.forceScale * ft.force(i);
+                const float width =
+                    std::min(simox::math::rescale(std::abs(length), 0.F, 100.F, 1.F, 10.F), 10.F);
+
+                const Eigen::Vector3f to =
+                    from + length * simox::math::orientation(forceTorqueSensorPose).col(i);
+
+                std::stringstream key;
+                ARMARX_CHECK_FITS_SIZE(i, xyz.size());
+                key << side << " Force " << xyz.at(i);
+                layer.add(viz::Arrow(key.str()).fromTo(from, to).color(color).width(width));
+
+                // TODO: Torque circle arrows.
+            }
+        }
+    }
+
+    Visu::RobotModel::RobotModel(const std::filesystem::path& robotPath) :
+        model{
+            VirtualRobot::RobotIO::loadRobot(robotPath, VirtualRobot::RobotIO::eStructure),
+        },
+        nameHelper{
+            RobotNameHelper::Create(robotPath),
+        }
+    {
     }
 
 } // namespace armarx::armem::server::robot_state
diff --git a/source/RobotAPI/libraries/armem_robot_state/server/common/Visu.h b/source/RobotAPI/libraries/armem_robot_state/server/common/Visu.h
index 265f08e2a0c10153c1b3cc8c624fd214713d57a9..2afa9a27f3396939c625050a942925db79129d64 100644
--- a/source/RobotAPI/libraries/armem_robot_state/server/common/Visu.h
+++ b/source/RobotAPI/libraries/armem_robot_state/server/common/Visu.h
@@ -28,14 +28,10 @@
 #include <ArmarXCore/libraries/DebugObserverHelper/DebugObserverHelper.h>
 
 #include <RobotAPI/components/ArViz/Client/Client.h>
-
+#include <RobotAPI/libraries/RobotStatechartHelpers/RobotNameHelper.h>
 #include <RobotAPI/libraries/armem_objects/types.h>
-
 #include <RobotAPI/libraries/armem_robot_state/server/forward_declarations.h>
 
-#include <RobotAPI/libraries/RobotStatechartHelpers/RobotNameHelper.h>
-
-
 namespace armarx::armem::server::robot_state
 {
 
@@ -46,41 +42,38 @@ namespace armarx::armem::server::robot_state
     class Visu : public armarx::Logging
     {
     public:
-
         Visu(const description::Segment& descriptionSegment,
              const proprioception::Segment& proprioceptionSegment,
              const localization::Segment& localizationSegment);
 
 
-        void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = "visu.");
+        void defineProperties(armarx::PropertyDefinitionsPtr defs,
+                              const std::string& prefix = "visu.");
         void init();
         void connect(const viz::Client& arviz, DebugObserverInterfacePrx debugObserver = nullptr);
 
 
     private:
-
         void visualizeRun();
         void visualizeOnce(const Time& timestamp);
 
 
-        static
-        void visualizeRobots(
-            viz::Layer& layer,
-            const robot::Robots& robots);
+        static void visualizeRobots(viz::Layer& layer, const robot::Robots& robots);
 
-        static
-        void visualizeFrames(
+        static void visualizeFrames(
             viz::Layer& layerFrames,
             const std::unordered_map<std::string, std::vector<Eigen::Affine3f>>& frames);
 
-        static
-        void visualizeFramesIndividual(
+        static void visualizeFramesIndividual(
             viz::Layer& layerFrames,
             const std::unordered_map<std::string, std::vector<Eigen::Affine3f>>& frames);
 
 
-    private:
+        void visualizeForceTorque(viz::Layer& layer,
+                                  const robot::Robot& robot,
+                                  const proprioception::SensorValues& sensorValues);
 
+    private:
         viz::Client arviz;
         std::optional<DebugObserverHelper> debugObserver;
 
@@ -88,9 +81,15 @@ namespace armarx::armem::server::robot_state
         const proprioception::Segment& proprioceptionSegment;
         const localization::Segment& localizationSegment;
 
-        std::map<std::string, RobotNameHelperPtr> robotNameHelper;
-        std::map<std::string, VirtualRobot::RobotPtr> robotModels;
+        struct RobotModel
+        {
+            RobotModel(const std::filesystem::path& robotPath);
+
+            VirtualRobot::RobotPtr model;
+            RobotNameHelperPtr nameHelper;
+        };
 
+        std::map<std::string, RobotModel> models;
 
         struct Properties
         {
@@ -98,18 +97,17 @@ namespace armarx::armem::server::robot_state
             float frequencyHz = 25.f;
 
             bool framesEnabled = false;
-            
+
             struct ForceTorque
             {
                 bool enabled = true;
                 float forceScale = 1.F;
             };
+
             ForceTorque forceTorque;
         } p;
 
-
         SimpleRunningTask<>::pointer_type updateTask;
-
     };
 
-}  // namespace armarx::armem::server::robot_state
+} // namespace armarx::armem::server::robot_state