diff --git a/.ccache/.gitkeep b/.ccache/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.env b/.env new file mode 100644 index 00000000..18dbe78b --- /dev/null +++ b/.env @@ -0,0 +1,16 @@ +# Defaults for the MoveIt Studio docker compose agent services. + +# Robot configuration package to launch +STUDIO_CONFIG_PACKAGE=picknik_ur_mock_hw_config + +# MoveIt Studio version tag +# Be careful! Changing this without understanding the consequences may break your installation. +STUDIO_DOCKER_TAG=2.6.0 + +# Licensing -- enter your MoveIt Studio license below +STUDIO_LICENSE_KEY= + +# User name and UID to use when building the container +# Ensure these settings match your host environment for mounted file permissions. +STUDIO_USERNAME= +STUDIO_USER_UID= diff --git a/.gitignore b/.gitignore index 13456571..9f859681 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.ccache/ build/ install/ log/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..9b0f39e4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,116 @@ +# Docker image for extending MoveIt Studio with a custom overlay. +# +# Example build command (with defaults): +# +# docker build -f ./Dockerfile . +# + +# Specify the MoveIt Studio release to build on top of. +ARG MOVEIT_STUDIO_BASE_IMAGE +ARG USERNAME=studio-user +ARG USER_UID=1000 +ARG USER_GID=1000 + +##################################################### +# Starting from the specified MoveIt Studio release # +##################################################### +# The image tag is specified in the argument itself. +# hadolint ignore=DL3006 +FROM ${MOVEIT_STUDIO_BASE_IMAGE} as base + +# hadolint ignore=DL3002 +USER root + +# Copy source code from the workspace's ROS 2 packages to a workspace inside the container +ARG USER_OVERLAY_WS=/opt/user_overlay_ws +ENV USER_OVERLAY_WS $USER_OVERLAY_WS +RUN mkdir -p ${USER_OVERLAY_WS}/src ${USER_OVERLAY_WS}/build ${USER_OVERLAY_WS}/install ${USER_OVERLAY_WS}/log +COPY ./src ${USER_OVERLAY_WS}/src + +# Create a non-root user +ARG USERNAME +ARG USER_UID +ARG USER_GID + +# Also mkdir with user permission directories which will be mounted later to avoid docker creating them as root +WORKDIR $USER_OVERLAY_WS +# hadolint ignore=DL3008 +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + groupadd --gid $USER_GID ${USERNAME} && \ + useradd --uid $USER_UID --gid $USER_GID --shell /bin/bash --create-home ${USERNAME} && \ + apt-get update && \ + apt-get install -q -y --no-install-recommends sudo && \ + echo ${USERNAME} ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/${USERNAME} && \ + chmod 0440 /etc/sudoers.d/${USERNAME} && \ + mkdir -p \ + /home/${USERNAME}/.ccache \ + /home/${USERNAME}/.config \ + /home/${USERNAME}/.ignition \ + /home/${USERNAME}/.ros/log && \ + chown -R $USER_UID:$USER_GID /home/${USERNAME} ${USER_OVERLAY_WS} /opt/overlay_ws/ + +# Install additional dependencies +# You can also add any necessary apt-get install, pip install, etc. commands at this point. +# NOTE: The /opt/overlay_ws folder contains MoveIt Studio binary packages and the source file. +# hadolint ignore=SC1091 +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + . /opt/overlay_ws/install/setup.sh && \ + apt-get update && \ + rosdep install -q -y \ + --from-paths src \ + --ignore-src + +# Remove .bashrc from parent image and create a new one +USER ${USERNAME} +RUN rm /home/${USERNAME}/.bashrc && touch /home/${USERNAME}/.bashrc + +######################################### +# Target for compiled, deployable image # +######################################### +FROM base as user-overlay + +ARG USERNAME +USER ${USERNAME} + +# Compile the workspace +# hadolint ignore=SC1091 +RUN --mount=type=cache,target=/home/studio-user/.ccache \ + . /opt/overlay_ws/install/setup.sh && \ + colcon build + +# Add the custom entrypoint +COPY ./entrypoint.sh /entrypoint.sh +ENTRYPOINT ["/entrypoint.sh"] +RUN echo "source /entrypoint.sh && set +e" >> ~/.bashrc +CMD ["/usr/bin/bash"] + +################################################################### +# Target for the developer build which does not compile any code. # +################################################################### +FROM base as user-overlay-dev + +USER root + +# The location of the user's workspace inside the container +ARG USER_OVERLAY_WS=/opt/user_overlay_ws +ENV USER_OVERLAY_WS $USER_OVERLAY_WS + +# Install any additional packages for development work +# hadolint ignore=DL3008 +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ + --mount=type=cache,target=/var/lib/apt,sharing=locked \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + less \ + gdb \ + nano + +# Add the dev entrypoint +ARG USERNAME +USER ${USERNAME} +COPY ./entrypoint.sh /entrypoint.sh +ENTRYPOINT ["/entrypoint.sh"] +RUN echo "source /entrypoint.sh && set +e" >> ~/.bashrc +CMD ["/usr/bin/bash"] diff --git a/build/.gitkeep b/build/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 00000000..3f6026fb --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,125 @@ +# Docker Compose file for user overlays of the MoveIt Studio images. + +version: "3.9" + +services: + # Sets common properties for other services. Should not be instantiated directly. + base: + # Extend the installed MoveIt Studio docker compose file. + # Change this to match your environment, if MoveIt Studio was installed to a different location. + extends: + file: ${HOME}/moveit_studio/docker-compose.yaml + service: base + image: moveit-studio-overlay + build: + context: . + target: user-overlay + args: + - USER_UID=${STUDIO_USER_UID:-1000} + - USER_GID=${STUDIO_USER_UID:-1000} + - USERNAME=${USERNAME:-studio-user} + - MOVEIT_STUDIO_BASE_IMAGE=picknikciuser/moveit-studio:${STUDIO_DOCKER_TAG:-main} + + # Starts the MoveIt Studio Agent + agent: + extends: base + privileged: true + # Allow the user to use the host's network video4linux and usb_device devices. + # "c 81:* rmw": This rule specifies that the container has read, write, and mknod access (rmw) to all character devices (c) with a major number of 81 (video4linux). + # "c 189:* rmw": This rule gives the container read, write, and mknod access (rmw) to all character devices (c) with a major number of 189 (usb_device). + device_cgroup_rules: + - "c 81:* rmw" + - "c 189:* rmw" + depends_on: + rest_api: + condition: service_healthy + volumes: + # Allow the user to run graphical programs from within the docker container. + - /tmp/.X11-unix:/tmp/.X11-unix:ro + # Allow access to host hardware e.g. RealSense cameras + - /dev:/dev + # TODO: replace this tee here and in common_aliases with some integrated logger + command: bash -c "ros2 launch moveit_studio_agent studio_agent.launch.py 2>&1 | tee -a ~/.ros/log/agent_0_0.log" + + # Starts the Bridge between the Agent and the Web UI + bridge: + extends: base + depends_on: + agent: + condition: service_started + # TODO: replace this tee here and in common_aliases with some integrated logger + command: bash -c "ros2 launch moveit_studio_bridge studio_bridge.launch.py 2>&1 | tee -a ~/.ros/log/bridge_0_0.log" + + # Starts the frontend-agent + frontend_agent: + extends: base + command: /usr/lib/formant/agent/formant-agent + + # Starts the REST API for the Web UI + rest_api: + extends: base + healthcheck: + test: "curl -f http://localhost:3200/objectives" + interval: 5s + timeout: 1m + # TODO: replace this tee here and in common_aliases with some integrated logger + command: bash -c "ros2 launch moveit_studio_rest_api rest_api.launch.py 2>&1 | tee -a ~/.ros/log/rest_api_0_0.log" + + # Starts the robot drivers + drivers: + extends: base + privileged: true + # Ensures the drivers container has RT priority + ulimits: + rtprio: 99 + devices: + - "/dev/ttyUSB0:/dev/ttyUSB0" # Allow access to the gripper. + # TODO: replace this tee here and in common_aliases with some integrated logger + command: bash -c "ros2 launch moveit_studio_agent robot_drivers.launch.py 2>&1 | tee -a ~/.ros/log/robot_0_0.log" + + web_ui: + image: picknikciuser/moveit-studio-frontend:${STUDIO_DOCKER_TAG:-main} + ports: + - "80:80" + network_mode: host + + # Starts RViz for visualization. + rviz: + extends: base + profiles: + - rviz + command: bash -c "ros2 launch moveit_studio_agent developer_rviz.launch.py" + + # Starts MoveIt Setup Assistant for creating MoveIt configurations. + setup_assistant: + extends: base + profiles: + - setup_assistant + command: bash -c "ros2 launch moveit_setup_assistant setup_assistant.launch.py" + + # Developer specific configuration + dev: + extends: base + build: + target: user-overlay-dev + image: moveit-studio-overlay-dev + stdin_open: true + tty: true + privileged: true + volumes: + # Mount the source code, colcon generated artifacts, and ccache + - ./src/:/opt/user_overlay_ws/src:rw + - ./build/:/opt/user_overlay_ws/build:rw + - ./install/:/opt/user_overlay_ws/install:rw + - ./log/:/opt/user_overlay_ws/log:rw + - ./.ccache/:/home/${USERNAME:-studio-user}/.ccache:rw + - ${HOME}/.ros/log_moveit_studio:/root/.ros/log:/root/.ros/log + # Allow access to host hardware e.g. RealSense cameras + - /dev:/dev + command: sleep infinity + # Making a separate profile prevents this service from being built when using `docker compose build` + # and launched when using `docker compose up`. + profiles: ["dev"] + +volumes: + ignition_resources: diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 00000000..eceb6b23 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Custom entrypoint to start when running an image that overlays MoveIt Studio + +set +e + +# Source the MoveIt Studio binaries and your workspace +source "/opt/overlay_ws/install/setup.bash" +if [ -f "${USER_OVERLAY_WS}/install/local_setup.bash" ]; then + source "${USER_OVERLAY_WS}/install/local_setup.bash" +fi + +# Set the location for custom Behavior package generation +export STUDIO_GENERATE_PACKAGE_OUTPUT_PATH="${USER_OVERLAY_WS}/src" + +# Set the permissions for your non-root user at startup. +# shellcheck source=bin/docker/utils/change_permissions.sh +source /moveit_studio_utils/change_permissions.sh + +# Set the DDS configuration for ROS 2 inter-process communication. +# shellcheck source=bin/docker/utils/copy_dds_configs.sh +source /moveit_studio_utils/copy_dds_configs.sh + +exec "$@" diff --git a/install/.gitkeep b/install/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/log/.gitkeep b/log/.gitkeep new file mode 100644 index 00000000..e69de29b