Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
111 changes: 83 additions & 28 deletions demos/moveit_pick_place/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# MoveIt 2 Pick-and-Place Integration Demo

A comprehensive integration demo combining a **Panda 7-DOF robot arm** with **MoveIt 2** motion planning and **ros2_medkit** SOVD-compliant diagnostics. The robot performs continuous pick-and-place cycles in a **Gazebo Harmonic factory scene** while a manipulation monitor detects faults planning failures, collisions and reports them through the SOVD REST API with environment snapshots.
A comprehensive integration demo combining a **Panda 7-DOF robot arm** with **MoveIt 2** motion planning and **ros2_medkit** SOVD-compliant diagnostics. The robot performs continuous pick-and-place cycles in a **Gazebo Harmonic factory scene** while a manipulation monitor detects faults - planning failures, collisions - and reports them through the SOVD REST API with environment snapshots.

## Status

✅ **Demo Ready** Docker-based deployment with MoveIt 2, Gazebo Harmonic physics simulation, factory environment, and full ros2_medkit stack.
✅ **Demo Ready** - Docker-based deployment with MoveIt 2, Gazebo Harmonic physics simulation, factory environment, and full ros2_medkit stack.

## Overview

Expand All @@ -14,7 +14,7 @@ This demo demonstrates:
- **Gazebo Harmonic simulation** with a realistic factory scene (conveyor belt, work table, storage, lighting)
- **Continuous pick-and-place** loop as a realistic manipulation workload
- **Manipulation fault monitoring** (planning failures, collision detection)
- **Fault snapshots** environment state captured at fault time (joint states, diagnostics)
- **Fault snapshots** - environment state captured at fault time (joint states, diagnostics)
- **SOVD-compliant REST API** with Areas → Components → Apps → Functions hierarchy
- **Manifest-based entity discovery** (hybrid mode with runtime enrichment)
- **2 fault injection scenarios** with visible Gazebo models and one-click scripts
Expand All @@ -25,7 +25,7 @@ This demo demonstrates:
- Docker and docker-compose
- `curl` and `jq` installed on the host (required for host-side scripts)
- X11 display server (for Gazebo GUI) or `--headless` mode
- (Optional) NVIDIA GPU + [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html) recommended for smooth Gazebo rendering
- (Optional) NVIDIA GPU + [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html) - recommended for smooth Gazebo rendering
- ~7 GB disk space for Docker image

## Quick Start
Expand Down Expand Up @@ -129,37 +129,37 @@ docker exec -it moveit_medkit_demo bash # Shell into container

```
Areas
├── manipulation/ Robot arm and gripper hardware
├── manipulation/ - Robot arm and gripper hardware
│ Components
│ ├── panda-arm 7-DOF Franka Emika Panda
│ ├── panda-arm - 7-DOF Franka Emika Panda
│ │ Apps: joint-state-broadcaster, panda-arm-controller, robot-state-publisher
│ └── panda-gripper 2-finger parallel gripper
│ └── panda-gripper - 2-finger parallel gripper
│ Apps: panda-hand-controller
├── planning/ MoveIt 2 motion planning stack
├── planning/ - MoveIt 2 motion planning stack
│ Components
│ ├── moveit-planning OMPL planning pipeline
│ ├── moveit-planning - OMPL planning pipeline
│ │ Apps: move-group
│ └── pick-place-loop Pick-and-place demo node
│ └── pick-place-loop - Pick-and-place demo node
│ Apps: pick-place-node
├── diagnostics/ ros2_medkit gateway and fault management
├── diagnostics/ - ros2_medkit gateway and fault management
│ Components
│ ├── gateway REST API
│ ├── gateway - REST API
│ │ Apps: medkit-gateway
│ └── fault-manager Fault aggregation
│ └── fault-manager - Fault aggregation
│ Apps: medkit-fault-manager
└── bridge/ Legacy diagnostics bridge
└── bridge/ - Legacy diagnostics bridge
Components
└── diagnostic-bridge
Apps: diagnostic-bridge-app, manipulation-monitor

Functions
├── pick-and-place Pick objects and place at target positions
├── motion-planning Plan collision-free motion trajectories
├── gripper-control Open and close the Panda gripper
└── fault-management Collect and expose faults via SOVD API
├── pick-and-place - Pick objects and place at target positions
├── motion-planning - Plan collision-free motion trajectories
├── gripper-control - Open and close the Panda gripper
└── fault-management - Collect and expose faults via SOVD API
```

