<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: priestly</title>
    <description>The latest articles on DEV Community by priestly (@priestlyops).</description>
    <link>https://dev.to/priestlyops</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4237487%2F059c3c5f-eca8-4f8f-b760-2035b5e70568.png</url>
      <title>DEV Community: priestly</title>
      <link>https://dev.to/priestlyops</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/priestlyops"/>
    <language>en</language>
    <item>
      <title>I Told a Simulated Robot to Stop. It Kept Moving Another Half Meter.</title>
      <dc:creator>priestly</dc:creator>
      <pubDate>Wed, 11 Nov 2026 00:46:29 +0000</pubDate>
      <link>https://dev.to/priestlyops/i-told-a-simulated-robot-to-stop-it-kept-moving-another-half-meter-4744</link>
      <guid>https://dev.to/priestlyops/i-told-a-simulated-robot-to-stop-it-kept-moving-another-half-meter-4744</guid>
      <description>&lt;h1&gt;
  
  
  I Told a Simulated Robot to Stop. It Kept Moving Another Half Meter.
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;What 60 Gazebo scenario observations taught me about stop commands, motion evidence, and the limits of sensor agreement.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ROS 2 · Gazebo Sim · Python · Robotics Reliability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I sent a stop command to a simulated robot. The command was published successfully—but it went to the wrong topic.&lt;/p&gt;

&lt;p&gt;The robot continued moving.&lt;/p&gt;

&lt;p&gt;Across 20 repetitions of this deliberately injected fault, the robot traveled an average of &lt;strong&gt;0.5225 meters&lt;/strong&gt; after the faulty stop command.&lt;/p&gt;

&lt;p&gt;This wasn't a malfunction I discovered by accident. I created the failure deliberately to investigate a straightforward robotics question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we know a robot actually stopped, rather than simply knowing that software sent a stop command?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That question led me to build &lt;strong&gt;Stop Evidence Monitor (SEM)&lt;/strong&gt;, an open-source ROS 2 research prototype that evaluates whether a stop request has supporting command and motion evidence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/priestly-ops/stop-evidence-monitor" rel="noopener noreferrer"&gt;View the source code on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The problem: A stop command is not a stopped robot
&lt;/h2&gt;

&lt;p&gt;Autonomous robots rely on several software components communicating with one another.&lt;/p&gt;

&lt;p&gt;A navigation system may generate velocity commands, which travel through ROS 2 topics and eventually reach a controller.&lt;/p&gt;

&lt;p&gt;But what happens when something breaks along that path?&lt;/p&gt;

&lt;p&gt;Consider a simple case: a navigation component publishes a zero-velocity command, but the message is sent to a topic the robot's drivetrain does not consume.&lt;/p&gt;

&lt;p&gt;The command publication succeeds. Meanwhile, the real velocity-command topic continues receiving forward commands.&lt;/p&gt;

&lt;p&gt;A naive check that treats successful publication as proof of stopping would miss the problem.&lt;/p&gt;

&lt;p&gt;This is an illustrative command-only baseline, &lt;strong&gt;not a separately benchmarked safety controller&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I wanted to explore whether observing the commands actually reaching the motion topic, alongside evidence of physical movement, could provide a more informative result.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Reproducing the failure in Gazebo
&lt;/h2&gt;

&lt;p&gt;I used Gazebo's differential-drive reference robot, &lt;code&gt;vehicle_blue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For the experiment, I constructed a controlled world containing a fixed wall and a front-facing LiDAR sensor.&lt;/p&gt;

&lt;p&gt;The robot received forward commands on its normal motion topic:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/model/vehicle_blue/cmd_vel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then I deliberately published the stop command to an unconnected topic:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/model/vehicle_blue/unconnected_stop&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The forward-command source continued running.&lt;/p&gt;

&lt;p&gt;As expected, the robot did not stop merely because a zero-velocity command had been published somewhere in the system.&lt;/p&gt;

&lt;p&gt;This gave me a reproducible failure scenario against which to test the monitoring logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[Insert the Gazebo + terminal demonstration video here]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Video caption: A separately recorded demonstration of the injected wrong-topic fault. SEM reports &lt;code&gt;STOP_FAILED&lt;/code&gt;. The video run measured 0.50772 m of continued motion; the 20-run benchmark mean reported below is 0.5225 m.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Building the Stop Evidence Monitor
&lt;/h2&gt;

&lt;p&gt;SEM is an observation layer, not a replacement navigation controller.&lt;/p&gt;

&lt;p&gt;It assesses three pieces of information:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The stop request:&lt;/strong&gt; When did the system request a stop?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Downstream commands:&lt;/strong&gt; What velocity commands are actually visible on the drivetrain's command topic?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Motion evidence:&lt;/strong&gt; Does an independently observed measurement support standstill or continued motion?&lt;/p&gt;

&lt;p&gt;For the live Gazebo experiment, I used changes in LiDAR distance to a static wall to estimate longitudinal movement.&lt;/p&gt;

