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
63 changes: 49 additions & 14 deletions demos/turtlebot3_integration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,45 @@ That's it! The script will:

1. Build the Docker images (first run takes ~5-10 min, downloads ~4GB)
2. Setup X11 forwarding for Gazebo GUI
3. Launch TurtleBot3 simulation + Nav2 + ros2_medkit gateway
3. Launch TurtleBot3 simulation + Nav2 + ros2_medkit gateway in **daemon mode** (background)
4. Launch sovd_web_ui at <http://localhost:3000>

**Note:** By default, the demo runs with **Gazebo GUI** for visualization. Requires X11 display.
**Note:** By default, the demo runs in **daemon mode** with **Gazebo GUI** enabled. This allows you to interact with ROS 2 while the demo is running.

### Running Headless (Server Only)

For CI/CD or remote servers without display:
### Available Options

```bash
HEADLESS=true docker compose up
# or:
./run-demo.sh --headless
./run-demo.sh # Daemon mode with GUI (default)
./run-demo.sh --attached # Foreground mode with live logs
./run-demo.sh --headless # Daemon mode without GUI (headless)
./run-demo.sh --nvidia # Use NVIDIA GPU acceleration
./run-demo.sh --update # Pull latest images before running
./run-demo.sh --no-cache # Rebuild without cache
```

### Running with GUI (Default)
### Viewing Logs and Interacting with ROS 2

With Gazebo visualization:
Since the demo runs in daemon mode by default, you can:

```bash
docker compose up
# or:
./run-demo.sh
# View live logs
docker compose --profile cpu logs -f

# Enter the container to run ROS 2 commands
docker exec -it turtlebot3_medkit_demo bash

# Inside the container:
ros2 node list
ros2 topic list
ros2 topic echo /odom
```

### Stopping the Demo

```bash
./stop-demo.sh # Stop containers
./stop-demo.sh --volumes # Stop and remove volumes
./stop-demo.sh --images # Stop and remove images
```

### 2. Access the Web UI
Expand All @@ -85,7 +101,15 @@ For hardware-accelerated Gazebo rendering with NVIDIA GPU:
You can also use Docker Compose directly:

```bash
docker compose --profile nvidia up --build
# CPU version (default profile)
docker compose --profile cpu up -d

# NVIDIA version
docker compose --profile nvidia up -d

# View logs
docker compose --profile cpu logs -f
docker compose --profile nvidia logs -f
```

## Controlling the Robot
Expand Down Expand Up @@ -118,14 +142,23 @@ curl -X PUT http://localhost:8080/api/v1/apps/turtlebot3-node/data/cmd_vel \

### Via ROS2 CLI (inside container)

First, enter the running container:

```bash
# Enter the container
docker exec -it turtlebot3_medkit_demo bash

# Inside the container:
# Send navigation goal
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose \
"{pose: {header: {frame_id: 'map'}, pose: {position: {x: 2.0, y: 0.5, z: 0.0}, orientation: {w: 1.0}}}}"

# Manual teleop
ros2 topic pub /cmd_vel geometry_msgs/msg/Twist \
"{linear: {x: 0.2}, angular: {z: 0.0}}" --once

# Exit container
exit
```

## REST API Endpoints
Expand Down Expand Up @@ -390,6 +423,7 @@ demos/turtlebot3_integration/
├── Dockerfile # ROS 2 Jazzy + TurtleBot3 + Nav2 + ros2_medkit
├── docker-compose.yml # Docker Compose (CPU & GPU via profiles)
├── run-demo.sh # One-click demo launcher
├── stop-demo.sh # Stop and cleanup demo
├── send-nav-goal.sh # Send navigation goal via SOVD API
├── check-entities.sh # Explore SOVD entity hierarchy
├── check-faults.sh # View active faults
Expand All @@ -412,6 +446,7 @@ demos/turtlebot3_integration/
| Script | Description |
|--------|-------------|
| `run-demo.sh` | Start the full demo (Docker) |
| `stop-demo.sh` | Stop containers and cleanup |
| `send-nav-goal.sh [x] [y] [yaw]` | Send navigation goal via SOVD API |
| `check-entities.sh` | Explore SOVD entity hierarchy |
| `check-faults.sh` | View active faults from gateway |
Expand Down
2 changes: 2 additions & 0 deletions demos/turtlebot3_integration/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
services:
# CPU-only version (default)
# Use with: docker compose --profile cpu up
turtlebot3-demo:
profiles: ["cpu"]
build:
context: .
dockerfile: Dockerfile
Expand Down
56 changes: 53 additions & 3 deletions demos/turtlebot3_integration/run-demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ trap cleanup EXIT
COMPOSE_ARGS=""
BUILD_ARGS=""
HEADLESS_MODE="false"
UPDATE_IMAGES="false"
DETACH_MODE="true"