## REST API Examples
Expand Down Expand Up @@ -223,8 +223,8 @@ curl http://localhost:8080/api/v1/apps/manipulation-monitor/faults/MOTION_PLANNI
```

Captured topics (background capture, always available):
- `/joint_states` Current joint positions at fault time
- `/diagnostics` Active diagnostics messages
- `/joint_states` - Current joint positions at fault time
- `/diagnostics` - Active diagnostics messages

### Modify Configurations via REST API

Expand Down Expand Up @@ -284,6 +284,59 @@ GATEWAY_URL=http://192.168.1.10:8080 ./inject-collision.sh

The host-side wrapper scripts (`./inject-collision.sh`, etc.) call the Scripts API automatically - no `docker exec` needed. Prerequisites: `curl` and `jq` must be installed on the host.

## Triggers (Condition-Based Alerts)

The gateway supports condition-based triggers that fire when specific events occur, delivering notifications via Server-Sent Events (SSE). This demo creates a fault-monitoring trigger that alerts on any new or updated faults reported by the manipulation monitor (including planning failures and collisions).

### Setup

```bash
# Terminal 1: Start the demo
./run-demo.sh

# Terminal 2: Create the fault trigger
./setup-triggers.sh

# Terminal 3: Watch for trigger events (blocking - Ctrl+C to stop)
./watch-triggers.sh

# Terminal 2: Inject a fault - the trigger fires in Terminal 3!
./inject-planning-failure.sh
```

### How It Works

1. `setup-triggers.sh` creates a trigger via `POST /api/v1/apps/manipulation_monitor/triggers`:
- **Resource:** `/api/v1/apps/manipulation_monitor/faults` (watches fault collection)
- **Condition:** `OnChange` (fires on any new or updated fault)
- **Multishot:** `true` (fires repeatedly, not just once)
- **Lifetime:** 3600 seconds (auto-expires after 1 hour)
2. `watch-triggers.sh` connects to the SSE event stream at the trigger's `event_source` URL
3. When a fault is injected and detected by the gateway, the trigger fires and an SSE event is delivered

### Manual API Usage

```bash
# Create a trigger
curl -X POST http://localhost:8080/api/v1/apps/manipulation_monitor/triggers \
-H "Content-Type: application/json" \
-d '{
"resource": "/api/v1/apps/manipulation_monitor/faults",
"trigger_condition": {"condition_type": "OnChange"},
"multishot": true,
"lifetime": 3600
}' | jq

# List triggers
curl http://localhost:8080/api/v1/apps/manipulation_monitor/triggers | jq

# Watch events (replace TRIGGER_ID)
curl -N http://localhost:8080/api/v1/apps/manipulation_monitor/triggers/TRIGGER_ID/events

# Delete a trigger
curl -X DELETE http://localhost:8080/api/v1/apps/manipulation_monitor/triggers/TRIGGER_ID
```

## Fault Injection Scenarios

The fault injection scripts run inside the container via the Scripts API. The host-side `./inject-*.sh` and `./restore-normal.sh` wrappers call the gateway REST endpoint - no `docker exec` required.
Expand All @@ -298,7 +351,7 @@ Blocks the robot's path with a large collision wall (visible as orange wall in G

| Code | Severity | Description |
|------|----------|-------------|
| `MOTION_PLANNING_FAILED` | ERROR | MoveGroup goal ABORTED no collision-free path |
| `MOTION_PLANNING_FAILED` | ERROR | MoveGroup goal ABORTED - no collision-free path |

### 2. Collision Detection

Expand Down Expand Up @@ -346,16 +399,18 @@ Connect it to the gateway at `http://localhost:8080` to browse:

| Script | Description |
|--------|-------------|
| `run-demo.sh` | **Start the demo** build and launch the Docker container |
| `run-demo.sh` | **Start the demo** - build and launch the Docker container |
| `stop-demo.sh` | Stop demo containers |
| `move-arm.sh` | **Interactive arm controller** move to preset positions |
| `move-arm.sh` | **Interactive arm controller** - move to preset positions |
| `check-entities.sh` | Explore the full SOVD entity hierarchy with sample data |
| `check-faults.sh` | View active faults with severity summary |
| `inject-planning-failure.sh` | Scripts API wrapper — inject planning failure |
| `inject-collision.sh` | Scripts API wrapper — inject collision obstacle |
| `restore-normal.sh` | Scripts API wrapper — restore normal operation |
| `arm-self-test.sh` | Scripts API wrapper — run arm self-test |
| `planning-benchmark.sh` | Scripts API wrapper — run planning benchmark |
| `inject-planning-failure.sh` | Scripts API wrapper - inject planning failure |
| `inject-collision.sh` | Scripts API wrapper - inject collision obstacle |
| `restore-normal.sh` | Scripts API wrapper - restore normal operation |
| `arm-self-test.sh` | Scripts API wrapper - run arm self-test |
| `planning-benchmark.sh` | Scripts API wrapper - run planning benchmark |
| `setup-triggers.sh` | Create OnChange fault trigger |
| `watch-triggers.sh` | Watch trigger events via SSE stream |