&lt;p&gt;This avoided relying on wheel odometry as the primary motion measurement in that experiment.&lt;/p&gt;

&lt;p&gt;The monitor produces three key outcomes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;STOP_EVIDENCED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Available measurements support standstill under defined assumptions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;STOP_FAILED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Observed commands or motion violate the expected stop behavior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UNVERIFIABLE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The evidence is insufficient to support a stop conclusion&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The rule I wanted to preserve was simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Missing evidence must never be interpreted as proof that a robot stopped.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The experiment also used Gazebo's model pose as an evaluation reference. That ground-truth pose was not supplied to SEM's decision-making logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Testing the approach: 20 complete simulation trials
&lt;/h2&gt;

&lt;p&gt;My initial experiment demonstrated the expected behavior once. But a single successful run provides very limited evidence about repeatability.&lt;/p&gt;

&lt;p&gt;I therefore repeated the experiment &lt;strong&gt;20 times&lt;/strong&gt;, restarting the Gazebo simulation world before each complete trial.&lt;/p&gt;

&lt;p&gt;Every trial contained three scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Normal stop:&lt;/strong&gt; The robot received valid zero-velocity commands and was expected to stop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Misrouted stop:&lt;/strong&gt; The stop command was deliberately sent to the wrong topic while forward commands continued.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing LiDAR:&lt;/strong&gt; Motion observations were deliberately withheld from the monitor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That produced &lt;strong&gt;20 complete trials and 60 scenario observations&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Expected SEM result&lt;/th&gt;
&lt;th&gt;Observed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Normal stop&lt;/td&gt;
&lt;td&gt;&lt;code&gt;STOP_EVIDENCED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Misrouted stop&lt;/td&gt;
&lt;td&gt;&lt;code&gt;STOP_FAILED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing LiDAR&lt;/td&gt;
&lt;td&gt;&lt;code&gt;UNVERIFIABLE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All 20 complete trials produced the expected classifications.&lt;/p&gt;

&lt;p&gt;In the misrouted-stop scenario, the measured movement after the faulty command was:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measurement&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mean displacement&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.5225 m&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sample standard deviation&lt;/td&gt;
&lt;td&gt;0.0024 m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Minimum displacement&lt;/td&gt;
&lt;td&gt;0.5173 m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maximum displacement&lt;/td&gt;
&lt;td&gt;0.5281 m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observed false stop confirmations in this scenario&lt;/td&gt;
&lt;td&gt;0/20&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The small standard deviation is important to interpret correctly.&lt;/p&gt;

&lt;p&gt;All 20 repetitions used the same robot model, world layout, command settings, and monitor thresholds. The tests did not deliberately introduce randomized environments or different motion profiles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;These results demonstrate repeatability in a controlled, nearly deterministic simulation—not robustness to real-world variation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The original single-run M4 experiment recorded 0.5046 m. The implementation's source hash matches the later repeatability campaign, but the recorded data does not establish the precise cause of the displacement difference. Execution and observation timing are plausible contributors.&lt;/p&gt;

&lt;p&gt;The repeated-run statistics above are therefore the primary quantitative results of this article.&lt;/p&gt;

&lt;p&gt;The experiment also did not measure detection latency or demonstrate any hardware safety guarantees.&lt;/p&gt;

&lt;p&gt;The complete results are available in the &lt;a href="https://github.com/priestly-ops/stop-evidence-monitor/tree/main/evidence/m4_repeat20" rel="noopener noreferrer"&gt;20-run evidence directory&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. The most important limitation: What happens when two sensors lie?
&lt;/h2&gt;

&lt;p&gt;The repeated Gazebo tests produced the expected outcomes.&lt;/p&gt;

&lt;p&gt;However, the more important challenge emerged during adversarial software testing.&lt;/p&gt;

&lt;p&gt;Imagine a robot that is still moving, but its sensors report otherwise.&lt;/p&gt;

&lt;p&gt;The LiDAR returns constant distance measurements with plausible increasing timestamps. Wheel odometry also reports zero velocity. The downstream command appears to be zero.&lt;/p&gt;

&lt;p&gt;SEM can interpret those consistent observations as standstill evidence, even though the robot is assumed to be moving.&lt;/p&gt;

&lt;p&gt;In a synthetic test, this produced &lt;code&gt;STOP_EVIDENCED&lt;/code&gt; under the false stationary measurements.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Two sensors agreeing does not necessarily mean both sensors are telling the truth.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a fundamental limitation of interpreting sensor agreement as physical truth.&lt;/p&gt;

&lt;p&gt;The failure was demonstrated with synthetic evidence; the test did not involve a second live robot-motion experiment.&lt;/p&gt;

&lt;p&gt;I documented this behavior as an unresolved limitation rather than hiding it behind the successful test counts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/priestly-ops/stop-evidence-monitor/issues/1" rel="noopener noreferrer"&gt;Read the known-failure issue on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What do 41 passing tests actually mean?
&lt;/h2&gt;

