diff --git a/.devcontainer/Dockerfile.windows b/.devcontainer/Dockerfile.windows new file mode 100644 index 0000000..d1f6126 --- /dev/null +++ b/.devcontainer/Dockerfile.windows @@ -0,0 +1,29 @@ +FROM python:3.9 + +# Install system dependencies for GUI and VNC +RUN apt-get update && apt-get install -y \ + fluxbox \ + x11vnc \ + xvfb \ + python3-tk \ + python3-opengl \ + mesa-utils \ + supervisor \ + && rm -rf /var/lib/apt/lists/* + +# Create VNC directory and set up supervisor +RUN mkdir -p /var/log/supervisor +COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf + +# Set up VNC password (optional) +RUN mkdir /root/.vnc +RUN x11vnc -storepasswd vncpass /root/.vnc/passwd + +# Expose VNC port +EXPOSE 5901 + +# Set display +ENV DISPLAY=:1 + +# Start supervisor to manage processes +CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] \ No newline at end of file diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000..d0d768c --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,112 @@ +# Dev Container Template System + +This directory contains a template-based dev container configuration system for the Tello Simulator project that automatically adapts to different platforms. + +## Quick Start + +Run the setup script to generate a platform-specific `devcontainer.json`: + +```bash +.devcontainer/setup.sh +``` + +The script will: + +1. 🔍 Auto-detect your platform (macOS, Linux, Windows, WSL) +2. 📝 Generate the appropriate `devcontainer.json` from the template +3. 📋 Show platform-specific setup instructions + +## Files + +- `devcontainer.template.json` - Template with platform variables +- `setup.sh` - Platform detection and configuration script +- `devcontainer.json` - Generated file (git-ignored) +- `Dockerfile` - Base Docker configuration +- `Dockerfile.windows` - Windows-specific Docker configuration with VNC +- `supervisord.conf` - Process manager for Windows VNC setup +- `setup-windows.sh` - Windows container initialization script + +## Manual Platform Selection + +You can also specify a platform manually: + +```bash +.devcontainer/setup.sh macos # Force macOS configuration +.devcontainer/setup.sh linux # Force Linux configuration +.devcontainer/setup.sh windows # Force Windows configuration +.devcontainer/setup.sh wsl # WSL with options +``` + +## Platform Configurations + +### macOS + +- ✅ Uses `host.docker.internal:0` for DISPLAY +- ❌ No X11 socket mounting (not available on macOS) +- 📦 Requires XQuartz: `brew install --cask xquartz` +- 🔧 Run `xhost +localhost` after XQuartz setup + +### Linux + +- ✅ Direct X11 socket mounting via `/tmp/.X11-unix` +- ✅ Host networking for optimal performance +- ✅ Uses local `$DISPLAY` environment variable +- 🚀 Works out of the box on most Linux distributions + +### Windows + +- 🖥️ VNC server on port 5901 (password: `vncpass`) +- 🌐 Web access: `http://localhost:5901` +- 📱 VNC client: `localhost:5901` +- 🎯 Virtual framebuffer with Fluxbox window manager + +### WSL (Windows Subsystem for Linux) + +Interactive setup with three options: + +1. **X11 forwarding** - Requires Windows X server (VcXsrv, Xming) +2. **VNC server** - Same as Windows setup +3. **Linux-style** - If X11 forwarding already configured + +## GUI Application Support + +All configurations support GUI applications required by the Tello simulator's Ursina engine: + +**Test GUI support:** + +```bash +python -c "import tkinter; tkinter.Tk().mainloop()" +``` + +**Run the simulator:** + +```bash +python tello_sim/run_sim.py +``` + +## Development Notes + +- The generated `devcontainer.json` is git-ignored to prevent platform conflicts +- Each developer runs `setup.sh` once to configure for their environment +- Template uses JSON variable substitution via the setup script +- Windows configuration includes full VNC stack for GUI support + +## Troubleshooting + +**Script fails to detect platform:** + +```bash +.devcontainer/setup.sh [platform] # Specify manually +``` + +**GUI not working:** + +- macOS: Ensure XQuartz is running and `xhost +localhost` was executed +- Linux: Check X11 forwarding with `echo $DISPLAY` +- Windows: Connect to VNC at `localhost:5901` + +**Container won't start:** + +- Check Docker is running +- Verify VS Code "Dev Containers" extension is installed +- Try "Dev Containers: Rebuild Container" from Command Palette diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 6ceec73..0000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "Python GUI Devcontainer", - "build": { - "dockerfile": "Dockerfile" - }, - "forwardPorts": [5901], - "runArgs": ["--env", "DISPLAY=host.docker.internal:0"], - "mounts": ["source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind"] - } \ No newline at end of file diff --git a/.devcontainer/devcontainer.template.json b/.devcontainer/devcontainer.template.json new file mode 100644 index 0000000..112cafa --- /dev/null +++ b/.devcontainer/devcontainer.template.json @@ -0,0 +1,18 @@ +{ + "name": "Python GUI Devcontainer - ${PLATFORM}", + "build": { + "dockerfile": "Dockerfile${DOCKERFILE_SUFFIX}" + }, + "forwardPorts": [5901], + "runArgs": ${RUN_ARGS}, + "mounts": ${MOUNTS}, + "overrideCommand": false, + "customizations": { + "vscode": { + "extensions": [ + "ms-python.python" + ] + } + }, + "postCreateCommand": "${POST_CREATE_COMMAND}" +} \ No newline at end of file diff --git a/.devcontainer/setup-windows.sh b/.devcontainer/setup-windows.sh new file mode 100755 index 0000000..9d2aa31 --- /dev/null +++ b/.devcontainer/setup-windows.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# Windows Dev Container Setup Script +# This script helps set up the development environment for Windows users + +echo "=== Tello Simulator - Windows Dev Container Setup ===" + +# Check if we're running in a container +if [ -f /.dockerenv ]; then + echo "✅ Running inside Docker container" + + # Install Python requirements + if [ -f "/workspaces/tello-sim/requirements.txt" ]; then + echo "📦 Installing Python requirements..." + pip install -r /workspaces/tello-sim/requirements.txt + fi + + # Test GUI support + echo "🖥️ Testing GUI support..." + python3 -c " +import tkinter as tk +import sys +try: + root = tk.Tk() + root.title('GUI Test - Tello Simulator') + tk.Label(root, text='✅ GUI Support Working!\\nClose this window to continue.').pack(pady=20) + root.geometry('300x100') + root.after(3000, root.destroy) # Auto-close after 3 seconds + root.mainloop() + print('✅ GUI test successful!') +except Exception as e: + print(f'❌ GUI test failed: {e}') + sys.exit(1) +" + + echo "🚁 Setup complete! You can now run the Tello simulator." + echo "📺 VNC server is running on port 5901 (password: vncpass)" + echo "🌐 Access via browser: http://localhost:5901" + +else + echo "⚠️ This script should be run inside the dev container." + echo "Please open this project in VS Code and use 'Reopen in Container'." +fi \ No newline at end of file diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh new file mode 100755 index 0000000..eee92ae --- /dev/null +++ b/.devcontainer/setup.sh @@ -0,0 +1,266 @@ +#!/bin/bash + +# Tello Simulator Dev Container Setup Script +# This script generates a platform-specific devcontainer.json from the template + +set -e # Exit on any error + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +TEMPLATE_FILE="$SCRIPT_DIR/devcontainer.template.json" +OUTPUT_FILE="$SCRIPT_DIR/devcontainer.json" + +echo "🚁 Tello Simulator Dev Container Setup" +echo "=====================================" + +# Function to detect platform +detect_platform() { + case "$(uname -s)" in + Darwin*) + echo "macos" + ;; + Linux*) + if grep -q Microsoft /proc/version 2>/dev/null; then + echo "wsl" + else + echo "linux" + fi + ;; + CYGWIN*|MINGW32*|MSYS*|MINGW*) + echo "windows" + ;; + *) + echo "unknown" + ;; + esac +} + +# Function to configure for macOS +configure_macos() { + local platform="macOS" + local dockerfile_suffix="" + local run_args='[ + "--env", "DISPLAY=host.docker.internal:0" + ]' + local mounts='[]' + local post_create_command="echo 'macOS setup complete. Install XQuartz and run: xhost +localhost'" + + echo "📱 Configuring for macOS..." + echo " - Using host.docker.internal for DISPLAY" + echo " - No X11 socket mounting (not available on macOS)" + echo " - Requires XQuartz for GUI support" + + generate_config "$platform" "$dockerfile_suffix" "$run_args" "$mounts" "$post_create_command" +} + +# Function to configure for Linux +configure_linux() { + local platform="Linux" + local dockerfile_suffix="" + local run_args='[ + "--env", "DISPLAY=${localEnv:DISPLAY:unix:0}", + "--network", "host" + ]' + local mounts='[ + "source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind" + ]' + local post_create_command="echo 'Linux setup complete. X11 forwarding configured.'" + + echo "🐧 Configuring for Linux..." + echo " - Using X11 socket mounting" + echo " - Host networking enabled" + echo " - Direct DISPLAY forwarding" + + generate_config "$platform" "$dockerfile_suffix" "$run_args" "$mounts" "$post_create_command" +} + +# Function to configure for Windows/WSL +configure_windows() { + local platform="Windows" + local dockerfile_suffix=".windows" + local run_args='[ + "--env", "DISPLAY=:1" + ]' + local mounts='[]' + local post_create_command=".devcontainer/setup-windows.sh" + + echo "🪟 Configuring for Windows..." + echo " - Using VNC server on port 5901" + echo " - Virtual framebuffer display" + echo " - GUI accessible via VNC viewer or browser" + + generate_config "$platform" "$dockerfile_suffix" "$run_args" "$mounts" "$post_create_command" +} + +# Function to configure for WSL +configure_wsl() { + echo "🪟🐧 WSL detected. Choose your preferred setup:" + echo "1) WSL with X11 forwarding (requires Windows X server)" + echo "2) VNC server (works without additional setup)" + echo "3) Linux-style (if you have X11 forwarding configured)" + + read -p "Enter choice (1-3): " choice + + case $choice in + 1) + local platform="WSL (X11)" + local dockerfile_suffix="" + local run_args='[ + "--env", "DISPLAY=host.docker.internal:0" + ]' + local mounts='[]' + local post_create_command="echo 'WSL X11 setup complete. Ensure Windows X server is running.'" + + echo " - Using Windows X server forwarding" + echo " - Requires VcXsrv, Xming, or similar on Windows" + ;; + 2) + configure_windows + return + ;; + 3) + configure_linux + return + ;; + *) + echo "❌ Invalid choice. Using VNC server setup." + configure_windows + return + ;; + esac + + generate_config "$platform" "$dockerfile_suffix" "$run_args" "$mounts" "$post_create_command" +} + +# Function to generate the final config +generate_config() { + local platform="$1" + local dockerfile_suffix="$2" + local run_args="$3" + local mounts="$4" + local post_create_command="$5" + + # Read template and substitute variables (escape forward slashes for sed) + local escaped_post_create=$(echo "$post_create_command" | sed 's/\//\\\//g') + sed -e "s/\${PLATFORM}/$platform/g" \ + -e "s/\${DOCKERFILE_SUFFIX}/$dockerfile_suffix/g" \ + -e "s/\${POST_CREATE_COMMAND}/$escaped_post_create/g" \ + "$TEMPLATE_FILE" > "$OUTPUT_FILE.tmp" + + # Replace JSON arrays (more complex substitution) + python3 -c " +import json +import sys + +# Read the template with placeholders +with open('$OUTPUT_FILE.tmp', 'r') as f: + content = f.read() + +# Replace the JSON array placeholders +run_args = $run_args +mounts = $mounts + +content = content.replace('\${RUN_ARGS}', json.dumps(run_args, indent=1).replace('\n', '\n\t')) +content = content.replace('\${MOUNTS}', json.dumps(mounts, indent=1).replace('\n', '\n\t')) + +# Write the final file +with open('$OUTPUT_FILE', 'w') as f: + f.write(content) + +# Validate JSON +try: + with open('$OUTPUT_FILE', 'r') as f: + json.load(f) + print('✅ Generated valid devcontainer.json') +except json.JSONDecodeError as e: + print(f'❌ Invalid JSON generated: {e}') + sys.exit(1) +" + + # Clean up temp file + rm "$OUTPUT_FILE.tmp" + + echo "✅ devcontainer.json generated for $platform" +} + +# Function to show usage instructions +show_usage_instructions() { + local platform="$1" + + echo "" + echo "📋 Next Steps:" + echo "==============" + + case "$platform" in + "macos") + echo "1. Install XQuartz: brew install --cask xquartz" + echo "2. Start XQuartz and enable 'Allow connections from network clients'" + echo "3. Run: xhost +localhost" + echo "4. Restart VS Code and 'Reopen in Container'" + ;; + "linux") + echo "1. Ensure X11 forwarding is enabled" + echo "2. Restart VS Code and 'Reopen in Container'" + echo "3. Test with: python -c \"import tkinter; tkinter.Tk().mainloop()\"" + ;; + "windows"|"WSL"*) + echo "1. Restart VS Code and 'Reopen in Container'" + echo "2. Connect to VNC server at: http://localhost:5901" + echo "3. VNC password: vncpass" + echo "4. Or use VNC viewer: localhost:5901" + ;; + esac + + echo "" + echo "🚁 Ready to run Tello Simulator!" + echo " python tello_sim/run_sim.py" +} + +# Main execution +main() { + # Check if template exists + if [[ ! -f "$TEMPLATE_FILE" ]]; then + echo "❌ Template file not found: $TEMPLATE_FILE" + exit 1 + fi + + # Auto-detect platform or allow override + if [[ $# -eq 0 ]]; then + PLATFORM=$(detect_platform) + echo "🔍 Auto-detected platform: $PLATFORM" + else + PLATFORM="$1" + echo "🎯 Using specified platform: $PLATFORM" + fi + + # Configure based on platform + case "$PLATFORM" in + "macos") + configure_macos + show_usage_instructions "macos" + ;; + "linux") + configure_linux + show_usage_instructions "linux" + ;; + "windows") + configure_windows + show_usage_instructions "windows" + ;; + "wsl") + configure_wsl + show_usage_instructions "WSL" + ;; + *) + echo "❌ Unsupported platform: $PLATFORM" + echo "Supported platforms: macos, linux, windows, wsl" + echo "Usage: $0 [platform]" + exit 1 + ;; + esac + + echo "" + echo "🎉 Setup complete! Your devcontainer.json is ready." +} + +# Run main function +main "$@" \ No newline at end of file diff --git a/.devcontainer/supervisord.conf b/.devcontainer/supervisord.conf new file mode 100644 index 0000000..dba9e27 --- /dev/null +++ b/.devcontainer/supervisord.conf @@ -0,0 +1,23 @@ +[supervisord] +nodaemon=true +logfile=/var/log/supervisor/supervisord.log +pidfile=/var/run/supervisord.pid + +[program:xvfb] +command=/usr/bin/Xvfb :1 -screen 0 1024x768x24 +autorestart=true +stdout_logfile=/var/log/supervisor/xvfb.log +stderr_logfile=/var/log/supervisor/xvfb.log + +[program:fluxbox] +command=/usr/bin/fluxbox -display :1 +autorestart=true +stdout_logfile=/var/log/supervisor/fluxbox.log +stderr_logfile=/var/log/supervisor/fluxbox.log +environment=DISPLAY=":1" + +[program:x11vnc] +command=/usr/bin/x11vnc -forever -usepw -shared -rfbport 5901 -display :1 +autorestart=true +stdout_logfile=/var/log/supervisor/x11vnc.log +stderr_logfile=/var/log/supervisor/x11vnc.log \ No newline at end of file diff --git a/.gitignore b/.gitignore index b9a518a..6371d30 100644 --- a/.gitignore +++ b/.gitignore @@ -83,4 +83,7 @@ cython_debug/ # Logs *.log +# Dev container generated files +.devcontainer/devcontainer.json + output/ diff --git a/README.md b/README.md index 2276731..cdc1ef9 100644 --- a/README.md +++ b/README.md @@ -8,29 +8,55 @@ In the repo there is the simulation server along with a client class that can be ## Setup +### Option 1: Dev Container (Recommended) + +The easiest way to get started is using the provided dev container which includes all dependencies and GUI support: + +1. **Setup the dev container for your platform:** + + ```bash + .devcontainer/setup.sh + ``` + + This will auto-detect your platform (macOS, Linux, Windows, WSL) and generate the appropriate `devcontainer.json`. + +2. **Open in VS Code:** + - Install the "Dev Containers" extension + - Open Command Palette (Cmd/Ctrl + Shift + P) + - Run "Dev Containers: Reopen in Container" + +3. **Platform-specific requirements:** + - **macOS**: Install XQuartz (`brew install --cask xquartz`) and run `xhost +localhost` + - **Linux**: X11 forwarding should work out of the box + - **Windows**: Access GUI via VNC at `http://localhost:5901` (password: `vncpass`) + +### Option 2: Manual Setup + +If you prefer to set up the environment manually: + 1. Create the virtual environment by running: -```bash -python3 -m venv venv -``` + ```bash + python3 -m venv venv + ``` 2. Activate the virtual environment by running: -```bash -source venv/bin/activate -``` + ```bash + source venv/bin/activate + ``` 3. Install the required packages by running: -```bash -pip install -r requirements.txt -``` + ```bash + pip install -r requirements.txt + ``` 4. Export the python path by running: -```bash -export PYTHONPATH=$PWD -``` + ```bash + export PYTHONPATH=$PWD + ``` ## Running the simulation @@ -41,6 +67,6 @@ To run the simulation, run the following command: python tello_sim/run_sim.py ``` -You can try running some of the [examples](./examples) to see how the simulation works. The examples are located in the `examples` folder. +You can try running some of the [examples](./examples) to see how the simulation works. The examples are located in the `examples` folder. Or use the [client](./tello_sim/tello_sim_client.py) class to interact with the simulation server. The client class is located in the `tello_sim` folder. \ No newline at end of file