Scripts API wrappers require `curl` and `jq` on the host and call the gateway REST endpoint directly - no `docker exec` needed.

Expand Down
5 changes: 5 additions & 0 deletions demos/moveit_pick_place/run-demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -166,5 +166,10 @@ if [[ "$DETACH_MODE" == "true" ]]; then
echo " docker exec -it moveit_medkit_demo bash # CPU"
echo " docker exec -it moveit_medkit_demo_nvidia bash # NVIDIA"
echo ""
echo "📡 Triggers (condition-based alerts):"
echo " 1. ./setup-triggers.sh # Create fault alert trigger"
echo " 2. ./watch-triggers.sh # Watch events in a new terminal (blocking)"
echo " 3. ./inject-planning-failure.sh # Inject a fault to fire the trigger"
echo ""
echo "🛑 To stop: ./stop-demo.sh"
fi
9 changes: 9 additions & 0 deletions demos/moveit_pick_place/setup-triggers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
# 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"
export INJECT_HINT="./inject-planning-failure.sh"
# shellcheck disable=SC1091
source "$(cd "$(dirname "$0")" && pwd)/../../lib/setup-trigger.sh"
7 changes: 7 additions & 0 deletions demos/moveit_pick_place/watch-triggers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash
# 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"
# shellcheck disable=SC1091
source "$(cd "$(dirname "$0")" && pwd)/../../lib/watch-trigger.sh" "$@"
55 changes: 55 additions & 0 deletions demos/sensor_diagnostics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,59 @@ GATEWAY_URL=http://192.168.1.10:8080 ./inject-nan.sh
| `inject-noise` | Inject high noise on LiDAR and Camera |
| `restore-normal` | Reset all sensors and clear faults |

## Triggers (Condition-Based Alerts)

The gateway supports condition-based triggers that fire when specific events occur, delivering notifications via Server-Sent Events (SSE). This demo creates a fault-monitoring trigger that alerts whenever a new fault is reported.

### Setup

```bash
# Terminal 1: Start the demo
./run-demo.sh

# Terminal 2: Create the fault trigger
./setup-triggers.sh

# Terminal 3: Watch for trigger events (blocking - Ctrl+C to stop)
./watch-triggers.sh

# Terminal 2: Inject a fault - the trigger fires in Terminal 3!
./inject-nan.sh
```

### How It Works

1. `setup-triggers.sh` creates a trigger via `POST /api/v1/apps/diagnostic_bridge/triggers`:
- **Resource:** `/api/v1/apps/diagnostic_bridge/faults` (watches fault collection)
- **Condition:** `OnChange` (fires on any new or updated fault)
- **Multishot:** `true` (fires repeatedly, not just once)
- **Lifetime:** 3600 seconds (auto-expires after 1 hour)
2. `watch-triggers.sh` connects to the SSE event stream at the trigger's `event_source` URL
3. When a fault is injected and detected by the gateway, the trigger fires and an SSE event is delivered

### Manual API Usage

```bash
# Create a trigger
curl -X POST http://localhost:8080/api/v1/apps/diagnostic_bridge/triggers \
-H "Content-Type: application/json" \
-d '{
"resource": "/api/v1/apps/diagnostic_bridge/faults",
"trigger_condition": {"condition_type": "OnChange"},
"multishot": true,
"lifetime": 3600
}' | jq

# List triggers
curl http://localhost:8080/api/v1/apps/diagnostic_bridge/triggers | jq

# Watch events (replace TRIGGER_ID)
curl -N http://localhost:8080/api/v1/apps/diagnostic_bridge/triggers/TRIGGER_ID/events

# Delete a trigger
curl -X DELETE http://localhost:8080/api/v1/apps/diagnostic_bridge/triggers/TRIGGER_ID
```

## API Examples

### Read Sensor Data
Expand Down Expand Up @@ -259,6 +312,8 @@ curl http://localhost:8080/api/v1/faults | jq
| `inject-nan.sh` | Inject NaN values |
| `inject-drift.sh` | Enable sensor drift |
| `restore-normal.sh` | Clear all faults |
| `setup-triggers.sh` | Create OnChange fault trigger |
| `watch-triggers.sh` | Watch trigger events via SSE stream |

