# Launch MoveIt Pro
# Notes on usage:
# Several environment variables can be set on the host to configure the containers.
# The variables are documented in the `environment:` section of the `base` service.
# The recommended method for overriding these variables is by setting them in your .env file,
# or setting them in your shell configuration if you are sharing configurations your custom applications and MoveIt Pro.

version: "3.9"

services:
  # Sets common properties for other services. Should not be instantiated directly.
  base:
    # We assume the user has a user workspace and that user workspace contains a Dockerfile with a target layer called "user-overlay"
    # As per these docs:
    # https://docs.picknik.ai/en/main/getting_started/configuration_tutorials/docker_configuration/create_overlay_docker_image.html#creating-a-release-overlay-container
    # MOVEIT_STUDIO_BASE_IMAGE: The image and tag to where the user overlay will start FROM
    # STUDIO_DOCKER_TAG: Version to pull from Docker Hub, e.g. "v1.10". Defaults to "main".
    # The following args ensure log files aren't owned by root
    # STUDIO_USERNAME: the username on the host
    # STUDIO_USER_UID: the user uid on the host
    # STDUIO_USER_GID: the user gid on the host
    build:
      dockerfile: ${STUDIO_HOST_USER_WORKSPACE}/Dockerfile
      context: ${STUDIO_HOST_USER_WORKSPACE}
      target: base
      args:
        USERNAME: ${STUDIO_USERNAME}
        USER_UID: ${STUDIO_USER_UID}
        USER_GID: ${STUDIO_USER_GID}
        MOVEIT_STUDIO_BASE_IMAGE: picknikciuser/moveit-studio:${STUDIO_DOCKER_TAG:-main}
    network_mode: host
    # Run an init process within the container to allow using default signal handling to cleanly shut down the container.
    # See this doc for more info: https://docs.docker.com/compose/compose-file/compose-file-v3/#init
    init: true
    environment:
      # The default for MoveIt Pro will use mock hardware, if available, to simulate the robot.
      - MOCK_HARDWARE=${MOCK_HARDWARE:-true}
      # The ROS domain ID to use in deployment. See https://docs.ros.org/en/humble/Concepts/About-Domain-ID.html
      - ROS_DOMAIN_ID
      # Provides a license key for the MoveIt Pro application to validate in the container.
      - STUDIO_LICENSE_KEY
      # Robot configuration package for deployment. Defaults to a mock hardware UR5e.
      - STUDIO_CONFIG_PACKAGE=${STUDIO_CONFIG_PACKAGE:-picknik_ur_mock_hw_config}
      # The directory on the host machine where MoveIt Pro configurations should be saved, such as new objectives.
      # Typically, this is "$HOME/.config/moveit_pro", which is the default.
      # Individual robot configuration packages will be stored in this folder.
      - STUDIO_HOST_CONFIG_DIR=${STUDIO_HOST_CONFIG_DIR:-$HOME/.config/moveit_pro}
      # The directory on the host machine where persistent MoveIt Pro data is stored, e.g. the frontend authentication data.
      # Typically, this is "$HOME/.local/share/moveit_pro", which is the default.
      - STUDIO_HOST_DATA_DIR=${STUDIO_HOST_DATA_DIR:-$HOME/.local/share/moveit_pro}
      # The path to the colcon workspace on the host machine containing user-defined packages,
      # containing, e.g., configuration packages and custom behaviors
      # Defaults to a folder named "moveit_studio_ws" in the current directory.
      # If this folder is blank, it will be ignored at container startup.
      - STUDIO_HOST_USER_WORKSPACE=${STUDIO_HOST_USER_WORKSPACE:-./moveit_studio_ws}
      # The location of the user workspace inside the Docker container
      - USER_WS=/home/${STUDIO_USERNAME:-studio-user}/user_ws/
      # Network interface to use in the generated DDS configuration (in the container). Defaults to "lo".
      - CYCLONEDDS_NETWORK_INTERFACE=${CYCLONEDDS_NETWORK_INTERFACE:-lo}
      # Comma-separated list of the IP addresses of machines that will participate in the ROS network,
      # including the host machine's own IP address. For example: CYCLONEDDS_PEER_ADDRESSES=192.168.0.35,192.168.0.37)
      # Defaults to "127.0.0.1"
      - CYCLONEDDS_PEER_ADDRESSES=${CYCLONEDDS_PEER_ADDRESSES:-127.0.0.1}
      - CYCLONEDDS_USE_MULTICAST=${CYCLONEDDS_USE_MULTICAST:-false}
      # The ROS middleware to use. Defaults to rmw_cyclonedds_cpp, the CycloneDDS middleware.
      # MoveIt Pro supports CycloneDDS and FastRTPS, and will respect your CYCLONEDDS_URI and FASTRTPS_DEFAULT_PROFILES_FILE for custom configurations.
      - RMW_IMPLEMENTATION=${RMW_IMPLEMENTATION:-rmw_cyclonedds_cpp}
      # If using FastRTPS, setting this variable to 1 allows modifying Quality-of-Service (QoS) settings from a specified XML file.
      - RMW_FASTRTPS_USE_QOS_FROM_XML
      # Renderer used for Gazebo (can be ogre or ogre2)
      - GAZEBO_RENDERER=${GAZEBO_RENDERER:-ogre}
      # Allow the user to run graphical programs from within the container. You probably don't want to change these!
      - DISPLAY
      - QT_X11_NO_MITSHM=1
      # User settings
      - USER_UID=${STUDIO_USER_UID:-1000}
      - USERNAME=${STUDIO_USERNAME:-studio-user}
      # If USE_HOST_DDS=true, MoveIt Pro will replicate the host DDS configuration files.
      - USE_HOST_DDS=${USE_HOST_DDS:-false}
    volumes:
      - ${HOME}/.ros/log_moveit_pro:/home/${STUDIO_USERNAME:-studio-user}/.ros/log
      - ${STUDIO_HOST_CONFIG_DIR:-$HOME/.config/moveit_pro}:/home/${STUDIO_USERNAME:-studio-user}/.config/moveit_pro/:rw
      - ${STUDIO_HOST_DATA_DIR:-$HOME/.local/share/moveit_pro}:/home/${STUDIO_USERNAME:-studio-user}/.local/share/moveit_pro/:rw
      - ${STUDIO_HOST_USER_WORKSPACE:-./moveit_studio_ws}:/home/${STUDIO_USERNAME:-studio-user}/user_ws/:rw
      # Persist Ignition model download cache
      - ignition_resources:/home/${STUDIO_USERNAME:-studio-user}/.ignition/
      # Mount the host's DDS config(s) so we can talk to user's ROS tooling
      - ${CYCLONEDDS_URI:-/dev/null}:/home/${STUDIO_USERNAME:-studio-user}/.ros/cyclonedds_host.xml
      - ${FASTRTPS_DEFAULT_PROFILES_FILE:-/dev/null}:/home/${STUDIO_USERNAME:-studio-user}/.ros/fastdds_host.xml

  # Builds the user workspace. If STUDIO_HOST_USER_WORKSPACE is empty, this service will do nothing.
  workspace_builder:
    extends: base
    profiles:
      - build_and_test
    command: bash -c "source /moveit_studio_utils/build_user_ws.sh"

  # Executes tests for the user workspace. If STUDIO_HOST_USER_WORKSPACE is empty, this service will do nothing.
  workspace_test:
    container_name: "moveit_studio_workspace_test"
    extends: base
    depends_on:
      workspace_builder:
        condition: service_completed_successfully
    profiles:
      - build_and_test
    command: bash -c "source /moveit_studio_utils/test_user_ws.sh"

  # Starts the MoveIt Pro Agent and Bridge between the Agent and the Web UI
  agent_bridge:
    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"
    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
    deploy:
      restart_policy:
        condition: any
        delay: 2s
    command: agent_bridge.app

  # Starts the REST API for the Web UI
  rest_api:
    extends: base
    depends_on:
      - agent_bridge
    healthcheck:
      test: "curl -f http://localhost:3200/objectives"
      interval: 5s
      timeout: 1m
    command: rest_api.app

  # 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.
    command: robot.app

  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"

  rqt_console:
    extends: base
    profiles:
      - logs
    command: bash -c "ros2 run rqt_console rqt_console"

volumes:
  ignition_resources:
