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
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,34 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Check for trailing whitespace
run: |
! git grep -I --line-number --perl-regexp '\s+$' -- \
'*.md' '*.py' '*.yaml' '*.yml' || \
(echo "Found trailing whitespace in the files above" && exit 1)

- name: Check shell scripts with shellcheck
run: |
sudo apt-get update && sudo apt-get install -y shellcheck
find . \( -name "*.sh" -o -name "*.bash" \) -type f | xargs shellcheck

- name: Validate YAML files
run: |
sudo apt-get update && sudo apt-get install -y yamllint
YAMLLINT_CONFIG="{extends: relaxed, rules: {line-length: {max: 120}}}"
find . \( -name "*.yaml" -o -name "*.yml" \) -type f | xargs yamllint -d "$YAMLLINT_CONFIG"

docker-build:
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build TurtleBot3 demo image
run: |
cd demos/turtlebot3_integration
docker build -t turtlebot3-medkit-demo:test -f Dockerfile .
16 changes: 16 additions & 0 deletions demos/turtlebot3_integration/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.8)
project(turtlebot3_medkit_demo)

find_package(ament_cmake REQUIRED)

# Install launch files
install(DIRECTORY launch/
DESTINATION share/${PROJECT_NAME}/launch
)

# Install config files
install(DIRECTORY config/
DESTINATION share/${PROJECT_NAME}/config
)

ament_package()
68 changes: 68 additions & 0 deletions demos/turtlebot3_integration/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# TurtleBot3 + ros2_medkit Discovery Demo with Nav2 Navigation
# Full desktop image with Gazebo GUI support

FROM osrf/ros:jazzy-desktop

ENV DEBIAN_FRONTEND=noninteractive
ENV ROS_DISTRO=jazzy
ENV TURTLEBOT3_MODEL=burger
ENV GAZEBO_MODEL_PATH=/opt/ros/jazzy/share/turtlebot3_gazebo/models
ENV COLCON_WS=/root/demo_ws

