diff --git a/demos/moveit_pick_place/arm-self-test.sh b/demos/moveit_pick_place/arm-self-test.sh old mode 100644 new mode 100755 diff --git a/demos/moveit_pick_place/container_scripts/moveit-planning/inject-collision/script.bash b/demos/moveit_pick_place/container_scripts/moveit-planning/inject-collision/script.bash index 3985905..5e39fcc 100644 --- a/demos/moveit_pick_place/container_scripts/moveit-planning/inject-collision/script.bash +++ b/demos/moveit_pick_place/container_scripts/moveit-planning/inject-collision/script.bash @@ -5,10 +5,13 @@ set -eu +# ROS setup.bash dereferences AMENT_TRACE_SETUP_FILES; relax nounset around it. +set +u # shellcheck source=/dev/null source /opt/ros/jazzy/setup.bash # shellcheck source=/dev/null source /root/demo_ws/install/setup.bash +set -u echo "Injecting COLLISION fault..." echo " Spawning surprise obstacle in robot workspace" diff --git a/demos/moveit_pick_place/container_scripts/moveit-planning/inject-planning-failure/script.bash b/demos/moveit_pick_place/container_scripts/moveit-planning/inject-planning-failure/script.bash index 18d8d8c..3e93a15 100644 --- a/demos/moveit_pick_place/container_scripts/moveit-planning/inject-planning-failure/script.bash +++ b/demos/moveit_pick_place/container_scripts/moveit-planning/inject-planning-failure/script.bash @@ -5,10 +5,13 @@ set -eu +# ROS setup.bash dereferences AMENT_TRACE_SETUP_FILES; relax nounset around it. +set +u # shellcheck source=/dev/null source /opt/ros/jazzy/setup.bash # shellcheck source=/dev/null source /root/demo_ws/install/setup.bash +set -u echo "Injecting PLANNING FAILURE fault..." echo " Adding collision wall between pick and place positions" diff --git a/demos/moveit_pick_place/container_scripts/moveit-planning/restore-normal/script.bash b/demos/moveit_pick_place/container_scripts/moveit-planning/restore-normal/script.bash index a50d81a..e9e02d7 100644 --- a/demos/moveit_pick_place/container_scripts/moveit-planning/restore-normal/script.bash +++ b/demos/moveit_pick_place/container_scripts/moveit-planning/restore-normal/script.bash @@ -4,10 +4,13 @@ set -eu +# ROS setup.bash dereferences AMENT_TRACE_SETUP_FILES; relax nounset around it. +set +u # shellcheck source=/dev/null source /opt/ros/jazzy/setup.bash # shellcheck source=/dev/null source /root/demo_ws/install/setup.bash +set -u GATEWAY_URL="${GATEWAY_URL:-http://localhost:8080}" API_BASE="${GATEWAY_URL}/api/v1" diff --git a/demos/moveit_pick_place/planning-benchmark.sh b/demos/moveit_pick_place/planning-benchmark.sh old mode 100644 new mode 100755 diff --git a/demos/moveit_pick_place/setup-triggers.sh b/demos/moveit_pick_place/setup-triggers.sh index 06ff53e..3f2ed7b 100755 --- a/demos/moveit_pick_place/setup-triggers.sh +++ b/demos/moveit_pick_place/setup-triggers.sh @@ -2,8 +2,8 @@ # Create fault-monitoring trigger for moveit pick-and-place demo # Alerts on any fault change reported by the manipulation monitor export ENTITY_TYPE="apps" -# Uses ROS node name (underscore) - must match reporting_sources in FaultEvent -export ENTITY_ID="manipulation_monitor" +# Gateway normalises entity IDs with hyphens (matches the registered apps id). +export ENTITY_ID="manipulation-monitor" export INJECT_HINT="./inject-planning-failure.sh" # shellcheck disable=SC1091 source "$(cd "$(dirname "$0")" && pwd)/../../lib/setup-trigger.sh" diff --git a/demos/moveit_pick_place/watch-triggers.sh b/demos/moveit_pick_place/watch-triggers.sh index 4cae6e7..53651bf 100755 --- a/demos/moveit_pick_place/watch-triggers.sh +++ b/demos/moveit_pick_place/watch-triggers.sh @@ -2,6 +2,6 @@ # Watch trigger events for moveit pick-and-place demo # Connects to SSE stream and prints fault events in real time export ENTITY_TYPE="apps" -export ENTITY_ID="manipulation_monitor" +export ENTITY_ID="manipulation-monitor" # shellcheck disable=SC1091 source "$(cd "$(dirname "$0")" && pwd)/../../lib/watch-trigger.sh" "$@" diff --git a/demos/multi_ecu_aggregation/container_scripts/actuation-ecu/inject-gripper-jam/script.bash b/demos/multi_ecu_aggregation/container_scripts/actuation-ecu/inject-gripper-jam/script.bash index e0a2f64..6913093 100644 --- a/demos/multi_ecu_aggregation/container_scripts/actuation-ecu/inject-gripper-jam/script.bash +++ b/demos/multi_ecu_aggregation/container_scripts/actuation-ecu/inject-gripper-jam/script.bash @@ -2,10 +2,13 @@ # Inject gripper jam - gripper controller stuck set -eu +# ROS setup.bash dereferences AMENT_TRACE_SETUP_FILES; relax nounset around it. +set +u # shellcheck source=/dev/null source /opt/ros/jazzy/setup.bash # shellcheck source=/dev/null source /root/demo_ws/install/setup.bash +set -u ros2 param set /actuation/gripper_controller inject_jam true diff --git a/demos/multi_ecu_aggregation/container_scripts/actuation-ecu/restore-normal/script.bash b/demos/multi_ecu_aggregation/container_scripts/actuation-ecu/restore-normal/script.bash index bb583e7..a7d6e72 100644 --- a/demos/multi_ecu_aggregation/container_scripts/actuation-ecu/restore-normal/script.bash +++ b/demos/multi_ecu_aggregation/container_scripts/actuation-ecu/restore-normal/script.bash @@ -2,10 +2,13 @@ # Reset all actuation node parameters to defaults set -eu +# ROS setup.bash dereferences AMENT_TRACE_SETUP_FILES; relax nounset around it. +set +u # shellcheck source=/dev/null source /opt/ros/jazzy/setup.bash # shellcheck source=/dev/null source /root/demo_ws/install/setup.bash +set -u ERRORS=0 diff --git a/demos/multi_ecu_aggregation/container_scripts/perception-ecu/inject-sensor-failure/script.bash b/demos/multi_ecu_aggregation/container_scripts/perception-ecu/inject-sensor-failure/script.bash index 321148f..4d784ce 100644 --- a/demos/multi_ecu_aggregation/container_scripts/perception-ecu/inject-sensor-failure/script.bash +++ b/demos/multi_ecu_aggregation/container_scripts/perception-ecu/inject-sensor-failure/script.bash @@ -2,10 +2,13 @@ # Inject LiDAR sensor failure - high failure probability set -eu +# ROS setup.bash dereferences AMENT_TRACE_SETUP_FILES; relax nounset around it. +set +u # shellcheck source=/dev/null source /opt/ros/jazzy/setup.bash # shellcheck source=/dev/null source /root/demo_ws/install/setup.bash +set -u ros2 param set /perception/lidar_driver failure_probability 0.8 diff --git a/demos/multi_ecu_aggregation/container_scripts/perception-ecu/restore-normal/script.bash b/demos/multi_ecu_aggregation/container_scripts/perception-ecu/restore-normal/script.bash index 9f22b5b..23d7e73 100644 --- a/demos/multi_ecu_aggregation/container_scripts/perception-ecu/restore-normal/script.bash +++ b/demos/multi_ecu_aggregation/container_scripts/perception-ecu/restore-normal/script.bash @@ -2,10 +2,13 @@ # Reset all perception node parameters to defaults set -eu +# ROS setup.bash dereferences AMENT_TRACE_SETUP_FILES; relax nounset around it. +set +u # shellcheck source=/dev/null source /opt/ros/jazzy/setup.bash # shellcheck source=/dev/null source /root/demo_ws/install/setup.bash +set -u ERRORS=0 diff --git a/demos/multi_ecu_aggregation/container_scripts/planning-ecu/inject-planning-delay/script.bash b/demos/multi_ecu_aggregation/container_scripts/planning-ecu/inject-planning-delay/script.bash index d48225b..d186826 100644 --- a/demos/multi_ecu_aggregation/container_scripts/planning-ecu/inject-planning-delay/script.bash +++ b/demos/multi_ecu_aggregation/container_scripts/planning-ecu/inject-planning-delay/script.bash @@ -2,10 +2,13 @@ # Inject path planning delay - 5000ms processing time set -eu +# ROS setup.bash dereferences AMENT_TRACE_SETUP_FILES; relax nounset around it. +set +u # shellcheck source=/dev/null source /opt/ros/jazzy/setup.bash # shellcheck source=/dev/null source /root/demo_ws/install/setup.bash +set -u ros2 param set /planning/path_planner planning_delay_ms 5000 diff --git a/demos/multi_ecu_aggregation/container_scripts/planning-ecu/restore-normal/script.bash b/demos/multi_ecu_aggregation/container_scripts/planning-ecu/restore-normal/script.bash index 68e4933..4ff9ced 100644 --- a/demos/multi_ecu_aggregation/container_scripts/planning-ecu/restore-normal/script.bash +++ b/demos/multi_ecu_aggregation/container_scripts/planning-ecu/restore-normal/script.bash @@ -2,10 +2,13 @@ # Reset all planning node parameters to defaults set -eu +# ROS setup.bash dereferences AMENT_TRACE_SETUP_FILES; relax nounset around it. +set +u # shellcheck source=/dev/null source /opt/ros/jazzy/setup.bash # shellcheck source=/dev/null source /root/demo_ws/install/setup.bash +set -u ERRORS=0 diff --git a/demos/sensor_diagnostics/inject-fault-scenario.sh b/demos/sensor_diagnostics/inject-fault-scenario.sh old mode 100644 new mode 100755 diff --git a/demos/sensor_diagnostics/run-diagnostics.sh b/demos/sensor_diagnostics/run-diagnostics.sh old mode 100644 new mode 100755 diff --git a/demos/sensor_diagnostics/setup-triggers.sh b/demos/sensor_diagnostics/setup-triggers.sh index f7dcbaf..7d731a0 100755 --- a/demos/sensor_diagnostics/setup-triggers.sh +++ b/demos/sensor_diagnostics/setup-triggers.sh @@ -2,8 +2,8 @@ # Create fault-monitoring trigger for sensor diagnostics demo # Alerts on any new fault reported via the diagnostic bridge export ENTITY_TYPE="apps" -# Uses ROS node name (underscore) - must match reporting_sources in FaultEvent -export ENTITY_ID="diagnostic_bridge" +# Gateway normalises entity IDs with hyphens (matches the registered apps id). +export ENTITY_ID="diagnostic-bridge" export INJECT_HINT="./inject-nan.sh" # shellcheck disable=SC1091 source "$(cd "$(dirname "$0")" && pwd)/../../lib/setup-trigger.sh" diff --git a/demos/sensor_diagnostics/watch-triggers.sh b/demos/sensor_diagnostics/watch-triggers.sh index 298f3b4..3fbd928 100755 --- a/demos/sensor_diagnostics/watch-triggers.sh +++ b/demos/sensor_diagnostics/watch-triggers.sh @@ -2,6 +2,6 @@ # Watch trigger events for sensor diagnostics demo # Connects to SSE stream and prints fault events in real time export ENTITY_TYPE="apps" -export ENTITY_ID="diagnostic_bridge" +export ENTITY_ID="diagnostic-bridge" # shellcheck disable=SC1091 source "$(cd "$(dirname "$0")" && pwd)/../../lib/watch-trigger.sh" "$@" diff --git a/demos/turtlebot3_integration/container_scripts/nav2-stack/inject-localization-failure/script.bash b/demos/turtlebot3_integration/container_scripts/nav2-stack/inject-localization-failure/script.bash index c34b396..64a3f57 100755 --- a/demos/turtlebot3_integration/container_scripts/nav2-stack/inject-localization-failure/script.bash +++ b/demos/turtlebot3_integration/container_scripts/nav2-stack/inject-localization-failure/script.bash @@ -15,7 +15,9 @@ echo "Waiting for particles to scatter..." sleep 2 echo "Sending navigation goal with high localization uncertainty..." -curl -sf -X POST "${API_BASE}/apps/bt-navigator/operations/navigate_to_pose/executions" \ +# Drop -f: action server typically rejects the goal under scattered particles, +# which is the demo's intended failure mode - treat HTTP 400 as expected. +RESPONSE=$(curl -s -X POST "${API_BASE}/apps/bt-navigator/operations/navigate_to_pose/executions" \ -H "Content-Type: application/json" \ -d '{ "goal": { @@ -27,7 +29,8 @@ curl -sf -X POST "${API_BASE}/apps/bt-navigator/operations/navigate_to_pose/exec } } } - }' + }') +echo "${RESPONSE}" | jq '.' 2>/dev/null || echo "${RESPONSE}" echo "" echo "Localization failure injected." diff --git a/demos/turtlebot3_integration/setup-triggers.sh b/demos/turtlebot3_integration/setup-triggers.sh index 8092c13..b9390f6 100755 --- a/demos/turtlebot3_integration/setup-triggers.sh +++ b/demos/turtlebot3_integration/setup-triggers.sh @@ -1,9 +1,10 @@ #!/bin/bash # Create fault-monitoring trigger for turtlebot3 integration demo -# Alerts on any fault change reported by the anomaly detector +# Alerts on any fault change reported via the diagnostic bridge - the +# anomaly-detector app has no faults of its own, faults arrive from +# /diagnostics through the bridge. export ENTITY_TYPE="apps" -# Uses ROS node name (underscore) - must match reporting_sources in FaultEvent -export ENTITY_ID="anomaly_detector" +export ENTITY_ID="diagnostic-bridge" export INJECT_HINT="./inject-nav-failure.sh" # shellcheck disable=SC1091 source "$(cd "$(dirname "$0")" && pwd)/../../lib/setup-trigger.sh" diff --git a/demos/turtlebot3_integration/watch-triggers.sh b/demos/turtlebot3_integration/watch-triggers.sh index 6f96330..d6d9b6c 100755 --- a/demos/turtlebot3_integration/watch-triggers.sh +++ b/demos/turtlebot3_integration/watch-triggers.sh @@ -2,6 +2,6 @@ # Watch trigger events for turtlebot3 integration demo # Connects to SSE stream and prints fault events in real time export ENTITY_TYPE="apps" -export ENTITY_ID="anomaly_detector" +export ENTITY_ID="diagnostic-bridge" # shellcheck disable=SC1091 source "$(cd "$(dirname "$0")" && pwd)/../../lib/watch-trigger.sh" "$@" diff --git a/lib/setup-trigger.sh b/lib/setup-trigger.sh index 83c937a..e43f5e2 100644 --- a/lib/setup-trigger.sh +++ b/lib/setup-trigger.sh @@ -8,7 +8,7 @@ if [ -z "${ENTITY_TYPE:-}" ] || [ -z "${ENTITY_ID:-}" ]; then exit 1 fi -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck disable=SC1091 source "${SCRIPT_DIR}/triggers-api.sh" diff --git a/lib/watch-trigger.sh b/lib/watch-trigger.sh index 57dfc1a..c16db14 100644 --- a/lib/watch-trigger.sh +++ b/lib/watch-trigger.sh @@ -8,7 +8,7 @@ if [ -z "${ENTITY_TYPE:-}" ] || [ -z "${ENTITY_ID:-}" ]; then exit 1 fi -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck disable=SC1091 source "${SCRIPT_DIR}/triggers-api.sh" diff --git a/tests/smoke_test_multi_ecu.sh b/tests/smoke_test_multi_ecu.sh index 3a5e2a2..8fec105 100755 --- a/tests/smoke_test_multi_ecu.sh +++ b/tests/smoke_test_multi_ecu.sh @@ -26,14 +26,25 @@ wait_for_gateway 120 # Wait for runtime node linking (perception ECU local nodes) wait_for_runtime_linking "/apps/lidar-driver/data" 90 -# Wait for aggregation to discover peer ECUs -echo " Waiting for aggregated entities from planning ECU (max 60s)..." -if poll_until "/apps" '.items[] | select(.id == "path-planner")' 60; then - echo -e " ${GREEN}Aggregation discovery complete${NC}" -else - echo -e " ${RED}Aggregation discovery did not complete within 60s${NC}" - exit 1 -fi +# Wait for aggregation to discover peer ECUs. +# The aggregator pulls each peer independently, so a single peer's marker app is +# not a sufficient readiness gate: we must see a representative app from EACH +# peer ECU before the discovery assertions run. Otherwise a slower peer +# (typically the actuation ECU) races the checks and surfaces as missing apps +# ("found 7" instead of >=10). +# planning ECU -> path-planner +# actuation ECU -> motor-controller +echo " Waiting for aggregated entities from planning + actuation ECUs (max 60s each)..." +for peer in "planning ECU:path-planner" "actuation ECU:motor-controller"; do + peer_name="${peer%%:*}" + peer_app="${peer##*:}" + if poll_until "/apps" ".items[] | select(.id == \"${peer_app}\")" 60; then + echo -e " ${GREEN}${peer_name} aggregated (${peer_app})${NC}" + else + echo -e " ${RED}${peer_name} not aggregated within 60s (${peer_app} missing)${NC}" + exit 1 + fi +done # --- Tests ---