diff --git a/src/object_locator.cpp b/src/object_locator.cpp
index b23630fc608f01e3efa2f4d5de648ed6ea80353e..6cabdfea7116b3d2f24119e4b4f9722d2924b6eb 100644
--- a/src/object_locator.cpp
+++ b/src/object_locator.cpp
@@ -6,6 +6,8 @@
     \date 15.06.22
 */
 
+#include <cmath>
+
 #include <ros/ros.h>
 #include <ros/package.h>
 #include <apriltag_ros/AprilTagDetectionArray.h>
@@ -17,7 +19,6 @@
 #include "ccf/util/NodeUtil.h"
 
 #include "Scene.pb.h"
-#include "google/protobuf/text_format.h"
 
 #include <google/protobuf/util/json_util.h>
 #include <google/protobuf/message.h>
@@ -31,6 +32,8 @@ const std::string CELL_BUNDLE = "CETI_TABLE_ONE";
 const double TABLE_HEIGHT = 0.89;
 const double GRID_SIZE = 0.05;
 const double MAX_ERROR = 0.02;
+const bool RISKY_MODE = true;
+const bool SNAP_TO_GRID = true;
 
 double distanceToGrid(geometry_msgs::Point point, double grid_size)
 {
@@ -57,26 +60,23 @@ int main(int argc, char** argv)
   ros::NodeHandle n("ccf");
 
   ros::Rate loop_rate(200);
-  ros::Rate pause_rate(ros::Duration(2));  // seconds
 
-  pause_rate.sleep();
+  ros::Duration(2).sleep(); // sleep for two seconds
 
   DummyRobotArmController controller(n, "object_locator", "nobot");
 
   auto mqttServer = getPrivateParameter<std::string>("mqtt_server", "localhost:1883");
-  std::unique_ptr<MqttConnection> mqtt_connection =
+  std::shared_ptr<MqttConnection> mqtt_connection =
       std::make_unique<MqttConnection>(mqttServer, ros::this_node::getName());
-  mqtt_connection->listen(getParameter<std::string>(n, "topics/selection", "selection"));
-  auto other_cell_scene_listener_topic =
-      getPrivateParameter<std::string>("other_cell_listener", "/ceti_cell_1"
-                                       "/scene/update");
-  auto other_cell_delta_update_topic =
+  auto observed_scene_listener_topic =
+      getPrivateParameter<std::string>("other_cell_listener", "/ceti_cell_1/scene/update");
+  auto observed_scene_delta_update_topic =
       getPrivateParameter<std::string>("other_cell_delta_updates", "object_locator/scene/update");
-  mqtt_connection->listen(other_cell_scene_listener_topic);
-  controller.addConnection(std::move(mqtt_connection));
+  controller.addConnection(mqtt_connection);
+  mqtt_connection->listen(observed_scene_listener_topic);
 
   // subscribe to a scene
-  controller.addCallback(other_cell_scene_listener_topic, [&controller](auto msg) {
+  controller.addCallback(observed_scene_listener_topic, [&controller](auto msg) {
     ROS_INFO_STREAM("Updating scene from other cell.");
     Scene scene;
     scene.ParseFromString(msg);
@@ -90,7 +90,7 @@ int main(int argc, char** argv)
                                                                                                           "objects."
                                                                                                           "json"));
 
-  ROS_ERROR_STREAM("object library contains " << objectLibrary.objects_size() << " objects");
+  ROS_DEBUG_STREAM("object library contains " << objectLibrary.objects_size() << " objects");
 
   std::map<std::string, geometry_msgs::Pose> located_poses;
 
@@ -161,11 +161,13 @@ int main(int argc, char** argv)
           tf2::Quaternion q{ pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w };
           std::cout.precision(3);
 
-          if (controller.resolveObject(name))
+          auto existingObject = controller.resolveObject(name);  // we need this also later to check if pose has changed
+          if (!RISKY_MODE && existingObject)
           {
             ROS_DEBUG_STREAM("skipping pose for " << name << " the object is already in the scene.");
             continue;
           }
+
           if (pose.orientation.w < 0.99)
           {
             ROS_WARN_STREAM("skipping pose for " << name << " because the object is rotated " << pose.orientation << " "
@@ -179,21 +181,48 @@ int main(int argc, char** argv)
             continue;
           }
           double e = distanceToGrid(pose.position, GRID_SIZE);
-          ROS_ERROR_STREAM("object " << name << " has an error of " << e);
+          ROS_DEBUG_STREAM("object " << name << " has an error of " << e);
 
           // sanitize pose
-          relevant_poses[name] = pose;
-          relevant_poses[name].position.z = TABLE_HEIGHT;
-          relevant_poses[name].position = closestGridPoint(relevant_poses[name].position, GRID_SIZE);
-          relevant_poses[name].orientation.x = 0;
-          relevant_poses[name].orientation.y = 0;
-          relevant_poses[name].orientation.z = 0;
-          relevant_poses[name].orientation.w = 1;
-
-          if (located_poses[name] == relevant_poses[name])
+          if (SNAP_TO_GRID)
+          {
+            relevant_poses[name] = pose;
+            relevant_poses[name].position.z = TABLE_HEIGHT;
+            relevant_poses[name].position = closestGridPoint(relevant_poses[name].position, GRID_SIZE);
+            relevant_poses[name].orientation.x = 0;
+            relevant_poses[name].orientation.y = 0;
+            relevant_poses[name].orientation.z = 0;
+            relevant_poses[name].orientation.w = 1;
+
+            if (RISKY_MODE && existingObject)
+            {
+              double dx = existingObject->pos().x() - relevant_poses[name].position.x;
+              double dy = existingObject->pos().y() - relevant_poses[name].position.y;
+              double distance = std::sqrt(dx * dx + dy * dy);
+              if (distance < GRID_SIZE / 2)
+              {
+                ROS_DEBUG_STREAM("Skipping object  " << name << " because its location has not changed.");
+                continue;
+              }
+              else
+              {
+                ROS_DEBUG_STREAM("Sending object  " << name << " because its location has changed by " << distance);
+              }
+            }
+          }
+
+          if (RISKY_MODE || located_poses[name] == relevant_poses[name])
           {
-            ROS_DEBUG_STREAM("found the same pose for " + name + " two times in a row: "
-                             << relevant_poses[name].position.x << ", " << relevant_poses[name].position.y);
+            if (RISKY_MODE)
+            {
+              ROS_DEBUG_STREAM("found the new pose for " + name + ": " << relevant_poses[name].position.x << ", "
+                                                                       << relevant_poses[name].position.y);
+            }
+            else
+            {
+              ROS_DEBUG_STREAM("found the same pose for " + name + " two times in a row: "
+                               << relevant_poses[name].position.x << ", " << relevant_poses[name].position.y);
+            }
             auto object = DummyRobotArmController::resolveObject(name, objectLibrary);
             if (!object)
             {
@@ -205,29 +234,22 @@ int main(int argc, char** argv)
             newObject->mutable_pos()->set_x(located_poses[name].position.x);
             newObject->mutable_pos()->set_y(located_poses[name].position.y);
             newObject->mutable_pos()->set_z(located_poses[name].position.z + newObject->size().height() / 2);
-            newObject->set_mode(Object_Mode_MODE_ADD);
+            newObject->set_mode(existingObject ? Object_Mode_MODE_MODIFY : Object_Mode_MODE_ADD);
             newObject->set_state(Object_State_STATE_STATIONARY);
           }
         }
 
         if (updateScene.objects_size() > 0)
         {
-          ROS_ERROR_STREAM("Sending scene with " << updateScene.objects_size() << " newly recognized objects.");
-          controller.sendToAll(other_cell_delta_update_topic, updateScene.SerializeAsString());
+          ROS_DEBUG_STREAM("Sending scene with " << updateScene.objects_size() << " newly recognized or updated objects.");
+          controller.sendToAll(observed_scene_delta_update_topic, updateScene.SerializeAsString());
         }
         located_poses = relevant_poses;
       });
 
-  // receive a tag position
-  // if no "base tag" is contained, abort
-  // if the contained objects are already in the robot scene, abort (we only detect new objects)
-  // if the object tag is not in the base scene, abort
-  // find the drop-of location in the scene that is closest to the
-
   while (ros::ok())
   {
     ros::spinOnce();
-
     loop_rate.sleep();
   }