# Install TurtleBot3, Nav2, and build dependencies
RUN apt-get update && apt-get install -y \
ros-jazzy-turtlebot3-gazebo \
ros-jazzy-turtlebot3-msgs \
ros-jazzy-turtlebot3-description \
ros-jazzy-turtlebot3-navigation2 \
ros-jazzy-nav2-bringup \
ros-jazzy-nav2-bt-navigator \
ros-jazzy-nav2-controller \
ros-jazzy-nav2-planner \
ros-jazzy-nav2-behaviors \
ros-jazzy-nav2-costmap-2d \
ros-jazzy-nav2-lifecycle-manager \
ros-jazzy-nav2-map-server \
ros-jazzy-nav2-amcl \
ros-jazzy-ament-lint-auto \
ros-jazzy-ament-lint-common \
ros-jazzy-ament-clang-format \
ros-jazzy-ament-cmake-clang-format \
ros-jazzy-ament-cmake-clang-tidy \
ros-jazzy-ament-cmake-gtest \
ros-jazzy-ament-cmake-pytest \
ros-jazzy-launch-testing-ament-cmake \
python3-colcon-common-extensions \
python3-requests \
nlohmann-json3-dev \
libcpp-httplib-dev \
git \
curl \
&& rm -rf /var/lib/apt/lists/*

# Create workspace and clone ros2_medkit
# TODO: Replace with proper ROS 2 package dependency once ros2_medkit is released
WORKDIR ${COLCON_WS}/src
RUN git clone https://github.com/selfpatch/ros2_medkit.git

# Copy demo package
COPY package.xml CMakeLists.txt ${COLCON_WS}/src/turtlebot3_medkit_demo/
COPY config/ ${COLCON_WS}/src/turtlebot3_medkit_demo/config/
COPY launch/ ${COLCON_WS}/src/turtlebot3_medkit_demo/launch/

# Build ros2_medkit and demo package
WORKDIR ${COLCON_WS}
RUN bash -c "source /opt/ros/jazzy/setup.bash && \
rosdep update && \
rosdep install --from-paths src --ignore-src -r -y && \
colcon build --symlink-install"

# Setup environment
RUN echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc && \
echo "source ${COLCON_WS}/install/setup.bash" >> ~/.bashrc && \
echo "export TURTLEBOT3_MODEL=burger" >> ~/.bashrc && \
echo "export GAZEBO_MODEL_PATH=/opt/ros/jazzy/share/turtlebot3_gazebo/models" >> ~/.bashrc

EXPOSE 8080

CMD ["bash"]
239 changes: 220 additions & 19 deletions demos/turtlebot3_integration/README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,241 @@
# TurtleBot3 Integration Demo
# TurtleBot3 Integration Demo with Nav2 Navigation

This demo shows how to integrate ros2_medkit with TurtleBot3 and Nav2 to provide
modern diagnostics for a mobile robot navigation system.
This demo shows how to integrate ros2_medkit with TurtleBot3 and Nav2 navigation stack
to provide modern diagnostics and control for a mobile robot system via REST API.

## Status

🚧 **Work in Progress**
**Demo Ready** - Full navigation demo with Web UI

## Overview

This demo will demonstrate:
This demo demonstrates:

- Discovering TurtleBot3 nodes through ros2_medkit REST API
- Organizing navigation components into diagnostic areas
- Reading sensor data and navigation state via HTTP
- Monitoring robot health during autonomous navigation
- Launching TurtleBot3 simulation in Gazebo with turtlebot3_world
- Running Nav2 navigation stack (AMCL, planner, controller)
- Running ros2_medkit gateway alongside the robot
- Discovering TurtleBot3 nodes through REST API
- Querying and publishing to ROS2 topics via HTTP
- **NEW:** Controlling the robot via sovd_web_ui

## Prerequisites

- ROS 2 Jazzy (Ubuntu 24.04)
- [ros2_medkit](https://github.com/selfpatch/ros2_medkit)
- TurtleBot3 packages
- Nav2 navigation stack
- Docker and docker-compose
- X11 display server (Linux with GUI, or XQuartz on macOS)
- (Optional) NVIDIA GPU + [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)

## Installation
## Quick Start

*Coming soon*
### 1. Start the ROS2 Backend

## Usage
```bash
cd demos/turtlebot3_integration
./run-demo.sh
```

*Coming soon*
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
4. Launch sovd_web_ui at <http://localhost:3000>

### 2. Access the Web UI

The Web UI is automatically started by docker-compose and available at <http://localhost:3000>.

Connect to the gateway using `http://localhost:8080/api/v1` in the connection dialog.

**Note:** The first build will take longer as it clones and builds sovd_web_ui from GitHub.

### With NVIDIA GPU

For hardware-accelerated Gazebo rendering with NVIDIA GPU:

```bash
./run-demo.sh --nvidia
```

**Requirements:**

- NVIDIA GPU with recent drivers
- [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html) installed

You can also use Docker Compose directly:

```bash
docker compose --profile nvidia up --build
```

## Controlling the Robot

### Via Web UI

1. Connect to the gateway in sovd_web_ui
2. In the "ROS2 Topics" panel on the right, select `/cmd_vel`
3. Enter velocity command JSON:

```json
{"linear": {"x": 0.2}, "angular": {"z": 0.0}}
```

4. Click "Send" - the robot will move!

### Via Command Line

```bash
# Send velocity command (moves robot forward)
curl -X POST http://localhost:8080/api/v1/topics/publish \
-H "Content-Type: application/json" \
-d '{
"topic": "/cmd_vel",
"type": "geometry_msgs/msg/Twist",
"data": {"linear": {"x": 0.2, "y": 0.0, "z": 0.0}, "angular": {"x": 0.0, "y": 0.0, "z": 0.0}}
}'

# Stop the robot
curl -X POST http://localhost:8080/api/v1/topics/publish \
-H "Content-Type: application/json" \
-d '{
"topic": "/cmd_vel",
"type": "geometry_msgs/msg/Twist",
"data": {"linear": {"x": 0.0}, "angular": {"z": 0.0}}
}'
```

### Via ROS2 CLI (inside container)

```bash
# 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
```

## REST API Endpoints

### Discovery

```bash
# Check gateway health
curl http://localhost:8080/api/v1/health

# List discovered areas
curl http://localhost:8080/api/v1/areas

# List all discovered components (nodes)
curl http://localhost:8080/api/v1/components
```

### Topics

```bash
# List all topics
curl http://localhost:8080/api/v1/topics

# Get topic details (URL-encode topic name: / -> %2F)
curl http://localhost:8080/api/v1/topics/%2Fcmd_vel

# Get topic without sample
curl "http://localhost:8080/api/v1/topics/%2Fcmd_vel?sample=false"

# Publish to topic (see examples above)
curl -X POST http://localhost:8080/api/v1/topics/publish ...
```

## What You'll See

*Coming soon*
When TurtleBot3 simulation starts with Nav2, ros2_medkit will discover nodes such as:

- `turtlebot3_node` - Main robot interface
- `robot_state_publisher` - TF tree publisher
- `gazebo` - Simulation engine
- `amcl` - Adaptive Monte Carlo Localization
- `bt_navigator` - Behavior Tree Navigator
- `controller_server` - Path following controller
- `planner_server` - Global path planner
- Various sensor and lifecycle nodes

These appear as **components** in the ros2_medkit REST API, organized into **areas** based on their ROS 2 namespaces.

## Architecture

*Coming soon*
```text
┌─────────────────────────────────────────────────────────────────────┐
│ Docker Container │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Gazebo Simulation │ │
│ │ ┌─────────────┐ ┌──────────────┐ ┌────────┐ ┌───────────┐ │ │
│ │ │ TurtleBot3 │ │ robot_state │ │ LIDAR │ │ Nav2 │ │ │
│ │ │ Node │ │ publisher │ │ sensor │ │ (AMCL, │ │ │
│ │ └──────┬──────┘ └──────┬───────┘ └───┬────┘ │ Planner, │ │ │
│ │ │ │ │ │ Controller│ │ │
│ │ └────────────────┼──────────────┘ └─────┬─────┘ │ │
│ │ ROS 2 Topics ◄────────────────────┘ │ │
│ └──────────────────────────┼────────────────────────────────────┘ │
│ │ │
│ ┌─────────────┴─────────────┐ │
│ │ ros2_medkit Gateway │ │
│ │ (REST Server :8080) │ │
│ └─────────────┬─────────────┘ │
└─────────────────────────────┼────────────────────────────────────────┘
HTTP REST API
┌────────────────────┼────────────────────┐
▼ ▼ ▼
sovd_web_ui curl/browser External tools
(localhost:3000)
```

## File Structure

```text
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
├── config/
│ ├── medkit_params.yaml # ros2_medkit gateway config
│ ├── nav2_params.yaml # Nav2 navigation parameters
│ └── turtlebot3_world.yaml # Map configuration
└── launch/
└── demo.launch.py # ROS 2 launch file
```

## Manual Setup (Alternative)

If you prefer not to use Docker:

1. Install ROS 2 Jazzy on Ubuntu 24.04
2. Install TurtleBot3: `sudo apt install ros-jazzy-turtlebot3-gazebo`
3. Install Nav2: `sudo apt install ros-jazzy-nav2-bringup`
4. Build [ros2_medkit](https://github.com/selfpatch/ros2_medkit) from source
5. Set environment:

```bash
export TURTLEBOT3_MODEL=burger
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:/opt/ros/jazzy/share/turtlebot3_gazebo/models
```

6. Run: `ros2 launch launch/demo.launch.py`

## Troubleshooting

### Gazebo window doesn't appear

- Ensure X11 forwarding is set up: `xhost +local:docker`
- Check DISPLAY environment variable

### Nav2 doesn't start properly

- Wait for AMCL to localize (give an initial pose in RViz or via CLI)
- Check lifecycle states with `ros2 lifecycle list`

### Robot doesn't move with /cmd_vel

- Make sure Nav2's velocity smoother isn't overriding commands
- Check if collision monitor is blocking movement
11 changes: 11 additions & 0 deletions demos/turtlebot3_integration/config/medkit_params.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ros2_medkit gateway configuration for TurtleBot3 demo
ros2_medkit_gateway:
ros__parameters:
server.host: "0.0.0.0"
server.port: 8080
refresh_interval_ms: 2000
cors.allowed_origins: ["*"]
cors.allowed_methods: ["GET", "PUT", "POST", "OPTIONS"]
cors.allowed_headers: ["Content-Type", "Accept"]
cors.allow_credentials: false
cors.max_age_seconds: 86400
Loading