├── .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 |
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 | 
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 | 
146 |
147 | 
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 |
--------------------------------------------------------------------------------