Skip to content

Conversation

@bburda
Copy link
Contributor

@bburda bburda commented Jan 25, 2026

Description

This PR adds a lightweight, Gazebo‑free sensor diagnostics demo for ros2_medkit, including simulated sensors, an anomaly detector, Docker/docker‑compose integration, and CI wiring. It provides REST‑driven fault injection and a walkthrough script to showcase monitoring, configuration, and fault detection.

Changes:

  • Introduces simulated LiDAR, IMU, GPS, and camera nodes with configurable fault injection and diagnostic publishing.
  • Adds an anomaly detector node, parameter/config/manifest files, Dockerfile, and docker‑compose setup for running the demo plus an optional web UI.
  • Updates documentation, helper shell scripts, and CI to build the new demo image and advertise it as the primary quick‑start path.

Related Issue

closes #13

Checklist

  • Tested locally
  • README updated (if needed)

Add lightweight sensor diagnostics demo (no Gazebo required):
- CMakeLists.txt and package.xml for ROS 2 package
- Simulated sensor base class with fault injection support
- LiDAR simulator node with configurable parameters:
  - scan_rate, range_min/max, noise_stddev
  - Runtime fault injection via parameters
  - Diagnostics publisher for sensor status

This is the foundation for the sensor diagnostics demo that demonstrates
ros2_medkit's data monitoring and configuration management features.
Add remaining simulated sensor nodes with fault injection:
- IMU simulator: acceleration, angular velocity, drift simulation
- GPS simulator: NavSatFix with position noise and signal loss
- Camera simulator: RGB image generation with noise/black frames

All sensors support runtime parameter changes for fault injection:
- failure_probability for timeouts
- inject_nan for invalid values
- drift_rate for gradual sensor drift
- noise parameters for degraded operation
Add anomaly detector that monitors sensor streams and reports faults:
- Subscribes to LiDAR, IMU, GPS topics
- Detects NaN values, out-of-range readings
- Monitors message rates and timeouts
- Publishes DiagnosticArray for detected faults

Fault detection thresholds are configurable via ROS parameters:
- rate_timeout_sec
- max_nan_ratio
- sensor-specific rate minimums
Add ROS 2 launch file and configuration:
- demo.launch.py: launches all nodes with proper namespacing
  - /sensors: lidar_sim, imu_sim, gps_sim, camera_sim
  - /processing: anomaly_detector
  - /diagnostics: ros2_medkit_gateway
- sensor_params.yaml: default sensor parameters
- medkit_params.yaml: gateway configuration
- sensor_manifest.yaml: SOVD entity hierarchy definition
Add lightweight Dockerfile and docker-compose.yml:
- Based on ros:jazzy-ros-base (no Gazebo/GUI packages)
- Image size: ~500MB vs ~4GB for TurtleBot3 demo
- Startup time: ~5s vs ~60s
- Includes CI profile for headless testing
- Optional sovd-web-ui service for visualization
Add interactive demo scripts:
- run-demo.sh: walkthrough of ros2_medkit API features
- inject-noise.sh: increase sensor noise levels
- inject-failure.sh: cause sensor timeouts
- inject-nan.sh: inject NaN values
- inject-drift.sh: enable sensor drift
- restore-normal.sh: clear all faults

Add comprehensive README.md with:
- Quick start guide (Docker and source)
- API examples for all sensor operations
- Fault scenario documentation
- Parameter reference tables
- Comparison with TurtleBot3 demo
- Add sensor diagnostics demo to demos table (marked as Ready)
- Add Quick Start section with docker compose instructions
@bburda bburda self-assigned this Jan 25, 2026
Copilot AI review requested due to automatic review settings January 25, 2026 12:45
Build sensor diagnostics demo image in Docker build job.
Runs before TurtleBot3 build (faster, validates basic ros2_medkit).
The gateway requires additional packages:
- ros2_medkit_serialization (JSON/ROS message conversion)
- ros2_medkit_msgs (custom messages)
- dynmsg (dynamic message introspection)

Also add ros-jazzy-yaml-cpp-vendor to apt dependencies.
@bburda bburda force-pushed the feat/sensor-diagnostics-demo branch from 9c090fb to 2c05967 Compare January 25, 2026 12:49
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a lightweight, Gazebo‑free sensor diagnostics demo for ros2_medkit, including simulated sensors, an anomaly detector, Docker/docker‑compose integration, and CI wiring. It provides REST‑driven fault injection and a walkthrough script to showcase monitoring, configuration, and fault detection.

Changes:

  • Introduces simulated LiDAR, IMU, GPS, and camera nodes with configurable fault injection and diagnostic publishing.
  • Adds an anomaly detector node, parameter/config/manifest files, Dockerfile, and docker‑compose setup for running the demo plus an optional web UI.
  • Updates documentation, helper shell scripts, and CI to build the new demo image and advertise it as the primary quick‑start path.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