> **Note:** All diagnostic scripts (`inject-*.sh`, `restore-normal.sh`, `run-diagnostics.sh`, `inject-fault-scenario.sh`) are also available via the [Scripts API](#scripts-api) - callable as REST endpoints without requiring the host-side scripts.

Expand Down
5 changes: 5 additions & 0 deletions demos/sensor_diagnostics/run-demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ if [[ "$DETACH_MODE" == "true" ]]; then
echo " ./inject-drift.sh # Inject sensor drift"
echo " ./restore-normal.sh # Restore normal operation"
echo ""
echo "📡 Triggers (condition-based alerts):"
echo " 1. ./setup-triggers.sh # Create fault alert trigger"
echo " 2. ./watch-triggers.sh # Watch events in a new terminal (blocking)"
echo " 3. ./inject-nan.sh # Inject a fault to fire the trigger"
echo ""
echo "🌐 Web UI: http://localhost:3000"
echo "🌐 REST API: http://localhost:8080/api/v1/"
echo ""
Expand Down
9 changes: 9 additions & 0 deletions demos/sensor_diagnostics/setup-triggers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
# 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"
export INJECT_HINT="./inject-nan.sh"
# shellcheck disable=SC1091
source "$(cd "$(dirname "$0")" && pwd)/../../lib/setup-trigger.sh"
7 changes: 7 additions & 0 deletions demos/sensor_diagnostics/watch-triggers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash
# 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"
# shellcheck disable=SC1091
source "$(cd "$(dirname "$0")" && pwd)/../../lib/watch-trigger.sh" "$@"
55 changes: 55 additions & 0 deletions demos/turtlebot3_integration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,59 @@ GATEWAY_URL=http://192.168.1.10:8080 ./inject-nav-failure.sh
| `inject-nav-failure` | Inject navigation failure (unreachable goal) |
| `restore-normal` | Reset parameters and clear faults |

## Triggers (Condition-Based Alerts)

The gateway supports condition-based triggers that fire when specific events occur, delivering notifications via Server-Sent Events (SSE). This demo creates a fault-monitoring trigger that alerts on any new or updated faults reported by the anomaly detector (including navigation failures).

### Setup

```bash
# Terminal 1: Start the demo
./run-demo.sh

# Terminal 2: Create the fault trigger
./setup-triggers.sh

# Terminal 3: Watch for trigger events (blocking - Ctrl+C to stop)
./watch-triggers.sh

# Terminal 2: Inject a fault - the trigger fires in Terminal 3!
./inject-nav-failure.sh
```

### How It Works

1. `setup-triggers.sh` creates a trigger via `POST /api/v1/apps/anomaly_detector/triggers`:
- **Resource:** `/api/v1/apps/anomaly_detector/faults` (watches fault collection)
- **Condition:** `OnChange` (fires on any new or updated fault)
- **Multishot:** `true` (fires repeatedly, not just once)
- **Lifetime:** 3600 seconds (auto-expires after 1 hour)
2. `watch-triggers.sh` connects to the SSE event stream at the trigger's `event_source` URL
3. When a fault is injected and detected by the gateway, the trigger fires and an SSE event is delivered

### Manual API Usage

```bash
# Create a trigger
curl -X POST http://localhost:8080/api/v1/apps/anomaly_detector/triggers \
-H "Content-Type: application/json" \
-d '{
"resource": "/api/v1/apps/anomaly_detector/faults",
"trigger_condition": {"condition_type": "OnChange"},
"multishot": true,
"lifetime": 3600
}' | jq

# List triggers
curl http://localhost:8080/api/v1/apps/anomaly_detector/triggers | jq

# Watch events (replace TRIGGER_ID)
curl -N http://localhost:8080/api/v1/apps/anomaly_detector/triggers/TRIGGER_ID/events

# Delete a trigger
curl -X DELETE http://localhost:8080/api/v1/apps/anomaly_detector/triggers/TRIGGER_ID
```

## Fault Injection Scenarios

This demo includes scripts to inject various fault conditions for testing fault management.
Expand Down Expand Up @@ -543,6 +596,8 @@ demos/turtlebot3_integration/
| `inject-nav-failure.sh` | Inject navigation failure (unreachable goal) |
| `inject-localization-failure.sh` | Inject localization failure (AMCL reset) |
| `restore-normal.sh` | Restore normal operation and clear faults |
| `setup-triggers.sh` | Create OnChange fault trigger |
| `watch-triggers.sh` | Watch trigger events via SSE stream |

> **Note:** The inject, restore, and diagnostic scripts are also available via the [Scripts API](#scripts-api) - callable as REST endpoints without requiring the host-side scripts.

Expand Down
5 changes: 5 additions & 0 deletions demos/turtlebot3_integration/run-demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -173,5 +173,10 @@ if [[ "$DETACH_MODE" == "true" ]]; then
echo " docker exec -it turtlebot3_medkit_demo bash # CPU"
echo " docker exec -it turtlebot3_medkit_demo_nvidia bash # NVIDIA"
echo ""
echo "📡 Triggers (condition-based alerts):"
echo " 1. ./setup-triggers.sh # Create fault alert trigger"
echo " 2. ./watch-triggers.sh # Watch events in a new terminal (blocking)"
echo " 3. ./inject-nav-failure.sh # Inject a fault to fire the trigger"
echo ""
echo "🛑 To stop: ./stop-demo.sh"
fi
Loading
Loading