# Webots Demo 7: Testing a Supervisory Gate Pattern on TIAGo (QERRA-v2 Classical)

**URL:** <https://discourse.openrobotics.org/t/webots-demo-7-testing-a-supervisory-gate-pattern-on-tiago-qerra-v2-classical/58768>\
**Category:** Projects\
**Tags:** ros2, webots, open-source\
**Created:** [October 11, 2026, 12:27pm UTC](https://discourse.openrobotics.org/t/webots-demo-7-testing-a-supervisory-gate-pattern-on-tiago-qerra-v2-classical/58768 "2026-10-11T12:27:59Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![marunigno-ship-it](https://sea2.discourse-cdn.com/flex022/user_avatar/discourse.openrobotics.org/marunigno-ship-it/32/34877_2.png) [@marunigno-ship-it](https://discourse.openrobotics.org/u/marunigno-ship-it)\
**Post date:** [October 11, 2026, 12:27pm UTC](https://discourse.openrobotics.org/t/webots-demo-7-testing-a-supervisory-gate-pattern-on-tiago-qerra-v2-classical/58768/1 "2026-10-11T12:27:59Z")

</div>

Hi everyone,

Following up on my previous posts on deterministic safety reflexes (Demo 6) and Layer 3 ranking rules, I wanted to share the latest simulation milestone from QERRA-v2 Classical: **Webots Demo 7 (Supervisory Gate & Authority Separation)**.

### The Motivation

In ROS 2 mobile bases, we typically route planner commands through twist\_mux or nav2\_collision\_monitor, with watchdog timeouts on cmd\_vel.

In Demo 7, I wanted to explore a stricter, isolated architectural pattern inspired by classical Simplex and doer-checker designs:

- The high-level planner is treated as an **untrusted proposer** running as a separate OS process over non-blocking UDP.
- The **Supervisory Gate** (the Webots controller) is the sole owner of the wheel motor joint handles. The default command is always zero velocity.
- When a hazard occurs or deliberation fails, the gate clamps the motors, latches, and enforces a formal recovery contract before allowing any motion to resume.

### The Scenario: Hospital Corridor Transit

I set up an illustrative healthcare logistics corridor in Webots (R2025a) with a PAL Robotics TIAGo base:

- TIAGo cruises down the corridor at a proposed speed of 2.0 rad/s (~0.196 m/s).
- An obstacle (a platform cart) sits in the active swept path at X = 2.8m.
- The gate continuously evaluates forward Hokuyo lidar ranges (240° FOV, 667 samples) filtered across a 0.64m corridor matching the base width plus margin.

### What the Gate Implements:

1. **Process-Level Isolation:**  
The proposer runs in an external Python process communicating via non-blocking localhost UDP. It holds zero Webots actuator handles and has no direct path to the motors.
2. **Kinematic Stopping Envelope:**  
The gate computes an envelope each tick:  
d\_stop = ceil(v² / (2 \* a\_design)) + margin  
At 2.0 rad/s with a\_design = 0.5 m/s² and a 300 mm margin, d\_stop is 339 mm. If clearance falls below this, the gate overrides the proposer and commands 0.0 rad/s within a single 32 ms simulation tick.
3. **Recovery Contract & Latch:**  
After a trip, the gate latches in TRIPPED. It requires a continuous 1.0s dwell of clear readings before an operator reset can be accepted. If an operator attempts a reset while the obstacle is still in front of the robot, the reset is rejected and logged (RESET\_REJECTED\_HAZARD), holding 0.0 rad/s.
4. **Tamper-Evident Flight Recorder:**  
Every single tick appends a canonical JSON line to gate\_audit.jsonl, chained with a SHA-256 hash of the preceding record for offline verification.

### What the Run Shows (RUN\_1791713619, n=1):

- **Startup Latch:** The gate boots in TRIPPED, runs the 1.0s clear dwell, and enters AWAITING\_RESET.
- **Edge-Triggered Reset:** An operator reset (Key R) is accepted at t = 4.38s, transitioning to RUN at 2.0 rad/s.
- **Gate Intervention:** At t = 31.52s, corridor clearance breaches the 339 mm threshold. The gate cuts velocity to 0.0 rad/s in that exact 32 ms tick.
  - **Trip reading:** 337 mm
  - **Standstill reading:** 301 mm (the robot coasted about 36 mm in simulation physics before reaching complete rest).
  - **Collision:** None observed; the cart was not displaced.

- **Recovery Guard:** While parked in front of the cart at t = 34s, an operator reset was attempted. The gate evaluated the active hazard and rejected the reset (RESET\_REJECTED\_HAZARD: 1), keeping motors locked.
- **Cryptographic Seal:** 1,485 discrete control cycles verified with zero discrepancies (verify\_log.py, Head seal: ae37ae62227c4fdca51233b7e4189607898ae2c27eca5bf0847414d1f0d4c191).

### Observations, Gaps & Non-Claims:

- **Unexplained Startup Slip:** From t = 5.76s to 14.40s, wheel encoders recorded 2.0 rad/s while lidar distance stayed flat (~3818 mm). The wheels were turning in simulation, but the base did not translate for about 9 seconds before steady translation began. The exact physics cause in Webots is unconfirmed; logging ground-truth poses is my next diagnostic step.
- **Smoke-Test Mode:** In this baseline run, the obstacle cart was placed via supervisor script at t = 3.5s. Full dynamic obstacle injection via an independent supervisor robot is scheduled next.
- **Placeholder Parameters:** a\_design (0.5 m/s²) and the 300 mm margin are uncalibrated placeholders. At 0.196 m/s, the braking term is only about 39 mm, so the 300 mm margin dominates. Empirical deceleration calibration against ground truth is needed.
- **Scope Boundary:** This is an open-source research prototype on a non-RTOS host (Windows 11). It does not claim SIL/PL certification under IEC 61508 or ISO 13849-1, and software process isolation does not replace a physical emergency stop relay.

### Video & Links

**Video (YouTube):**

[![](https://us1.discourse-cdn.com/flex022/uploads/ros/original/3X/0/4/04168349c15762af4064b3f1b6eca4d468dba1c1.jpeg "QERRA-v2 Classical — Webots Demo 7: Supervisory Gate Authority Separation") ](https://www.youtube.com/watch?v=sZxwLtu5YWQ)

**Repository:** [GitHub - marunigno-ship-it/QERRA-v2-classical: Three-layer deterministic safety & ethical execution guard for autonomous robots (ROS 2 & Behavior Trees). Sub-ms physical reflex (QERRA-HSR) + moral filter (SEMEV-12) + values ranker (THRIVE). Fully auditable. · GitHub](https://github.com/marunigno-ship-it/QERRA-v2-classical)

**Licensing:**

- **Layer 1 (QERRA-HSR physical reflex):** Permissive **Apache-2.0** (standard library only, designed for standalone reuse).
- **Core Framework:** Dual-licensed under **AGPL-3.0** / commercial licensing (COMMERCIAL-LICENSE.md).

**I would welcome any genuine feedback**! 😊

1. Is this supervisory pattern useful beyond what nav2\_collision\_monitor + cmd\_vel timeouts already provide?
2. Does the latch-plus-dwell-plus-operator-reset recovery contract match how you handle physical holds in shared spaces?

_ **Transparency note:** _ _Post drafted with AI engineering assistance in line with QERRA open development disclosure. All architecture, code, and simulation runs were executed locally_

* * *

* * *

* * *

* * *

* * *
