├── .ci ├── .gitkeep ├── build_humble_bin.sh ├── download_and_install_sdk.sh ├── jetson_build_humble_src.sh ├── jetson_download_and_install_sdk.sh ├── run_build_in_humble.sh └── run_tests.sh ├── .github ├── ISSUE_TEMPLATE │ ├── 1_feature_request.yml │ ├── 2_bug_report.yml │ └── config.yml └── workflows │ └── stale_issues.yml ├── .gitignore ├── .gitlab-ci.yml ├── CHANGELOG.rst ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docker ├── Dockerfile.desktop-humble ├── Dockerfile.l4t-humble ├── README.md ├── desktop_build_dockerfile_from_sdk_ubuntu_and_cuda_version.sh ├── jetson_build_dockerfile_from_sdk_and_l4T_version.sh ├── ros_entrypoint.sh └── ros_entrypoint_jetson.sh ├── images ├── .gitkeep ├── Picto+STEREOLABS_Black.jpg ├── PointCloud_Depth_ROS.jpg ├── depth.jpg ├── point_cloud.jpg ├── rgb.jpg ├── sim_rviz.jpg └── zed_shelves.jpg ├── zed_components ├── CMakeLists.txt ├── package.xml └── src │ ├── include │ └── visibility_control.hpp │ ├── tools │ ├── include │ │ ├── gnss_replay.hpp │ │ ├── json.hpp │ │ ├── sl_logging.hpp │ │ ├── sl_tools.hpp │ │ ├── sl_types.hpp │ │ └── sl_win_avg.hpp │ └── src │ │ ├── gnss_replay.cpp │ │ ├── sl_tools.cpp │ │ ├── sl_types.cpp │ │ └── sl_win_avg.cpp │ └── zed_camera │ ├── include │ ├── cost_traversability.hpp │ ├── zed_camera_component.hpp │ └── zed_camera_one_component.hpp │ └── src │ ├── cost_traversability.cpp │ ├── zed_camera_component_bodytrk.cpp │ ├── zed_camera_component_main.cpp │ ├── zed_camera_component_objdet.cpp │ └── zed_camera_one_component.cpp ├── zed_ros2 ├── CMakeLists.txt └── package.xml └── zed_wrapper ├── CMakeLists.txt ├── config ├── common_mono.yaml ├── common_stereo.yaml ├── custom_object_detection.yaml ├── ffmpeg.yaml ├── object_detection.yaml ├── virtual.yaml ├── zed.yaml ├── zed2.yaml ├── zed2i.yaml ├── zedm.yaml ├── zedx.yaml ├── zedxm.yaml ├── zedxone4k.yaml └── zedxonegs.yaml ├── launch └── zed_camera.launch.py ├── package.xml └── urdf ├── include └── materials.urdf.xacro ├── zed_descr.urdf.xacro └── zed_macro.urdf.xacro /.ci/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereolabs/zed-ros2-wrapper/ec8a0b4c8c9b0b6b4c7fab63b026fbf69ee00d74/.ci/.gitkeep -------------------------------------------------------------------------------- /.ci/build_humble_bin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | pwd_path="$(pwd)" 4 | if [[ ${pwd_path:${#pwd_path}-3} == ".ci" ]] ; then cd .. && pwd_path="$(pwd)"; fi 5 | ttk="===>" 6 | WORKDIR=${pwd_path} 7 | PROJ_NAME=${PWD##*/} 8 | 9 | echo "${ttk} Root repository folder: ${WORKDIR}" 10 | echo "${ttk} Repository name: ${PROJ_NAME}" 11 | 12 | # Create the ROS 2 workspace 13 | echo "${ttk} Create ROS2 workspace" 14 | cd .. 15 | WS_DIR="$(pwd)"/ros2_ws 16 | rm -rf ${WS_DIR} # clean residual cache files 17 | mkdir -p ${WS_DIR}/src 18 | echo "${ttk} ROS2 Workspace: ${WS_DIR}" 19 | cd ${WORKDIR} 20 | cd .. 21 | echo "cp -a ./${PROJ_NAME} ${WS_DIR}/src/" 22 | cp -a ./${PROJ_NAME} ${WS_DIR}/src/ 23 | 24 | echo "${ttk} Check environment variables" 25 | env | grep ROS 26 | 27 | echo "${ttk} Update bin repositories" 28 | apt-get update || true 29 | apt-get upgrade --yes 30 | rosdep update 31 | 32 | echo "${ttk} Install ZED ROS2 Package dependencies" 33 | cd ${WS_DIR} 34 | rosdep install --from-paths src --ignore-src -r -y 35 | 36 | echo "${ttk} Build the ZED ROS2 Package" 37 | colcon build --cmake-args=-DCMAKE_BUILD_TYPE=Release --parallel-workers $(nproc) 38 | 39 | echo "${ttk} Prepare 'install' artifact" 40 | cd ${WS_DIR} 41 | mkdir -p ${WORKDIR}/ros2_ws 42 | cp -a ./install ${WORKDIR}/ros2_ws/ 43 | 44 | cd ${WORKDIR} 45 | -------------------------------------------------------------------------------- /.ci/download_and_install_sdk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | UBUNTU_RELEASE_YEAR=$1 5 | CUDA_MAJOR=$2 6 | CUDA_MINOR=$3 7 | ZED_SDK_MAJOR=$4 8 | ZED_SDK_MINOR=$5 9 | 10 | ttk="===>" 11 | 12 | echo "Europe/Paris" > /etc/localtime ; echo "CUDA Version ${CUDA_MAJOR}.${CUDA_MINOR}.0" > /usr/local/cuda/version.txt 13 | 14 | # Setup the ZED SDK 15 | echo "${ttk} Installing ZED SDK v${ZED_SDK_MAJOR}.${ZED_SDK_MINOR} for Ubuntu ${UBUNTU_RELEASE_YEAR}.04 CUDA ${CUDA_MAJOR}.${CUDA_MINOR}" 16 | apt-get update -y || true 17 | apt-get install --no-install-recommends lsb-release wget less udev sudo build-essential cmake zstd python3 python3-pip libpng-dev libgomp1 -y && \ 18 | python3 -m pip install --upgrade pip; python3 -m pip install numpy opencv-python-headless && \ 19 | wget -q -O ZED_SDK_Linux_Ubuntu${UBUNTU_RELEASE_YEAR}.run https://download.stereolabs.com/zedsdk/${ZED_SDK_MAJOR}.${ZED_SDK_MINOR}/cu${CUDA_MAJOR}${CUDA_MINOR%.*}/ubuntu${UBUNTU_RELEASE_YEAR} && \ 20 | chmod +x ZED_SDK_Linux_Ubuntu${UBUNTU_RELEASE_YEAR}.run ; ./ZED_SDK_Linux_Ubuntu${UBUNTU_RELEASE_YEAR}.run -- silent skip_tools skip_cuda skip_python skip_hub && \ 21 | ln -sf /lib/x86_64-linux-gnu/libusb-1.0.so.0 /usr/lib/x86_64-linux-gnu/libusb-1.0.so && \ 22 | rm ZED_SDK_Linux_Ubuntu${UBUNTU_RELEASE_YEAR}.run && \ 23 | rm -rf /var/lib/apt/lists/* 24 | -------------------------------------------------------------------------------- /.ci/jetson_build_humble_src.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | pwd_path="$(pwd)" 4 | if [[ ${pwd_path:${#pwd_path}-3} == ".ci" ]] ; then cd .. && pwd_path="$(pwd)"; fi 5 | ttk="===>" 6 | WORKDIR=${pwd_path} 7 | PROJ_NAME=${PWD##*/} 8 | 9 | echo "${ttk} Root repository folder: ${WORKDIR}" 10 | echo "${ttk} Repository name: ${PROJ_NAME}" 11 | echo "${ttk} User: ${USER}" 12 | 13 | # Set timezone 14 | TZ=Europe/Paris 15 | ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezone 16 | 17 | # Create the ROS 2 workspace 18 | echo "${ttk} Create ROS2 workspace" 19 | cd .. 20 | WS_DIR="$(pwd)"/ros2_ws 21 | rm -rf ${WS_DIR} # clean residual cached files 22 | mkdir -p ${WS_DIR}/src 23 | echo "${ttk} ROS2 Workspace: ${WS_DIR}" 24 | 25 | echo "${ttk} Check environment variables" 26 | env | grep ROS 27 | 28 | echo "${ttk} Install missing ZED ROS2 Package dependencies from the sources" 29 | cd ${WS_DIR}/src 30 | apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 42D5A192B819C5DA 31 | # xacro 32 | XACRO_VERSION=2.0.8 33 | wget https://github.com/ros/xacro/archive/refs/tags/${XACRO_VERSION}.tar.gz -O - | tar -xvz && mv xacro-${XACRO_VERSION} xacro 34 | # Diagnostic 35 | DIAGNOSTICS_VERSION=3.0.0 36 | wget https://github.com/ros/diagnostics/archive/refs/tags/${DIAGNOSTICS_VERSION}.tar.gz -O - | tar -xvz && mv diagnostics-${DIAGNOSTICS_VERSION} diagnostics 37 | # lint 38 | AMENT_LINT_VERSION=0.12.7 39 | wget https://github.com/ament/ament_lint/archive/refs/tags/${AMENT_LINT_VERSION}.tar.gz -O - | tar -xvz && mv ament_lint-${AMENT_LINT_VERSION} ament-lint 40 | # Geographic Info 41 | GEOGRAPHIC_INFO_VERSION=1.0.4 42 | wget https://github.com/ros-geographic-info/geographic_info/archive/refs/tags/${GEOGRAPHIC_INFO_VERSION}.tar.gz -O - | tar -xvz && mv geographic_info-${GEOGRAPHIC_INFO_VERSION} geographic-info 43 | cp -r geographic-info/geographic_msgs/ . 44 | rm -rf geographic-info 45 | # Robot Localization 46 | ROBOT_LOCALIZATION_VERSION=3.4.2 47 | wget https://github.com/cra-ros-pkg/robot_localization/archive/refs/tags/${ROBOT_LOCALIZATION_VERSION}.tar.gz -O - | tar -xvz && mv robot_localization-${ROBOT_LOCALIZATION_VERSION} robot-localization 48 | # NMEA msgs 49 | git clone https://github.com/ros-drivers/nmea_msgs.git --branch ros2 50 | # Angles 51 | git clone https://github.com/ros/angles.git --branch humble-devel 52 | 53 | echo "${ttk} Copy the ZED ROS2 Package sources in the workspace" 54 | cd ${WORKDIR} 55 | cd .. 56 | echo "cp -a ./${PROJ_NAME} ${WS_DIR}/src/" 57 | cp -a ./${PROJ_NAME} ${WS_DIR}/src/ 58 | 59 | echo "${ttk} Check that all the dependencies are satisfied" 60 | cd ${WS_DIR} 61 | apt-get update -y || true && rosdep update 62 | rosdep install --from-paths src --ignore-src -r -y 63 | 64 | # force install cython to make sure all pacakges are clean 65 | python3 -m pip install --force-reinstall cython 66 | 67 | echo "${ttk} Build the ZED ROS2 Package and the dependencies" 68 | cd ${WS_DIR} 69 | colcon build --cmake-args ' -DCMAKE_BUILD_TYPE=Release' ' -DCMAKE_LIBRARY_PATH=/usr/local/cuda/lib64/stubs' ' -DCMAKE_CXX_FLAGS="-Wl,--allow-shlib-undefined"' ' --no-warn-unused-cli' --parallel-workers $(nproc) 70 | 71 | echo "${ttk} Prepare 'install' artifact" 72 | cd ${WS_DIR} 73 | mkdir -p ${WORKDIR}/ros2_ws 74 | cp -a ./install ${WORKDIR}/ros2_ws/ 75 | 76 | cd ${WORKDIR} 77 | -------------------------------------------------------------------------------- /.ci/jetson_download_and_install_sdk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | JETPACK_MAJOR=$1 5 | JETPACK_MINOR=$2 6 | L4T_MAJOR=$3 7 | L4T_MINOR=$4 8 | ZED_SDK_MAJOR=$5 9 | ZED_SDK_MINOR=$6 10 | 11 | ttk="===>" 12 | 13 | echo "Europe/Paris" > /etc/timezone 14 | echo "# R${L4T_MAJOR} (release), REVISION: ${L4T_MINOR}" > /etc/nv_tegra_release 15 | 16 | #Install ZED SDK 17 | echo "${ttk} Installing ZED SDK v${ZED_SDK_MAJOR}.${ZED_SDK_MINOR} for Jetpack ${JETPACK_MAJOR}.${JETPACK_MINOR} (L4T v${L4T_MAJOR}.${L4T_MINOR})" 18 | apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 42D5A192B819C5DA 19 | apt-get update -y || true 20 | apt-get install -y --no-install-recommends zstd wget less cmake curl gnupg2 \ 21 | build-essential python3 python3-pip python3-dev python3-setuptools libusb-1.0-0-dev -y && \ 22 | pip install protobuf && \ 23 | wget -q --no-check-certificate -O ZED_SDK_Linux_JP.run \ 24 | https://download.stereolabs.com/zedsdk/${ZED_SDK_MAJOR}.${ZED_SDK_MINOR}/l4t${L4T_MAJOR}.${L4T_MINOR}/jetsons && \ 25 | chmod +x ZED_SDK_Linux_JP.run ; ./ZED_SDK_Linux_JP.run silent skip_tools && \ 26 | rm -rf /usr/local/zed/resources/* && \ 27 | rm -rf ZED_SDK_Linux_JP.run && \ 28 | rm -rf /var/lib/apt/lists/* 29 | -------------------------------------------------------------------------------- /.ci/run_build_in_humble.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | ZED_SDK_MAJOR=4 4 | ZED_SDK_MINOR=1 5 | 6 | # Retrieve CUDA version from environment variable CUDA_VERSION 7 | CUDA_MAJOR=`echo ${CUDA_VERSION} | cut -d. -f1` 8 | CUDA_MINOR=`echo ${CUDA_VERSION} | cut -d. -f2` 9 | 10 | pwd_path="$(pwd)" 11 | if [[ ${pwd_path:${#pwd_path}-3} == ".ci" ]] ; then cd .. && pwd_path="$(pwd)"; fi 12 | ttk="---> " 13 | ROOT_PATH=${pwd_path} 14 | REPO_NAME=${PWD##*/} 15 | 16 | echo "${ttk} Root repository folder: ${ROOT_PATH}" 17 | echo "${ttk} Repository name: ${REPO_NAME}" 18 | #echo "${ttk} User: ${USER}" 19 | 20 | sudocmd="" 21 | if [[ ! $(uname) == "MINGW"* ]]; then 22 | LINUX_OS=1 23 | if [[ ! ${CI_RUNNER_TAGS} == *"docker-builder"* ]]; then 24 | sudocmd="sudo " 25 | fi 26 | fi 27 | 28 | ${sudocmd} chmod +x .ci/*.sh 29 | 30 | #the . command.sh syntaxe allows env var to be accessible cross-scripts (needed for timers) 31 | 32 | # Check Ubuntu version 33 | ubuntu=$(lsb_release -r) 34 | echo "${ttk} Ubuntu $ubuntu" 35 | VER=$(cut -f2 <<< "$ubuntu") 36 | echo "${ttk} Version: ${VER}" 37 | 38 | # Build the node 39 | cd "${ROOT_PATH}" 40 | ARCH=$(uname -m) 41 | echo "${ttk} Architecture: ${ARCH}" 42 | if [[ $ARCH == "x86_64" ]]; then 43 | if [[ $VER == "20.04" ]]; then 44 | echo "${ttk} Install the ZED SDK for ${ARCH} under Ubuntu ${VER}" 45 | . .ci/download_and_install_sdk.sh 20 ${CUDA_MAJOR} ${CUDA_MINOR} ${ZED_SDK_MAJOR} ${ZED_SDK_MINOR} 46 | echo "${ttk} Build ROS2 Humble from the source." 47 | . .ci/build_humble_src.sh 48 | fi 49 | if [[ $VER == "22.04" ]]; then 50 | echo "${ttk} Install the ZED SDK for ${ARCH} under Ubuntu ${VER}" 51 | . .ci/download_and_install_sdk.sh 22 ${CUDA_MAJOR} ${CUDA_MINOR} ${ZED_SDK_MAJOR} ${ZED_SDK_MINOR} 52 | echo "${ttk} Install ROS2 Humble from the binaries." 53 | . .ci/build_humble_bin.sh 54 | fi 55 | elif [[ $ARCH == "aarch64" ]]; then 56 | if [[ $VER == "20.04" ]]; then 57 | JP_MAJOR=5 58 | JP_MINOR=0 59 | L4T_MAJOR=35 60 | L4T_MINOR=1 61 | echo "${ttk} Install the ZED SDK for ${ARCH} under Ubuntu ${VER}" 62 | . .ci/jetson_download_and_install_sdk.sh ${JP_MAJOR} ${JP_MINOR} ${L4T_MAJOR} ${L4T_MINOR} ${ZED_SDK_MAJOR} ${ZED_SDK_MINOR} 63 | echo "${ttk} Build ROS2 Humble from the source." 64 | . .ci/jetson_build_humble_src.sh 65 | fi 66 | else 67 | echo "${ttk} Architecture ${ARCH} is not supported." 68 | exit 1 69 | fi 70 | if [ $? -ne 0 ]; then echo "${ttk} ROS2 Node build failed" > "$pwd_path/failure.txt" ; cat "$pwd_path/failure.txt" ; exit 1 ; fi 71 | -------------------------------------------------------------------------------- /.ci/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | ttk='--->' 5 | WORKDIR=$(pwd) 6 | 7 | #echo "${ttk} WORKDIR (${WORKDIR})content" 8 | #ls -lah ${WORKDIR} 9 | 10 | echo "${ttk} Check artifact presence" 11 | ls -lah ../ros2_ws/install 12 | 13 | #ls -lah /builds/sl/ros2_ws/install/zed_msgs/share/zed_msgs/ 14 | #ls -lah /builds/sl/ros2_ws/install/zed_components/share/zed_components/ 15 | #ls -lah /builds/sl/ros2_ws/install/zed_wrapper/share/zed_wrapper/ 16 | #ls -lah /builds/sl/ros2_ws/install/zed_ros2/share/zed_ros2/ 17 | 18 | echo "${ttk} Initialize local ROS2 environment" 19 | cd ${WORKDIR} 20 | source ../ros2_ws/install/local_setup.bash 21 | env | grep COLCON 22 | env | grep ROS 23 | 24 | echo "${ttk} Check ROS2 installation" 25 | ros2 doctor -r 26 | 27 | echo "${ttk} Check ZED ROS2 packages presence" 28 | ros2 pkg list | grep zed 29 | 30 | echo "${ttk} USB peripherals" 31 | lsusb | grep 2b03 32 | 33 | echo "${ttk} Test node running for 10 seconds" 34 | timeout --signal=SIGTERM 10 ros2 launch zed_wrapper zed2.launch.py 35 | 36 | exit 0 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1_feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 🧭 2 | description: Suggest an idea for this project. 3 | labels: "feature_request" 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | # Welcome 👋 9 | 10 | Thanks for taking the time to fill out this feature request module. 11 | Please fill out each section below. This info allows Stereolabs developers to correctly evaluate your request. 12 | 13 | Useful Links: 14 | - Documentation: https://www.stereolabs.com/docs/ 15 | - Stereolabs support: https://support.stereolabs.com/hc/en-us/ 16 | - type: checkboxes 17 | attributes: 18 | label: Preliminary Checks 19 | description: Please make sure that you verify each checkbox and follow the instructions for them. 20 | options: 21 | - label: "This issue is not a duplicate. Before opening a new issue, please search existing issues." 22 | required: true 23 | - label: "This issue is not a question, bug report, or anything other than a feature request directly related to this project." 24 | required: true 25 | - type: textarea 26 | attributes: 27 | label: Proposal 28 | description: "What would you like to have as a new feature?" 29 | placeholder: "A clear and concise description of what you want to happen." 30 | validations: 31 | required: true 32 | - type: textarea 33 | attributes: 34 | label: Use-Case 35 | description: "How would this help you?" 36 | placeholder: "Tell us more what you'd like to achieve." 37 | validations: 38 | required: false 39 | - type: textarea 40 | id: anything-else 41 | attributes: 42 | label: Anything else? 43 | description: "Let us know if you have anything else to share" 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2_bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 🐛 2 | description: Something isn't working as expected? Report your bugs here. 3 | labels: "bug" 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | # Welcome 👋 9 | 10 | Thanks for taking the time to fill out this bug report. 11 | Please fill out each section below. This info allows Stereolabs developers to diagnose (and fix!) your issue as quickly as possible. Otherwise we might need to close the issue without e.g. clear reproduction steps. 12 | 13 | Bug reports also shoulnd't be used for generic questions, please use the [Stereolabs Community forum](https://community.stereolabs.com/) instead. 14 | 15 | Useful Links: 16 | - Documentation: https://www.stereolabs.com/docs/ 17 | - Stereolabs support: https://support.stereolabs.com/hc/en-us/ 18 | - type: checkboxes 19 | attributes: 20 | label: Preliminary Checks 21 | description: Please make sure that you verify each checkbox and follow the instructions for them. 22 | options: 23 | - label: "This issue is not a duplicate. Before opening a new issue, please search existing issues." 24 | required: true 25 | - label: "This issue is not a question, feature request, or anything other than a bug report directly related to this project." 26 | required: true 27 | - type: textarea 28 | attributes: 29 | label: Description 30 | description: Describe the issue that you're seeing. 31 | placeholder: Be as precise as you can. Feel free to share screenshots, videos, or data. The more information you provide the easier will be to provide you with a fast solution. 32 | validations: 33 | required: true 34 | - type: textarea 35 | attributes: 36 | label: Steps to Reproduce 37 | description: Clear steps describing how to reproduce the issue. 38 | value: | 39 | 1. 40 | 2. 41 | 3. 42 | ... 43 | validations: 44 | required: true 45 | - type: textarea 46 | attributes: 47 | label: Expected Result 48 | description: Describe what you expected to happen. 49 | validations: 50 | required: true 51 | - type: textarea 52 | attributes: 53 | label: Actual Result 54 | description: Describe what actually happened. 55 | validations: 56 | required: true 57 | - type: dropdown 58 | attributes: 59 | label: ZED Camera model 60 | description: What model of ZED camera are you using? 61 | options: 62 | - "ZED" 63 | - "ZED Mini" 64 | - "ZED2" 65 | - "ZED2i" 66 | validations: 67 | required: true 68 | - type: textarea 69 | attributes: 70 | label: Environment 71 | render: shell 72 | description: Useful information about your system. 73 | placeholder: | 74 | OS: Operating System 75 | CPU: e.g. ARM 76 | GPU: Nvidia Jetson Xavier NX 77 | ZED SDK version: e.g. v3.5.3 78 | Other info: e.g. ROS Melodic 79 | validations: 80 | required: true 81 | - type: textarea 82 | attributes: 83 | label: Anything else? 84 | description: Please add any other information or comment that you think may be useful for solving the problem 85 | placeholder: 86 | validations: 87 | required: false 88 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Online Documentation 4 | url: https://www.stereolabs.com/docs/ 5 | about: Check out the Stereolabs documentation for answers to common questions. 6 | - name: Stereolabs Community 7 | url: https://community.stereolabs.com/ 8 | about: Ask questions, request features & discuss with other users and developers. 9 | - name: Stereolabs Twitter 10 | url: https://twitter.com/Stereolabs3D 11 | about: The official Stereolabs Twitter account to ask questions, comment our products and share your projects with the ZED community. 12 | 13 | -------------------------------------------------------------------------------- /.github/workflows/stale_issues.yml: -------------------------------------------------------------------------------- 1 | name: 'Stale issue handler' 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: '00 00 * * *' 6 | 7 | jobs: 8 | stale: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/stale@main 12 | id: stale 13 | with: 14 | stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment otherwise it will be automatically closed in 5 days' 15 | stale-pr-message: 'This PR is stale because it has been open 30 days with no activity. Remove stale label or comment otherwise it will be automatically closed in 5 days' 16 | days-before-stale: 30 17 | days-before-close: 5 18 | operations-per-run: 1500 19 | exempt-issue-labels: 'feature_request' 20 | exempt-pr-labels: 'feature_request' 21 | enable-statistics: 'true' 22 | close-issue-label: 'closed_for_stale' 23 | close-pr-label: 'closed_for_stale' 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | devel/ 2 | logs/ 3 | build/ 4 | log/ 5 | install/ 6 | bin/ 7 | lib/ 8 | msg_gen/ 9 | srv_gen/ 10 | msg/*Action.msg 11 | msg/*ActionFeedback.msg 12 | msg/*ActionGoal.msg 13 | msg/*ActionResult.msg 14 | msg/*Feedback.msg 15 | msg/*Goal.msg 16 | msg/*Result.msg 17 | msg/_*.py 18 | build_isolated/ 19 | devel_isolated/ 20 | 21 | # Generated by dynamic reconfigure 22 | *.cfgc 23 | /cfg/cpp/ 24 | /cfg/*.py 25 | 26 | # Ignore generated docs 27 | *.dox 28 | *.wikidoc 29 | 30 | # eclipse stuff 31 | .project 32 | .cproject 33 | 34 | # qcreator stuff 35 | CMakeLists.txt.user 36 | 37 | srv/_*.py 38 | *.pcd 39 | *.pyc 40 | qtcreator-* 41 | *.user 42 | 43 | /planning/cfg 44 | /planning/docs 45 | /planning/src 46 | 47 | *~ 48 | 49 | # Emacs 50 | .#* 51 | 52 | # Catkin custom files 53 | CATKIN_IGNORE 54 | 55 | # C++ objects and libs 56 | 57 | *.slo 58 | *.lo 59 | *.o 60 | *.a 61 | *.la 62 | *.lai 63 | *.so 64 | *.dll 65 | *.dylib 66 | 67 | # Qt-es 68 | 69 | /.qmake.cache 70 | /.qmake.stash 71 | *.pro.user 72 | *.pro.user.* 73 | *.qbs.user 74 | *.qbs.user.* 75 | *.moc 76 | moc_*.cpp 77 | moc_*.h 78 | qrc_*.cpp 79 | ui_*.h 80 | Makefile* 81 | *build-* 82 | 83 | # QtCreator 84 | 85 | *.autosave 86 | 87 | # QtCtreator Qml 88 | *.qmlproject.user 89 | *.qmlproject.user.* 90 | 91 | # QtCtreator CMake 92 | CMakeLists.txt.user* 93 | 94 | # VSCode 95 | .vscode 96 | 97 | # TMP folders 98 | docker/tmp_sources 99 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | ############################## 2 | # Artifacts default values # 3 | ############################## 4 | #Folders to be saved after the build 5 | .artifacts_files: 6 | paths: &artifacts_files_definition 7 | - ros2_ws/install 8 | 9 | #Folders to be saved after the tests 10 | .test_artifacts_files: 11 | paths: &test_artifacts_files_definition 12 | #- lib/test/bin/data/current/* 13 | - ros2/test/bin/data/current/* 14 | 15 | #XML files to be used for Gitlab test report interface 16 | .test_artifacts_report_files: 17 | reports: &test_artifacts_report_files_definition 18 | #junit: lib/test/bin/output/*/*_test_*.xml 19 | junit: ros2/test/bin/output/*/*_test_*.xml 20 | 21 | .linux_artifacts: 22 | name: &linux_artifacts_naming_definition "${CI_PROJECT_NAMESPACE}_${CI_PROJECT_NAME}_${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}" 23 | 24 | #Artifacts configuration 25 | .artifacts_config: 26 | expire_in: &artifacts_expire_in_definition 2 weeks 27 | 28 | ############ 29 | # Stages # 30 | ############ 31 | stages: 32 | - build 33 | - unit_test 34 | - deploy 35 | - deploy_docker 36 | 37 | 38 | variables: 39 | #GIT_SUBMODULE_STRATEGY: normal 40 | GIT_SUBMODULE_STRATEGY: recursive 41 | #GIT_CLONE_PATH: $CI_BUILDS_DIR/ros2_ws/src/$CI_PROJECT_NAME # must be enabled in the configuration of the runners! 42 | 43 | ###################### 44 | # BUILDER selection # 45 | ###################### 46 | 47 | .linux_docker_builder_target: 48 | tags: &linux_docker_builder_target_definition 49 | - docker-builder 50 | - linux 51 | 52 | # deploy-support is actually linux + docker (but for weaker builder) 53 | .deploy_target: 54 | tags: &deploy_target_definition 55 | - deploy-support 56 | 57 | .linux_docker_builder_qemu_target: 58 | tags: &linux_docker_builder_qemu_target_definition 59 | - docker-builder 60 | - linux 61 | - qemu-support 62 | 63 | .linux_docker_builder_native_target: 64 | tags: &linux_docker_builder_native_target_definition 65 | - jetson 66 | - L4T35.1 67 | 68 | 69 | ###################### 70 | # Runner selection # 71 | ###################### 72 | 73 | # generic 74 | .runner_linux_jetson_l4t35_1_target: 75 | tags: &runner_linux_jetson_l4t35_1_target_definition 76 | - linux 77 | - jetson 78 | - L4T35.1 79 | 80 | .runner_linux_jetson_l4t32_7_target: 81 | tags: &runner_linux_jetson_l4t32_7_target_definition 82 | - linux 83 | - jetson 84 | - L4T32.7 85 | 86 | .runner_linux_jetson_nano_l4t32_7_target: 87 | tags: &runner_linux_jetson_nano_l4t32_7_target_definition 88 | - linux 89 | - jetson 90 | - nano 91 | - perfTest 92 | - L4T32.7 93 | 94 | .runner_linux_jetson_tx2_nx_l4t32_7_target: 95 | tags: &runner_linux_jetson_tx2_nx_l4t32_7_target_definition 96 | - linux 97 | - jetson 98 | - tx2_nx 99 | - perfTest 100 | - L4T32.7 101 | 102 | .runner_linux_jetson_xavier_nx_l4t35_1_target: 103 | tags: &runner_linux_jetson_xavier_nx_l4t35_1_target_definition 104 | - linux 105 | - jetson 106 | - xavier_nx 107 | - perfTest 108 | - L4T35.1 109 | 110 | .runner_linux_jetson_xavier_agx_l4t35_1_target: 111 | tags: &runner_linux_jetson_xavier_agx_l4t35_1_target_definition 112 | - linux 113 | - jetson 114 | - xavier 115 | - perfTest 116 | - L4T35.1 117 | 118 | .runner_linux_jetson_orin_agx_l4t35_1_target: 119 | tags: &runner_linux_jetson_orin_agx_l4t35_1_target_definition 120 | - linux 121 | - jetson 122 | - orin 123 | - perfTest 124 | - L4T35.1 125 | 126 | .runner_linux_jetson_live_l4t32_7_target: 127 | tags: &runner_linux_jetson_live_l4t32_7_target_definition 128 | - linux 129 | - jetson 130 | - live-runner 131 | - L4T32.7 132 | 133 | .runner_ubuntu18_desktop_live_cuda11_0_target: 134 | tags: &runner_ubuntu18_desktop_live_cuda11_0_target_definition 135 | - ubuntu18 136 | - x86_64 137 | - perfTest 138 | - CUDA11 139 | - live-runner 140 | 141 | .runner_ubuntu18_desktop_cuda11_0_target: 142 | tags: &runner_ubuntu18_desktop_cuda11_0_target_definition 143 | - ubuntu18 144 | - x86_64 145 | - perfTest 146 | - CUDA11 147 | 148 | .runner_ubuntu_docker_desktop_target: 149 | tags: &runner_ubuntu_docker_desktop_target_definition 150 | - x86_64 151 | - docker-runner 152 | - linux 153 | 154 | .runner_ubuntu_docker_live_desktop_target: 155 | tags: &runner_ubuntu_docker_live_desktop_target_definition 156 | - x86_64 157 | - docker-runner 158 | - linux 159 | - live-runner 160 | - deploy-support 161 | 162 | ## Memory target 163 | .memory_ubuntu18_desktop_cuda11_0_target: 164 | tags: &memory_ubuntu18_desktop_cuda11_0_target_definition 165 | - ubuntu18 166 | - x86_64 167 | - memTest 168 | - CUDA11 169 | 170 | ###################### 171 | # Build script # 172 | ###################### 173 | .build_script_linux_humble: 174 | script: &humble_linux_build_script_definition 175 | - sudo chmod +x .ci/run_build_in_humble.sh 176 | - ./.ci/run_build_in_humble.sh 177 | 178 | ################# 179 | # Build Tasks # 180 | ################# 181 | 182 | humble_u22_cu117_build: 183 | stage: build 184 | #image: stereolabs/ci-compiler:ubuntu22.04-cuda11.7-tensorrt8.4.2-ros2-humble 185 | image: myzhar/test:ubuntu22.04-cuda11.7-tensorrt8.4.2-ros2-humble 186 | tags: *linux_docker_builder_target_definition 187 | script: *humble_linux_build_script_definition 188 | artifacts: 189 | name: *linux_artifacts_naming_definition 190 | paths: *artifacts_files_definition 191 | expire_in: *artifacts_expire_in_definition 192 | when: on_success 193 | 194 | humble_l4t35_1_build: 195 | stage: build 196 | image: dustynv/ros:humble-ros-base-l4t-r35.1.0 197 | # Consider using qemu in the future 198 | tags: *linux_docker_builder_qemu_target_definition 199 | #tags: *linux_docker_builder_native_target_definition 200 | script: *humble_linux_build_script_definition 201 | artifacts: 202 | name: *linux_artifacts_naming_definition 203 | paths: *artifacts_files_definition 204 | expire_in: *artifacts_expire_in_definition 205 | when: on_success 206 | 207 | ###################### 208 | # Test script # 209 | ###################### 210 | .setup_docker_sdk_before_script_linux: 211 | before_script: &linux_docker_install_sdk_before_script_definition 212 | - echo "Europe/Paris" > /etc/localtime 213 | - mv ZED_SDK_*.run ZED_SDK_Linux.run 214 | - apt update || true ; apt install -y lsb-release wget less udev sudo build-essential cmake python3 python3-dev zstd python3-pip python3-wheel git binutils-dev jq libusb-1* libopencv-dev 215 | - chmod +x ZED_SDK_Linux.run ; ./ZED_SDK_Linux.run -- silent 216 | - ln -sf /usr/bin/python3 /usr/bin/python 217 | - python -m pip install wheel setuptools #scikit-build 218 | #- python -m pip install opencv-python-headless 219 | # Replace libs by debug info ones 220 | #- mv lib/build/libsl_ai_dbginfo.so /usr/local/zed/lib/libsl_ai.so 221 | #- mv lib/build/libsl_zed_dbginfo.so /usr/local/zed/lib/libsl_zed.so 222 | 223 | .setup_sdk_before_script_linux: 224 | before_script: &linux_install_sdk_before_script_definition 225 | - ls lib/build/* 226 | - mv ZED_SDK_*.run ZED_SDK_Linux.run 227 | - sudo apt update || true ; sudo apt install -y binutils-dev zstd jq git cmake 228 | - chmod +x ZED_SDK_Linux.run ; ./ZED_SDK_Linux.run -- silent 229 | # Replace libs by debug info ones 230 | #- mv lib/build/libsl_ai_dbginfo.so /usr/local/zed/lib/libsl_ai.so 231 | #- mv lib/build/libsl_zed_dbginfo.so /usr/local/zed/lib/libsl_zed.so 232 | 233 | .setup_sdk_u22_cu117_web_before_script: 234 | before_script: &setup_sdk_u22_cu117_web_before_script_definition 235 | - sudo chmod +x .ci/download_and_install_sdk.sh 236 | - ./.ci/download_and_install_sdk.sh 22 11 7 3 8 237 | # clean previous artifacts 238 | - rm -rf ../ros2_ws 239 | # create new ROS2 workspace folders 240 | - mkdir -p ../ros2_ws/install 241 | # move new artifacts in the workspace folder 242 | - cp -a ./ros2_ws/install ../ros2_ws/ 243 | - rm -rf ./ros2_ws/ 244 | 245 | .test_script_linux: 246 | script: &linux_test_script_definition 247 | - sudo chmod +x .ci/run_tests.sh 248 | - ./.ci/run_tests.sh 249 | 250 | ################### 251 | # Unit Test tasks # 252 | ################### 253 | 254 | unit_test_ros2_humble_u22_cu117: 255 | stage: unit_test 256 | #image: stereolabs/ci-runner:ubuntu22.04-cuda11.7-ros2-humble 257 | image: myzhar/test:ubuntu22.04-cuda11.7-ros2-humble-v1.1 258 | tags: *runner_ubuntu_docker_live_desktop_target_definition 259 | before_script: *setup_sdk_u22_cu117_web_before_script_definition 260 | script: *linux_test_script_definition 261 | #artifacts: 262 | # when: always 263 | # name: *linux_artifacts_naming_definition 264 | # paths: *test_artifacts_files_definition 265 | # expire_in: *artifacts_expire_in_definition 266 | # reports: *test_artifacts_report_files_definition 267 | needs: 268 | - job: humble_u22_cu117_build 269 | artifacts: true 270 | when: manual 271 | 272 | ##################### 273 | # Docker Deploy # 274 | ##################### 275 | 276 | # ROS2 Humble U22 Docker Image DEVEL - use the current branch source to build the wrapper 277 | ros2_humble_u22_docker_image_dev: 278 | needs: 279 | - job: humble_u22_cu117_build 280 | stage: deploy_docker 281 | image: docker 282 | services: 283 | - docker:dind 284 | script: 285 | - docker login -u $CI_REGISTRY_USER_WALT -p $CI_REGISTRY_PASSWORD_WALT 286 | - cd docker 287 | - IMG_TAG=${CI_PROJECT_NAME}_u22_cuda121_humble_${CI_COMMIT_BRANCH} 288 | - ./desktop_build_dockerfile_from_sdk_ubuntu_and_cuda_version.sh ubuntu22.04 cuda12.1.0 zedsdk4.1.2 289 | - docker tag zed_ros2_desktop_image "myzhar/zed-ros2-devel:${IMG_TAG}" 290 | - docker push myzhar/zed-ros2-devel:${IMG_TAG} 291 | when: on_success 292 | tags: *linux_docker_builder_target_definition 293 | except: 294 | - master 295 | allow_failure: true 296 | 297 | # ROS2 Humble L4T Docker Image DEVEL - use the current branch source to build the wrapper 298 | ros2_humble_l4t_docker_image_dev: 299 | needs: 300 | - job: humble_l4t35_1_build 301 | stage: deploy_docker 302 | image: docker 303 | services: 304 | - docker:dind 305 | script: 306 | - docker login -u $CI_REGISTRY_USER_WALT -p $CI_REGISTRY_PASSWORD_WALT 307 | - cd docker 308 | - IMG_TAG=${CI_PROJECT_NAME}_l4t35_4_humble_${CI_COMMIT_BRANCH} 309 | - ./jetson_build_dockerfile_from_sdk_and_l4T_version.sh l4t-r35.4.1 zedsdk4.1.2 310 | - docker tag zed_ros2_l4t_image "myzhar/zed-ros2-devel:${IMG_TAG}" 311 | - docker push myzhar/zed-ros2-devel:${IMG_TAG} 312 | - rm -r ./tmp_sources 313 | when: on_success 314 | tags: *linux_docker_builder_qemu_target_definition 315 | except: 316 | - master 317 | allow_failure: true 318 | 319 | ################# 320 | # GitHub Deploy # 321 | ################# 322 | 323 | # Update Github master branch 324 | github_push: 325 | needs: 326 | - job: humble_u22_cu117_build 327 | artifacts: false 328 | - job: humble_l4t35_1_build 329 | artifacts: false 330 | stage: deploy 331 | image: alpine 332 | script: 333 | - apk add --no-cache bash git 334 | - git config --global user.email "support@stereolabs.com" 335 | - git config --global user.name "Stereolabs" 336 | - git clone http://wlucetti:${GITLAB_PULL_TOKEN}@192.168.1.93/sl/zed-ros2-wrapper.git 337 | - cd zed-ros2-wrapper 338 | - git remote set-url origin https://${GITHUB_PUSH_TOKEN}@github.com/stereolabs/zed-ros2-wrapper.git 339 | - git remote -v 340 | - git config pull.rebase false 341 | - git pull origin master --allow-unrelated-histories 342 | - git push https://${GITHUB_PUSH_TOKEN}@github.com/stereolabs/zed-ros2-wrapper.git 343 | when: on_success 344 | tags: 345 | - docker-builder 346 | - linux 347 | only: 348 | - master 349 | allow_failure: true 350 | 351 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | ## Submitting your code changes 3 | 4 | Code contributions should be made via pull requests to the appropriate repositories: 5 | * [zed-ros2-wrapper](https://github.com/stereolabs/zed-ros2-wrapper/pulls) 6 | * [zed-ros2-interfaces](https://github.com/stereolabs/zed-ros2-interfaces/pulls) 7 | * [zed-ros2-examples](https://github.com/stereolabs/zed-ros2-examples/pulls) 8 | 9 | We ask all contributors to follow the practices explained in [ROS2 documentation](https://docs.ros.org/en/humble/The-ROS2-Project/Contributing/Code-Style-Language-Versions.html). 10 | 11 | Before submitting a pull request please perform this list of tasks from the root of your ROS2 workspace: 12 | 1. Automatic code formatting: 13 | 14 | `$ ament_uncrustify --reformat src` 15 | 16 | 2. Build the packages to check for compile errors: 17 | 18 | `$ colcon build --symlink-install --cmake-args=-DCMAKE_BUILD_TYPE=Release` 19 | 20 | 3. Perform the automatic build tests: 21 | 22 | `$ colcon test` 23 | 24 | 4. Analyze and solve eventually reported errors: 25 | 26 | `$ colcon test-result --verbose` 27 | 28 | 5. Repeat steps (1) -> (4) until all reported formatting errors have been resolved. 29 | 30 | 31 | ## License 32 | 33 | Any contribution that you make to this repository will 34 | be under the Apache 2 License, as dictated by that 35 | [license](http://www.apache.org/licenses/LICENSE-2.0.html): 36 | 37 | ~~~ 38 | 5. Submission of Contributions. Unless You explicitly state otherwise, 39 | any Contribution intentionally submitted for inclusion in the Work 40 | by You to the Licensor shall be under the terms and conditions of 41 | this License, without any additional terms or conditions. 42 | Notwithstanding the above, nothing herein shall supersede or modify 43 | the terms of any separate license agreement you may have executed 44 | with Licensor regarding such Contributions. 45 | ~~~ 46 | 47 | Contributors must sign-off each commit by adding a `Signed-off-by: ...` 48 | line to commit messages to certify that they have the right to submit 49 | the code they are contributing to the project according to the 50 | [Developer Certificate of Origin (DCO)](https://developercertificate.org/). -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | ## Some of TensorFlow's code is derived from Caffe, which is subject to the following copyright notice: 204 | 205 | COPYRIGHT 206 | 207 | All contributions by the University of California: 208 | 209 | Copyright (c) 2014, The Regents of the University of California (Regents) 210 | All rights reserved. 211 | 212 | All other contributions: 213 | 214 | Copyright (c) 2014, the respective contributors 215 | All rights reserved. 216 | 217 | Caffe uses a shared copyright model: each contributor holds copyright over 218 | their contributions to Caffe. The project versioning records all such 219 | contribution and copyright details. If a contributor wants to further mark 220 | their specific copyright on a particular contribution, they should indicate 221 | their copyright solely in the commit message of the change when it is 222 | committed. 223 | 224 | LICENSE 225 | 226 | Redistribution and use in source and binary forms, with or without 227 | modification, are permitted provided that the following conditions are met: 228 | 229 | 1. Redistributions of source code must retain the above copyright notice, this 230 | list of conditions and the following disclaimer. 231 | 232 | 2. Redistributions in binary form must reproduce the above copyright notice, 233 | this list of conditions and the following disclaimer in the documentation 234 | and/or other materials provided with the distribution. 235 | 236 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 237 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 238 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 239 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 240 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 241 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 242 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 243 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 244 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 245 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 246 | 247 | CONTRIBUTION AGREEMENT 248 | 249 | By contributing to the BVLC/caffe repository through pull-request, comment, 250 | or otherwise, the contributor releases their content to the 251 | license and copyright terms herein. 252 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Stereolabs
3 | ROS 2 wrapper 4 |

5 | 6 |

7 | ROS 2 packages for using Stereolabs ZED Camera cameras.
8 | ROS 2 Foxy Fitzroy (Ubuntu 20.04) - ROS 2 Humble Hawksbill (Ubuntu 22.04) - ROS 2 Jazzy Jalisco (Ubuntu 24.04) 9 |

10 | 11 |
12 | 13 | This package enables the use of ZED cameras with ROS 2, providing access to a variety of data types, including: 14 | 15 | - Color and grayscale images, both rectified and unrectified 16 | - Depth data 17 | - Colored 3D point clouds 18 | - Position and mapping, with optional GNSS data fusion 19 | - Sensor data 20 | - Detected objects 21 | - Human skeleton data 22 | - And more... 23 | 24 | [More information](https://www.stereolabs.com/docs/ros2) 25 | 26 | ![Point_cloud](./images/PointCloud_Depth_ROS.jpg) 27 | 28 | ## Installation 29 | 30 | ### Prerequisites 31 | 32 | - [Ubuntu 20.04 (Focal Fossa)](https://releases.ubuntu.com/focal/), [Ubuntu 22.04 (Jammy Jellyfish)](https://releases.ubuntu.com/jammy/), or [Ubuntu 24.04 (Noble Numbat)](https://releases.ubuntu.com/noble/) 33 | - [ZED SDK](https://www.stereolabs.com/developers/release/latest/) v5.0 EA (for older versions support please check the [releases](https://github.com/stereolabs/zed-ros2-wrapper/releases)) 34 | - [CUDA](https://developer.nvidia.com/cuda-downloads) dependency 35 | - ROS 2 Foxy Fitzroy (deprecated), ROS 2 Humble Hawksbill, or ROS 2 Jazzy Jalisco: 36 | - [Foxy on Ubuntu 20.04](https://docs.ros.org/en/foxy/Installation/Linux-Install-Debians.html) [**Not recommended. EOL reached**] 37 | - [Humble on Ubuntu 22.04](https://docs.ros.org/en/humble/Installation/Linux-Install-Debians.html) [EOL May 2027] 38 | - [Jazzy Jalisco on Ubuntu 24.04](https://docs.ros.org/en/jazzy/Installation/Linux-Install-Debians.html) [EOL May 2029] 39 | 40 | ### Build the package 41 | 42 | The **zed_ros2_wrapper** is a [colcon](http://design.ros2.org/articles/build_tool.html) package. 43 | 44 | > :pushpin: **Note:** If you haven’t set up your colcon workspace yet, please follow this short [tutorial](https://index.ros.org/doc/ros2/Tutorials/Colcon-Tutorial/). 45 | 46 | To install the **zed_ros2_wrapper**, open a bash terminal, clone the package from GitHub, and build it: 47 | 48 | ```bash 49 | mkdir -p ~/ros2_ws/src/ # create your workspace if it does not exist 50 | cd ~/ros2_ws/src/ #use your current ros2 workspace folder 51 | git clone https://github.com/stereolabs/zed-ros2-wrapper.git 52 | cd .. 53 | sudo apt update 54 | rosdep update 55 | rosdep install --from-paths src --ignore-src -r -y # install dependencies 56 | colcon build --symlink-install --cmake-args=-DCMAKE_BUILD_TYPE=Release --parallel-workers $(nproc) # build the workspace 57 | echo source $(pwd)/install/local_setup.bash >> ~/.bashrc # automatically source the installation in every new bash (optional) 58 | source ~/.bashrc 59 | ``` 60 | 61 | > :pushpin: **Note:** the dependency `zed_msgs` is no longer installed as a submodule of this package, but is available through `apt` as a binary package with ROS 2 Humble. When working with ROS 2 Foxy, or other distributions, you can install it from the sources from the [zed-ros2-interfaces repository](https://github.com/stereolabs/zed-ros2-interfaces?tab=readme-ov-file#install-the-package-from-the-source-code). 62 | 63 | > :pushpin: **Note:** If `rosdep` is missing, you can install it with: 64 | > 65 | >`sudo apt-get install python3-rosdep python3-rosinstall-generator python3-vcstool python3-rosinstall build-essential` 66 | 67 | > :pushpin: **Note:** When using the ZED ROS 2 Wrapper on an NVIDIA Jetson with JP6, you may get the following error when building the package for the first time 68 | > 69 | > ```bash 70 | > CMake Error at /usr/share/cmake-3.22/Modules/FindCUDA.cmake:859 (message): 71 | > Specify CUDA_TOOLKIT_ROOT_DIR 72 | > Call Stack (most recent call first): 73 | > /usr/local/zed/zed-config.cmake:72 (find_package) 74 | > CMakeLists.txt:81 (find_package) 75 | > ``` 76 | > 77 | > You can fix the problem by installing the missing `nvidia-jetpack` packages: 78 | > 79 | > `sudo apt install nvidia-jetpack nvidia-jetpack-dev` 80 | > 81 | > :pushpin: **Note:** The option `--symlink-install` is very important, it allows the use of symlinks instead of copying files to the ROS 2 folders during the installation, where possible. Each package in ROS 2 must be installed, and all the files used by the nodes must be copied into the installation folders. Using symlinks allows you to modify them in your workspace, reflecting the modification during the next executions without issuing a new `colcon build` command. This is true only for all the files that don't need to be compiled (Python scripts, configurations, etc.). 82 | > 83 | > :pushpin: **Note:** If you are using a different console interface like zsh, you have to change the `source` command as follows: `echo source $(pwd)/install/local_setup.zsh >> ~/.zshrc` and `source ~/.zshrc`. 84 | 85 | ## Starting the ZED node 86 | 87 | > :pushpin: **Note:** we recommend reading [this ROS 2 tuning guide](https://www.stereolabs.com/docs/ros2/150_dds_and_network_tuning) to improve the ROS 2 experience with ZED. 88 | 89 | To start the ZED node, open a bash terminal and use the [CLI](https://index.ros.org/doc/ros2/Tutorials/Introspection-with-command-line-tools/) command `ros2 launch`: 90 | 91 | ```bash 92 | ros2 launch zed_wrapper zed_camera.launch.py camera_model:= 93 | ``` 94 | 95 | Replace `` with the model of the camera that you are using: `'zed'`, `'zedm'`, `'zed2'`, `'zed2i'`, `'zedx'`, `'zedxm'`, `'virtual'`,`'zedxonegs'`,`'zedxone4k'`. 96 | 97 | The `zed_camera.launch.py` is a Python launch script that automatically starts the ZED node using ["manual composition"](https://index.ros.org/doc/ros2/Tutorials/Composition/). The parameters for the indicated camera model are loaded from the relative "YAML files." 98 | A Robot State Publisher node is started to publish the camera static links and joints loaded from the URDF model associated with the camera model. 99 | 100 | > :pushpin: **Note:** You can set your configurations by modifying the parameters in the files **common_stereo.yaml**, **zed.yaml** **zedm.yaml**, **zed2.yaml**, **zed2i.yaml**, **zedx.yaml**, **zedxm.yaml**, **common_mono.yaml**, **zedxonegs.yaml**, and **zedxone4k.yaml** available in the folder `zed_wrapper/config`. 101 | 102 | You can get the list of all the available launch parameters by using the `-s` launch option: 103 | 104 | ```bash 105 | ros2 launch zed_wrapper zed_camera.launch.py -s 106 | ros2 launch zed_display_rviz2 display_zed_cam.launch.py -s 107 | ``` 108 | 109 | For full descriptions of each parameter, follow the complete guide [here](https://www.stereolabs.com/docs/ros2/zed_node#configuration-parameters). 110 | 111 | ### RViz visualization 112 | 113 | To start a pre-configured RViz environment and visualize the data of all ZED cameras, we provide in the [`zed-ros2-examples` repository](https://github.com/stereolabs/zed-ros2-examples/tree/master/zed_display_rviz2). You'll see there more advanced examples and visualization that demonstrate depth, point clouds, odometry, object detection, etc. 114 | 115 | You can also quickly check that your depth data is correctly retrieved in RViz with `rviz2 -d ./zed_wrapper/config/rviz2/.rviz`. RViz subscribes to numerous ROS topics, which can potentially impact the performance of your application compared to when it runs without RViz. 116 | 117 | ### Simulation mode 118 | 119 | > :pushpin: **Note:** This feature is incompatible with the ZED X One and the older first-generation ZED cameras. 120 | 121 | Launch a standalone ZED ROS 2 node with simulated ZED data as input by using the following command: 122 | 123 | ```bash 124 | ros2 launch zed_wrapper zed_camera.launch.py camera_model:=zedx sim_mode:=true 125 | ``` 126 | 127 | Launch options: 128 | 129 | - [Mandatory] `camera_model`: indicates the model of the simulated camera. It's required that this parameter matches the model of the simulated camera. In most cases, it will be a ZED X, since the first versions of the simulation plugins that we released are simulating this type of device. 130 | - [Mandatory] `sim_mode`: start the ZED node in simulation mode if `true`. 131 | - [Optional] `use_sim_time`: force the node to wait for valid messages on the topic `/clock`, and so use the simulation clock as the time reference. 132 | - [Optional] `sim_address`: set the address of the simulation server. The default is `127.0.0.1`, and it's valid if the node runs on the same machine as the simulator. 133 | - [Optional] `sim_port`: set the port of the simulation server. It must match the value of the field `Streaming Port` of the properties of the `ZED camera streamer` Action Graph node. A different `Streaming Port` value for each camera is required in multi-camera simulations. 134 | 135 | You can also start a preconfigured instance of `rviz2` to visualize all the information available in the simulation by using the command: 136 | 137 | ```bash 138 | ros2 launch zed_display_rviz2 display_zed_cam.launch.py camera_model:=zedx sim_mode:=true 139 | ``` 140 | 141 | The `display_zed_cam.launch.py` launch file includes the `zed_camera.launch.py` launch file, hence it gets the same parameters. 142 | 143 | Here's an example of `rviz2` running with the simulated information obtained by placing the ZED camera on a shelf of a simulated warehouse: 144 | 145 | ![Sim RVIZ2](./images/sim_rviz.jpg) 146 | 147 | ![Shelves](./images/zed_shelves.jpg) 148 | 149 | Supported simulation environments: 150 | 151 | - [NVIDIA Omniverse Isaac Sim](https://www.stereolabs.com/docs/isaac-sim/) 152 | 153 | ## More features 154 | 155 | ### SVO recording 156 | 157 | [SVO recording](https://www.stereolabs.com/docs/video/recording/) can be started and stopped while the ZED node is running using the service `start_svo_recording` and the service `stop_svo_recording`. 158 | [More information](https://www.stereolabs.com/docs/ros2/zed_node/#services) 159 | 160 | ### Object Detection 161 | 162 | > :pushpin: **Note:** This feature is incompatible with the ZED X One and the older first-generation ZED cameras. 163 | 164 | Object Detection can be enabled *automatically* when the node starts by setting the parameter `object_detection/od_enabled` to `true` in the file `common_stereo.yaml`. 165 | The Object Detection can be enabled/disabled *manually* by calling the services `enable_obj_det`. 166 | 167 | You can find a detailed explanation of the Object Detection module in the [ZED ROS 2 documentation](https://www.stereolabs.com/docs/ros2/object-detection). 168 | 169 | ### Custom Object Detection with YOLO-like ONNX model file 170 | 171 | > :pushpin: **Note:** This feature is incompatible with the ZED X One and the older first-generation ZED cameras. 172 | 173 | Object Detection inference can be performed using a **custom inference engine** in YOLO-like ONNX format. 174 | 175 | You can generate your ONNX model by using Ultralytics YOLO tools. 176 | 177 | Install Ultralytics YOLO tools: 178 | 179 | ```bash 180 | python -m pip install ultralytics 181 | ``` 182 | 183 | If you have already installed the `ultralytics` package, we recommend updating it to the latest version: 184 | 185 | ```bash 186 | pip install -U ultralytics 187 | ``` 188 | 189 | Export an ONNX file from a YOLO model (more info [here](https://docs.ultralytics.com/modes/export/)), for example: 190 | 191 | ```bash 192 | yolo export model=yolo11n.pt format=onnx simplify=True dynamic=False imgsz=640 193 | ``` 194 | 195 | For a custom-trained YOLO model, the weight file can be changed, for example: 196 | 197 | ```bash 198 | yolo export model=yolov8l_custom_model.pt format=onnx simplify=True dynamic=False imgsz=512 199 | ``` 200 | 201 | Please refer to the [Ultralytics documentation](https://github.com/ultralytics/ultralytics) for details. 202 | 203 | Modify the `common_stereo.yaml` parameters to match your configuration: 204 | 205 | - Set `object_detection.model` to `CUSTOM_YOLOLIKE_BOX_OBJECTS` 206 | 207 | Modify the `custom_object_detection.yaml` parameters to match your configuration. 208 | 209 | > :pushpin: **Note:** The first time the custom model is used, the ZED SDK optimizes it to get the best performance from the GPU installed on the host. Please wait for the optimization to complete. When using Docker, we recommend using a shared volume to store the optimized file on the host and perform the optimization only once. 210 | 211 | Console log while optimization is running: 212 | 213 | ```bash 214 | [zed_wrapper-3] [INFO] [1729184874.634985183] [zed.zed_node]: === Starting Object Detection === 215 | [zed_wrapper-3] [2024-10-17 17:07:55 UTC][ZED][INFO] Please wait while the AI model is being optimized for your graphics card 216 | [zed_wrapper-3] This operation will be run only once and may take a few minutes 217 | ``` 218 | 219 | You can find a detailed explanation of the Custom Object Detection module in the [ZED ROS 2 documentation](https://www.stereolabs.com/docs/ros2/custom-object-detection). 220 | 221 | ### Body Tracking 222 | 223 | > :pushpin: **Note:** This feature is incompatible with the ZED X One and the older first-generation ZED cameras. 224 | 225 | The Body Tracking can be enabled *automatically* when the node starts by setting the parameter `body_tracking/bt_enabled` to `true` in the file `common_stereo.yaml`. 226 | 227 | ### Spatial Mapping 228 | 229 | > :pushpin: **Note:** This feature is incompatible with the ZED X One camera. 230 | 231 | The Spatial Mapping can be enabled automatically when the node starts setting the parameter `mapping/mapping_enabled` to `true` in the file `common_stereo.yaml`. 232 | The Spatial Mapping can be enabled/disabled manually by calling the service `enable_mapping`. 233 | 234 | ### GNSS fusion 235 | 236 | > :pushpin: **Note:** This feature is incompatible with the ZED X One camera. 237 | 238 | The ZED ROS 2 Wrapper can subscribe to a `NavSatFix` topic and fuse GNSS data information 239 | with Positional Tracking information to obtain a precise robot localization referred to Earth coordinates. 240 | To enable GNSS fusion, set the parameter `gnss_fusion.gnss_fusion_enabled` to `true`. 241 | You must set the correct `gnss_frame` parameter when launching the node, e.g. `gnss_frame:='gnss_link'`. 242 | The services `toLL` and `fromLL` can be used to convert Latitude/Longitude coordinates to robot `map` coordinates. 243 | 244 | ### 2D mode 245 | 246 | > :pushpin: **Note:** This feature is incompatible with the ZED X One camera. 247 | 248 | For robots moving on a planar surface, activating the "2D mode" (parameter `pos_tracking/two_d_mode` in `common_stereo.yaml`) is possible. 249 | The value of the coordinate Z for odometry and pose will have a fixed value (parameter `pos_tracking/fixed_z_value` in `common_stereo.yaml`). 250 | Roll, Pitch, and the relative velocities will be fixed to zero. 251 | 252 | ## Examples and Tutorials 253 | 254 | Examples and tutorials are provided to better understand how to use the ZED wrapper and how to integrate it into the ROS 2 framework. 255 | See the [`zed-ros2-examples` repository](https://github.com/stereolabs/zed-ros2-examples) 256 | 257 | ### RVIZ2 visualization examples 258 | 259 | - Example launch files to start a preconfigured instance of Rviz displaying all the ZED Wrapper node information: [zed_display_rviz2](https://github.com/stereolabs/zed-ros2-examples/tree/master/zed_display_rviz2) 260 | - ROS 2 plugin for ZED2 to visualize the results of the Object Detection and Body Tracking modules (bounding boxes and skeletons): [rviz-plugin-zed-od](https://github.com/stereolabs/zed-ros2-examples/tree/master/rviz-plugin-zed-od) 261 | 262 | ### Tutorials 263 | 264 | A series of tutorials are provided to better understand how to use the ZED nodes in the ROS2 environment : 265 | 266 | - [Video subscribing](./zed_video_tutorial): `zed_video_tutorial` - In this tutorial, you will learn how to write a simple node that subscribes to messages of type `sensor_msgs/Image` to retrieve the left and right rectified images published by the ZED node. 267 | - [Depth subscribing](./zed_depth_tutorial): `zed_depth_tutorial` - In this tutorial, you will learn how to write a simple node that subscribes to messages of type `sensor_msgs/Image` to retrieve the depth images published by the ZED node and to get the measured distance at the center of the image. 268 | - [Pose/Odometry subscribing](./zed_pose_tutorial): `zed_pose_tutorial` - In this tutorial, you will learn how to write a simple node that subscribes to messages of type `geometry_msgs/PoseStamped` and `nav_msgs/Odometry` to retrieve the position and the odometry of the camera while moving in the world. 269 | - [ROS2 Composition + BGRA2BGR conversion](./zed_rgb_convert): `zed_rgb_convert` - In this tutorial, you will learn how to use the concept of "ROS2 Composition" and "Intra Process Communication" to write a ROS2 component that gets a 4 channel BGRA image as input and re-publishes it as 3 channels BGR image. 270 | - [ROS2 Multi-Camera](./zed_multi_camera): `zed_multi_camera` - In this tutorial, you will learn how to use the provided launch file to start a multi-camera robot configuration. 271 | - [Robot integration](./zed_robot_integration): `zed_robot_integration` - In this tutorial, you will learn how to add one or more ZED cameras to a robot configuration. 272 | 273 | ### Examples 274 | 275 | How to use the ZED ROS 2 nodes alongside other ROS 2 packages or advanced features. 276 | 277 | - [zed_aruco_localization](./zed_aruco_localization): Use localized ArUco tag as a reference for localization. 278 | - [zed_depth_to_laserscan](./zed_depth_to_laserscan): Convert ZED Depth maps into virtual Laser Scans using 279 | 280 | ## Update the local repository 281 | 282 | To update the repository to the latest release, use the following command that will retrieve the latest commits of `zed-ros2-wrapper` and of all the submodules: 283 | 284 | ```bash 285 | git checkout master # if you are not on the main branch 286 | git pull 287 | ``` 288 | 289 | Clean the cache of your colcon workspace before compiling with the `colcon build` command to be sure that everything will work as expected: 290 | 291 | ```bash 292 | cd # replace with your workspace folder, for example ~/ros2_ws/src/ 293 | rm -r install 294 | rm -r build 295 | rm -r log 296 | colcon build --symlink-install --cmake-args=-DCMAKE_BUILD_TYPE=Release --parallel-workers $(nproc) 297 | ``` 298 | 299 | ## Known issues 300 | 301 | -------------------------------------------------------------------------------- /docker/Dockerfile.desktop-humble: -------------------------------------------------------------------------------- 1 | ARG UBUNTU_MAJOR=22 2 | ARG UBUNTU_MINOR=04 3 | ARG CUDA_MAJOR=12 4 | ARG CUDA_MINOR=6 5 | ARG CUDA_PATCH=3 6 | ARG ZED_SDK_MAJOR=4 7 | ARG ZED_SDK_MINOR=2 8 | ARG ZED_SDK_PATCH=5 9 | 10 | ARG IMAGE_NAME=nvcr.io/nvidia/cuda:${CUDA_MAJOR}.${CUDA_MINOR}.${CUDA_PATCH}-devel-ubuntu${UBUNTU_MAJOR}.${UBUNTU_MINOR} 11 | 12 | FROM ${IMAGE_NAME} 13 | 14 | ARG UBUNTU_MAJOR=22 15 | ARG UBUNTU_MINOR=04 16 | ARG CUDA_MAJOR=12 17 | ARG CUDA_MINOR=6 18 | ARG CUDA_PATCH=3 19 | ARG ZED_SDK_MAJOR=4 20 | ARG ZED_SDK_MINOR=2 21 | ARG ZED_SDK_PATCH=3 22 | # Optional: Override ZED SDK URL 23 | ARG CUSTOM_ZED_SDK_URL="" 24 | 25 | ARG ROS2_DIST=humble # ROS2 distribution 26 | 27 | ARG DEBIAN_FRONTEND=noninteractive 28 | 29 | ENV NVIDIA_DRIVER_CAPABILITIES \ 30 | ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}compute,video,utility 31 | 32 | # Disable apt-get warnings 33 | RUN apt-get update || true && apt-get install -y --no-install-recommends apt-utils dialog curl && \ 34 | rm -rf /var/lib/apt/lists/* 35 | 36 | ENV ZED_SDK_URL=${CUSTOM_ZED_SDK_URL:-"https://download.stereolabs.com/zedsdk/${ZED_SDK_MAJOR}.${ZED_SDK_MINOR}.${ZED_SDK_PATCH}/cu${CUDA_MAJOR}/ubuntu${UBUNTU_MAJOR}"} 37 | 38 | # Check that this SDK exists 39 | RUN echo "SDK link: $ZED_SDK_URL" 40 | RUN if [ "$(curl -L -I "${ZED_SDK_URL}" -o /dev/null -s -w '%{http_code}\n' | head -n 1)" = "200" ]; then \ 41 | echo "The URL points to something."; \ 42 | else \ 43 | echo "The URL does not point to a .run file or the file does not exist."; \ 44 | exit 1; \ 45 | fi 46 | 47 | 48 | ENV TZ=Europe/Paris 49 | 50 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \ 51 | apt-get update && \ 52 | apt-get install --yes lsb-release wget less udev sudo build-essential cmake python3 python3-dev python3-pip python3-wheel git jq libopencv-dev libpq-dev zstd usbutils && \ 53 | rm -rf /var/lib/apt/lists/* 54 | 55 | ############ Install ROS2 ############ 56 | 57 | # Set and Check Locale 58 | RUN apt-get update || true && \ 59 | apt-get install --no-install-recommends -y locales && \ 60 | locale-gen en_US en_US.UTF-8 && \ 61 | update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 && \ 62 | export LANG=en_US.UTF-8 && \ 63 | locale # verify settings && \ 64 | rm -rf /var/lib/apt/lists/* 65 | 66 | # Setup Sources 67 | RUN apt-get update || true && \ 68 | apt-get install --no-install-recommends -y software-properties-common && \ 69 | add-apt-repository universe && \ 70 | apt-get install -y curl && \ 71 | curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg && \ 72 | echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null && \ 73 | rm -rf /var/lib/apt/lists/* 74 | 75 | # Install ROS 2 Base packages and Python dependencies 76 | RUN apt-get update || true && \ 77 | apt-get install --no-install-recommends -y \ 78 | ros-${ROS2_DIST}-ros-base \ 79 | python3-flake8-docstrings \ 80 | python3-pip \ 81 | python3-pytest-cov \ 82 | ros-dev-tools && \ 83 | pip3 install \ 84 | argcomplete \ 85 | numpy \ 86 | empy \ 87 | lark && \ 88 | rm -rf /var/lib/apt/lists/* 89 | 90 | # Initialize rosdep 91 | RUN rosdep init && rosdep update 92 | 93 | # Install the ZED SDK 94 | RUN echo "CUDA Version $CUDA_VERSION" > /usr/local/cuda/version.txt 95 | 96 | # Setup the ZED SDK 97 | RUN apt-get update -y || true && \ 98 | apt-get install --no-install-recommends dialog bash-completion lsb-release wget less udev sudo build-essential cmake zstd python3 python3-pip libpng-dev libgomp1 -y && \ 99 | python3 -m pip install --upgrade pip; python3 -m pip install numpy opencv-python-headless && \ 100 | wget -q -O ZED_SDK_Linux_Ubuntu.run ${ZED_SDK_URL} && \ 101 | chmod +x ZED_SDK_Linux_Ubuntu.run && \ 102 | ./ZED_SDK_Linux_Ubuntu.run -- silent skip_tools skip_cuda && \ 103 | ln -sf /lib/x86_64-linux-gnu/libusb-1.0.so.0 /usr/lib/x86_64-linux-gnu/libusb-1.0.so && \ 104 | rm ZED_SDK_Linux_Ubuntu.run && \ 105 | rm -rf /var/lib/apt/lists/* 106 | 107 | # Install the ZED ROS2 Wrapper 108 | ENV ROS_DISTRO ${ROS2_DIST} 109 | 110 | # Copy the sources in the Docker image 111 | WORKDIR /root/ros2_ws/src 112 | COPY tmp_sources/ ./ 113 | 114 | # RUN ls -lah /root/ros2_ws/src/ 115 | WORKDIR /root/ros2_ws/ 116 | 117 | RUN /bin/bash -c "source /opt/ros/$ROS_DISTRO/setup.bash && \ 118 | apt-get update -y || true && rosdep update && \ 119 | rosdep install --from-paths src --ignore-src -r -y && \ 120 | colcon build --parallel-workers $(nproc) --symlink-install \ 121 | --event-handlers console_direct+ --base-paths src \ 122 | --cmake-args ' -DCMAKE_BUILD_TYPE=Release' \ 123 | ' -DCMAKE_LIBRARY_PATH=/usr/local/cuda/lib64/stubs' \ 124 | ' -DCMAKE_CXX_FLAGS="-Wl,--allow-shlib-undefined"' " && \ 125 | rm -rf /var/lib/apt/lists/* 126 | 127 | WORKDIR /root/ros2_ws 128 | 129 | # Setup environment variables 130 | COPY ros_entrypoint.sh /sbin/ros_entrypoint.sh 131 | RUN sudo chmod 755 /sbin/ros_entrypoint.sh 132 | 133 | ENTRYPOINT ["/sbin/ros_entrypoint.sh"] 134 | CMD ["bash"] 135 | -------------------------------------------------------------------------------- /docker/Dockerfile.l4t-humble: -------------------------------------------------------------------------------- 1 | # Define the L4T_VERSION argument 2 | ARG L4T_VERSION=l4t-r36.3.0 3 | ARG IMAGE_NAME=dustynv/ros:humble-ros-base-l4t-r36.3.0 4 | 5 | FROM ${IMAGE_NAME} 6 | 7 | ARG ZED_SDK_MAJOR=4 8 | ARG ZED_SDK_MINOR=2 9 | ARG ZED_SDK_PATCH=3 10 | ARG L4T_MAJOR=36 11 | ARG L4T_MINOR=3 12 | # Optional: Override ZED SDK URL 13 | ARG CUSTOM_ZED_SDK_URL="" 14 | 15 | # ROS2 distribution 16 | ARG ROS2_DIST=humble 17 | 18 | # ZED ROS2 Wrapper dependencies version 19 | ARG XACRO_VERSION=2.0.8 20 | ARG DIAGNOSTICS_VERSION=4.0.0 21 | ARG AMENT_LINT_VERSION=0.12.11 22 | ARG ROBOT_LOCALIZATION_VERSION=3.5.3 23 | ARG ZED_MSGS_VERSION=5.0.0 24 | ARG NMEA_MSGS_VERSION=2.0.0 25 | ARG ANGLES_VERSION=1.15.0 26 | ARG GEOGRAPHIC_INFO_VERSION=1.0.6 27 | ARG POINTCLOUD_TRANSPORT_VERSION=1.0.18 28 | ARG POINTCLOUD_TRANSPORT_PLUGINS_VERSION=1.0.11 29 | ARG RMW_CYCLONEDDS_VERSION=1.3.4 30 | ARG BACKWARD_ROS_VERSION=1.0.7 31 | 32 | 33 | ENV DEBIAN_FRONTEND=noninteractive 34 | 35 | # ZED SDK link 36 | ENV ZED_SDK_URL=${CUSTOM_ZED_SDK_URL:-"https://download.stereolabs.com/zedsdk/${ZED_SDK_MAJOR}.${ZED_SDK_MINOR}.${ZED_SDK_PATCH}/l4t${L4T_MAJOR}.${L4T_MINOR}/jetsons"} 37 | 38 | # Check that this SDK exists 39 | RUN if [ "$(curl -L -I "${ZED_SDK_URL}" -o /dev/null -s -w '%{http_code}\n' | head -n 1)" = "200" ]; then \ 40 | echo "The URL points to something."; \ 41 | else \ 42 | echo "The URL does not point to a .run file or the file does not exist."; \ 43 | exit 1; \ 44 | fi 45 | 46 | # Disable apt-get warnings 47 | RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 42D5A192B819C5DA || true && \ 48 | apt-get update || true && apt-get install -y --no-install-recommends apt-utils dialog && \ 49 | rm -rf /var/lib/apt/lists/* 50 | 51 | ENV TZ=Europe/Paris 52 | 53 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \ 54 | apt-get update && \ 55 | apt-get install --yes lsb-release wget less udev sudo build-essential cmake python3 python3-dev python3-pip python3-wheel git jq libpq-dev zstd usbutils && \ 56 | rm -rf /var/lib/apt/lists/* 57 | 58 | RUN echo "# R${L4T_MAJOR} (release), REVISION: ${L4T_MINOR}" > /etc/nv_tegra_release && \ 59 | apt-get update -y || true && \ 60 | apt-get install -y --no-install-recommends zstd wget less cmake curl gnupg2 \ 61 | build-essential python3 python3-pip python3-dev python3-setuptools libusb-1.0-0-dev \ 62 | libgeographic-dev libdraco-dev zlib1g-dev -y && \ 63 | pip install protobuf && \ 64 | wget -q --no-check-certificate -O ZED_SDK_Linux_JP.run \ 65 | ${ZED_SDK_URL} && \ 66 | chmod +x ZED_SDK_Linux_JP.run ; ./ZED_SDK_Linux_JP.run silent skip_tools && \ 67 | rm -rf /usr/local/zed/resources/* && \ 68 | rm -rf ZED_SDK_Linux_JP.run && \ 69 | rm -rf /var/lib/apt/lists/* 70 | 71 | # Install the ZED ROS2 Wrapper 72 | ENV ROS_DISTRO=${ROS2_DIST} 73 | 74 | # Copy the sources in the Docker image 75 | WORKDIR /root/ros2_ws/src 76 | COPY tmp_sources/ ./ 77 | 78 | # Install missing dependencies from the sources 79 | WORKDIR /root/ros2_ws/src 80 | RUN wget https://github.com/ros/xacro/archive/refs/tags/${XACRO_VERSION}.tar.gz -O - | tar -xvz && mv xacro-${XACRO_VERSION} xacro && \ 81 | wget https://github.com/ros/diagnostics/archive/refs/tags/${DIAGNOSTICS_VERSION}.tar.gz -O - | tar -xvz && mv diagnostics-${DIAGNOSTICS_VERSION} diagnostics && \ 82 | wget https://github.com/ament/ament_lint/archive/refs/tags/${AMENT_LINT_VERSION}.tar.gz -O - | tar -xvz && mv ament_lint-${AMENT_LINT_VERSION} ament-lint && \ 83 | wget https://github.com/cra-ros-pkg/robot_localization/archive/refs/tags/${ROBOT_LOCALIZATION_VERSION}.tar.gz -O - | tar -xvz && mv robot_localization-${ROBOT_LOCALIZATION_VERSION} robot-localization && \ 84 | wget https://github.com/stereolabs/zed-ros2-interfaces/archive/refs/tags/${ZED_MSGS_VERSION}.tar.gz -O - | tar -xvz && mv zed-ros2-interfaces-${ZED_MSGS_VERSION} zed-ros2-interfaces && \ 85 | wget https://github.com/ros-drivers/nmea_msgs/archive/refs/tags/${NMEA_MSGS_VERSION}.tar.gz -O - | tar -xvz && mv nmea_msgs-${NMEA_MSGS_VERSION} nmea_msgs && \ 86 | wget https://github.com/ros/angles/archive/refs/tags/${ANGLES_VERSION}.tar.gz -O - | tar -xvz && mv angles-${ANGLES_VERSION} angles && \ 87 | wget https://github.com/ros-perception/point_cloud_transport/archive/refs/tags/${POINTCLOUD_TRANSPORT_VERSION}.tar.gz -O - | tar -xvz && mv point_cloud_transport-${POINTCLOUD_TRANSPORT_VERSION} point_cloud_transport && \ 88 | wget https://github.com/ros-perception/point_cloud_transport_plugins/archive/refs/tags/${POINTCLOUD_TRANSPORT_PLUGINS_VERSION}.tar.gz -O - | tar -xvz && mv point_cloud_transport_plugins-${POINTCLOUD_TRANSPORT_PLUGINS_VERSION} point_cloud_transport_plugins && \ 89 | wget https://github.com/ros2/rmw_cyclonedds/archive/refs/tags/${RMW_CYCLONEDDS_VERSION}.tar.gz -O - | tar -xvz && mv rmw_cyclonedds-${RMW_CYCLONEDDS_VERSION} rmw_cyclonedds && \ 90 | wget https://github.com/ros-geographic-info/geographic_info/archive/refs/tags/${GEOGRAPHIC_INFO_VERSION}.tar.gz -O - | tar -xvz && mv geographic_info-${GEOGRAPHIC_INFO_VERSION} geographic-info && \ 91 | wget https://github.com/pal-robotics/backward_ros/archive/refs/tags/${BACKWARD_ROS_VERSION}.tar.gz -O - | tar -xvz && mv backward_ros-${BACKWARD_ROS_VERSION} backward_ros && \ 92 | cp -r geographic-info/geographic_msgs/ . && \ 93 | rm -rf geographic-info 94 | 95 | # Install cython 96 | RUN python3 -m pip install --upgrade cython 97 | 98 | # Build the dependencies and the ZED ROS2 Wrapper 99 | WORKDIR /root/ros2_ws 100 | RUN /bin/bash -c "source /opt/ros/$ROS_DISTRO/install/setup.bash && \ 101 | colcon build --parallel-workers $(nproc) --symlink-install \ 102 | --event-handlers console_direct+ --base-paths src \ 103 | --cmake-args ' -DCMAKE_BUILD_TYPE=Release' \ 104 | ' -DCMAKE_LIBRARY_PATH=/usr/local/cuda/lib64/stubs' \ 105 | ' -DCMAKE_CXX_FLAGS="-Wl,--allow-shlib-undefined"' \ 106 | ' --no-warn-unused-cli' " 107 | 108 | WORKDIR /root/ros2_ws 109 | 110 | # Setup environment variables 111 | COPY ros_entrypoint_jetson.sh /sbin/ros_entrypoint.sh 112 | RUN sudo chmod 755 /sbin/ros_entrypoint.sh 113 | 114 | ENTRYPOINT ["/sbin/ros_entrypoint.sh"] 115 | CMD ["bash"] 116 | 117 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | # Docker 2 | 3 | This folder contains a list of Dockerfile files to build Docker images ready to start the nodes of the *ZED ROS2 Wrapper*: 4 | 5 | * `Dockerfile.desktop-humble`: development desktop image for ROS2 Humble, running on the specified Ubuntu and CUDA versions. The ZED Wrapper is copied from the source file of the current branch and compiled. 6 | * `Dockerfile.l4t-humble`: Jetson image for ROS2 Humble, running on the given L4T version (L4T35.4 by default). 7 | 8 | > :pushpin: **NOTE:** in the entrypoint files we set the value of the `ROS_DOMAIN_ID` environment 9 | > variable to `0` that is the default value in ROS 2. 10 | > 11 | > If your setup requires a different value you can change it in the `ros_entrypoint_jetson.sh` and 12 | > `ros_entrypoint.sh` file before building your image to set it automatically when starting your Docker image, 13 | > or you can use the CLI command `export ROS_DOMAIN_ID=` when each interactive session is started. 14 | > 15 | > You can get more details concerning the `ROS_DOMAIN_ID` usage on the [official ROS 2 documentation](https://docs.ros.org/en/humble/Concepts/Intermediate/About-Domain-ID.html#the-ros-domain-id). 16 | 17 | ## Cross compilation 18 | 19 | You can easily compile the image for Jetson from your usual Desktop PC. 20 | For that you just need to run the following line before launching the build command: 21 | 22 | ```bash 23 | docker run --rm --privileged multiarch/qemu-user-static --reset -p yes 24 | ``` 25 | 26 | ## Build the Docker images 27 | 28 | We provide a script to build your image with the right L4T / ZED SDK version. 29 | 30 | * Checkout the tag or commit of the ROS2 wrapper that you need. 31 | 32 | ```bash 33 | git checkout 34 | ``` 35 | 36 | e.g. to build the master branch: 37 | 38 | ```bash 39 | git checkout master 40 | ``` 41 | 42 | * Build the image for **Jetson**: 43 | 44 | ```bash 45 | ./jetson_build_dockerfile_from_sdk_and_l4T_version.sh 46 | ``` 47 | 48 | * Build the image for **Desktop**: 49 | 50 | ```bash 51 | ./desktop_build_dockerfile_from_sdk_ubuntu_and_cuda_version.sh 52 | ``` 53 | 54 | Examples: 55 | 56 | ```bash 57 | # Jetson with JP6.0 and ZED SDK v4.2.5 58 | ./jetson_build_dockerfile_from_sdk_and_l4T_version.sh l4t-r36.3.0 zedsdk-4.2.5 59 | ``` 60 | 61 | ```bash 62 | # Jetson with JP6.2 and ZED SDK v5.0.0 63 | ./jetson_build_dockerfile_from_sdk_and_l4T_version.sh l4t-r36.4.0 zedsdk-5.0.0 64 | ``` 65 | 66 | ```bash 67 | # Desktop on Ubuntu 22.04m CUDA 12.6.3 and ZED SDK v4.2.5 68 | ./desktop_build_dockerfile_from_sdk_ubuntu_and_cuda_version.sh ubuntu-22.04 cuda-12.6.3 zedsdk-4.2.5 69 | ``` 70 | 71 | > :warning: Some configurations will not work. For example, if a specific ZED SDK does not exist for a given Ubuntu/CUDA/L4T version, or if the given ROS 2 wrapper is not compatible with the selected Ubuntu version. 72 | 73 | ## Run the Docker image 74 | 75 | ### NVIDIA runtime 76 | 77 | NVIDIA drivers must be accessible from the Docker image to run the ZED SDK code on the GPU. You'll need : 78 | 79 | * The `nvidia` container runtime installed, following [this guide](https://www.stereolabs.com/docs/docker/install-guide-linux/#nvidia-docker) 80 | * A specific docker runtime environment with `-gpus all` or `-e NVIDIA_DRIVER_CAPABILITIES=all` 81 | * Docker privileged mode with `--privileged` 82 | 83 | ### Network 84 | 85 | Setup the network configuration to enable the communication between the Docker image, other Docker images, and the host: 86 | 87 | * `--network=host`: Remove network isolation between the container and the Docker host 88 | * `--ipc=host`: Use the host system's Inter-Process Communication namespace 89 | * `--pid=host`: Use the host system's namespace for process ID 90 | 91 | ### Display context to use CUDA based applications 92 | 93 | Use the same host `DISPLAY` environment variable in every Docker image to enable CUDA-based applications with `-e DISPLAY=$DISPLAY`. 94 | 95 | > :pushpin: **NOTE**: the shared volume `/tmp/.X11-unix/:/tmp/.X11-unix` is also required. 96 | 97 | ### Volumes 98 | 99 | A few volumes should also be shared with the host. 100 | 101 | * `/tmp/.X11-unix/:/tmp/.X11-unix` is required to enable X11 server communication for CUDA-based applications 102 | * `/usr/local/zed/settings:/usr/local/zed/settings` if you plan to use the robot in an Internet-negated area, and you previously downloaded the camera calibration files by following [this guide](https://support.stereolabs.com/hc/en-us/articles/21614848880791-How-can-I-use-the-ZED-with-Docker-on-a-robot-with-no-internet-connection). 103 | * `/usr/local/zed/resources:/usr/local/zed/resources` if you plan to use the AI module of the ZED SDK (Object Detection, Skeleton Tracking, NEURAL depth) we suggest binding mounting a folder to avoid downloading and optimizing the AI models each time the Docker image is restarted. The first time you use the AI model inside the Docker image, it will be downloaded and optimized in the local bound-mounted folder, and stored there for the next runs. 104 | * If you plan to use different SDK versions in different Docker images it's preferred to use a different 105 | volume on the host for each of them: `//:/usr/local/zed/resources` 106 | * `/dev:/dev` to share the video devices 107 | * For GMSL2 cameras (ZED X, ZED X One) you'll also need 108 | * `/tmp:/tmp` 109 | * `/var/nvidia/nvcam/settings/:/var/nvidia/nvcam/settings/` 110 | * `/etc/systemd/system/zed_x_daemon.service:/etc/systemd/system/zed_x_daemon.service` 111 | * `/dev:/dev`: to share the video and other required devices 112 | * `/dev/shm:/dev/shm`: to use ROS 2 with shared memory 113 | 114 | ### Start the Docker container 115 | 116 | First of all, allow the container to access EGL display resources (required only once): 117 | 118 | ```bash 119 | sudo xhost +si:localuser:root 120 | ``` 121 | 122 | then you can start an interactive session: 123 | 124 | #### USB3 cameras 125 | 126 | ```bash 127 | docker run --runtime nvidia -it --privileged --network=host --ipc=host --pid=host \ 128 | -e NVIDIA_DRIVER_CAPABILITIES=all -e DISPLAY=$DISPLAY \ 129 | -v /tmp/.X11-unix/:/tmp/.X11-unix \ 130 | -v /dev:/dev \ 131 | -v /dev/shm:/dev/shm \ 132 | -v /usr/local/zed/resources/:/usr/local/zed/resources/ \ 133 | -v /usr/local/zed/settings/:/usr/local/zed/settings/ \ 134 | 135 | ``` 136 | 137 | #### GMSL cameras 138 | 139 | ```bash 140 | docker run --runtime nvidia -it --privileged --network=host --ipc=host --pid=host \ 141 | -e NVIDIA_DRIVER_CAPABILITIES=all -e DISPLAY=$DISPLAY \ 142 | -v /tmp:/tmp \ 143 | -v /dev:/dev \ 144 | -v /var/nvidia/nvcam/settings/:/var/nvidia/nvcam/settings/ \ 145 | -v /etc/systemd/system/zed_x_daemon.service:/etc/systemd/system/zed_x_daemon.service \ 146 | -v /usr/local/zed/resources/:/usr/local/zed/resources/ \ 147 | -v /usr/local/zed/settings/:/usr/local/zed/settings/ \ 148 | 149 | ``` 150 | -------------------------------------------------------------------------------- /docker/desktop_build_dockerfile_from_sdk_ubuntu_and_cuda_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd $(dirname $0) 3 | 4 | if [ "$#" -lt 3 ]; then 5 | echo "Give Ubuntu version then CUDA version then ZED SDK version has parameters, like this:" 6 | echo "./desktop_build_dockerfile_from_sdk_ubuntu_and_cuda_version.sh ubuntu-22.04 cuda-12.6.3 zedsdk-4.2.3" 7 | exit 1 8 | fi 9 | 10 | # Ubuntu version 11 | # Verify the format (l4t-r digits.digits.digits) 12 | if ! [[ $1 =~ ^ubuntu-[0-9]+\.[0-9]+$ ]]; then 13 | echo "Invalid Ubuntu version format." 14 | exit 1 15 | fi 16 | 17 | ubuntu_version=$1 18 | ubuntu_version_number="${ubuntu_version#ubuntu-}" 19 | 20 | # Split the string and assign to variables 21 | IFS='.' read -r ubuntu_major ubuntu_minor <<< "$ubuntu_version_number" 22 | echo "Ubuntu $ubuntu_major.$ubuntu_minor detected." 23 | 24 | # CUDA version 25 | # Verify the format (l4t-r digits.digits.digits) 26 | if ! [[ $2 =~ ^cuda-[0-9]+\.[0-9]\.[0-9]$ ]]; then 27 | echo "Invalid CUDA version format." 28 | exit 1 29 | fi 30 | 31 | cuda_version=$2 32 | cuda_version_number="${cuda_version#cuda-}" 33 | 34 | # Split the string and assign to variables 35 | IFS='.' read -r cuda_major cuda_minor cuda_patch <<< "$cuda_version_number" 36 | echo "CUDA $cuda_major.$cuda_minor.$cuda_patch detected." 37 | 38 | 39 | ZED_SDK_version=$3 40 | 41 | # copy the wrapper content 42 | rm -r ./tmp_sources 43 | mkdir -p ./tmp_sources 44 | cp -r ../zed* ./tmp_sources 45 | 46 | # Check if the third arg is a custom path 47 | CUSTOM_ZED_SDK_URL=$3 48 | # Use curl to check if the URL is valid (returns HTTP 200) 49 | if [ "$(curl -L -I "${CUSTOM_ZED_SDK_URL}" -o /dev/null -s -w '%{http_code}\n' | head -n 1)" = "200" ]; then 50 | echo "${ZED_SDK_version} detected as a valid custom installer URL" 51 | 52 | echo "Building dockerfile for $1, CUDA $2 and a custom ZED SDK" 53 | 54 | docker build -t zed_ros2_desktop_u${ubuntu_major}.${ubuntu_minor}_sdk_custom_cuda_${cuda_major}.${cuda_minor}.${cuda_patch} \ 55 | --build-arg CUSTOM_ZED_SDK_URL=$CUSTOM_ZED_SDK_URL \ 56 | --build-arg UBUNTU_MAJOR=$ubuntu_major \ 57 | --build-arg UBUNTU_MINOR=$ubuntu_minor \ 58 | --build-arg CUDA_MAJOR=$cuda_major \ 59 | --build-arg CUDA_MINOR=$cuda_minor \ 60 | --build-arg CUDA_PATCH=$cuda_patch \ 61 | -f ./Dockerfile.desktop-humble . 62 | else 63 | # Verify the ZED SDK format (digits.digits.digits) 64 | if ! [[ $3 =~ ^zedsdk-[0-9]\.[0-9]\.[0-9]$ ]]; then 65 | echo "Invalid ZED SDK version format." 66 | exit 1 67 | fi 68 | 69 | # Remove the prefix 'zedsdk-' 70 | zed_sdk_version_number="${ZED_SDK_version#zedsdk-}" 71 | 72 | # Split the string and assign to variables 73 | IFS='.' read -r sdk_major sdk_minor sdk_patch <<< "$zed_sdk_version_number" 74 | echo "ZED SDK $major.$minor.$patch detected." 75 | 76 | echo "Building dockerfile for $1, CUDA $2 and ZED SDK $3" 77 | 78 | docker build -t zed_ros2_desktop_u${ubuntu_major}.${ubuntu_minor}_sdk_${sdk_major}.${sdk_minor}.${sdk_patch}_cuda_${cuda_major}.${cuda_minor}.${cuda_patch} \ 79 | --build-arg ZED_SDK_MAJOR=$sdk_major \ 80 | --build-arg ZED_SDK_MINOR=$sdk_minor \ 81 | --build-arg ZED_SDK_PATCH=$sdk_patch \ 82 | --build-arg UBUNTU_MAJOR=$ubuntu_major \ 83 | --build-arg UBUNTU_MINOR=$ubuntu_minor \ 84 | --build-arg CUDA_MAJOR=$cuda_major \ 85 | --build-arg CUDA_MINOR=$cuda_minor \ 86 | --build-arg CUDA_PATCH=$cuda_patch \ 87 | -f ./Dockerfile.desktop-humble . 88 | fi 89 | 90 | ########### 91 | 92 | # Remove the temporary folder 93 | rm -r ./tmp_sources -------------------------------------------------------------------------------- /docker/jetson_build_dockerfile_from_sdk_and_l4T_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd $(dirname $0) 3 | 4 | if [ "$#" -lt 2 ]; then 5 | echo "Please enter valid L4T version and ZED SDK version has parameters. For example:" 6 | echo "./jetson_build_dockerfile_from_sdk_and_l4T_version.sh l4t-r36.3.0 zedsdk-4.2.5" 7 | exit 1 8 | fi 9 | 10 | # L4T version 11 | # Verify the format (l4t-r digits.digits.digits) 12 | if ! [[ $1 =~ ^l4t-r[0-9]+\.[0-9]+\.[0-9]+$ ]]; then 13 | echo "Invalid L4T version format." 14 | exit 1 15 | fi 16 | 17 | L4T_version=$1 18 | # Remove the prefix 'l4t-r' 19 | l4t_version_number="${L4T_version#l4t-r}" 20 | 21 | 22 | ZED_SDK_version=$2 23 | 24 | 25 | # copy the wrapper content 26 | rm -r ./tmp_sources 27 | mkdir -p ./tmp_sources 28 | cp -r ../zed* ./tmp_sources 29 | 30 | # Split the string and assign to variables 31 | IFS='.' read -r l4t_major l4t_minor l4t_patch <<< "$l4t_version_number" 32 | ########### 33 | 34 | L4T_VERSION=${1:-l4t-r${l4t_major}.${l4t_minor}.${l4t_patch}} 35 | 36 | # Determine the IMAGE_NAME based on the L4T_VERSION 37 | if [[ "$L4T_VERSION" == *"l4t-r36.4"* ]]; then 38 | IMAGE_NAME="dustynv/ros:humble-desktop-${L4T_VERSION}" 39 | else 40 | IMAGE_NAME="dustynv/ros:humble-ros-base-${L4T_VERSION}" 41 | fi 42 | 43 | # Check if the third arg is a custom path 44 | CUSTOM_ZED_SDK_URL=$2 45 | # Use curl to check if the URL is valid (returns HTTP 200) 46 | if [ "$(curl -L -I "${CUSTOM_ZED_SDK_URL}" -o /dev/null -s -w '%{http_code}\n' | head -n 1)" = "200" ]; then 47 | echo "${ZED_SDK_version} detected as a valid custom installer URL" 48 | 49 | echo "Building dockerfile for $1 and a custom ZED SDK" 50 | 51 | docker build -t zed_ros2_l4t_${l4t_major}.${l4t_minor}.${l4t_patch}_sdk_custom \ 52 | --build-arg CUSTOM_ZED_SDK_URL=$CUSTOM_ZED_SDK_URL \ 53 | --build-arg L4T_VERSION=$1 \ 54 | --build-arg L4T_MAJOR=$l4t_major \ 55 | --build-arg L4T_MINOR=$l4t_minor \ 56 | --build-arg IMAGE_NAME=$IMAGE_NAME \ 57 | -f ./Dockerfile.l4t-humble . 58 | else 59 | # Verify the ZED SDK format (digits.digits.digits) 60 | if ! [[ $2 =~ ^zedsdk-[0-9]+\.[0-9]+\.[0-9]+$ ]]; then 61 | echo "Invalid ZED SDK version format." 62 | exit 1 63 | fi 64 | 65 | # Remove the prefix 'zedsdk-' 66 | zed_sdk_version_number="${ZED_SDK_version#zedsdk-}" 67 | 68 | # Split the string and assign to variables 69 | IFS='.' read -r sdk_major sdk_minor sdk_patch <<< "$zed_sdk_version_number" 70 | 71 | echo "Building dockerfile for $1 and ZED SDK $2" 72 | 73 | docker build -t zed_ros2_l4t_${l4t_major}.${l4t_minor}.${l4t_patch}_sdk_${sdk_major}.${sdk_minor}.${sdk_patch} \ 74 | --build-arg ZED_SDK_MAJOR=$sdk_major \ 75 | --build-arg ZED_SDK_MINOR=$sdk_minor \ 76 | --build-arg ZED_SDK_PATCH=$sdk_patch \ 77 | --build-arg L4T_VERSION=$1 \ 78 | --build-arg L4T_MAJOR=$l4t_major \ 79 | --build-arg L4T_MINOR=$l4t_minor \ 80 | --build-arg IMAGE_NAME=$IMAGE_NAME \ 81 | -f ./Dockerfile.l4t-humble . 82 | fi 83 | 84 | # Remove the temporary folder 85 | rm -r ./tmp_sources -------------------------------------------------------------------------------- /docker/ros_entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # setup ros2 environment 5 | source "/opt/ros/$ROS_DISTRO/setup.bash" -- 6 | source "/root/ros2_ws/install/local_setup.bash" -- 7 | 8 | export ROS_DOMAIN_ID=0 9 | 10 | # Welcome information 11 | echo "ZED ROS2 Docker Image" 12 | echo "---------------------" 13 | echo 'ROS distro: ' $ROS_DISTRO 14 | echo 'DDS middleware: ' $RMW_IMPLEMENTATION 15 | echo 'ROS 2 Workspaces:' $COLCON_PREFIX_PATH 16 | echo 'ROS 2 Domain ID:' $ROS_DOMAIN_ID 17 | echo ' * Note: Host and Docker image Domain ID must match to allow communication' 18 | echo 'Local IPs:' $(hostname -I) 19 | echo "---" 20 | echo 'Available ZED packages:' 21 | ros2 pkg list | grep zed 22 | echo "---------------------" 23 | echo 'To start a ZED camera node:' 24 | echo ' ros2 launch zed_wrapper zed_camera.launch.py camera_model:=' 25 | echo "---------------------" 26 | exec "$@" 27 | -------------------------------------------------------------------------------- /docker/ros_entrypoint_jetson.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # setup ros2 environment 5 | source "/opt/ros/$ROS_DISTRO/install/setup.bash" 6 | source "/root/ros2_ws/install/local_setup.bash" 7 | 8 | export ROS_DOMAIN_ID=0 9 | 10 | # Welcome information 11 | echo "ZED ROS2 Docker Image" 12 | echo "---------------------" 13 | echo 'ROS distro: ' $ROS_DISTRO 14 | echo 'DDS middleware: ' $RMW_IMPLEMENTATION 15 | echo 'ROS 2 Workspaces:' $COLCON_PREFIX_PATH 16 | echo 'ROS 2 Domain ID:' $ROS_DOMAIN_ID 17 | echo ' * Note: Host and Docker image Domain ID must match to allow communication' 18 | echo 'Local IPs:' $(hostname -I) 19 | echo "---" 20 | echo 'Available ZED packages:' 21 | ros2 pkg list | grep zed 22 | echo "---------------------" 23 | echo 'To start a ZED camera node:' 24 | echo ' ros2 launch zed_wrapper zed_camera.launch.py camera_model:=' 25 | echo "---------------------" 26 | exec "$@" 27 | -------------------------------------------------------------------------------- /images/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereolabs/zed-ros2-wrapper/ec8a0b4c8c9b0b6b4c7fab63b026fbf69ee00d74/images/.gitkeep -------------------------------------------------------------------------------- /images/Picto+STEREOLABS_Black.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereolabs/zed-ros2-wrapper/ec8a0b4c8c9b0b6b4c7fab63b026fbf69ee00d74/images/Picto+STEREOLABS_Black.jpg -------------------------------------------------------------------------------- /images/PointCloud_Depth_ROS.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereolabs/zed-ros2-wrapper/ec8a0b4c8c9b0b6b4c7fab63b026fbf69ee00d74/images/PointCloud_Depth_ROS.jpg -------------------------------------------------------------------------------- /images/depth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereolabs/zed-ros2-wrapper/ec8a0b4c8c9b0b6b4c7fab63b026fbf69ee00d74/images/depth.jpg -------------------------------------------------------------------------------- /images/point_cloud.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereolabs/zed-ros2-wrapper/ec8a0b4c8c9b0b6b4c7fab63b026fbf69ee00d74/images/point_cloud.jpg -------------------------------------------------------------------------------- /images/rgb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereolabs/zed-ros2-wrapper/ec8a0b4c8c9b0b6b4c7fab63b026fbf69ee00d74/images/rgb.jpg -------------------------------------------------------------------------------- /images/sim_rviz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereolabs/zed-ros2-wrapper/ec8a0b4c8c9b0b6b4c7fab63b026fbf69ee00d74/images/sim_rviz.jpg -------------------------------------------------------------------------------- /images/zed_shelves.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereolabs/zed-ros2-wrapper/ec8a0b4c8c9b0b6b4c7fab63b026fbf69ee00d74/images/zed_shelves.jpg -------------------------------------------------------------------------------- /zed_components/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(zed_components) 3 | 4 | ################################################ 5 | ## Generate symbols for IDE indexer (VSCode) 6 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 7 | 8 | ################################################ 9 | # Check the ROS2 version 10 | 11 | set(ROS2_FOUND FALSE) 12 | if(DEFINED ENV{ROS_DISTRO}) 13 | set(FOUND_ROS2_DISTRO $ENV{ROS_DISTRO}) 14 | set(ROS2_FOUND TRUE) 15 | #message("* Found ROS2 ${FOUND_ROS2_DISTRO}") 16 | else() 17 | message("* ROS2 distro variable not set. Trying to figure it out...") 18 | set(ROS2_DISTROS "ardent;crystal;dashing;eloquent;foxy;galactic;humble;jazzy;rolling") 19 | set(ROS2_FOUND FALSE) 20 | foreach(distro ${ROS2_DISTROS}) 21 | if(NOT ROS2_FOUND) 22 | find_path(RCLCPP_H rclcpp.hpp PATHS /opt/ros/${distro}/include/rclcpp) 23 | if(RCLCPP_H) 24 | #message("* Found ROS2 ${distro}") 25 | set(FOUND_ROS2_DISTRO ${distro}) 26 | set(ROS2_FOUND TRUE) 27 | endif() 28 | endif() 29 | endforeach() 30 | endif() 31 | 32 | if(ROS2_FOUND) 33 | if(${FOUND_ROS2_DISTRO} STREQUAL "foxy") 34 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 35 | add_definitions(-DFOUND_FOXY) 36 | elseif(${FOUND_ROS2_DISTRO} STREQUAL "humble") 37 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 38 | add_definitions(-DFOUND_HUMBLE) 39 | elseif(${FOUND_ROS2_DISTRO} STREQUAL "iron") 40 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 41 | add_definitions(-DFOUND_IRON) 42 | elseif(${FOUND_ROS2_DISTRO} STREQUAL "jazzy") 43 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 44 | add_definitions(-DFOUND_JAZZY) 45 | else() 46 | message("*** WARNING *** Unsupported ROS2 ${FOUND_ROS2_DISTRO}. '${PROJECT_NAME}' may not work correctly.") 47 | endif() 48 | else() 49 | message("*** WARNING *** ROS2 distro is unknown. This package could not work correctly.") 50 | endif() 51 | ################################################ 52 | 53 | # Default to C99 54 | if(NOT CMAKE_C_STANDARD) 55 | set(CMAKE_C_STANDARD 99) 56 | endif() 57 | 58 | # Default to C++17 59 | if(NOT CMAKE_CXX_STANDARD) 60 | set(CMAKE_CXX_STANDARD 17) 61 | endif() 62 | 63 | # if CMAKE_BUILD_TYPE is not specified, take 'Release' as default 64 | if(NOT CMAKE_BUILD_TYPE) 65 | set(CMAKE_BUILD_TYPE Release) 66 | endif() 67 | 68 | if(CMAKE_BUILD_TYPE MATCHES Release) 69 | #message(" * Release Mode") 70 | add_compile_options(-Wno-deprecated-declarations) 71 | endif() 72 | 73 | if(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) 74 | #message(" * Release with Debug Info Mode") 75 | add_compile_options(-Wno-deprecated-declarations) 76 | endif() 77 | 78 | if(CMAKE_BUILD_TYPE MATCHES Debug) 79 | message(" * Debug Mode") 80 | endif() 81 | 82 | ############################################# 83 | # Dependencies 84 | find_package(ZED REQUIRED) 85 | 86 | exec_program(uname ARGS -p OUTPUT_VARIABLE CMAKE_SYSTEM_NAME2) 87 | if(CMAKE_SYSTEM_NAME2 MATCHES "aarch64") # Jetson TX 88 | set(CUDA_USE_STATIC_CUDA_RUNTIME OFF) 89 | endif() 90 | 91 | find_package(CUDA REQUIRED) 92 | 93 | set(DEPENDENCIES 94 | rclcpp 95 | rclcpp_components 96 | image_transport 97 | builtin_interfaces 98 | std_msgs 99 | rosgraph_msgs 100 | tf2 101 | tf2_ros 102 | tf2_geometry_msgs 103 | geometry_msgs 104 | nav_msgs 105 | nmea_msgs 106 | geographic_msgs 107 | sensor_msgs 108 | stereo_msgs 109 | zed_msgs 110 | std_srvs 111 | diagnostic_msgs 112 | diagnostic_updater 113 | visualization_msgs 114 | shape_msgs 115 | robot_localization 116 | backward_ros 117 | ) 118 | 119 | find_package(ament_cmake_auto REQUIRED) 120 | ament_auto_find_build_dependencies() 121 | 122 | find_package(rcutils REQUIRED) 123 | find_package(zed_msgs) 124 | find_package(rclcpp REQUIRED) 125 | find_package(rclcpp_components REQUIRED) 126 | find_package(builtin_interfaces REQUIRED) 127 | find_package(std_msgs REQUIRED) 128 | find_package(rosgraph_msgs REQUIRED) 129 | find_package(tf2 REQUIRED) 130 | find_package(tf2_ros REQUIRED) 131 | find_package(tf2_geometry_msgs REQUIRED) 132 | find_package(geometry_msgs REQUIRED) 133 | find_package(nav_msgs REQUIRED) 134 | find_package(nmea_msgs REQUIRED) 135 | find_package(geographic_msgs REQUIRED) 136 | find_package(sensor_msgs REQUIRED) 137 | find_package(stereo_msgs REQUIRED) 138 | find_package(backward_ros REQUIRED) 139 | 140 | find_package(image_transport REQUIRED) 141 | find_package(std_srvs REQUIRED) 142 | find_package(diagnostic_msgs REQUIRED) 143 | find_package(diagnostic_updater REQUIRED) 144 | find_package(visualization_msgs REQUIRED) 145 | find_package(shape_msgs REQUIRED) 146 | find_package(robot_localization REQUIRED) 147 | 148 | if(NOT ${FOUND_ROS2_DISTRO} STREQUAL "foxy") 149 | find_package(point_cloud_transport REQUIRED) 150 | list(APPEND DEPENDENCIES point_cloud_transport) 151 | endif() 152 | 153 | if(BUILD_TESTING) 154 | find_package(ament_lint_auto REQUIRED) 155 | ament_lint_auto_find_test_dependencies() 156 | endif() 157 | 158 | ############################################################################### 159 | #Add all files in subdirectories of the project in 160 | # a dummy_target so qtcreator have access to all files 161 | file(GLOB_RECURSE all_files ${CMAKE_SOURCE_DIR}/*) 162 | add_custom_target(all_${PROJECT_NAME}_files SOURCES ${all_files}) 163 | 164 | ############################################################################### 165 | # LIBS 166 | 167 | 168 | # create ament index resource which references the libraries in the binary dir 169 | set(node_plugins "") 170 | 171 | link_directories(${ZED_LIBRARY_DIR}) 172 | link_directories(${CUDA_LIBRARY_DIRS}) 173 | 174 | set(ZED_LIBS 175 | ${ZED_LIBRARIES} 176 | ${CUDA_LIBRARIES} 177 | ) 178 | 179 | ############################################################################### 180 | # SOURCES 181 | set(SL_TOOLS_INC 182 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/include/sl_tools.hpp 183 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/include/sl_win_avg.hpp 184 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/include/sl_logging.hpp 185 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/include/json.hpp 186 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/include/gnss_replay.hpp 187 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/include/sl_types.hpp 188 | ) 189 | 190 | set(SL_TOOLS_SRC 191 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/src/sl_tools.cpp 192 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/src/sl_win_avg.cpp 193 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/src/gnss_replay.cpp 194 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/src/sl_types.cpp 195 | ) 196 | 197 | set(ZED_CAMERA_INC 198 | ${CMAKE_CURRENT_SOURCE_DIR}/src/include/visibility_control.hpp 199 | ${CMAKE_CURRENT_SOURCE_DIR}/src/zed_camera/include/zed_camera_component.hpp 200 | ) 201 | 202 | set(ZED_CAMERA_SRC 203 | ${CMAKE_CURRENT_SOURCE_DIR}/src/zed_camera/src/zed_camera_component_main.cpp 204 | ${CMAKE_CURRENT_SOURCE_DIR}/src/zed_camera/src/zed_camera_component_objdet.cpp 205 | ${CMAKE_CURRENT_SOURCE_DIR}/src/zed_camera/src/zed_camera_component_bodytrk.cpp 206 | ) 207 | 208 | set(ZED_CAMERA_ONE_INC 209 | ${CMAKE_CURRENT_SOURCE_DIR}/src/include/visibility_control.hpp 210 | ${CMAKE_CURRENT_SOURCE_DIR}/src/zed_camera/include/zed_camera_one_component.hpp 211 | ) 212 | 213 | set(ZED_CAMERA_ONE_SRC 214 | ${CMAKE_CURRENT_SOURCE_DIR}/src/zed_camera/src/zed_camera_one_component.cpp 215 | ) 216 | ############################################################################### 217 | # Bin and Install 218 | 219 | # ZED Camera Component 220 | add_library(zed_camera_component SHARED 221 | ${SL_TOOLS_INC} 222 | ${SL_TOOLS_SRC} 223 | ${ZED_CAMERA_INC} 224 | ${ZED_CAMERA_SRC} 225 | ) 226 | target_include_directories(zed_camera_component PUBLIC 227 | ${CUDA_INCLUDE_DIRS} 228 | ${ZED_INCLUDE_DIRS} 229 | ${CMAKE_CURRENT_SOURCE_DIR}/src/include 230 | ${CMAKE_CURRENT_SOURCE_DIR}/src/zed_camera/include 231 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/include 232 | ) 233 | target_compile_definitions(zed_camera_component 234 | PRIVATE "COMPOSITION_BUILDING_DLL" 235 | ) 236 | target_link_libraries(zed_camera_component 237 | ${ZED_LIBS} 238 | ) 239 | ament_target_dependencies(zed_camera_component 240 | ${DEPENDENCIES} 241 | ) 242 | 243 | rclcpp_components_register_nodes(zed_camera_component "stereolabs::ZedCamera") 244 | set(node_plugins "${node_plugins}stereolabs::ZedCamera;$\n") 245 | 246 | # ZED Camera One Component 247 | add_library(zed_camera_one_component SHARED 248 | ${SL_TOOLS_INC} 249 | ${SL_TOOLS_SRC} 250 | ${ZED_CAMERA_ONE_INC} 251 | ${ZED_CAMERA_ONE_SRC} 252 | ) 253 | target_include_directories(zed_camera_one_component PUBLIC 254 | ${CUDA_INCLUDE_DIRS} 255 | ${ZED_INCLUDE_DIRS} 256 | ${CMAKE_CURRENT_SOURCE_DIR}/src/include 257 | ${CMAKE_CURRENT_SOURCE_DIR}/src/zed_camera/include 258 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/include 259 | ) 260 | target_compile_definitions(zed_camera_one_component 261 | PRIVATE "COMPOSITION_BUILDING_DLL" 262 | ) 263 | target_link_libraries(zed_camera_one_component 264 | ${ZED_LIBS} 265 | ) 266 | ament_target_dependencies(zed_camera_one_component 267 | ${DEPENDENCIES} 268 | ) 269 | 270 | rclcpp_components_register_nodes(zed_camera_one_component "stereolabs::ZedCameraOne") 271 | set(node_plugins "${node_plugins}stereolabs::ZedCameraOne;$\n") 272 | 273 | # Install components 274 | install(TARGETS zed_camera_component zed_camera_one_component 275 | ARCHIVE DESTINATION lib 276 | LIBRARY DESTINATION lib 277 | RUNTIME DESTINATION lib/${PROJECT_NAME} 278 | ) 279 | 280 | # Install header files 281 | install(DIRECTORY 282 | ${CMAKE_CURRENT_SOURCE_DIR}/src/zed_camera/include/ 283 | ${CMAKE_CURRENT_SOURCE_DIR}/src/tools/include/ 284 | ${CMAKE_CURRENT_SOURCE_DIR}/src/include/ 285 | DESTINATION include/${PROJECT_NAME}/ 286 | ) 287 | 288 | ament_export_include_directories(include) 289 | ament_export_libraries( 290 | zed_camera_component 291 | zed_camera_one_component 292 | ) 293 | ament_export_dependencies(${DEPENDENCIES}) 294 | ament_package() 295 | -------------------------------------------------------------------------------- /zed_components/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | zed_components 5 | 5.0.0 6 | Contains the main ROS2 components to use a camera of the Ztereolabs ZED family 7 | STEREOLABS 8 | Apache License 2.0 9 | https://www.stereolabs.com/ 10 | https://github.com/stereolabs/zed-ros2-wrapper 11 | https://github.com/stereolabs/zed-ros2-wrapper/issues 12 | ament_cmake 13 | ament_cmake_auto 14 | 15 | zed_msgs 16 | rclcpp 17 | rclcpp_components 18 | rcutils 19 | builtin_interfaces 20 | std_msgs 21 | rosgraph_msgs 22 | stereo_msgs 23 | sensor_msgs 24 | geometry_msgs 25 | nav_msgs 26 | nmea_msgs 27 | geographic_msgs 28 | tf2 29 | tf2_ros 30 | tf2_geometry_msgs 31 | image_transport 32 | point_cloud_transport 33 | std_srvs 34 | diagnostic_msgs 35 | diagnostic_updater 36 | visualization_msgs 37 | robot_localization 38 | backward_ros 39 | launch_ros 40 | zed_msgs 41 | rclcpp 42 | rclcpp_components 43 | rcutils 44 | builtin_interfaces 45 | std_msgs 46 | rosgraph_msgs 47 | stereo_msgs 48 | sensor_msgs 49 | geometry_msgs 50 | nav_msgs 51 | nmea_msgs 52 | geographic_msgs 53 | tf2 54 | tf2_ros 55 | tf2_geometry_msgs 56 | image_transport 57 | diagnostic_msgs 58 | diagnostic_updater 59 | visualization_msgs 60 | robot_localization 61 | image_transport_plugins 62 | compressed_image_transport 63 | compressed_depth_image_transport 64 | theora_image_transport 65 | point_cloud_transport_plugins 66 | draco_point_cloud_transport 67 | zlib_point_cloud_transport 68 | zstd_point_cloud_transport 69 | backward_ros 70 | ament_lint_auto 71 | ament_cmake_copyright 72 | ament_cmake_cppcheck 73 | ament_cmake_lint_cmake 74 | ament_cmake_pep257 75 | ament_cmake_uncrustify 76 | ament_cmake_xmllint 77 | 78 | ament_cmake 79 | 80 | 81 | -------------------------------------------------------------------------------- /zed_components/src/include/visibility_control.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Stereolabs 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef VISIBILITY_CONTROL_HPP_ 16 | #define VISIBILITY_CONTROL_HPP_ 17 | 18 | /* *INDENT-OFF* */ 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | /* *INDENT-ON* */ 23 | 24 | // This logic was borrowed (then namespaced) from the examples on the gcc wiki: 25 | // https://gcc.gnu.org/wiki/Visibility 26 | 27 | #if defined _WIN32 || defined __CYGWIN__ 28 | #ifdef __GNUC__ 29 | #define ZED_COMPONENTS_EXPORT __attribute__((dllexport)) 30 | #define ZED_COMPONENTS_IMPORT __attribute__((dllimport)) 31 | #else 32 | #define ZED_COMPONENTS_EXPORT __declspec(dllexport) 33 | #define ZED_COMPONENTS_IMPORT __declspec(dllimport) 34 | #endif 35 | #ifdef ZED_COMPONENTS_BUILDING_DLL 36 | #define ZED_COMPONENTS_PUBLIC ZED_COMPONENTS_EXPORT 37 | #else 38 | #define ZED_COMPONENTS_PUBLIC ZED_COMPONENTS_IMPORT 39 | #endif 40 | #define ZED_COMPONENTS_PUBLIC_TYPE ZED_COMPONENTS_PUBLIC 41 | #define ZED_COMPONENTS_LOCAL 42 | #else 43 | #define ZED_COMPONENTS_EXPORT __attribute__((visibility("default"))) 44 | #define ZED_COMPONENTS_IMPORT 45 | #if __GNUC__ >= 4 46 | #define ZED_COMPONENTS_PUBLIC __attribute__((visibility("default"))) 47 | #define ZED_COMPONENTS_LOCAL __attribute__((visibility("hidden"))) 48 | #else 49 | #define ZED_COMPONENTS_PUBLIC 50 | #define ZED_COMPONENTS_LOCAL 51 | #endif 52 | #define ZED_COMPONENTS_PUBLIC_TYPE 53 | #endif 54 | 55 | /* *INDENT-OFF* */ 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | /* *INDENT-ON* */ 60 | 61 | #endif // VISIBILITY_CONTROL_HPP_ 62 | -------------------------------------------------------------------------------- /zed_components/src/tools/include/gnss_replay.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GPSD_Replay_H 2 | #define GPSD_Replay_H 3 | 4 | #include 5 | #include 6 | 7 | #include "json.hpp" 8 | 9 | namespace sl_tools 10 | { 11 | 12 | /** 13 | * @brief GNSSReplay is a common interface that read GNSS saved data 14 | */ 15 | class GNSSReplay 16 | { 17 | public: 18 | explicit GNSSReplay(const std::shared_ptr & zed); 19 | ~GNSSReplay(); 20 | bool initialize(); 21 | void close(); 22 | 23 | sl::FUSION_ERROR_CODE grab(sl::GNSSData & current_data, uint64_t current_timestamp); 24 | 25 | protected: 26 | sl::GNSSData getNextGNSSValue(uint64_t current_timestamp); 27 | 28 | private: 29 | unsigned _current_gnss_idx = 0; 30 | unsigned long long _previous_ts = 0; 31 | unsigned long long _last_cam_ts = 0; 32 | nlohmann::json _gnss_data; 33 | 34 | std::shared_ptr _zed; 35 | }; 36 | 37 | } // namespace sl_tools 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /zed_components/src/tools/include/sl_logging.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Stereolabs 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef SL_LOGGING_HPP 16 | #define SL_LOGGING_HPP 17 | 18 | #include 19 | 20 | // ----> DEBUG MACROS 21 | // Common 22 | #define DEBUG_COMM(...) \ 23 | if (_debugCommon) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 24 | #define DEBUG_STREAM_COMM(stream_arg) \ 25 | if (_debugCommon) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 26 | #define DEBUG_STREAM_COMM_ONCE(stream_arg) \ 27 | if (_debugCommon) RCLCPP_DEBUG_STREAM_ONCE(get_logger(), stream_arg) 28 | 29 | // Simulation 30 | #define DEBUG_SIM(...) \ 31 | if (_debugSim) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 32 | #define DEBUG_ONCE_SIM(...) \ 33 | if (_debugSim) RCLCPP_DEBUG_ONCE(get_logger(), __VA_ARGS__) 34 | #define DEBUG_STREAM_SIM(stream_arg) \ 35 | if (_debugSim) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 36 | #define DEBUG_STREAM_THROTTLE_SIM(duration, stream_arg) \ 37 | if (_debugSim) { \ 38 | rclcpp::Clock steady_clock(RCL_STEADY_TIME); \ 39 | RCLCPP_DEBUG_STREAM_THROTTLE( \ 40 | get_logger(), steady_clock, duration, \ 41 | stream_arg); \ 42 | } 43 | 44 | // Advanced 45 | #define DEBUG_ADV(...) \ 46 | if (_debugAdvanced) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 47 | #define DEBUG_ONCE_ADV(...) \ 48 | if (_debugAdvanced) RCLCPP_DEBUG_ONCE(get_logger(), __VA_ARGS__) 49 | #define DEBUG_STREAM_ADV(stream_arg) \ 50 | if (_debugAdvanced) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 51 | #define DEBUG_STREAM_THROTTLE_ADV(duration, stream_arg) \ 52 | if (_debugAdvanced) { \ 53 | rclcpp::Clock steady_clock(RCL_STEADY_TIME); \ 54 | RCLCPP_DEBUG_STREAM_THROTTLE( \ 55 | get_logger(), steady_clock, duration, \ 56 | stream_arg); \ 57 | } 58 | 59 | // Video Depth 60 | #define DEBUG_VD(...) \ 61 | if (_debugVideoDepth) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 62 | #define DEBUG_STREAM_VD(stream_arg) \ 63 | if (_debugVideoDepth) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 64 | 65 | // Camera Controls settings 66 | #define DEBUG_CTRL(...) \ 67 | if (_debugCamCtrl) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 68 | #define DEBUG_STREAM_CTRL(stream_arg) \ 69 | if (_debugCamCtrl) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 70 | 71 | // Point Cloud 72 | #define DEBUG_PC(...) \ 73 | if (_debugPointCloud) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 74 | #define DEBUG_STREAM_PC(stream_arg) \ 75 | if (_debugPointCloud) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 76 | 77 | // Positional Tracking 78 | #define DEBUG_PT(...) \ 79 | if (_debugPosTracking) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 80 | #define DEBUG_ONCE_PT(...) \ 81 | if (_debugPosTracking) RCLCPP_DEBUG_ONCE(get_logger(), __VA_ARGS__) 82 | #define DEBUG_STREAM_PT(stream_arg) \ 83 | if (_debugPosTracking) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 84 | #define DEBUG_STREAM_THROTTLE_PT(duration, stream_arg) \ 85 | if (_debugPosTracking) { \ 86 | rclcpp::Clock steady_clock(RCL_STEADY_TIME); \ 87 | RCLCPP_DEBUG_STREAM_THROTTLE( \ 88 | get_logger(), steady_clock, duration, \ 89 | stream_arg); \ 90 | } 91 | 92 | // GNSS integration 93 | #define DEBUG_GNSS(...) \ 94 | if (_debugGnss) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 95 | #define DEBUG_STREAM_GNSS(stream_arg) \ 96 | if (_debugGnss) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 97 | #define DEBUG_STREAM_THROTTLE_GNSS(duration, stream_arg) \ 98 | if (_debugGnss) { \ 99 | rclcpp::Clock steady_clock(RCL_STEADY_TIME); \ 100 | RCLCPP_DEBUG_STREAM_THROTTLE( \ 101 | get_logger(), steady_clock, duration, \ 102 | stream_arg); \ 103 | } 104 | 105 | // Sensors 106 | #define DEBUG_SENS(...) \ 107 | if (_debugSensors) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 108 | #define DEBUG_STREAM_SENS(stream_arg) \ 109 | if (_debugSensors) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 110 | #define DEBUG_STREAM_ONCE_SENS(stream_arg) \ 111 | if (_debugSensors) RCLCPP_DEBUG_STREAM_ONCE(get_logger(), stream_arg) 112 | 113 | // Mapping 114 | #define DEBUG_MAP(...) \ 115 | if (_debugMapping) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 116 | #define DEBUG_STREAM_MAP(stream_arg) \ 117 | if (_debugMapping) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 118 | #define DEBUG_STREAM_ONCE_MAP(stream_arg) \ 119 | if (_debugMapping) RCLCPP_DEBUG_STREAM_ONCE(get_logger(), stream_arg) 120 | 121 | // Object Detection 122 | #define DEBUG_OD(...) \ 123 | if (_debugObjectDet) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 124 | #define DEBUG_STREAM_OD(stream_arg) \ 125 | if (_debugObjectDet) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 126 | 127 | // Body Tracking 128 | #define DEBUG_BT(...) \ 129 | if (_debugBodyTrk) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 130 | #define DEBUG_STREAM_BT(stream_arg) \ 131 | if (_debugBodyTrk) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 132 | 133 | // Region of Interest 134 | #define DEBUG_ROI(...) \ 135 | if (_debugRoi) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 136 | #define DEBUG_ONCE_ROI(...) \ 137 | if (_debugRoi) RCLCPP_DEBUG_ONCE(get_logger(), __VA_ARGS__) 138 | #define DEBUG_STREAM_ROI(stream_arg) \ 139 | if (_debugRoi) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 140 | #define DEBUG_STREAM_THROTTLE_ROI(duration, stream_arg) \ 141 | if (_debugRoi) { \ 142 | rclcpp::Clock steady_clock(RCL_STEADY_TIME); \ 143 | RCLCPP_DEBUG_STREAM_THROTTLE( \ 144 | get_logger(), steady_clock, duration, \ 145 | stream_arg); \ 146 | } 147 | 148 | // Streaming 149 | #define DEBUG_STR(...) \ 150 | if (_debugStreaming) RCLCPP_DEBUG(get_logger(), __VA_ARGS__) 151 | #define DEBUG_ONCE_STR(...) \ 152 | if (_debugStreaming) RCLCPP_DEBUG_ONCE(get_logger(), __VA_ARGS__) 153 | #define DEBUG_STREAM_STR(stream_arg) \ 154 | if (_debugStreaming) RCLCPP_DEBUG_STREAM(get_logger(), stream_arg) 155 | #define DEBUG_STREAM_THROTTLE_STR(duration, stream_arg) \ 156 | if (_debugStreaming) { \ 157 | rclcpp::Clock steady_clock(RCL_STEADY_TIME); \ 158 | RCLCPP_DEBUG_STREAM_THROTTLE( \ 159 | get_logger(), steady_clock, duration, \ 160 | stream_arg); \ 161 | } 162 | // <---- DEBUG MACROS 163 | 164 | #endif // SL_LOGGING_HPP_ 165 | -------------------------------------------------------------------------------- /zed_components/src/tools/include/sl_tools.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Stereolabs 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef SL_TOOLS_HPP_ 16 | #define SL_TOOLS_HPP_ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "gnss_replay.hpp" 29 | #include "sl_win_avg.hpp" 30 | 31 | #include 32 | 33 | namespace sl_tools 34 | { 35 | 36 | /*! \brief Get a parameter from the node 37 | * \param node : the node to get the parameter from 38 | * \param paramName : the name of the parameter 39 | * \param defValue : the default value of the parameter 40 | * \param outVal : the output value of the parameter 41 | * \param log_info : the info to log 42 | * \param dynamic : if the parameter is dynamic 43 | * \param min : the minimum value of the parameter 44 | * \param max : the maximum value of the parameter 45 | * \tparam T : the type of the parameter 46 | */ 47 | template 48 | void getParam( 49 | const std::shared_ptr node, 50 | std::string paramName, T defValue, T & outVal, 51 | std::string log_info = std::string(), bool dynamic = false, 52 | T minVal = std::numeric_limits::min(), T maxVal = std::numeric_limits::max()); 53 | 54 | /*! \brief Convert a sl::float3 to a vector of float 55 | * \param r : the sl::float3 to convert 56 | * \return a vector of float 57 | */ 58 | std::vector convertRodrigues(sl::float3 r); 59 | 60 | /*! \brief Test if a file exist 61 | * \param name : the path to the file 62 | */ 63 | bool file_exist(const std::string & name); 64 | 65 | /*! \brief Get Stereolabs SDK version 66 | * \param major : major value for version 67 | * \param minor : minor value for version 68 | * \param sub_minor _ sub_minor value for version 69 | */ 70 | std::string getSDKVersion(int & major, int & minor, int & sub_minor); 71 | 72 | /*! \brief Convert StereoLabs timestamp to ROS timestamp 73 | * \param t : Stereolabs timestamp to be converted 74 | * \param t : ROS2 clock type 75 | */ 76 | rclcpp::Time slTime2Ros(sl::Timestamp t, rcl_clock_type_t clock_type = RCL_ROS_TIME); 77 | 78 | /*! \brief check if ZED 79 | * \param camModel the model to check 80 | */ 81 | bool isZED(sl::MODEL camModel); 82 | 83 | /*! \brief check if ZED Mini 84 | * \param camModel the model to check 85 | */ 86 | bool isZEDM(sl::MODEL camModel); 87 | 88 | /*! \brief check if ZED2 or ZED2i 89 | * \param camModel the model to check 90 | */ 91 | bool isZED2OrZED2i(sl::MODEL camModel); 92 | 93 | /*! \brief check if ZED-X or ZED-X Mini 94 | * \param camModel the model to check 95 | */ 96 | bool isZEDX(sl::MODEL camModel); 97 | 98 | /*! \brief check if Object Detection is available 99 | * \param camModel the camera model to check 100 | */ 101 | bool isObjDetAvailable(sl::MODEL camModel); 102 | 103 | /*! \brief sl::Mat to ros message conversion 104 | * \param img : the image to publish 105 | * \param frameId : the id of the reference frame of the image 106 | * \param t : rclcpp ros::Time to stamp the image 107 | */ 108 | std::unique_ptr imageToROSmsg( 109 | const sl::Mat & img, const std::string & frameId, const rclcpp::Time & t); 110 | 111 | /*! \brief sl::Mat to ros message conversion 112 | * \param left : the left image to convert and stitch 113 | * \param right : the right image to convert and stitch 114 | * \param frameId : the id of the reference frame of the image 115 | * \param t : rclcpp rclcpp::Time to stamp the image 116 | */ 117 | std::unique_ptr imagesToROSmsg( 118 | const sl::Mat & left, const sl::Mat & right, const std::string & frameId, 119 | const rclcpp::Time & t); 120 | 121 | /*! \brief qos value to string 122 | * \param qos the value to convert 123 | */ 124 | std::string qos2str(rmw_qos_history_policy_t qos); 125 | 126 | /*! \brief qos value to string 127 | * \param qos the value to convert 128 | */ 129 | std::string qos2str(rmw_qos_reliability_policy_t qos); 130 | 131 | /*! \brief qos value to string 132 | * \param qos the value to convert 133 | */ 134 | std::string qos2str(rmw_qos_durability_policy_t qos); 135 | 136 | /*! \brief Creates an sl::Mat containing a ROI from a polygon 137 | * \param poly the ROI polygon. Coordinates must be normalized from 0.0 to 1.0 138 | * \param out_roi the `sl::Mat` containing the ROI 139 | */ 140 | bool generateROI(const std::vector & poly, sl::Mat & out_roi); 141 | 142 | /*! \brief Parse a vector of vector of floats from a string. 143 | * \param input 144 | * \param error_return 145 | * Syntax is [[1.0, 2.0], [3.3, 4.4, 5.5], ...] */ 146 | std::vector> parseStringVector( 147 | const std::string & input, std::string & error_return); 148 | 149 | /*! 150 | * @brief Convert thread policy to string 151 | * @param thread_sched_policy 152 | * @return policy string 153 | */ 154 | std::string threadSched2Str(int thread_sched_policy); 155 | 156 | /*! 157 | * @brief check if root is available 158 | * @return true if root 159 | */ 160 | bool checkRoot(); 161 | 162 | /*! 163 | * @brief Convert seconds to string in format DD:HH:MM:SS 164 | * @param sec seconds 165 | * @return string 166 | */ 167 | std::string seconds2str(double sec); 168 | 169 | /*! 170 | * @brief read custom OD labels from a COCO-Like YAML file 171 | * @param label_file label file full path 172 | * @param out_labels the map containing the labels. The map idx corresponds to the class ID 173 | * @return true if successfull 174 | */ 175 | bool ReadCocoYaml( 176 | const std::string & label_file, std::unordered_map & out_labels); 178 | 179 | /** 180 | * @brief Stop Timer used to measure time intervals 181 | * 182 | */ 183 | class StopWatch 184 | { 185 | public: 186 | explicit StopWatch(rclcpp::Clock::SharedPtr clock); 187 | ~StopWatch() {} 188 | 189 | void tic(); //!< Set the reference time point to the current time 190 | double toc(std::string func_name = std::string() ); //!< Returns the seconds elapsed from the last tic in ROS clock reference (it works also in simulation) 191 | 192 | private: 193 | rclcpp::Time mStartTime; // Reference time point 194 | rclcpp::Clock::SharedPtr mClockPtr; // Node clock interface 195 | }; 196 | 197 | // ----> Template functions definitions 198 | template 199 | void getParam( 200 | const std::shared_ptr node, 201 | std::string paramName, T defValue, T & outVal, 202 | std::string log_info, bool dynamic, 203 | T minVal, T maxVal) 204 | { 205 | rcl_interfaces::msg::ParameterDescriptor descriptor; 206 | descriptor.read_only = !dynamic; 207 | 208 | std::stringstream ss; 209 | if constexpr (std::is_same::value) { 210 | ss << "Default value: " << (defValue ? "TRUE" : "FALSE"); 211 | } else { 212 | ss << "Default value: " << defValue; 213 | } 214 | descriptor.description = ss.str(); 215 | 216 | if constexpr (std::is_same::value) { 217 | descriptor.additional_constraints = "Range: [" + std::to_string(minVal) + ", " + std::to_string( 218 | maxVal) + "]"; 219 | rcl_interfaces::msg::FloatingPointRange range; 220 | range.from_value = minVal; 221 | range.to_value = maxVal; 222 | descriptor.floating_point_range.push_back(range); 223 | } else if constexpr (std::is_same::value) { 224 | descriptor.additional_constraints = "Range: [" + std::to_string(minVal) + ", " + std::to_string( 225 | maxVal) + "]"; 226 | rcl_interfaces::msg::IntegerRange range; 227 | range.from_value = minVal; 228 | range.to_value = maxVal; 229 | descriptor.integer_range.push_back(range); 230 | } 231 | 232 | node->declare_parameter(paramName, rclcpp::ParameterValue(defValue), descriptor); 233 | 234 | if (!node->get_parameter(paramName, outVal)) { 235 | RCLCPP_WARN_STREAM( 236 | node->get_logger(), 237 | "The parameter '" 238 | << paramName 239 | << "' is not available or is not valid, using the default value: " 240 | << defValue); 241 | } 242 | 243 | if (!log_info.empty()) { 244 | std::stringstream ss; 245 | ss << log_info; 246 | if constexpr (std::is_same::value) { 247 | ss << (outVal ? "TRUE" : "FALSE"); 248 | } else { 249 | ss << outVal; 250 | } 251 | if (dynamic) { 252 | ss << " [DYNAMIC]"; 253 | } 254 | RCLCPP_INFO_STREAM(node->get_logger(), ss.str()); 255 | } 256 | } 257 | // <---- Template functions definitions 258 | 259 | } // namespace sl_tools 260 | 261 | #endif // SL_TOOLS_HPP_ 262 | -------------------------------------------------------------------------------- /zed_components/src/tools/include/sl_types.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Stereolabs 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef SL_TYPES_HPP_ 16 | #define SL_TYPES_HPP_ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | 71 | #ifndef FOUND_FOXY 72 | #include 73 | #endif 74 | 75 | #define TIMEZERO_ROS rclcpp::Time(0, 0, RCL_ROS_TIME) 76 | #define TIMEZERO_SYS rclcpp::Time(0, 0, RCL_SYSTEM_TIME) 77 | 78 | namespace stereolabs 79 | { 80 | 81 | // ----> Global constants 82 | const double DEG2RAD = 0.017453293; 83 | const double RAD2DEG = 57.295777937; 84 | 85 | const sl::COORDINATE_SYSTEM ROS_COORDINATE_SYSTEM = 86 | sl::COORDINATE_SYSTEM::RIGHT_HANDED_Z_UP_X_FWD; 87 | const sl::UNIT ROS_MEAS_UNITS = sl::UNIT::METER; 88 | 89 | const int QOS_QUEUE_SIZE = 10; 90 | // <---- Global constants 91 | 92 | #ifdef _SL_JETSON_ 93 | const bool IS_JETSON = true; 94 | #else 95 | const bool IS_JETSON = false; 96 | #endif 97 | 98 | const float NOT_VALID_TEMP = -273.15f; 99 | 100 | // ----> Typedefs to simplify declarations 101 | typedef std::shared_ptr camInfoMsgPtr; 102 | typedef std::shared_ptr> clockPub; 103 | typedef std::shared_ptr> 104 | svoStatusPub; 105 | typedef std::shared_ptr> 106 | healthStatusPub; 107 | typedef std::shared_ptr> 108 | heartbeatStatusPub; 109 | 110 | typedef std::shared_ptr> imagePub; 111 | typedef std::shared_ptr> 112 | disparityPub; 113 | 114 | typedef std::shared_ptr> 115 | pointcloudPub; 116 | 117 | typedef std::shared_ptr> imuPub; 118 | typedef std::shared_ptr> 119 | magPub; 120 | typedef std::shared_ptr> 121 | pressPub; 122 | typedef std::shared_ptr> 123 | tempPub; 124 | 125 | typedef std::shared_ptr> 126 | posePub; 127 | typedef std::shared_ptr> 128 | poseStatusPub; 129 | typedef std::shared_ptr> 130 | gnssFusionStatusPub; 131 | typedef std::shared_ptr< 132 | rclcpp::Publisher> 133 | poseCovPub; 134 | typedef std::shared_ptr> 135 | transfPub; 136 | typedef std::shared_ptr> odomPub; 137 | typedef std::shared_ptr> pathPub; 138 | 139 | typedef std::shared_ptr> 140 | objPub; 141 | typedef std::shared_ptr> 142 | depthInfoPub; 143 | 144 | typedef std::shared_ptr> 145 | planePub; 146 | typedef std::shared_ptr> 147 | markerPub; 148 | 149 | typedef std::shared_ptr> 150 | geoPosePub; 151 | typedef std::shared_ptr> 152 | gnssFixPub; 153 | 154 | typedef std::shared_ptr> healthPub; 155 | 156 | typedef std::shared_ptr> clickedPtSub; 157 | typedef std::shared_ptr> gnssFixSub; 158 | typedef std::shared_ptr> clockSub; 159 | 160 | typedef rclcpp::Service::SharedPtr resetOdomSrvPtr; 161 | typedef rclcpp::Service::SharedPtr resetPosTrkSrvPtr; 162 | typedef rclcpp::Service::SharedPtr setPoseSrvPtr; 163 | typedef rclcpp::Service::SharedPtr enableObjDetPtr; 164 | typedef rclcpp::Service::SharedPtr enableBodyTrkPtr; 165 | typedef rclcpp::Service::SharedPtr enableMappingPtr; 166 | 167 | typedef rclcpp::Service::SharedPtr 168 | startSvoRecSrvPtr; 169 | typedef rclcpp::Service::SharedPtr setRoiSrvPtr; 170 | typedef rclcpp::Service::SharedPtr stopSvoRecSrvPtr; 171 | typedef rclcpp::Service::SharedPtr pauseSvoSrvPtr; 172 | typedef rclcpp::Service::SharedPtr setSvoFramePtr; 173 | typedef rclcpp::Service::SharedPtr resetRoiSrvPtr; 174 | typedef rclcpp::Service::SharedPtr toLLSrvPtr; 175 | typedef rclcpp::Service::SharedPtr fromLLSrvPtr; 176 | typedef rclcpp::Service::SharedPtr enableStreamingPtr; 177 | 178 | /*! 179 | * @brief Video/Depth topic resolution 180 | */ 181 | typedef enum 182 | { 183 | NATIVE, //!< Same camera grab resolution 184 | CUSTOM //!< Custom Rescale Factor 185 | } PubRes; 186 | 187 | std::string toString(const PubRes & res); 188 | 189 | typedef enum 190 | { 191 | PUB, //!< Same resolution as Color and Depth Map. [Old behavior for compatibility] 192 | FULL, //!< Full resolution. Not recommended because slow processing and high bandwidth requirements 193 | COMPACT, //!< Standard resolution. Optimizes processing and bandwidth 194 | REDUCED //!< Half resolution. Low processing and bandwidth requirements 195 | } PcRes; 196 | 197 | std::string toString(const PcRes & res); 198 | 199 | const int NEURAL_W = 896; 200 | const int NEURAL_H = 512; 201 | // <---- Typedefs to simplify declarations 202 | 203 | } // namespace stereolabs 204 | 205 | #endif // SL_TYPES_HPP_ 206 | -------------------------------------------------------------------------------- /zed_components/src/tools/include/sl_win_avg.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Stereolabs 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef SL_WIN_AVG_HPP_ 16 | #define SL_WIN_AVG_HPP_ 17 | 18 | #include // size_t 19 | #include // std::dequeue 20 | #include 21 | 22 | namespace sl_tools 23 | { 24 | 25 | class WinAvg 26 | { 27 | public: 28 | explicit WinAvg(size_t win_size = 15); 29 | ~WinAvg(); 30 | 31 | double setNewSize(size_t win_size); 32 | double addValue(double val); 33 | 34 | /// @brief Get the current average of the stored values 35 | /// @return average of the stored values 36 | double getAvg(); 37 | 38 | inline size_t size() {return mVals.size();} 39 | 40 | private: 41 | size_t mWinSize; 42 | 43 | std::deque mVals; // The values in the queue used to calculate the windowed average 44 | double mSumVals = 0.0; // The updated sum of the values in the queue 45 | 46 | std::mutex mQueueMux; 47 | }; 48 | 49 | } 50 | 51 | #endif // SL_WIN_AVG_HPP_ 52 | -------------------------------------------------------------------------------- /zed_components/src/tools/src/gnss_replay.cpp: -------------------------------------------------------------------------------- 1 | #include "gnss_replay.hpp" 2 | 3 | using json = nlohmann::json; 4 | 5 | namespace sl_tools 6 | { 7 | 8 | inline bool is_microseconds(uint64_t timestamp) 9 | { 10 | // Check if the timestamp is in microseconds 11 | return 1'000'000'000'000'000 <= timestamp && timestamp < 10'000'000'000'000'000ULL; 12 | } 13 | 14 | inline bool is_nanoseconds(uint64_t timestamp) 15 | { 16 | // Check if the timestamp is in microseconds 17 | return 1'000'000'000'000'000'000 <= timestamp && timestamp < 10'000'000'000'000'000'000ULL; 18 | } 19 | 20 | GNSSReplay::GNSSReplay(const std::shared_ptr & zed) {_zed = zed;} 21 | 22 | GNSSReplay::~GNSSReplay() {close();} 23 | 24 | bool GNSSReplay::initialize() 25 | { 26 | auto svo_custom_data_keys = _zed->getSVODataKeys(); 27 | std::string gnss_key = "GNSS_json"; 28 | bool found = false; 29 | for (auto & it : svo_custom_data_keys) { 30 | if (it.find(gnss_key) != std::string::npos) { 31 | found = true; 32 | break; 33 | } 34 | } 35 | 36 | if (!found) { 37 | return false; 38 | } 39 | 40 | std::map data; 41 | auto status = _zed->retrieveSVOData(gnss_key, data); // Get ALL 42 | 43 | /* 44 | We handle 2 formats: 45 | * 46 | * { 47 | "coordinates": { 48 | "latitude": XXX, 49 | "longitude": XXX, 50 | "altitude": XXX 51 | }, 52 | "ts": 1694263390000000, 53 | "latitude_std": 0.51, 54 | "longitude_std": 0.51, 55 | "altitude_std": 0.73, 56 | "position_covariance": [ 57 | 0.2601, 58 | 0, 59 | 0, 60 | 0, 61 | 0.2601, 62 | 0, 63 | 0, 64 | 0, 65 | 0.5328999999999999 66 | ] 67 | }, 68 | ========= 69 | * Or 70 | * this one will be converted to the format above 71 | { 72 | "Eph": 0.467, 73 | "EpochTimeStamp": 1694266998000000, 74 | "Epv": 0.776, 75 | "Geopoint": { 76 | "Altitude": XXX, 77 | "Latitude": XXX, 78 | "Longitude": XXX 79 | }, 80 | "Position": [ 81 | [ 82 | XXX, 83 | XXX, 84 | XXX 85 | ] 86 | ], 87 | "Velocity": [ 88 | [ 89 | -0.63, 90 | 0.25, 91 | 0.53 92 | ] 93 | ] 94 | } 95 | */ 96 | 97 | auto tmp_array = json::array(); 98 | for (auto & it : data) { 99 | try { 100 | auto _gnss_data_point = 101 | json::parse(it.second.content.begin(), it.second.content.end()); 102 | auto _gnss_data_point_formatted = json::object(); 103 | 104 | if (!_gnss_data_point["Geopoint"].is_null()) { 105 | _gnss_data_point_formatted["coordinates"] = { 106 | {"latitude", _gnss_data_point["Geopoint"]["Latitude"]}, 107 | {"longitude", _gnss_data_point["Geopoint"]["Longitude"]}, 108 | {"altitude", _gnss_data_point["Geopoint"]["Altitude"]}, 109 | }; 110 | _gnss_data_point_formatted["ts"] = _gnss_data_point["EpochTimeStamp"]; 111 | 112 | float latitude_std = _gnss_data_point["Eph"]; 113 | float longitude_std = _gnss_data_point["Eph"]; 114 | float altitude_std = _gnss_data_point["Epv"]; 115 | 116 | _gnss_data_point_formatted["latitude_std"] = latitude_std; 117 | _gnss_data_point_formatted["longitude_std"] = longitude_std; 118 | _gnss_data_point_formatted["altitude_std"] = altitude_std; 119 | 120 | _gnss_data_point_formatted["position_covariance"] = 121 | json::array( 122 | {longitude_std + longitude_std, 0, 0, 0, 123 | latitude_std + latitude_std, 0, 0, 0, 124 | altitude_std + altitude_std}); 125 | 126 | _gnss_data_point_formatted["original__gnss_data"] = _gnss_data_point; 127 | 128 | } else if (!_gnss_data_point["coordinates"].is_null() && 129 | !_gnss_data_point["latitude_std"].is_null() && 130 | !_gnss_data_point["longitude_std"].is_null()) 131 | { 132 | // no conversion 133 | _gnss_data_point_formatted = _gnss_data_point; 134 | } 135 | 136 | tmp_array.push_back(_gnss_data_point_formatted); 137 | 138 | } catch (const std::runtime_error & e) { 139 | std::cerr << "Error while reading GNSS data: " << e.what() << std::endl; 140 | } 141 | } 142 | _gnss_data["GNSS"] = tmp_array; 143 | 144 | _current_gnss_idx = 0; 145 | _previous_ts = 0; 146 | 147 | return true; 148 | } 149 | 150 | void GNSSReplay::close() 151 | { 152 | _gnss_data.clear(); 153 | _current_gnss_idx = 0; 154 | } 155 | 156 | 157 | inline std::string gps_mode2str(int status) 158 | { 159 | std::string out; 160 | switch (status) { 161 | case 1: 162 | out = "STATUS_GPS"; 163 | break; 164 | case 2: 165 | out = "STATUS_DGPS"; 166 | break; 167 | case 3: 168 | out = "STATUS_RTK_FIX"; 169 | break; 170 | case 4: 171 | out = "STATUS_RTK_FLT"; 172 | break; 173 | case 5: 174 | out = "STATUS_DR"; 175 | break; 176 | case 6: 177 | out = "STATUS_GNSSDR"; 178 | break; 179 | case 7: 180 | out = "STATUS_TIME"; 181 | break; 182 | case 8: 183 | out = "STATUS_SIM"; 184 | break; 185 | case 9: 186 | out = "STATUS_PPS_FIX"; 187 | break; 188 | default: 189 | case 0: 190 | out = "STATUS_UNK"; 191 | break; 192 | } 193 | return out; 194 | } 195 | 196 | sl::GNSSData getGNSSData(json & _gnss_data, int gnss_idx) 197 | { 198 | sl::GNSSData current__gnss_data; 199 | current__gnss_data.ts = 0; 200 | 201 | // If we are at the end of GNSS data, exit 202 | if (gnss_idx >= _gnss_data["GNSS"].size()) { 203 | std::cout << "Reached the end of the GNSS playback data." << std::endl; 204 | return current__gnss_data; 205 | } 206 | 207 | json current__gnss_data_json = _gnss_data["GNSS"][gnss_idx]; 208 | // Check inputs: 209 | if ( 210 | current__gnss_data_json["coordinates"].is_null() || 211 | current__gnss_data_json["coordinates"]["latitude"].is_null() || 212 | current__gnss_data_json["coordinates"]["longitude"].is_null() || 213 | current__gnss_data_json["coordinates"]["altitude"].is_null() || 214 | current__gnss_data_json["ts"].is_null()) 215 | { 216 | std::cout << "Null GNSS playback data." << std::endl; 217 | return current__gnss_data; 218 | } 219 | 220 | 221 | // if (!current__gnss_data_json["original__gnss_data"].is_null()) { 222 | // if (!current__gnss_data_json["original__gnss_data"]["fix"].is_null()) { 223 | // if (!current__gnss_data_json["original__gnss_data"]["fix"]["status"].is_null()) 224 | // std::cout << "GNSS info: " << gps_mode2str(current__gnss_data_json["original__gnss_data"]["fix"]["status"]) << " " << current__gnss_data_json["longitude_std"] << " " << current__gnss_data_json["altitude_std"] << std::endl; 225 | // } 226 | // } 227 | 228 | auto gnss_timestamp = current__gnss_data_json["ts"].get(); 229 | // Fill out timestamp: 230 | if (is_microseconds(gnss_timestamp)) { 231 | current__gnss_data.ts.setMicroseconds(gnss_timestamp); 232 | } else if (is_nanoseconds(gnss_timestamp)) { 233 | current__gnss_data.ts.setNanoseconds(gnss_timestamp); 234 | } else { 235 | std::cerr << "Warning: Invalid timestamp format from GNSS file" << std::endl; 236 | } 237 | 238 | // Fill out coordinates: 239 | current__gnss_data.setCoordinates( 240 | current__gnss_data_json["coordinates"]["latitude"].get(), 241 | current__gnss_data_json["coordinates"]["longitude"].get(), 242 | current__gnss_data_json["coordinates"]["altitude"].get(), 243 | false); 244 | 245 | // Fill out default standard deviation: 246 | current__gnss_data.longitude_std = current__gnss_data_json["longitude_std"]; 247 | current__gnss_data.latitude_std = current__gnss_data_json["latitude_std"]; 248 | current__gnss_data.altitude_std = current__gnss_data_json["altitude_std"]; 249 | // Fill out covariance [must be not null] 250 | std::array position_covariance; 251 | for (unsigned i = 0; i < 9; i++) { 252 | position_covariance[i] = 0.0; // initialize empty covariance 253 | 254 | } 255 | // set covariance diagonal 256 | position_covariance[0] = current__gnss_data.longitude_std * current__gnss_data.longitude_std; 257 | position_covariance[1 * 3 + 1] = current__gnss_data.latitude_std * 258 | current__gnss_data.latitude_std; 259 | position_covariance[2 * 3 + 2] = current__gnss_data.altitude_std * 260 | current__gnss_data.altitude_std; 261 | current__gnss_data.position_covariance = position_covariance; 262 | 263 | return current__gnss_data; 264 | } 265 | 266 | sl::GNSSData GNSSReplay::getNextGNSSValue(uint64_t current_timestamp) 267 | { 268 | sl::GNSSData current__gnss_data = getGNSSData(_gnss_data, _current_gnss_idx); 269 | 270 | if (current__gnss_data.ts.data_ns == 0) { 271 | return current__gnss_data; 272 | } 273 | 274 | if (current__gnss_data.ts.data_ns > current_timestamp) { 275 | current__gnss_data.ts.data_ns = 0; 276 | return current__gnss_data; 277 | } 278 | 279 | sl::GNSSData last_data; 280 | int step = 1; 281 | while (1) { 282 | last_data = current__gnss_data; 283 | int diff_last = current_timestamp - current__gnss_data.ts.data_ns; 284 | current__gnss_data = getGNSSData(_gnss_data, _current_gnss_idx + step++); 285 | if (current__gnss_data.ts.data_ns == 0) { //error / end of file 286 | break; 287 | } 288 | 289 | if (current__gnss_data.ts.data_ns > current_timestamp) { 290 | if ((current__gnss_data.ts.data_ns - current_timestamp) > diff_last) { // keep last 291 | current__gnss_data = last_data; 292 | } 293 | break; 294 | } 295 | _current_gnss_idx++; 296 | } 297 | 298 | return current__gnss_data; 299 | } 300 | 301 | sl::FUSION_ERROR_CODE GNSSReplay::grab(sl::GNSSData & current_data, uint64_t current_timestamp) 302 | { 303 | current_data.ts.data_ns = 0; 304 | 305 | if (current_timestamp > 0 && (current_timestamp > _last_cam_ts)) { 306 | current_data = getNextGNSSValue(current_timestamp); 307 | } 308 | 309 | if (current_data.ts.data_ns == _previous_ts) { 310 | current_data.ts.data_ns = 0; 311 | } 312 | 313 | _last_cam_ts = current_timestamp; 314 | 315 | if (current_data.ts.data_ns == 0) { // Invalid data 316 | return sl::FUSION_ERROR_CODE::FAILURE; 317 | } 318 | 319 | _previous_ts = current_data.ts.data_ns; 320 | return sl::FUSION_ERROR_CODE::SUCCESS; 321 | } 322 | 323 | } // namespace sl_tools 324 | -------------------------------------------------------------------------------- /zed_components/src/tools/src/sl_types.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2025 Stereolabs 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "sl_types.hpp" 16 | 17 | namespace stereolabs 18 | { 19 | 20 | std::string toString(const PubRes & res) 21 | { 22 | switch (res) { 23 | case NATIVE: 24 | return "NATIVE"; 25 | case CUSTOM: 26 | return "CUSTOM"; 27 | default: 28 | return ""; 29 | } 30 | } 31 | 32 | std::string toString(const PcRes & res) 33 | { 34 | switch (res) { 35 | case PUB: 36 | return "PUB"; 37 | case FULL: 38 | return "FULL"; 39 | case COMPACT: 40 | return "COMPACT"; 41 | case REDUCED: 42 | return "REDUCED"; 43 | default: 44 | return ""; 45 | } 46 | } 47 | 48 | } // namespace stereolabs 49 | -------------------------------------------------------------------------------- /zed_components/src/tools/src/sl_win_avg.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Stereolabs 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "sl_win_avg.hpp" 16 | 17 | namespace sl_tools 18 | { 19 | 20 | WinAvg::WinAvg(size_t win_size) 21 | { 22 | mWinSize = win_size; 23 | mSumVals = 0.0; 24 | } 25 | 26 | WinAvg::~WinAvg() {} 27 | 28 | double WinAvg::setNewSize(size_t win_size) 29 | { 30 | std::lock_guard guard(mQueueMux); 31 | 32 | mWinSize = win_size; 33 | while (mVals.size() > mWinSize) { 34 | double val = mVals.back(); 35 | mVals.pop_back(); 36 | mSumVals -= val; 37 | } 38 | 39 | return mSumVals / mVals.size(); 40 | } 41 | 42 | double WinAvg::addValue(double val) 43 | { 44 | std::lock_guard guard(mQueueMux); 45 | if (mVals.size() == mWinSize) { 46 | double older = mVals.back(); 47 | mVals.pop_back(); 48 | mSumVals -= older; 49 | } 50 | 51 | mVals.push_front(val); 52 | mSumVals += val; 53 | 54 | auto avg = mSumVals / mVals.size(); 55 | 56 | // std::cout << "New val: " << val << " - Size: " << mVals.size() 57 | // << " - Sum: " << mSumVals << " - Avg: " << avg << std::endl; 58 | 59 | return avg; 60 | } 61 | 62 | double WinAvg::getAvg() 63 | { 64 | std::lock_guard guard(mQueueMux); 65 | 66 | double avg = mSumVals / mVals.size(); 67 | 68 | return avg; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /zed_components/src/zed_camera/include/cost_traversability.hpp: -------------------------------------------------------------------------------- 1 | #ifndef COST_TRAVERSABILITY_HPP 2 | #define COST_TRAVERSABILITY_HPP__ 3 | 4 | #include "sl/Fusion.hpp" 5 | 6 | namespace stereolabs 7 | { 8 | namespace cost_traversability 9 | { 10 | /** 11 | \brief Defines robot parameters, this will be used to compute the TRAVERSABILITY_COST 12 | */ 13 | struct RobotParameters 14 | { 15 | float radius = 0.25f; 16 | float step_max = 0.1f; 17 | float slope_max = 20.0f; // degrees 18 | float roughness_max = 0.1f; 19 | }; 20 | 21 | /** 22 | \brief Defines the traversability parameters, this will be used to compute the TRAVERSABILITY_COST 23 | */ 24 | struct TraversabilityParameters 25 | { 26 | float occupancy_threshold = 0.5f; 27 | float slope_weight = 1.f / 3.f; 28 | float step_weight = 1.f / 3.f; 29 | float roughness_weight = 1.f / 3.f; 30 | }; 31 | 32 | constexpr sl::LayerName TRAVERSABILITY_COST = 33 | static_cast(static_cast(sl::LayerName::LAST) + 1); 34 | constexpr sl::LayerName OCCUPANCY = 35 | static_cast(static_cast(sl::LayerName::LAST) + 2); 36 | constexpr sl::LayerName TRAVERSABILITY_COST_STEP = 37 | static_cast(static_cast(sl::LayerName::LAST) + 3); 38 | constexpr sl::LayerName TRAVERSABILITY_COST_SLOPE = 39 | static_cast(static_cast(sl::LayerName::LAST) + 4); 40 | constexpr sl::LayerName TRAVERSABILITY_COST_ROUGHNESS = 41 | static_cast(static_cast(sl::LayerName::LAST) + 5); 42 | 43 | constexpr float OCCUPIED_CELL = 1.f; 44 | constexpr float FREE_CELL = 0.f; 45 | constexpr float INVALID_CELL_DATA = NAN; 46 | constexpr float UNKNOWN_CELL = NAN; 47 | 48 | void initCostTraversibily( 49 | sl::Terrain & cost_terrain, float resolution, float range, 50 | float height_threshold); 51 | 52 | void computeCost( 53 | sl::Terrain & elevation_terrain, sl::Terrain & cost_terrain, 54 | const float grid_resolution, RobotParameters robot_parameters, 55 | TraversabilityParameters traversability_parameters); 56 | 57 | void normalization(sl::Terrain & cost_terrain, sl::LayerName layer, sl::Mat & view); 58 | 59 | } // namespace cost_traversability 60 | 61 | } // namespace stereolabs 62 | 63 | // SDK internal function 64 | namespace plane 65 | { 66 | void compute_pca( 67 | std::vector & points, sl::float3 & normal_vect, sl::float3 & centroid, 68 | sl::float3 & eigen_values); 69 | } 70 | 71 | #endif // COST_TRAVERSABILITY_HPP_ 72 | -------------------------------------------------------------------------------- /zed_components/src/zed_camera/include/zed_camera_one_component.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Stereolabs 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef ZED_CAMERA_ONE_COMPONENT_HPP_ 16 | #define ZED_CAMERA_ONE_COMPONENT_HPP_ 17 | 18 | #define ENABLE_GRAY_IMAGE 1 19 | #define ENABLE_STREAM_INPUT 1 20 | #define ENABLE_SVO 0 21 | 22 | #include 23 | #include 24 | 25 | #include "sl_tools.hpp" 26 | #include "sl_types.hpp" 27 | #include "visibility_control.hpp" 28 | 29 | 30 | namespace stereolabs 31 | { 32 | 33 | class ZedCameraOne : public rclcpp::Node 34 | { 35 | public: 36 | ZED_COMPONENTS_PUBLIC 37 | explicit ZedCameraOne(const rclcpp::NodeOptions & options); 38 | 39 | virtual ~ZedCameraOne(); 40 | 41 | protected: 42 | // ----> Initialization functions 43 | void init(); 44 | void initParameters(); 45 | void initServices(); 46 | void initThreadsAndTimers(); 47 | void initTFCoordFrameNames(); 48 | void initPublishers(); 49 | 50 | void getSensorsParams(); 51 | void getDebugParams(); 52 | void getVideoParams(); 53 | void getGeneralParams(); 54 | void getStreamingServerParams(); 55 | void getAdvancedParams(); 56 | 57 | void close(); 58 | 59 | bool startCamera(); 60 | void closeCamera(); 61 | void startTempPubTimer(); 62 | bool startStreamingServer(); 63 | void stopStreamingServer(); 64 | #if ENABLE_SVO 65 | bool startSvoRecording(std::string & errMsg); 66 | void stopSvoRecording(); 67 | #endif 68 | // <---- Initialization functions 69 | 70 | // ----> Utility functions 71 | void fillCamInfo( 72 | const std::shared_ptr & camInfoMsg, 73 | const std::string & frameId, 74 | bool rawParam = false); 75 | 76 | void applyDynamicSettings(); 77 | bool areImageTopicsSubscribed(); 78 | bool areSensorsTopicsSubscribed(); 79 | void retrieveImages(); 80 | void publishImages(); 81 | void publishImageWithInfo( 82 | const sl::Mat & img, 83 | const image_transport::CameraPublisher & pubImg, 84 | const camInfoMsgPtr & camInfoMsg, const std::string & imgFrameId, 85 | const rclcpp::Time & t); 86 | bool publishSensorsData(); 87 | void publishImuFrameAndTopic(); 88 | // <---- Utility functions 89 | 90 | // ----> Callbacks functions 91 | rcl_interfaces::msg::SetParametersResult callback_dynamicParamChange( 92 | std::vector parameters); 93 | void callback_updateDiagnostic( 94 | diagnostic_updater::DiagnosticStatusWrapper & stat); 95 | void callback_pubTemp(); 96 | 97 | void callback_enableStreaming( 98 | const std::shared_ptr request_header, 99 | const std::shared_ptr req, 100 | std::shared_ptr res); 101 | #if ENABLE_SVO 102 | void callback_startSvoRec( 103 | const std::shared_ptr request_header, 104 | const std::shared_ptr req, 105 | std::shared_ptr res); 106 | void callback_stopSvoRec( 107 | const std::shared_ptr request_header, 108 | const std::shared_ptr req, 109 | std::shared_ptr res); 110 | void callback_pauseSvoInput( 111 | const std::shared_ptr request_header, 112 | const std::shared_ptr req, 113 | std::shared_ptr res); 114 | #endif 115 | // <---- Callbacks functions 116 | 117 | // ----> Thread functions 118 | void threadFunc_zedGrab(); 119 | void threadFunc_pubSensorsData(); 120 | // <---- Threads functions 121 | 122 | private: 123 | // ----> ZED SDK 124 | std::shared_ptr _zed; 125 | sl::InitParametersOne _initParams; 126 | // <---- ZED SDK 127 | 128 | // ----> Threads and Timers 129 | std::thread _grabThread; // Main grab thread 130 | std::thread _sensThread; // Sensors data publish thread 131 | 132 | std::atomic _threadStop; 133 | rclcpp::TimerBase::SharedPtr _initTimer; 134 | rclcpp::TimerBase::SharedPtr _tempPubTimer; // Timer to retrieve and publish camera temperature 135 | // <---- Threads and Timers 136 | 137 | // ----> Thread Sync 138 | std::mutex _recMutex; 139 | // <---- Thread Sync 140 | 141 | // ----> Debug variables 142 | bool _debugCommon = false; 143 | bool _debugVideoDepth = false; 144 | bool _debugSensors = false; 145 | bool _debugCamCtrl = false; 146 | bool _debugStreaming = false; 147 | bool _debugAdvanced = false; 148 | // <---- Debug variables 149 | 150 | // ----> QoS 151 | // https://github.com/ros2/ros2/wiki/About-Quality-of-Service-Settings 152 | rclcpp::QoS _qos; 153 | rclcpp::PublisherOptions _pubOpt; 154 | rclcpp::SubscriptionOptions _subOpt; 155 | // <---- QoS 156 | 157 | // ----> Topics 158 | std::string _topicRoot = "~/"; 159 | std::string _imgTopic; 160 | std::string _imgRawTopic; 161 | #if ENABLE_GRAY_IMAGE 162 | std::string _imgGrayTopic; 163 | std::string _imgRawGrayTopic; 164 | #endif 165 | 166 | std::string _tempTopic; 167 | // <---- Topics 168 | 169 | // ----> Publishers 170 | image_transport::CameraPublisher _pubColorImg; 171 | image_transport::CameraPublisher _pubColorRawImg; 172 | #if ENABLE_GRAY_IMAGE 173 | image_transport::CameraPublisher _pubGrayImg; 174 | image_transport::CameraPublisher _pubGrayRawImg; 175 | #endif 176 | 177 | imuPub _pubImu; 178 | imuPub _pubImuRaw; 179 | tempPub _pubTemp; 180 | 181 | transfPub _pubCamImuTransf; 182 | // <---- Publishers 183 | 184 | // ----> Publisher variables 185 | sl::Timestamp _lastTs_grab = 0; // Used to calculate stable publish frequency 186 | sl::Timestamp _sdkGrabTS = 0; 187 | std::atomic _colorSubCount; 188 | std::atomic _colorRawSubCount; 189 | #if ENABLE_GRAY_IMAGE 190 | std::atomic _graySubCount = 0; 191 | std::atomic _grayRawSubCount = 0; 192 | #endif 193 | 194 | std::atomic _imuSubCount; 195 | std::atomic _imuRawSubCount; 196 | double _sensRateComp = 1.0; 197 | 198 | sl::Mat _matColor, _matColorRaw; 199 | #if ENABLE_GRAY_IMAGE 200 | sl::Mat _matGray, _matGrayRaw; 201 | #endif 202 | // <---- Publisher variables 203 | 204 | // ----> Parameters 205 | std::string _cameraName = "zed_one"; // Name of the camera 206 | int _camGrabFrameRate = 30; // Grab frame rate 207 | sl::RESOLUTION _camResol = sl::RESOLUTION::HD1080; // Default resolution: RESOLUTION_HD1080 208 | PubRes _pubResolution = PubRes::NATIVE; // Use native grab resolution by default 209 | double _customDownscaleFactor = 1.0; // Used to rescale data with user factor 210 | bool _cameraFlip = false; // Camera flipped? 211 | bool _enableHDR = false; // Enable HDR if supported? 212 | std::string _opencvCalibFile; // Custom OpenCV calibration file 213 | int _sdkVerbose = 0; // SDK verbose level 214 | std::string _sdkVerboseLogFile = ""; // SDK Verbose Log file 215 | int _gpuId = -1; // GPU ID 216 | 217 | int _camSerialNumber = 0; // Camera serial number 218 | int _camId = -1; // Camera ID 219 | 220 | sl::MODEL _camUserModel = sl::MODEL::ZED_XONE_GS; // Default camera model 221 | 222 | std::string _svoFilepath = ""; // SVO input 223 | #if ENABLE_SVO 224 | bool _svoRealtime = true; // SVO playback with real time 225 | bool _svoLoop = false; // SVO loop playback 226 | #endif 227 | 228 | std::string _streamAddr = ""; // Address for local streaming input 229 | int _streamPort = 10000; 230 | 231 | std::string _threadSchedPolicy; 232 | int _threadPrioGrab; 233 | int _threadPrioSens; 234 | 235 | std::atomic _streamingServerRequired; 236 | sl::STREAMING_CODEC _streamingServerCodec = sl::STREAMING_CODEC::H264; 237 | int _streamingServerPort = 30000; 238 | int _streamingServerBitrate = 12500; 239 | int _streamingServerGopSize = -1; 240 | bool _streamingServerAdaptiveBitrate = false; 241 | int _streamingServerChunckSize = 16084; 242 | int _streamingServerTargetFramerate = 0; 243 | 244 | bool _publishImuTF = false; 245 | double _sensPubRate = 200.; 246 | // <---- Parameters 247 | 248 | // ----> Dynamic params 249 | OnSetParametersCallbackHandle::SharedPtr _paramChangeCallbackHandle; 250 | 251 | int _camSaturation = 4; 252 | int _camSharpness = 4; 253 | int _camGamma = 8; 254 | bool _camAutoWB = true; 255 | int _camWBTemp = 42; 256 | 257 | bool _camAutoExposure = true; 258 | int _camExpTime = 16666; 259 | int _camAutoExpTimeRangeMin = 28; 260 | int _camAutoExpTimeRangeMax = 30000; 261 | int _camExposureComp = 50; 262 | bool _camAutoAnalogGain = true; 263 | int _camAnalogGain = 8000; 264 | int _camAutoAnalogGainRangeMin = 1000; 265 | int _camAutoAnalogGainRangeMax = 16000; 266 | bool _camAutoDigitalGain = true; 267 | int _camDigitalGain = 128; 268 | int _camAutoDigitalGainRangeMin = 1; 269 | int _camAutoDigitalGainRangeMax = 256; 270 | int _camDenoising = 50; 271 | std::unordered_map _camDynParMapChanged; 272 | // <---- Dynamic params 273 | 274 | // ----> Running status 275 | bool _debugMode = false; // Debug mode active? 276 | bool _svoMode = false; // Input from SVO? 277 | bool _svoPause = false; // SVO pause status 278 | bool _useSvoTimestamp = false; // Use SVO timestamp 279 | bool _streamMode = false; // Expecting local streaming data? 280 | 281 | std::atomic _triggerUpdateDynParams; // Trigger auto exposure/gain 282 | 283 | bool _recording = false; 284 | sl::RecordingStatus _recStatus = sl::RecordingStatus(); 285 | // <---- Running status 286 | 287 | // ----> Timestamps 288 | rclcpp::Time _frameTimestamp; 289 | rclcpp::Time _lastTs_imu; 290 | // <---- Timestamps 291 | 292 | // ----> TF handling 293 | std::unique_ptr _tfBuffer; 294 | std::unique_ptr _tfListener; 295 | std::unique_ptr _tfBroadcaster; 296 | 297 | // Camera IMU transform 298 | sl::Transform _slCamImuTransf; 299 | // <---- TF handling 300 | 301 | // ----> Camera info 302 | sl::MODEL _camRealModel; // Camera model requested to SDK 303 | unsigned int _camFwVersion; // Camera FW version 304 | unsigned int _sensFwVersion; // Sensors FW version 305 | // <---- Camera info 306 | 307 | // ----> Stereolabs Mat Info 308 | int _camWidth; // Camera frame width 309 | int _camHeight; // Camera frame height 310 | sl::Resolution _matResol; 311 | // <---- Stereolabs Mat Info 312 | 313 | // ----> Camera infos 314 | camInfoMsgPtr _camInfoMsg; 315 | camInfoMsgPtr _camInfoRawMsg; 316 | // <---- Camera infos 317 | 318 | // ----> Frame IDs 319 | std::string _cameraLinkFrameId; 320 | std::string _cameraCenterFrameId; 321 | std::string _camImgFrameId; 322 | std::string _camOptFrameId; 323 | std::string _imuFrameId; 324 | // <---- Frame IDs 325 | 326 | // ----> Diagnostic variables 327 | diagnostic_updater::Updater _diagUpdater; // Diagnostic Updater 328 | 329 | sl_tools::StopWatch _uptimer; 330 | 331 | sl::ERROR_CODE _connStatus = sl::ERROR_CODE::LAST; // Connection status 332 | sl::ERROR_CODE _grabStatus = sl::ERROR_CODE::LAST; // Grab status 333 | float _tempImu = NOT_VALID_TEMP; 334 | uint64_t _frameCount = 0; 335 | std::unique_ptr _elabPeriodMean_sec; 336 | std::unique_ptr _grabPeriodMean_sec; 337 | std::unique_ptr _imagePeriodMean_sec; 338 | std::unique_ptr _imageElabMean_sec; 339 | std::unique_ptr _imuPeriodMean_sec; 340 | std::unique_ptr _pubImuTF_sec; 341 | std::unique_ptr _pubImu_sec; 342 | bool _imuPublishing = false; 343 | bool _videoPublishing = false; 344 | bool _imageSubscribed = false; 345 | 346 | sl_tools::StopWatch _grabFreqTimer; 347 | sl_tools::StopWatch _imuFreqTimer; 348 | sl_tools::StopWatch _imuTfFreqTimer; 349 | sl_tools::StopWatch _imgPubFreqTimer; 350 | int _sysOverloadCount = 0; 351 | 352 | std::atomic _streamingServerRunning; 353 | // <---- Diagnostic variables 354 | 355 | // ----> SVO Recording parameters 356 | #if ENABLE_SVO 357 | unsigned int _svoRecBitrate = 0; 358 | sl::SVO_COMPRESSION_MODE _svoRecCompr = sl::SVO_COMPRESSION_MODE::H264; 359 | unsigned int _svoRecFramerate = 0; 360 | bool _svoRecTranscode = false; 361 | std::string _svoRecFilename; 362 | #endif 363 | // <---- SVO Recording parameters 364 | 365 | // ----> Services 366 | enableStreamingPtr _srvEnableStreaming; 367 | #if ENABLE_SVO 368 | startSvoRecSrvPtr _srvStartSvoRec; 369 | stopSvoRecSrvPtr _srvStopSvoRec; 370 | pauseSvoSrvPtr _srvPauseSvo; 371 | #endif 372 | // <---- Services 373 | 374 | // ----> Services names 375 | const std::string _srvEnableStreamingName = "enable_streaming"; 376 | #if ENABLE_SVO 377 | const std::string _srvStartSvoRecName = "start_svo_rec"; 378 | const std::string _srvStopSvoRecName = "stop_svo_rec"; 379 | const std::string _srvToggleSvoPauseName = "toggle_svo_pause"; 380 | #endif 381 | // <---- Services names 382 | }; 383 | 384 | } // namespace stereolabs 385 | 386 | #endif // ZED_CAMERA_ONE_COMPONENT_HPP_ 387 | -------------------------------------------------------------------------------- /zed_components/src/zed_camera/src/cost_traversability.cpp: -------------------------------------------------------------------------------- 1 | #include "cost_traversability.hpp" 2 | 3 | namespace stereolabs 4 | { 5 | namespace cost_traversability 6 | { 7 | template 8 | T clamp(T const & v, T const & lo, T const & hi) 9 | { 10 | return (v < lo) ? lo : ((v > hi) ? hi : v); 11 | } 12 | 13 | void initCostTraversibily( 14 | sl::Terrain & cost_terrain, float resolution, float range, 15 | float height_threshold) 16 | { 17 | std::vector layers; 18 | layers.push_back(TRAVERSABILITY_COST); 19 | layers.push_back(OCCUPANCY); 20 | layers.push_back(TRAVERSABILITY_COST_STEP); 21 | layers.push_back(TRAVERSABILITY_COST_SLOPE); 22 | layers.push_back(TRAVERSABILITY_COST_ROUGHNESS); 23 | 24 | auto range_cell = round(range / resolution); 25 | cost_terrain.init(resolution, range_cell, layers); 26 | } 27 | 28 | void computeCost( 29 | sl::Terrain & elevation_terrain, sl::Terrain & cost_terrain, 30 | const float grid_resolution, RobotParameters robot_parameters, 31 | TraversabilityParameters traversability_parameters) 32 | { 33 | auto square_size_cost = robot_parameters.radius / grid_resolution; 34 | if (square_size_cost < 1) { 35 | square_size_cost = 1; 36 | } 37 | 38 | auto factor_step_ = traversability_parameters.step_weight / robot_parameters.step_max; 39 | auto factor_slope_ = traversability_parameters.slope_weight / robot_parameters.slope_max; 40 | auto factor_roughness_ = traversability_parameters.roughness_weight / 41 | robot_parameters.roughness_max; 42 | 43 | // Update only the recent one, and manage the border ? 44 | const float step_height_crit = robot_parameters.step_max; 45 | 46 | double reso_d = grid_resolution * 1.; 47 | 48 | sl::Timestamp ts_tmp_elevation, ts_tmp_cost; 49 | 50 | double a_rad = robot_parameters.radius * 1.; 51 | int nb_cells = (2. * a_rad) / reso_d; // big agent with small grid size is heavier to compute 52 | 53 | const sl::float3 z_vector(0, 0, 1); 54 | 55 | auto chunks_idx = elevation_terrain.getAllValidChunk(); 56 | 57 | // for each chunk 58 | for (auto chunk_id : chunks_idx) { 59 | 60 | auto & chunk_elevation = elevation_terrain.getChunk(chunk_id); 61 | auto & layer_height = chunk_elevation.getLayer(sl::LayerName::ELEVATION); 62 | 63 | auto & chunk_cost = cost_terrain.getChunk(chunk_id); 64 | 65 | chunk_cost.getLayer(TRAVERSABILITY_COST).clear(); 66 | chunk_cost.getLayer(OCCUPANCY).clear(); 67 | chunk_cost.getLayer(TRAVERSABILITY_COST_STEP).clear(); 68 | chunk_cost.getLayer(TRAVERSABILITY_COST_SLOPE).clear(); 69 | chunk_cost.getLayer(TRAVERSABILITY_COST_ROUGHNESS).clear(); 70 | 71 | auto & cost_data = chunk_cost.getLayer(TRAVERSABILITY_COST).getData(); 72 | auto & occupancy_data = chunk_cost.getLayer(OCCUPANCY).getData(); 73 | auto & cost_step_data = chunk_cost.getLayer(TRAVERSABILITY_COST_STEP).getData(); 74 | auto & cost_slope_data = chunk_cost.getLayer(TRAVERSABILITY_COST_SLOPE).getData(); 75 | auto & cost_roughness_data = chunk_cost.getLayer(TRAVERSABILITY_COST_ROUGHNESS).getData(); 76 | 77 | auto dim = chunk_elevation.getDimension(); 78 | const int size_ = dim.getSize() * dim.getSize(); 79 | 80 | auto & elevation_data = layer_height.getData(); 81 | 82 | unsigned int idx_tmp; 83 | float x, y; 84 | for (unsigned int idx_current = 0; idx_current < size_; idx_current++) { 85 | const float ref_height = elevation_data[idx_current]; 86 | if (std::isfinite(ref_height)) { 87 | dim.index2x_y(idx_current, x, y); 88 | // SLOPE 89 | std::vector normals_tmp; 90 | normals_tmp.reserve(nb_cells * nb_cells); 91 | 92 | float max_diff_height = 0; 93 | 94 | double x_area_min = x - a_rad; 95 | double y_area_min = y - a_rad; 96 | 97 | for (int x_ = 0; x_ < nb_cells; x_++) { 98 | float x_v = x_area_min + (x_ * reso_d); 99 | for (int y_ = 0; y_ < nb_cells; y_++) { 100 | float y_v = y_area_min + (y_ * reso_d); 101 | 102 | float curr_height; 103 | if (dim.getIndex(x_v, y_v, idx_tmp) /*True = error*/) { 104 | // Probably chunk edges 105 | curr_height = elevation_terrain.readValue(sl::LayerName::ELEVATION, x_v, y_v); 106 | } else { 107 | curr_height = elevation_data[idx_tmp]; 108 | } 109 | 110 | if (std::isfinite(curr_height)) { 111 | normals_tmp.emplace_back(x_v, y_v, curr_height); 112 | max_diff_height = std::max(max_diff_height, fabsf32(curr_height - ref_height)); 113 | } 114 | } 115 | } 116 | 117 | sl::float3 normal, centroid, eigen_values; 118 | plane::compute_pca(normals_tmp, normal, centroid, eigen_values); 119 | 120 | float roughness = 0, slope = 0, step = 0, cost; 121 | 122 | if (max_diff_height > step_height_crit) { 123 | step = max_diff_height; 124 | } 125 | 126 | if (normals_tmp.size() >= 3) { // minimum points 127 | slope = 128 | acos( 129 | sl::float3::dot( 130 | normal, 131 | z_vector) / sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z)) * 132 | 57.295779513; // the norm of z_vector is 1 133 | 134 | } 135 | if (slope > 90) { 136 | slope = 180.f - slope; 137 | } 138 | 139 | roughness = sqrt(eigen_values.z); // Standard deviation of fitted plane 140 | 141 | cost = clamp( 142 | (roughness * factor_roughness_ + slope * factor_slope_ + step * factor_step_) * 0.3f, 143 | 0.f, 1.f); 144 | cost_data[idx_current] = cost; 145 | occupancy_data[idx_current] = 146 | (cost > traversability_parameters.occupancy_threshold) ? OCCUPIED_CELL : FREE_CELL; 147 | if (slope == 0) { 148 | slope = INVALID_CELL_DATA; 149 | } 150 | cost_slope_data[idx_current] = slope; 151 | cost_step_data[idx_current] = step; 152 | cost_roughness_data[idx_current] = roughness; 153 | } else { 154 | occupancy_data[idx_current] = UNKNOWN_CELL; 155 | } 156 | } 157 | } 158 | } 159 | 160 | static const sl::float3 clr_a(244, 242, 246); 161 | static const sl::float3 clr_b(0, 0, 0); 162 | 163 | // generate a linear ColorMap to match ogl interpol 164 | inline sl::uchar3 getColorMap(float value) 165 | { 166 | auto new_clr = clr_a * value + clr_b * (1.f - value); 167 | return sl::uchar3(new_clr.b, new_clr.g, new_clr.r); 168 | } 169 | 170 | void normalization(sl::Terrain & cost_terrain, sl::LayerName layer, sl::Mat & view) 171 | { 172 | sl::Mat cost; 173 | auto cost_mat = cost_terrain.retrieveView(cost, sl::MAT_TYPE::F32_C1, layer); 174 | auto cost_res = cost.getResolution(); 175 | view.alloc(cost_res, sl::MAT_TYPE::U8_C3); 176 | 177 | for (int y = 0; y < cost_res.height; y++) { 178 | 179 | auto ptr_cost = cost.getPtr() + y * cost.getStep(); 180 | auto ptr_view = view.getPtr() + y * view.getStep(); 181 | 182 | for (int x = 0; x < cost_res.width; x++) { 183 | float cost = ptr_cost[x]; 184 | if (std::isfinite(cost)) { 185 | ptr_view[x] = getColorMap(cost); 186 | } else { 187 | ptr_view[x] = sl::uchar3(22, 22, 22); 188 | } 189 | } 190 | } 191 | } 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /zed_ros2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(zed_ros2 NONE) 3 | 4 | ## Generate symbols for IDE indexer 5 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 6 | 7 | ################################################ 8 | # Check the ROS2 version 9 | 10 | set(ROS2_FOUND FALSE) 11 | if(DEFINED ENV{ROS_DISTRO}) 12 | set(FOUND_ROS2_DISTRO $ENV{ROS_DISTRO}) 13 | set(ROS2_FOUND TRUE) 14 | #message("* Found ROS2 ${FOUND_ROS2_DISTRO}") 15 | else() 16 | message("* ROS2 distro variable not set. Trying to figure it out...") 17 | set(ROS2_DISTROS "ardent;crystal;dashing;eloquent;foxy;galactic;humble;jazzy;rolling") 18 | set(ROS2_FOUND FALSE) 19 | foreach(distro ${ROS2_DISTROS}) 20 | if(NOT ROS2_FOUND) 21 | find_path(RCLCPP_H rclcpp.hpp PATHS /opt/ros/${distro}/include/rclcpp) 22 | if(RCLCPP_H) 23 | #message("* Found ROS2 ${distro}") 24 | set(FOUND_ROS2_DISTRO ${distro}) 25 | set(ROS2_FOUND TRUE) 26 | endif() 27 | endif() 28 | endforeach() 29 | endif() 30 | 31 | if(ROS2_FOUND) 32 | if(${FOUND_ROS2_DISTRO} STREQUAL "foxy") 33 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 34 | add_definitions(-DFOUND_FOXY) 35 | elseif(${FOUND_ROS2_DISTRO} STREQUAL "humble") 36 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 37 | add_definitions(-DFOUND_HUMBLE) 38 | elseif(${FOUND_ROS2_DISTRO} STREQUAL "iron") 39 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 40 | add_definitions(-DFOUND_IRON) 41 | elseif(${FOUND_ROS2_DISTRO} STREQUAL "jazzy") 42 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 43 | add_definitions(-DFOUND_JAZZY) 44 | else() 45 | message("*** WARNING *** Unsupported ROS2 ${FOUND_ROS2_DISTRO}. '${PROJECT_NAME}' may not work correctly.") 46 | endif() 47 | else() 48 | message("*** WARNING *** ROS2 distro is unknown. This package could not work correctly.") 49 | endif() 50 | ################################################ 51 | 52 | find_package(ament_cmake_auto REQUIRED) 53 | ament_auto_find_build_dependencies() 54 | 55 | if(BUILD_TESTING) 56 | find_package(ament_lint_auto REQUIRED) 57 | ament_lint_auto_find_test_dependencies() 58 | endif() 59 | 60 | ############################################################################### 61 | # Add all files in subdirectories of the project in 62 | # a dummy_target so qtcreator have access to all files 63 | file(GLOB_RECURSE all_files ${CMAKE_SOURCE_DIR}/*) 64 | add_custom_target(all_${PROJECT_NAME}_files SOURCES ${all_files}) 65 | ############################################################################### 66 | 67 | ament_package() 68 | -------------------------------------------------------------------------------- /zed_ros2/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | zed_ros2 5 | 5.0.0 6 | Stereolabs zed-ros2-wrapper support meta package 7 | STEREOLABS 8 | Apache License 2.0 9 | http://stereolabs.com/ 10 | https://github.com/stereolabs/zed-ros2-wrapper 11 | https://github.com/stereolabs/zed-ros2-wrapper/issues 12 | ament_cmake 13 | ament_cmake_auto 14 | zed_msgs 15 | zed_components 16 | zed_wrapper 17 | ament_lint_auto 18 | ament_cmake_copyright 19 | ament_cmake_cppcheck 20 | ament_cmake_lint_cmake 21 | ament_cmake_pep257 22 | ament_cmake_uncrustify 23 | ament_cmake_xmllint 24 | 25 | ament_cmake 26 | 27 | 28 | -------------------------------------------------------------------------------- /zed_wrapper/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(zed_wrapper) 3 | 4 | ## Generate symbols for IDE indexer 5 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 6 | 7 | ################################################ 8 | # Check the ROS2 version 9 | 10 | set(ROS2_FOUND FALSE) 11 | if(DEFINED ENV{ROS_DISTRO}) 12 | set(FOUND_ROS2_DISTRO $ENV{ROS_DISTRO}) 13 | set(ROS2_FOUND TRUE) 14 | #message("* Found ROS2 ${FOUND_ROS2_DISTRO}") 15 | else() 16 | message("* ROS2 distro variable not set. Trying to figure it out...") 17 | set(ROS2_DISTROS "ardent;crystal;dashing;eloquent;foxy;galactic;humble;jazzy;rolling") 18 | set(ROS2_FOUND FALSE) 19 | foreach(distro ${ROS2_DISTROS}) 20 | if(NOT ROS2_FOUND) 21 | find_path(RCLCPP_H rclcpp.hpp PATHS /opt/ros/${distro}/include/rclcpp) 22 | if(RCLCPP_H) 23 | #message("* Found ROS2 ${distro}") 24 | set(FOUND_ROS2_DISTRO ${distro}) 25 | set(ROS2_FOUND TRUE) 26 | endif() 27 | endif() 28 | endforeach() 29 | endif() 30 | 31 | if(ROS2_FOUND) 32 | if(${FOUND_ROS2_DISTRO} STREQUAL "foxy") 33 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 34 | add_definitions(-DFOUND_FOXY) 35 | elseif(${FOUND_ROS2_DISTRO} STREQUAL "iron") 36 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 37 | add_definitions(-DFOUND_IRON) 38 | elseif(${FOUND_ROS2_DISTRO} STREQUAL "humble") 39 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 40 | add_definitions(-DFOUND_HUMBLE) 41 | elseif(${FOUND_ROS2_DISTRO} STREQUAL "jazzy") 42 | #message("* ROS2 ${FOUND_ROS2_DISTRO} is officially supported by this package.") 43 | add_definitions(-DFOUND_JAZZY) 44 | else() 45 | message("*** WARNING *** Unsupported ROS2 ${FOUND_ROS2_DISTRO}. '${PROJECT_NAME}' may not work correctly.") 46 | endif() 47 | else() 48 | message("*** WARNING *** ROS2 distro is unknown. This package could not work correctly.") 49 | endif() 50 | ################################################ 51 | 52 | ############################################# 53 | # Dependencies 54 | find_package(ament_cmake_auto REQUIRED) 55 | ament_auto_find_build_dependencies() 56 | 57 | ############################################# 58 | # Install 59 | 60 | # Install PARAMS files 61 | install(DIRECTORY 62 | config 63 | DESTINATION share/${PROJECT_NAME} 64 | ) 65 | 66 | # Install URDF files 67 | install(DIRECTORY 68 | urdf 69 | DESTINATION share/${PROJECT_NAME} 70 | ) 71 | 72 | # Install LAUNCH files 73 | install(DIRECTORY 74 | launch 75 | DESTINATION share/${PROJECT_NAME} 76 | ) 77 | 78 | ament_package() 79 | -------------------------------------------------------------------------------- /zed_wrapper/config/common_mono.yaml: -------------------------------------------------------------------------------- 1 | # config/common_mono.yaml 2 | # Common parameters to Stereolabs ZED Stereo cameras 3 | 4 | --- 5 | /**: 6 | ros__parameters: 7 | general: 8 | serial_number: 0 # overwritten by launch file 9 | pub_resolution: "NATIVE" # The resolution used for output. 'NATIVE' to use the same `general.grab_resolution` - `CUSTOM` to apply the `general.pub_downscale_factor` downscale factory to reduce bandwidth in transmission 10 | pub_downscale_factor: 2.0 # rescale factor used to rescale image before publishing when 'pub_resolution' is 'CUSTOM' 11 | gpu_id: -1 12 | optional_opencv_calibration_file: "" # Optional path where the ZED SDK can find a file containing the calibration information of the camera computed by OpenCV. Read the ZED SDK documentation for more information: https://www.stereolabs.com/docs/api/structsl_1_1InitParameters.html#a9eab2753374ef3baec1d31960859ba19 13 | 14 | video: 15 | saturation: 4 # [DYNAMIC] 16 | sharpness: 4 # [DYNAMIC] 17 | gamma: 8 # [DYNAMIC] 18 | auto_whitebalance: true # [DYNAMIC] 19 | whitebalance_temperature: 42 # [DYNAMIC] - [28,65] x100 - works only if `auto_whitebalance` is false 20 | auto_exposure: true # [DYNAMIC] - Enables or disables auto exposure control. false: manual, true: auto 21 | exposure_time: 16000 # [DYNAMIC] - Defines the real exposure time in microseconds. Recommended to control manual exposure (instead of `video.exposure` setting) 22 | auto_exposure_time_range_min: 28 # [DYNAMIC] - Defines the minimum range of exposure auto control in micro seconds 23 | auto_exposure_time_range_max: 30000 # [DYNAMIC] - Defines the maximum range of exposure auto control in micro seconds 24 | exposure_compensation: 50 # [DYNAMIC] - Defines the Exposure-target compensation made after auto exposure. Reduces the overall illumination target by factor of F-stops. Values range is [0 - 100]. Default value is 50, i.e. no compensation applied 25 | auto_analog_gain: true # [DYNAMIC] - Enables or disables auto gain control. false: manual, true: auto 26 | analog_gain: 1255 # [DYNAMIC] - Defines the real analog gain (sensor) in mDB. Range [1000-16000]. Recommended to control manual sensor gain (instead of `video.gain` setting) 27 | auto_analog_gain_range_min: 1000 # [DYNAMIC] - Defines the minimum range of sensor gain in automatic control 28 | auto_analog_gain_range_max: 16000 # [DYNAMIC] - Defines the maximum range of sensor gain in automatic control 29 | auto_digital_gain: false # [DYNAMIC] - Enables or disables auto digital gain control. false: manual, true: auto 30 | digital_gain: 1 # [DYNAMIC] - Defines the real digital gain (ISP) as a factor. Range [1-256]. Recommended to control manual ISP gain (instead of `video.gain` setting) 31 | auto_digital_gain_range_min: 1 # [DYNAMIC] - Defines the minimum range of digital ISP gain in automatic control 32 | auto_digital_gain_range_max: 256 # [DYNAMIC] - Defines the maximum range of digital ISP gain in automatic control 33 | denoising: 50 # [DYNAMIC] - Defines the level of denoising applied on both left and right images. Range [0-100] 34 | 35 | sensors: 36 | publish_imu_tf: true # [overwritten by launch file options] enable/disable the IMU TF broadcasting 37 | sensors_pub_rate: 100. # [DYNAMIC] - frequency of publishing of sensors data. MAX: 400. - MIN: grab rate 38 | 39 | stream_server: 40 | stream_enabled: false # enable the streaming server when the camera is open 41 | codec: 'H264' # different encoding types for image streaming: 'H264', 'H265' 42 | port: 30000 # Port used for streaming. Port must be an even number. Any odd number will be rejected. 43 | bitrate: 12500 # [1000 - 60000] Streaming bitrate (in Kbits/s) used for streaming. See https://www.stereolabs.com/docs/api/structsl_1_1StreamingParameters.html#a873ba9440e3e9786eb1476a3bfa536d0 44 | gop_size: -1 # [max 256] The GOP size determines the maximum distance between IDR/I-frames. Very high GOP size will result in slightly more efficient compression, especially on static scenes. But latency will increase. 45 | adaptative_bitrate: false # Bitrate will be adjusted depending the number of packet dropped during streaming. If activated, the bitrate can vary between [bitrate/4, bitrate]. 46 | chunk_size: 16084 # [1024 - 65000] Stream buffers are divided into X number of chunks where each chunk is chunk_size bytes long. You can lower chunk_size value if network generates a lot of packet lost: this will generates more chunk for a single image, but each chunk sent will be lighter to avoid inside-chunk corruption. Increasing this value can decrease latency. 47 | target_framerate: 0 # Framerate for the streaming output. This framerate must be below or equal to the camera framerate. Allowed framerates are 15, 30, 60 or 100 if possible. Any other values will be discarded and camera FPS will be taken. 48 | 49 | advanced: # WARNING: do not modify unless you are confident of what you are doing 50 | # Reference documentation: https://man7.org/linux/man-pages/man7/sched.7.html 51 | thread_sched_policy: "SCHED_BATCH" # 'SCHED_OTHER', 'SCHED_BATCH', 'SCHED_FIFO', 'SCHED_RR' - NOTE: 'SCHED_FIFO' and 'SCHED_RR' require 'sudo' 52 | thread_grab_priority: 50 # ONLY with 'SCHED_FIFO' and 'SCHED_RR' - [1 (LOW) z-> 99 (HIGH)] - NOTE: 'sudo' required 53 | thread_sensor_priority: 70 # ONLY with 'SCHED_FIFO' and 'SCHED_RR' - [1 (LOW) z-> 99 (HIGH)] - NOTE: 'sudo' required 54 | 55 | debug: 56 | sdk_verbose: 1 # Set the verbose level of the ZED SDK 57 | sdk_verbose_log_file: '' # Path to the file where the ZED SDK will log its messages. If empty, no file will be created. The log level can be set using the `sdk_verbose` parameter. 58 | debug_common: false 59 | debug_video_depth: false 60 | debug_camera_controls: false 61 | debug_sensors: false 62 | debug_streaming: false 63 | debug_advanced: false 64 | -------------------------------------------------------------------------------- /zed_wrapper/config/ffmpeg.yaml: -------------------------------------------------------------------------------- 1 | # config/ffmpeg.yaml 2 | # Parameters to setup FFMPEG encoding in image_transport 3 | 4 | # Full parameter documentation: https://github.com/ros-misc-utilities/ffmpeg_image_transport/blob/master/README.md 5 | 6 | --- 7 | /**: 8 | ros__parameters: 9 | ffmpeg_image_transport: 10 | bit_rate: 4194304 # Default: 8242880 11 | delay: '0' # default is 4 frames for parallel processing. 0 is lowest latency 12 | encoding: 'libx264' # Only ever tested: libx264, h264_nvenc, h264, hevc_nvenc, h264_vaapi. If you have an Nvidia card it most likely supports hevc_nvenc. This will dramatically reduce the CPU load compare to libx264 (the default). You can list all available codecs with ffmpeg -codecs. In the relevant row, look for what it says under (encoders). 13 | gop_size: 10 # The number of frames inbetween keyframes. Default is 15. The larger this number the more latency you will have, but also the more efficient the transmission becomes. 14 | measure_performance: false # Enable performance analysis 15 | performance_interval: 100 # number of frames between perf printouts 16 | pixel_format: '' 17 | preset: '' # 'll','ultrafast','superfast','veryfast','faster','fast','medium','slow','slower','veryslow' -> https://trac.ffmpeg.org/wiki/Encode/H.264#Preset 18 | profile: '' # 'baseline','main' -> https://trac.ffmpeg.org/wiki/Encode/H.264#Tune 19 | qmax: 0 # max allowed quantization. The lower the better quality 20 | tune: '' # 'film','animation','grain','stillimage','fastdecode','zerolatency' -------------------------------------------------------------------------------- /zed_wrapper/config/object_detection.yaml: -------------------------------------------------------------------------------- 1 | /**: 2 | ros__parameters: 3 | object_detection: 4 | class: 5 | people: 6 | enabled: true # [DYNAMIC] - Enable/disable the detection of persons 7 | confidence_threshold: 65.0 # [DYNAMIC] - Minimum value of the detection confidence of an object [0,99] 8 | vehicle: 9 | enabled: true # [DYNAMIC] - Enable/disable the detection of vehicles 10 | confidence_threshold: 60.0 # [DYNAMIC] - Minimum value of the detection confidence of an object [0,99] 11 | bag: 12 | enabled: true # [DYNAMIC] - Enable/disable the detection of bags 13 | confidence_threshold: 40.0 # [DYNAMIC] - Minimum value of the detection confidence of an object [0,99] 14 | animal: 15 | enabled: true # [DYNAMIC] - Enable/disable the detection of animals 16 | confidence_threshold: 40.0 # [DYNAMIC] - Minimum value of the detection confidence of an object [0,99] 17 | electronics: 18 | enabled: true # [DYNAMIC] - Enable/disable the detection of electronic devices 19 | confidence_threshold: 45.0 # [DYNAMIC] - Minimum value of the detection confidence of an object [0,99] 20 | fruit_vegetable: 21 | enabled: true # [DYNAMIC] - Enable/disable the detection of fruits and vegetables 22 | confidence_threshold: 50.0 # [DYNAMIC] - Minimum value of the detection confidence of an object [0,99] 23 | sport: 24 | enabled: true # [DYNAMIC] - Enable/disable the detection of sport-related objects 25 | confidence_threshold: 30.0 # [DYNAMIC] - Minimum value of the detection confidence of an object [0,99] 26 | 27 | -------------------------------------------------------------------------------- /zed_wrapper/config/virtual.yaml: -------------------------------------------------------------------------------- 1 | # config/zedx.yaml 2 | # Parameters for Stereolabs ZED X camera 3 | --- 4 | /**: 5 | ros__parameters: 6 | general: 7 | camera_model: 'virtual' 8 | camera_name: 'virtual' # overwritten by launch file 9 | grab_resolution: 'HD1080' # The native camera grab resolution. '4K', 'HD1200', 'HD1080', 'SVGA', 'AUTO' 10 | grab_frame_rate: 30 # ZED SDK internal grabbing rate (HD1200/HD1080: 60, 30, 15 - SVGA: 120, 60, 30, 15) 11 | 12 | video: 13 | exposure_time: 16000 # Defines the real exposure time in microseconds. Recommended to control manual exposure (instead of `video.exposure` setting) 14 | auto_exposure_time_range_min: 28 # Defines the minimum range of exposure auto control in micro seconds 15 | auto_exposure_time_range_max: 30000 # Defines the maximum range of exposure auto control in micro seconds 16 | exposure_compensation: 50 # Defines the Exposure-target compensation made after auto exposure. Reduces the overall illumination target by factor of F-stops. Values range is [0 - 100]. Default value is 50, i.e. no compensation applied 17 | analog_gain: 1255 # Defines the real analog gain (sensor) in mDB. Range [1000-16000]. Recommended to control manual sensor gain (instead of `video.gain` setting) 18 | auto_analog_gain_range_min: 1000 # Defines the minimum range of sensor gain in automatic control 19 | auto_analog_gain_range_max: 16000 # Defines the maximum range of sensor gain in automatic control 20 | digital_gain: 1 # Defines the real digital gain (ISP) as a factor. Range [1-256]. Recommended to control manual ISP gain (instead of `video.gain` setting) 21 | auto_digital_gain_range_min: 1 # Defines the minimum range of digital ISP gain in automatic control 22 | auto_digital_gain_range_max: 256 # Defines the maximum range of digital ISP gain in automatic control 23 | denoising: 50 # Defines the level of denoising applied on both left and right images. Range [0-100] 24 | 25 | depth: 26 | min_depth: 0.3 # Min: 0.3, Max: 3.0 27 | max_depth: 40.0 28 | -------------------------------------------------------------------------------- /zed_wrapper/config/zed.yaml: -------------------------------------------------------------------------------- 1 | # config/zed_yaml 2 | # Parameters for Stereolabs ZED camera 3 | --- 4 | /**: 5 | ros__parameters: 6 | general: 7 | camera_model: 'zed' 8 | camera_name: 'zed' # overwritten by launch file 9 | grab_resolution: 'HD720' # The native camera grab resolution. 'HD2K', 'HD1080', 'HD720', 'VGA', 'AUTO' 10 | grab_frame_rate: 30 # ZED SDK internal grabbing rate 11 | 12 | video: 13 | brightness: 4 # [DYNAMIC] Image brightness. Range: 0-8 14 | contrast: 4 # [DYNAMIC] Image contrast. Range: 0-8 15 | hue: 0 # [DYNAMIC] Image hue. Range: 0 to 11 16 | 17 | depth: 18 | min_depth: 0.3 # Min: 0.3, Max: 3.0 19 | max_depth: 10. # Dynamic 20 | -------------------------------------------------------------------------------- /zed_wrapper/config/zed2.yaml: -------------------------------------------------------------------------------- 1 | # config/zed2_yaml 2 | # Parameters for Stereolabs ZED2 camera 3 | --- 4 | /**: 5 | ros__parameters: 6 | general: 7 | camera_model: 'zed2' 8 | camera_name: 'zed2' # overwritten by launch file 9 | grab_resolution: 'HD720' # The native camera grab resolution. 'HD2K', 'HD1080', 'HD720', 'VGA', 'AUTO' 10 | grab_frame_rate: 30 # ZED SDK internal grabbing rate 11 | 12 | video: 13 | brightness: 4 # [DYNAMIC] Image brightness. Range: 0-8 14 | contrast: 4 # [DYNAMIC] Image contrast. Range: 0-8 15 | hue: 0 # [DYNAMIC] Image hue. Range: 0 to 11 16 | 17 | depth: 18 | min_depth: 0.3 # Min: 0.3, Max: 3.0 19 | max_depth: 10.0 # Max: 40.0 20 | 21 | -------------------------------------------------------------------------------- /zed_wrapper/config/zed2i.yaml: -------------------------------------------------------------------------------- 1 | # config/zed2i_yaml 2 | # Parameters for Stereolabs zed2i camera 3 | --- 4 | /**: 5 | ros__parameters: 6 | general: 7 | camera_model: 'zed2i' 8 | camera_name: 'zed2i' # overwritten by launch file 9 | grab_resolution: 'HD720' # The native camera grab resolution. 'HD2K', 'HD1080', 'HD720', 'VGA', 'AUTO' 10 | grab_frame_rate: 30 # ZED SDK internal grabbing rate 11 | 12 | video: 13 | brightness: 4 # [DYNAMIC] Image brightness. Range: 0-8 14 | contrast: 4 # [DYNAMIC] Image contrast. Range: 0-8 15 | hue: 0 # [DYNAMIC] Image hue. Range: 0 to 11 16 | 17 | depth: 18 | min_depth: 0.3 # Min: 0.3, Max: 3.0 19 | max_depth: 10.0 # Max: 40.0 20 | 21 | -------------------------------------------------------------------------------- /zed_wrapper/config/zedm.yaml: -------------------------------------------------------------------------------- 1 | # config/zedm_yaml 2 | # Parameters for Stereolabs ZED mini camera 3 | --- 4 | /**: 5 | ros__parameters: 6 | general: 7 | camera_model: 'zedm' 8 | camera_name: 'zedm' # overwritten by launch file 9 | grab_resolution: 'HD1080' # The native camera grab resolution. 'HD2K', 'HD1080', 'HD720', 'VGA', 'AUTO' 10 | grab_frame_rate: 30 # ZED SDK internal grabbing rate 11 | 12 | video: 13 | brightness: 4 # [DYNAMIC] Image brightness. Range: 0-8 14 | contrast: 4 # [DYNAMIC] Image contrast. Range: 0-8 15 | hue: 0 # [DYNAMIC] Image hue. Range: 0 to 11 16 | 17 | depth: 18 | min_depth: 0.1 # Min: 0.1, Max: 3.0 19 | max_depth: 10.0 # Max: 20.0 20 | 21 | -------------------------------------------------------------------------------- /zed_wrapper/config/zedx.yaml: -------------------------------------------------------------------------------- 1 | # config/zedx.yaml 2 | # Parameters for Stereolabs ZED X camera 3 | --- 4 | /**: 5 | ros__parameters: 6 | general: 7 | camera_model: 'zedx' 8 | camera_name: 'zedx' # overwritten by launch file 9 | grab_resolution: 'HD1200' # The native camera grab resolution. 'HD1200', 'HD1080', 'SVGA', 'AUTO' 10 | grab_frame_rate: 30 # ZED SDK internal grabbing rate (HD1200/HD1080: 60, 30, 15 - SVGA: 120, 60, 30, 15) 11 | 12 | video: 13 | exposure_time: 16000 # Defines the real exposure time in microseconds. Recommended to control manual exposure (instead of `video.exposure` setting) 14 | auto_exposure_time_range_min: 28 # Defines the minimum range of exposure auto control in micro seconds 15 | auto_exposure_time_range_max: 30000 # Defines the maximum range of exposure auto control in micro seconds 16 | exposure_compensation: 50 # Defines the Exposure-target compensation made after auto exposure. Reduces the overall illumination target by factor of F-stops. Values range is [0 - 100]. Default value is 50, i.e. no compensation applied 17 | analog_gain: 1255 # Defines the real analog gain (sensor) in mDB. Range [1000-16000]. Recommended to control manual sensor gain (instead of `video.gain` setting) 18 | auto_analog_gain_range_min: 1000 # Defines the minimum range of sensor gain in automatic control 19 | auto_analog_gain_range_max: 16000 # Defines the maximum range of sensor gain in automatic control 20 | digital_gain: 1 # Defines the real digital gain (ISP) as a factor. Range [1-256]. Recommended to control manual ISP gain (instead of `video.gain` setting) 21 | auto_digital_gain_range_min: 1 # Defines the minimum range of digital ISP gain in automatic control 22 | auto_digital_gain_range_max: 256 # Defines the maximum range of digital ISP gain in automatic control 23 | denoising: 50 # Defines the level of denoising applied on both left and right images. Range [0-100] 24 | 25 | depth: 26 | min_depth: 0.3 # Min: 0.3, Max: 3.0 27 | max_depth: 10.0 # Max: 20.0 28 | 29 | -------------------------------------------------------------------------------- /zed_wrapper/config/zedxm.yaml: -------------------------------------------------------------------------------- 1 | # config/zedxm_yaml 2 | # Parameters for Stereolabs ZED X Mini camera 3 | --- 4 | /**: 5 | ros__parameters: 6 | general: 7 | camera_model: 'zedxm' 8 | camera_name: 'zedxm' # overwritten by launch file 9 | grab_resolution: 'HD1200' # The native camera grab resolution. 'HD1200', 'HD1080', 'SVGA', 'AUTO' 10 | grab_frame_rate: 30 # ZED SDK internal grabbing rate (HD1200/HD1080: 60, 30, 15 - SVGA: 120, 60, 30, 15) 11 | 12 | video: 13 | exposure_time: 16666 # Defines the real exposure time in microseconds. Recommended to control manual exposure (instead of `video.exposure` setting) 14 | auto_exposure_time_range_min: 28 # Defines the minimum range of exposure auto control in micro seconds 15 | auto_exposure_time_range_max: 16666 # Defines the maximum range of exposure auto control in micro seconds 16 | exposure_compensation: 50 # Defines the Exposure-target compensation made after auto exposure. Reduces the overall illumination target by factor of F-stops. Values range is [0 - 100]. Default value is 50, i.e. no compensation applied 17 | analog_gain: 8000 # Defines the real analog gain (sensor) in mDB. Range [1000-16000]. Recommended to control manual sensor gain (instead of `video.gain` setting) 18 | auto_analog_gain_range_min: 1000 # Defines the minimum range of sensor gain in automatic control 19 | auto_analog_gain_range_max: 16000 # Defines the maximum range of sensor gain in automatic control 20 | digital_gain: 128 # Defines the real digital gain (ISP) as a factor. Range [1-256]. Recommended to control manual ISP gain (instead of `video.gain` setting) 21 | auto_digital_gain_range_min: 1 # Defines the minimum range of digital ISP gain in automatic control 22 | auto_digital_gain_range_max: 256 # Defines the maximum range of digital ISP gain in automatic control 23 | denoising: 50 # Defines the level of denoising applied on both left and right images. Range [0-100] 24 | 25 | depth: 26 | min_depth: 0.3 # Min: 0.3, Max: 3.0 27 | max_depth: 10.0 # Max: 20.0 28 | 29 | -------------------------------------------------------------------------------- /zed_wrapper/config/zedxone4k.yaml: -------------------------------------------------------------------------------- 1 | # config/zedxone4k.yaml 2 | # Parameters for Stereolabs ZED X One 4K camera 3 | --- 4 | /**: 5 | ros__parameters: 6 | general: 7 | camera_model: 'zedxone4k' 8 | camera_name: 'zedxone4k' # overwritten by launch file 9 | grab_resolution: 'QHDPLUS' # The native camera grab resolution. 'HD4K', 'HD1200', 'QHDPLUS, 'HD1080', 'SVGA', 'AUTO' 10 | grab_frame_rate: 30 # ZED SDK internal grabbing rate (HD4K/QHDPLUS: 15 - HD1200/HD1080: 60, 30, 15 - SVGA: 120, 60, 30, 15) 11 | 12 | video: 13 | enable_hdr: false # When set to true, the camera will be set in HDR mode if the camera model and resolution allows it 14 | 15 | -------------------------------------------------------------------------------- /zed_wrapper/config/zedxonegs.yaml: -------------------------------------------------------------------------------- 1 | # config/zedxonegs.yaml 2 | # Parameters for Stereolabs ZED X One GS camera 3 | --- 4 | /**: 5 | ros__parameters: 6 | general: 7 | camera_model: 'zedxonegs' 8 | camera_name: 'zedxonegs' # overwritten by launch file 9 | grab_resolution: 'HD1200' # The native camera grab resolution. 'HD1200', 'HD1080', 'SVGA', 'AUTO' 10 | grab_frame_rate: 30 # ZED SDK internal grabbing rate (HD1200/HD1080: 60, 30, 15 - SVGA: 120, 60, 30, 15) -------------------------------------------------------------------------------- /zed_wrapper/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | zed_wrapper 5 | 5.0.0 6 | zed_wrapper loading zed_components in a single process 7 | STEREOLABS 8 | Apache License 2.0 9 | https://www.stereolabs.com/ 10 | https://github.com/stereolabs/zed-ros2-wrapper 11 | https://github.com/stereolabs/zed-ros2-wrapper/issues 12 | ament_cmake 13 | ament_cmake_auto 14 | zed_components 15 | rclcpp 16 | rclcpp_components 17 | rcutils 18 | zed_components 19 | launch_ros 20 | rclcpp 21 | rclcpp_components 22 | rcutils 23 | xacro 24 | image_transport_plugins 25 | compressed_image_transport 26 | compressed_depth_image_transport 27 | theora_image_transport 28 | ffmpeg_image_transport 29 | ffmpeg_encoder_decoder 30 | point_cloud_transport_plugins 31 | draco_point_cloud_transport 32 | zlib_point_cloud_transport 33 | zstd_point_cloud_transport 34 | ament_lint_auto 35 | ament_cmake_copyright 36 | ament_cmake_cppcheck 37 | ament_cmake_lint_cmake 38 | ament_cmake_pep257 39 | ament_cmake_uncrustify 40 | ament_cmake_xmllint 41 | 42 | ament_cmake 43 | 44 | 45 | -------------------------------------------------------------------------------- /zed_wrapper/urdf/include/materials.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /zed_wrapper/urdf/zed_descr.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /zed_wrapper/urdf/zed_macro.urdf.xacro: -------------------------------------------------------------------------------- 1 | 2 | 3 | 18 | 19 | 20 | 21 | 22 | 23 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | --------------------------------------------------------------------------------