&lt;p&gt;The software test suite completed 41 tests:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;40 expected-behavior tests&lt;/strong&gt; examine the monitor's responses to scenarios such as normal stopping, movement after a stop request, stale measurements, missing evidence, contradictory inputs, and timing conditions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1 known-failure characterization test&lt;/strong&gt; deliberately reproduces the correlated-sensor false-confirmation vulnerability.&lt;/p&gt;

&lt;p&gt;All 41 tests passed.&lt;/p&gt;

&lt;p&gt;But the interpretation matters.&lt;/p&gt;

&lt;p&gt;A passing test that successfully reproduces a known failure is evidence that the failure was demonstrated—not that the underlying problem was fixed.&lt;/p&gt;

&lt;p&gt;Similarly, the 20 repeated Gazebo trials do not tell us how often SEM would make an incorrect decision on an unfamiliar physical robot.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. How does this relate to existing robotics safety systems?
&lt;/h2&gt;

&lt;p&gt;Robotic systems already use command timeouts, watchdogs, controller monitoring, and hardware safety functions.&lt;/p&gt;

&lt;p&gt;For example, ROS 2 Control's &lt;code&gt;diff_drive_controller&lt;/code&gt; provides command-timeout behavior and supports hardware-based odometry feedback.&lt;/p&gt;

&lt;p&gt;These mechanisms are important, and SEM does not replace them.&lt;/p&gt;

&lt;p&gt;My experiment explores a narrower question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can an additional ROS 2 observation layer distinguish selected failed-stop conditions from situations where the available evidence supports standstill?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This prototype does not establish novelty over industrial safe-standstill monitoring or certified safety controllers.&lt;/p&gt;

&lt;p&gt;It is also not a collision-prevention system.&lt;/p&gt;

&lt;p&gt;SEM cannot guarantee physical standstill, detect every correlated fault, or assess every direction of movement. Its demonstrated LiDAR estimator was specifically designed for longitudinal motion toward a static wall.&lt;/p&gt;

&lt;p&gt;No physical robot experiments or safety certification were performed.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. What I learned
&lt;/h2&gt;

&lt;p&gt;This project started with a small question about a stop command.&lt;/p&gt;

&lt;p&gt;It became an exercise in understanding what software can actually conclude from the evidence it receives.&lt;/p&gt;

&lt;p&gt;The controlled experiments showed that SEM could detect a deliberately misrouted stop, support a normal-stop conclusion, and report uncertainty when LiDAR evidence was unavailable.&lt;/p&gt;

&lt;p&gt;The adversarial testing exposed something equally valuable: a system can be completely consistent internally and still reach the wrong conclusion when its evidence sources are misleading.&lt;/p&gt;

&lt;p&gt;That is why I think robotics reliability needs careful attention not only to sensor measurements, but also to their assumptions, freshness, dependencies, and observability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SEM v0.1.0-sim is a simulation-validated research prototype, not a certified safety system or a general solution to robot stop verification.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've made the source code, experiments, and known limitations available for others to inspect, reproduce, and challenge.&lt;/p&gt;

&lt;p&gt;I'd especially welcome feedback from robotics engineers working with ROS 2, mobile robot controllers, state estimation, and runtime monitoring.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project resources
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/priestly-ops/stop-evidence-monitor" rel="noopener noreferrer"&gt;https://github.com/priestly-ops/stop-evidence-monitor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Research pre-release:&lt;/strong&gt; &lt;a href="https://github.com/priestly-ops/stop-evidence-monitor/releases/tag/v0.1.0-sim" rel="noopener noreferrer"&gt;https://github.com/priestly-ops/stop-evidence-monitor/releases/tag/v0.1.0-sim&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;20-run experimental evidence:&lt;/strong&gt; &lt;a href="https://github.com/priestly-ops/stop-evidence-monitor/tree/main/evidence/m4_repeat20" rel="noopener noreferrer"&gt;https://github.com/priestly-ops/stop-evidence-monitor/tree/main/evidence/m4_repeat20&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Known failure:&lt;/strong&gt; &lt;a href="https://github.com/priestly-ops/stop-evidence-monitor/issues/1" rel="noopener noreferrer"&gt;https://github.com/priestly-ops/stop-evidence-monitor/issues/1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related ROS 2 Control documentation:&lt;/strong&gt; &lt;a href="https://control.ros.org/master/doc/ros2_controllers/diff_drive_controller/doc/userdoc.html" rel="noopener noreferrer"&gt;https://control.ros.org/master/doc/ros2_controllers/diff_drive_controller/doc/userdoc.html&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article reports controlled simulation experiments and synthetic software tests. It makes no claim of hardware safety certification or reliability in arbitrary environments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>robotics</category>
      <category>ros2</category>
      <category>python</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
