From becfc27093b57b93bddd55cd50ee3e735f8bb3b4 Mon Sep 17 00:00:00 2001 From: Bartosz Burda Date: Sun, 1 Feb 2026 11:07:29 +0000 Subject: [PATCH 1/2] fix(sensor-demo): correct app IDs and improve script consistency - Fix incorrect app IDs: use dashes instead of underscores - lidar_sim -> lidar-sim - imu_sim -> imu-sim - gps_sim -> gps-sim - camera_sim -> camera-sim - anomaly_detector -> anomaly-detector - diagnostic_bridge -> diagnostic-bridge - Split run-demo.sh into separate concerns - run-demo.sh: only starts Docker services - check-demo.sh: new interactive API demonstration script - stop-demo.sh: new script to stop services - Update all scripts to use correct Gateway API entity IDs - check-demo.sh: fixed all API endpoint calls - inject-*.sh: updated fault injection scripts - restore-normal.sh: fixed configuration and fault clearing - Update documentation - README.md: updated Quick Start and API examples - demos/sensor_diagnostics/README.md: corrected all API examples Fixes API calls that were failing with 'entity not found' errors. Makes demo scripts consistent with turtlebot3_integration behavior. --- README.md | 19 +- demos/sensor_diagnostics/README.md | 50 +++-- demos/sensor_diagnostics/check-demo.sh | 108 +++++++++++ demos/sensor_diagnostics/inject-drift.sh | 6 +- demos/sensor_diagnostics/inject-failure.sh | 4 +- demos/sensor_diagnostics/inject-nan.sh | 16 +- demos/sensor_diagnostics/inject-noise.sh | 8 +- demos/sensor_diagnostics/restore-normal.sh | 52 ++--- demos/sensor_diagnostics/run-demo.sh | 213 +++++++++++---------- demos/sensor_diagnostics/stop-demo.sh | 70 +++++++ 10 files changed, 387 insertions(+), 159 deletions(-) create mode 100755 demos/sensor_diagnostics/check-demo.sh create mode 100755 demos/sensor_diagnostics/stop-demo.sh diff --git a/README.md b/README.md index b562408..b135254 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,19 @@ The sensor diagnostics demo is the fastest way to try ros2_medkit: ```bash cd demos/sensor_diagnostics -docker compose up -# Open http://localhost:3000 for the Web UI -# Run ./run-demo.sh for an interactive walkthrough +./run-demo.sh +# Docker services start in daemon mode +# Web UI available at http://localhost:3000 + +# Explore the API +./check-demo.sh +``` + +**Options:** +```bash +./run-demo.sh --attached # Run in foreground with logs +./check-demo.sh # Interactive API demonstration +./stop-demo.sh # Stop the demo ``` **Features:** @@ -69,6 +79,9 @@ cd demos/turtlebot3_integration ./run-demo.sh # Gazebo will open, Web UI at http://localhost:3000 # Try: ./send-nav-goal.sh 2.0 0.5 + +# To stop +./stop-demo.sh ``` **Features:** diff --git a/demos/sensor_diagnostics/README.md b/demos/sensor_diagnostics/README.md index 2e338eb..4c05628 100644 --- a/demos/sensor_diagnostics/README.md +++ b/demos/sensor_diagnostics/README.md @@ -17,14 +17,32 @@ This demo showcases ros2_medkit's data monitoring, configuration management, and ### Using Docker (Recommended) ```bash -# Start the demo -docker compose up +# Start the demo (builds and starts Docker services) +./run-demo.sh -# In another terminal, open the Web UI -# Navigate to http://localhost:3000 +# The script will: +# 1. Build and start Docker containers in daemon mode +# 2. Display access URLs and available commands -# Or run the demo script -./run-demo.sh +# Explore the API with interactive demonstration +./check-demo.sh + +# To stop the demo +./stop-demo.sh +``` + +**Options:** +```bash +./run-demo.sh --attached # Run in foreground with logs +./run-demo.sh --update # Pull latest images before running +./run-demo.sh --no-cache # Build without cache +``` + +**Advanced usage:** +```bash +# Manual Docker control (if needed) +docker compose up # Start services manually +docker compose down # Stop services ``` ### Building from Source @@ -126,40 +144,40 @@ Sensor Topics → anomaly_detector monitors ```bash # Get LiDAR scan -curl http://localhost:8080/api/v1/apps/lidar_sim/data/scan | jq '.ranges[:5]' +curl http://localhost:8080/api/v1/apps/lidar-sim/data/scan | jq '.ranges[:5]' # Get IMU data -curl http://localhost:8080/api/v1/apps/imu_sim/data/imu | jq '.linear_acceleration' +curl http://localhost:8080/api/v1/apps/imu-sim/data/imu | jq '.linear_acceleration' # Get GPS fix -curl http://localhost:8080/api/v1/apps/gps_sim/data/fix | jq '{lat: .latitude, lon: .longitude}' +curl http://localhost:8080/api/v1/apps/gps-sim/data/fix | jq '{lat: .latitude, lon: .longitude}' ``` ### View Configurations ```bash # List all LiDAR configurations -curl http://localhost:8080/api/v1/apps/lidar_sim/configurations | jq +curl http://localhost:8080/api/v1/apps/lidar-sim/configurations | jq # Get specific parameter -curl http://localhost:8080/api/v1/apps/lidar_sim/configurations/noise_stddev | jq +curl http://localhost:8080/api/v1/apps/lidar-sim/configurations/noise_stddev | jq ``` ### Inject Faults ```bash # Increase sensor noise -curl -X PUT http://localhost:8080/api/v1/apps/lidar_sim/configurations/noise_stddev \ +curl -X PUT http://localhost:8080/api/v1/apps/lidar-sim/configurations/noise_stddev \ -H "Content-Type: application/json" \ -d '{"value": 0.5}' # Cause sensor timeout -curl -X PUT http://localhost:8080/api/v1/apps/lidar_sim/configurations/failure_probability \ +curl -X PUT http://localhost:8080/api/v1/apps/lidar-sim/configurations/failure_probability \ -H "Content-Type: application/json" \ -d '{"value": 1.0}' # Inject NaN values -curl -X PUT http://localhost:8080/api/v1/apps/lidar_sim/configurations/inject_nan \ +curl -X PUT http://localhost:8080/api/v1/apps/lidar-sim/configurations/inject_nan \ -H "Content-Type: application/json" \ -d '{"value": true}' ``` @@ -185,7 +203,9 @@ curl http://localhost:8080/api/v1/faults | jq | Script | Description | |--------|-------------| -| `run-demo.sh` | Interactive demo walkthrough | +| `run-demo.sh` | Start Docker services (daemon mode) | +| `stop-demo.sh` | Stop Docker services | +| `check-demo.sh` | Interactive API demonstration and exploration | | `inject-noise.sh` | Inject high noise fault | | `inject-failure.sh` | Cause sensor timeout | | `inject-nan.sh` | Inject NaN values | diff --git a/demos/sensor_diagnostics/check-demo.sh b/demos/sensor_diagnostics/check-demo.sh new file mode 100755 index 0000000..8da9027 --- /dev/null +++ b/demos/sensor_diagnostics/check-demo.sh @@ -0,0 +1,108 @@ +#!/bin/bash +# Sensor Diagnostics Demo - Interactive API Demonstration +# Explores ros2_medkit capabilities with simulated sensors + +GATEWAY_URL="${GATEWAY_URL:-http://localhost:8080}" +API_BASE="${GATEWAY_URL}/api/v1" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +echo_step() { + echo -e "\n${BLUE}=== $1 ===${NC}\n" +} + +echo_success() { + echo -e "${GREEN}✓ $1${NC}" +} + +echo_error() { + echo -e "${RED}✗ $1${NC}" +} + +echo "╔════════════════════════════════════════════════════════════╗" +echo "║ Sensor Diagnostics Demo - API Explorer ║" +echo "║ (ros2_medkit + Simulated Sensors) ║" +echo "╚════════════════════════════════════════════════════════════╝" + +# Check for jq dependency +if ! command -v jq >/dev/null 2>&1; then + echo_error "'jq' is required but not installed." + echo " Please install jq (e.g., 'sudo apt-get install jq') and retry." + exit 1 +fi + +# Check gateway health +echo "" +echo "Checking gateway health..." +if ! curl -sf "${API_BASE}/health" > /dev/null 2>&1; then + echo_error "Gateway not available at ${GATEWAY_URL}" + echo " Start with: ./run-demo.sh" + exit 1 +fi +echo_success "Gateway is healthy!" + +echo_step "1. Checking Gateway Health" +curl -s "${API_BASE}/health" | jq '.' + +echo_step "2. Listing All Areas (Namespaces)" +curl -s "${API_BASE}/areas" | jq '.items[] | {id: .id, name: .name, description: .description}' + +echo_step "3. Listing All Components" +curl -s "${API_BASE}/components" | jq '.items[] | {id: .id, name: .name, area: .area}' + +echo_step "4. Listing All Apps (ROS 2 Nodes)" +curl -s "${API_BASE}/apps" | jq '.items[] | {id: .id, name: .name, namespace: .namespace}' + +echo_step "5. Reading LiDAR Data" +echo "Getting latest scan from LiDAR simulator..." +curl -s "${API_BASE}/apps/lidar-sim/data/scan" | jq '{ + angle_min: .angle_min, + angle_max: .angle_max, + range_min: .range_min, + range_max: .range_max, + sample_ranges: .ranges[:5] +}' + +echo_step "6. Reading IMU Data" +echo "Getting latest IMU reading..." +curl -s "${API_BASE}/apps/imu-sim/data/imu" | jq '{ + linear_acceleration: .linear_acceleration, + angular_velocity: .angular_velocity +}' + +echo_step "7. Reading GPS Fix" +echo "Getting current GPS position..." +curl -s "${API_BASE}/apps/gps-sim/data/fix" | jq '{ + latitude: .latitude, + longitude: .longitude, + altitude: .altitude, + status: .status +}' + +echo_step "8. Listing LiDAR Configurations" +echo "These parameters can be modified at runtime to inject faults..." +curl -s "${API_BASE}/apps/lidar-sim/configurations" | jq '.items[] | {name: .name, value: .value, type: .type}' + +echo_step "9. Checking Current Faults" +curl -s "${API_BASE}/faults" | jq '.' + +echo "" +echo_success "API demonstration complete!" +echo "" +echo "🔧 Try injecting faults with these scripts:" +echo " ./inject-noise.sh # Increase sensor noise" +echo " ./inject-failure.sh # Cause sensor timeouts" +echo " ./inject-nan.sh # Inject NaN values" +echo " ./inject-drift.sh # Inject sensor drift" +echo " ./restore-normal.sh # Restore normal operation" +echo "" +echo "🌐 Web UI: http://localhost:3000" +echo "🌐 REST API: http://localhost:8080/api/v1/" +echo "" +echo "📖 More examples:" +echo " curl ${API_BASE}/apps/imu-sim/configurations | jq # IMU parameters" +echo " curl ${API_BASE}/apps/gps-sim/data/fix | jq # GPS data" diff --git a/demos/sensor_diagnostics/inject-drift.sh b/demos/sensor_diagnostics/inject-drift.sh index 4b19189..2b4818e 100755 --- a/demos/sensor_diagnostics/inject-drift.sh +++ b/demos/sensor_diagnostics/inject-drift.sh @@ -10,8 +10,8 @@ echo "" # LiDAR drift: uses legacy diagnostics path echo "[LEGACY PATH] Setting LiDAR drift_rate to 0.1 m/s..." -echo " Fault path: lidar_sim → /diagnostics topic → diagnostic_bridge → FaultManager" -curl -s -X PUT "${API_BASE}/apps/lidar_sim/configurations/drift_rate" \ +echo " Fault path: lidar-sim → /diagnostics topic → diagnostic-bridge → FaultManager" +curl -s -X PUT "${API_BASE}/apps/lidar-sim/configurations/drift_rate" \ -H "Content-Type: application/json" \ -d '{"value": 0.1}' @@ -21,5 +21,5 @@ echo "" echo "Fault codes expected (auto-generated from diagnostic name):" echo " - LIDAR_SIM (DRIFTING status, WARN severity)" echo "" -echo "Watch the drift accumulate with: curl ${GATEWAY_URL}/api/v1/apps/lidar_sim/data/scan | jq '.ranges[:5]'" +echo "Watch the drift accumulate with: curl ${GATEWAY_URL}/api/v1/apps/lidar-sim/data/scan | jq '.ranges[:5]'" echo "Check faults with: curl ${GATEWAY_URL}/api/v1/faults | jq" diff --git a/demos/sensor_diagnostics/inject-failure.sh b/demos/sensor_diagnostics/inject-failure.sh index 8553aff..66bce3f 100755 --- a/demos/sensor_diagnostics/inject-failure.sh +++ b/demos/sensor_diagnostics/inject-failure.sh @@ -9,12 +9,12 @@ echo "Injecting SENSOR FAILURE fault (Modern path: IMU → anomaly_detector)..." # Set high failure probability - IMU will stop publishing echo "Setting IMU failure_probability to 1.0 (complete failure)..." -curl -s -X PUT "${API_BASE}/apps/imu_sim/configurations/failure_probability" \ +curl -s -X PUT "${API_BASE}/apps/imu-sim/configurations/failure_probability" \ -H "Content-Type: application/json" \ -d '{"value": 1.0}' echo "" echo "✓ IMU failure injected!" -echo " Fault reporting path: imu_sim → anomaly_detector → /fault_manager/report_fault" +echo " Fault reporting path: imu-sim → anomaly-detector → /fault_manager/report_fault" echo " The anomaly detector should report SENSOR_TIMEOUT fault directly to FaultManager." echo " Check faults with: curl ${API_BASE}/faults | jq" diff --git a/demos/sensor_diagnostics/inject-nan.sh b/demos/sensor_diagnostics/inject-nan.sh index f46ae2e..b9f5dca 100755 --- a/demos/sensor_diagnostics/inject-nan.sh +++ b/demos/sensor_diagnostics/inject-nan.sh @@ -9,23 +9,23 @@ echo "" # LEGACY PATH: LiDAR publishes DiagnosticArray → diagnostic_bridge → FaultManager echo "[LEGACY PATH] Enabling LiDAR inject_nan..." -echo " Fault path: lidar_sim → /diagnostics topic → diagnostic_bridge → FaultManager" -curl -s -X PUT "${API_BASE}/apps/lidar_sim/configurations/inject_nan" \ +echo " Fault path: lidar-sim → /diagnostics topic → diagnostic-bridge → FaultManager" +curl -s -X PUT "${API_BASE}/apps/lidar-sim/configurations/inject_nan" \ -H "Content-Type: application/json" \ -d '{"value": true}' echo "" # MODERN PATH: IMU/GPS → anomaly_detector → FaultManager (direct service call) echo "[MODERN PATH] Enabling IMU inject_nan..." -echo " Fault path: imu_sim → anomaly_detector → /fault_manager/report_fault" -curl -s -X PUT "${API_BASE}/apps/imu_sim/configurations/inject_nan" \ +echo " Fault path: imu-sim → anomaly_detector → /fault_manager/report_fault" +curl -s -X PUT "${API_BASE}/apps/imu-sim/configurations/inject_nan" \ -H "Content-Type: application/json" \ -d '{"value": true}' echo "" echo "[MODERN PATH] Enabling GPS inject_nan..." -echo " Fault path: gps_sim → anomaly_detector → /fault_manager/report_fault" -curl -s -X PUT "${API_BASE}/apps/gps_sim/configurations/inject_nan" \ +echo " Fault path: gps-sim → anomaly_detector → /fault_manager/report_fault" +curl -s -X PUT "${API_BASE}/apps/gps-sim/configurations/inject_nan" \ -H "Content-Type: application/json" \ -d '{"value": true}' @@ -33,7 +33,7 @@ echo "" echo "✓ NaN injection enabled on multiple sensors!" echo "" echo "Fault codes expected:" -echo " - LIDAR_SIM (from diagnostic_bridge, auto-generated from diagnostic name)" -echo " - SENSOR_NAN (from anomaly_detector)" +echo " - LIDAR_SIM (from diagnostic-bridge, auto-generated from diagnostic name)" +echo " - SENSOR_NAN (from anomaly-detector)" echo "" echo "Check faults with: curl ${API_BASE}/faults | jq" diff --git a/demos/sensor_diagnostics/inject-noise.sh b/demos/sensor_diagnostics/inject-noise.sh index 52849af..9ec85f7 100755 --- a/demos/sensor_diagnostics/inject-noise.sh +++ b/demos/sensor_diagnostics/inject-noise.sh @@ -10,16 +10,16 @@ echo "" # LiDAR: increase noise stddev (uses legacy diagnostics path) echo "[LEGACY PATH] Setting LiDAR noise_stddev to 0.5 (very noisy)..." -echo " Fault path: lidar_sim → /diagnostics topic → diagnostic_bridge → FaultManager" -curl -s -X PUT "${API_BASE}/apps/lidar_sim/configurations/noise_stddev" \ +echo " Fault path: lidar-sim → /diagnostics topic → diagnostic-bridge → FaultManager" +curl -s -X PUT "${API_BASE}/apps/lidar-sim/configurations/noise_stddev" \ -H "Content-Type: application/json" \ -d '{"value": 0.5}' echo "" # Camera: add noise (uses legacy diagnostics path) echo "[LEGACY PATH] Setting Camera noise_level to 0.3..." -echo " Fault path: camera_sim → /diagnostics topic → diagnostic_bridge → FaultManager" -curl -s -X PUT "${API_BASE}/apps/camera_sim/configurations/noise_level" \ +echo " Fault path: camera-sim → /diagnostics topic → diagnostic-bridge → FaultManager" +curl -s -X PUT "${API_BASE}/apps/camera-sim/configurations/noise_level" \ -H "Content-Type: application/json" \ -d '{"value": 0.3}' diff --git a/demos/sensor_diagnostics/restore-normal.sh b/demos/sensor_diagnostics/restore-normal.sh index 075aacd..8e009fc 100755 --- a/demos/sensor_diagnostics/restore-normal.sh +++ b/demos/sensor_diagnostics/restore-normal.sh @@ -8,61 +8,61 @@ echo "Restoring NORMAL operation..." # LiDAR echo "Resetting LiDAR parameters..." -curl -s -X PUT "${API_BASE}/apps/lidar_sim/configurations/noise_stddev" \ +curl -s -X PUT "${API_BASE}/apps/lidar-sim/configurations/noise_stddev" \ -H "Content-Type: application/json" -d '{"value": 0.01}' -curl -s -X PUT "${API_BASE}/apps/lidar_sim/configurations/failure_probability" \ +curl -s -X PUT "${API_BASE}/apps/lidar-sim/configurations/failure_probability" \ -H "Content-Type: application/json" -d '{"value": 0.0}' -curl -s -X PUT "${API_BASE}/apps/lidar_sim/configurations/inject_nan" \ +curl -s -X PUT "${API_BASE}/apps/lidar-sim/configurations/inject_nan" \ -H "Content-Type: application/json" -d '{"value": false}' -curl -s -X PUT "${API_BASE}/apps/lidar_sim/configurations/drift_rate" \ +curl -s -X PUT "${API_BASE}/apps/lidar-sim/configurations/drift_rate" \ -H "Content-Type: application/json" -d '{"value": 0.0}' # IMU echo "Resetting IMU parameters..." -curl -s -X PUT "${API_BASE}/apps/imu_sim/configurations/accel_noise_stddev" \ +curl -s -X PUT "${API_BASE}/apps/imu-sim/configurations/accel_noise_stddev" \ -H "Content-Type: application/json" -d '{"value": 0.01}' -curl -s -X PUT "${API_BASE}/apps/imu_sim/configurations/failure_probability" \ +curl -s -X PUT "${API_BASE}/apps/imu-sim/configurations/failure_probability" \ -H "Content-Type: application/json" -d '{"value": 0.0}' -curl -s -X PUT "${API_BASE}/apps/imu_sim/configurations/inject_nan" \ +curl -s -X PUT "${API_BASE}/apps/imu-sim/configurations/inject_nan" \ -H "Content-Type: application/json" -d '{"value": false}' -curl -s -X PUT "${API_BASE}/apps/imu_sim/configurations/drift_rate" \ +curl -s -X PUT "${API_BASE}/apps/imu-sim/configurations/drift_rate" \ -H "Content-Type: application/json" -d '{"value": 0.0}' # GPS echo "Resetting GPS parameters..." -curl -s -X PUT "${API_BASE}/apps/gps_sim/configurations/position_noise_stddev" \ +curl -s -X PUT "${API_BASE}/apps/gps-sim/configurations/position_noise_stddev" \ -H "Content-Type: application/json" -d '{"value": 2.0}' -curl -s -X PUT "${API_BASE}/apps/gps_sim/configurations/failure_probability" \ +curl -s -X PUT "${API_BASE}/apps/gps-sim/configurations/failure_probability" \ -H "Content-Type: application/json" -d '{"value": 0.0}' -curl -s -X PUT "${API_BASE}/apps/gps_sim/configurations/inject_nan" \ +curl -s -X PUT "${API_BASE}/apps/gps-sim/configurations/inject_nan" \ -H "Content-Type: application/json" -d '{"value": false}' -curl -s -X PUT "${API_BASE}/apps/gps_sim/configurations/drift_rate" \ +curl -s -X PUT "${API_BASE}/apps/gps-sim/configurations/drift_rate" \ -H "Content-Type: application/json" -d '{"value": 0.0}' # Camera echo "Resetting Camera parameters..." -curl -s -X PUT "${API_BASE}/apps/camera_sim/configurations/noise_level" \ +curl -s -X PUT "${API_BASE}/apps/camera-sim/configurations/noise_level" \ -H "Content-Type: application/json" -d '{"value": 0.0}' -curl -s -X PUT "${API_BASE}/apps/camera_sim/configurations/failure_probability" \ +curl -s -X PUT "${API_BASE}/apps/camera-sim/configurations/failure_probability" \ -H "Content-Type: application/json" -d '{"value": 0.0}' -curl -s -X PUT "${API_BASE}/apps/camera_sim/configurations/inject_black_frames" \ +curl -s -X PUT "${API_BASE}/apps/camera-sim/configurations/inject_black_frames" \ -H "Content-Type: application/json" -d '{"value": false}' # Clear all faults from FaultManager -# All sensors now publish to /diagnostics, so all faults come through diagnostic_bridge +# All sensors now publish to /diagnostics, so all faults come through diagnostic-bridge echo "" echo "Clearing all faults from FaultManager..." -curl -s -X DELETE "${API_BASE}/apps/diagnostic_bridge/faults/LIDAR_SIM" > /dev/null 2>&1 -curl -s -X DELETE "${API_BASE}/apps/diagnostic_bridge/faults/CAMERA_SIM" > /dev/null 2>&1 -curl -s -X DELETE "${API_BASE}/apps/diagnostic_bridge/faults/IMU_SIM" > /dev/null 2>&1 -curl -s -X DELETE "${API_BASE}/apps/diagnostic_bridge/faults/GPS_SIM" > /dev/null 2>&1 +curl -s -X DELETE "${API_BASE}/apps/diagnostic-bridge/faults/LIDAR_SIM" > /dev/null 2>&1 +curl -s -X DELETE "${API_BASE}/apps/diagnostic-bridge/faults/CAMERA_SIM" > /dev/null 2>&1 +curl -s -X DELETE "${API_BASE}/apps/diagnostic-bridge/faults/IMU_SIM" > /dev/null 2>&1 +curl -s -X DELETE "${API_BASE}/apps/diagnostic-bridge/faults/GPS_SIM" > /dev/null 2>&1 -# Faults from anomaly_detector (modern path for anomaly detection) -curl -s -X DELETE "${API_BASE}/apps/anomaly_detector/faults/SENSOR_TIMEOUT" > /dev/null 2>&1 -curl -s -X DELETE "${API_BASE}/apps/anomaly_detector/faults/SENSOR_NAN" > /dev/null 2>&1 -curl -s -X DELETE "${API_BASE}/apps/anomaly_detector/faults/SENSOR_OUT_OF_RANGE" > /dev/null 2>&1 -curl -s -X DELETE "${API_BASE}/apps/anomaly_detector/faults/RATE_DEGRADED" > /dev/null 2>&1 -curl -s -X DELETE "${API_BASE}/apps/anomaly_detector/faults/NO_FIX" > /dev/null 2>&1 +# Faults from anomaly-detector (modern path for anomaly detection) +curl -s -X DELETE "${API_BASE}/apps/anomaly-detector/faults/SENSOR_TIMEOUT" > /dev/null 2>&1 +curl -s -X DELETE "${API_BASE}/apps/anomaly-detector/faults/SENSOR_NAN" > /dev/null 2>&1 +curl -s -X DELETE "${API_BASE}/apps/anomaly-detector/faults/SENSOR_OUT_OF_RANGE" > /dev/null 2>&1 +curl -s -X DELETE "${API_BASE}/apps/anomaly-detector/faults/RATE_DEGRADED" > /dev/null 2>&1 +curl -s -X DELETE "${API_BASE}/apps/anomaly-detector/faults/NO_FIX" > /dev/null 2>&1 echo "" echo "✓ Normal operation restored! All fault injections and faults cleared." diff --git a/demos/sensor_diagnostics/run-demo.sh b/demos/sensor_diagnostics/run-demo.sh index c10db28..305e1e7 100755 --- a/demos/sensor_diagnostics/run-demo.sh +++ b/demos/sensor_diagnostics/run-demo.sh @@ -1,107 +1,124 @@ #!/bin/bash -# Sensor Diagnostics Demo - Interactive Demo Script -# Run this script to see ros2_medkit in action with simulated sensors - -set -e - -GATEWAY_URL="${GATEWAY_URL:-http://localhost:8080}" -API_BASE="${GATEWAY_URL}/api/v1" - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -echo_step() { - echo -e "\n${BLUE}=== $1 ===${NC}\n" -} - -echo_success() { - echo -e "${GREEN}✓ $1${NC}" +# Sensor Diagnostics Demo Runner +# Starts Docker services with ros2_medkit and simulated sensors + +set -eu + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# Parse arguments +DETACH_MODE="true" +UPDATE_IMAGES="false" +BUILD_ARGS="" + +usage() { + echo "Usage: $0 [OPTIONS]" + echo "" + echo "Options:" + echo " --attached Run in foreground (default: daemon mode)" + echo " --update Pull latest images before running" + echo " --no-cache Build Docker images without cache" + echo " -h, --help Show this help message" + echo "" + echo "Examples:" + echo " $0 # Daemon mode (default)" + echo " $0 --attached # Foreground with logs" + echo " $0 --update # Pull and run latest version" } -echo_warning() { - echo -e "${YELLOW}⚠ $1${NC}" -} - -echo_error() { - echo -e "${RED}✗ $1${NC}" -} +while [[ $# -gt 0 ]]; do + case "$1" in + --attached) + echo "Running in foreground mode" + DETACH_MODE="false" + ;; + --update) + echo "Will pull latest images" + UPDATE_IMAGES="true" + ;; + --no-cache) + echo "Building without cache" + BUILD_ARGS="--no-cache" + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown option: $1" + usage + exit 1 + ;; + esac + shift +done + +echo "🔬 Sensor Diagnostics Demo with ros2_medkit" +echo "============================================" +echo " (Lightweight - No Gazebo Required)" +echo "" -wait_for_gateway() { - echo "Waiting for gateway to be ready..." - for _ in {1..30}; do - if curl -sf "${API_BASE}/health" > /dev/null 2>&1; then - echo_success "Gateway is ready!" - return 0 - fi - sleep 1 - done - echo_error "Gateway not available at ${GATEWAY_URL}" +# Check for Docker +if ! command -v docker &> /dev/null; then + echo "Error: Docker is not installed" exit 1 -} - -# Main demo flow -echo "╔════════════════════════════════════════════════════════════╗" -echo "║ Sensor Diagnostics Demo with ros2_medkit ║" -echo "║ (Lightweight - No Gazebo Required) ║" -echo "╚════════════════════════════════════════════════════════════╝" - -echo_step "1. Checking Gateway Health" -wait_for_gateway -curl -s "${API_BASE}/health" | jq '.' - -echo_step "2. Listing All Areas (Namespaces)" -curl -s "${API_BASE}/areas" | jq '.' - -echo_step "3. Listing All Components" -curl -s "${API_BASE}/components" | jq '.items[] | {id: .id, name: .name, area: .area}' - -echo_step "4. Listing All Apps (ROS 2 Nodes)" -curl -s "${API_BASE}/apps" | jq '.items[] | {id: .id, name: .name, namespace: .namespace}' - -echo_step "5. Reading LiDAR Data" -echo "Getting latest scan from LiDAR simulator..." -curl -s "${API_BASE}/apps/lidar_sim/data/scan" | jq '{ - angle_min: .angle_min, - angle_max: .angle_max, - range_min: .range_min, - range_max: .range_max, - sample_ranges: .ranges[:5] -}' - -echo_step "6. Reading IMU Data" -echo "Getting latest IMU reading..." -curl -s "${API_BASE}/apps/imu_sim/data/imu" | jq '{ - linear_acceleration: .linear_acceleration, - angular_velocity: .angular_velocity -}' - -echo_step "7. Reading GPS Fix" -echo "Getting current GPS position..." -curl -s "${API_BASE}/apps/gps_sim/data/fix" | jq '{ - latitude: .latitude, - longitude: .longitude, - altitude: .altitude, - status: .status -}' - -echo_step "8. Listing LiDAR Configurations" -echo "These parameters can be modified at runtime to inject faults..." -curl -s "${API_BASE}/apps/lidar_sim/configurations" | jq '.items[] | {name: .name, value: .value, type: .type}' - -echo_step "9. Checking Current Faults" -curl -s "${API_BASE}/faults" | jq '.' +fi +echo "Run mode: $([ "$DETACH_MODE" = "true" ] && echo "daemon (background)" || echo "attached (foreground)")" echo "" -echo_success "Demo complete!" + +# Pull images if --update flag is set +if [[ "$UPDATE_IMAGES" == "true" ]]; then + echo "📥 Pulling latest images..." + if docker compose version &> /dev/null; then + docker compose pull + else + docker-compose pull + fi + echo "" +fi + +# Build and start services +echo "🚀 Building and starting demo..." +echo " (First run may take a few minutes)" echo "" -echo "Try injecting faults with these scripts:" -echo " ./inject-noise.sh - Increase sensor noise" -echo " ./inject-failure.sh - Cause sensor timeouts" -echo " ./inject-nan.sh - Inject NaN values" -echo " ./restore-normal.sh - Restore normal operation" +echo "🌐 REST API will be available at: http://localhost:8080/api/v1/" +echo "🌐 Web UI will be available at: http://localhost:3000/" echo "" -echo "Or use the Web UI at http://localhost:3000" + +DETACH_FLAG="" +if [[ "$DETACH_MODE" == "true" ]]; then + DETACH_FLAG="-d" +fi + +if docker compose version &> /dev/null; then + # shellcheck disable=SC2086 + docker compose build ${BUILD_ARGS} && docker compose up ${DETACH_FLAG} +else + # shellcheck disable=SC2086 + docker-compose build ${BUILD_ARGS} && docker-compose up ${DETACH_FLAG} +fi + +if [[ "$DETACH_MODE" == "true" ]]; then + echo "" + echo "✅ Demo started in background!" + echo "" + echo "📊 To view logs:" + echo " docker compose logs -f" + echo "" + echo "🔬 Explore the API:" + echo " ./check-demo.sh # Interactive API demonstration" + echo "" + echo "🔧 Inject faults:" + echo " ./inject-noise.sh # Increase sensor noise" + echo " ./inject-failure.sh # Cause sensor timeouts" + echo " ./inject-nan.sh # Inject NaN values" + echo " ./inject-drift.sh # Inject sensor drift" + echo " ./restore-normal.sh # Restore normal operation" + echo "" + echo "🌐 Web UI: http://localhost:3000" + echo "🌐 REST API: http://localhost:8080/api/v1/" + echo "" + echo "🛑 To stop: ./stop-demo.sh" +fi diff --git a/demos/sensor_diagnostics/stop-demo.sh b/demos/sensor_diagnostics/stop-demo.sh new file mode 100755 index 0000000..4fda29f --- /dev/null +++ b/demos/sensor_diagnostics/stop-demo.sh @@ -0,0 +1,70 @@ +#!/bin/bash +# Stop Sensor Diagnostics Demo + +set -eu + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +echo "🛑 Stopping Sensor Diagnostics Demo" +echo "=====================================" + +# Check for Docker +if ! command -v docker &> /dev/null; then + echo "Error: Docker is not installed" + exit 1 +fi + +# Parse arguments +REMOVE_VOLUMES="" +REMOVE_IMAGES="" + +usage() { + echo "Usage: $0 [OPTIONS]" + echo "" + echo "Options:" + echo " -v, --volumes Remove named volumes" + echo " --images Remove images" + echo " -h, --help Show this help message" + echo "" + echo "Examples:" + echo " $0 # Stop containers" + echo " $0 --volumes # Stop and remove volumes" + echo " $0 --images # Stop and remove images" +} + +while [[ $# -gt 0 ]]; do + case "$1" in + -v|--volumes) + echo "Will remove named volumes" + REMOVE_VOLUMES="-v" + ;; + --images) + echo "Will remove images" + REMOVE_IMAGES="--rmi all" + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown option: $1" + usage + exit 1 + ;; + esac + shift +done + +# Stop containers +echo "Stopping containers..." +if docker compose version &> /dev/null; then + # shellcheck disable=SC2086 + docker compose down ${REMOVE_VOLUMES} ${REMOVE_IMAGES} +else + # shellcheck disable=SC2086 + docker-compose down ${REMOVE_VOLUMES} ${REMOVE_IMAGES} +fi + +echo "" +echo "✅ Demo stopped successfully!" From 9a042d67828882e740fdca401b3018db08e4f6bd Mon Sep 17 00:00:00 2001 From: Bartosz Burda Date: Sun, 1 Feb 2026 18:44:41 +0000 Subject: [PATCH 2/2] fix(sensor-demo): use consistent dash-based naming in comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply review suggestions from @mfaferek93: - Change anomaly_detector → anomaly-detector in inject-nan.sh, inject-failure.sh - Change diagnostic_bridge → diagnostic-bridge in inject-drift.sh, inject-noise.sh Maintains consistency with dash-based entity IDs used in API calls. --- demos/sensor_diagnostics/inject-drift.sh | 4 ++-- demos/sensor_diagnostics/inject-failure.sh | 4 ++-- demos/sensor_diagnostics/inject-nan.sh | 6 +++--- demos/sensor_diagnostics/inject-noise.sh | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/demos/sensor_diagnostics/inject-drift.sh b/demos/sensor_diagnostics/inject-drift.sh index 2b4818e..0cb30d2 100755 --- a/demos/sensor_diagnostics/inject-drift.sh +++ b/demos/sensor_diagnostics/inject-drift.sh @@ -1,11 +1,11 @@ #!/bin/bash # Inject sensor drift fault - demonstrates LEGACY fault reporting path -# LiDAR drift → DiagnosticArray → /diagnostics → diagnostic_bridge → FaultManager +# LiDAR drift → DiagnosticArray → /diagnostics → diagnostic-bridge → FaultManager GATEWAY_URL="${GATEWAY_URL:-http://localhost:8080}" API_BASE="${GATEWAY_URL}/api/v1" -echo "Injecting DRIFT fault (Legacy path: LiDAR → diagnostic_bridge)..." +echo "Injecting DRIFT fault (Legacy path: LiDAR → diagnostic-bridge)..." echo "" # LiDAR drift: uses legacy diagnostics path diff --git a/demos/sensor_diagnostics/inject-failure.sh b/demos/sensor_diagnostics/inject-failure.sh index 66bce3f..71ff173 100755 --- a/demos/sensor_diagnostics/inject-failure.sh +++ b/demos/sensor_diagnostics/inject-failure.sh @@ -1,11 +1,11 @@ #!/bin/bash # Inject sensor failure (timeout) fault - demonstrates MODERN fault reporting path -# IMU sensor → anomaly_detector → FaultManager (via ReportFault service) +# IMU sensor → anomaly-detector → FaultManager (via ReportFault service) GATEWAY_URL="${GATEWAY_URL:-http://localhost:8080}" API_BASE="${GATEWAY_URL}/api/v1" -echo "Injecting SENSOR FAILURE fault (Modern path: IMU → anomaly_detector)..." +echo "Injecting SENSOR FAILURE fault (Modern path: IMU → anomaly-detector)..." # Set high failure probability - IMU will stop publishing echo "Setting IMU failure_probability to 1.0 (complete failure)..." diff --git a/demos/sensor_diagnostics/inject-nan.sh b/demos/sensor_diagnostics/inject-nan.sh index b9f5dca..94f0931 100755 --- a/demos/sensor_diagnostics/inject-nan.sh +++ b/demos/sensor_diagnostics/inject-nan.sh @@ -15,16 +15,16 @@ curl -s -X PUT "${API_BASE}/apps/lidar-sim/configurations/inject_nan" \ -d '{"value": true}' echo "" -# MODERN PATH: IMU/GPS → anomaly_detector → FaultManager (direct service call) +# MODERN PATH: IMU/GPS → anomaly-detector → FaultManager (direct service call) echo "[MODERN PATH] Enabling IMU inject_nan..." -echo " Fault path: imu-sim → anomaly_detector → /fault_manager/report_fault" +echo " Fault path: imu-sim → anomaly-detector → /fault_manager/report_fault" curl -s -X PUT "${API_BASE}/apps/imu-sim/configurations/inject_nan" \ -H "Content-Type: application/json" \ -d '{"value": true}' echo "" echo "[MODERN PATH] Enabling GPS inject_nan..." -echo " Fault path: gps-sim → anomaly_detector → /fault_manager/report_fault" +echo " Fault path: gps-sim → anomaly-detector → /fault_manager/report_fault" curl -s -X PUT "${API_BASE}/apps/gps-sim/configurations/inject_nan" \ -H "Content-Type: application/json" \ -d '{"value": true}' diff --git a/demos/sensor_diagnostics/inject-noise.sh b/demos/sensor_diagnostics/inject-noise.sh index 9ec85f7..a4fdfe7 100755 --- a/demos/sensor_diagnostics/inject-noise.sh +++ b/demos/sensor_diagnostics/inject-noise.sh @@ -1,11 +1,11 @@ #!/bin/bash # Inject high noise fault - demonstrates LEGACY fault reporting path -# LiDAR/Camera → DiagnosticArray → /diagnostics → diagnostic_bridge → FaultManager +# LiDAR/Camera → DiagnosticArray → /diagnostics → diagnostic-bridge → FaultManager GATEWAY_URL="${GATEWAY_URL:-http://localhost:8080}" API_BASE="${GATEWAY_URL}/api/v1" -echo "Injecting HIGH NOISE fault (Legacy path: LiDAR/Camera → diagnostic_bridge)..." +echo "Injecting HIGH NOISE fault (Legacy path: LiDAR/Camera → diagnostic-bridge)..." echo "" # LiDAR: increase noise stddev (uses legacy diagnostics path)