From 4b713f90ae19ddf32d45e55ca20adde6f3de716e Mon Sep 17 00:00:00 2001 From: Bharat Jain Date: Tue, 7 Oct 2025 21:47:50 +0530 Subject: [PATCH 01/11] fix: Add cross-platform X11 forwarding support for Docker turtlesim - Fix macOS XQuartz display issues with dynamic DOCKER_DISPLAY variable - Add platform-specific setup instructions for macOS, Linux, Windows - Remove hard-coded IP addresses and display numbers - Add comprehensive troubleshooting for common X11 connection errors Resolves Docker GUI display issues on macOS and improves cross-platform compatibility. --- examples/5_docker_turtlesim/README.md | 162 +++++++++++++++--- .../5_docker_turtlesim/docker-compose.yml | 11 +- 2 files changed, 146 insertions(+), 27 deletions(-) diff --git a/examples/5_docker_turtlesim/README.md b/examples/5_docker_turtlesim/README.md index 06e0ad1..cc0a40b 100644 --- a/examples/5_docker_turtlesim/README.md +++ b/examples/5_docker_turtlesim/README.md @@ -5,15 +5,27 @@ Turtlesim is a lightweight simulator for learning ROS / ROS 2. It illustrates wh ## Prerequisites -✅ **Note:** This tutorial is designed to be run on linux and has been tested with Ubuntu as well as [Ubuntu running on WSL](https://apps.microsoft.com/detail/9pn20msr04dw?hl=en-US&gl=US). Being a dockerized container, it is likely to work on other OS versions as well with the correct X11 forwarding settings. +✅ **Cross-Platform Support:** This tutorial works on Linux, macOS, and Windows with proper X11/display forwarding setup. Each platform has specific requirements detailed below. Before starting this tutorial, make sure you have the following installed: +### All Platforms - **Docker**: [Install Docker](https://docs.docker.com/get-docker/) - **Docker Compose**: Usually comes with Docker Desktop, or install separately -- **X Server** (for Windows): Install [X410](https://x410.dev/) or another X Server from Microsoft Store -- **X11 forwarding** (for Linux): `sudo apt-get install x11-apps` -- **XQuartz** (for macOS): Install from [XQuartz website](https://www.xquartz.org/) + +### Platform-Specific Requirements + +#### macOS +- **XQuartz**: Install from [XQuartz website](https://www.xquartz.org/) +- **Important**: XQuartz setup can be complex - see [macOS Setup](#macos-setup) section below for detailed instructions + +#### Linux +- **X11 forwarding**: `sudo apt-get install x11-apps` +- Usually works out of the box with minimal setup + +#### Windows +- **X Server**: Install [X410](https://x410.dev/), [VcXsrv](https://sourceforge.net/projects/vcxsrv/), or another X Server from Microsoft Store +- **WSL recommended**: Works best with Windows Subsystem for Linux **Note:** If your OS is Windows, take a look at the following:
@@ -38,23 +50,43 @@ docker compose build --no-cache turtlesim ### 2. Start the Container -Launch the turtlesim container +**The startup process varies by platform. Choose your OS:** +#### MacOS ```bash +# 1. Start XQuartz +open -a XQuartz + +# 2. Set up X11 permissions (wait for XQuartz to start) +export DISPLAY=:1 && xhost + + +# 3. Set up Docker display variable +export DOCKER_DISPLAY="$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}'):1" + +# 4. Launch container docker compose up ``` -If your OS is Windows and you want to launch docker in PowerShell, you first need to set the DISPLAY: +#### Linux ```bash -$env:DISPLAY="host.docker.internal:0.0" -``` +# 1. Allow X11 forwarding +xhost +local:docker -If your OS is Ubuntu/WSL and the docker doesn't run successfully, consider: +# 2. Launch container +DOCKER_DISPLAY=$DISPLAY docker compose up +``` +#### Windows (PowerShell) ```bash -dos2unix docker/scripts/launch_turtlesim.sh +# 1. Set DISPLAY for Windows Docker Desktop +$env:DOCKER_DISPLAY="host.docker.internal:0.0" + +# 2. Launch container +docker compose up ``` + + The container will automatically start both turtlesim and rosbridge websocket server. You should see: - A turtlesim window appear with a turtle @@ -92,35 +124,119 @@ Follow the [installation guide](../../docs/installation.md) for full setup instr Since it is running on the same machine, you can tell the LLM to connect to the robot on localhost. -## Troubleshooting +## macOS Setup -### Display Issues (Linux) +macOS requires special X11 forwarding setup. Follow these steps carefully: -If you encounter display issues on Linux, run: +### Step 1: Install XQuartz +Download and install from [XQuartz website](https://www.xquartz.org/) + +### Step 2: Configure XQuartz +1. **Start XQuartz**: `open -a XQuartz` +2. **Wait for it to fully load** (you'll see an xterm window) +### Step 3: Detect Your Setup ```bash -xhost +local:docker +# Check if XQuartz is running and which display it's using +ps aux | grep -i xquartz + +# You should see something like: +# /opt/X11/bin/Xquartz :1 -listen tcp ... +# The `:1` or `:0` is your display number +``` + +### Step 4: Get Your Machine IP +```bash +# Get your machine's IP address +ifconfig en0 | grep inet | awk '$1=="inet" {print $2}' +# Example output: 10.1.56.72 +``` + +### Step 5: Set Up Environment +```bash +# Set DISPLAY for your Mac (use the display number from Step 3) +export DISPLAY=:1 # or :0 depending on what you found + +# Allow X11 connections +xhost + + +# Set DISPLAY for Docker (use your IP from Step 4 + display number) +export DOCKER_DISPLAY="10.1.56.72:1" # Replace with your actual IP ``` -### Display Issues (macOS) +## Troubleshooting + +### macOS Display Issues + +**Problem**: `qt.qpa.xcb: could not connect to display` + +**Solutions**: -For macOS users, make sure XQuartz is running and configured: +1. **Check XQuartz is running**: + ```bash + ps aux | grep X11 + ``` +2. **Verify display number**: + ```bash + # Look for :0 or :1 in the Xquartz process + ps aux | grep Xquartz | grep -o ":[0-9]" + ``` + +3. **Check your IP address**: + ```bash + ifconfig en0 | grep inet + ``` + +4. **Set correct DOCKER_DISPLAY**: + ```bash + export DOCKER_DISPLAY="YOUR_IP:DISPLAY_NUMBER" + # Example: export DOCKER_DISPLAY="10.1.56.72:1" + ``` + +5. **Allow X11 connections**: + ```bash + export DISPLAY=:1 # Use your display number + xhost + + ``` + +**Problem**: `xhost: unable to open display ":0"` + +**Solution**: XQuartz might be using `:1` instead of `:0`: ```bash -# Start XQuartz -open -a XQuartz +export DISPLAY=:1 +xhost + +``` + +### Linux Display Issues + +If you encounter display issues on Linux, run: -# Allow connections from localhost -xhost +localhost +```bash +xhost +local:docker ``` -### Display Issues (Windows/PowerShell) +### Windows Display Issues + For Windows users, make sure you install an X Server (X410) and set the DISPLAY: ```bash -$env:DISPLAY="host.docker.internal:0.0" +$env:DOCKER_DISPLAY="host.docker.internal:0.0" ``` +### General Issues + +**Problem**: Container starts but no window appears + +**Solutions**: +1. Check if the window is hidden behind other windows +2. Look in Mission Control (macOS) or Alt+Tab (Windows/Linux) +3. Verify your DOCKER_DISPLAY is set correctly for your platform + +**Problem**: `libGL error: No matching fbConfigs or visuals found` + +**Solution**: This is just a warning and doesn't prevent the GUI from working. The turtlesim window should still appear. + ### Container Networking If you need to access the container from outside, the container uses host networking mode, so ROS2 topics should be accessible on localhost. @@ -202,4 +318,4 @@ Now that you have turtlesim running, you can: 3. **Explore other examples in this repository** -This example provides a foundation for understanding how the MCP server can interact with ROS2 systems, from simple simulators like turtlesim to complex robotic platforms. +This example provides a foundation for understanding how the MCP server can interact with ROS2 systems, from simple simulators like turtlesim to complex robotic platforms. \ No newline at end of file diff --git a/examples/5_docker_turtlesim/docker-compose.yml b/examples/5_docker_turtlesim/docker-compose.yml index 406fb8c..5114f2e 100644 --- a/examples/5_docker_turtlesim/docker-compose.yml +++ b/examples/5_docker_turtlesim/docker-compose.yml @@ -5,12 +5,15 @@ services: dockerfile: Dockerfile.turtlesim container_name: ros2-turtlesim environment: - - DISPLAY=${DISPLAY} + - DISPLAY=${DOCKER_DISPLAY} - ROS_DISTRO=humble + - QT_X11_NO_MITSHM=1 volumes: - - /tmp/.X11-unix:/tmp/.X11-unix:rw - ./docker/scripts:/ros2_ws/scripts:ro - network_mode: host + # Linux X11 socket (only works on Linux) + - /tmp/.X11-unix:/tmp/.X11-unix:rw + ports: + - "9090:9090" stdin_open: true tty: true - command: bash -c "/ros2_ws/scripts/launch_turtlesim.sh" + command: ["/bin/bash", "/ros2_ws/scripts/launch_turtlesim.sh"] From 8b41691ef43f91cd2abdfc7b319b4504bded476f Mon Sep 17 00:00:00 2001 From: Bharat Jain Date: Wed, 8 Oct 2025 11:47:25 +0530 Subject: [PATCH 02/11] Fixed the error in building uv venv --- .../docker/scripts/launch_headless.sh | 64 +++++++++++++ .../scripts/launch_turtlesim_headless.sh | 0 examples/5_docker_turtlesim/start_headless.sh | 0 examples/5_docker_turtlesim/start_linux.sh | 0 examples/5_docker_turtlesim/start_macos.sh | 92 +++++++++++++++++++ examples/5_docker_turtlesim/start_windows.sh | 0 mcp_json.txt | 22 +++++ 7 files changed, 178 insertions(+) create mode 100644 examples/5_docker_turtlesim/docker/scripts/launch_headless.sh create mode 100644 examples/5_docker_turtlesim/docker/scripts/launch_turtlesim_headless.sh create mode 100644 examples/5_docker_turtlesim/start_headless.sh create mode 100644 examples/5_docker_turtlesim/start_linux.sh create mode 100644 examples/5_docker_turtlesim/start_macos.sh create mode 100644 examples/5_docker_turtlesim/start_windows.sh create mode 100644 mcp_json.txt diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_headless.sh b/examples/5_docker_turtlesim/docker/scripts/launch_headless.sh new file mode 100644 index 0000000..8df5caf --- /dev/null +++ b/examples/5_docker_turtlesim/docker/scripts/launch_headless.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +set -eo pipefail + +# Source ROS2 environment +source /opt/ros/humble/setup.bash + +echo "Starting ROS Bridge WebSocket server (headless mode)..." +echo "WebSocket server will be available at: ws://localhost:9090" +echo "This version runs without GUI for cross-platform compatibility" + +# Launch rosbridge websocket server in the background +ros2 launch rosbridge_server rosbridge_websocket_launch.xml & + +# Wait a moment for rosbridge to start +sleep 3 + +echo "Starting Turtlesim in headless mode..." +echo "Turtlesim will run without GUI display" +echo "You can still control it programmatically via ROS topics" + +# Set Qt to use offscreen platform (no GUI) +export QT_QPA_PLATFORM=offscreen + +# Launch turtlesim in headless mode +ros2 run turtlesim turtlesim_node & + +sleep 2 + +echo "" +echo "🎉 Services started successfully!" +echo "📡 ROS Bridge WebSocket: ws://localhost:9090" +echo "🐢 Turtlesim topics available via ROS2" +echo "🛑 Use Ctrl+C to stop" +echo "" +echo "Available topics:" +echo " - /turtle1/pose (turtle position)" +echo " - /turtle1/cmd_vel (turtle movement commands)" +echo "" + +# Trap signals to clean up processes +cleanup() { + echo "" + echo "🛑 Stopping turtlesim and rosbridge..." + pkill -f turtlesim_node || true + pkill -f rosbridge_server || true + wait + echo "✅ Cleanup complete" +} + +trap cleanup SIGINT SIGTERM + +# Keep container running and show status +while true; do + sleep 5 + # Check if processes are still running + if ! pgrep -f turtlesim_node > /dev/null; then + echo "❌ Turtlesim process died, restarting..." + ros2 run turtlesim turtlesim_node & + fi + if ! pgrep -f rosbridge_server > /dev/null; then + echo "❌ ROS Bridge process died, restarting..." + ros2 launch rosbridge_server rosbridge_websocket_launch.xml & + fi +done diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_turtlesim_headless.sh b/examples/5_docker_turtlesim/docker/scripts/launch_turtlesim_headless.sh new file mode 100644 index 0000000..e69de29 diff --git a/examples/5_docker_turtlesim/start_headless.sh b/examples/5_docker_turtlesim/start_headless.sh new file mode 100644 index 0000000..e69de29 diff --git a/examples/5_docker_turtlesim/start_linux.sh b/examples/5_docker_turtlesim/start_linux.sh new file mode 100644 index 0000000..e69de29 diff --git a/examples/5_docker_turtlesim/start_macos.sh b/examples/5_docker_turtlesim/start_macos.sh new file mode 100644 index 0000000..04d3dba --- /dev/null +++ b/examples/5_docker_turtlesim/start_macos.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# Simple macOS startup script for turtlesim GUI +# This script handles all the X11 forwarding complexity automatically + +set -e + +echo "🐢 Starting Turtlesim on macOS with GUI" +echo "========================================" + +# Function to detect display number +detect_display() { + if pgrep -f "Xquartz :1" > /dev/null; then + echo "1" + elif pgrep -f "Xquartz :0" > /dev/null; then + echo "0" + else + echo "0" # Default fallback + fi +} + +# Function to get machine IP +get_machine_ip() { + # Try en0 first (most common) + local ip=$(ifconfig en0 2>/dev/null | grep 'inet ' | awk '{print $2}' | head -n1) + + # If en0 doesn't work, try other interfaces + if [[ -z "$ip" ]]; then + ip=$(ifconfig 2>/dev/null | grep 'inet ' | grep -v '127.0.0.1' | awk '{print $2}' | head -n1) + fi + + echo "$ip" +} + +# Step 1: Start XQuartz if not running +if ! pgrep -x "X11.bin" > /dev/null; then + echo "📱 Starting XQuartz..." + open -a XQuartz + + # Wait for XQuartz to start (up to 10 seconds) + for i in {1..10}; do + if pgrep -x "X11.bin" > /dev/null; then + echo "✅ XQuartz started" + break + fi + echo " Waiting for XQuartz... ($i/10)" + sleep 1 + done + + if ! pgrep -x "X11.bin" > /dev/null; then + echo "❌ XQuartz failed to start. Please start it manually." + exit 1 + fi +else + echo "✅ XQuartz already running" +fi + +# Step 2: Detect display number and machine IP +DISPLAY_NUM=$(detect_display) +MACHINE_IP=$(get_machine_ip) + +if [[ -z "$MACHINE_IP" ]]; then + echo "❌ Could not detect machine IP address" + echo "💡 Please run: ifconfig en0 | grep inet" + exit 1 +fi + +echo "🖥️ Display detected: :$DISPLAY_NUM" +echo "🌐 Machine IP: $MACHINE_IP" + +# Step 3: Set up X11 permissions +export DISPLAY=:$DISPLAY_NUM +if command -v xhost >/dev/null 2>&1; then + echo "🔓 Allowing X11 connections..." + xhost + >/dev/null 2>&1 || echo "⚠️ xhost command failed, but continuing..." +else + echo "⚠️ xhost not found - X11 forwarding may not work" +fi + +# Step 4: Export DISPLAY for Docker +export DISPLAY="$MACHINE_IP:$DISPLAY_NUM" +echo "🐳 Docker will use DISPLAY=$DISPLAY" + +# Step 5: Start the container +echo "" +echo "🚀 Starting Turtlesim container..." +echo " If successful, you should see a window with a turtle!" +echo "" + +docker compose up turtlesim + +echo "" +echo "🎉 Done! The turtle window should be visible on your screen." diff --git a/examples/5_docker_turtlesim/start_windows.sh b/examples/5_docker_turtlesim/start_windows.sh new file mode 100644 index 0000000..e69de29 diff --git a/mcp_json.txt b/mcp_json.txt new file mode 100644 index 0000000..b882d8b --- /dev/null +++ b/mcp_json.txt @@ -0,0 +1,22 @@ +{ + "mcpServers": { + "filesystem": { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-filesystem", + "/Users/bharatjain/Desktop", + "/Users/bharatjain/Downloads" + ] + }, + "ros-mcp-server": { + "command": "/Users/bharatjain/.local/bin/uv", + "args": [ + "--directory", + "/Users/bharatjain/Desktop/ros-mcp-server", + "run", + "server.py" + ] + } + } +} From 35b4d05b8ef902cddc2489fed4ba52d90d47c4f3 Mon Sep 17 00:00:00 2001 From: Bharat Jain Date: Sun, 2 Nov 2025 16:08:14 +0530 Subject: [PATCH 03/11] feat: Enhance turtlesim launch scripts for cross-platform compatibility and X11 support --- examples/5_docker_turtlesim/README.md | 47 +++++++------- .../5_docker_turtlesim/docker-compose.yml | 2 +- .../docker/scripts/launch_headless.sh | 64 ------------------- .../docker/scripts/launch_linux.sh | 42 ++++++++++++ .../scripts/launch_macos.sh} | 2 +- .../scripts/launch_turtlesim_headless.sh | 0 .../docker/scripts/launch_windows.sh | 51 +++++++++++++++ examples/5_docker_turtlesim/launch.sh | 30 +++++++++ examples/5_docker_turtlesim/start_headless.sh | 0 examples/5_docker_turtlesim/start_linux.sh | 0 examples/5_docker_turtlesim/start_windows.sh | 0 11 files changed, 147 insertions(+), 91 deletions(-) delete mode 100644 examples/5_docker_turtlesim/docker/scripts/launch_headless.sh create mode 100755 examples/5_docker_turtlesim/docker/scripts/launch_linux.sh rename examples/5_docker_turtlesim/{start_macos.sh => docker/scripts/launch_macos.sh} (99%) mode change 100644 => 100755 delete mode 100644 examples/5_docker_turtlesim/docker/scripts/launch_turtlesim_headless.sh create mode 100755 examples/5_docker_turtlesim/docker/scripts/launch_windows.sh create mode 100755 examples/5_docker_turtlesim/launch.sh delete mode 100644 examples/5_docker_turtlesim/start_headless.sh delete mode 100644 examples/5_docker_turtlesim/start_linux.sh delete mode 100644 examples/5_docker_turtlesim/start_windows.sh diff --git a/examples/5_docker_turtlesim/README.md b/examples/5_docker_turtlesim/README.md index cc0a40b..9a88508 100644 --- a/examples/5_docker_turtlesim/README.md +++ b/examples/5_docker_turtlesim/README.md @@ -1,7 +1,7 @@ # Example - TurtleSim in Docker -For users who want to test the MCP server without needing to install ROS, this is an example that provides a dockerized ROS2 container preinstalled with the simplest possible 'robot' in the ROS ecosystem - TurtleSim. + For users who want to test the MCP server without needing to install ROS, this is an example that provides a dockerized ROS2 container preinstalled with the simplest possible 'robot' in the ROS ecosystem - TurtleSim. -Turtlesim is a lightweight simulator for learning ROS / ROS 2. It illustrates what ROS does at the most basic level to give you an idea of what you will do with a real robot or a robot simulation later on. + Turtlesim is a lightweight simulator for learning ROS / ROS 2. It illustrates what ROS does at the most basic level to give you an idea of what you will do with a real robot or a robot simulation later on. ## Prerequisites @@ -48,41 +48,38 @@ cd examples/5_docker_turtlesim docker compose build --no-cache turtlesim ``` -### 2. Start the Container +### 2. Launch Turtlesim -**The startup process varies by platform. Choose your OS:** +#### Automatic Setup (Recommended) + +The easiest way to launch turtlesim with proper X11 setup: -#### MacOS ```bash -# 1. Start XQuartz -open -a XQuartz +./launch.sh +``` -# 2. Set up X11 permissions (wait for XQuartz to start) -export DISPLAY=:1 && xhost + +This script automatically detects your OS and handles all platform-specific X11 configuration. It will: +- **macOS**: Start XQuartz, detect display, configure IP-based forwarding +- **Linux**: Set up X11 permissions with `xhost +local:docker` +- **Windows**: Configure X server connection via `host.docker.internal` -# 3. Set up Docker display variable -export DOCKER_DISPLAY="$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}'):1" +#### Manual Setup (Advanced) -# 4. Launch container -docker compose up -``` +If you prefer manual control or the automatic script doesn't work: -#### Linux +**macOS:** ```bash -# 1. Allow X11 forwarding -xhost +local:docker - -# 2. Launch container -DOCKER_DISPLAY=$DISPLAY docker compose up +./docker/scripts/launch_macos.sh ``` -#### Windows (PowerShell) +**Linux:** ```bash -# 1. Set DISPLAY for Windows Docker Desktop -$env:DOCKER_DISPLAY="host.docker.internal:0.0" +./docker/scripts/launch_linux.sh +``` -# 2. Launch container -docker compose up +**Windows (WSL/Git Bash):** +```bash +./docker/scripts/launch_windows.sh ``` diff --git a/examples/5_docker_turtlesim/docker-compose.yml b/examples/5_docker_turtlesim/docker-compose.yml index 5114f2e..880a68d 100644 --- a/examples/5_docker_turtlesim/docker-compose.yml +++ b/examples/5_docker_turtlesim/docker-compose.yml @@ -5,7 +5,7 @@ services: dockerfile: Dockerfile.turtlesim container_name: ros2-turtlesim environment: - - DISPLAY=${DOCKER_DISPLAY} + - DISPLAY=${DISPLAY} - ROS_DISTRO=humble - QT_X11_NO_MITSHM=1 volumes: diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_headless.sh b/examples/5_docker_turtlesim/docker/scripts/launch_headless.sh deleted file mode 100644 index 8df5caf..0000000 --- a/examples/5_docker_turtlesim/docker/scripts/launch_headless.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env bash -set -eo pipefail - -# Source ROS2 environment -source /opt/ros/humble/setup.bash - -echo "Starting ROS Bridge WebSocket server (headless mode)..." -echo "WebSocket server will be available at: ws://localhost:9090" -echo "This version runs without GUI for cross-platform compatibility" - -# Launch rosbridge websocket server in the background -ros2 launch rosbridge_server rosbridge_websocket_launch.xml & - -# Wait a moment for rosbridge to start -sleep 3 - -echo "Starting Turtlesim in headless mode..." -echo "Turtlesim will run without GUI display" -echo "You can still control it programmatically via ROS topics" - -# Set Qt to use offscreen platform (no GUI) -export QT_QPA_PLATFORM=offscreen - -# Launch turtlesim in headless mode -ros2 run turtlesim turtlesim_node & - -sleep 2 - -echo "" -echo "🎉 Services started successfully!" -echo "📡 ROS Bridge WebSocket: ws://localhost:9090" -echo "🐢 Turtlesim topics available via ROS2" -echo "🛑 Use Ctrl+C to stop" -echo "" -echo "Available topics:" -echo " - /turtle1/pose (turtle position)" -echo " - /turtle1/cmd_vel (turtle movement commands)" -echo "" - -# Trap signals to clean up processes -cleanup() { - echo "" - echo "🛑 Stopping turtlesim and rosbridge..." - pkill -f turtlesim_node || true - pkill -f rosbridge_server || true - wait - echo "✅ Cleanup complete" -} - -trap cleanup SIGINT SIGTERM - -# Keep container running and show status -while true; do - sleep 5 - # Check if processes are still running - if ! pgrep -f turtlesim_node > /dev/null; then - echo "❌ Turtlesim process died, restarting..." - ros2 run turtlesim turtlesim_node & - fi - if ! pgrep -f rosbridge_server > /dev/null; then - echo "❌ ROS Bridge process died, restarting..." - ros2 launch rosbridge_server rosbridge_websocket_launch.xml & - fi -done diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh b/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh new file mode 100755 index 0000000..cf3c534 --- /dev/null +++ b/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Linux startup script for turtlesim GUI + +set -e + +echo "🐢 Starting Turtlesim on Linux with GUI" +echo "========================================" + +# Step 1: Check if X11 is available +if [[ -z "$DISPLAY" ]]; then + echo "❌ DISPLAY variable not set" + echo "💡 X11 forwarding is required. Are you running in a GUI environment?" + exit 1 +fi + +echo "🖥️ Using DISPLAY: $DISPLAY" + +# Step 2: Allow Docker to access X11 +if command -v xhost >/dev/null 2>&1; then + echo "🔓 Allowing Docker X11 access..." + xhost +local:docker >/dev/null 2>&1 || { + echo "⚠️ xhost command failed, trying without sudo..." + xhost + >/dev/null 2>&1 || echo "⚠️ Could not run xhost, X11 forwarding may not work" + } +else + echo "⚠️ xhost not found. Install with: sudo apt-get install x11-xserver-utils" + echo " Continuing anyway, but GUI may not work..." +fi + +# Step 3: Export DISPLAY for Docker +echo "🐳 Docker will use DISPLAY=$DISPLAY" + +# Step 4: Start the container +echo "" +echo "🚀 Starting Turtlesim container..." +echo " If successful, you should see a window with a turtle!" +echo "" + +docker compose up turtlesim + +echo "" +echo "🎉 Done! The turtle window should be visible on your screen." diff --git a/examples/5_docker_turtlesim/start_macos.sh b/examples/5_docker_turtlesim/docker/scripts/launch_macos.sh old mode 100644 new mode 100755 similarity index 99% rename from examples/5_docker_turtlesim/start_macos.sh rename to examples/5_docker_turtlesim/docker/scripts/launch_macos.sh index 04d3dba..15c1e25 --- a/examples/5_docker_turtlesim/start_macos.sh +++ b/examples/5_docker_turtlesim/docker/scripts/launch_macos.sh @@ -89,4 +89,4 @@ echo "" docker compose up turtlesim echo "" -echo "🎉 Done! The turtle window should be visible on your screen." +echo "🎉 Done! The turtle window should be visible on your screen." \ No newline at end of file diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_turtlesim_headless.sh b/examples/5_docker_turtlesim/docker/scripts/launch_turtlesim_headless.sh deleted file mode 100644 index e69de29..0000000 diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_windows.sh b/examples/5_docker_turtlesim/docker/scripts/launch_windows.sh new file mode 100755 index 0000000..d5dcb54 --- /dev/null +++ b/examples/5_docker_turtlesim/docker/scripts/launch_windows.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# Windows (WSL/Git Bash) startup script for turtlesim GUI +# Requires an X server like VcXsrv, X410, or Xming running on Windows + +set -e + +echo "🐢 Starting Turtlesim on Windows with GUI" +echo "==========================================" + +# Step 1: Check if running in WSL or Git Bash +if grep -qi microsoft /proc/version 2>/dev/null; then + PLATFORM="WSL" +elif uname -s | grep -qi "MINGW\|MSYS\|CYGWIN"; then + PLATFORM="Git Bash/MSYS" +else + PLATFORM="Unknown" +fi + +echo "🖥️ Detected platform: $PLATFORM" + +# Step 2: Check if X server is running on Windows +echo "🔍 Checking for X server on Windows..." +echo " Make sure VcXsrv, X410, or another X server is running!" +echo " If not installed, get VcXsrv from: https://sourceforge.net/projects/vcxsrv/" + +# Step 3: Set DISPLAY for Docker +# Docker Desktop on Windows uses host.docker.internal to reach Windows host +export DISPLAY="host.docker.internal:0.0" +echo "🐳 Docker will use DISPLAY=$DISPLAY" + +# Step 4: Warn about common issues +cat << 'TIPS' + +📝 Important Notes for Windows: + - Start your X server (VcXsrv/X410) BEFORE running this script + - In VcXsrv: disable "Native opengl" and enable "Disable access control" + - If GUI doesn't appear, check Windows Firewall settings + - Docker Desktop must be running + +TIPS + +# Step 5: Start the container +echo "" +echo "🚀 Starting Turtlesim container..." +echo " If successful, you should see a window with a turtle!" +echo "" + +docker compose up turtlesim + +echo "" +echo "🎉 Done! The turtle window should appear in your X server." diff --git a/examples/5_docker_turtlesim/launch.sh b/examples/5_docker_turtlesim/launch.sh new file mode 100755 index 0000000..e16ba32 --- /dev/null +++ b/examples/5_docker_turtlesim/launch.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Unified launcher for turtlesim - auto-detects OS and runs appropriate script + +set -e + +# Detect operating system +OS_TYPE=$(uname -s) + +case "$OS_TYPE" in + Darwin*) + echo "🍎 Detected macOS - launching with XQuartz support..." + ./docker/scripts/launch_macos.sh + ;; + Linux*) + echo "🐧 Detected Linux - launching with X11 support..." + ./docker/scripts/launch_linux.sh + ;; + MINGW*|MSYS*|CYGWIN*) + echo "🪟 Detected Windows - launching with X server support..." + ./docker/scripts/launch_windows.sh + ;; + *) + echo "❌ Unsupported OS: $OS_TYPE" + echo " Please run the appropriate script manually:" + echo " - macOS: ./docker/scripts/launch_macos.sh" + echo " - Linux: ./docker/scripts/launch_linux.sh" + echo " - Windows: ./docker/scripts/launch_windows.sh" + exit 1 + ;; +esac diff --git a/examples/5_docker_turtlesim/start_headless.sh b/examples/5_docker_turtlesim/start_headless.sh deleted file mode 100644 index e69de29..0000000 diff --git a/examples/5_docker_turtlesim/start_linux.sh b/examples/5_docker_turtlesim/start_linux.sh deleted file mode 100644 index e69de29..0000000 diff --git a/examples/5_docker_turtlesim/start_windows.sh b/examples/5_docker_turtlesim/start_windows.sh deleted file mode 100644 index e69de29..0000000 From 679e2e0f89a1f429d1649185823b17d3c7ed2e55 Mon Sep 17 00:00:00 2001 From: Bharat Jain Date: Sun, 2 Nov 2025 16:20:52 +0530 Subject: [PATCH 04/11] Added CI test --- .github/workflows/test-docker-turtlesim.yml | 131 ++++++++++++++++++ .../docker/scripts/launch_linux.sh | 22 +-- .../docker/scripts/launch_macos.sh | 30 ++-- .../docker/scripts/launch_windows.sh | 14 +- examples/5_docker_turtlesim/launch.sh | 8 +- 5 files changed, 168 insertions(+), 37 deletions(-) create mode 100644 .github/workflows/test-docker-turtlesim.yml diff --git a/.github/workflows/test-docker-turtlesim.yml b/.github/workflows/test-docker-turtlesim.yml new file mode 100644 index 0000000..f6e6b9e --- /dev/null +++ b/.github/workflows/test-docker-turtlesim.yml @@ -0,0 +1,131 @@ +name: Test Docker Turtlesim Launch + +on: + push: + branches: [ develop, main ] + paths: + - 'examples/5_docker_turtlesim/**' + - '.github/workflows/test-docker-turtlesim.yml' + pull_request: + branches: [ develop, main ] + paths: + - 'examples/5_docker_turtlesim/**' + +jobs: + test-docker-build: + name: Test Docker Build on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-13] + + defaults: + run: + working-directory: examples/5_docker_turtlesim + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker on macOS + if: runner.os == 'macOS' + run: | + brew install docker docker-compose colima + colima start --memory 4 --cpu 2 + + - name: Build Docker image + run: docker compose build turtlesim + timeout-minutes: 15 + + - name: Test container can start (headless) + run: | + # Set headless display for testing + export DISPLAY=:99 + export QT_QPA_PLATFORM=offscreen + + # Start container in detached mode + timeout 60 docker compose up -d turtlesim || echo "Container start timeout" + + # Wait for services to initialize + sleep 15 + + # Check if container is running + docker ps -a + + # Check container logs for errors + docker compose logs turtlesim + + - name: Test ROS Bridge WebSocket + run: | + # Check if rosbridge websocket server started + docker compose logs turtlesim | grep -i "rosbridge" || echo "Rosbridge log check" + + # Try to connect to port 9090 (may not work without proper setup) + timeout 10 bash -c 'until curl -s http://localhost:9090 2>/dev/null; do sleep 1; done' || echo "Rosbridge connection test skipped in CI" + + - name: Cleanup + if: always() + run: | + docker compose down -v || true + if [ "${{ runner.os }}" == "macOS" ]; then + colima stop || true + fi + + test-launch-scripts: + name: Validate Launch Scripts + runs-on: ubuntu-latest + + defaults: + run: + working-directory: examples/5_docker_turtlesim + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install shellcheck + run: sudo apt-get update && sudo apt-get install -y shellcheck + + - name: Make scripts executable + run: | + chmod +x launch.sh + chmod +x docker/scripts/*.sh + + - name: Test script syntax + run: | + bash -n launch.sh + bash -n docker/scripts/launch_linux.sh + bash -n docker/scripts/launch_macos.sh + bash -n docker/scripts/launch_windows.sh + echo "All scripts have valid syntax" + + - name: Run shellcheck + run: | + shellcheck launch.sh || echo "Shellcheck warnings in launch.sh" + shellcheck docker/scripts/launch_linux.sh || echo "Shellcheck warnings in launch_linux.sh" + shellcheck docker/scripts/launch_macos.sh || echo "Shellcheck warnings in launch_macos.sh" + shellcheck docker/scripts/launch_windows.sh || echo "Shellcheck warnings in launch_windows.sh" + + - name: Verify platform scripts exist + run: | + test -f docker/scripts/launch_linux.sh || exit 1 + test -f docker/scripts/launch_macos.sh || exit 1 + test -f docker/scripts/launch_windows.sh || exit 1 + echo "All platform-specific scripts found" + + - name: Verify launch.sh references platform scripts + run: | + grep -q "docker/scripts/launch_macos.sh" launch.sh || exit 1 + grep -q "docker/scripts/launch_linux.sh" launch.sh || exit 1 + grep -q "docker/scripts/launch_windows.sh" launch.sh || exit 1 + echo "launch.sh correctly references all platform scripts" + + - name: Test OS detection logic + run: | + # Test that the script can identify OS types + grep -q "Darwin\*)" launch.sh || exit 1 + grep -q "Linux\*)" launch.sh || exit 1 + grep -q "MINGW\*|MSYS\*|CYGWIN\*)" launch.sh || exit 1 + echo "OS detection logic verified" + diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh b/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh index cf3c534..8ccf6d3 100755 --- a/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh +++ b/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh @@ -3,40 +3,40 @@ set -e -echo "🐢 Starting Turtlesim on Linux with GUI" +echo "Starting Turtlesim on Linux with GUI" echo "========================================" # Step 1: Check if X11 is available if [[ -z "$DISPLAY" ]]; then - echo "❌ DISPLAY variable not set" - echo "💡 X11 forwarding is required. Are you running in a GUI environment?" + echo "ERROR: DISPLAY variable not set" + echo "X11 forwarding is required. Are you running in a GUI environment?" exit 1 fi -echo "🖥️ Using DISPLAY: $DISPLAY" +echo "Using DISPLAY: $DISPLAY" # Step 2: Allow Docker to access X11 if command -v xhost >/dev/null 2>&1; then - echo "🔓 Allowing Docker X11 access..." + echo "Allowing Docker X11 access..." xhost +local:docker >/dev/null 2>&1 || { - echo "⚠️ xhost command failed, trying without sudo..." - xhost + >/dev/null 2>&1 || echo "⚠️ Could not run xhost, X11 forwarding may not work" + echo "WARNING: xhost command failed, trying without sudo..." + xhost + >/dev/null 2>&1 || echo "WARNING: Could not run xhost, X11 forwarding may not work" } else - echo "⚠️ xhost not found. Install with: sudo apt-get install x11-xserver-utils" + echo "WARNING: xhost not found. Install with: sudo apt-get install x11-xserver-utils" echo " Continuing anyway, but GUI may not work..." fi # Step 3: Export DISPLAY for Docker -echo "🐳 Docker will use DISPLAY=$DISPLAY" +echo "Docker will use DISPLAY=$DISPLAY" # Step 4: Start the container echo "" -echo "🚀 Starting Turtlesim container..." +echo "Starting Turtlesim container..." echo " If successful, you should see a window with a turtle!" echo "" docker compose up turtlesim echo "" -echo "🎉 Done! The turtle window should be visible on your screen." +echo "Done! The turtle window should be visible on your screen." diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_macos.sh b/examples/5_docker_turtlesim/docker/scripts/launch_macos.sh index 15c1e25..63138b9 100755 --- a/examples/5_docker_turtlesim/docker/scripts/launch_macos.sh +++ b/examples/5_docker_turtlesim/docker/scripts/launch_macos.sh @@ -4,7 +4,7 @@ set -e -echo "🐢 Starting Turtlesim on macOS with GUI" +echo "Starting Turtlesim on macOS with GUI" echo "========================================" # Function to detect display number @@ -33,13 +33,13 @@ get_machine_ip() { # Step 1: Start XQuartz if not running if ! pgrep -x "X11.bin" > /dev/null; then - echo "📱 Starting XQuartz..." + echo "Starting XQuartz..." open -a XQuartz # Wait for XQuartz to start (up to 10 seconds) for i in {1..10}; do if pgrep -x "X11.bin" > /dev/null; then - echo "✅ XQuartz started" + echo "XQuartz started" break fi echo " Waiting for XQuartz... ($i/10)" @@ -47,11 +47,11 @@ if ! pgrep -x "X11.bin" > /dev/null; then done if ! pgrep -x "X11.bin" > /dev/null; then - echo "❌ XQuartz failed to start. Please start it manually." + echo "ERROR: XQuartz failed to start. Please start it manually." exit 1 fi else - echo "✅ XQuartz already running" + echo "XQuartz already running" fi # Step 2: Detect display number and machine IP @@ -59,34 +59,34 @@ DISPLAY_NUM=$(detect_display) MACHINE_IP=$(get_machine_ip) if [[ -z "$MACHINE_IP" ]]; then - echo "❌ Could not detect machine IP address" - echo "💡 Please run: ifconfig en0 | grep inet" + echo "ERROR: Could not detect machine IP address" + echo "Please run: ifconfig en0 | grep inet" exit 1 fi -echo "🖥️ Display detected: :$DISPLAY_NUM" -echo "🌐 Machine IP: $MACHINE_IP" +echo "Display detected: :$DISPLAY_NUM" +echo "Machine IP: $MACHINE_IP" # Step 3: Set up X11 permissions export DISPLAY=:$DISPLAY_NUM if command -v xhost >/dev/null 2>&1; then - echo "🔓 Allowing X11 connections..." - xhost + >/dev/null 2>&1 || echo "⚠️ xhost command failed, but continuing..." + echo "Allowing X11 connections..." + xhost + >/dev/null 2>&1 || echo "WARNING: xhost command failed, but continuing..." else - echo "⚠️ xhost not found - X11 forwarding may not work" + echo "WARNING: xhost not found - X11 forwarding may not work" fi # Step 4: Export DISPLAY for Docker export DISPLAY="$MACHINE_IP:$DISPLAY_NUM" -echo "🐳 Docker will use DISPLAY=$DISPLAY" +echo "Docker will use DISPLAY=$DISPLAY" # Step 5: Start the container echo "" -echo "🚀 Starting Turtlesim container..." +echo "Starting Turtlesim container..." echo " If successful, you should see a window with a turtle!" echo "" docker compose up turtlesim echo "" -echo "🎉 Done! The turtle window should be visible on your screen." \ No newline at end of file +echo "Done! The turtle window should be visible on your screen." \ No newline at end of file diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_windows.sh b/examples/5_docker_turtlesim/docker/scripts/launch_windows.sh index d5dcb54..9fcd3e8 100755 --- a/examples/5_docker_turtlesim/docker/scripts/launch_windows.sh +++ b/examples/5_docker_turtlesim/docker/scripts/launch_windows.sh @@ -4,7 +4,7 @@ set -e -echo "🐢 Starting Turtlesim on Windows with GUI" +echo "Starting Turtlesim on Windows with GUI" echo "==========================================" # Step 1: Check if running in WSL or Git Bash @@ -16,22 +16,22 @@ else PLATFORM="Unknown" fi -echo "🖥️ Detected platform: $PLATFORM" +echo "Detected platform: $PLATFORM" # Step 2: Check if X server is running on Windows -echo "🔍 Checking for X server on Windows..." +echo "Checking for X server on Windows..." echo " Make sure VcXsrv, X410, or another X server is running!" echo " If not installed, get VcXsrv from: https://sourceforge.net/projects/vcxsrv/" # Step 3: Set DISPLAY for Docker # Docker Desktop on Windows uses host.docker.internal to reach Windows host export DISPLAY="host.docker.internal:0.0" -echo "🐳 Docker will use DISPLAY=$DISPLAY" +echo "Docker will use DISPLAY=$DISPLAY" # Step 4: Warn about common issues cat << 'TIPS' -📝 Important Notes for Windows: +Important Notes for Windows: - Start your X server (VcXsrv/X410) BEFORE running this script - In VcXsrv: disable "Native opengl" and enable "Disable access control" - If GUI doesn't appear, check Windows Firewall settings @@ -41,11 +41,11 @@ TIPS # Step 5: Start the container echo "" -echo "🚀 Starting Turtlesim container..." +echo "Starting Turtlesim container..." echo " If successful, you should see a window with a turtle!" echo "" docker compose up turtlesim echo "" -echo "🎉 Done! The turtle window should appear in your X server." +echo "Done! The turtle window should appear in your X server." diff --git a/examples/5_docker_turtlesim/launch.sh b/examples/5_docker_turtlesim/launch.sh index e16ba32..2bee89c 100755 --- a/examples/5_docker_turtlesim/launch.sh +++ b/examples/5_docker_turtlesim/launch.sh @@ -8,19 +8,19 @@ OS_TYPE=$(uname -s) case "$OS_TYPE" in Darwin*) - echo "🍎 Detected macOS - launching with XQuartz support..." + echo "Detected macOS - launching with XQuartz support..." ./docker/scripts/launch_macos.sh ;; Linux*) - echo "🐧 Detected Linux - launching with X11 support..." + echo "Detected Linux - launching with X11 support..." ./docker/scripts/launch_linux.sh ;; MINGW*|MSYS*|CYGWIN*) - echo "🪟 Detected Windows - launching with X server support..." + echo "Detected Windows - launching with X server support..." ./docker/scripts/launch_windows.sh ;; *) - echo "❌ Unsupported OS: $OS_TYPE" + echo "Unsupported OS: $OS_TYPE" echo " Please run the appropriate script manually:" echo " - macOS: ./docker/scripts/launch_macos.sh" echo " - Linux: ./docker/scripts/launch_linux.sh" From d315bb55715ac638b8c79e2b760589578b7c3659 Mon Sep 17 00:00:00 2001 From: Bharat Jain Date: Sun, 2 Nov 2025 16:26:50 +0530 Subject: [PATCH 05/11] Added CI test --- .github/workflows/test-docker-turtlesim.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-docker-turtlesim.yml b/.github/workflows/test-docker-turtlesim.yml index f6e6b9e..65664e7 100644 --- a/.github/workflows/test-docker-turtlesim.yml +++ b/.github/workflows/test-docker-turtlesim.yml @@ -2,12 +2,12 @@ name: Test Docker Turtlesim Launch on: push: - branches: [ develop, main ] + branches: [ test ] paths: - 'examples/5_docker_turtlesim/**' - '.github/workflows/test-docker-turtlesim.yml' pull_request: - branches: [ develop, main ] + branches: [ test ] paths: - 'examples/5_docker_turtlesim/**' From 237b3603c3631a2fe5092e3a50b1bc871d4db8d0 Mon Sep 17 00:00:00 2001 From: Bharat Jain Date: Tue, 4 Nov 2025 22:43:53 +0530 Subject: [PATCH 06/11] launch scripts --- examples/5_docker_turtlesim/docker/scripts/launch_linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh b/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh index 8ccf6d3..6b3a8ac 100755 --- a/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh +++ b/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh @@ -33,7 +33,7 @@ echo "Docker will use DISPLAY=$DISPLAY" # Step 4: Start the container echo "" echo "Starting Turtlesim container..." -echo " If successful, you should see a window with a turtle!" +echo "If successful, you should see a window with a turtle!" echo "" docker compose up turtlesim From d9d474a8243f90a4712b7ab3cbe7b370e03c730b Mon Sep 17 00:00:00 2001 From: Bharat Jain Date: Wed, 5 Nov 2025 00:58:38 +0530 Subject: [PATCH 07/11] Removed ci --- .github/workflows/test-docker-turtlesim.yml | 131 -------------------- 1 file changed, 131 deletions(-) delete mode 100644 .github/workflows/test-docker-turtlesim.yml diff --git a/.github/workflows/test-docker-turtlesim.yml b/.github/workflows/test-docker-turtlesim.yml deleted file mode 100644 index 65664e7..0000000 --- a/.github/workflows/test-docker-turtlesim.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: Test Docker Turtlesim Launch - -on: - push: - branches: [ test ] - paths: - - 'examples/5_docker_turtlesim/**' - - '.github/workflows/test-docker-turtlesim.yml' - pull_request: - branches: [ test ] - paths: - - 'examples/5_docker_turtlesim/**' - -jobs: - test-docker-build: - name: Test Docker Build on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-13] - - defaults: - run: - working-directory: examples/5_docker_turtlesim - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker on macOS - if: runner.os == 'macOS' - run: | - brew install docker docker-compose colima - colima start --memory 4 --cpu 2 - - - name: Build Docker image - run: docker compose build turtlesim - timeout-minutes: 15 - - - name: Test container can start (headless) - run: | - # Set headless display for testing - export DISPLAY=:99 - export QT_QPA_PLATFORM=offscreen - - # Start container in detached mode - timeout 60 docker compose up -d turtlesim || echo "Container start timeout" - - # Wait for services to initialize - sleep 15 - - # Check if container is running - docker ps -a - - # Check container logs for errors - docker compose logs turtlesim - - - name: Test ROS Bridge WebSocket - run: | - # Check if rosbridge websocket server started - docker compose logs turtlesim | grep -i "rosbridge" || echo "Rosbridge log check" - - # Try to connect to port 9090 (may not work without proper setup) - timeout 10 bash -c 'until curl -s http://localhost:9090 2>/dev/null; do sleep 1; done' || echo "Rosbridge connection test skipped in CI" - - - name: Cleanup - if: always() - run: | - docker compose down -v || true - if [ "${{ runner.os }}" == "macOS" ]; then - colima stop || true - fi - - test-launch-scripts: - name: Validate Launch Scripts - runs-on: ubuntu-latest - - defaults: - run: - working-directory: examples/5_docker_turtlesim - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Install shellcheck - run: sudo apt-get update && sudo apt-get install -y shellcheck - - - name: Make scripts executable - run: | - chmod +x launch.sh - chmod +x docker/scripts/*.sh - - - name: Test script syntax - run: | - bash -n launch.sh - bash -n docker/scripts/launch_linux.sh - bash -n docker/scripts/launch_macos.sh - bash -n docker/scripts/launch_windows.sh - echo "All scripts have valid syntax" - - - name: Run shellcheck - run: | - shellcheck launch.sh || echo "Shellcheck warnings in launch.sh" - shellcheck docker/scripts/launch_linux.sh || echo "Shellcheck warnings in launch_linux.sh" - shellcheck docker/scripts/launch_macos.sh || echo "Shellcheck warnings in launch_macos.sh" - shellcheck docker/scripts/launch_windows.sh || echo "Shellcheck warnings in launch_windows.sh" - - - name: Verify platform scripts exist - run: | - test -f docker/scripts/launch_linux.sh || exit 1 - test -f docker/scripts/launch_macos.sh || exit 1 - test -f docker/scripts/launch_windows.sh || exit 1 - echo "All platform-specific scripts found" - - - name: Verify launch.sh references platform scripts - run: | - grep -q "docker/scripts/launch_macos.sh" launch.sh || exit 1 - grep -q "docker/scripts/launch_linux.sh" launch.sh || exit 1 - grep -q "docker/scripts/launch_windows.sh" launch.sh || exit 1 - echo "launch.sh correctly references all platform scripts" - - - name: Test OS detection logic - run: | - # Test that the script can identify OS types - grep -q "Darwin\*)" launch.sh || exit 1 - grep -q "Linux\*)" launch.sh || exit 1 - grep -q "MINGW\*|MSYS\*|CYGWIN\*)" launch.sh || exit 1 - echo "OS detection logic verified" - From 1c2229f3754044afe604ca08455da96a422fe43b Mon Sep 17 00:00:00 2001 From: Bharat Jain <152432505+itsbharatj@users.noreply.github.com> Date: Wed, 5 Nov 2025 01:00:08 +0530 Subject: [PATCH 08/11] Delete mcp_json.txt --- mcp_json.txt | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 mcp_json.txt diff --git a/mcp_json.txt b/mcp_json.txt deleted file mode 100644 index b882d8b..0000000 --- a/mcp_json.txt +++ /dev/null @@ -1,22 +0,0 @@ -{ - "mcpServers": { - "filesystem": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-filesystem", - "/Users/bharatjain/Desktop", - "/Users/bharatjain/Downloads" - ] - }, - "ros-mcp-server": { - "command": "/Users/bharatjain/.local/bin/uv", - "args": [ - "--directory", - "/Users/bharatjain/Desktop/ros-mcp-server", - "run", - "server.py" - ] - } - } -} From c147d596356df58942856c933dfe382ea5ee933b Mon Sep 17 00:00:00 2001 From: Bharat Jain Date: Wed, 5 Nov 2025 01:12:54 +0530 Subject: [PATCH 09/11] updated README --- examples/5_docker_turtlesim/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/5_docker_turtlesim/README.md b/examples/5_docker_turtlesim/README.md index 9a88508..c7db778 100644 --- a/examples/5_docker_turtlesim/README.md +++ b/examples/5_docker_turtlesim/README.md @@ -158,7 +158,7 @@ export DISPLAY=:1 # or :0 depending on what you found xhost + # Set DISPLAY for Docker (use your IP from Step 4 + display number) -export DOCKER_DISPLAY="10.1.56.72:1" # Replace with your actual IP +export DOCKER_DISPLAY= # Replace with your actual IP ``` ## Troubleshooting From 5109cf115208677c646b3ba89aec5cab4c3c858b Mon Sep 17 00:00:00 2001 From: Bharat Jain Date: Wed, 5 Nov 2025 19:01:59 +0530 Subject: [PATCH 10/11] *launch.py for turtlesim docker --- .../5_docker_turtlesim/docker-compose.yml | 5 +- .../docker/scripts/launch_linux.sh | 2 +- .../launch_turtlesim.launch.py | 92 +++++++++++++++++++ 3 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 examples/5_docker_turtlesim/launch_turtlesim.launch.py diff --git a/examples/5_docker_turtlesim/docker-compose.yml b/examples/5_docker_turtlesim/docker-compose.yml index 880a68d..44ee388 100644 --- a/examples/5_docker_turtlesim/docker-compose.yml +++ b/examples/5_docker_turtlesim/docker-compose.yml @@ -9,11 +9,12 @@ services: - ROS_DISTRO=humble - QT_X11_NO_MITSHM=1 volumes: - - ./docker/scripts:/ros2_ws/scripts:ro + # Mount launch file into the container + - ./launch_turtlesim.launch.py:/ros2_ws/launch/launch_turtlesim.launch.py:ro # Linux X11 socket (only works on Linux) - /tmp/.X11-unix:/tmp/.X11-unix:rw ports: - "9090:9090" stdin_open: true tty: true - command: ["/bin/bash", "/ros2_ws/scripts/launch_turtlesim.sh"] + command: ["ros2", "launch", "/ros2_ws/launch/launch_turtlesim.launch.py"] diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh b/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh index 6b3a8ac..33cb46d 100755 --- a/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh +++ b/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh @@ -24,7 +24,7 @@ if command -v xhost >/dev/null 2>&1; then } else echo "WARNING: xhost not found. Install with: sudo apt-get install x11-xserver-utils" - echo " Continuing anyway, but GUI may not work..." + exit 1 fi # Step 3: Export DISPLAY for Docker diff --git a/examples/5_docker_turtlesim/launch_turtlesim.launch.py b/examples/5_docker_turtlesim/launch_turtlesim.launch.py new file mode 100644 index 0000000..f1204eb --- /dev/null +++ b/examples/5_docker_turtlesim/launch_turtlesim.launch.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 + +""" +ROS2 Launch file for Turtlesim with Rosbridge WebSocket Server +Launches both turtlesim node and rosbridge server for MCP integration. +""" + +from launch.actions import DeclareLaunchArgument, LogInfo +from launch.substitutions import LaunchConfiguration +from launch_ros.actions import Node + +from launch import LaunchDescription + + +def generate_launch_description(): + """Generate the launch description for turtlesim with rosbridge.""" + + # Declare launch arguments + port_arg = DeclareLaunchArgument( + "port", default_value="9090", description="Port for rosbridge websocket server" + ) + + address_arg = DeclareLaunchArgument( + "address", + default_value="", + description="Address for rosbridge websocket server (empty for all interfaces)", + ) + + log_level_arg = DeclareLaunchArgument( + "log_level", default_value="info", description="Log level for nodes" + ) + + # Turtlesim node + turtlesim_node = Node( + package="turtlesim", + executable="turtlesim_node", + name="turtlesim", + output="screen", + arguments=["--ros-args", "--log-level", LaunchConfiguration("log_level")], + ) + + # Rosbridge websocket server node + rosbridge_node = Node( + package="rosbridge_server", + executable="rosbridge_websocket", + name="rosbridge_websocket", + output="screen", + parameters=[ + { + "port": LaunchConfiguration("port"), + "address": LaunchConfiguration("address"), + "use_compression": False, + "max_message_size": 10000000, + "send_action_goals_in_new_thread": True, + "call_services_in_new_thread": True, + "default_call_service_timeout": 5.0, + } + ], + arguments=["--ros-args", "--log-level", LaunchConfiguration("log_level")], + ) + + # ROS API node (needed for some rosbridge operations) + rosapi_node = Node( + package="rosapi", + executable="rosapi_node", + name="rosapi", + output="screen", + arguments=["--ros-args", "--log-level", LaunchConfiguration("log_level")], + ) + + # Log info + log_info = LogInfo( + msg=[ + "Starting Turtlesim with Rosbridge WebSocket Server:", + " - Port: ", + LaunchConfiguration("port"), + " - Log level: ", + LaunchConfiguration("log_level"), + ] + ) + + return LaunchDescription( + [ + port_arg, + address_arg, + log_level_arg, + log_info, + rosbridge_node, + rosapi_node, + turtlesim_node, + ] + ) From d9db7b37ab529845d5a573ba54d01ff00ba2a393 Mon Sep 17 00:00:00 2001 From: Stefano Dalla Gasperina Date: Mon, 10 Nov 2025 08:55:41 -0600 Subject: [PATCH 11/11] Reorganize docker turtlesim example scripts --- examples/5_docker_turtlesim/README.md | 70 +++++++++++-------- .../docker/scripts/launch_turtlesim.sh | 36 ---------- .../{ => scripts}/launch.sh | 0 .../{docker => }/scripts/launch_linux.sh | 0 .../{docker => }/scripts/launch_macos.sh | 0 .../{docker => }/scripts/launch_windows.sh | 0 6 files changed, 41 insertions(+), 65 deletions(-) delete mode 100755 examples/5_docker_turtlesim/docker/scripts/launch_turtlesim.sh rename examples/5_docker_turtlesim/{ => scripts}/launch.sh (100%) rename examples/5_docker_turtlesim/{docker => }/scripts/launch_linux.sh (100%) rename examples/5_docker_turtlesim/{docker => }/scripts/launch_macos.sh (100%) rename examples/5_docker_turtlesim/{docker => }/scripts/launch_windows.sh (100%) diff --git a/examples/5_docker_turtlesim/README.md b/examples/5_docker_turtlesim/README.md index c7db778..fe68a03 100644 --- a/examples/5_docker_turtlesim/README.md +++ b/examples/5_docker_turtlesim/README.md @@ -1,7 +1,8 @@ # Example - TurtleSim in Docker - For users who want to test the MCP server without needing to install ROS, this is an example that provides a dockerized ROS2 container preinstalled with the simplest possible 'robot' in the ROS ecosystem - TurtleSim. - Turtlesim is a lightweight simulator for learning ROS / ROS 2. It illustrates what ROS does at the most basic level to give you an idea of what you will do with a real robot or a robot simulation later on. +For users who want to test the MCP server without needing to install ROS, this is an example that provides a dockerized ROS2 container preinstalled with the simplest possible 'robot' in the ROS ecosystem - TurtleSim. + +Turtlesim is a lightweight simulator for learning ROS / ROS 2. It illustrates what ROS does at the most basic level to give you an idea of what you will do with a real robot or a robot simulation later on. ## Prerequisites @@ -16,7 +17,7 @@ Before starting this tutorial, make sure you have the following installed: ### Platform-Specific Requirements #### macOS -- **XQuartz**: Install from [XQuartz website](https://www.xquartz.org/) +- **XQuartz**: Install from [XQuartz website](https://www.xquartz.org/) - **Important**: XQuartz setup can be complex - see [macOS Setup](#macos-setup) section below for detailed instructions #### Linux @@ -27,7 +28,6 @@ Before starting this tutorial, make sure you have the following installed: - **X Server**: Install [X410](https://x410.dev/), [VcXsrv](https://sourceforge.net/projects/vcxsrv/), or another X Server from Microsoft Store - **WSL recommended**: Works best with Windows Subsystem for Linux -**Note:** If your OS is Windows, take a look at the following:
PowerShell and WSL (Windows) @@ -72,18 +72,16 @@ If you prefer manual control or the automatic script doesn't work: ./docker/scripts/launch_macos.sh ``` -**Linux:** +**Linux (or Windows WSL):** ```bash ./docker/scripts/launch_linux.sh ``` -**Windows (WSL/Git Bash):** +**Windows:** ```bash ./docker/scripts/launch_windows.sh ``` - - The container will automatically start both turtlesim and rosbridge websocket server. You should see: - A turtlesim window appear with a turtle @@ -98,8 +96,8 @@ Launch the container in the background: ```bash docker compose up -d ``` -And attach to the container +And attach to the container: ```bash docker exec -it ros2-turtlesim bash ``` @@ -107,7 +105,7 @@ docker exec -it ros2-turtlesim bash Once inside the container, you can manually launch turtle teleop to control the turtle: ```bash -source /opt/ros/humble/setup.bash +source /opt/ros/${ROS_DISTRO}$/setup.bash ros2 run turtlesim turtle_teleop_key ``` @@ -116,12 +114,14 @@ This will allow you to use arrow keys or WASD to manually move the turtle around ## Integration with MCP Server Once turtlesim and rosbridge are running, you can connect the MCP server to control the turtle programmatically. -Follow the [installation guide](../../docs/installation.md) for full setup instructions if you haven't already set up the MCP server. +Follow the [installation guide](../../docs/installation.md) for full setup instructions if you haven't already set up the MCP server. -Since it is running on the same machine, you can tell the LLM to connect to the robot on localhost. +Since it is running on the same machine, you can tell the LLM to connect to the robot on localhost. +## Platform-Specific Setup -## macOS Setup +
+macOS Setup macOS requires special X11 forwarding setup. Follow these steps carefully: @@ -160,12 +160,14 @@ xhost + # Set DISPLAY for Docker (use your IP from Step 4 + display number) export DOCKER_DISPLAY= # Replace with your actual IP ``` +
## Troubleshooting ### macOS Display Issues -**Problem**: `qt.qpa.xcb: could not connect to display` +
+Problem: qt.qpa.xcb: could not connect to display **Solutions**: @@ -196,49 +198,61 @@ export DOCKER_DISPLAY= # Replace with your actual IP export DISPLAY=:1 # Use your display number xhost + ``` +
-**Problem**: `xhost: unable to open display ":0"` +
+Problem: xhost: unable to open display ":0" **Solution**: XQuartz might be using `:1` instead of `:0`: + ```bash export DISPLAY=:1 xhost + ``` +
### Linux Display Issues +
+Display issues on Linux + If you encounter display issues on Linux, run: ```bash xhost +local:docker ``` +
### Windows Display Issues +
+Display issues on Windows + For Windows users, make sure you install an X Server (X410) and set the DISPLAY: ```bash $env:DOCKER_DISPLAY="host.docker.internal:0.0" ``` +
### General Issues -**Problem**: Container starts but no window appears +
+Problem: Container starts but no window appears **Solutions**: 1. Check if the window is hidden behind other windows 2. Look in Mission Control (macOS) or Alt+Tab (Windows/Linux) 3. Verify your DOCKER_DISPLAY is set correctly for your platform +
-**Problem**: `libGL error: No matching fbConfigs or visuals found` +
+Problem: libGL error: No matching fbConfigs or visuals found **Solution**: This is just a warning and doesn't prevent the GUI from working. The turtlesim window should still appear. +
-### Container Networking - -If you need to access the container from outside, the container uses host networking mode, so ROS2 topics should be accessible on localhost. - -### Manual Launch (Alternative) +## Manual Launch (Alternative) If the automatic launch isn't working or you prefer to launch turtlesim manually, you can run these commands inside the container: @@ -247,7 +261,7 @@ If the automatic launch isn't working or you prefer to launch turtlesim manually docker exec -it ros2-turtlesim bash # Source ROS2 environment -source /opt/ros/humble/setup.bash +source /opt/ros/${ROS_DISTRO}$/setup.bash # Start turtlesim in one terminal ros2 run turtlesim turtlesim_node @@ -256,11 +270,11 @@ ros2 run turtlesim turtlesim_node ros2 run turtlesim turtle_teleop_key ``` -### Testing Turtlesim +## Testing Turtlesim If you need to verify that turtlesim is working correctly: -#### ROS2 Topic Inspection +### ROS2 Topic Inspection In a separate terminal, you can inspect the ROS2 topics: @@ -269,7 +283,7 @@ In a separate terminal, you can inspect the ROS2 topics: docker exec -it ros2-turtlesim bash # Source ROS2 environment -source /opt/ros/humble/setup.bash +source /opt/ros/${ROS_DISTRO}$/setup.bash # List all topics ros2 topic list @@ -281,7 +295,7 @@ ros2 topic echo /turtle1/pose ros2 topic echo /turtle1/cmd_vel ``` -#### ROS Bridge WebSocket Server +### ROS Bridge WebSocket Server The rosbridge websocket server is automatically started and available at `ws://localhost:9090`. You can test the connection using a WebSocket client or the MCP server. @@ -309,10 +323,8 @@ docker rmi ros-mcp-server_turtlesim Now that you have turtlesim running, you can: - 1. **Try more complex commands** like drawing shapes or following paths 2. **Install ROS Locally** to add more nodes and services 3. **Explore other examples in this repository** - This example provides a foundation for understanding how the MCP server can interact with ROS2 systems, from simple simulators like turtlesim to complex robotic platforms. \ No newline at end of file diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_turtlesim.sh b/examples/5_docker_turtlesim/docker/scripts/launch_turtlesim.sh deleted file mode 100755 index ed556f5..0000000 --- a/examples/5_docker_turtlesim/docker/scripts/launch_turtlesim.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env bash -set -eo pipefail - -# Source ROS2 environment -source /opt/ros/humble/setup.bash - -echo "Starting ROS Bridge WebSocket server..." -echo "WebSocket server will be available at: ws://localhost:9090" - -# Launch rosbridge websocket server in the background -ros2 launch rosbridge_server rosbridge_websocket_launch.xml & - -# Wait a moment for rosbridge to start -sleep 3 - -echo "Starting Turtlesim..." -echo "Turtlesim window should appear shortly" -echo "You can control the turtle using:" -echo " - Arrow keys or WASD to move" -echo " - Ctrl+C to stop" - -# Launch turtlesim in the background -ros2 run turtlesim turtlesim_node & - -# Trap signals to clean up processes -cleanup() { - # Cleanup when teleop exits - echo "Stopping turtlesim and rosbridge..." - pkill -f turtlesim_node - pkill -f rosbridge_server - wait -} - -trap cleanup SIGINT SIGTERM - -wait \ No newline at end of file diff --git a/examples/5_docker_turtlesim/launch.sh b/examples/5_docker_turtlesim/scripts/launch.sh similarity index 100% rename from examples/5_docker_turtlesim/launch.sh rename to examples/5_docker_turtlesim/scripts/launch.sh diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_linux.sh b/examples/5_docker_turtlesim/scripts/launch_linux.sh similarity index 100% rename from examples/5_docker_turtlesim/docker/scripts/launch_linux.sh rename to examples/5_docker_turtlesim/scripts/launch_linux.sh diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_macos.sh b/examples/5_docker_turtlesim/scripts/launch_macos.sh similarity index 100% rename from examples/5_docker_turtlesim/docker/scripts/launch_macos.sh rename to examples/5_docker_turtlesim/scripts/launch_macos.sh diff --git a/examples/5_docker_turtlesim/docker/scripts/launch_windows.sh b/examples/5_docker_turtlesim/scripts/launch_windows.sh similarity index 100% rename from examples/5_docker_turtlesim/docker/scripts/launch_windows.sh rename to examples/5_docker_turtlesim/scripts/launch_windows.sh