diff --git a/README.md b/README.md index 3f2798a4805137d69cdb2b1ae774c1fd1e172e24..c55317fabaf2698aa51b05e2c33cf5aedb8ec37a 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ python3 -m pipx ensurepath pipx install git+https://github.com/osrf/rocker.git pipx inject rocker git+https://github.com/sloretz/off-your-rocker.git pipx inject rocker git+https://github.com/miguelprada/mp_rocker.git +pipx inject rocker git+https://github.com/anfemosa/roscker_extensions.git # WIP ``` **Nvidia-container-toolkit** @@ -76,7 +77,7 @@ Clone the repository: git clone git@git.code.tecnalia.com:andres.montano/development_environment.git ``` -## Usage/Examples +## How to use it ### Before generate a docker image @@ -113,7 +114,7 @@ pyk4a # EOF ``` -**TIP** To obtain the dependencies list for you workspace you can use the command `rosdep check --from-paths src --ignore-src` +**TIP** To obtain the dependencies list for you workspace you can use the command `rosdep check --from-paths src --ignore-src` or `rosdep install --reinstall --simulate --from-path src --ignore-src --skip-keys --rosdistro ${ROS_DISTRO}` If some extra libs are needed, they can be added in extra_libs folder, where a common_libs.txt file is located jointly with ROS_DISTRO_libs.txt files. These libs are packages downloaded and installed in the docker image during the build process. Therefore, files containing urls with links to the sources of the libs. @@ -121,15 +122,13 @@ Example of common_libs.txt file: ```bash # List with links to additional libraries to install in devenv image -# bat-musl -https://github.com/sharkdp/bat/releases/download/v0.24.0/bat-musl_0.24.0_amd64.deb # lsd-musl -https://github.com/lsd-rs/lsd/releases/download/v1.0.0/lsd-musl_1.0.0_amd64.deb -# ripgrep -https://github.com/BurntSushi/ripgrep/releases/download/14.1.0/ripgrep_14.1.0-1_amd64.deb +https://github.com/lsd-rs/lsd/releases/download/v1.1.5/lsd-musl_1.1.5_amd64.deb ``` -### TECNALIA login info +The package dependencies as binaries can be passed to the dockerfile with the option `--build-arg PACKAGES=${ws_packages}` e.g. `docker build --build-arg PACKAGES=neurondones_humble -t deven:humble .` + +### TECNALIA login info (Deprecated?) An auth.conf file with TECNALIA login info is required to add access to the Tecnalia's artifactory repository. @@ -141,50 +140,106 @@ password AVERYLONGPASSWORDGENERATEDBYTOKENINARTIFACTORY ### dotfiles -#### docker.sh +There are a bunch of useful optional functions to simplify the docker or ros usage at [dotfiles](https://github.com/andres-montano/dotfiles). Check repo readme to get more info. + +**Summary** + +```bash + echo "${BLUE} dockbuild: Build a docker image for ROS" + echo "Usage: dockbuild <ROS_DISTRO> [build_args]" + echo "ROS_DISTRO: Ros distribution. e.g. melodic, noetic, humble, etc." + echo "build_args:" + echo " --shell: shell to use in the container. e.g. bash or zsh" + echo " --ws: file name with packages to install in the workspace. e.g. neurondones_humble.txt" + echo " --force: force rebuild the image" + echo "Whiout build_args, default shell: ${ext}${NC}" +``` + +```bash + echo "${BLUE} dockrun: Run a docker image for ROS" + echo "Usage: dockrun <ROS_DISTRO> [options]" + echo "ROS_DISTRO:" + echo " melodic, noetic, humble, jazzy,etc." + echo "Options:" + echo " --ws: path to workspace. e.g. odin_ws" + echo " --share: resource to share with the container, e.g. video, pcan or dev" + echo " --shell: shell to use in the container. By default zsh" + echo " --parse: parse_args to use in the container, e.g. --oyr-spacenav. By default none" + echo " --image: use an specific image. By default uses the ROS base image" + echo "Examples:" + echo "dockrun humble --ws mairon_ws" + echo "dockrun noetic --ws neurondones_ws --share pcan" + echo "dockrun melodic --ws odinrobot_ws --share video --shell bash${NC}" +``` -dotfile with useful commands to simplify the docker use. +**Summary** -Useful commands: +There are four configuration files: +- distro_dependencies -- common to all workspaces at the same ros distro +- ws_dependencies -- particular dependencies for a given workspace +- extra_libs -- deb packages to install in the docker image +- auth.conf -- TECNALIA's artifactory login info + +To build a docker image: ```bash -Usage: dockbuild <ROS_DISTRO> [build_args] -ROS_DISTRO: Ros distribution. e.g. melodic, noetic, humble, etc. -build_args: - --shell: shell to use in the container. e.g. bash or zsh - Without build_args, default shell: zsh +docker build -t devenv:${ros_distro} ${build_options} -f devenv.Dockerfile . +or +dockbuild humble --shell zsh --ws neurondones_humble --force ``` +where build_options could be: + ```bash -Usage: dockrun <ROS_DISTRO> [options] -ROS_DISTRO: - melodic, noetic, humble, etc. -Options: - --ws: path to workspace. e.g. odin_ws - --share: resource to share with the container, e.g. video, pcan or dev - --shell: shell to use in the container. By default zsh - --parse: parse_args to use in the container, e.g. --oyr-spacenav. - By default none -Examples: -dockrun humble --ws mairon_ws -dockrun noetic --ws neurondones_ws --share pcan -dockrun melodic --ws odinrobot_ws --share video --shell bash +--build-arg ROS_DISTRO=${ros_distro} # Mandatory +--build-arg PACKAGES=${ws_packages} +--build-arg SHELL=${ext} +--build-arg SHELL=${shell_path} +--no-cache ``` +To run a container: + ```bash -Usage: dockexec <ROS_DISTRO> [options] -ROS_DISTRO: Ros distribution. e.g. melodic, noetic, humble, etc. -options: - --ws: path to workspace. e.g. odin_ws - --shell: shell to use in the container. e.g. bash or zsh -Example: -dockexec noetic --ws neurondones_ws --shell bash +rocker --home --ssh --git --user --user-preserve-groups --privileged --nvidia --x11 --network host --name ${container_name} ${image} zsh +or +dockrun melodic --ws odinrobot_ws --share dev ``` +## ROS and VS-Code + +To use ROS with VS Code there a lot of resources but most of them are focused on launch a docker image and then attach VS-Code to it. The problem with this approach is it does not allow to properly debug ROS nodes in VS-Code. + +Resources list: + +- [Setup ROS 2 with VSCode and Docker](https://docs.ros.org/en/rolling/How-To-Guides/Setup-ROS-2-with-VSCode-and-Docker-Container.html) +- [ROS 2 and VSCode](https://picknik.ai/vscode/docker/ros2/2024/01/23/ROS2-and-VSCode.html) +- [VSCode ROS2 Workspace Template](https://github.com/athackst/vscode_ros2_workspace) +- [Step By Step Integration of ROS in VS Code](https://github.com/lzptr/VS_Code_ROS) +- [IDE Visual Studio Code](https://health_software.pages.code.tecnalia.com/software_good_practices/ide/ide-vscode/) +- [IDEs and Debugging](https://docs.ros.org/en/rolling/How-To-Guides/ROS-2-IDEs.html) + +One of the most complete guide is [Setup ROS 2 with VSCode and Docker](https://docs.ros.org/en/rolling/How-To-Guides/Setup-ROS-2-with-VSCode-and-Docker-Container.html), it is a good starting point and is maintained by the ROS Community. + +To summarize, some configuration files should be added to workspace. '.devconatiner' folder including 'devcontainer.json' and 'Dockerfile'. '.vscode' folder including 'launch.json', 'tasks.json', 'c_cpp_properties.json' and 'settings.json'. + +- devcontainer.json contains the configuration to launch the container on VS-Code. Including Mount points, VS-Code extensions and Shared resources. +- Dockerfile contains the configuration to add $USER to the container avoiding permission issues. +- launch.json contains the configuration to launch a ROS node in the container. +- tasks.json contains the configuration to define tasks in VS-Code. +- c_cpp_properties.json and settings.json are autogenerated by VS-Code. + +Examples of functional commented files are stored at [vscode_config](https://git.code.tecnalia.com/andres.montano/development_environment/-/blob/master/vscode_config)' folder. + +As final remarks, the launch.json and tasks.json should be adapted to workspace/project needs. The launch.json contains the configuration to launch a ROS node in the container, it is recommended to avoid debug nodes as RViz or Gazebo (GZ), therefore the launch file should only be used to launch core project nodes. + +In order to make easy to use the configurations, a local env could be loaded with [direnv](https://github.com/direnv/direnv) (.envrc file), but it is not mandatory. -## Authors +## Contributors - [@andres.montano](https://git.code.tecnalia.com/andres.montano) +- [@jon.onativia](https://git.code.tecnalia.com/jon.onativia) +- [@javier.gonzalez](https://git.code.tecnalia.com/javier.gonzalez) ## Feedback diff --git a/vscode_config/.devcontainer/Dockerfile b/vscode_config/.devcontainer/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..3d2d32e8202b6054fe57836766fe441a6091f6c8 --- /dev/null +++ b/vscode_config/.devcontainer/Dockerfile @@ -0,0 +1,38 @@ +ARG ROS_DISTRO +ARG IMAGE_BASE +FROM ${IMAGE_BASE}:${ROS_DISTRO} +ARG USERNAME=USERNAME +ARG USER_UID=1000 +ARG USER_GID=$USER_UID + +# Delete user if it exists in container (e.g Ubuntu Noble: ubuntu) +RUN if id -u $USER_UID ; then userdel `id -un $USER_UID` ; fi + +# Create the user +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \ + # [Optional] Add sudo support. Omit if you don't need to install software after connecting. + && apt-get update \ + && apt-get install -y sudo \ + && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME +RUN apt-get update && apt-get upgrade -y +RUN apt-get install -y python3-pip + +# Set the shell by dafault +ARG SHELL=/bin/zsh +ENV SHELL ${SHELL} + +# [Optional] Set the default user. Omit if you want to keep the default as root. +USER $USERNAME + +# [Optional] Clone dotfiles and apply configuration +RUN git clone https://github.com/andsens/homeshick.git /home/$USERNAME/.homesick/repos/homeshick \ + && /home/$USERNAME/.homesick/repos/homeshick/bin/homeshick clone anfemosa/dotfiles \ + && /home/$USERNAME/.homesick/repos/homeshick/bin/homeshick link dotfiles + +# ******************************************************** +# * Anything else you want to do like clean up goes here * +# ******************************************************** + +CMD ["/bin/zsh"] \ No newline at end of file diff --git a/vscode_config/.devcontainer/devcontainer.json b/vscode_config/.devcontainer/devcontainer.json new file mode 100644 index 0000000000000000000000000000000000000000..da5efdb177fae136eb84972f2faf994a2b9da85c --- /dev/null +++ b/vscode_config/.devcontainer/devcontainer.json @@ -0,0 +1,129 @@ +{ + // Name of the tool + "name": "ROS2 Development Container", + "privileged": true, + "remoteUser": "${env:USERNAME}", + // Dockerfile used to generate the image, alternatively a given image could be use by "image" parameter, e.g. "image":"devenv:humble" + // But build and image cannot be used together + "build": { + "dockerfile": "Dockerfile", + "args": { + "IMAGE_BASE": "${env:IMAGE_BASE}", + "ROS_DISTRO": "${env:ROS_DISTRO}", + "SHELL": "${env:SHELL}", + "USERNAME": "${env:USERNAME}" + } + }, + //"image": "${localEnv:IMAGE_BASE}:${localEnv:ROS_DISTRO}", + // Arguments to pass to the container. The same arguments are passed to the docker run command + "runArgs": [ + "--cap-add=SYS_PTRACE", // Allows the container to trace processes using ptrace system call + "--security-opt=seccomp=unconfined", // Disables seccomp security profiles for the container + "--net=host", + "--pid=host", + "--ipc=host", + "--rm", // Remove the container when stop it. + "--name=${localEnv:ROS_DISTRO}" // Name of the container; useful to attache terminals to it using the dotfiles + ], + // Mount the workspace + "workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind", + "workspaceFolder": "${localWorkspaceFolder}", + // Uncomment to allow the container to access the X server on the host e.g. to run Rviz and other GUI tools + // As rocker is not used nvidia and other features are not supported [WIP] + "containerEnv": { + "DISPLAY": "${localEnv:DISPLAY}" + }, + "mounts": [ + ///* + // Uncomment to allow the container to access the X server on the host e.g. to run Rviz and other GUI tools + { + "source": "/tmp/.X11-unix", + "target": "/tmp/.X11-unix", + "type": "bind" + }, + { + "source": "${localEnv:XAUTHORITY:-$HOME/.Xauthority}", + "target": "${localEnv:HOME}/.Xauthority", + "type": "bind" + }, + // Mount the host's /dev directory allowing the container to access hardware/devices on the host + { + "source": "/dev", + "target": "/dev", + "type": "bind" + } + // [Optional] Mount bash history + , + { + "source": "${localEnv:HOME}/.bash_eternal_history", + "target": "${localEnv:HOME}/.bash_eternal_history", + "type": "bind" + } + //*/ + ], + // Commands to run after creating the container + //"postCreateCommand": "sudo rosdep update && sudo rosdep install --from-paths src --ignore-src -y", + "postCreateCommand": "direnv allow .", + // VS Code settings + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.shell.linux": "${localEnv:SHELL}" + }, + "extensions": [ + "aaron-bond.better-comments", + "alefragnani.project-manager", + "cheshirekow.cmake-format", + "codeium.codeium", + "codezombiech.gitignore", + "eamodio.gitlens", + "github.github-vscode-theme", + "hbenl.vscode-test-explorer", + "jeff-hykin.better-cpp-syntax", + "josetr.cmake-language-support-vscode", + "kaih2o.python-resource-monitor", + "kevinrose.vsc-python-indent", + "llvm-vs-code-extensions.vscode-clangd", + "mhutchie.git-graph", + "mintlify.document", + "ms-azuretools.vscode-docker", + "ms-dotnettools.vscode-dotnet-runtime", + "ms-iot.vscode-ros", + "ms-python.autopep8", + "ms-python.black-formatter", + "ms-python.debugpy", + "ms-python.flake8", + "ms-python.isort", + "ms-python.python", + "ms-python.vscode-pylance", + "ms-toolsai.jupyter-keymap", + "ms-vscode-remote.remote-containers", + "ms-vscode-remote.remote-ssh-edit", + "ms-vscode-remote.remote-ssh", + "ms-vscode-remote.remote-wsl", + "ms-vscode-remote.vscode-remote-extensionpack", + "ms-vscode.cmake-tools", + "ms-vscode.cpptools-extension-pack", + "ms-vscode.cpptools-themes", + "ms-vscode.cpptools", + "ms-vscode.remote-explorer", + "ms-vscode.remote-server", + "ms-vscode.test-adapter-converter", + "njpwerner.autodocstring", + "njqdev.vscode-python-typehint", + "oderwat.indent-rainbow", + "slevesque.vscode-3dviewer", + "streetsidesoftware.code-spell-checker", + "theumletteam.umlet", + "trabpukcip.wolf", + "twxs.cmake", + "visualstudioexptteam.intellicode-api-usage-examples", + "visualstudioexptteam.vscodeintellicode", + "vscode-icons-team.vscode-icons", + "xirider.livecode", + "yzane.markdown-pdf", + "ziyasal.vscode-open-in-github" + ] + } + } +} \ No newline at end of file diff --git a/vscode_config/.envrc b/vscode_config/.envrc new file mode 100644 index 0000000000000000000000000000000000000000..d2ba466b3867c4846b4d675442c4d70e1a0b7b1a --- /dev/null +++ b/vscode_config/.envrc @@ -0,0 +1,7 @@ +export ROS_DISTRO=humble +export IMAGE_BASE=devenv + +# Set direnv log format easier for the eyes +export DIRENV_LOG_FORMAT=$'\033[2mdirenv: %s\033[0m' +# to completely disable direnv logging +# export DIRENV_LOG_FORMAT='' diff --git a/vscode_config/.vscode/launch.json b/vscode_config/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..21cb808c52159af2c150c4b24ddef7381a77b504 --- /dev/null +++ b/vscode_config/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "ROS: Launch servers", + "request": "launch", + "target": "${workspaceFolder}/src/neurondones_workcell/neurondones_bringup/neurondones_bringup/launch/robot.launch.py", + "arguments": [ + "robot_ip:='192.168.135.50'", + "use_sim_time:=true", + "use_fake_hardware:=true", + "launch_rviz:=false" + ], + "type": "ros" + } + ] +} \ No newline at end of file diff --git a/vscode_config/.vscode/tasks.json b/vscode_config/.vscode/tasks.json new file mode 100644 index 0000000000000000000000000000000000000000..90cf57d53309db6efc183a7576c826f0012a87eb --- /dev/null +++ b/vscode_config/.vscode/tasks.json @@ -0,0 +1,56 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "colcon: build (debug)", + "type": "shell", + "command": [ + "source /opt/ros/humble/setup.zsh;", + "colcon build", + "--symlink-install", + "--cmake-args -DCMAKE_BUILD_TYPE=Debug", + "--packages-skip allegro_hand_weiss" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "colcon: build", + "type": "shell", + "command": [ + "source /opt/ros/humble/setup.zsh;", + "colcon build", + "--symlink-install", + "--packages-skip allegro_hand_weiss" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": false + } + }, + { + "label": "colcon: clean", + "type": "shell", + "command": [ + "rm -rf build/ install/ log/;" + ] + }, + { + "label": "colcon: test", + "type": "shell", + "command": [ + "source /opt/ros/humble/setup.zsh;", + "source install/setup.zsh;", + "colcon test", + "--packages-select <package-name>", + "--event-handlers console_direct+;" + ] + } + ] +} \ No newline at end of file