usage() {
echo "Usage: $0 [OPTIONS]"
Expand All @@ -49,13 +51,17 @@ usage() {
echo " --nvidia Use NVIDIA GPU acceleration"
echo " --no-cache Build Docker images without cache"
echo " --headless Run without Gazebo GUI (default: GUI enabled)"
echo " --update Pull latest images before running"
echo " --attached Run in foreground (default: daemon mode)"
echo " -h, --help Show this help message"
echo ""
echo "Examples:"
echo " $0 # With Gazebo GUI (default)"
echo " $0 # Daemon mode (default)"
echo " $0 --attached # Foreground with logs"
echo " $0 --headless # Headless mode (no GUI)"
echo " $0 --nvidia # GPU acceleration + GUI"
echo " $0 --no-cache # Rebuild without cache"
echo " $0 --update # Pull and run latest version"
echo ""
echo "Environment variables:"
echo " HEADLESS=true|false Control GUI mode (default: false)"
Expand All @@ -75,6 +81,14 @@ while [[ $# -gt 0 ]]; do
echo "Running in headless mode (no GUI)"
HEADLESS_MODE="true"
;;
--update)
echo "Will pull latest images"
UPDATE_IMAGES="true"
;;
--attached)
echo "Running in foreground mode"
DETACH_MODE="false"
;;
-h|--help)
usage
exit 0
Expand All @@ -90,11 +104,13 @@ done

if [[ -z "$COMPOSE_ARGS" ]]; then
echo "Using CPU-only mode (use --nvidia flag for GPU acceleration)"
COMPOSE_ARGS="--profile cpu"
fi

# Export HEADLESS mode for docker-compose
export HEADLESS=$HEADLESS_MODE
echo "Gazebo mode: $([ "$HEADLESS_MODE" = "true" ] && echo "headless (no GUI)" || echo "GUI enabled")"
echo "Run mode: $([ "$DETACH_MODE" = "true" ] && echo "daemon (background)" || echo "attached (foreground)")"

# Build and run
echo " Building and starting demo..."
Expand All @@ -108,12 +124,46 @@ echo "🌐 REST API available at: http://localhost:8080/api/v1/"
echo "🌐 Web UI available at: http://localhost:3000/"
echo ""

# Pull images if --update flag is set
if [[ "$UPDATE_IMAGES" == "true" ]]; then
echo "📥 Pulling latest images..."
if docker compose version &> /dev/null; then
# shellcheck disable=SC2086
docker compose ${COMPOSE_ARGS} pull
else
# shellcheck disable=SC2086
docker-compose ${COMPOSE_ARGS} pull
fi
echo ""
fi

# Set detach flag
DETACH_FLAG=""
if [[ "$DETACH_MODE" == "true" ]]; then
DETACH_FLAG="-d"
fi

if docker compose version &> /dev/null; then
# shellcheck disable=SC2086
docker compose ${COMPOSE_ARGS} build ${BUILD_ARGS} && \
docker compose ${COMPOSE_ARGS} up
docker compose ${COMPOSE_ARGS} up ${DETACH_FLAG}
else
# shellcheck disable=SC2086
docker-compose ${COMPOSE_ARGS} build ${BUILD_ARGS} && \
docker-compose ${COMPOSE_ARGS} up
docker-compose ${COMPOSE_ARGS} up ${DETACH_FLAG}
fi

if [[ "$DETACH_MODE" == "true" ]]; then
echo ""
echo "✅ Demo started in background!"
echo ""
echo "📊 To view logs:"
echo " docker compose --profile cpu logs -f # CPU version"
echo " docker compose --profile nvidia logs -f # NVIDIA version"
echo ""
echo "🔧 To interact with ROS 2:"
echo " docker exec -it turtlebot3_medkit_demo bash # CPU"
echo " docker exec -it turtlebot3_medkit_demo_nvidia bash # NVIDIA"
echo ""
echo "🛑 To stop: ./stop-demo.sh"
fi
74 changes: 74 additions & 0 deletions demos/turtlebot3_integration/stop-demo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/bin/bash
# Stop TurtleBot3 + ros2_medkit Demo

set -eu

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"

echo "🛑 Stopping TurtleBot3 + ros2_medkit 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

# Cleanup X11
echo "Cleaning up X11 permissions..."
xhost -local:docker 2>/dev/null || true

echo ""
echo "✅ Demo stopped successfully!"