Add Chinese documentation for camera and lidar devices

This commit is contained in:
ob-yalian
2025-12-31 17:42:46 +08:00
parent c59af3d328
commit fd13aba31f
172 changed files with 466 additions and 8 deletions
@@ -0,0 +1,267 @@
# 引言
OrbbecSDK ROS2 封装为 Orbbec 相机与 ROS 2 环境提供无缝集成。它支持 ROS2 Foxy、Humble 和 Jazzy 发行版。
默认推荐使用 **v2-main** 分支。对于 v2-main 尚不支持的旧 OpenNI 设备,请使用 **main** 分支。仅由 main 分支支持的设备型号列在下表中。
如果您是中国用户,推荐使用 [gitee 仓库](https://gitee.com/orbbecdeveloper/OrbbecSDK_ROS2)。
下面是 main 分支 (v1.x) 与 v2-main 分支 (v2.x) 的设备支持列表:
<table border="1" style="border-collapse: collapse; text-align: left; width: 100%;">
<thead>
<tr style="background-color: #1f4e78; color: white; text-align: center;">
<th>产品系列</th>
<th>产品</th>
<th><a href="https://github.com/orbbec/OrbbecSDK_ROS2/tree/main" style="color: black; text-decoration: none;">main 分支</a></th>
<th><a href="https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main" style="color: black; text-decoration: none;">v2-main 分支</a></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center; font-weight: bold;">Gemini 435Le</td>
<td>Gemini 435Le</td>
<td>not supported</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td rowspan="8" style="text-align: center; font-weight: bold;">Gemini 330</td>
<td>Gemini 335Le</td>
<td>not supported</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Gemini 335</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Gemini 336</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Gemini 330</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Gemini 335L</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Gemini 336L</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Gemini 330L</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Gemini 335Lg</td>
<td>not supported</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td rowspan="5" style="text-align: center; font-weight: bold;">Gemini 2</td>
<td>Gemini 2</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Gemini 2 L</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Gemini 2 XL</td>
<td>recommended for new designs</td>
<td>to be supported</td>
</tr>
<tr>
<td>Gemini 215</td>
<td>not supported</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Gemini 210</td>
<td>not supported</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td rowspan="3" style="text-align: center; font-weight: bold;">Femto</td>
<td>Femto Bolt</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Femto Mega</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Femto Mega I</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td rowspan="3" style="text-align: center; font-weight: bold;">Astra</td>
<td>Astra 2</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
<tr>
<td>Astra+</td>
<td>limited maintenance</td>
<td>not supported</td>
</tr>
<tr>
<td>Astra Pro Plus</td>
<td>limited maintenance</td>
<td>not supported</td>
</tr>
<tr>
<td style="text-align: center; font-weight: bold;">Astra Mini</td>
<td>Astra Mini (S) Pro</td>
<td>full maintenance</td>
<td>recommended for new designs</td>
</tr>
</tbody>
</table>
**注意**: 如果未找到您的设备,请联系我们的 FAE 或销售代表获取帮助。
**术语定义**:
1. 建议用于新设计:我们将提供完整支持,包括新特性、缺陷修复与性能优化;
2. 完整维护:我们将提供缺陷修复支持;
3. 限制维护:我们仅提供关键缺陷修复支持;
4. 不支持:当前版本不支持该设备;
5. 即将支持:近期将添加支持。
## 支持的硬件产品
以下设备由 OrbbecSDK ROS2 封装 v2-main 分支支持。后续将增加更多设备支持。如果您在下表中未找到设备,请尝试 [main](https://github.com/orbbec/OrbbecSDK_ROS2) 分支。
为获得最佳性能,强烈建议升级到最新固件版本,以确保获得最新的改进与缺陷修复。
关于如何获取与升级最新固件,[请点击这里](../3_quickstarts/orbbecviewer.md)。
| **产品列表** | **推荐固件版本** | **启动文件** |
| ----------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------- |
| Astra Mini Pro | [2.0.03](https://github.com/orbbec/OrbbecFirmware/releases/tag/Astra-Mini-Pro) | astra.launch.py |
| Astra Mini S Pro | [2.0.03](https://github.com/orbbec/OrbbecFirmware/releases/tag/Astra-Mini-S-Pro) | astra.launch.py |
| Gemini 435Le | [1.3.2](https://github.com/orbbec/OrbbecFirmware/releases/tag/Gemin435Le-Firmware) | gemini435_le.launch.py |
| Gemini 330 series | [1.6.00](https://orbbec-debian-repos-aws.s3.amazonaws.com/product/Gemini330_Release_1.6.00.zip) | gemini_330_series.launch.py |
| Gemini 215 | [1.0.9](https://github.com/orbbec/OrbbecFirmware/releases/tag/Gemini215-Firmware) | gemini210.launch.py |
| Gemini 210 | [1.0.9](https://github.com/orbbec/OrbbecFirmware/releases/tag/Gemini210-Firmware) | gemini210.launch.py |
| Gemini 2 | [1.4.98](https://github.com/orbbec/OrbbecFirmware/releases/tag/Gemini2-Firmware) | gemini2.launch.py |
| Gemini 2 L | [1.5.2](https://github.com/orbbec/OrbbecFirmware/releases/tag/Gemini2L-Firmware) | gemini2L.launch.py |
| Femto Bolt | [1.1.2](https://github.com/orbbec/OrbbecFirmware/releases/tag/Femto-Bolt-Firmware) | femto_bolt.launch.py |
| Femto Mega | [1.3.1](https://github.com/orbbec/OrbbecFirmware/releases/tag/Femto-Mega-Firmware) | femto_mega.launch.py |
| Femto Mega I | [2.0.4](https://github.com/orbbec/OrbbecFirmware/releases/tag/Femto-Mega-I-Firmware) | femto_mega.launch.py |
| Astra 2 | [2.8.20](https://orbbec-debian-repos-aws.s3.amazonaws.com/product/Astra2_Release_2.8.20.zip) | astra2.launch.py |
所有启动文件本质上是类似的,主要区别在于同系列不同型号设置的参数默认值。USB 标准差异(如 USB 2.0 与 USB 3.0)可能需要调整这些参数。如果遇到启动失败,请仔细查看规格说明书,特别关注启动文件中的分辨率设置以及其他参数,以确保兼容与最佳性能。
## Orbbec 相机规格书
更多信息请参考相机规格书。
<style>
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid #ccc;
padding: 8px;
text-align: left;
vertical-align: middle;
}
thead th {
background-color: #1f4e78;
color: white;
text-align: center;
vertical-align: middle;
}
</style>
<table>
<thead>
<tr>
<th>产品系列</th>
<th>产品</th>
<th>规格书</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">Gemini 435Le</td>
<td>Gemini 435Le</td>
<td><a href="https://new-orbbec3d-s3.s3.amazonaws.com/wp-content/uploads/2025/06/04011158/Orbbec-Gemini-435Le-Datasheet-V1.pdf">Orbbec Gemini 435Le 规格书</a></td>
</tr>
<tr>
<td style="text-align: center;" rowspan="6">Gemini 330</td>
<td>Gemini 335</td>
<td rowspan="4"><a href="https://new-orbbec3d-s3.s3.amazonaws.com/wp-content/uploads/2025/04/22062452/Gemini-330-series-Datasheet-V1.6.pdf">Gemini 330 系列 USB 设备规格书</a></td>
</tr>
<tr><td>Gemini 336</td></tr>
<tr><td>Gemini 335L</td></tr>
<tr><td>Gemini 336L</td></tr>
<tr>
<td>Gemini 335Lg</td>
<td><a href="https://new-orbbec3d-s3.s3.amazonaws.com/wp-content/uploads/2024/10/22030914/Gemini-335Lg-Datasheet-V1.0-241022.pdf">Gemini 330 系列 GMSL 设备规格书</a></td>
</tr>
<tr>
<td>Gemini 335Le</td>
<td><a href="https://new-orbbec3d-s3.s3.amazonaws.com/wp-content/uploads/2025/03/24023151/Orbbec-Gemini-335Le-Datasheet-V1-2.pdf">Gemini 330 系列 以太网设备规格书</a></td>
</tr>
<tr>
<td style="text-align: center;" rowspan="3">Gemini 2</td>
<td>Gemini 2</td>
<td rowspan="2"><a href="https://xm917ch2uk.feishu.cn/file/Khxfb2vdioUghexIMqJcAyL3nXf">Orbbec Gemini 2 系列规格书</a></td>
</tr>
<tr><td>Gemini 2 L</td></tr>
<tr>
<td>Gemini 2 XL</td>
<td><a href="https://xm917ch2uk.feishu.cn/file/QW2vbNvwxoocRIxSL6Zcvut2npS">Orbbec Gemini 2 XL 规格书</a></td>
</tr>
<tr>
<td style="text-align: center;" rowspan="3">Femto</td>
<td>Femto Bolt</td>
<td><a href="https://d1cd332k3pgc17.cloudfront.net/wp-content/uploads/2024/08/ORBBEC_Datasheet_Femto-Bolt-v1.0.pdf">Orbbec Femto Bolt 规格书</a></td>
</tr>
<tr>
<td>Femto Mega</td>
<td><a href="https://d1cd332k3pgc17.cloudfront.net/wp-content/uploads/2023/04/ORBBEC_Datasheet_Femto-Mega1.pdf">Orbbec Femto Mega 规格书</a></td>
</tr>
<tr>
<td>Femto Mega I</td>
<td><a href="https://d1cd332k3pgc17.cloudfront.net/wp-content/uploads/2023/08/ORBBEC_Datasheet_Femto-Mega-I.pdf">Orbbec Femto Mega I 规格书</a></td>
</tr>
<tr>
<td style="text-align: center;" rowspan="3">Astra</td>
<td>Astra 2</td>
<td><a href="https://d1cd332k3pgc17.cloudfront.net/wp-content/uploads/2023/04/ORBBEC_Datasheet_Astra-2_V1.2.pdf">Orbbec Astra 2 规格书</a></td>
</tr>
<tr>
<td>Astra+</td>
<td><a href="https://xm917ch2uk.feishu.cn/file/Qk0zbx26Doh8XMxw0rIcOgQYnff">Orbbec Astra+ 规格书</a></td>
</tr>
<tr>
<td>Astra Mini Pro</td>
<td><a href="https://d1cd332k3pgc17.cloudfront.net/wp-content/uploads/2023/04/ORBBEC_Datasheet_Astra-Mini-Pro-1.pdf">Orbbec Astra Mini Pro 规格书</a></td>
</tr>
</tbody>
</table>
---
## 支持的平台
- Linux x64:已在 Ubuntu 22.04 上测试
- Linux ARM64:已在 NVIDIA Jetson AGX Orin、NVIDIA Jetson Orin NX、NVIDIA Jetson Orin Nano、NVIDIA Jetson AGX Xavier、NVIDIA Jetson Xavier NX 上测试
@@ -0,0 +1,106 @@
# Orbbec SDK 概述
本节介绍 C++ 版本的 Orbbec SDK。其架构和概念与 Python 包装器一致。
## 术语
| 序号 | 名称 | 说明 |
| --- | --- | --- |
| 1 | USB | 通用串行总线(Universal Serial Bus) |
| 2 | UVC | USB 视频类(USB Video Class) |
| 3 | Firmware | 3D 相机的固件 |
| 4 | Disparity | 视差是指从两个有一定距离的点观察同一目标时的方向差异。 |
| 5 | D2D (Disparity to depth) | 视差转深度是一种图像处理技术,用于将视差信息转换为深度信息。 |
| 6 | Hardware D2D | 视差转深度在设备内部实现,不占用主机的计算能力。 |
| 7 | Software D2D | 视差转深度,在 Orbbec SDK 中实现 |
| 8 | Depth point cloud | 深度点云,三维世界坐标系中点的坐标,可以使用深度相机的内参转换为点云。 |
| 9 | RGBD point cloud | 叠加了 RGB 信息的点云 |
| 10 | D2C | "深度到彩色"(Depth to Color)是一种对深度图像进行逐像素几何变换的功能。其结果是通过 D2C 变换将深度图像与其对应的彩色图像对齐,使我们能够通过在变换后的深度图像中使用相同图像坐标位置来定位彩色像素的深度信息。经过 D2C 变换后,我们生成一个与目标彩色图像大小相同的深度图像,其中图像内容表示彩色相机坐标系中的深度数据。换句话说,它重建了一个使用彩色相机的原点和尺寸"拍摄"的深度图像,其中每个像素与彩色相机的相应像素坐标匹配。 |
| 11 | Hardware D2C | 硬件 D2C 是指在相机内部执行深度到彩色变换的功能,相机直接输出 D2C 变换的结果。 |
| 12 | Software D2C | 使用 SDK 在主机端执行 D2C 计算。 |
| 13 | Frame aggregation (FrameSet) | 帧聚合,将深度、红外和彩色帧组合成一个帧集(Frameset),并通过管道调用。 |
| 14 | C2D | "彩色到深度"(Color to Depth)是一种对彩色图像进行逐像素几何变换的功能。其结果是通过 C2D 变换将彩色图像与其对应的深度图像对齐。 |
| 15 | MetaData | 帧元数据是一组参数(或属性),提供了帧生成时传感器配置和/或系统状态的快照。 |
| 16 | HDR | 高动态范围(High Dynamic Range,HDR)成像允许成像系统在极暗和极亮的场景中拍摄图像。我们提出了一种在主机 CPU 上运行的软件解决方案来实现此功能。它利用两个连续帧的数据,直接合成这两个深度图像,从而增强 16 位深度图像的动态范围。 |
| 17 | LDP | 激光近距离保护(Laser close-range protection) |
## Orbbec SDK v2 架构概述
![OrbbecSDK v2 软件架构](../image/Soft_Architecture.png)
- 应用层(Application)
OrbbecViewer、示例程序和用户应用程序实现。
- 接口和封装层(Interfaces and Encapsulation Layer)
OrbbecSDK 接口封装和包装器封装。
- 高级层(High-level Layer)
HighLevel 封装了核心业务组件,并使用管道(pipeline)向外部提供接口。
- 基础业务层(Basic business layer)
核心业务逻辑框架的实现。
- 平台抽象层(Platform abstraction layer)
跨平台组件抽象操作系统差异,提供统一的访问接口。
- 平台实现层(Platform implementation layer)
各平台的驱动实现。
## SDK 概念概述
- Context(上下文)
上下文提供一组设置,包括设备状态更改回调、日志级别等设置。Context 可以访问多个设备。
- Device(设备)
一个实际的硬件设备对应一个 Device 对象,用于获取设备的相关信息并控制其属性。
- Pipeline(管道)
HighLevel 对应的对象,封装了快速访问 SDK 的接口。它具有简单的功能,使用户能够快速上手并使用 SDK。
- Config(配置)
提供启用数据流、对齐模式和帧聚合模式的配置,用于控制数据输出的行为。
- StreamProfile(流配置)
流配置定义分辨率、帧率和编码格式等参数,还提供相机参数的管理。
- Frame(帧)
表示流中的一帧数据,还包含该帧数据的相关信息,如时间戳、类型等。
- Filter(滤镜)
主要指用于复合流 FrameSet 的一些算法处理模块,如点云算法处理。
- Record(录制)
录制功能,捕获数据流并将其保存为文件,以便后续分析或回放。
- Playback(回放)
回放功能,播放录制的文件,并支持控制回放速度和其他相关参数。
## SDK 编程模型
以下是 C++ 编程逻辑流程图。Python 的编程逻辑与之相同。
- 标准流程图:
![image.png](../image/Standard_Flowchart.png)
标准流程图演示了如何从设备列表创建设备、设置和获取参数,以及应用后处理滤镜。
- 使用默认配置的流程图(基于 OrbbecSDKConfig.xml 中的默认设置获取流):
![image](../image/Default_Flowchart.png)
@@ -0,0 +1,11 @@
概述
======================================================
本章节提供 Orbbec SDK 的概述,包括支持的产品、主要功能和架构。
.. toctree::
:maxdepth: 2
introduction.md
orbbecsdk_overview.md
@@ -0,0 +1,65 @@
### 环境配置
根据官方指南安装 ROS 2:
* [ROS 2 安装指南(Ubuntu)](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html)
安装依赖项:
```bash
sudo apt install libgflags-dev nlohmann-json3-dev \
ros-$ROS_DISTRO-image-transport ros-${ROS_DISTRO}-image-transport-plugins ros-${ROS_DISTRO}-compressed-image-transport \
ros-$ROS_DISTRO-image-publisher ros-$ROS_DISTRO-camera-info-manager \
ros-$ROS_DISTRO-diagnostic-updater ros-$ROS_DISTRO-diagnostic-msgs ros-$ROS_DISTRO-statistics-msgs ros-$ROS_DISTRO-xacro \
ros-$ROS_DISTRO-backward-ros libdw-dev libssl-dev
```
启用 ROS 2 自动补全:
```bash
eval "$(register-python-argcomplete3 ros2)"
eval "$(register-python-argcomplete3 colcon)"
```
### 二进制安装
查看软件包:
```bash
sudo apt update
apt list | grep orbbec
```
安装 OrbbecSDK ROS2 包:
```bash
sudo apt install ros-humble-orbbec-camera ros-humble-orbbec-description
```
安装完成后,直接使用即可,无需编译。
---
### 从源码构建
创建 `colcon` 工作空间:
```bash
mkdir -p ~/ros2_ws/src
```
克隆源代码并切换到 `v2-main` 分支:
```bash
cd ~/ros2_ws/src
git clone https://github.com/orbbec/OrbbecSDK_ROS2.git
cd OrbbecSDK_ROS2
git checkout v2-main
```
构建:
```bash
cd ~/ros2_ws
colcon build --event-handlers console_direct+ --cmake-args -DCMAKE_BUILD_TYPE=Release
```
@@ -0,0 +1,11 @@
安装
======================================================
本章节说明如何安装 Orbbec ROS2 Python SDK,包括从源码构建、安装依赖项以及使用注册脚本。
.. toctree::
:maxdepth: 2
build_the_package.md
registration_script.md
@@ -0,0 +1,22 @@
## 注册脚本(必需)
为了让 Orbbec 相机在 Linux 上被正确识别,请安装 udev 规则。
### 二进制安装
```bash
sudo cp /opt/ros/$ROS_DISTRO/share/orbbec_camera/udev/99-obsensor-libusb.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger
```
### 从源码构建
```bash
cd ~/ros2_ws/src/OrbbecSDK_ROS2/orbbec_camera/scripts
sudo bash install_udev_rules.sh
sudo udevadm control --reload-rules && sudo udevadm trigger
```
此步骤对于 Linux 用户是**必需的**。
`注意:` 如果不执行此脚本,由于权限问题,打开设备将会失败。您需要使用 sudo(管理员权限)运行示例程序。
@@ -0,0 +1,46 @@
# OrbbecViewer 快速入门
> **注意:** 此 ROS 包的参数和功能与 **Orbbec Viewer** 保持一致;有关参数使用或设备型号支持的任何问题,请参考 Orbbec Viewer。
## 下载
**仓库链接:**[OrbbecViewer 下载](https://github.com/orbbec/OrbbecSDK_v2/releases)
根据您的设备类型选择合适版本的 OrbbecViewer。
![orbbecviewer](../image/orbbecviewer1.png)
## 连接设备
当 Orbbec Viewer 打开时,当前设备连接状态将显著地显示在应用程序窗口的左上角。此区域提供关于相机是否已连接并正常工作的即时反馈。
![orbbecviewer](../image/orbbecviewer2.png)
## 相机控制
您可以使用窗口顶部的按钮快速查看图像,并在窗口左侧的相机面板中调整图像参数。
![orbbecviewer](../image/orbbecviewer3.png)
## 设备信息和固件升级
点击窗口左下角的图标以查看当前相机信息并升级固件。
![orbbecviewer](../image/orbbecviewer4.png)
请参考下面的列表获取最新的相机固件。[更多信息请点击这里。](https://www.orbbec.com/docs/g330-explore-camera-functions-in-orbbec-viewer/)
**仓库链接:**[固件下载](https://github.com/orbbec/OrbbecFirmware?tab=readme-ov-file#firmware-download)
| **产品列表** | **下载链接** | 最新版本 |
| ------------------ | -------------------------------------------------------------------------------------------------- | ---------- |
| Femto Bolt | [Femto Bolt 固件](https://github.com/orbbec/OrbbecFirmware/releases/tag/Femto-Bolt-Firmware) | v1.1.2 |
| Femto Mega | [Femto Mega 固件](https://github.com/orbbec/OrbbecFirmware/releases/tag/Femto-Mega-Firmware) | v1.3.1 |
| Gemini 2 | [Gemini 2 固件](https://github.com/orbbec/OrbbecFirmware/releases/tag/Gemini2-Firmware) | v1.4.98 |
| Gemini 2 L | [Gemini 2L 固件](https://github.com/orbbec/OrbbecFirmware/releases/tag/Gemini2L-Firmware) | v1.5.02 |
| Femto Mega I | [Femto Mega I 固件](https://github.com/orbbec/OrbbecFirmware/releases/tag/Femto-Mega-I-Firmware) | v2.0.4 |
| Gemini 330 系列 | [Gemini 330 系列固件](https://www.orbbec.com/docs/g330-firmware-release/?_gl=1) | |
| Gemini 215 | [Gemini 215](https://github.com/orbbec/OrbbecFirmware/releases/tag/Gemini215-Firmware) | v1.0.9 |
| Gemini 210 | [Gemini 210](https://github.com/orbbec/OrbbecFirmware/releases/tag/Gemini210-Firmware) | v1.0.9 |
| Gemini 435Le | [Gemini 435Le](https://github.com/orbbec/OrbbecFirmware/releases/tag/Gemin435Le-Firmware) | v1.3.2 |
@@ -0,0 +1,96 @@
## ROS 包快速入门
### 简介
本节提供 Orbbec ROS 2 包装器的快速入门指南。
您将学习如何:
* 启动相机节点。
* 在 **RViz2** 中可视化深度/彩色流。
* 使用 **ROS 2 CLI 工具**与话题和服务交互。
---
### 构建您的第一个相机应用
#### 步骤 1:配置 ROS 2 和工作空间环境
确保已配置 ROS 2 和工作空间环境:
```bash
source /opt/ros/$ROS_DISTRO/setup.bash
```
源码构建需要
```bash
source ~/ros2_ws/install/setup.bash
```
#### 步骤 2:启动相机节点
- 在终端 1 中
```bash
. ./install/setup.bash
ros2 run orbbec_camera list_devices_node #检查相机是否已连接
ros2 launch orbbec_camera gemini_330_series.launch.py # 或其他启动文件,见下表
```
如果您连接了多个相机,可以指定**序列号**:
```bash
ros2 launch orbbec_camera gemini_330_series.launch.py serial_number:=<您的相机序列号>
```
#### 步骤 3:在 RViz2 中可视化
启动 RViz2 并加载默认配置:
- 在终端 2 中
```bash
rviz2
```
* 添加一个 **Image** 显示,将话题设置为 `/camera/color/image_raw`。
* 为 `/camera/depth/image_raw` 添加另一个 **Image** 显示。
* 可选:为 `/camera/depth/points` 添加 **PointCloud2** 显示。
现在您应该能在 RViz2 中看到彩色流、深度流和 3D 点云。
---
### 示例功能
节点运行后,尝试一些 ROS 2 CLI 命令:
#### 列出可用的话题/服务/参数
```bash
ros2 topic list
ros2 service list
ros2 param list
```
#### 回显话题
查看深度相机数据:
```bash
ros2 topic echo /camera/depth/camera_info
```
#### 调用服务
例如,获取设备信息:
```bash
ros2 service call /camera/get_device_info orbbec_camera_msgs/srv/GetDeviceInfo '{}'
```
#### 使用 rosbag2 录制
```bash
ros2 bag record /camera/color/image_raw /camera/depth/image_raw
```
@@ -0,0 +1,11 @@
快速开始
======================================================
本章节提供 SDK 的快速入门指南,帮助用户快速运行基本示例程序。
.. toctree::
:maxdepth: 2
quickstart.md
orbbecviewer.md
@@ -0,0 +1,14 @@
应用指南
======================================================
本章介绍使用SDK进行应用开发,包括启动参数配置、ROS2服务和话题使用。
.. toctree::
:maxdepth: 2
launch_parameters.md
services.md
topics.md
coordinate_and_tf.md
compressed_image.md
point_cloud.md
@@ -0,0 +1,11 @@
### 压缩图像
您可以使用 `image_transport` 通过 `jpeg` 压缩图像。以下是使用示例:
要访问压缩的彩色图像,可以使用以下命令:
```bash
ros2 topic echo /camera/color/image_raw/compressed --no-arr
```
此命令将允许您从指定话题接收压缩的彩色图像。
@@ -0,0 +1,367 @@
## 坐标系和 TF 变换
### 相机传感器结构
![module in rviz2](../image/application_guide/image3.png)
![module in rviz2](../image/application_guide/image1.png)
### 从坐标系A到坐标系B的TF变换:
在Orbbec相机中,原点(0,0,0)取自camera_link位置。
可以使用以下命令查看相机的URDF模型和坐标系结构:
```bash
ros2 launch orbbec_description view_model.launch.py model:=gemini_335_336.urdf.xacro
```
![rviz2中的模块](../image/application_guide/image2.png)
### ROS2机器人坐标系 vs 相机光学坐标系
* 视角:
* 想象我们站在相机后面,向前看。
* 在讨论坐标、左右红外、传感器位置等时,始终使用此视角。
![ROS2和相机坐标系统](../image/application_guide/image0.png)
* ROS2坐标系:(X: 向前,Y: 向左,Z: 向上)
* 相机光学坐标系:(X: 向右,Y: 向下,Z: 向前)
* 我们封装器话题中发布的所有数据都是直接从相机传感器获取的光学数据。
* 静态和动态TF话题发布光学坐标系和ROS坐标系,使用户能够在两个坐标系之间转换。
### ROS2 TF工具的使用
#### 查看TF树结构
可以使用以下ROS2命令来打印和可视化相机包发布的TF树:
**打印所有TF关系:**
```bash
ros2 run tf2_tools view_frames
```
这个命令会生成一个 `frames.pdf`文件,展示所有frame之间的层级关系。
![image-20251027111351870](../image/application_guide/image4.png)
**查看所有正在发布的TF信息:**
```bash
ros2 topic echo /tf_static
```
**查看指定两个frame之间的TF变换关系:**
使用以下命令可以查看两个特定frame之间的变换关系:
```bash
ros2 run tf2_ros tf2_echo [source_frame] [target_frame]
```
例如,查看从 `camera_link` 到 `camera_depth_optical_frame` 的变换:
```bash
ros2 run tf2_ros tf2_echo camera_link camera_depth_optical_frame
```
此命令会持续输出两个frame之间的实时变换信息,包括:
- 平移 (Translation):x、y、z 坐标(单位:米)
- 旋转 (Rotation):四元数 (x, y, z, w)
- 欧拉角 (RPY):以欧拉角形式表示的旋转
- 齐次变换矩阵 (Transform Matrix):包含旋转和平移信息的 4×4 矩阵
示例输出:
```
At time 0.0
- Translation: [0.000, 0.000, 0.000]
- Rotation: in Quaternion [-0.500, 0.500, -0.500, 0.500]
- Rotation: in RPY (radian) [-1.571, -0.000, -1.571]
- Rotation: in RPY (degree) [-90.000, -0.000, -90.000]
- Matrix:
0.000 0.000 1.000 0.000
-1.000 0.000 0.000 0.000
0.000 -1.000 0.000 0.000
0.000 0.000 0.000 1.000
```
#### 使用rviz2可视化TF树
在rviz2中可以实时可视化TF树结构和坐标系的相对位置:
```bash
rviz2
```
在rviz2中:
- 添加 `TF`显示插件
- 配置固定框架(Fixed Frame)为 `camera_link`或 `camera_depth_optical_frame`
- 选择显示的TF框架树
![image-20251027140652727](../image/application_guide/image5.png)
### 相机TF计算和发布机制
#### 核心函数:[OBCameraNode::calcAndPublishStaticTransform()](https://github.com/orbbec/OrbbecSDK_ROS2/blob/166c35b4ea211c60265ca9b38b1b15519d1ea3dd/orbbec_camera/src/ob_camera_node.cpp#L3475)
相机节点通过此函数计算和发布所有传感器之间的静态转换关系。
```cpp
void OBCameraNode::calcAndPublishStaticTransform() {
tf2::Quaternion quaternion_optical, zero_rot;
zero_rot.setRPY(0.0, 0.0, 0.0);
quaternion_optical.setRPY(-M_PI / 2, 0.0, -M_PI / 2);
tf2::Vector3 zero_trans(0, 0, 0);
auto base_stream_profile = stream_profile_[base_stream_];
auto device_info = device_->getDeviceInfo();
CHECK_NOTNULL(device_info);
auto pid = device_info->getPid();
if (!base_stream_profile) {
RCLCPP_ERROR_STREAM(logger_, "Failed to get base stream profile");
return;
}
CHECK_NOTNULL(base_stream_profile.get());
for (const auto &item : stream_profile_) {
auto stream_index = item.first;
auto stream_profile = item.second;
if (!stream_profile) {
continue;
}
OBExtrinsic ex;
try {
ex = stream_profile->getExtrinsicTo(base_stream_profile);
} catch (const ob::Error &e) {
RCLCPP_ERROR_STREAM(logger_, "Failed to get " << stream_name_[stream_index]
<< " extrinsic: " << e.getMessage());
ex = OBExtrinsic({{1, 0, 0, 0, 1, 0, 0, 0, 1}, {0, 0, 0}});
}
auto Q = rotationMatrixToQuaternion(ex.rot);
Q = quaternion_optical * Q * quaternion_optical.inverse();
tf2::Vector3 trans(ex.trans[0], ex.trans[1], ex.trans[2]);
auto timestamp = node_->now();
if (stream_index.first != base_stream_.first) {
if (stream_index.first == OB_STREAM_IR_RIGHT && base_stream_.first == OB_STREAM_DEPTH) {
trans[0] = std::abs(trans[0]); // because left and right ir calibration is error
}
publishStaticTF(timestamp, trans, Q, frame_id_[base_stream_], frame_id_[stream_index]);
}
publishStaticTF(timestamp, zero_trans, quaternion_optical, frame_id_[stream_index],
optical_frame_id_[stream_index]);
RCLCPP_INFO_STREAM(logger_, "Publishing static transform from " << stream_name_[stream_index]
<< " to "
<< stream_name_[base_stream_]);
RCLCPP_INFO_STREAM(logger_, "Translation " << trans[0] << ", " << trans[1] << ", " << trans[2]);
RCLCPP_INFO_STREAM(logger_, "Rotation " << Q.getX() << ", " << Q.getY() << ", " << Q.getZ()
<< ", " << Q.getW());
}
if ((pid == FEMTO_BOLT_PID || pid == FEMTO_MEGA_PID) && enable_stream_[DEPTH] &&
enable_stream_[COLOR] && enable_publish_extrinsic_) {
// calc depth to color
CHECK_NOTNULL(stream_profile_[COLOR]);
auto depth_to_color_extrinsics = base_stream_profile->getExtrinsicTo(stream_profile_[COLOR]);
auto Q = rotationMatrixToQuaternion(depth_to_color_extrinsics.rot);
Q = quaternion_optical * Q * quaternion_optical.inverse();
publishStaticTF(node_->now(), zero_trans, Q, camera_link_frame_id_, frame_id_[base_stream_]);
} else {
publishStaticTF(node_->now(), zero_trans, zero_rot, camera_link_frame_id_,
frame_id_[base_stream_]);
}
if (enable_stream_[DEPTH] && enable_stream_[COLOR] && enable_publish_extrinsic_) {
static const char *frame_id = "depth_to_color_extrinsics";
OBExtrinsic ex;
try {
ex = base_stream_profile->getExtrinsicTo(stream_profile_[COLOR]);
} catch (const ob::Error &e) {
RCLCPP_ERROR_STREAM(logger_,
"Failed to get " << frame_id << " extrinsic: " << e.getMessage());
ex = OBExtrinsic({{1, 0, 0, 0, 1, 0, 0, 0, 1}, {0, 0, 0}});
}
depth_to_other_extrinsics_[COLOR] = ex;
auto ex_msg = obExtrinsicsToMsg(ex, frame_id);
CHECK_NOTNULL(depth_to_other_extrinsics_publishers_[COLOR]);
depth_to_other_extrinsics_publishers_[COLOR]->publish(ex_msg);
}
if (enable_stream_[DEPTH] && enable_stream_[INFRA0] && enable_publish_extrinsic_) {
static const char *frame_id = "depth_to_ir_extrinsics";
OBExtrinsic ex;
try {
ex = base_stream_profile->getExtrinsicTo(stream_profile_[INFRA0]);
} catch (const ob::Error &e) {
RCLCPP_ERROR_STREAM(logger_,
"Failed to get " << frame_id << " extrinsic: " << e.getMessage());
ex = OBExtrinsic({{1, 0, 0, 0, 1, 0, 0, 0, 1}, {0, 0, 0}});
}
depth_to_other_extrinsics_[INFRA0] = ex;
auto ex_msg = obExtrinsicsToMsg(ex, frame_id);
CHECK_NOTNULL(depth_to_other_extrinsics_publishers_[INFRA0]);
depth_to_other_extrinsics_publishers_[INFRA0]->publish(ex_msg);
}
if (enable_stream_[DEPTH] && enable_stream_[INFRA1] && enable_publish_extrinsic_) {
static const char *frame_id = "depth_to_left_ir_extrinsics";
OBExtrinsic ex;
try {
ex = base_stream_profile->getExtrinsicTo(stream_profile_[INFRA1]);
} catch (const ob::Error &e) {
RCLCPP_ERROR_STREAM(logger_,
"Failed to get " << frame_id << " extrinsic: " << e.getMessage());
ex = OBExtrinsic({{1, 0, 0, 0, 1, 0, 0, 0, 1}, {0, 0, 0}});
}
depth_to_other_extrinsics_[INFRA1] = ex;
auto ex_msg = obExtrinsicsToMsg(ex, frame_id);
CHECK_NOTNULL(depth_to_other_extrinsics_publishers_[INFRA1]);
depth_to_other_extrinsics_publishers_[INFRA1]->publish(ex_msg);
}
if (enable_stream_[DEPTH] && enable_stream_[INFRA2] && enable_publish_extrinsic_) {
static const char *frame_id = "depth_to_right_ir_extrinsics";
OBExtrinsic ex;
try {
ex = base_stream_profile->getExtrinsicTo(stream_profile_[INFRA2]);
} catch (const ob::Error &e) {
RCLCPP_ERROR_STREAM(logger_,
"Failed to get " << frame_id << " extrinsic: " << e.getMessage());
ex = OBExtrinsic({{1, 0, 0, 0, 1, 0, 0, 0, 1}, {0, 0, 0}});
}
ex.trans[0] = -std::abs(ex.trans[0]);
depth_to_other_extrinsics_[INFRA2] = ex;
auto ex_msg = obExtrinsicsToMsg(ex, frame_id);
CHECK_NOTNULL(depth_to_other_extrinsics_publishers_[INFRA2]);
depth_to_other_extrinsics_publishers_[INFRA2]->publish(ex_msg);
}
if (enable_stream_[DEPTH] && enable_stream_[ACCEL] && enable_publish_extrinsic_) {
static const char *frame_id = "depth_to_accel_extrinsics";
OBExtrinsic ex;
try {
ex = base_stream_profile->getExtrinsicTo(stream_profile_[ACCEL]);
} catch (const ob::Error &e) {
RCLCPP_ERROR_STREAM(logger_,
"Failed to get " << frame_id << " extrinsic: " << e.getMessage());
ex = OBExtrinsic({{1, 0, 0, 0, 1, 0, 0, 0, 1}, {0, 0, 0}});
}
depth_to_other_extrinsics_[ACCEL] = ex;
auto ex_msg = obExtrinsicsToMsg(ex, frame_id);
CHECK_NOTNULL(depth_to_other_extrinsics_publishers_[ACCEL]);
depth_to_other_extrinsics_publishers_[ACCEL]->publish(ex_msg);
}
if (enable_stream_[DEPTH] && enable_stream_[GYRO] && enable_publish_extrinsic_) {
static const char *frame_id = "depth_to_gyro_extrinsics";
OBExtrinsic ex;
try {
ex = base_stream_profile->getExtrinsicTo(stream_profile_[GYRO]);
} catch (const ob::Error &e) {
RCLCPP_ERROR_STREAM(logger_,
"Failed to get " << frame_id << " extrinsic: " << e.getMessage());
ex = OBExtrinsic({{1, 0, 0, 0, 1, 0, 0, 0, 1}, {0, 0, 0}});
}
depth_to_other_extrinsics_[GYRO] = ex;
auto ex_msg = obExtrinsicsToMsg(ex, frame_id);
CHECK_NOTNULL(depth_to_other_extrinsics_publishers_[GYRO]);
depth_to_other_extrinsics_publishers_[GYRO]->publish(ex_msg);
}
if (enable_sync_output_accel_gyro_) {
tf2::Quaternion zero_rot;
zero_rot.setRPY(0.0, 0.0, 0.0);
tf2::Vector3 zero_trans(0, 0, 0);
publishStaticTF(node_->now(), zero_trans, zero_rot, optical_frame_id_[GYRO],
accel_gyro_frame_id_);
}
}
```
#### 函数解析
下面是代码的详细解释:
**四元数初始化与坐标系变换**
```cpp
tf2::Quaternion quaternion_optical, zero_rot;
zero_rot.setRPY(0.0, 0.0, 0.0);
quaternion_optical.setRPY(-M_PI / 2, 0.0, -M_PI / 2);
```
- `quaternion_optical`:定义光学坐标系到ROS标准坐标系的旋转变换(90度旋转)
- 这个旋转将相机光学坐标系(X右、Y下、Z前)转换为ROS标准坐标系(X前、Y左、Z上)
**获取设备信息与基准流**
```cpp
auto base_stream_profile = stream_profile_[base_stream_];
auto device_info = device_->getDeviceInfo();
// 通常基准流是深度流(DEPTH)
```
- 选择一个基准流(通常是深度流),所有其他传感器的变换都相对于这个基准流进行计算
**遍历所有流并计算相对变换**
```cpp
for (const auto &item : stream_profile_) {
auto stream_index = item.first;
auto stream_profile = item.second;
// 获取该流相对于基准流的外参
OBExtrinsic ex;
ex = stream_profile->getExtrinsicTo(base_stream_profile);
// 将旋转矩阵转换为四元数
auto Q = rotationMatrixToQuaternion(ex.rot);
// 应用光学坐标系变换:Q_new = quaternion_optical * Q * quaternion_optical.inverse()
Q = quaternion_optical * Q * quaternion_optical.inverse();
tf2::Vector3 trans(ex.trans[0], ex.trans[1], ex.trans[2]);
```
- `OBExtrinsic`包含了两个传感器之间的旋转矩阵(`rot`)和平移向量(`trans`)
- 通过四元数乘法将光学坐标系变换应用到每个传感器的旋转关系中
- 这个变换将相机原生的光学坐标系转换为ROS标准坐标系
**发布TF变换**
```cpp
// 发布传感器到基准流的变换(在ROS坐标系中)
publishStaticTF(timestamp, trans, Q, frame_id_[base_stream_], frame_id_[stream_index]);
// 发布传感器到其光学frame的变换
publishStaticTF(timestamp, zero_trans, quaternion_optical, frame_id_[stream_index],
optical_frame_id_[stream_index]);
```
- 第一个 `publishStaticTF`:发布从基准流到当前传感器的变换(平移+旋转)
- 第二个 `publishStaticTF`:发布从物理frame到光学frame的变换(纯旋转,无平移)
- `frame_id_[stream_index]`:物理坐标系frame名称(如 `camera_depth_frame`)
- `optical_frame_id_[stream_index]`:光学坐标系frame名称(如 `camera_depth_optical_frame`)
**特殊处理左右红外摄像头**
```cpp
if (stream_index.first == OB_STREAM_IR_RIGHT && base_stream_.first == OB_STREAM_DEPTH) {
trans[0] = std::abs(trans[0]);
}
```
- 左右红外摄像头在设备坐标系中关于中心平面对称
- 通过 `abs()`确保X轴偏移为正值,保持几何一致性
**发布深度到其他传感器的外参**
```cpp
if (enable_stream_[DEPTH] && enable_stream_[COLOR] && enable_publish_extrinsic_) {
OBExtrinsic ex = base_stream_profile->getExtrinsicTo(stream_profile_[COLOR]);
auto ex_msg = obExtrinsicsToMsg(ex, "depth_to_color_extrinsics");
depth_to_other_extrinsics_publishers_[COLOR]->publish(ex_msg);
}
```
- 通过TF发布变换关系
@@ -0,0 +1,283 @@
# 启动参数
> 如果您不确定如何设置参数,可以连接orbbec相机并打开 [OrbbecViewer](https://github.com/orbbec/OrbbecSDK/releases)。
以下是可用的启动参数:
### 核心与数据流配置
* **`camera_name`**
* 启动节点的命名空间。
* **`serial_number`**
* 相机的序列号。当使用多个相机时需要此参数。
* **`usb_port`**
* 相机的USB端口。当使用多个相机时需要此参数。
* **`device_num`**
* 设备数量。如果需要多个相机,必须填写此参数。
* **`[color|depth|left_ir|right_ir|ir]_[width|height|fps|format]`**
* 传感器流的分辨率和帧率。
* **`[color|depth|left_ir|right_ir|ir]_rotation`**
* 设置流图像旋转。
* 可能的值为 `0`、`90`、`180`、`270`。
* **`[color|depth|left_ir|right_ir|ir]_flip`**
* 启用流图像翻转。
* **`[color|depth|left_ir|right_ir|ir]_mirror`**
* 启用流图像镜像。
* **`enable_point_cloud`**
* 启用点云。
* **`enable_colored_point_cloud`**
* 启用RGB点云。
* **`cloud_frame_id`**
* 修改ros消息中的 `frame_id` 名称。
* **`ordered_pc`**
* 启用无效点云过滤。
* **`point_cloud_qos`、`[stream]_qos`、`[stream]_camera_info_qos`**
* ROS 2消息服务质量(QoS)设置。可能的值为 `SYSTEM_DEFAULT`、`DEFAULT`、`PARAMETER_EVENTS`、`SERVICES_DEFAULT`、`PARAMETERS`、`SENSOR_DATA`,不区分大小写。这些分别对应 `rmw_qos_profile_system_default`、`rmw_qos_profile_default`、`rmw_qos_profile_parameter_events`、`rmw_qos_profile_services_default`、`rmw_qos_profile_parameters` 和 `SENSOR_DATA`。
* **`color.image_raw.enable_pub_plugins`**
* 启用彩色图像传输插件。默认值:`["image_transport/compressed", "image_transport/raw", "image_transport/theora"]`。
* **`depth.image_raw.enable_pub_plugins`**
* 启用深度图像传输插件。默认值:`["image_transport/compressedDepth", "image_transport/raw"]`。
* **`left_ir.image_raw.enable_pub_plugins`**
* 启用左红外图像传输插件。默认值:`["image_transport/compressed", "image_transport/raw", "image_transport/theora"]`。
* **`right_ir.image_raw.enable_pub_plugins`**
* 启用右红外图像传输插件。默认值:`["image_transport/compressed", "image_transport/raw", "image_transport/theora"]`。
* **`point_cloud_decimation_filter_factor`**
* 点云下采样因子。范围:`1–8`,`1`表示不下采样,数值越大下采样越强。
* **`preset_resolution_config`**
* 摄像头设备的预设分辨率配置。格式: "width,height,ir_decimation_factor,depth_decimation_factor". Example: "1280,720,4,4". 仅在 Gemini435Le 设备上受支持。留空禁用。
### 传感器控制
#### 彩色流
* **`enable_color_auto_exposure`**
* 启用彩色自动曝光。
* **`enable_color_auto_exposure_priority`**
* 启用彩色自动曝光优先级。
* **`color_exposure`**
* 设置彩色曝光。
* **`color_gain`**
* 设置彩色增益。
* **`enable_color_auto_white_balance`**
* 启用彩色自动白平衡。
* **`color_white_balance`**
* 设置彩色白平衡。
* **`color_ae_max_exposure`**
* 设置彩色自动曝光的最大曝光值。
* **`color_brightness`**、**`color_sharpness`**、**`color_gamma`**、**`color_saturation`**、**`color_contrast`**、**`color_hue`**
* 设置彩色亮度、锐度、伽马、饱和度、对比度和色调。
* **`color_backlight_compensation`**
* 启用彩色相机的背光补偿功能。**范围**:`0–6`,**默认值**:`3`。
* **`color_powerline_freq`**
* 设置电源线频率。可能的值为 `disable`、`50hz`、`60hz`、`auto`。
* **`enable_color_decimation_filter`** / **`color_decimation_filter_scale`**
* 启用彩色抽取滤波器并设置其比例。
* **`color_ae_roi_[left|right|top|bottom]`**
* 设置彩色自动曝光ROI。
* **`color_denoising_level`**
* 启用Gemini 330系列设备的ISP降噪功能。**范围:** `0–8`,**默认值:** `0`(自动)。
#### 深度流
* **`enable_depth_auto_exposure_priority`**
* 启用深度自动曝光优先级。
* **`mean_intensity_set_point`**
* 设置深度图像的目标平均强度。例如:`mean_intensity_set_point:=100`。
> **注意:** 这取代了已弃用的 `depth_brightness`,后者仍支持以保持向后兼容性。
* **`enable_depth_scale`**
* 启用深度缩放。
* **`depth_precision`**
* 深度精度应为 `1mm` 格式。默认值为 `1mm`。
* **`depth_ae_roi_[left|right|top|bottom]`**
* 设置深度自动曝光ROI。
#### 红外流
* **`enable_ir_auto_exposure`**
* 启用红外自动曝光。
* **`ir_exposure`** / **`ir_gain`**
* 设置红外曝光和增益。
* **`ir_ae_max_exposure`**
* 设置红外自动曝光的最大曝光值。
* **`ir_brightness`**
* 设置红外亮度。
#### 激光 / LDP
* **`enable_laser`**
* 启用激光。默认值为 `true`。
* **`laser_energy_level`**
* 设置激光能量级别。
* **`enable_ldp`** / **`ldp_power_level`**
* 启用LDP并设置其功率级别。
### 设备、同步与高级功能
#### 多相机同步
* **`sync_mode`**
* 设置同步模式。默认值为 `standalone`。
* **`depth_delay_us`** / **`color_delay_us`**
* 接收捕获命令或触发信号后深度/彩色图像捕获的延迟时间(微秒)。
* **`trigger2image_delay_us`**
* 接收捕获命令或触发信号后图像捕获的延迟时间(微秒)。
* **`trigger_out_delay_us`**
* 接收捕获命令或触发信号后触发信号输出的延迟时间(微秒)。
* **`trigger_out_enabled`**
* 启用触发输出信号。
* **`software_trigger_enabled`** / **`software_trigger_period`**
* 启用软件触发输出信号 / 设置软件触发周期(毫秒)。
* **`frames_per_trigger`**
* 触发模式下每次触发后每个流的帧数。
> 用于 [多相机同步](../5_advanced_guide/multi_camera/multi_camera_synced.md)。
#### 网络相机
* **`enumerate_net_device`**
* 启用自动枚举网络设备。
* **`net_device_ip`** / **`net_device_port`**
* 设置网络设备的IP地址和端口(通常为 `8090`)。
* **`force_ip_enable`**
* 启用强制IP功能。**默认值:** `false`
* **`force_ip_mac`**
* 连接多个相机时的目标设备MAC地址(例如,`"54:14:FD:06:07:DA"`)。您可以使用 `list_devices_node` 查找每个设备的MAC。**默认值:** `""`
* **`force_ip_address`**
* 要分配的静态IP地址。**默认值:** `192.168.1.10`
* **`force_ip_subnet_mask`**
* 静态IP的子网掩码。**默认值:** `255.255.255.0`
* **`force_ip_gateway`**
* 静态IP的网关地址。**默认值:** `192.168.1.1`
> 用于 [网络相机](../5_advanced_guide/configuration/net_camera.md)。
#### 设备特定
* **`device_preset`**
* 默认值为 `Default`。仅支持G330系列。有关更多信息,请参阅 [G330文档](https://www.orbbec.com/docs/g330-use-depth-presets/)。该值应为 [表中列出](../5_advanced_guide/configuration/predefined_presets.md) 的预设名称之一。
* **`enable_gmsl_trigger`** / **`gmsl_trigger_fps`**
* 启用gmsl触发输出信号 / 设置gmsl触发fps。用于 [gmsl相机](../5_advanced_guide/multi_camera/gmsl_camera.md)。
#### 视差
* **`disparity_to_depth_mode`**
* `HW`:使用硬件视差到深度转换。`SW`:使用软件视差到深度转换。
* **`disparity_range_mode`**、**`disparity_search_offset`**、**`disparity_offset_config`**
* 视差搜索偏移参数。用于 [视差搜索偏移](../5_advanced_guide/configuration/disparity_search_offset.md)。
#### 交错AE模式
* **`interleave_ae_mode`**
* 设置 `laser` 或 `hdr` 交错。
* **`interleave_frame_enable`**、**`interleave_skip_enable`**、**`interleave_skip_index`**
* 控制交错帧模式的参数。
* **`[hdr|laser]_index[0|1]_[...]`**
* 在交错帧模式下,设置hdr或laser交错帧的第0和第1帧参数。
* *所有交错参数用于 [交错ae模式](../5_advanced_guide/configuration/interleave_ae_mode.md)。*
#### 相机内同步
- **`depth_registration`**
* 启用深度帧与彩色帧的对齐。当 `enable_colored_point_cloud` 设置为 `true` 时需要此字段。
- **`align_mode`**
* 要使用的对齐模式。选项为 `HW`(硬件对齐)和 `SW`(软件对齐)。
- **`align_target_stream`**
* 设置对齐目标流模式。
* 可能的值为 `COLOR`、`DEPTH`。
* `COLOR`:将深度对齐到彩色。
* `DEPTH`:将彩色对齐到深度。
- **`intra_camera_sync_reference`**
- 设置相机内同步的参考点。适用于Gemini 330系列设备,当 `sync_mode` 设置为**软件**或**硬件触发**模式时。**选项:** `Start`、`Middle`、`End`。设置为空时,长基线设备默认End,短基线设备默认Middle。
### 基础与通用参数
#### 固件与后端
* **`upgrade_firmware`**
* 输入参数为固件路径。
* **`preset_firmware_path`**
* 输入参数为预设固件路径。如果输入多个路径,每个路径需要用 `,` 分隔,最多可输入3个固件路径。
* **`uvc_backend`**
* 可选值:`v4l2`、`libuvc`。
* **`connection_delay`**
* 重新打开设备的延迟时间(毫秒)。某些设备(如Astra mini)需要较长时间初始化,热插拔时立即重新打开设备可能导致固件崩溃。
* **`retry_on_usb3_detection_failure`**
* 如果相机连接到USB 2.0端口且未检测到,系统将尝试重置相机最多三次。使用USB 2.0连接时建议将此参数设置为 `false`,以避免不必要的重置。
#### TF、外参与校准
* **`publish_tf`** / **`tf_publish_rate`**
* 启用TF发布并设置其发布速率。
* **`enable_publish_extrinsic`**
* 启用外参发布。
* **`ir_info_url`** / **`color_info_url`**
* 设置IR/彩色相机信息的URL。
* **`enable_color_undistortion`**
* 启用彩色去畸变。
#### 时间同步
* **`enable_sync_host_time`**
* 启用主机时间与相机时间的同步。默认值为 `true`。如果使用全局时间,设置为 `false`。
* **`time_domain`**
* 选择时间戳类型:`device`、`global` 和 `system`。
* **`time_sync_period`**
* 相机时间与主机系统同步的间隔(秒)。
> **注意**:仅当 **`enable_sync_host_time = true`** 且 **`time_domain = device`** 时需要设置此参数。
* **`enable_ptp_config`**
* 启用PTP时间同步。仅适用于Gemini 335Le。需要 `enable_sync_host_time` 设置为 `false`。
* **`enable_frame_sync`**
* 启用帧同步。
#### 日志与诊断
* **`log_level`**
* SDK日志级别。默认为 `info`。可选值:`debug`、`info`、`warn`、`error`、`fatal`。
* **`log_file_name`**
* 保存的SDK日志文件名。当`log_level`为`debug`时生效。
* **`diagnostic_period`**
* 诊断周期(秒)。
* **`enable_heartbeat`**
* 启用心跳功能。默认为 `false`。如果为 `true`,相机节点将向固件发送心跳信号。
#### 其他
* **`config_file_path`**
* YAML配置文件的路径。默认为 `""`。如果未指定,将使用启动文件中的默认参数。
* **`frame_aggregate_mode`**
* 设置帧聚合输出模式。可选值:`full_frame`、`color_frame`、`ANY`、`disable`。
* **`enable_d2c_viewer`**
* 发布D2C叠加图像(仅用于测试)。
### IMU
* **`enable_accel`** / **`enable_gyro`**
* 启用加速度计/陀螺仪并输出其信息话题数据。
* **`enable_sync_output_accel_gyro`**
* 启用同步 `accel_gyro`,并输出IMU话题实时数据。
* **`accel_rate`** / **`gyro_rate`**
* 加速度计/陀螺仪的频率。值范围从 `1.5625hz` 到 `32khz`。
* **`accel_range`** / **`gyro_range`**
* 加速度计(`2g`、`4g`、`8g`、`16g`)和陀螺仪(`16dps` 到 `2000dps`)的范围。
* **`enable_accel_data_correction`** / **`enable_gyro_data_correction`**
* 启用加速度计/陀螺仪的数据校正。
* **`linear_accel_cov`** / **`angular_vel_cov`**
* 线性加速度和角速度的协方差。
### 深度滤波器
* **`enable_decimation_filter`**
* 启用深度抽取滤波器。使用 `decimation_filter_scale` 设置。
* **`enable_hdr_merge`**
* 启用深度hdr合并滤波器。使用 `hdr_merge_exposure_1` 等设置。
* **`enable_sequence_id_filter`**
* 启用深度序列id滤波器。使用 `sequence_id_filter_id` 设置。
* **`enable_threshold_filter`**
* 启用深度阈值滤波器。使用 `threshold_filter_max`、`threshold_filter_min` 设置。
* **`enable_hardware_noise_removal_filter`**
* 启用深度硬件降噪滤波器。
* **`enable_noise_removal_filter`**
* 启用深度软件降噪滤波器。使用 `noise_removal_filter_min_diff` 等设置。
* **`enable_spatial_filter`**
* 启用深度空间滤波器。使用 `spatial_filter_alpha` 等设置。
* **`enable_temporal_filter`**
* 启用深度时间滤波器。使用 `temporal_filter_diff_threshold` 等设置。
* **`enable_hole_filling_filter`**
* 启用深度孔洞填充滤波器。使用 `hole_filling_filter_mode` 设置。
* **`enable_spatial_fast_filter`**
* 启用深度空间快速滤波器。使用 `spatial_fast_filter_radius` 设置。
* **`enable_spatial_moderate_filter`**
* 启用深度空间中等滤波器。使用 `spatial_moderate_filter_diff_threshold` 等设置。
---
> **_重要_**:请仔细阅读 [此链接](https://www.orbbec.com/docs/g330-use-depth-post-processing-blocks/) 中有关软件滤波设置的说明。如果不确定,请勿修改这些设置。
@@ -0,0 +1,53 @@
## 在ROS 2中启用和可视化点云
本节演示如何从相机节点启用点云数据输出并使用RViz2进行可视化。
### 启用深度点云
#### 启用深度点云的命令
要激活深度信息的点云数据流,使用以下命令:
```bash
ros2 launch orbbec_camera gemini_330_series.launch.py enable_point_cloud:=true
```
#### 在RViz2中可视化深度点云
运行上述命令后,执行以下步骤可视化深度点云:
1. 打开RViz2。
2. 添加 `PointCloud2` 显示。
3. 选择 `/camera/depth/points` 话题进行可视化。
4. 将固定帧设置为 `camera_link` 以正确对齐数据。
- **可视化示例**
深度点云在RViz2中可能如下所示:
![深度点云可视化](../image/point_cloud/image5.jpg)
### 启用彩色点云
#### 启用彩色点云的命令
要启用彩色点云功能,输入以下命令:
```bash
ros2 launch orbbec_camera gemini_330_series.launch.py enable_colored_point_cloud:=true
```
#### 在RViz2中可视化彩色点云
要可视化彩色点云数据:
1. 执行命令后启动RViz2。
2. 添加 `PointCloud2` 显示面板。
3. 从列表中选择 `/camera/depth_registered/points` 话题。
4. 确保固定帧设置为 `camera_link`。
- **可视化示例**
RViz2中彩色点云的结果应该如下所示:
![彩色点云可视化](../image/point_cloud/image6.jpg)
@@ -0,0 +1,268 @@
# 所有可用的相机控制服务
> **注意:** 与特定数据流相关的服务(例如 `/camera/set_color_*`)仅在启动文件中启用该数据流时可用(例如 `enable_color:=true`)。
### 数据流控制
#### 彩色流
* `/camera/toggle_color`
```bash
ros2 service call /camera/toggle_color std_srvs/srv/SetBool '{data: true}'
```
* `/camera/get_color_exposure` & `/camera/get_color_gain`
```bash
ros2 service call /camera/get_color_exposure orbbec_camera_msgs/srv/GetInt32 '{}'
ros2 service call /camera/get_color_gain orbbec_camera_msgs/srv/GetInt32 '{}'
```
* `/camera/set_color_auto_exposure`
```bash
ros2 service call /camera/set_color_auto_exposure std_srvs/srv/SetBool '{data: true}'
```
* `/camera/set_color_exposure` & `/camera/set_color_gain`
```bash
ros2 service call /camera/set_color_exposure orbbec_camera_msgs/srv/SetInt32 '{data: 1}'
ros2 service call /camera/set_color_gain orbbec_camera_msgs/srv/SetInt32 '{data: 64}'
```
* `/camera/set_color_mirror`, `/camera/set_color_flip`, `/camera/set_color_rotation`
```bash
ros2 service call /camera/set_color_mirror std_srvs/srv/SetBool '{data: true}'
ros2 service call /camera/set_color_flip std_srvs/srv/SetBool '{data: true}'
ros2 service call /camera/set_color_rotation orbbec_camera_msgs/srv/SetInt32 '{data: 180}'
```
* `/camera/set_color_ae_roi`
```bash
# data_param: [左, 右, 上, 下]
ros2 service call /camera/set_color_ae_roi orbbec_camera_msgs/srv/SetArrays '{data_param: [0,1279,0,719]}'
```
#### 深度流
* `/camera/toggle_depth`
```bash
ros2 service call /camera/toggle_depth std_srvs/srv/SetBool '{data: true}'
```
* `/camera/get_depth_exposure` & `/camera/get_depth_gain`
```bash
ros2 service call /camera/get_depth_exposure orbbec_camera_msgs/srv/GetInt32 '{}'
ros2 service call /camera/get_depth_gain orbbec_camera_msgs/srv/GetInt32 '{}'
```
* `/camera/set_depth_auto_exposure`
```bash
ros2 service call /camera/set_depth_auto_exposure std_srvs/srv/SetBool '{data: true}'
```
* `/camera/set_depth_exposure` & `/camera/set_depth_gain`
```bash
ros2 service call /camera/set_depth_exposure orbbec_camera_msgs/srv/SetInt32 '{data: 3000}'
ros2 service call /camera/set_depth_gain orbbec_camera_msgs/srv/SetInt32 '{data: 64}'
```
* `/camera/set_depth_mirror`, `/camera/set_depth_flip`, `/camera/set_depth_rotation`
```bash
ros2 service call /camera/set_depth_mirror std_srvs/srv/SetBool '{data: true}'
ros2 service call /camera/set_depth_flip std_srvs/srv/SetBool '{data: true}'
ros2 service call /camera/set_depth_rotation orbbec_camera_msgs/srv/SetInt32 '{data: 180}'
```
* `/camera/set_depth_ae_roi`
```bash
# data_param: [左, 右, 上, 下]
ros2 service call /camera/set_depth_ae_roi orbbec_camera_msgs/srv/SetArrays '{data_param: [0,847,0,479]}'
```
#### 红外流
* `/camera/toggle_ir`
```bash
ros2 service call /camera/toggle_ir std_srvs/srv/SetBool '{data: true}'
```
* `/camera/get_ir_exposure` & `/camera/get_ir_gain`
```bash
ros2 service call /camera/get_ir_exposure orbbec_camera_msgs/srv/GetInt32 '{}'
ros2 service call /camera/get_ir_gain orbbec_camera_msgs/srv/GetInt32 '{}'
```
* `/camera/set_ir_long_exposure`
```bash
ros2 service call /camera/set_ir_long_exposure std_srvs/srv/SetBool '{data: true}'
```
* `/camera/set_ir_auto_exposure`
```bash
ros2 service call /camera/set_ir_auto_exposure std_srvs/srv/SetBool '{data: true}'
```
* `/camera/set_ir_exposure` & `/camera/set_ir_gain`
```bash
ros2 service call /camera/set_ir_exposure orbbec_camera_msgs/srv/SetInt32 '{data: 3000}'
ros2 service call /camera/set_ir_gain orbbec_camera_msgs/srv/SetInt32 '{data: 64}'
```
* `/camera/set_ir_mirror`, `/camera/set_ir_flip`, `/camera/set_ir_rotation`
```bash
ros2 service call /camera/set_ir_mirror std_srvs/srv/SetBool '{data: true}'
ros2 service call /camera/set_ir_flip std_srvs/srv/SetBool '{data: true}'
ros2 service call /camera/set_ir_rotation orbbec_camera_msgs/srv/SetInt32 '{data: 180}'
```
* `/camera/switch_ir`
```bash
ros2 service call /camera/switch_ir orbbec_camera_msgs/srv/SetString '{data: left}'
```
#### 所有数据流
* `/camera/get_streams_enable` & `/camera/set_streams_enable`
```bash
ros2 service call /camera/get_streams_enable orbbec_camera_msgs/srv/GetBool '{}'
ros2 service call /camera/set_streams_enable std_srvs/srv/SetBool '{data: false}'
```
### 传感器与发射器控制
* `/camera/set_auto_white_balance` & `/camera/get_auto_white_balance`
```bash
ros2 service call /camera/set_auto_white_balance std_srvs/srv/SetBool '{data: true}'
ros2 service call /camera/get_auto_white_balance orbbec_camera_msgs/srv/GetInt32 '{}'
```
* `/camera/set_white_balance` & `/camera/get_white_balance`
```bash
ros2 service call /camera/set_white_balance orbbec_camera_msgs/srv/SetInt32 '{data: 2800}'
ros2 service call /camera/get_white_balance orbbec_camera_msgs/srv/GetInt32 '{}'
```
* `/camera/set_laser_enable`
```bash
ros2 service call /camera/set_laser_enable std_srvs/srv/SetBool '{data: true}'
```
`/camera/get_laser_status`
```bash
ros2 service call /camera/get_laser_status orbbec_camera_msgs/srv/GetBool '{}'
```
* `/camera/set_ldp_enable` & `/camera/get_ldp_status`
```bash
ros2 service call /camera/set_ldp_enable std_srvs/srv/SetBool '{data: true}'
ros2 service call /camera/get_ldp_status orbbec_camera_msgs/srv/GetBool '{}'
```
* `/camera/set_ptp_config` & `/camera/get_ptp_config`
```bash
ros2 service call /camera/set_ptp_config std_srvs/srv/SetBool '{data: true}'
ros2 service call /camera/get_ptp_config orbbec_camera_msgs/srv/GetBool '{}'
```
* `/camera/get_lrm_measure_distance`
```bash
ros2 service call /camera/get_lrm_measure_distance orbbec_camera_msgs/srv/GetInt32 '{}'
```
* `/camera/set_fan_work_mode`
```bash
ros2 service call /camera/set_fan_work_mode orbbec_camera_msgs/srv/SetInt32 '{data: 0}'
```
* `/camera/set_floor_enable`
```bash
ros2 service call /camera/set_floor_enable std_srvs/srv/SetBool '{data: true}'
```
### 设备信息与管理
* `/camera/get_device_info`
```bash
ros2 service call /camera/get_device_info orbbec_camera_msgs/srv/GetDeviceInfo
```
* `/camera/get_sdk_version`
```bash
ros2 service call /camera/get_sdk_version orbbec_camera_msgs/srv/GetString
```
* `/camera/reboot_device`
```bash
ros2 service call /camera/reboot_device std_srvs/srv/Empty '{}'
```
### 同步与触发
* `/camera/send_software_trigger`
```bash
ros2 service call /camera/send_software_trigger std_srvs/srv/SetBool '{data: true}'
```
* `/camera/set_sync_hosttime`
```bash
ros2 service call /camera/set_sync_hosttime std_srvs/srv/SetBool '{data: true}'
```
* `/camera/set_reset_timestamp`
```bash
# 仅在time_domain参数设置为device时可用
ros2 service call /camera/set_reset_timestamp std_srvs/srv/SetBool '{data: true}'
```
* `/camera/set_sync_interleaverlaser`
```bash
# 仅在interleave_ae_mode为'laser'且interleave_frame_enable为true时可用
ros2 service call /camera/set_sync_interleaverlaser orbbec_camera_msgs/srv/SetInt32 '{data: 0}'
```
### 深度滤波器配置
* `/camera/set_filter`
```bash
# 设置DecimationFilter
ros2 service call /camera/set_filter orbbec_camera_msgs/srv/SetFilter '{filter_name: DecimationFilter, filter_enable: false, filter_param: [5]}'
# 设置SpatialAdvancedFilter
ros2 service call /camera/set_filter orbbec_camera_msgs/srv/SetFilter '{filter_name: SpatialAdvancedFilter, filter_enable: true, filter_param: [0.5,160,1,8]}'
# 设置SequenceIdFilter
ros2 service call /camera/set_filter orbbec_camera_msgs/srv/SetFilter '{filter_name: SequenceIdFilter, filter_enable: true, filter_param: [1]}'
# 设置ThresholdFilter
ros2 service call /camera/set_filter orbbec_camera_msgs/srv/SetFilter '{filter_name: ThresholdFilter, filter_enable: true, filter_param: [0,15999]}'
# 设置NoiseRemovalFilter
ros2 service call /camera/set_filter orbbec_camera_msgs/srv/SetFilter '{filter_name: NoiseRemovalFilter, filter_enable: true, filter_param: [256,80]}'
# 设置HardwareNoiseRemoval
ros2 service call /camera/set_filter orbbec_camera_msgs/srv/SetFilter '{filter_name: HardwareNoiseRemoval, filter_enable: true, filter_param: []}'
# 设置SpatialFastFilter
# filter_param: [radius]
ros2 service call /camera/set_filter orbbec_camera_msgs/srv/SetFilter '{filter_name: SpatialFastFilter, filter_enable: true, filter_param: [4]}'
# 设置SpatialModerateFilter
# filter_param: [disp_diff, magnitude, radius]
ros2 service call /camera/set_filter orbbec_camera_msgs/srv/SetFilter '{filter_name: SpatialModerateFilter, filter_enable: true, filter_param: [160,1,3]}'
```
### 数据捕获与校准管理
* `/camera/save_images`
```bash
ros2 service call /camera/save_images std_srvs/srv/Empty '{}'
```
* `/camera/save_point_cloud`
```bash
ros2 service call /camera/save_point_cloud std_srvs/srv/Empty '{}'
```
> **注意**:以下服务目前仅支持435Le模块。每个服务一次只能存储一组数据或字符串。
* `/camera/write_customer_data` & `/camera/read_customer_data`
```bash
ros2 service call /camera/write_customer_data orbbec_camera_msgs/srv/SetString '{data: "string"}'
ros2 service call /camera/read_customer_data orbbec_camera_msgs/srv/GetString '{}'
```
* `/camera/set_user_calib_params` & `/camera/get_user_calib_params`
```bash
ros2 service call /camera/set_user_calib_params orbbec_camera_msgs/srv/SetUserCalibParams \
'{k: [614.9613647460938, 0.0, 634.91552734375,
0.0, 614.65771484375, 391.407470703125,
0.0, 0.0, 1.0],
d: [-0.03131488710641861,
0.032955970615148544,
9.096559369936585e-05,
-0.0003368517500348389,
-0.01115430984646082,
0.0, 0.0, 0.0],
rotation: [0.9999880790710449, 0.0003024190664291382, -0.004874417092651129,
-0.0002965621242765337, 0.9999992251396179, 0.001202247804030776,
0.004874777048826218, -0.0012007878394797444, 0.9999874234199524],
translation: [-0.023897956848144532,
-9.439220279455185e-05,
-6.804073229432106e-06]}'
ros2 service call /camera/get_user_calib_params orbbec_camera_msgs/srv/GetUserCalibParams '{}'
```
### 点云下采样
* `/camera/set_point_cloud_decimation`
```bash
ros2 service call /camera/set_point_cloud_decimation orbbec_camera_msgs/srv/SetInt32 '{data: 8}'
```
* `/camera/get_point_cloud_decimation`
```bash
ros2 service call /camera/get_point_cloud_decimation orbbec_camera_msgs/srv/GetInt32 '{}'
```
@@ -0,0 +1,67 @@
# 可用话题
话题按数据流和功能组织。默认情况下,所有话题都发布在 `/camera` 命名空间下,可以通过 `camera_name` 启动参数进行更改。
> **注意:** 特定数据流的话题(例如 `/camera/color/...`)只有在相应的启动参数(例如 `enable_color`)设置为 `true` 时才会发布。
### 图像流
这些话题提供每个启用的相机数据流的原始图像数据和相应的校准信息。对于 `color`、`depth`、`ir`、`left_ir` 和 `right_ir` 数据流,模式是一致的。
* `/camera/color/image_raw`
* 彩色流的原始图像数据。
* `/camera/color/camera_info`
* 彩色流的相机校准数据和元数据。
* `/camera/color/metadata`
* 来自彩色流固件的底层元数据。
* `/camera/depth/image_raw`
* 深度流的原始图像数据。
* `/camera/depth/camera_info`
* 深度流的相机校准数据和元数据。
* `/camera/depth/metadata`
* 来自深度流固件的底层元数据。
* `/camera/ir/image_raw`
* 红外(IR)流的原始图像数据。
* `/camera/ir/camera_info`
* IR流的相机校准数据和元数据。
* `/camera/ir/metadata`
* 来自IR流固件的底层元数据。
### 点云话题
* `/camera/depth/points`
* 从深度流生成的点云数据。
* **条件:** 仅在 `enable_point_cloud` 为 `true` 时发布。
* `/camera/depth_registered/points`
* 彩色点云数据,其中深度点配准到彩色图像帧。
* **条件:** 仅在 `enable_colored_point_cloud` 为 `true` 时发布。
### IMU话题
惯性测量单元(IMU)话题提供加速度计和陀螺仪数据。其行为取决于同步设置。
* `/camera/accel/sample`
* 单独的加速度计数据流。
* **条件:** 在 `enable_accel` 为 `true` 且 `enable_sync_output_accel_gyro` 为 `false` 时发布。
* `/camera/gyro/sample`
* 单独的陀螺仪数据流。
* **条件:** 在 `enable_gyro` 为 `true` 且 `enable_sync_output_accel_gyro` 为 `false` 时发布。
* `/camera/gyro_accel/sample`
* 包含加速度计和陀螺仪数据的同步数据流(单条消息)。
* **条件:** 在 `enable_sync_output_accel_gyro` 为 `true` 时发布。
### 设备状态与诊断
* `/camera/device_status`
* 报告相机设备的当前状态。
* `/camera/depth_filter_status`
* 报告深度传感器后处理滤波器的状态。
* `/diagnostics`
* 发布相机节点的诊断信息。目前包括设备温度。
@@ -0,0 +1,44 @@
高级指南
======================================================
本章介绍SDK的高级功能,包括多相机使用和特殊配置模式。
性能与优化
------------------------------------------------------
.. toctree::
:maxdepth: 2
performance/lower_cpu_usage.md
performance/efficient_intra_process_communication.md
performance/fastdds_tuning.md
多相机
------------------------------------------------------
.. toctree::
:maxdepth: 2
multi_camera/multi_camera.md
multi_camera/multi_camera_synced.md
multi_camera/multi_camera_synced_verification_tool.md
multi_camera/gmsl_camera.md
配置与模式
------------------------------------------------------
.. toctree::
:maxdepth: 2
configuration/align_depth_color.md
configuration/configuration_of_depth_NFOV_and_WFOV_modes.md
configuration/depth_work_mode_switch.md
configuration/disparity_search_offset.md
configuration/interleave_ae_mode.md
configuration/predefined_presets.md
configuration/net_camera.md
@@ -0,0 +1,40 @@
## 在 ROS 2 中对齐深度到彩色
本节说明如何使用 ROS 2 将深度图像与彩色图像对齐以创建叠加图像。这对于需要来自不同传感器模态的同步视觉信息的应用特别有用。
### 对齐和查看深度和彩色图像的命令
1. **基本深度到彩色对齐:**
要简单地将深度图像对齐到彩色图像,请使用以下命令:
```bash
ros2 launch orbbec_camera gemini_330_series.launch.py depth_registration:=true
```
此命令激活深度配准功能,但不打开查看器。
2. **查看深度到彩色叠加:**
如果您希望查看深度到彩色叠加,需要使用以下命令启用查看器:
```bash
ros2 launch orbbec_camera gemini_330_series.launch.py depth_registration:=true enable_d2c_viewer:=true
```
这将启动带有深度到彩色配准的相机节点并打开查看器以显示叠加图像。
### 在 RViz2 中选择话题
要在 RViz2 中可视化对齐的图像:
1. 运行上述命令之一后启动 RViz2。
2. 选择深度到彩色叠加图像的话题。话题选择示例如下所示:
![深度到彩色叠加的话题选择](../../image/align_depth_color/image3.png)
### 深度到彩色叠加示例
在 RViz2 中选择适当的话题后,您将能够看到深度到彩色叠加图像。它可能看起来像这样:
![深度到彩色叠加图像](../../image/align_depth_color/image4.jpg)
@@ -0,0 +1,12 @@
# 深度 NFOV 和 WFOV 模式配置
对于 Femto Mega 和 Femto Bolt 设备,NFOV 和 WFOV 模式通过在启动文件中配置深度和 IR 的分辨率来实现。
在启动文件中,depth_width、depth_height、ir_width、ir_height 分别表示深度的分辨率和 IR 的分辨率。
IR 的帧率和分辨率必须与深度保持一致。不同模式与分辨率的对应关系如下:
- NFOV unbinned:640 x 576
- NFOV binned:320 x 288
- WFOV unbinned:1024 x 1024
- WFOV binned:512 x 512
@@ -0,0 +1,29 @@
# 深度工作模式切换
Orbbec SDK ROS 2 支持深度工作模式切换。Gemini 2、Gemini 2 L 和 Femto 以及 Femto Bolt 相机支持深度工作模式切换。
- 在启动相机之前,可以为相应的 xxx.launch.py 文件的支持配置深度工作模式(depth_work_mode)。
- Gemini 2、Gemini 2 L 和 Gemini 2 XL 相机支持深度工作模式切换。
- xxx.launch.py 的默认深度工作模式配置是相机的默认配置。如果需要修改,可以根据需要切换到相应的模式。
- 具体相机深度工作模式支持类型可以在深度模式的注释中找到。
```python
# 深度工作模式支持如下:
# Unbinned Dense Default
# Unbinned Sparse Default
# Binned Sparse Default
# Obstacle Avoidance
DeclareLaunchArgument('depth_work_mode', default_value='')
```
- 查看深度工作模式:
```bash
ros2 run orbbec_camera list_depth_work_mode_node
```
* 示例:
```bash
ros2 launch orbbec_camera gemini2L.launch.py depth_work_mode:="Unbinned Dense Default"
```
@@ -0,0 +1,47 @@
# 视差搜索偏移
> 本节介绍如何在 Gemini330 系列相机中使用 disparity_search_offset 功能(相机固件最低版本 [1.4.60](https://www.orbbec.com/docs/g330-firmware-release/))。Disparity_search_offset 仅对深度流的 1280×720、1280×800 和 640×400 分辨率有效。
## 功能介绍
视差搜索范围的定义:对于左图像中的任何像素 *(u_l, v)*,默认情况下,右图像中对应的视差搜索范围为 *[ (u_l - 255, v)*, *(u_l, v) ]*,其中视差搜索长度为 256,最大整数视差为 255。如果将搜索的起点调整为 *[ (u_l - 255 - offset, v)*, *(u_l - offset, v) ]*,则偏移量定义为视差偏移。因此,我们的视差搜索范围配置包括视差搜索长度和搜索位置偏移(也可称为视差偏移)。
![深度点云可视化](../../image/disparity_search_offset/search_offset0.png)
## 参数介绍
disparity_search_offset 相关参数在 [gemini_330_series.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/launch/gemini_330_series.launch.py) 中设置
* `disparity_range_mode`:视差搜索长度,只能设置为 64、128 和 256。
* `disparity_search_offset`:视差搜索偏移值,可以设置为 0 到 127。
* `disparity_offset_config`:视差搜索偏移交错帧。
* `offset_index0`:帧 0 视差搜索偏移值。
* `offset_index1`:帧 1 视差搜索偏移值。
| 视差范围模式 | 视差搜索偏移 | 倾斜墙最小深度 (mm) |
| :------------------: | :---------------------: | :---------------------------------: |
| 64 | 85 | Gemini 335L 388-406 |
| 64 | 127 | Gemini 335L 302-317 |
| 视差范围模式 | 视差搜索偏移 | 倾斜墙最小深度 (mm) |
| :------------------: | :---------------------: | :---------------------------------------------: |
| 128 | 0 | Gemini 335 233-249<br />Gemini 335L 453-475 |
| 128 | 45 | Gemini 335 172-184<br />Gemini 335L 334-349 |
| 128 | 127 | Gemini 335 117-125<br />Gemini 335L 226-236 |
| 视差范围模式 | 视差搜索偏移 | 倾斜墙最小深度 (mm) |
| :------------------: | :---------------------: | :---------------------------------: |
| 256 | 85 | Gemini 335L 169-178 |
| 256 | 127 | Gemini 335L 151-158 |
## 运行启动文件
设置 disparity_search_offset 参数,重新 `colcon build` 并运行启动文件
```bash
ros2 launch orbbec_camera gemini_330_series.launch.py
```
@@ -0,0 +1,81 @@
# 在 Gemini330 系列相机中使用 interleave_ae
> 本节介绍如何在 Gemini 330 系列相机中使用 interleave_ae(相机固件最低版本 [1.4.00](https://www.orbbec.com/docs/g330-firmware-release/))
## 参数介绍
interleave_ae 相关参数在 [gemini_330_series.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/launch/gemini_330_series.launch.py) 中设置
* `interleave_ae_mode`:设置激光或 hdr 交错。
* `interleave_frame_enable`:启用交错帧模式。
* `interleave_skip_enable`:启用跳帧模式。
* `interleave_skip_index`:设置为 0 跳过图案 ir,设置为 1 跳过泛光 ir。
**interleave hdr**
当 `interleave_ae_mode` 参数设置为 `hdr` 且 `interleave_frame_enable` 设置为 `true` 时,将启用 interleave hdr
* `hdr_index1_laser_control`:帧 1 激光开关设置。
* `hdr_index1_depth_exposure`:帧 1 深度曝光值设置,非 AE 模式。
* `hdr_index1_depth_gain`:帧 1 深度增益值设置,非 AE 模式。
* `hdr_index1_ir_brightness`:帧 1 ir 增益值设置。
* `hdr_index1_ir_ae_max_exposure`:AE(自动曝光)中帧 1 ir 最大曝光值设置。
* `hdr_index0_laser_control`:帧 0 激光开关设置。
* `hdr_index0_depth_exposure`:帧 0 深度曝光值设置,非 AE 模式。
* `hdr_index0_depth_gain`:帧 0 深度增益值设置,非 AE 模式。
* `hdr_index0_ir_brightness`:帧 0 ir 增益值设置。
* `hdr_index0_ir_ae_max_exposure`:AE(自动曝光)中帧 0 ir 最大曝光值设置。
**interleave laser**
当 `interleave_ae_mode` 参数设置为 `laser` 且 `interleave_frame_enable` 设置为 `true` 时,将启用 interleave laser
* `laser_index1_laser_control`:帧 1 激光开关设置。
* `laser_index1_depth_exposure`:帧 1 深度曝光值设置,非 AE 模式。
* `laser_index1_depth_gain`:帧 1 深度增益值设置,非 AE 模式。
* `laser_index1_ir_brightness`:帧 1 ir 增益值设置。
* `laser_index1_ir_ae_max_exposure`:AE(自动曝光)中帧 1 ir 最大曝光值设置。
* `laser_index0_laser_control`:帧 0 激光开关设置。
* `laser_index0_depth_exposure`:帧 0 深度曝光值设置,非 AE 模式。
* `laser_index0_depth_gain`:帧 0 深度增益值设置,非 AE 模式。
* `laser_index0_ir_brightness`:帧 0 ir 增益值设置。
* `laser_index0_ir_ae_max_exposure`:AE(自动曝光)中帧 0 ir 最大曝光值设置。
## 运行启动文件
设置 interleave_ae 参数,重新 `colcon build` 并运行启动文件
```bash
ros2 launch orbbec_camera gemini_330_series.launch.py
```
**示例可视化**
![深度点云可视化](../../image/interleave_ae_mode/interleave_ae0.jpeg)
![深度点云可视化](../../image/interleave_ae_mode/interleave_ae1.jpeg)
## Multi_camera_synced + Interleave_ae
请参考 [multi_camera_synced](./multi_camera_synced.md) 和 [参数介绍](#参数介绍)
@@ -0,0 +1,99 @@
# 网络相机
> 本节介绍如何在 OrbbecSDK_ROS2 中使用网络相机。目前仅支持 Femto_Mega、Gemini 335Le 和 Gemini 435Le 设备,其他网络设备将在不久的将来得到支持。
您可以在 [example](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples) 中找到示例使用代码。
## Femto Mega & Gemini 435Le & Gemini 335Le
**参数介绍**
网络设备设置:`enumerate_net_device` 设置为 true,将自动枚举网络设备。
如果您不想自动枚举网络设备,可以将 `enumerate_net_device` 设置为 false,将 `net_device_ip` 设置为设备的 IP 地址,并将 `net_device_port` 设置为默认值 8090。
* `enumerate_net_device`:启用自动枚举网络设备。
* `net_device_ip`:设置网络设备的 IP 地址。
* `net_device_port`:设置网络设备的端口。通常可以设置为 8090。
**单个网络相机**
> 如果您需要运行 Gemini 435Le/Gemini 335Le,只需在运行命令中将 [femto_mega.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/femto_mega.launch.py) 替换为 [gemini435_le.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/gemini435_le.launch.py)/[gemini_330_series.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/gemini_330_series.launch.py)
以 [femto_mega.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/femto_mega.launch.py) 为例:
- **自动枚举网络设备:**
```bash
ros2 launch orbbec_camera femto_mega.launch.py enumerate_net_device:=true
```
- **指定 IP 地址启动设备:**
注意:`net_device_ip` 需要更改为设备的 IP 地址,这里是 192.168.1.10
```bash
ros2 launch orbbec_camera femto_mega.launch.py enumerate_net_device:=false net_device_ip:=192.168.1.10 net_device_port:=8090
```
**多个网络相机**
以 [multi_net_camera.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/examples/net_camera/multi_net_camera.launch.py) 为例:
```bash
ros2 launch orbbec_camera multi_net_camera.launch.py
```
## set_device_ip 工具
**`set_device_ip`** 可执行文件允许您直接从 ROS 2 配置网络相机的 IP 设置,包括在 DHCP 和静态 IP 之间切换,以及设置子网掩码和网关。这对于快速分配或更新 IP 地址而无需修改启动文件非常有用。
> **注意:**使用 `set_device_ip` 应用的 IP 设置是**永久性的**,如果设备断电或重启,**不会重置**。
**示例用法**
```bash
ros2 run orbbec_camera set_device_ip --ros-args \
-p old_ip:=192.168.1.10 \
-p dhcp:=false \
-p new_ip:=192.168.1.11 \
-p mask:=255.255.255.0 \
-p gateway:=192.168.1.1
```
**参数**
- **`old_ip`** – 设备的当前 IP 地址。
- **`dhcp`** – 设置为 `true` 使用 DHCP 或 `false` 使用静态 IP。
- **`new_ip`** – 禁用 DHCP 时要分配的静态 IP 地址。
- **`mask`** – 新 IP 的子网掩码。
- **`gateway`** – 新 IP 的网关地址。
## 强制 IP 功能
**强制 IP** 功能允许您为网络相机分配**静态 IP 地址**,覆盖 DHCP 设置。当连接多个网络相机时,这非常有用,您需要每个设备具有固定的 IP 以实现可靠的通信。
> **注意:**如果设备断电或重启,强制 IP 配置**将被重置**。您需要在重启后重新应用设置。
**参数**
- **`force_ip_enable`** – 启用强制 IP 功能。**默认值:** `false`
- **`force_ip_mac`** – 连接多个相机时的目标设备 MAC 地址(例如 `"54:14:FD:06:07:DA"`)。您可以使用 `list_devices_node` 查找每个设备的 MAC。**默认值:** `""`
- **`force_ip_address`** – 要分配的静态 IP 地址。**默认值:** `192.168.1.10`
- **`force_ip_subnet_mask`** – 静态 IP 的子网掩码。**默认值:** `255.255.255.0`
- **`force_ip_gateway`** – 静态 IP 的网关地址。**默认值:** `192.168.1.1`
**示例用法**
- **为特定设备启用强制 IP:**
```bash
ros2 launch orbbec_camera gemini_330_series.launch.py \
force_ip_enable:=true \
force_ip_mac:=54:14:FD:06:07:DA \
force_ip_address:=192.168.1.50 \
force_ip_subnet_mask:=255.255.255.0 \
force_ip_gateway:=192.168.1.1 \
net_device_ip:=192.168.1.50 \
net_device_port:=8090
```
@@ -0,0 +1,12 @@
# 预定义预设
| 预设 | 特点 | 推荐使用场景 |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Default | - 最佳视觉感知<br>- 在精度、填充率、微小物体等方面的整体性能良好 | - 通用场景<br>- 机器人应用 |
| Hand | - 清晰的手部和手指边缘 | - 手势识别 |
| High Accuracy | - 高置信度深度<br>- 几乎无噪声深度值<br>- 填充率较低 | - 避障<br>- 物体扫描 |
| High Density | - 更高填充率<br>- 更多微小物体<br>- 可能存在噪声深度值 | - 物体识别<br>- 抓取和放置<br>- 前景和背景动画 |
| Medium Density | - 填充率和精度的平衡性能<br>- 与 Default 相比:填充率较低,边缘质量更好 | - 通用场景和 Default 的替代方案 |
| Custom | - 用户自定义预设<br>- 从上述预设派生,具有自定义修改,例如后处理管道的新配置、深度 AE 功能的修改平均强度设定点等 | - 通过使用自定义配置可获得比预定义预设更好的深度性能<br>- 适用于已建立的自定义配置 |
根据您的具体使用场景选择合适的预设名称,并将其设置为 `device_preset` 参数的值。
@@ -0,0 +1,66 @@
# GMSL 相机
> 本节介绍如何在 OrbbecSDK_ROS2 中使用 GMSL 相机。目前仅支持 Gemini 335Lg 和 Gemini 345Lg 设备,其他 GMSL 设备将在不久的将来得到支持。
您可以在 [example](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples) 中找到示例使用代码。
## 单个 GMSL 相机
GMSL 相机在 OrbbecSDK_ROS2 中的使用与通过 USB 的 Gemini 330 系列相机相同。
```bash
ros2 launch orbbec_camera gemini_330_gmsl.launch.py
```
## 多个 GMSL 相机
要获取 GMSL 相机的 `usb_port`,插入相机并在终端中运行以下命令:
```bash
ros2 run orbbec_camera list_devices_node
```
例如,获得的 gmsl 相机 `usb_port`:`gmsl2-1`
转到 [multi_gmsl_camera.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera.launch.py) 文件并更改 `usb_port`。
```bash
ros2 launch orbbec_camera multi_gmsl_camera.launch.py
```
> 注意:默认情况下,multi_gmsl_camera.launch.py 仅启动 color 和 depth。如果您想启动其他传感器,请转到 [camera_secondary_params.yaml](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/config/camera_secondary_params.yaml) 进行修改。
## 多个 GMSL 相机同步
首先,请查看如何使用 [multi_camera_synced](./multi_camera_synced.md)。
此外,GMSL 多相机同步不需要 Multi-Camera Sync Hub Pro,因此无需设置 `primary` 模式。每个 GMSL 相机都是 `secondary`。
**额外的参数设置**
* `gmsl_trigger_fps`:设置硬件 soc 触发源帧率。
* `enable_gmsl_trigger`:启用硬件 soc 触发。
**运行启动文件**
请参考 [multi_gmsl_camera_synced.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera_synced.launch.py) 中的配置。
```bash
ros2 launch orbbec_camera multi_gmsl_camera_synced.launch.py
```
> 注意:默认情况下,multi_gmsl_camera_synced.launch.py 仅启动 color 和 depth。如果您想启动其他传感器,请转到 [camera_secondary_params.yaml](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/config/camera_secondary_params.yaml) 进行修改。
## GMSL 相机的使用限制
GMSL 相机与各种反序列化器芯片(如 MAX9296 和 MAX92716)接口。Orbbec GMSL 相机支持多个流,包括深度、彩色、IR 和 IMU 数据,但存在某些使用限制:
- GMSL 仅支持 V4L2 和 YUYV 格式;不支持 MJPG 格式。RGB 输出源自 YUYV 格式转换。
- Gemini-335Lg 的元数据通过单独的节点提供,而其他型号的元数据嵌入在视频帧中,这对用户保持透明。
- 当使用 Max96712 作为反序列化器芯片时,由于 Max96712 芯片的特性,在 secondary_synced 模式下必须提供多机同步触发信号。否则,在切换数据流时会发生数据流中断。
- 连接在同一个 MAX9296、MAX96712 LinkA/B 或 MAX96712 LinkC/D 上的两个相机有以下限制:
- 在驱动程序版本 v1.2.02 之前,存在一个限制,即一个相机的 RGB 和另一个相机的右 IR 不能同时流式传输。在驱动程序版本 v1.2.02 之后,限制修改为一个相机的 RGB 和另一个相机的左 IR 不能同时流式传输。
- 在驱动程序版本 v1.2.02 之前,存在一个限制,即一个相机的 DEPTH 和另一个相机的左 IR 不能同时流式传输。在驱动程序版本 v1.2.02 之后,限制修改为一个相机的 DEPTH 和另一个相机的右 IR 不能同时流式传输。
- 两个相机的活动流的组合最大数量限制为四个(满足上述两个条件即可确保合规)。
有关更多已知限制,请参考 [Orbbec GMSL 相机的使用限制](https://github.com/orbbec/MIPI_Camera_Platform_Driver/blob/main/doc/Instructions%20for%20Using%20GMSL%20Camera.md)
@@ -0,0 +1,91 @@
# 多相机
- 要获取相机的 `usb_port`,插入相机并在终端中运行以下命令:
```bash
ros2 run orbbec_camera list_devices_node
```
- 将 `device_num` 参数设置为您拥有的相机数量。
- 转到 `OrbbecSDK_ROS2/launch/multi_xxx.launch.py` 文件并更改 `usb_port`。
- 不要忘记将 `include` 标签放在 `group` 标签内。
否则,不同相机的参数值可能会被污染。
```python
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription, GroupAction, ExecuteProcess
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
import os
def generate_launch_description():
# Include launch files
package_dir = get_package_share_directory('orbbec_camera')
launch_file_dir = os.path.join(package_dir, 'launch')
launch1_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(launch_file_dir, 'gemini2L.launch.py')
),
launch_arguments={
'camera_name': 'camera_01',
'usb_port': '6-2.4.4.2', # replace your usb port here
'device_num': '2'
}.items()
)
launch2_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(launch_file_dir, 'gemini2L.launch.py')
),
launch_arguments={
'camera_name': 'camera_02',
'usb_port': '6-2.4.1', # replace your usb port here
'device_num': '2'
}.items()
)
# If you need more cameras, just add more launch_include here, and change the usb_port and device_num
# Launch description
ld = LaunchDescription([
GroupAction([launch1_include]),
GroupAction([launch2_include]),
])
return ld
```
- 要启动相机,运行以下命令:
```bash
ros2 launch orbbec_camera multi_camera.launch.py
```
## 多相机无数据流
**电源供应不足**:
- 确保每个相机连接到单独的集线器。
- 使用带电源的集线器为每个相机提供足够的电力。
**高分辨率**:
- 尝试降低分辨率以解决数据流问题。
**增加 usbfs_memory_mb 值**:
- 将 `usbfs_memory_mb` 值增加到 128MB(这是一个参考值,可以根据系统需求进行调整)
通过运行以下命令:
```bash
echo 128 | sudo tee /sys/module/usbcore/parameters/usbfs_memory_mb
```
- 要使此更改永久生效,请查看[此链接](https://github.com/OpenKinect/libfreenect2/issues/807)。
## 多相机图像话题帧率过低
请参考 [Fast DDS 配置](../performance/fastdds_tuning.md) 文件。
@@ -0,0 +1,55 @@
# 多相机同步说明
> 本文档的目的是说明如何在 OrbbecSDK_ROS2 中使用多相机同步
### 设置说明
* 请阅读多相机同步设置指南:[多相机同步设置](https://www.orbbec.com/docs/set-up-cameras-for-external-synchronization_v1-2/)
* 确保相机正确连接到多相机同步器。
![深度点云可视化](../../image/multi_camera_synced/multi_camera_synced1.png)
### 使用 OrbbecSDK_ROS2 检查相机端口
```bash
ros2 run orbbec_camera list_devices_node
```
### OrbbecSDK_ROS2 多相机同步配置
打开 multi_camera_synced.launch.py,并按照下面所示配置相机设置:
![深度点云可视化](../../image/multi_camera_synced/multi_camera_synced2.png)
1. `gemini_330_series.launch.py` 是用于启动相机的启动文件。
2. 将 `camera_name` 设置为 `G330_0`。例如,发布的彩色图像话题将是 `/G330_0/color/image_raw`。
3. 将 `usb_port` 设置为 `2-2`,表示正在使用端口 `2-2` 上的相机设备。此值可以在 `ros2 run orbbec_camera list_devices_node` 命令的输出中找到。
4. 将 `device_num` 设置为 `2`,表示将使用两个相机。
5. 将 `sync_mode` 设置为 `primary`,表示 `2-7` 相机设备处于主模式。多相机同步模式选项可以在下图中找到。
6. 来自 `config_file_path` 的参数可以覆盖在 `gemini_330_series.launch.py` 中设置的参数(可选)。
7. 对于从属相机,将 `trigger_out_enabled` 设置为 false。
| **模式名称** | **设置效果说明** |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| free_run | - 支持不同的帧率设置<br />- 8 针同步接口不支持外部输出同步相关信号 |
| standalone(默认) | ● 默认与 Primary 相同<br />● 内置 RGBD 帧同步<br />● 8 针同步接口默认不向外部输出信号 |
| primary | ● 设置为主相机<br />● 8 针同步接口向外部设备输出信号 |
| secondary | ● 设置为从属(被动同步;当外部有硬件连续触发信号输入且连续触发信号与当前设置的帧率匹配时,根据外部触发信号采集图像;当没有外部触发信号时,停止流)<br />● 8 针同步接口向外部设备输出信号 |
| secondary_synced | ● 设置为从属同步(被动同步;当外部有硬件连续触发信号输入且连续触发信号与当前设置的帧率匹配时,根据外部触发信号采集图像;当没有外部触发信号时,根据设置的帧率的内部触发信号采集图像)<br />● 8 针同步接口向外部设备输出信号 |
| hardware_triggering | ● 设置为硬件触发(被动触发;当外部有硬件触发信号输入且触发信号时间间隔不小于当前上限时,根据外部触发信号采集图像;当没有外部触发信号时,不采集图像)<br />● 8 针同步接口向外部设备输出信号 |
| software_triggering | ● 设置为软件触发(被动触发;当主机有触发命令输入且触发命令时间间隔不小于当前上限时,根据触发命令采集图像;当没有触发命令时,不采集图像)<br />● 8 针同步接口向外部设备输出信号 |
* 主相机应该最后启动。
* 理想情况下,启动每个相机之间应该有 2 秒的延迟。
### 运行以下命令启动多相机同步
```bash
ros2 launch orbbec_camera multi_camera_synced.launch.py
```
@@ -0,0 +1,161 @@
# 多相机同步验证节点
文件路径:[image_sync_example_node.cpp](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/examples/multi_camera_time_sync/image_sync_example_node.cpp)
此示例节点用于 **4 台 Orbbec 相机** 的同步采集与时间戳验证。
它可用于验证多相机主从同步(Primary / Secondary Synced)模式下的帧对齐精度。
---
## 使用教程
### **在 `multi_camera_synced.launch.py` 的基础上做以下修改**
- 增加 `launch_include` 以适配 4 台相机
- 根据设备型号选择对应的 launch 文件,如 330 系列选择 gemini_330_series.launch.py
- 命名规范:camera_name 命名方式 camera_01、camera_02、camera_03 ...
- 设置 device_num 数量为 4
- USB 端口配置 usb_port,使用以下命令查看并绑定正确的端口
`ros2 run orbbec_camera list_devices_node`
- 同步模式设置为主从模式,一个 primary 相机,其他设置为 secondary_synced
- 启动顺序:主相机(Primary)应最后启动,以确保同步信号建立正确。
---
### **参数文件修改**
修改 `config` 目录下的以下两个配置文件:
- `camera_params.yaml`
- `camera_secondary_params.yaml`
确保以下内容统一:
- 启用 **depth** 与 **color** 流;
- 统一各相机的 **帧率(fps)**。
---
### **启动与验证**
- 启动多机同步 launch: `multi_camera_synced.launch.py`
- 打开新终端运行同步验证节点: `ros2 run orbbec_camera image_sync_example_node`
该节点会输出多相机图像的时间戳差异信息,用于验证同步效果。
---
### **参考 launch 文件**
```
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import IncludeLaunchDescription, GroupAction, TimerAction
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch_ros.actions import Node, LoadComposableNodes
def generate_launch_description():
# Include launch files
package_dir = get_package_share_directory("orbbec_camera")
launch_file_dir = os.path.join(package_dir, "launch")
config_file_dir = os.path.join(package_dir, "config")
config_file_path = os.path.join(config_file_dir, "camera_params.yaml")
secondary_config_file_path = os.path.join(config_file_dir, "camera_secondary_params.yaml")
launch1_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(launch_file_dir, "gemini_330_series.launch.py")
),
launch_arguments={
"camera_name": "camera_01",
"usb_port": "2-2.3",
"device_num": "4",
"sync_mode": "primary",
"config_file_path": config_file_path,
"trigger_out_enabled": "true"
}.items(),
)
launch2_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(launch_file_dir, "gemini_330_series.launch.py")
),
launch_arguments={
"camera_name": "camera_02",
"usb_port": "2-1",
"device_num": "4",
"sync_mode": "secondary_synced",
"config_file_path": secondary_config_file_path,
"trigger_out_enabled": "false"
}.items(),
)
launch3_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(launch_file_dir, "gemini_330_series.launch.py")
),
launch_arguments={
"camera_name": "camera_03",
"usb_port": "2-3",
"device_num": "4",
"sync_mode": "secondary_synced",
"config_file_path": secondary_config_file_path,
"trigger_out_enabled": "false"
}.items(),
)
launch4_include = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(launch_file_dir, "gemini_330_series.launch.py")
),
launch_arguments={
"camera_name": "camera_04",
"usb_port": "2-4",
"device_num": "4",
"sync_mode": "secondary_synced",
"config_file_path": secondary_config_file_path,
"trigger_out_enabled": "false"
}.items(),
)
# Launch description
ld = LaunchDescription(
[
TimerAction(period=0.0, actions=[GroupAction([launch2_include])]),
TimerAction(period=2.0, actions=[GroupAction([launch3_include])]),
TimerAction(period=4.0, actions=[GroupAction([launch4_include])]),
TimerAction(period=6.0, actions=[GroupAction([launch1_include])]),
# The primary camera should be launched at last
]
)
return ld
```
---
## 必要系统配置
### **提升 USB 缓冲区容量**
```
echo 512 | sudo tee /sys/module/usbcore/parameters/usbfs_memory_mb
```
### **配置 Fast DDS**
优化 ROS2 节点间通信延迟,可以有效减少图像传输延迟,[配置过程见此章节](../performance/fastdds_tuning.md)。
@@ -0,0 +1,39 @@
# 高效的进程内通信:
### 简介
如果我们的ROS2封装器节点与订阅者节点加载在同一进程中,它支持零拷贝通信。这可以减少图像/点云话题的拷贝时间,特别是在大帧分辨率和高FPS的情况下。
您需要启动一个组件容器,并将我们的节点作为组件与其他组件节点一起启动。有关"在单个进程中组合多个节点"的更多详细信息,请参见 [此处](https://docs.ros.org/en/rolling/Tutorials/Composition.html)。
有关高效进程内通信的更多详细信息,请参见 [此处](https://docs.ros.org/en/humble/Tutorials/Intra-Process-Communication.html#efficient-intra-process-communication)。
### 示例
**手动将多个组件加载到同一进程中**
* 启动组件:
```bash
ros2 run rclcpp_components component_container
```
* 添加封装器:
```bash
ros2 component load /ComponentManager orbbec_camera orbbec_camera::OBCameraNodeDriver -e use_intra_process_comms:=true
```
以相同方式加载其他组件节点(封装器话题的消费者)。
**使用启动文件**
```bash
ros2 launch orbbec_camera gemini_intra_process_demo_launch.py
```
**限制**
* RCLPY目前不支持节点组件
* 使用 `image_transport` 的压缩图像将被禁用,因为进程内通信不支持此功能
@@ -0,0 +1,146 @@
# 针对Orbbec相机与ROS2的Fast DDS优化
使用默认配置时,Fast DDS表现出次优的传输效率,导致在ROS2中使用Orbbec相机时图像传输延迟显著。本文档提供了优化Fast DDS以提高图像传输效率的指导。
## 调整系统参数
**IP分片时间**
- **路径**: `/proc/sys/net/ipv4/ipfrag_time`(默认值:30秒)
- **目的**: 定义IP分片保留在内存中的持续时间。
- **调整**: 减少此值以缩短未接收到分片的时间窗口,这有助于减少延迟。考虑到您环境的具体需求,因为此设置会影响所有传入的分片。
**示例**: 设置为3秒。
```bash
sudo sysctl net.ipv4.ipfrag_time=3
```
**IP分片内存阈值**
- **路径**: `/proc/sys/net/ipv4/ipfrag_high_thresh`(默认值:262144字节)
- **目的**: 设置用于重组IP分片的最大内存。
- **调整**: 增加此值以允许更多内存用于分片重组,这可以改善较大数据包的处理。
**示例**: 增加到128 MB。
```bash
sudo sysctl net.ipv4.ipfrag_high_thresh=134217728
```
**最大缓冲区大小**
- **目的**: 配置接收和发送数据的最大缓冲区大小,这对高吞吐量数据传输至关重要。
- **调整**: 设置接收和发送操作的最大缓冲区大小。
**命令**:
```bash
sudo sysctl -w net.core.rmem_max=2147483647
sudo sysctl -w net.core.rmem_default=2147483647
sudo sysctl -w net.core.wmem_max=2147483647
sudo sysctl -w net.core.wmem_default=2147483647
```
或者,通过将这些设置添加到 `/etc/sysctl.d/10-fastrtps-max.conf` 文件中使其永久生效。
```bash
sudo gedit /etc/sysctl.d/10-fastrtps-max.conf
```
将以下行添加到文件中:
```bash
net.core.rmem_max=2147483647
net.core.rmem_default=2147483647
net.core.wmem_max=2147483647
net.core.wmem_default=2147483647
```
然后保存并退出文件。运行 `sudo sysctl -p` 以应用更改。
有关详细指导,请参考 [ROS 2 DDS调优文档](https://docs.ros.org/en/foxy/How-To-Guides/DDS-tuning.html)。
## Fast DDS配置
以下是针对Orbbec相机与ROS2使用而优化的Fast DDS配置文件示例。此配置通过调整缓冲区大小和传输设置来增强整体数据传输。
**配置文件:** `shm_fastdds.xml`
将此文件放在 `$HOME` 目录中。
```xml
<?xml version="1.0" encoding="UTF-8"?>
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
<transport_descriptors>
<transport_descriptor>
<transport_id>UDP_transport</transport_id>
<type>UDPv4</type>
<maxInitialPeersRange>10</maxInitialPeersRange>
<maxMessageSize>65000</maxMessageSize>
<sendBufferSize>1048576</sendBufferSize>
<receiveBufferSize>1048576</receiveBufferSize>
</transport_descriptor>
</transport_descriptors>
<participant profile_name="participant_profile_ros2" is_default_profile="true">
<rtps>
<name>profile_for_ros2_context</name>
<userTransports>
<transport_id>UDP_transport</transport_id>
</userTransports>
<useBuiltinTransports>false</useBuiltinTransports>
<sendSocketBufferSize>1048576</sendSocketBufferSize>
<listenSocketBufferSize>1048576</listenSocketBufferSize>
<builtin>
<initialPeersList>
<locator>
<udpv4>
<address>127.0.0.1</address>
</udpv4>
</locator>
</initialPeersList>
</builtin>
</rtps>
</participant>
<data_writer profile_name="default publisher profile" is_default_profile="true">
<qos>
<publishMode>
<kind>ASYNCHRONOUS</kind>
</publishMode>
<latencyBudget>
<duration>
<sec>0</sec>
<nanosec>1000000</nanosec>
</duration>
</latencyBudget>
</qos>
<historyMemoryPolicy>PREALLOCATED_WITH_REALLOC</historyMemoryPolicy>
</data_writer>
<data_reader profile_name="default subscription profile" is_default_profile="true">
<qos>
<data_sharing>
<kind>AUTOMATIC</kind>
</data_sharing>
<latencyBudget>
<duration>
<sec>0</sec>
<nanosec>1000000</nanosec>
</duration>
</latencyBudget>
</qos>
<historyMemoryPolicy>PREALLOCATED_WITH_REALLOC</historyMemoryPolicy>
</data_reader>
</profiles>
```
**环境变量**
设置以下环境变量以使用自定义Fast DDS配置文件:
```bash
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
export FASTRTPS_DEFAULT_PROFILES_FILE=$HOME/shm_fastdds.xml
export RMW_FASTRTPS_USE_QOS_FROM_XML=1
```
此配置旨在优化数据流并减少传输延迟,提高Orbbec相机系统在ROS2环境中的响应性和可靠性。
@@ -0,0 +1,95 @@
## 使用Orbbec ROS包降低CPU使用率
您可以在 [示例](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples) 中找到使用示例代码。
本文档概述了在使用 **Gemini 330系列相机** 的 **OrbbecSDK_ROS2 v2** 环境中最小化CPU使用率的策略。固件版本必须 **不低于1.4.10**,且 `device` 应设置为 **Default**。
### 降低CPU使用率的推荐设置
要在OrbbecSDK_ROS2中实现最低的CPU使用率,建议配置以下参数。
| 参数 | 推荐值 | 说明 |
| :--------------: | :------------------------------------: | :--------------------------------------------: |
| `uvc_backend` | `v4l2` | 与 `libuvc` 相比CPU使用率更低 |
| `color_format` | `RGB` | CPU使用率低于 `MJPG` |
| `filter` | 仅使用 `hardware_noise_removal_filter` | 其他滤波器会显著增加CPU使用率 |
### 用于测试的启动文件
* `gemini_330_series_lower_cpu_usage.launch.py`
* `multi_camera_lower_cpu_usage.launch.py`
### 测试环境
**硬件配置**
* **CPU**: Intel i7-8700 @ 3.20GHz
* **内存**: 24 GB
* **存储**: Micron 2200S NVMe 256GB
* **GPU**: NVIDIA GeForce GTX 1660Ti
* **操作系统**: Ubuntu22.04
**ROS配置**
* **ROS版本**: ROS2 Humble
* **SDK版本**: OrbbecSDK_ROS2 v2.2.1
**相机设置**
* 设备: 2x Gemini 335, 1x Gemini 336, 1x Gemini 336L
* 固件版本: 1.4.10
### 测试设置
**数据流设置:**
* 深度/左IR/右IR: 848×480 @ 30fps
* 彩色: 848×480 @ 30fps
注意:以下CPU使用率数据重点关注 `uvc_backend`、`color_format` 和各种滤波器组合。
### 测试结果
**`uvc_backend` 对比(RGB格式)**
| libuvc CPU使用率 | v4l2 CPU使用率 | 绝对变化 |
| :--------------: | :------------: | :-------------: |
| 182.8% | 118.8% | -64.0% |
使用v4l2后端可以显著降低CPU使用率。在我们的实现中,v4l2无需对Linux内核进行任何补丁即可工作,允许用户轻松在v4l2和libuvc之间切换,并保持与标准Linux发行版的完全兼容性。
**`color_format` 对比(MJPG vs RGB)**
| 后端 | MJPG CPU使用率 | RGB CPU使用率 | 绝对变化 |
| :-----: | :------------: | :-----------: | :-------------: |
| libuvc | 347.7% | 182.8% | -164.9% |
| v4l2 | 170.0% | 118.8% | -51.2% |
如果选择RGB格式而不是MJPG,可以降低CPU使用率,因为MJPG图像的解码会消耗主机CPU资源。
**滤波器配置影响**
| 应用的滤波器 | libuvc CPU使用率 | CPU使用率增加 | v4l2 CPU使用率 | CPU使用率增加 |
| ----------------------------------------------------- | ---------------- | ------------------ | -------------- | ------------------ |
| 无滤波器(基准) | 182.8% | 0.0%(基准) | 118.8% | 0.0%(基准) |
| `(软件)noise_removal_filter` | 218.0% | +35.2% | 128.5% | +9.7% |
| `(软件)noise_removal_filter + spatial_filter` | 469.6% | +286.8% | 336.7% | +217.9% |
| `hardware_noise_removal_filter` | 186.3% | +3.5% | 115.4% | -3.4% |
| `hardware_noise_removal_filter + spatial_filter` | 251.3% | +68.5% | 152.5% | +33.7% |
根据测试结果,仅使用 `hardware_noise_removal_filter` 相比无滤波器基准,对 `libuvc`(+3.5%)和 `v4l2`(-3.4%)的CPU使用率变化可以忽略不计,因为此滤波器在相机硬件内部运行。相比之下,其他滤波器在主机系统上执行。将 `spatial_filter` 添加到硬件滤波器会导致CPU使用率适度增加,而应用基于软件的 `noise_removal_filter`——无论是单独使用还是与 `spatial_filter` 结合——都会显著增加CPU负载。为保持较低的CPU使用率,建议避免使用基于软件的滤波器,仅依赖 `hardware_noise_removal_filter`。
### 进一步优化
| 参数 | 推荐值 | 说明 |
| :----------------------------: | :----------------------------------------------: | :---------------------------------------------: |
| `depth_registration` | `false` 或 `true` 配合 `align_mode=HW` | 软件对齐消耗更多CPU |
| `enable_point_cloud` | `false` | 禁用点云可降低CPU使用率 |
| `enable_colored_point_cloud` | `false` | 禁用彩色点云可降低CPU使用率 |
@@ -0,0 +1,12 @@
性能基准测试
======================================================
本章介绍如何使用性能基准测试工具,并提供不同相机的测试结果。
.. toctree::
:maxdepth: 2
introduction.md
benchmark_usage.md
benchmark_data.md
othertools.md
@@ -0,0 +1,16 @@
# 性能基准测试数据
本节记录了使用性能基准测试工具测试不同相机的数据。点击链接下载 xlsx 数据。
## 通用基准测试数据
使用默认启动文件运行 `common_benchmark_node` 并测试 1 小时的数据。
- [通用基准测试数据](../../_static/ros2_common_benchmark_data.xlsx)
## 服务基准测试数据
使用默认启动文件分别运行 `service_benchmark_node` 和 `service_benchmark_node.py`。每个服务调用 10 次,并记录数据。
- [服务基准测试数据 C++](../../_static/ros2_service_benchmark_cpp.xlsx)
- [服务基准测试数据 Python](../../_static/ros2_service_benchmark_python.xlsx)
@@ -0,0 +1,115 @@
# 性能基准测试使用
本节介绍如何在 C++ 和 Python 中使用性能基准测试工具,并提供示例 YAML 配置文件。
## 使用通用基准测试节点
```
ros2 run orbbec_camera common_benchmark_node.py \
--run_time 2h \
--csv_file /path/to/log.csv
```
* **参数**
* **--run_time**:监控持续时间,指定为时间字符串,如 `"10s"`、`"5m"`、`"1h"`、`"2d"`。默认为 10 秒。
* **--csv_file**:输出 CSV 文件的路径。默认情况下,它保存在工作空间目录中,名称为 "camera_monitor_log.csv"。
## 使用服务基准测试节点
### ROS2 C++
* **单个服务基准测试**
```
ros2 run orbbec_camera service_benchmark_node \
--ros-args \
-p service_name:=/camera/get_depth_gain \
-p service_type:=orbbec_camera_msgs/srv/GetInt32 \
-p count:=10
```
* **多个服务基准测试(YAML 配置)**
```
ros2 run orbbec_camera service_benchmark_node \
--ros-args \
-p yaml_file:=/path/to/default_service_cpp.yaml
```
### ROS2 Python
* **单个服务基准测试**
```
ros2 run orbbec_camera service_benchmark_node.py --service /camera/get_depth_gain --count 10
```
* **多个服务基准测试(YAML 配置)**
```
ros2 run orbbec_camera service_benchmark_node.py --yaml_file /path/to/default_service.yaml
```
### **示例 YAML 配置**
我们提供了一个示例 YAML 配置,位于 `scripts` 目录中,名为 `service_default.yaml`。
```yaml
default_count: 50
services:
- name: /camera/get_auto_white_balance
type: orbbec_camera_msgs/srv/GetInt32
- name: /camera/get_color_exposure
type: orbbec_camera_msgs/srv/GetInt32
- name: /camera/get_color_gain
type: orbbec_camera_msgs/srv/GetInt32
- name: /camera/get_depth_exposure
type: orbbec_camera_msgs/srv/GetInt32
- name: /camera/get_depth_gain
type: orbbec_camera_msgs/srv/GetInt32
- name: /camera/get_device_info
type: orbbec_camera_msgs/srv/GetDeviceInfo
- name: /camera/send_software_trigger
type: std_srvs/srv/SetBool
request: {data: false}
- name: /camera/set_auto_white_balance
type: std_srvs/srv/SetBool
request: {data: false}
- name: /camera/set_color_ae_roi
type: orbbec_camera_msgs/srv/SetArrays
request: {data_param: [0,1279,0,719]}
- name: /camera/set_color_auto_exposure
type: std_srvs/srv/SetBool
request: {data: false}
- name: /camera/set_color_exposure
type: orbbec_camera_msgs/srv/SetInt32
request: {data: 30}
- name: /camera/set_color_flip
type: std_srvs/srv/SetBool
request: {data: false}
- name: /camera/set_color_gain
type: orbbec_camera_msgs/srv/SetInt32
request: {data: 20}
- name: /camera/set_color_mirror
type: std_srvs/srv/SetBool
request: {data: false}
- name: /camera/set_color_rotation
type: orbbec_camera_msgs/srv/SetInt32
request: {data: 90}
- name: /camera/set_depth_ae_roi
type: orbbec_camera_msgs/srv/SetArrays
request: {data_param: [0,1279,0,719]}
- name: /camera/set_depth_auto_exposure
type: std_srvs/srv/SetBool
request: {data: false}
- name: /camera/set_depth_exposure
type: orbbec_camera_msgs/srv/SetInt32
request: {data: 3000}
- name: /camera/set_depth_flip
type: std_srvs/srv/SetBool
request: {data: false}
- name: /camera/set_depth_gain
type: orbbec_camera_msgs/srv/SetInt32
request: {data: 200}
```
@@ -0,0 +1,45 @@
# 介绍
本节介绍性能基准测试工具,解释其目的、功能以及它可以帮助您测量的内容。
## 通用基准测试节点
`common_benchmark_node.py` 是一个用于监控在 ROS 环境中运行的 Orbbec 相机性能的工具。它实时收集和记录关键相机指标,如帧率、延迟、系统资源使用和丢包率,帮助用户评估相机节点的稳定性和性能(每秒更新一次)。
**功能**
- 测量发布的图像帧率和延迟(当前、最小、最大、平均)
- 监控相机节点的 CPU/ARM 使用率(当前、最小、最大、平均)
- 跟踪丢帧率(发布者)和丢包率(订阅者)
- 将实时统计信息(1 Hz)打印到终端并将结果保存到 CSV 文件
- 支持可配置的运行时长和 CSV 输出路径
**示例**
在 ROS1 中,可以测量丢帧率和丢包率,而在 ROS2 中,header 缺少 `seq` 字段,因此仅计算发布者端的丢帧率。
![common_benchmark_ros1](../image/benchmark_images/common_benchmark_ros1.png "ROS1")
![common_benchmark_ros2](../image/benchmark_images/common_benchmark_ros2.png "ROS2")
## 服务基准测试节点
`service_benchmark_node` 工具用于监控服务调用的性能。它可以测量服务调用的成功率和执行服务所需的时间。
**功能**
- 对单个服务调用进行基准测试,测量延迟和成功率
- 对 YAML 配置文件中定义的多个服务进行基准测试
- 可选择将基准测试结果保存到 CSV 文件
**示例**
![service benchmark](../image/benchmark_images/service_benchmark.png)
当您需要收集多个服务的数据时,建议使用 CSV 文件进行分析。
@@ -0,0 +1,52 @@
# 其他工具
## Ob_benchmark 工具
> 此工具的目标是对各种 OrbbecSDK_ROS2 相机配置的性能进行基准测试。基准测试结果取决于使用的相机和设置。(目前仅适用于 ROS2 Humble)
您可以在 [example](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples) 中找到示例使用代码。
### 工具配置 ([start_benchmark_params.json](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/config/tools/startbenchmark/start_benchmark_params.json))
```json
{
"start_benchmark_params": {
"camera_name": [
"camera_01",
"camera_02",
"camera_03",
"camera_04"
],
"process_name": "component_conta",
"switch_cycle": 300,
"test_cycle": 1,
"skip_number": 30
}
}
```
- `camera_name`:要配置的相机名称。例如:`"camera_01"`、`"camera_02"` 等。
- `process_name`:要监控的进程名称。例如,`"component_conta"` 将监控容器进程的数据。
- `switch_cycle`:切换配置的周期时间,以秒为单位。例如,设置为 `300` 意味着配置将每 300 秒切换一次。
- `test_cycle`:测试周期,以秒为单位。例如,设置为 `1` 意味着工具将每 1 秒收集一次监控进程的数据。
- `skip_number`:要跳过的数据点数量。例如,设置为 `30` 意味着将忽略前 30 个数据点。
### 相机配置(启动文件)
在 launch 文件夹中,有多个 .launch.py 文件(`ob_benchmark_0.launch.py`、`ob_benchmark_1.launch.py`、...、`ob_benchmark_19.launch.py`)。每个文件对应不同的相机配置。
### 运行 ob_benchmark 工具
要运行该工具,请使用以下命令:
```bash
source install/setup.bash
ros2 run orbbec_camera ob_benchmark_node
```
### 输出数据文件
输出数据文件将存储在 ob_benchmark 文件夹中,文件名如 `0.csv`、`1.csv`、...、19.csv。例如:
- `0.csv` 包含来自 `ob_benchmark_0.launch.py` 配置的数据。
- `1.csv` 包含来自 `ob_benchmark_1.launch.py` 配置的数据。
@@ -0,0 +1,43 @@
# 构建 Debian 软件包
## 准备环境
在开始之前,安装所需的工具:
```bash
sudo apt install debhelper fakeroot python3-bloom
```
## 配置 ROS 依赖项
在系统中的 `/etc/ros/rosdep/sources.list.d/00-orbbec.yaml` 添加以下 YAML 文件。确保将 `focal` 替换为您的 Ubuntu 版本的代号,将 `humble` 替换为您的 ROS2 发行版名称:
```yaml
orbbec_camera_msgs:
ubuntu:
focal: [ ros-humble-orbbec-camera-msgs ]
```
接下来,创建一个新文件 `/etc/ros/rosdep/sources.list.d/50-orbbec.list` 并添加此行以指定 YAML 文件的路径:
```bash
yaml file:///etc/ros/rosdep/sources.list.d/00-orbbec.yaml
```
更新 rosdep 数据库以反映这些更改:
```bash
rosdep update
```
## 构建软件包
导航到您的工作空间并构建项目:
```bash
cd ~/ros2_ws/
colcon build --event-handlers console_direct+ --cmake-args -DCMAKE_BUILD_TYPE=Release
. install/setup.bash
cd src/OrbbecSDK_ROS2/
bash .make_deb.sh
```
@@ -0,0 +1,10 @@
开发者指南
======================================================
本章为 SDK 的开发人员和维护人员提供文档。
.. toctree::
:maxdepth: 2
migration_guide.md
building_a_Debian_Package.md
@@ -0,0 +1,196 @@
# 从 main 分支迁移到开源 v2-main 分支
## 引言
最初,奥比中光提供了一个**闭源 SDK — Orbbec SDK v1**,它构成了 [OrbbecSDK ROS2 Wrapper main 分支](https://github.com/orbbec/OrbbecSDK_ROS2/tree/main)的基础。虽然 ROS 封装层本身是开源的,但它依赖于闭源的底层 SDK。这种架构限制了灵活性,阻碍了社区驱动的改进。
随着开发者越来越需要透明性、可维护性和更广泛的设备支持,奥比中光发布了全新的开源 v2-main **— Orbbec SDK_v2** ([GitHub 链接](https://github.com/orbbec/OrbbecSDK/tree/v2-main))。基于此 SDK,[OrbbecSDK ROS2 的开源 v2-main 分支](https://github.com/orbbec/OrbbecSDK_ROS2)现在完全开源,提供了更好的可扩展性,并与奥比中光未来的产品路线图保持一致。
本文档介绍了将 ROS 包从 main 分支(基于 SDK v1)迁移到 v2-main 分支(基于 Orbbec SDK_v2)的动机和好处。它重点介绍了**启动文件、参数、话题和服务**的主要差异,并提供迁移指南帮助开发者顺利过渡。
**注意:** 在以下内容中,**main** 指闭源分支,而 **v2-main** 指开源 v2-main 分支。
## 从 main 迁移到 v2-main 的优势
2024年10月,奥比中光发布了重大更新:**OrbbecSDK ROS2 Wrapper v2**,它完全基于开源的 Orbbec SDK_v2。与传统的 main 分支(SDK v1.x)相比,v2-main 分支(Orbbec SDK_v2.x)提供了更大的灵活性和可扩展性,同时为所有符合 UVC 标准的奥比中光 USB 产品提供全面支持。从 main --> v2-main 的迁移带来以下关键优势:
### **全面的设备支持**
v2-main 分支支持所有符合 UVC 标准的奥比中光 USB 相机,并将成为支持所有新发布设备的主要平台。
### **透明性和可扩展性**
Orbbec SDK_v2 完全开源,允许开发者直接访问底层实现,便于调试、优化和二次开发。相比之下,SDK v1 是闭源的,引入了"黑盒"约束。
### 维护和更新优势
v2-main 分支提供全功能支持,包括新功能开发、性能优化和错误修复。main 分支已进入仅维护模式,只有关键错误可能获得有限更新,不再开发新功能。
### **社区和生态系统支持**
有了开源 SDK,开发者可以直接在 GitHub 或 Gitee 上提交问题和拉取请求,为功能演进做出贡献。这不仅加速了问题解决,还促进了更开放和活跃的奥比中光生态系统。
## main 和 v2-main 分支的比较
### **启动文件差异**
1. 在 v2-main 中,为 Gemini 330 系列添加了新的低功耗启动文件:
- `gemini_330_series_low_cpu.launch.py`
2. v2-main 引入了对 **Gemini 435Le**、**Gemini 345** 和 **Gemini 345Lg** 相机的支持。
3. 由于 **OrbbecSDK_v2 仅支持 UVC 设备**,v2-main 中支持的相机型号范围比 main 略窄。详细信息见下表。
| **相机** | **main** | **v2-main** |
| ---------------------------------- | ------------------------------------ | -------------------------------------------------- |
| Gemini 435Le | 不支持 | gemini435_le.launch.py |
| Gemini 345 | 不支持 | gemini345.launch.py |
| Gemini 345Lg | 不支持 | gemini345_lg.launch.py |
| Gemini 330 系列 | gemini_330_series.launch.py | gemini_330_series.launch.py |
| Gemini 330 低CPU | - | gemini_330_series_low_cpu.launch.py |
| Gemini 210 | gemini210.launch.py | gemini210.launch.py |
| Gemini 2 | gemini2.launch.py | gemini2.launch.py |
| Gemini 2L | gemini2L.launch.py | gemini2.launch.py |
| Gemini 2XL | gemini2XL.launch.py | - |
| Femto Bolt | femto_bolt.launch.py | femto_bolt.launch.py |
| Femto Mega | femto_mega.launch.py | femto_mega.launch.py |
| Femto | femto.launch.py | femto.launch.py |
| Astra 2 | astra2.launch.py | astra2.launch.py |
| Astra | astra.launch.py | astra.launch.py |
| Astra Mini Pro / S Pro | astra_mini_pro.launch.py ... | astra.launch.py |
| 多相机(同步) | multi_camera_synced.launch.py | multi_camera_synced.launch.py |
| 多相机(通用/通用) | multi_camera.launch.py | multi_camera.launch.py 或 orbbec_multicamera.launch.py |
| 单相机通用启动 | ob_camera.launch.py | orbbec_camera.launch.py |
| OpenNI 设备(大白、得雅) | 对应型号独立文件 | 不支持 |
### **参数差异**
**v2-main 中的新参数(main 中不可用)**
| **参数名称** | **main** | **v2-main** | **描述** |
| -------------------------------------- | -------- | ----------- | ---------------------------------------------- |
| upgrade_firmware | - | 已添加 | 固件升级路径 |
| preset_firmware_path | - | 已添加 | 预设固件文件路径 |
| load_config_json_file_path | - | 已添加 | 加载 JSON 配置 |
| export_config_json_file_path | - | 已添加 | 导出 JSON 配置 |
| uvc_backend | - | 已添加 | libuvc / v4l2 后端选择 |
| enable_color_auto_exposure_priority | - | 已添加 | AE 优先级控制 |
| color_flip | - | 已添加 | 彩色图像垂直翻转 |
| color_mirror | - | 已添加 | 彩色图像水平镜像 |
| depth_flip | - | 已添加 | 深度图像垂直翻转 |
| depth_mirror | - | 已添加 | 深度图像水平镜像 |
| left_ir_flip | - | 已添加 | 左红外垂直翻转 |
| left_ir_mirror | - | 已添加 | 左红外水平镜像 |
| right_ir_flip | - | 已添加 | 右红外垂直翻转 |
| right_ir_mirror | - | 已添加 | 右红外水平镜像 |
| enable_left_ir_sequence_id_filter | - | 已添加 | 左红外序列 ID 滤波器 |
| enable_right_ir_sequence_id_filter | - | 已添加 | 右红外序列 ID 滤波器 |
| enable_accel_data_correction | - | 已添加 | 加速度计数据校正 |
| enable_gyro_data_correction | - | 已添加 | 陀螺仪数据校正 |
| enumerate_net_device | - | 已添加 | 自动枚举网络设备 |
| net_device_ip | - | 已添加 | 网络设备 IP 地址 |
| net_device_port | - | 已添加 | 网络设备端口 |
| exposure_range_mode | - | 已添加 | 曝光范围模式:default / ultimate / regular |
| disparity_to_depth_mode | - | 已添加 | 硬件视差到深度转换 |
| ldp_power_level | - | 已添加 | LDP 功率级别 |
| time_sync_period | - | 已添加 | 时间同步周期 |
| gmsl_trigger_fps | - | 已添加 | GMSL 触发帧率 |
| enable_gmsl_trigger | - | 已添加 | GMSL 触发启用 |
| disparity_range_mode | - | 已添加 | 视差范围模式 |
| disparity_search_offset | - | 已添加 | 视差搜索偏移 |
| disparity_offset_config | - | 已添加 | 视差偏移配置 |
| offset_index0 | - | 已添加 | 视差偏移索引 0 |
| offset_index1 | - | 已添加 | 视差偏移索引 1 |
| interleave_ae_mode | - | 已添加 | AE 交错模式 |
| interleave_frame_enable | - | 已添加 | 交错帧启用 |
| interleave_skip_enable | - | 已添加 | 跳过红外帧启用 |
| interleave_skip_index | - | 已添加 | 跳过红外帧索引 |
| hdr_index1_laser_control | - | 已添加 | HDR 激光控制参数 |
| hdr_index1_depth_exposure | - | 已添加 | HDR 深度曝光 |
| hdr_index1_depth_gain | - | 已添加 | HDR 深度增益 |
| hdr_index1_ir_brightness | - | 已添加 | HDR 红外亮度 |
| hdr_index1_ir_ae_max_exposure | - | 已添加 | HDR 红外最大 AE |
| hdr_index0_laser_control | - | 已添加 | HDR 激光控制参数 |
| hdr_index0_depth_exposure | - | 已添加 | HDR 深度曝光 |
| hdr_index0_depth_gain | - | 已添加 | HDR 深度增益 |
| hdr_index0_ir_brightness | - | 已添加 | HDR 红外亮度 |
| hdr_index0_ir_ae_max_exposure | - | 已添加 | HDR 红外最大 AE |
| laser_index1_laser_control | - | 已添加 | 激光交错控制 |
| laser_index1_depth_exposure | - | 已添加 | 激光深度曝光 |
| laser_index1_depth_gain | - | 已添加 | 激光深度增益 |
| laser_index1_ir_brightness | - | 已添加 | 激光红外亮度 |
| laser_index1_ir_ae_max_exposure | - | 已添加 | 激光红外最大 AE |
| laser_index0_laser_control | - | 已添加 | 激光交错控制 |
| laser_index0_depth_exposure | - | 已添加 | 激光深度曝光 |
| laser_index0_depth_gain | - | 已添加 | 激光深度增益 |
| laser_index0_ir_brightness | - | 已添加 | 激光红外亮度 |
| laser_index0_ir_ae_max_exposure | - | 已添加 | 激光红外最大 AE |
| software_trigger_enabled | - | 已添加 | 软件触发启用 |
| enable_ptp_config | - | 已添加 | PTP 配置(Gemini 335Le) |
| align_target_stream | - | 已添加 | 对齐目标流 |
| spatial_fast_filter_radius | - | 已添加 | 快速空间滤波器半径 |
| spatial_moderate_filter_diff_threshold | - | 已添加 | 中等空间滤波器差异阈值 |
| spatial_moderate_filter_magnitude | - | 已添加 | 中等空间滤波器幅度 |
| spatial_moderate_filter_radius | - | 已添加 | 中等空间滤波器半径 |
| color.image_raw.enable_pub_plugins | - | 已添加 | 彩色图像传输插件 |
| depth.image_raw.enable_pub_plugins | - | 已添加 | 深度图像传输插件 |
| left_ir.image_raw.enable_pub_plugins | - | 已添加 | 左红外传输插件 |
| right_ir.image_raw.enable_pub_plugins | - | 已添加 | 右红外传输插件 |
| force_ip_enable | - | 已添加 | 强制 IP 功能 |
| force_ip_mac | - | 已添加 | 强制 IP MAC 地址 |
| force_ip_dhcp | - | 已添加 | DHCP 自动分配 |
| force_ip_address | - | 已添加 | 强制 IP 静态地址 |
| force_ip_subnet_mask | - | 已添加 | 强制 IP 子网掩码 |
| force_ip_gateway | - | 已添加 | 强制 IP 网关 |
**已移除参数(仅 main 有,v2-main 中已移除)**
| **参数** | **描述** |
| ------------------------------------ | ------------------------------------------------------------ |
| enable_3d_reconstruction_mode | 3D 重建模式已弃用 |
| enable_hardware_reset | 硬件重置接口已弃用 |
| enable_hardware_noise_removal_filter | 硬件噪声去除滤波器已弃用 |
| laser_on_off_mode | 旧激光开关接口,由 interleave / laser_index 替换 |
| enable_3d_reconstruction_mode | 3D 重建模式重复;v2-main 中不再使用 |
| device_preset | 部分逻辑迁移到新固件 / 交错参数 |
| enable_trigger_out | 旧软件触发接口由 software_trigger_enabled 替换 |
| retry_on_usb3_detection_failure | 可选;v2-main 中逻辑已调整或移除 |
| enable_color_undistortion | 旧接口逻辑集成到其他地方;v2-main 中仍存在但使用可能已调整 |
### **话题差异**
**v2-main** 在 main 基础上添加了以下话题:
| **话题** | **main** | **v2-main** | **描述** |
| --------------------- | -------- | ----------- | ------------------------------------------------------------ |
| /camera/device_status | - | 已添加 | 发布设备状态(帧率延迟、设备连接状态等) |
### **服务差异**
**v2-main** 在 main 基础上添加了以下服务:
| **服务** | **main** | **v2-main** | **描述** |
| ------------------------- | -------- | ----------- | ------------------------ |
| get_ptp_config | - | 已添加 | 获取 PTP 配置 |
| set_ptp_config | - | 已添加 | 设置 PTP 配置 |
| get_streams_enable | - | 已添加 | 获取每个流的启用状态 |
| set_streams_enable | - | 已添加 | 设置每个流的启用状态 |
| get_user_calib_params | - | 已添加 | 获取用户校准参数 |
| set_user_calib_params | - | 已添加 | 设置用户校准参数 |
| read_customer_data | - | 已添加 | 读取用户存储的自定义数据 |
| write_customer_data | - | 已添加 | 写入用户存储的自定义数据 |
| send_software_trigger | - | 已添加 | 发送软件触发 |
| set_color_ae_roi | - | 已添加 | 设置彩色图像的 AE ROI |
| set_depth_ae_roi | - | 已添加 | 设置深度图像的 AE ROI |
| set_color_flip | - | 已添加 | 设置彩色图像垂直翻转 |
| set_depth_flip | - | 已添加 | 设置深度图像垂直翻转 |
| set_color_rotation | - | 已添加 | 设置彩色图像旋转 |
| set_depth_rotation | - | 已添加 | 设置深度图像旋转 |
| set_left_ir_ae_roi | - | 已添加 | 设置左红外的 AE ROI |
| set_right_ir_ae_roi | - | 已添加 | 设置右红外的 AE ROI |
| set_left_ir_flip | - | 已添加 | 左红外垂直翻转 |
| set_right_ir_flip | - | 已添加 | 右红外垂直翻转 |
| set_left_ir_rotation | - | 已添加 | 左红外旋转 |
| set_right_ir_rotation | - | 已添加 | 右红外旋转 |
| set_reset_timestamp | - | 已添加 | 重置时间戳 |
| set_sync_hosttime | - | 已添加 | 同步主机时间 |
| set_sync_interleaverlaser | - | 已添加 | 交错激光同步 |
| set_filter | - | 已添加 | 设置深度/点云滤波器 |
@@ -0,0 +1,79 @@
# 常见问题
### 意外崩溃
如果相机节点意外崩溃,它将在当前运行目录中生成崩溃日志:`Log/camera_crash_stack_trace_xx.log`。请将此日志发送给支持团队或提交到GitHub issue以获得进一步帮助。
### 多相机无数据流
**电源供应不足**:
- 确保每个相机连接到单独的集线器。
- 使用有源集线器为每个相机提供足够的电力。
**高分辨率**:
- 尝试降低分辨率以解决数据流问题。
**增加usbfs_memory_mb值**:
- 通过运行以下命令将 `usbfs_memory_mb` 值增加到128MB(这是参考值,可根据系统需求调整):
```
echo 128 | sudo tee /sys/module/usbcore/parameters/usbfs_memory_mb
```
- 要使此更改永久生效,请查看[此链接](https://github.com/OpenKinect/libfreenect2/issues/807)。
### 其他故障排除
- 如果遇到其他问题,将 `log_level` 参数设置为 `debug`。这将在运行目录中生成SDK日志文件:`Log/OrbbecSDK.log.txt`。请将此文件提供给支持团队以获得进一步帮助。
- 如果需要固件日志,将 `enable_heartbeat` 设置为 `true` 以激活此功能。
### 为什么有这么多启动文件?
- 不同的相机具有不同的默认分辨率和图像格式。
- 为简化使用,每个相机都有自己的启动文件。
### 多相机连接时如何指定启动某一个相机
如果启动文件未显式指定要使用的设备,在同时连接多台相机时,驱动会默认连接到其中一个(默认设备)。
可以先通过以下命令查看设备序列号:
```bash
ros2 run orbbec_camera list_devices_node
```
然后在启动时显式指定序列号,例如:
```bash
ros2 launch orbbec_camera femto_bolt.launch.py serial_number:=CL8H741005J
```
### 多相机启动或切换流时为什么需要设置延迟?
多相机系统对带宽和设备初始化时序要求较高。如果在同一时间启动或切换多个相机流,可能会引发带宽瞬时拥塞,进而导致设备初始化失败、流启动异常或丢帧等问题。为确保系统稳定性,建议注意以下几点:
- **多相机启动阶段**
在启动多个相机时,建议在每个相机启动之间增加适当的延迟(例如 **2s**),以避免瞬时带宽过载或底层设备初始化冲突。
- **流开关与模式切换阶段**
在调用开关流相关服务(如 `set_streams_enable`、`toggle_depth`、`toggle_color`)时,不建议同时触发多个接口调用,应在各操作之间设置合理的时间间隔(例如 **20 ms**),以保证流状态切换的可靠性。
遵循上述时序控制原则,有助于提升多相机系统在启动和运行过程中的稳定性,减少异常和不可预期行为的发生。
### femto bolt 深度流无数据
该模组运行时依赖 OpenGL 库,若系统未安装或驱动不完整,将导致深度流无数据。请先安装 OpenGL 相关库(以 Ubuntu 为例):
```bash
sudo apt update && sudo apt install -y mesa-utils libgl1-mesa-glx libglu1-mesa
```
安装后可通过以下命令检查 OpenGL 是否可用:
```bash
glxinfo -B
```
@@ -0,0 +1,10 @@
常见问题
======================================================
本章收集了与SDK使用相关的常见问题及解答。
.. toctree::
:maxdepth: 2
FAQ.md
Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

+16
View File
@@ -0,0 +1,16 @@
Camera Devices
=======================================
.. toctree::
:maxdepth: 3
:numbered:
source/1_overview/overview.rst
source/2_installation/installation.rst
source/3_quickstarts/quickstarts.rst
source/4_application_guide/application_guide.rst
source/5_advanced_guide/advanced_guide.rst
source/6_benchmark/benchmark.rst
source/7_developer_guide/developer_guide.rst
source/8_FAQ/FAQ.rst