Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,47 @@ jobs:
working-directory: demos/turtlebot3_integration
run: docker compose --profile ci down

# The debounce profile is a second configuration of the same demo, so it needs
# its own run: the default profile never loads the per-source threshold file,
# and a key that stops matching it fails silently by falling back to the
# global thresholds.
build-and-test-turtlebot-debounce:
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v4

# Static check, so it also covers the cpu and nvidia services that CI
# never starts. A service missing from the override runs the default
# profile while the caller believes it is debouncing.
- name: Check the debounce override covers every demo service
run: ./tests/check_debounce_overlay.sh

- name: Build and start turtlebot3 demo in debounce mode
working-directory: demos/turtlebot3_integration
run: |
docker compose --profile ci \
-f docker-compose.yml -f docker-compose.debounce.yml \
up -d --build turtlebot3-demo-ci

- name: Run debounce smoke tests
run: ./tests/smoke_test_debounce.sh

- name: Show container logs on failure
if: failure()
working-directory: demos/turtlebot3_integration
run: |
docker compose --profile ci \
-f docker-compose.yml -f docker-compose.debounce.yml \
logs turtlebot3-demo-ci --tail=200

- name: Teardown
if: always()
working-directory: demos/turtlebot3_integration
run: |
docker compose --profile ci \
-f docker-compose.yml -f docker-compose.debounce.yml down

build-and-test-moveit:
runs-on: ubuntu-24.04
steps:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2026 bburda
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Per-source debounce for the debounce demo. Keys match a source_id by longest
# prefix, so the entry below applies only to the goal-status reporter and the
# global thresholds still cover the no-progress one.
#
# The prefix is anchored at the start of the source_id, which the detector builds
# as its fully qualified node name plus a suffix. demo.launch.py puts the node in
# the "bridge" namespace, so the name is /bridge/anomaly_detector and the leading
# /bridge is part of the key. Renaming the node or its namespace in the launch
# file breaks this match silently: the resolver falls back to the global
# thresholds and the goal-status faults never leave PREFAILED.

/bridge/anomaly_detector/goal_status:
# A goal aborting or being cancelled is a single status change, so exactly one
# FAILED arrives and exactly one PASSED on the next success. -1 confirms on
# that one event and 0 heals on it. Under the global -3 the counter stops at -1
# and both codes stay PREFAILED for good. They are still listed, because the
# default fault filter includes PREFAILED alongside CONFIRMED, but they never
# count as confirmed: confirmedDTC stays 0, a confirmed-only query does not
# return them, and nothing that keys off confirmation runs.
confirmation_threshold: -1
# These two repeat the global values rather than changing them. They are stated
# so this source keeps confirming and healing on a single event even if the
# global profile is retuned later; only confirmation_threshold differs today.
healing_enabled: true
healing_threshold: 0
2 changes: 1 addition & 1 deletion demos/turtlebot3_integration/config/medkit_params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ fault_manager:
database_path: "/var/lib/ros2_medkit/faults.db"

# Debounce configuration
confirmation_threshold: 0 # Immediate confirmation
confirmation_threshold: -1 # Immediate confirmation; 0 is rejected and falls back to this
healing_enabled: false
healing_threshold: 3
auto_confirm_after_sec: 0.0
Expand Down
27 changes: 21 additions & 6 deletions demos/turtlebot3_integration/config/medkit_params_debounce.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# ros2_medkit gateway configuration for TurtleBot3 demo
# ARTICLE 3 - DEBOUNCE VERSION
# Differences from default:
# confirmation_threshold: -3 (was 0) — requires 3 sustained FAILED events
# healing_enabled: true (was false) — auto-heal after PASSED events
# Differences from the default profile in medkit_params.yaml:
# confirmation_threshold: -3, so three sustained FAILED events are needed
# before an operator sees the fault, instead of the default -1
# healing_enabled: true, so a fault clears itself once the condition is gone
#
# Node runs under /diagnostics namespace, so we need to match that here
diagnostics:
Expand Down Expand Up @@ -38,11 +39,25 @@ fault_manager:
database_path: "/var/lib/ros2_medkit/faults.db"

# === DEBOUNCE CONFIGURATION (Article 3) ===
confirmation_threshold: -3 # Need 3 sustained FAILED events to confirm
healing_enabled: true # Auto-heal when problem resolves
healing_threshold: 3 # Need 3 PASSED events to heal
# -3 filters the no-progress reporter, which repeats every 5 s while the
# robot is stuck: three reports, so roughly 15 s of it, before an operator
# sees anything. That is the contrast with the storm profile.
confirmation_threshold: -3
healing_enabled: true
# A confirmed fault sits at the confirmation threshold, because the counter is
# clamped to the band, so healing costs healing_threshold minus -3 PASSED
# events: three at 0, six at 3. The detector answers a recovery with a burst
# of three, which is what makes 0 the value that heals and 3 the value that
# would not.
healing_threshold: 0
Comment thread
bburda marked this conversation as resolved.
auto_confirm_after_sec: 0.0 # Disabled

# The goal-status faults fire once per status change, so the -3 above would
# hide them permanently. They report under their own source and take their
# own thresholds from here.
entity_thresholds:
config_file: "/root/demo_ws/src/turtlebot3_medkit_demo/config/entity_thresholds.yaml"

# Snapshot configuration (freeze frames)
snapshots:
enabled: true
Expand Down
14 changes: 14 additions & 0 deletions demos/turtlebot3_integration/docker-compose.debounce.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
# DEBOUNCE (with filtering):
# docker compose --profile cpu -f docker-compose.yml -f docker-compose.debounce.yml up -d
#
# DEBOUNCE in CI (headless, driven by tests/smoke_test_debounce.sh):
# docker compose --profile ci -f docker-compose.yml -f docker-compose.debounce.yml up -d
#
# Every service that can run the demo needs an entry here. A service left out
# starts with the default profile while the caller believes it is debouncing,
# and every assertion about thresholds then measures the wrong configuration.
#
# The override mounts the debounce config over the default one inside the container.
# colcon build --symlink-install means the installed config points to the source,
# so mounting over the source path works.
Expand All @@ -15,7 +22,14 @@ services:
turtlebot3-demo:
volumes:
- ./config/medkit_params_debounce.yaml:/root/demo_ws/src/turtlebot3_medkit_demo/config/medkit_params.yaml:ro
- ./config/entity_thresholds_debounce.yaml:/root/demo_ws/src/turtlebot3_medkit_demo/config/entity_thresholds.yaml:ro

turtlebot3-demo-nvidia:
volumes:
- ./config/medkit_params_debounce.yaml:/root/demo_ws/src/turtlebot3_medkit_demo/config/medkit_params.yaml:ro
- ./config/entity_thresholds_debounce.yaml:/root/demo_ws/src/turtlebot3_medkit_demo/config/entity_thresholds.yaml:ro

turtlebot3-demo-ci:
volumes:
- ./config/medkit_params_debounce.yaml:/root/demo_ws/src/turtlebot3_medkit_demo/config/medkit_params.yaml:ro
- ./config/entity_thresholds_debounce.yaml:/root/demo_ws/src/turtlebot3_medkit_demo/config/entity_thresholds.yaml:ro
Loading
Loading