demos/sensor_diagnostics/src/lidar_sim_node.cpp LiDAR simulator node publishing LaserScan with noise, NaN, drift, and failure injection plus diagnostic status.
demos/sensor_diagnostics/src/imu_sim_node.cpp IMU simulator node publishing Imu with configurable noise, NaN, drift, and failure injection plus diagnostics.
demos/sensor_diagnostics/src/gps_sim_node.cpp GPS simulator node publishing NavSatFix with noise, drift, NaN, and loss‑of‑fix behavior plus diagnostics.
demos/sensor_diagnostics/src/camera_sim_node.cpp Camera simulator node publishing Image and CameraInfo with noise, black frames, and brightness faults plus diagnostics.
demos/sensor_diagnostics/src/anomaly_detector_node.cpp Anomaly detector node subscribing to sensor topics, detecting anomalies/timeouts/rate degradation, and publishing fault events.
demos/sensor_diagnostics/run-demo.sh Interactive shell script driving the REST API to show gateway health, sensor data, configs, and current faults.
demos/sensor_diagnostics/restore-normal.sh Helper script to reset all sensor fault‑related parameters back to normal values via the REST API.
demos/sensor_diagnostics/inject-noise.sh Helper script to inject high‑noise faults into all sensors via configuration updates.
demos/sensor_diagnostics/inject-nan.sh Helper script to enable NaN injection on LiDAR, IMU, and GPS via configuration updates.
demos/sensor_diagnostics/inject-failure.sh Helper script to force LiDAR sensor timeouts by setting failure probability to 1.0.
demos/sensor_diagnostics/inject-drift.sh Helper script to configure drift faults on LiDAR, IMU, and GPS sensors.
demos/sensor_diagnostics/restore-normal.sh Script to clear all configured faults and restore baseline sensor settings.
demos/sensor_diagnostics/package.xml Defines the sensor_diagnostics_demo ROS 2 package and its dependencies/exec deps.
demos/sensor_diagnostics/launch/demo.launch.py Launch description that starts all simulated sensors, the anomaly detector, and the ros2_medkit gateway with appropriate namespaces and configs.
demos/sensor_diagnostics/include/sensor_diagnostics/simulated_sensor_base.hpp Adds a (currently unused) base class and config struct for reusable fault‑injection behavior in simulated sensors.
demos/sensor_diagnostics/docker-compose.yml docker‑compose stack to run the sensor demo container and optional SOVD web UI, plus a CI profile variant.
demos/sensor_diagnostics/config/sensor_params.yaml Default ROS 2 parameters for each simulated sensor and the anomaly detector.
demos/sensor_diagnostics/config/sensor_manifest.yaml SOVD manifest describing areas, components, and apps for the sensor diagnostics demo.
demos/sensor_diagnostics/config/medkit_params.yaml ros2_medkit gateway configuration (HTTP server, CORS, discovery via manifest) for this demo.
demos/sensor_diagnostics/README.md Dedicated README explaining the demo, architecture, REST API examples, fault scenarios, scripts, and parameter reference.
demos/sensor_diagnostics/Dockerfile Dockerfile building a lightweight Jazzy‑based image containing ros2_medkit_gateway and the sensor diagnostics demo.
demos/sensor_diagnostics/CMakeLists.txt CMake configuration for building and installing the new simulator and anomaly detector nodes plus config/launch assets.
README.md (root) Top‑level README updated to add the Sensor Diagnostics demo and quick‑start instructions.
.github/workflows/ci.yml CI workflow updated to build the sensor diagnostics Docker image alongside the TurtleBot3 demo image.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@bburda bburda marked this pull request as draft January 25, 2026 13:01
- Add --recurse-submodules to clone dynmsg submodule
- Add ros-jazzy-example-interfaces to apt dependencies
- Skip test dependencies not in ros-base image
- Disable BUILD_TESTING for faster builds
- Use ghcr.io/selfpatch/sovd_web_ui:latest image
- Add ros2_medkit_fault_manager to Docker image
- Add fault_manager node to launch file
- Integrate anomaly_detector with ReportFault service
- Fix topic subscriptions (/sensors/scan instead of /sensors/lidar_sim/scan)
- Fix run-demo.sh jq queries for {items: []} response format
- Add libsqlite3-dev for fault_manager storage

Fault injection now properly reports to FaultManager:
- inject-nan.sh -> SENSOR_NAN faults
- inject-failure.sh -> SENSOR_TIMEOUT faults
- inject-noise.sh -> RATE_DEGRADED faults
@bburda bburda changed the title Add senosr diagnostic demo Add sensor diagnostics demo Jan 25, 2026
Demonstrates two fault reporting mechanisms in ros2_medkit:

LEGACY PATH (diagnostics → bridge):
- LiDAR and Camera publish DiagnosticArray to /diagnostics topic
- ros2_medkit_diagnostic_bridge converts and reports to fault_manager
- Auto-generates fault codes from diagnostic names (e.g., LIDAR_SIM)

MODERN PATH (direct service call):
- IMU and GPS monitored by anomaly_detector
- Anomaly detector calls /fault_manager/report_fault directly
- Uses specific fault codes (SENSOR_NAN, SENSOR_TIMEOUT, etc.)

Changes:
- Add diagnostic_bridge and fault_reporter to Dockerfile
- Update lidar_sim and camera_sim to publish DiagnosticArray
- Add diagnostic_bridge node to launch file
- Remove LiDAR monitoring from anomaly_detector
- Update all inject scripts with path documentation
- Add comprehensive dual-path documentation to README
@bburda bburda marked this pull request as ready for review January 25, 2026 18:11
@bburda bburda requested a review from Copilot January 25, 2026 18:11
@bburda bburda added the enhancement New feature or request label Jan 25, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Add missing <algorithm> include for std::clamp (lidar, camera)
- Validate rate parameters to prevent division by zero (all sensors)
- Remove unused max_nan_ratio parameter from anomaly_detector
- Remove unused lidar_rate_min from config (LiDAR uses legacy path now)
- Remove empty clear_passed_faults function and clear_timer_
- Fix DRIFT_DETECTED → DRIFTING in README fault table
- Add documentation to simulated_sensor_base.hpp explaining future use
- Add response callback to async_send_request() in anomaly_detector
  to ensure service requests are properly processed by the executor
- Fix restore-normal.sh to use correct entity paths for fault clearing:
  - Legacy path faults: /apps/diagnostic_bridge/faults/{fault_code}
  - Modern path faults: /apps/anomaly_detector/faults/{fault_code}
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@bburda bburda changed the title Add sensor diagnostics demo [#13] Add sensor diagnostics demo Jan 26, 2026
Fixes from @mfaferek93:
- Update copyright year 2025 → 2026 in all source files
- Add early return in report_fault() to avoid spamming FaultManager
- Remove unused normal_dist_ member from camera_sim_node
- Unify diagnostic topic to /diagnostics for all sensors (IMU, GPS, LiDAR, Camera)

Fixes from @Copilot:
- Add rcl_interfaces to ament_target_dependencies for lidar/camera nodes
- Fix docker-compose jq filter: .[] → .items[]
- Add exec_depend for ros2_medkit_diagnostic_bridge and fault_manager
- Fix anomaly_detector topic subscriptions to match sensor namespaces
- Add runtime scan_rate validation in lidar parameter callback
- Add num_readings validation with fallback to 360

Additional fixes:
- Update restore-normal.sh to clear IMU_SIM and GPS_SIM faults
Per @mfaferek93's review: removed speculative base class that was never
used. Can be re-added when/if sensors actually need shared fault injection logic.
- Fix anomaly_detector topic subscriptions to match actual sensor topics
  (/sensors/imu instead of /sensors/imu_sim/imu)
- Change NaN injection rate from 5% to 100% for clear fault demonstration
- Simplify diagnostic levels: all non-OK statuses now ERROR for reliable
  fault reporting through diagnostic_bridge
- Reset drift start_time when drift_rate parameter changes for accurate
  drift accumulation
- Remove unused simulated_sensor_base.hpp (YAGNI)
@mfaferek93 mfaferek93 self-requested a review January 26, 2026 17:50
@bburda bburda merged commit 79680b7 into main Jan 26, 2026
2 checks passed
bburda added a commit that referenced this pull request Jan 26, 2026
Fixes from @mfaferek93:
- Update copyright year 2025 → 2026 in all source files
- Add early return in report_fault() to avoid spamming FaultManager
- Remove unused normal_dist_ member from camera_sim_node
- Unify diagnostic topic to /diagnostics for all sensors (IMU, GPS, LiDAR, Camera)

Fixes from @Copilot:
- Add rcl_interfaces to ament_target_dependencies for lidar/camera nodes
- Fix docker-compose jq filter: .[] → .items[]
- Add exec_depend for ros2_medkit_diagnostic_bridge and fault_manager
- Fix anomaly_detector topic subscriptions to match sensor namespaces
- Add runtime scan_rate validation in lidar parameter callback
- Add num_readings validation with fallback to 360

Additional fixes:
- Update restore-normal.sh to clear IMU_SIM and GPS_SIM faults
@bburda bburda deleted the feat/sensor-diagnostics-demo branch January 26, 2026 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Lightweight demo focusing on sensor data and configurations

3 participants