# syntax=docker/dockerfile:1 # ───────────────────────────────────────────────────────────────────────────── # Raspbot V2 — robot deployment image # # Target: Raspberry Pi 5 (linux/arm64) # Build: docker buildx build --platform linux/arm64 \ # -t raspbot-v2:latest -f Dockerfile.robot . # # Run: docker run --rm -it \ # --network host \ # --device /dev/i2c-1 \ # raspbot-v2:latest # # Override CMD to pass launch arguments, e.g.: # docker run ... raspbot-v2:latest \ # ros2 launch raspbot_v2_hardware hardware.launch.py enable_camera:=false # ───────────────────────────────────────────────────────────────────────────── ARG ROS_DISTRO=kilted # ── Stage 1: build ─────────────────────────────────────────────────────────── FROM ros:${ROS_DISTRO}-ros-base AS builder ARG ROS_DISTRO RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ cmake \ python3-colcon-common-extensions \ python3-rosdep \ ros-${ROS_DISTRO}-hardware-interface \ ros-${ROS_DISTRO}-pluginlib \ ros-${ROS_DISTRO}-rclcpp \ && rm -rf /var/lib/apt/lists/* WORKDIR /ros2_ws # raspbot_v2_sim is intentionally excluded — Gazebo is not needed on the robot COPY src/raspbot_v2_bringup src/raspbot_v2_bringup COPY src/raspbot_v2_control src/raspbot_v2_control COPY src/raspbot_v2_description src/raspbot_v2_description COPY src/raspbot_v2_hardware src/raspbot_v2_hardware COPY src/raspbot_v2_hardware_interface src/raspbot_v2_hardware_interface RUN . /opt/ros/${ROS_DISTRO}/setup.sh \ && sudo apt-get update \ && rosdep update --rosdistro ${ROS_DISTRO} \ && rosdep install --from-paths src --ignore-src -r -y \ && rm -rf /var/lib/apt/lists/* RUN . /opt/ros/${ROS_DISTRO}/setup.sh \ && colcon build \ --cmake-args -DCMAKE_BUILD_TYPE=Release \ --parallel-workers "$(nproc)" # ── Stage 2: runtime ───────────────────────────────────────────────────────── FROM ros:${ROS_DISTRO}-ros-base AS runtime ARG ROS_DISTRO RUN apt-get update && apt-get install -y --no-install-recommends \ # I2C access for Yahboom MCU (motors, LEDs, servos, ultrasonic) python3-smbus \ # ros2_control: controller_manager, hardware_interface, spawner CLI ros-${ROS_DISTRO}-ros2-control \ # Standard controllers: MecanumDriveController, JointStateBroadcaster, # ForwardCommandController (pan/tilt) ros-${ROS_DISTRO}-ros2-controllers \ # URDF/xacro processing and joint-state → TF broadcasting ros-${ROS_DISTRO}-robot-state-publisher \ ros-${ROS_DISTRO}-xacro \ && rm -rf /var/lib/apt/lists/* COPY --from=builder /ros2_ws/install /ros2_ws/install # Entrypoint sources both the ROS underlay and the workspace overlay RUN echo '#!/bin/bash' > /entrypoint.sh \ && echo 'set -e' >> /entrypoint.sh \ && echo "source /opt/ros/${ROS_DISTRO}/setup.bash" >> /entrypoint.sh \ && echo 'source /ros2_ws/install/setup.bash' >> /entrypoint.sh \ && echo 'exec "$@"' >> /entrypoint.sh \ && chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] CMD ["ros2", "launch", "raspbot_v2_hardware", "hardware.launch.py"]