diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile.base similarity index 56% rename from .devcontainer/Dockerfile rename to .devcontainer/Dockerfile.base index 14ff64d1f81449d3436a6d518e62dee9b7947682..c257ee615dc32afdd16afcbc6d511e9b895ff273 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile.base @@ -3,8 +3,6 @@ FROM osrf/ros:humble-desktop SHELL ["/bin/bash", "-c"] ENV RCUTILS_COLORIZED_OUTPUT=1 -ENV CMAKE_BUILD_TYPE=RelWithDebInfo - # Install required packages RUN --mount=type=cache,sharing=locked,target=/var/cache/apt \ @@ -13,49 +11,54 @@ RUN --mount=type=cache,sharing=locked,target=/var/cache/apt \ apt-get update \ && apt-get upgrade -y \ && apt-get install -qqy --no-install-recommends \ - # general dependencies - bash-completion \ - build-essential \ - clang-format \ - cmake \ - gdb \ - git \ - htop \ - nano \ - iputils-ping \ - net-tools \ - sudo \ - wget \ - vim \ - # libfranka dependencies - libpoco-dev \ - libeigen3-dev \ - # python dependencies - python-is-python3 \ - python3-flake8 \ - python3-pip \ - python3-setuptools \ - # ros dependencies - ros-$ROS_DISTRO-rmw-fastrtps-cpp \ - ros-$ROS_DISTRO-rmw-cyclonedds-cpp \ - ros-$ROS_DISTRO-plotjuggler \ - ros-$ROS_DISTRO-plotjuggler-ros \ - ros-dev-tools \ + # general dependencies + bash-completion \ + build-essential \ + clang \ + clang-format \ + cmake \ + ninja-build \ + gdb \ + git \ + htop \ + nano \ + iputils-ping \ + net-tools \ + sudo \ + wget \ + vim \ + unzip \ + # OpenMP + libomp-dev \ + # python dependencies + python-is-python3 \ + python3-flake8 \ + python3-pip \ + python3-setuptools \ + python-is-python3 \ + python3-dev \ + python3-numpy \ + python3-scipy \ + # ROS 2 dependencies + ros-$ROS_DISTRO-rmw-fastrtps-cpp \ + ros-$ROS_DISTRO-rmw-cyclonedds-cpp \ + ros-$ROS_DISTRO-plotjuggler \ + ros-$ROS_DISTRO-plotjuggler-ros \ + ros-dev-tools \ && python -m pip install -U \ - argcomplete \ - pre-commit + argcomplete \ + pre-commit -# Add robotpkg dependency RUN mkdir -p /etc/apt/keyrings \ && curl http://robotpkg.openrobots.org/packages/debian/robotpkg.asc \ - | tee /etc/apt/keyrings/robotpkg.asc \ + | tee /etc/apt/keyrings/robotpkg.asc \ && echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/robotpkg.asc] http://robotpkg.openrobots.org/packages/debian/pub $(lsb_release -cs) robotpkg" \ - | tee /etc/apt/sources.list.d/robotpkg.list + | tee /etc/apt/sources.list.d/robotpkg.list ENV PATH=/opt/openrobots/bin:${PATH} ENV PKG_CONFIG_PATH=/opt/openrobots/lib/pkgconfig:${PKG_CONFIG_PATH} ENV LD_LIBRARY_PATH=/opt/openrobots/lib:${LD_LIBRARY_PATH} -ENV PYTHONPATH=/opt/openrobots/lib/python3.10/site-packages:${PYTHONPATH} +ENV PYTHONPATH=/usr/local/lib/python3.10/site-packages:/opt/openrobots/lib/python3.10/site-packages:${PYTHONPATH} ENV CMAKE_PREFIX_PATH=/opt/openrobots:${CMAKE_PREFIX_PATH} # Create the user @@ -73,9 +76,8 @@ RUN mkdir /commandhistory \ USER gepetto WORKDIR /home/gepetto/ros2_ws +# Change compilation defaults to enable a bit more efficient preserving portability +ENV CMAKE_BUILD_TYPE=RelWithDebInfo +ENV CMAKE_CXX_FLAGS="-O3" +# Set default DDS implementation ENV RMW_IMPLEMENTATION=rmw_fastrtps_cpp - -RUN echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> /home/gepetto/.bashrc \ - && echo "source /home/gepetto/ros2_ws/install/setup.bash" >> /home/gepetto/.bashrc \ - && echo "source /usr/share/ignition/setup.sh" >> /home/gepetto/.bashrc \ - && echo "source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash" >> /home/gepetto/.bashrc diff --git a/.devcontainer/control/Dockerfile b/.devcontainer/control/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..9c37c86f82692f710891d72783e7eca07e3b778f --- /dev/null +++ b/.devcontainer/control/Dockerfile @@ -0,0 +1,117 @@ +ARG AGIMUS_DOCKER_BASE_IMAGE=gitlab.laas.fr:4567/agimus-project/agimus_dev_container:humble-devel-base +FROM $AGIMUS_DOCKER_BASE_IMAGE + +# Install required packages +RUN --mount=type=cache,sharing=locked,target=/var/cache/apt \ + --mount=type=cache,sharing=locked,target=/var/lib/apt \ + --mount=type=cache,sharing=locked,target=/root/.cache \ + sudo apt-get update \ + && sudo apt-get install -qqy --no-install-recommends \ + # libfranka dependencies + libpoco-dev \ + # ROS 2 dependencies + ros-$ROS_DISTRO-ros-gz \ + # Crocoddyl dependencies + coinor-libipopt-dev \ + libassimp-dev \ + libboost-all-dev \ + libeigen3-dev \ + liboctomap-dev \ + libqhull-dev \ + libtinyxml-dev \ + liburdfdom-dev \ + # ProxSuite dependencies + libsimde-dev \ + libmatio-dev \ + # HPP dependencies + omniidl \ + libomniorb4-dev \ + robotpkg-collada-dom \ + robotpkg-omniorb \ + robotpkg-openscenegraph \ + robotpkg-py310-omniorbpy \ + robotpkg-py310-ros-catkin \ + robotpkg-qpoases \ + robotpkg-qt5-osgqt \ + robotpkg-qt5-qgv + +# Build libfranka +RUN git clone -b active-control-backport --recursive https://github.com/agimus-project/libfranka.git \ + && cmake -B build -S libfranka -DBUILD_TESTS=OFF \ + && cmake --build build \ + && sudo cmake --install build \ + && rm -rf libfranka build + +# Install all dependencies up to Crocoddyl system-wise +WORKDIR /home/gepetto/dependencies +ADD install_dependency.sh /home/gepetto/dependencies/install_dependency.sh +RUN bash install_dependency.sh stack-of-tasks/eigenpy/v3.10.0/1 \ + && bash install_dependency.sh coal-library/coal/v3.0.0/1 \ + && bash install_dependency.sh stack-of-tasks/pinocchio/v3.3.0/1 \ + && bash install_dependency.sh gepetto/example-robot-data/v4.1.0/1 \ + && bash install_dependency.sh loco-3d/crocoddyl/v2.1.0/1 \ + && bash install_dependency.sh machines-in-motion/mim_solvers/devel/1 \ + && bash install_dependency.sh agimus-project/colmpc/main/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-util/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-template-corba/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-statistics/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-environments/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-pinocchio/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-constraints/v6.0.0/1 \ + && bash install_dependency.sh Simple-Robotics/proxsuite/devel/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-core/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-corbaserver/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-manipulation/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-manipulation-urdf/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-manipulation-corba/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/gepetto-viewer/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/gepetto-viewer-corba/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-gepetto-viewer/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-plot/v6.0.0/1 \ + && bash install_dependency.sh humanoid-path-planner/hpp-gui/v6.0.0/1 \ + && bash install_dependency.sh florent-lamiraux/hpp-bin-picking/devel/1 \ + # Remove folders with meshes and binary data to reduce image size + && rm -rf example-robot-data \ + && rm -rf pinocchio/models \ + && rm -rf proxsuite/test/data + +ENV PATH=/usr/local/bin:${PATH} +ENV LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH} +ENV PYTHONPATH=/usr/local/lib/python3.10/site-packages:${PYTHONPATH} +ENV CMAKE_PREFIX_PATH=/usr/local:${CMAKE_PREFIX_PATH} +ENV AMENT_PREFIX_PATH=/usr/local + +# Install ROS dependencies for Franka ROS +WORKDIR /home/gepetto/franka_deps_ws +RUN --mount=type=cache,sharing=locked,target=/var/cache/apt \ + --mount=type=cache,sharing=locked,target=/var/lib/apt \ + --mount=type=cache,sharing=locked,target=/root/.cache \ + sudo apt-get update \ + && mkdir src \ + # Clone required repositories + && git clone --branch humble_devel https://github.com/agimus-project/franka_description.git src/franka_description \ + && git clone --branch v0.1.15 https://github.com/agimus-project/franka_ros2.git src/franka_ros2 \ + # Remplace new libfranka version with old one + && find src/franka_ros2 -type f -name 'CMakeLists.txt' | xargs sed -i 's/find_package(Franka 0.13.* REQUIRED)/find_package(Franka 0.9.3 REQUIRED)/' \ + # Build packages from source + && source /opt/ros/$ROS_DISTRO/setup.bash \ + && rosdep update --rosdistro $ROS_DISTRO \ + && rosdep install -y -i --from-paths src --rosdistro $ROS_DISTRO \ + --skip-keys libfranka \ + --skip-keys eigenpy \ + --skip-keys hpp-fcl \ + --skip-keys coal \ + --skip-keys pinocchio \ + --skip-keys crocoddyl \ + && colcon build \ + # Remove unused folders + && rm -rf build log src + +# Install ROS dependencies for Franka ROS +WORKDIR /home/gepetto/ros2_ws + +RUN echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> /home/gepetto/.bashrc \ + && echo "source /home/gepetto/franka_deps_ws/install/setup.bash" >> /home/gepetto/.bashrc \ + && echo "source /home/gepetto/ros2_ws/install/setup.bash" >> /home/gepetto/.bashrc \ + && echo "source /usr/share/ignition/setup.sh" >> /home/gepetto/.bashrc \ + && echo "source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash" >> /home/gepetto/.bashrc diff --git a/.devcontainer/devcontainer.json b/.devcontainer/control/devcontainer.json similarity index 76% rename from .devcontainer/devcontainer.json rename to .devcontainer/control/devcontainer.json index 5113bd60d68a63419d8dd347bdfbc8f2d039efde..fa0b5aa33aa1f0f87a08d145b03b05cdf887ddbf 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/control/devcontainer.json @@ -5,16 +5,16 @@ // "dockerfile": "Dockerfile", // "context": "." // }, - "image": "gitlab.laas.fr:4567/kwojciecho/gepetto-dev-container:humble", - // chmod is a dirty walkaround to a problem with access rights of the user in docker - "initializeCommand": "xhost +local:docker && sudo chmod 777 /dev/dri/*", + "image": "gitlab.laas.fr:4567/agimus-project/agimus_dev_container:humble-devel-control", + "initializeCommand": "xhost +local:docker", "containerEnv": { "DISPLAY": "${localEnv:DISPLAY}", - "QT_X11_NO_MITSHM": "1" - // Uncomment to enable GUI applications to be rendered with GPU - // "NVIDIA_DRIVER_CAPABILITIES": "all", - // "__NV_PRIME_RENDER_OFFLOAD": "1", - // "__GLX_VENDOR_LIBRARY_NAME": "nvidia" + "QT_X11_NO_MITSHM": "1", + // NVIDIA related ENV variables make no difference + // in case no discrete GPU is present in the system + "NVIDIA_DRIVER_CAPABILITIES": "all", + "__NV_PRIME_RENDER_OFFLOAD": "1", + "__GLX_VENDOR_LIBRARY_NAME": "nvidia" }, "remoteUser": "gepetto", "privileged": true, @@ -37,8 +37,8 @@ "type": "bind" }, { - "source": "${localEnv:XAUTHORITY}", - "target": "${localEnv:XAUTHORITY}", + "source": "/dev/dri", + "target": "/dev/dri", "type": "bind" }, // Presist bash history @@ -52,8 +52,8 @@ "workspaceFolder": "/home/gepetto/ros2_ws/src", "workspaceMount": "source=${localWorkspaceFolder},target=/home/gepetto/ros2_ws/src,type=bind,consistency=cached", "runArgs": [ - "--network=host", - "--ipc=host" + "--ipc=host", + "--net=host" ], "hostRequirements": { "gpu": "optional" @@ -81,7 +81,8 @@ "ajshort.msg", "xaver.clang-format", "njpwerner.autodocstring", - "cschlosser.doxdocgen" + "cschlosser.doxdocgen", + "streetsidesoftware.code-spell-checker" ] } } diff --git a/.devcontainer/control/install_dependency.sh b/.devcontainer/control/install_dependency.sh new file mode 100755 index 0000000000000000000000000000000000000000..5cc68ee75db8b03c83ee0a51d5c827879c785fbb --- /dev/null +++ b/.devcontainer/control/install_dependency.sh @@ -0,0 +1,39 @@ +#!/bin/bash -eux + +CMAKE_PREFIX_PATH=${1:-$PWD/install} + +export CMAKE_PREFIX_PATH + +IFS="/" read -r -a split <<< "$1" +ORG="${split[0]}" +PRJ="${split[1]}" +TAG="${split[2]}" +CORES="${split[3]}" + +git clone --branch "$TAG" --recursive "https://github.com/$ORG/$PRJ" +cmake -B "$PRJ/build" -S "$PRJ" \ + -DPYTHON_EXECUTABLE=/usr/bin/python3 \ + -DPYTHON_SITELIB=/usr/local/lib/python3.10/site-packages \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DPYTHON_STANDARD_LAYOUT=OFF \ + -DPYTHON_DEB_LAYOUT=OFF \ + -DBUILD_TESTING=OFF \ + -DBUILD_BENCHMARK=OFF \ + -DBUILD_BENCHMARKS=OFF \ + -DBUILD_EXAMPLES=OFF \ + -DINSTALL_DOCUMENTATION=OFF \ + -DBUILD_PYTHON_INTERFACE=ON \ + -DGENERATE_PYTHON_STUBS=OFF \ + -DCOAL_BACKWARD_COMPATIBILITY_WITH_HPP_FCL=ON \ + -DCOAL_HAS_QHULL=ON \ + -DBUILD_WITH_COLLISION_SUPPORT=ON \ + -DPROJECT_USE_QT4=OFF \ + -DUSE_QPOASES=OFF \ + -DBUILD_WITH_MULTITHREADS=ON \ + -DBUILD_WITH_VECTORIZATION_SUPPORT=ON \ + -Wno-dev +cmake --build "$PRJ/build" -j $CORES +sudo cmake --build "$PRJ/build" -t install +# Removing those files reduces size of the docker by 1.2 Gb +# This makes it is worth the sacrifice of git history +sudo rm -rf "$PRJ/build" "$PRJ/cmake" "$PRJ/.git" diff --git a/.devcontainer/scripts/setup.sh b/.devcontainer/scripts/setup.sh index 9a9d6e2bde26d1138ad19a37f6e584cc1cdf9af2..ac07ef42e5a5be94fb40526ac0cd38de646cef69 100755 --- a/.devcontainer/scripts/setup.sh +++ b/.devcontainer/scripts/setup.sh @@ -9,4 +9,29 @@ rosdep update --rosdistro $ROS_DISTRO rosdep install -y -i \ --from-paths src \ --rosdistro $ROS_DISTRO \ - --skip-keys libfranka + --skip-keys libfranka \ + --skip-keys eigenpy \ + --skip-keys hpp-fcl \ + --skip-keys coal \ + --skip-keys pinocchio \ + --skip-keys crocoddyl \ + --skip-keys mim_solvers \ + --skip-keys colmpc \ + --skip-keys hpp-util \ + --skip-keys hpp-template \ + --skip-keys hpp-statistics \ + --skip-keys hpp-environments \ + --skip-keys hpp-pinocchio \ + --skip-keys hpp-constraints \ + --skip-keys proxsuite \ + --skip-keys hpp-core \ + --skip-keys hpp-corbaserver \ + --skip-keys hpp-manipulation \ + --skip-keys hpp-manipulation \ + --skip-keys hpp-manipulation \ + --skip-keys gepetto-viewer \ + --skip-keys gepetto-viewer \ + --skip-keys hpp-gepetto \ + --skip-keys hpp-plot \ + --skip-keys hpp-gui \ + --skip-keys hpp-bin-picking diff --git a/.devcontainer/vision/Dockerfile b/.devcontainer/vision/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..69450f36786a77f6ba6b3dbc05bd4b8be43b3b48 --- /dev/null +++ b/.devcontainer/vision/Dockerfile @@ -0,0 +1,118 @@ +ARG AGIMUS_DOCKER_BASE_IMAGE=gitlab.laas.fr:4567/agimus-project/agimus_dev_container:humble-devel-base +FROM $AGIMUS_DOCKER_BASE_IMAGE + +# Choose between `cpu` and `cu124` +ARG HAPPYPOSE_INSTALL_TYPE=cpu + +RUN --mount=type=cache,sharing=locked,target=/var/cache/apt \ + --mount=type=cache,sharing=locked,target=/var/lib/apt \ + --mount=type=cache,sharing=locked,target=/root/.cache \ + sudo apt-get update \ + && sudo apt-get install -qqy --no-install-recommends \ + libglfw3 \ + libglfw3-dev + +# Install HappyPose and PyM3T +WORKDIR /home/gepetto/vision_deps +RUN git clone --branch dev --recurse-submodules https://github.com/agimus-project/happypose.git \ + && cd happypose \ + && pip install -U pip \ + && pip install -r requirements/pypi.txt -r requirements/$HAPPYPOSE_INSTALL_TYPE.txt \ + && pip install git+https://github.com/agimus-project/pym3t@master + +# Download CosyPose models +WORKDIR /home/gepetto/happypose_data_dir +ENV HAPPYPOSE_DATA_DIR=/home/gepetto/happypose_data_dir +# Download YCBV pretrained models +RUN python -m happypose.toolbox.utils.download \ + --bop_dataset ycbv \ + --cosypose_models \ + detector-bop-ycbv-pbr--970850 \ + coarse-bop-ycbv-pbr--724183 \ + refiner-bop-ycbv-pbr--604090 \ + detector-bop-ycbv-synt+real--292971 \ + coarse-bop-ycbv-synt+real--822463 \ + refiner-bop-ycbv-synt+real--631598 \ + && cd $HAPPYPOSE_DATA_DIR/bop_datasets/ycbv \ + && unzip -n -qq ycbv_base.zip \ + && unzip -n -qq ycbv_models.zip \ + # Remove unused files + && rm -rf models_eval models_file *.zip \ + # Download TLESS pretrained models + && python -m happypose.toolbox.utils.download \ + --bop_dataset tless \ + --cosypose_models \ + detector-bop-tless-pbr--873074 \ + coarse-bop-tless-pbr--506801 \ + refiner-bop-tless-pbr--233420 \ + detector-bop-tless-synt+real--452847 \ + coarse-bop-tless-synt+real--160982 \ + refiner-bop-tless-synt+real--881314 \ + && cd $HAPPYPOSE_DATA_DIR/bop_datasets/tless \ + && unzip -n -qq tless_base.zip \ + && unzip -n -qq tless_models.zip \ + # Remove unused files + && rm -rf models_eval models_reconst *.zip + +ENV M3T_DATA_DIR=/home/gepetto/m3t_data_dir +# Install ROS dependencies for vision pipeline +WORKDIR /home/gepetto/vision_deps_ws +RUN --mount=type=cache,sharing=locked,target=/var/cache/apt \ + --mount=type=cache,sharing=locked,target=/var/lib/apt \ + --mount=type=cache,sharing=locked,target=/root/.cache \ + sudo apt-get update \ + && mkdir src \ + # Clone required repositories + && git clone --branch main https://github.com/agimus-project/happypose_ros.git src/happypose_ros \ + && git clone --branch main https://github.com/agimus-project/m3t_tracker_ros.git src/m3t_tracker_ros \ + && git clone --branch main https://github.com/agimus-project/olt_ros2_pipeline.git src/olt_ros2_pipeline \ + && git clone --branch main https://github.com/agimus-project/detection2d_marker_publisher.git src/detection2d_marker_publisher \ + # Build packages from source + && source /opt/ros/$ROS_DISTRO/setup.bash \ + && rosdep update --rosdistro $ROS_DISTRO \ + && rosdep install -y -i --from-paths src --rosdistro $ROS_DISTRO \ + --skip-keys pinocchio \ + --skip-keys hpp-fcl \ + --skip-keys happypose_marker_publisher \ + && colcon build \ + # Remove unused folders + && rm -rf build log \ + # Convert HappyPose models to M3T views + && mkdir -p $M3T_DATA_DIR +# RUN source install/setup.bash \ +# # Create sparse views for YCBV +# && ros2 run m3t_tracker_ros prepare_sparse_views \ +# --input-path $HAPPYPOSE_DATA_DIR/bop_datasets/ycbv/models \ +# --output-path $M3T_DATA_DIR \ +# --use-depth \ +# # Create sparse views for TLESS +# && ros2 run m3t_tracker_ros prepare_sparse_views \ +# --input-path $HAPPYPOSE_DATA_DIR/bop_datasets/tless/models_cad \ +# --output-path $M3T_DATA_DIR \ +# --use-depth + +# Install ROS dependencies for Franka ROS +WORKDIR /home/gepetto/franka_deps_ws +RUN --mount=type=cache,sharing=locked,target=/var/cache/apt \ + --mount=type=cache,sharing=locked,target=/var/lib/apt \ + --mount=type=cache,sharing=locked,target=/root/.cache \ + sudo apt-get update \ + && mkdir src \ + # Clone required repositories + && git clone --branch humble_devel https://github.com/agimus-project/franka_description.git src/franka_description \ + # Build packages from source + && source /opt/ros/$ROS_DISTRO/setup.bash \ + && rosdep update --rosdistro $ROS_DISTRO \ + && rosdep install -y -i --from-paths src --rosdistro $ROS_DISTRO \ + && colcon build \ + # Remove unused folders + && rm -rf build log src + +# Install ROS dependencies for Franka ROS +WORKDIR /home/gepetto/ros2_ws + +RUN echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> /home/gepetto/.bashrc \ + && echo "source /home/gepetto/vision_deps_ws/install/setup.bash" >> /home/gepetto/.bashrc \ + && echo "source /home/gepetto/franka_deps_ws/install/setup.bash" >> /home/gepetto/.bashrc \ + && echo "source /home/gepetto/ros2_ws/install/setup.bash" >> /home/gepetto/.bashrc \ + && echo "source /usr/share/colcon_argcomplete/hook/colcon-argcomplete.bash" >> /home/gepetto/.bashrc diff --git a/.devcontainer/vision/devcontainer.json b/.devcontainer/vision/devcontainer.json new file mode 100644 index 0000000000000000000000000000000000000000..4fe58ac484650a8440353ee7fe163bbfd982ba54 --- /dev/null +++ b/.devcontainer/vision/devcontainer.json @@ -0,0 +1,89 @@ +{ + "name": "gepetto-devcontainer", + // Uncomment ``build`` and comment out ``image`` to build from source + // "build": { + // "dockerfile": "Dockerfile", + // "context": "." + // }, + "image": "gitlab.laas.fr:4567/agimus-project/agimus_dev_container:humble-devel-vision", + "initializeCommand": "xhost +local:docker", + "containerEnv": { + "DISPLAY": "${localEnv:DISPLAY}", + "QT_X11_NO_MITSHM": "1", + // NVIDIA related ENV variables make no difference + // in case no discrete GPU is present in the system + "NVIDIA_DRIVER_CAPABILITIES": "all", + "__NV_PRIME_RENDER_OFFLOAD": "1", + "__GLX_VENDOR_LIBRARY_NAME": "nvidia" + }, + "remoteUser": "gepetto", + "privileged": true, + "mounts": [ + // Mount the workspace + { + "source": "${localWorkspaceFolder}/.devcontainer/scripts/build.sh", + "target": "/home/gepetto/ros2_ws/build.sh", + "type": "bind" + }, + { + "source": "${localWorkspaceFolder}/.devcontainer/scripts/setup.sh", + "target": "/home/gepetto/ros2_ws/setup.sh", + "type": "bind" + }, + // Enable sceen acess + { + "source": "/tmp/.X11-unix", + "target": "/tmp/.X11-unix", + "type": "bind" + }, + { + "source": "/dev/dri", + "target": "/dev/dri", + "type": "bind" + }, + // Presist bash history + { + "source": "${localWorkspaceFolderBasename}-bashhistory", + "target": "/commandhistory", + "type": "volume" + } + + ], + "workspaceFolder": "/home/gepetto/ros2_ws/src", + "workspaceMount": "source=${localWorkspaceFolder},target=/home/gepetto/ros2_ws/src,type=bind,consistency=cached", + "runArgs": [ + "--ipc=host", + "--net=host" + ], + "hostRequirements": { + "gpu": "optional" + }, + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.profiles.linux": { + "bash": { + "path": "bash" + } + }, + "terminal.integrated.defaultProfile.linux": "bash" + }, + "extensions": [ + "ms-vscode.cpptools-extension-pack", + "ms-python.python", + "ms-python.black-formatter", + "ms-python.isort", + "ms-toolsai.jupyter", + "ms-iot.vscode-ros", + "redhat.vscode-yaml", + "redhat.vscode-xml", + "twxs.cmake", + "ajshort.msg", + "xaver.clang-format", + "njpwerner.autodocstring", + "cschlosser.doxdocgen", + "streetsidesoftware.code-spell-checker" + ] + } + } +} diff --git a/.gitignore b/.gitignore index 34fdad21282681b6f094611cf4318e0d12d004a7..727e07aafa7502bcda405b6405a41a848176a33d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .devcontainer/*/* !.devcontainer/scripts/*.sh +!.devcontainer/vision/* +!.devcontainer/control/* vcs_repos diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ce02688a20f857f69e1d9b0432dc08bcc5bf4f55..c3623fd6fa6769a750cc3db0da20cd4ef6249754 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,11 +1,68 @@ -build: +.build-common: + timeout: 7 hours 0 minutes image: docker rules: - - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "humble"' + # Temporary for coding week + - if: '$CI_COMMIT_BRANCH == "humble-devel"' script: - - DATE=$(date -d @1706538067 +"%d-%m-%Y") - - docker build -t "${CI_REGISTRY_IMAGE}:${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}-${DATE}" - -t "${CI_REGISTRY_IMAGE}:${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}" ./.devcontainer + - DATE=$(date -d "${CI_PIPELINE_CREATED_AT:0:10}" +"%d-%m-%Y") + # For true base image this will be ignored as a build argument + - BASE_IMAGE="${CI_REGISTRY_IMAGE}:${CI_COMMIT_BRANCH}-base-${DATE}" + - IMAGE_NAME_SHORT="${CI_REGISTRY_IMAGE}:${CI_COMMIT_BRANCH}-${IMAGE_NAME}" + - IMAGE_NAME_LONG="$IMAGE_NAME_SHORT-${DATE}" + - docker build + -t "${IMAGE_NAME_SHORT}" + -t "${IMAGE_NAME_LONG}" + -f "${DOCKER_FILE}" + --build-arg AGIMUS_DOCKER_BASE_IMAGE="${BASE_IMAGE}" + --build-arg HAPPYPOSE_INSTALL_TYPE="${HAPPYPOSE_INSTALL_TYPE}" + "${CONTEXT_PATH}" - docker login -u "${CI_REGISTRY_USER}" -p "${CI_REGISTRY_PASSWORD}" "${CI_REGISTRY}" - - docker push "${CI_REGISTRY_IMAGE}:${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}-${DATE}" - - docker push "${CI_REGISTRY_IMAGE}:${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}" + - docker push "${IMAGE_NAME_SHORT}" + - docker push "${IMAGE_NAME_LONG}" + variables: + IMAGE_NAME: base + DOCKER_FILE: ./.devcontainer/Dockerfile.base + CONTEXT_PATH: ./.devcontainer + HAPPYPOSE_INSTALL_TYPE: cpu + +stages: + - base + - derived + +build-base-image: + stage: base + extends: .build-common + variables: + IMAGE_NAME: base + DOCKER_FILE: ./.devcontainer/Dockerfile.base + CONTEXT_PATH: ./.devcontainer + +build-control-image: + stage: derived + needs: [build-base-image] + extends: .build-common + variables: + IMAGE_NAME: control + DOCKER_FILE: ./.devcontainer/control/Dockerfile + CONTEXT_PATH: ./.devcontainer/control + +.build-vision-image: + stage: derived + needs: [build-base-image] + extends: .build-common + variables: + IMAGE_NAME: vision + DOCKER_FILE: ./.devcontainer/vision/Dockerfile + CONTEXT_PATH: ./.devcontainer/vision + HAPPYPOSE_INSTALL_TYPE: cpu + +build-cpu-vision-image: + extends: .build-vision-image + variables: + HAPPYPOSE_INSTALL_TYPE: cpu + +build-cuda-vision-image: + extends: .build-vision-image + variables: + HAPPYPOSE_INSTALL_TYPE: cu124 diff --git a/README.md b/README.md index eb83d3c46e910bed19199931d115b8cd1e0d5fc3..62f042eb0044e6cc694e14d50ba87fe7c51ca8fc 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,18 @@ -# gepetto-dev-container +# Agimus devcontainer -Devcontainer setup was initially created for the AGIMUS project. +Devcontainer setup for the AGIMUS project. It provides a devcontainer for ROS 2 Humble with predefined VS Code plugins and autocompletion for VS Code for C++ and Python, including ROS paths. -This setup provides a devcontainer for ROS 2 Humble with predefined VS Code plugins and autocompletion for VS Code for C++ and Python, including ROS paths. + This project consists of 4 prebuilt docker images: + - `agimus_dev_container:humble-devel-base`: Common image with all the shared utils preinstalled. + - `agimus_dev_container:humble-devel-control`: Image specialized for control and planning part of Agimus experiments. Extends base image with Ignition-Gazebo installation and custom libfranka for interaction with old Panda robot. Additionally it has prebuilt list of dependencies such as [Coal](https://github.com/coal-library/coal), [Pinocchio](https://github.com/stack-of-tasks/pinocchio), [Crocoddyl](https://github.com/loco-3d/crocoddyl) and [HPP](https://humanoid-path-planner.github.io/hpp-doc/) with a set of GUI tools like [Gepetto Viewer](https://github.com/Gepetto/gepetto-viewer). Everything is build with python bindings. + - `agimus_dev_container:humble-devel-vision`: Image specialized for vision tasks of Agimus project. Has preinstalled [HappyPose](https://github.com/agimus-project/happypose) (Torch installation for CPU) and [PyM3T](https://github.com/agimus-project/pym3t) with their ROS nodes as well as [olt_ros2_pipeline](https://github.com/agimus-project/olt_ros2_pipeline.git) with dependencies. HappyPose comes with pre-downloaded models and weights for `tless` and `ycbv` datasets. + - `agimus_dev_container:humble-devel-vision-cuda`: Image specialized for vision tasks of Agimus project. Consists of the same configuration as `humble-devel-vision` image, but [HappyPose](https://github.com/agimus-project/happypose) is installed with CUDA support. + + To choose between which docker to launch user will be prompted which configuration they want to launch. Available are `control`, `vision` and `vision_cuda`. In order to obtain full pipeline consisting of control and vision modules one has to launch two instances of VS Code. One with devcontainer launched for vision configuration and one with configuration for control. + +## Usage + +This repository is meant to be used in the same spirit as ROS workspaces. After downloading and launching devcontainer (for more information follow later steps) users can download repositories they wish to work on. When started, docker container creates bind mount between folder `/home/gepetto/ros2_ws/src` and folder of the downloaded repository. This way files within this directory will be accessible from host machine. ## Install docker and set up VS Code @@ -38,12 +48,17 @@ The last option starts by clicking the green square with arrows in the lower-lef </p> </div> -Due to user access rights, VS Code will prompt you to type in `sudo` password. This is due to walk-round to have non-root access to `/dev/dri/*` devices to obtain hardware acceleration for GUI applications. +And then choose the container variant you want to launch. + +<div align="center"> + <img src="./resources/center_choose_container.png" width=500 /> +</div> ## Additional scripts -Inside the container in the main ROS workspace directory, there are scripts `setup.sh` and `build.sh`. They simplify the pipeline by scripting installation of the dependencies with `rosdep` and run `colcon build` commands. +Inside of the the docker container in the directory `/home/gepetto/ros2_ws` two utility scripts can be sound. +[setup.sh](.devcontainer/setup.sh) used to invoke `rosdep install` with some defaults and [build.sh](.devcontainer/build.sh) used to invoke `colcon build`. ## GPU support for rendering -The dev container automatically sets up access to NVIDIA GPUs. Commands such as `nvidia-smi` are available and work as long as NVIDIA drivers are installed on the host system. For neural network inference everything should be automatic, yet for GUI applications additional variables are required. For more information see [devcontainer.json](./.devcontainer/devcontainer.json) file. +The dev container automatically sets up access to NVIDIA GPUs. Commands such as `nvidia-smi` are available and work as long as NVIDIA drivers and [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) are installed on the host system. For neural network inference and Gazebo rendering acceleration everything should be automatic. diff --git a/resources/center_choose_container.png b/resources/center_choose_container.png new file mode 100644 index 0000000000000000000000000000000000000000..f4b1f0979a14dd04422be9a312a7a7ee10abceb1 Binary files /dev/null and b/resources/center_choose_container.png differ