# ============================================================================= # RDC Simulation - Docker Compose (GPU-enabled, Wayland, Multi-Service) # ============================================================================= # Runs the complete simulation stack with 3 services: # 1. gazebo - Gazebo Harmonic simulation # 2. sitl - ArduPilot SITL (ArduCopter) # 3. controller - Python flight controller # # Usage: # # Start all services # docker compose up # # # Or start individually # docker compose up gazebo # docker compose up sitl # docker compose up controller # # # Interactive shell # docker compose run --rm simulation bash # # # Stop everything # docker compose down # ============================================================================= # Common configuration anchor x-common: &common image: rdc-simulation:latest build: context: . dockerfile: Dockerfile # GPU support (NVIDIA) deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [ gpu ] # Environment variables - use XWayland for OpenGL compatibility environment: # X11/XWayland display (better for OpenGL in containers) &common-env - DISPLAY=${DISPLAY:-:0} - XDG_RUNTIME_DIR=/run/user/1000 # GPU - NVIDIA_VISIBLE_DEVICES=all - NVIDIA_DRIVER_CAPABILITIES=all # Force X11/XCB for Qt (more stable for OpenGL than native Wayland) - QT_QPA_PLATFORM=xcb - QT_X11_NO_MITSHM=1 # OpenGL settings - __GLX_VENDOR_LIBRARY_NAME=nvidia - LIBGL_ALWAYS_SOFTWARE=0 # Gazebo paths - GZ_SIM_SYSTEM_PLUGIN_PATH=/home/pilot/ardupilot_gazebo/build - GZ_SIM_RESOURCE_PATH=/home/pilot/ardupilot_gazebo/models:/home/pilot/ardupilot_gazebo/worlds:/home/pilot/RDC_Simulation/gazebo/models # Mount Wayland and X11 sockets volumes: # Wayland socket - ${XDG_RUNTIME_DIR:-/run/user/1000}/${WAYLAND_DISPLAY:-wayland-0}:/run/user/1000/wayland-0:rw # X11 socket (for XWayland fallback) - /tmp/.X11-unix:/tmp/.X11-unix:rw # GPU device - /dev/dri:/dev/dri:rw # Network mode for SITL communication (all services share host network) network_mode: host # Run as user with access to Wayland socket user: "1000:1000" stdin_open: true tty: true working_dir: /home/pilot/RDC_Simulation services: # ========================================================================= # Interactive Shell (for manual control) # ========================================================================= simulation: <<: *common container_name: rdc-sim entrypoint: [ "/home/pilot/docker-entrypoint.sh" ] command: [ "bash" ] # ========================================================================= # Service 1: Gazebo Simulation # ========================================================================= gazebo: <<: *common container_name: rdc-gazebo entrypoint: [ "/bin/bash", "-c" ] command: - | source /opt/ros/jazzy/setup.bash source ~/.bashrc echo "Starting Gazebo Harmonic..." echo "Waiting 5 seconds for initialization..." sleep 5 cd /home/pilot/RDC_Simulation ./scripts/run_ardupilot_sim.sh runway # ========================================================================= # Service 2: ArduPilot SITL # ========================================================================= sitl: <<: *common container_name: rdc-sitl depends_on: gazebo: condition: service_started entrypoint: [ "/bin/bash", "-c" ] command: - | source /opt/ros/jazzy/setup.bash source ~/.bashrc echo "Waiting 15 seconds for Gazebo to start..." sleep 15 echo "Starting ArduPilot SITL..." cd /home/pilot/ardupilot sim_vehicle.py -v ArduCopter -f gazebo-iris --model JSON --console --no-mavproxy # ========================================================================= # Service 3: Flight Controller # ========================================================================= controller: <<: *common container_name: rdc-controller depends_on: sitl: condition: service_started entrypoint: [ "/bin/bash", "-c" ] command: - | source /opt/ros/jazzy/setup.bash source ~/.bashrc source /home/pilot/RDC_Simulation/venv/bin/activate echo "Waiting 30 seconds for SITL to initialize..." sleep 30 echo "Starting flight controller..." cd /home/pilot/RDC_Simulation python scripts/run_ardupilot.py --pattern square # ========================================================================= # Headless Mode (CI/Server - no display) # ========================================================================= simulation-headless: <<: *common container_name: rdc-sim-headless user: "1000:1000" environment: - NVIDIA_VISIBLE_DEVICES=all - NVIDIA_DRIVER_CAPABILITIES=compute,utility - HEADLESS=1 - LIBGL_ALWAYS_SOFTWARE=1 - GZ_SIM_SYSTEM_PLUGIN_PATH=/home/pilot/ardupilot_gazebo/build - GZ_SIM_RESOURCE_PATH=/home/pilot/ardupilot_gazebo/models:/home/pilot/ardupilot_gazebo/worlds:/home/pilot/RDC_Simulation/gazebo/models volumes: [] # No display mounts needed entrypoint: [ "/home/pilot/docker-entrypoint.sh" ] command: [ "bash" ] # ========================================================================= # All-in-One (runs everything in one container) # ========================================================================= all-in-one: <<: *common container_name: rdc-all entrypoint: [ "/bin/bash", "-c" ] command: - | source /opt/ros/jazzy/setup.bash source ~/.bashrc source /home/pilot/RDC_Simulation/venv/bin/activate cd /home/pilot/RDC_Simulation echo "Starting all-in-one simulation..." ./scripts/run_ardupilot_controller.sh