mirror of
https://github.com/orbbec/OrbbecSDK_ROS2.git
synced 2026-10-12 23:39:50 +08:00
Merge branch 'docs/improve-user-navigation' into v2/develop
This commit is contained in:
@@ -53,6 +53,27 @@ The **OrbbecSDK ROS2 Wrapper** provides seamless integration of Orbbec cameras w
|
|||||||
- For legacy **OpenNI** devices: use the **main** branch
|
- For legacy **OpenNI** devices: use the **main** branch
|
||||||
- For users in China: use the [Gitee repository](https://gitee.com/orbbecdeveloper/OrbbecSDK_ROS2)
|
- For users in China: use the [Gitee repository](https://gitee.com/orbbecdeveloper/OrbbecSDK_ROS2)
|
||||||
|
|
||||||
|
## Start Here
|
||||||
|
|
||||||
|
Detailed usage, parameters, and troubleshooting are maintained on the official
|
||||||
|
[OrbbecSDK ROS2 documentation site](https://orbbec.github.io/OrbbecSDK_ROS2/en/index.html).
|
||||||
|
Use the links below to go directly to the guide for your task.
|
||||||
|
|
||||||
|
| I want to... | Go to... |
|
||||||
|
| --- | --- |
|
||||||
|
| Install the wrapper and configure device permissions | [Installation](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/2_installation/installation.html) |
|
||||||
|
| Launch a camera and view images in RViz2 | [ROS Package QuickStarts](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/3_quickstarts/quickstart.html) |
|
||||||
|
| Check device support, firmware, and the correct launch file | [Supported hardware](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/1_overview/introduction.html) |
|
||||||
|
| Configure launch parameters, topics, services, TF, or point clouds | [Application Guide](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/4_application_guide/application_guide.html) |
|
||||||
|
| Find maintenance, diagnostic, benchmark, or multi-camera tools | [Tool Index](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/6_benchmark/tools.html) |
|
||||||
|
| Use network cameras, GMSL, multi-camera, or advanced modes | [Advanced Guide](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/5_advanced_guide/advanced_guide.html) |
|
||||||
|
| Diagnose a failure or collect logs for support | [Frequently Asked Questions](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/8_FAQ/FAQ.html) |
|
||||||
|
| Migrate an existing project from main (v1.x) | [Migration Guide](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/7_developer_guide/migration_guide.html) |
|
||||||
|
| Use an Orbbec LiDAR | [LiDAR documentation](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/lidar_devices/index.html) |
|
||||||
|
|
||||||
|
Source files for practical launch examples are listed in the
|
||||||
|
[Examples index](./orbbec_camera/examples/).
|
||||||
|
|
||||||
## branch selection
|
## branch selection
|
||||||
|
|
||||||
Here is the device support list of main branch (v1.x) and v2-main branch (v2.x):
|
Here is the device support list of main branch (v1.x) and v2-main branch (v2.x):
|
||||||
@@ -490,17 +511,10 @@ For optimal performance, we strongly recommend updating to the latest firmware v
|
|||||||
All launch files are essentially similar, with the primary difference being the default values of the parameters set
|
All launch files are essentially similar, with the primary difference being the default values of the parameters set
|
||||||
for different models within the same series. Differences in USB standards, such as USB 2.0 versus USB 3.0, may require adjustments to these parameters. If you encounter a startup failure, please carefully review the specification manual. Pay special attention to the resolution settings in the launch file, as well as other parameters, to ensure compatibility and optimal performance.
|
for different models within the same series. Differences in USB standards, such as USB 2.0 versus USB 3.0, may require adjustments to these parameters. If you encounter a startup failure, please carefully review the specification manual. Pay special attention to the resolution settings in the launch file, as well as other parameters, to ensure compatibility and optimal performance.
|
||||||
|
|
||||||
## Tutorial
|
## Related Links
|
||||||
|
|
||||||
please refer to the official [OrbbecSDK ROS2 documentation](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/5_advanced_guide/advanced_guide.html)
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
To explore practical examples and gain insight into how to use the camera in ROS, please navigate to the [Examples](./orbbec_camera/examples/) section for more information.
|
|
||||||
|
|
||||||
## Other useful links
|
|
||||||
|
|
||||||
- [OrbbecSDK ROS2 documentation](https://orbbec.github.io/OrbbecSDK_ROS2/en/index.html)
|
- [OrbbecSDK ROS2 documentation](https://orbbec.github.io/OrbbecSDK_ROS2/en/index.html)
|
||||||
|
- [Examples index](./orbbec_camera/examples/)
|
||||||
- [OrbbecSDK_v2](https://github.com/orbbec/OrbbecSDK_v2/releases)
|
- [OrbbecSDK_v2](https://github.com/orbbec/OrbbecSDK_v2/releases)
|
||||||
- [Gemini 330 depth presets](https://www.orbbec.com/docs/g330-use-depth-presets/)
|
- [Gemini 330 depth presets](https://www.orbbec.com/docs/g330-use-depth-presets/)
|
||||||
|
|
||||||
|
|||||||
+23
-49
@@ -5,46 +5,6 @@
|
|||||||
</a>
|
</a>
|
||||||
<h1><a href="https://github.com/orbbec/OrbbecSDK_ROS2">OrbbecSDK ROS2 Wrapper v2</a></h1>
|
<h1><a href="https://github.com/orbbec/OrbbecSDK_ROS2">OrbbecSDK ROS2 Wrapper v2</a></h1>
|
||||||
|
|
||||||
<!-- Language: -->
|
|
||||||
<p align="center">
|
|
||||||
<a href="./README.MD">English</a> | <a href="./README_CN.MD">中文</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<!-- Labels: -->
|
|
||||||
<!-- First row: -->
|
|
||||||
<a href="https://docs.ros.org/en/foxy/">
|
|
||||||
<img src="https://img.shields.io/badge/ROS-Foxy-f5792a?style=flat-square&logo=ros&logoColor=white" height="20" alt="ROS Foxy">
|
|
||||||
</a>
|
|
||||||
<a href="https://docs.ros.org/en/humble/">
|
|
||||||
<img src="https://img.shields.io/badge/ROS-Humble-f5792a?style=flat-square&logo=ros&logoColor=white" height="20" alt="ROS Humble">
|
|
||||||
</a>
|
|
||||||
<a href="https://docs.ros.org/en/jazzy/">
|
|
||||||
<img src="https://img.shields.io/badge/ROS-Jazzy-f5792a?style=flat-square&logo=ros&logoColor=white" height="20" alt="ROS Jazzy">
|
|
||||||
</a>
|
|
||||||
<a href="https://docs.ros.org/en/lyrical/">
|
|
||||||
<img src="https://img.shields.io/badge/ROS-Lyrical-f5792a?style=flat-square&logo=ros&logoColor=white" height="20" alt="ROS Lyrical">
|
|
||||||
</a>
|
|
||||||
<a href="https://docs.ros.org/en/rolling/">
|
|
||||||
<img src="https://img.shields.io/badge/ROS-Rolling%20(experimental)-e5c07b?style=flat-square&logo=ros&logoColor=white" height="20" alt="ROS Rolling (experimental)">
|
|
||||||
</a>
|
|
||||||
<img src="https://img.shields.io/badge/Ubuntu-20.04-0078d4?style=flat-square&logo=ubuntu&logoColor=white" height="20" alt="Ubuntu 20.04">
|
|
||||||
<img src="https://img.shields.io/badge/Ubuntu-22.04-0078d4?style=flat-square&logo=ubuntu&logoColor=white" height="20" alt="Ubuntu 22.04">
|
|
||||||
<img src="https://img.shields.io/badge/Ubuntu-24.04-0078d4?style=flat-square&logo=ubuntu&logoColor=white" height="20" alt="Ubuntu 24.04">
|
|
||||||
<img src="https://img.shields.io/badge/Ubuntu-26.04-0078d4?style=flat-square&logo=ubuntu&logoColor=white" height="20" alt="Ubuntu 26.04">
|
|
||||||
|
|
||||||
<!-- Second row: -->
|
|
||||||
<br>
|
|
||||||
<a href="https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main">
|
|
||||||
<img src="https://img.shields.io/badge/branch-v2--main-555555?style=flat-square" height="20" alt="branch v2-main">
|
|
||||||
</a>
|
|
||||||
<a href="http://www.apache.org/licenses/LICENSE-2.0">
|
|
||||||
<img src="https://img.shields.io/badge/license-Apache--2.0-6bcf00?style=flat-square" height="20" alt="license Apache-2.0">
|
|
||||||
</a>
|
|
||||||
<a href="https://gitee.com/orbbecdeveloper/OrbbecSDK_ROS2">
|
|
||||||
<img src="https://img.shields.io/badge/Gitee-mirror-c71d23?style=flat-square" height="20" alt="Gitee mirror">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
|
|
||||||
OrbbecSDK ROS2 Wrapper 提供 Orbbec 相机与 ROS 2 环境的无缝集成,支持 **ROS2 Foxy、Humble、Jazzy 和 Lyrical** 发行版,并提供对 **Rolling** 的实验性支持。
|
OrbbecSDK ROS2 Wrapper 提供 Orbbec 相机与 ROS 2 环境的无缝集成,支持 **ROS2 Foxy、Humble、Jazzy 和 Lyrical** 发行版,并提供对 **Rolling** 的实验性支持。
|
||||||
@@ -53,6 +13,26 @@ OrbbecSDK ROS2 Wrapper 提供 Orbbec 相机与 ROS 2 环境的无缝集成,支
|
|||||||
- 对于旧的 **OpenNI** 设备(v2-main 不支持),请使用 **main** 分支。
|
- 对于旧的 **OpenNI** 设备(v2-main 不支持),请使用 **main** 分支。
|
||||||
- 如果您在中国使用,建议使用 [gitee 仓库](https://gitee.com/orbbecdeveloper/OrbbecSDK_ROS2)。
|
- 如果您在中国使用,建议使用 [gitee 仓库](https://gitee.com/orbbecdeveloper/OrbbecSDK_ROS2)。
|
||||||
|
|
||||||
|
## 从这里开始
|
||||||
|
|
||||||
|
完整的使用方法、参数说明和故障排查统一维护在官方
|
||||||
|
[OrbbecSDK ROS2 文档站](https://orbbec.github.io/OrbbecSDK_ROS2/zh/index.html)。
|
||||||
|
请根据您的目标直接进入对应指南。
|
||||||
|
|
||||||
|
| 我想要…… | 请查看…… |
|
||||||
|
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| 安装驱动并配置设备权限 | [安装指南](https://orbbec.github.io/OrbbecSDK_ROS2/zh/source/camera_devices/2_installation/installation.html) |
|
||||||
|
| 启动相机并在 RViz2 中查看图像 | [ROS 包快速入门](https://orbbec.github.io/OrbbecSDK_ROS2/zh/source/camera_devices/3_quickstarts/quickstart.html) |
|
||||||
|
| 确认设备支持、固件版本和启动文件 | [支持的硬件](https://orbbec.github.io/OrbbecSDK_ROS2/zh/source/camera_devices/1_overview/introduction.html) |
|
||||||
|
| 配置启动参数、话题、服务、TF 或点云 | [应用指南](https://orbbec.github.io/OrbbecSDK_ROS2/zh/source/camera_devices/4_application_guide/application_guide.html) |
|
||||||
|
| 查找维护、诊断、性能测试或多相机工具 | [工具索引](https://orbbec.github.io/OrbbecSDK_ROS2/zh/source/camera_devices/6_benchmark/tools.html) |
|
||||||
|
| 使用网络相机、GMSL、多相机或高级模式 | [高级指南](https://orbbec.github.io/OrbbecSDK_ROS2/zh/source/camera_devices/5_advanced_guide/advanced_guide.html) |
|
||||||
|
| 排查故障或收集技术支持所需日志 | [常见问题](https://orbbec.github.io/OrbbecSDK_ROS2/zh/source/camera_devices/8_FAQ/FAQ.html) |
|
||||||
|
| 将现有项目从 main (v1.x) 迁移 | [迁移指南](https://orbbec.github.io/OrbbecSDK_ROS2/zh/source/camera_devices/7_developer_guide/migration_guide.html) |
|
||||||
|
| 使用 Orbbec LiDAR | [LiDAR 文档](https://orbbec.github.io/OrbbecSDK_ROS2/zh/source/lidar_devices/index.html) |
|
||||||
|
|
||||||
|
实用启动示例的源文件可在[示例索引](./orbbec_camera/examples/)中查找。
|
||||||
|
|
||||||
## 分支选择
|
## 分支选择
|
||||||
|
|
||||||
以下是 main 分支 (v1.x) 和 v2-main 分支 (v2.x) 的设备支持列表:
|
以下是 main 分支 (v1.x) 和 v2-main 分支 (v2.x) 的设备支持列表:
|
||||||
@@ -301,6 +281,7 @@ git checkout v2-main
|
|||||||
cd ~/ros2_ws
|
cd ~/ros2_ws
|
||||||
colcon build --event-handlers console_direct+ --cmake-args -DCMAKE_BUILD_TYPE=Release
|
colcon build --event-handlers console_direct+ --cmake-args -DCMAKE_BUILD_TYPE=Release
|
||||||
```
|
```
|
||||||
|
|
||||||
## 注册脚本(必需)
|
## 注册脚本(必需)
|
||||||
|
|
||||||
为了让 Orbbec 相机在 Linux 上被正确识别,请安装 udev 规则。
|
为了让 Orbbec 相机在 Linux 上被正确识别,请安装 udev 规则。
|
||||||
@@ -488,17 +469,10 @@ ros2 service call /camera/get_sdk_version orbbec_camera_msgs/srv/GetString '{}'
|
|||||||
|
|
||||||
所有启动文件基本相似,主要区别在于针对不同型号的默认参数设置。不同的 USB 标准(如 USB 2.0 和 USB 3.0)可能需要调整这些参数。如果遇到启动失败,请仔细查看规格说明书,特别是启动文件中的分辨率设置以及其他参数,以确保兼容性和最佳性能。
|
所有启动文件基本相似,主要区别在于针对不同型号的默认参数设置。不同的 USB 标准(如 USB 2.0 和 USB 3.0)可能需要调整这些参数。如果遇到启动失败,请仔细查看规格说明书,特别是启动文件中的分辨率设置以及其他参数,以确保兼容性和最佳性能。
|
||||||
|
|
||||||
## 教程
|
## 相关链接
|
||||||
|
|
||||||
请参考官方 [OrbbecSDK ROS2 文档](https://orbbec.github.io/OrbbecSDK_ROS2/zh/source/camera_devices/5_advanced_guide/advanced_guide.html)
|
|
||||||
|
|
||||||
## 示例
|
|
||||||
|
|
||||||
要查看更多实践示例并了解如何在 ROS 中使用相机,请参阅 [Examples](./orbbec_camera/examples/) 部分。
|
|
||||||
|
|
||||||
## 其他有用链接
|
|
||||||
|
|
||||||
- [OrbbecSDK ROS2 文档](https://orbbec.github.io/OrbbecSDK_ROS2/zh/index.html)
|
- [OrbbecSDK ROS2 文档](https://orbbec.github.io/OrbbecSDK_ROS2/zh/index.html)
|
||||||
|
- [示例索引](./orbbec_camera/examples/)
|
||||||
- [OrbbecSDK_v2](https://github.com/orbbec/OrbbecSDK_v2/releases)
|
- [OrbbecSDK_v2](https://github.com/orbbec/OrbbecSDK_v2/releases)
|
||||||
- [Gemini 330 深度预设](https://www.orbbec.com/docs/g330-use-depth-presets/)
|
- [Gemini 330 深度预设](https://www.orbbec.com/docs/g330-use-depth-presets/)
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
# Sample launch for OrbbecSDK_ROS2
|
# OrbbecSDK ROS2 Examples
|
||||||
|
|
||||||
These simple examples demonstrate how to easily use the camera with OrbbecSDK_ROS2
|
This directory contains practical launch and tool examples. Full usage,
|
||||||
|
configuration, and troubleshooting are maintained on the official documentation
|
||||||
|
site so that instructions have a single source of truth.
|
||||||
|
|
||||||
## List of Examples:
|
For command-line maintenance and diagnostic utilities, see the official
|
||||||
|
[Tool Index](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/6_benchmark/tools.html).
|
||||||
|
|
||||||
| Name | Description | Experience Level | Document |
|
## Example Index
|
||||||
| :---------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------- |
|
|
||||||
| [Net_camera](./net_camera) | How to use Net camera in OrbbecSDK_ROS2(Only Femto Mega nad Gemini 335Le) | ⭐️ | [Net_camera](https://orbbec.github.io/OrbbecSDK_ROS2/source/5_advanced_guide/configuration/net_camera.html) |
|
| Source | Purpose | Experience Level | Official Guide |
|
||||||
| [Gmsl_camera](./gmsl_camera) | How to use GMSL cameras (Gemini 335Lg, 338Lg, 345Lg, and 305g). | ⭐️ | [Gmsl_camera](https://orbbec.github.io/OrbbecSDK_ROS2/source/5_advanced_guide/multi_camera/gmsl_camera.html) |
|
| :---: | --- | :---: | --- |
|
||||||
| [Benchmark](./benchmark) | The goal of this tool is to benchmark the performance of various OrbbecSDK_ROS2 camera configurations. | ⭐️⭐️ | [Benchmark](https://orbbec.github.io/OrbbecSDK_ROS2/source/5_advanced_guide/performance/benchmark.html) |
|
| [Net camera](./net_camera) | Launch supported Orbbec network cameras. | ⭐️ | [Network camera guide](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/5_advanced_guide/configuration/net_camera.html) |
|
||||||
| [Multi_camera_synced_verification_tool](./multi_camera_synced_verification_tool) | How to verify the synchronization accuracy of multi-camera synchronization. | ⭐️⭐️⭐️ | [Multi_camera_synced_verification_tool](https://orbbec.github.io/OrbbecSDK_ROS2/source/5_advanced_guide/multi_camera/multi_camera_synced_verification_tool.html) |
|
| [GMSL camera](./gmsl_camera) | Launch single, multiple, or synchronized GMSL cameras. | ⭐️ | [GMSL camera guide](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/5_advanced_guide/multi_camera/gmsl_camera.html) |
|
||||||
|
| [Benchmark](./benchmark) | Benchmark the performance of different camera configurations. | ⭐️⭐️ | [Performance benchmark tools](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/6_benchmark/benchmark_tools.html) |
|
||||||
|
| [Multi-camera synchronization verification](./multi_camera_synced_verification_tool) | Verify synchronization accuracy across multiple cameras. | ⭐️⭐️⭐️ | [Synchronization verification guide](https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/5_advanced_guide/multi_camera/multi_camera_synced_verification_tool.html) |
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ usage:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import sys
|
||||||
import rclpy
|
import rclpy
|
||||||
from rclpy.node import Node
|
from rclpy.node import Node
|
||||||
import psutil
|
import psutil
|
||||||
@@ -21,11 +22,24 @@ import os
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from orbbec_camera_msgs.msg import DeviceStatus
|
from orbbec_camera_msgs.msg import DeviceStatus
|
||||||
from sensor_msgs.msg import Image
|
from sensor_msgs.msg import Image
|
||||||
import sys
|
|
||||||
|
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
|
|
||||||
CAMERA_NODE_NAMES = ["component_container", "orbbec_camera_node", "nodelet"]
|
CAMERA_NODE_NAMES = ["component_container", "orbbec_camera_node", "nodelet"]
|
||||||
|
DOCUMENTATION_URL = (
|
||||||
|
"https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/"
|
||||||
|
"6_benchmark/benchmark_tools.html"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentationArgumentParser(argparse.ArgumentParser):
|
||||||
|
def error(self, message):
|
||||||
|
self.print_usage(sys.stderr)
|
||||||
|
self.exit(
|
||||||
|
2,
|
||||||
|
f"{self.prog}: error: {message}\n"
|
||||||
|
f"For usage and troubleshooting, see: {DOCUMENTATION_URL}\n",
|
||||||
|
)
|
||||||
|
|
||||||
# ----------------tool functions----------------
|
# ----------------tool functions----------------
|
||||||
def parse_duration(s):
|
def parse_duration(s):
|
||||||
@@ -471,7 +485,10 @@ class CameraMonitorNode(Node):
|
|||||||
|
|
||||||
|
|
||||||
def main(argv=None):
|
def main(argv=None):
|
||||||
parser = argparse.ArgumentParser()
|
parser = DocumentationArgumentParser(
|
||||||
|
epilog=f"Documentation: {DOCUMENTATION_URL}",
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
)
|
||||||
parser.add_argument("--run_time", type=str, default="10s", help="Total run time for monitoring, e.g., 10s, 5m, 1h.")
|
parser.add_argument("--run_time", type=str, default="10s", help="Total run time for monitoring, e.g., 10s, 5m, 1h.")
|
||||||
parser.add_argument("--csv_file", type=str, default="camera_monitor_log.csv")
|
parser.add_argument("--csv_file", type=str, default="camera_monitor_log.csv")
|
||||||
parser.add_argument("--ideal_fps", type=float, default=0.0, help="Optional ideal frame rate to use for drop detection (overrides reported avg).")
|
parser.add_argument("--ideal_fps", type=float, default=0.0, help="Optional ideal frame rate to use for drop detection (overrides reported avg).")
|
||||||
@@ -494,4 +511,8 @@ def main(argv=None):
|
|||||||
node.destroy_node()
|
node.destroy_node()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
try:
|
||||||
|
main()
|
||||||
|
except Exception:
|
||||||
|
print(f"For usage and troubleshooting, see: {DOCUMENTATION_URL}", file=sys.stderr)
|
||||||
|
raise
|
||||||
|
|||||||
@@ -23,6 +23,23 @@ from statistics import mean
|
|||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
import importlib
|
import importlib
|
||||||
import csv
|
import csv
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
DOCUMENTATION_URL = (
|
||||||
|
"https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/"
|
||||||
|
"6_benchmark/benchmark_tools.html"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DocumentationArgumentParser(argparse.ArgumentParser):
|
||||||
|
def error(self, message):
|
||||||
|
self.print_usage(sys.stderr)
|
||||||
|
self.exit(
|
||||||
|
2,
|
||||||
|
f"{self.prog}: error: {message}\n"
|
||||||
|
f"For usage and troubleshooting, see: {DOCUMENTATION_URL}\n",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ServiceBenchmark:
|
class ServiceBenchmark:
|
||||||
@@ -180,7 +197,10 @@ class BenchmarkRunner:
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser()
|
parser = DocumentationArgumentParser(
|
||||||
|
epilog=f"Documentation: {DOCUMENTATION_URL}",
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
)
|
||||||
parser.add_argument("--service", help="Service name")
|
parser.add_argument("--service", help="Service name")
|
||||||
parser.add_argument("--count", type=int, default=10, help="Number of calls")
|
parser.add_argument("--count", type=int, default=10, help="Number of calls")
|
||||||
parser.add_argument("--yaml_file", help="YAML config file for batch testing")
|
parser.add_argument("--yaml_file", help="YAML config file for batch testing")
|
||||||
@@ -207,4 +227,8 @@ def main():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
try:
|
||||||
|
main()
|
||||||
|
except Exception:
|
||||||
|
print(f"For usage and troubleshooting, see: {DOCUMENTATION_URL}", file=sys.stderr)
|
||||||
|
raise
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
#include "orbbec_camera/utils.h"
|
#include "orbbec_camera/utils.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
constexpr char kDocumentationUrl[] =
|
||||||
|
"https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/6_benchmark/"
|
||||||
|
"firmware_update_tool.html";
|
||||||
|
|
||||||
constexpr int kProgressLogBucketPercent = 25;
|
constexpr int kProgressLogBucketPercent = 25;
|
||||||
constexpr int kFirmwareLogDrainDelaySec = 5;
|
constexpr int kFirmwareLogDrainDelaySec = 5;
|
||||||
@@ -131,7 +134,9 @@ void printUsage() {
|
|||||||
<< " 2) If multiple devices are connected, specify target by serial/usb/ip to avoid wrong "
|
<< " 2) If multiple devices are connected, specify target by serial/usb/ip to avoid wrong "
|
||||||
"updates.\n"
|
"updates.\n"
|
||||||
<< " 3) Repeating --serial_number or passing comma-separated values enables sequential "
|
<< " 3) Repeating --serial_number or passing comma-separated values enables sequential "
|
||||||
"batch update.\n";
|
"batch update.\n\n"
|
||||||
|
<< "Documentation:\n"
|
||||||
|
<< " " << kDocumentationUrl << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
|
bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
|
||||||
@@ -862,6 +867,7 @@ int main(int argc, char **argv) {
|
|||||||
RCLCPP_ERROR(logger, "Unknown error");
|
RCLCPP_ERROR(logger, "Unknown error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCLCPP_ERROR(logger, "For usage and troubleshooting, see: %s", kDocumentationUrl);
|
||||||
rclcpp::shutdown();
|
rclcpp::shutdown();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ using namespace ob;
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr int kFirmwareLogDrainDelaySec = 5;
|
constexpr int kFirmwareLogDrainDelaySec = 5;
|
||||||
|
constexpr char kDocumentationUrl[] =
|
||||||
|
"https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/6_benchmark/"
|
||||||
|
"network_config_tools.html";
|
||||||
|
|
||||||
void waitForFirmwareLogDrain(const rclcpp::Logger &logger) {
|
void waitForFirmwareLogDrain(const rclcpp::Logger &logger) {
|
||||||
RCLCPP_INFO(logger, "Waiting %d seconds to keep firmware log alive...",
|
RCLCPP_INFO(logger, "Waiting %d seconds to keep firmware log alive...",
|
||||||
@@ -25,6 +28,12 @@ bool isSdkLogEnabled(const std::string &log_level) {
|
|||||||
return orbbec_camera::obLogSeverityFromString(log_level) != OBLogSeverity::OB_LOG_SEVERITY_OFF;
|
return orbbec_camera::obLogSeverityFromString(log_level) != OBLogSeverity::OB_LOG_SEVERITY_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int reportFailure(const rclcpp::Logger &logger) {
|
||||||
|
RCLCPP_ERROR(logger, "For usage and troubleshooting, see: %s", kDocumentationUrl);
|
||||||
|
rclcpp::shutdown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct CliArgs {
|
struct CliArgs {
|
||||||
@@ -177,7 +186,9 @@ void printHelp() {
|
|||||||
<< " Debug: ros2 run orbbec_camera ip_config_tool -- \\\n"
|
<< " Debug: ros2 run orbbec_camera ip_config_tool -- \\\n"
|
||||||
<< " set_ip --current_ip 192.168.1.10 --enable_dhcp true "
|
<< " set_ip --current_ip 192.168.1.10 --enable_dhcp true "
|
||||||
"--enable_persistent_ip false \\\n"
|
"--enable_persistent_ip false \\\n"
|
||||||
<< " --sdk_log_level debug\n";
|
<< " --sdk_log_level debug\n\n"
|
||||||
|
<< "Documentation:\n"
|
||||||
|
<< " " << kDocumentationUrl << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
|
bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
|
||||||
@@ -461,18 +472,15 @@ int main(int argc, char **argv) {
|
|||||||
uint8_t gateway[4] = {0};
|
uint8_t gateway[4] = {0};
|
||||||
if (args.persistent_ip && !parseIpString(args.new_ip, address)) {
|
if (args.persistent_ip && !parseIpString(args.new_ip, address)) {
|
||||||
RCLCPP_ERROR(logger, "Invalid new_ip format: %s", args.new_ip.c_str());
|
RCLCPP_ERROR(logger, "Invalid new_ip format: %s", args.new_ip.c_str());
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
if (args.persistent_ip && !parseIpString(args.mask, mask)) {
|
if (args.persistent_ip && !parseIpString(args.mask, mask)) {
|
||||||
RCLCPP_ERROR(logger, "Invalid mask format: %s", args.mask.c_str());
|
RCLCPP_ERROR(logger, "Invalid mask format: %s", args.mask.c_str());
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
if (args.persistent_ip && !parseIpString(args.gateway, gateway)) {
|
if (args.persistent_ip && !parseIpString(args.gateway, gateway)) {
|
||||||
RCLCPP_ERROR(logger, "Invalid gateway format: %s", args.gateway.c_str());
|
RCLCPP_ERROR(logger, "Invalid gateway format: %s", args.gateway.c_str());
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OBNetIpConfigV2 ip_config_v2{};
|
OBNetIpConfigV2 ip_config_v2{};
|
||||||
@@ -521,8 +529,7 @@ int main(int argc, char **argv) {
|
|||||||
"Legacy IP config (1041) supports mutually exclusive DHCP and persistent "
|
"Legacy IP config (1041) supports mutually exclusive DHCP and persistent "
|
||||||
"IP only. Use --enable_dhcp true --enable_persistent_ip false or "
|
"IP only. Use --enable_dhcp true --enable_persistent_ip false or "
|
||||||
"--enable_dhcp false --enable_persistent_ip true.");
|
"--enable_dhcp false --enable_persistent_ip true.");
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
ip_config.dhcp = args.dhcp ? 1 : 0;
|
ip_config.dhcp = args.dhcp ? 1 : 0;
|
||||||
uint8_t address[4] = {0};
|
uint8_t address[4] = {0};
|
||||||
@@ -530,18 +537,15 @@ int main(int argc, char **argv) {
|
|||||||
uint8_t gateway[4] = {0};
|
uint8_t gateway[4] = {0};
|
||||||
if (args.persistent_ip && !parseIpString(args.new_ip, address)) {
|
if (args.persistent_ip && !parseIpString(args.new_ip, address)) {
|
||||||
RCLCPP_ERROR(logger, "Invalid new_ip format: %s", args.new_ip.c_str());
|
RCLCPP_ERROR(logger, "Invalid new_ip format: %s", args.new_ip.c_str());
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
if (args.persistent_ip && !parseIpString(args.mask, mask)) {
|
if (args.persistent_ip && !parseIpString(args.mask, mask)) {
|
||||||
RCLCPP_ERROR(logger, "Invalid mask format: %s", args.mask.c_str());
|
RCLCPP_ERROR(logger, "Invalid mask format: %s", args.mask.c_str());
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
if (args.persistent_ip && !parseIpString(args.gateway, gateway)) {
|
if (args.persistent_ip && !parseIpString(args.gateway, gateway)) {
|
||||||
RCLCPP_ERROR(logger, "Invalid gateway format: %s", args.gateway.c_str());
|
RCLCPP_ERROR(logger, "Invalid gateway format: %s", args.gateway.c_str());
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
if (args.persistent_ip) {
|
if (args.persistent_ip) {
|
||||||
std::memcpy(ip_config.address, address, sizeof(address));
|
std::memcpy(ip_config.address, address, sizeof(address));
|
||||||
@@ -579,18 +583,15 @@ int main(int argc, char **argv) {
|
|||||||
if (!args.dhcp) {
|
if (!args.dhcp) {
|
||||||
if (!parseIpString(args.new_ip, ip_config.address)) {
|
if (!parseIpString(args.new_ip, ip_config.address)) {
|
||||||
RCLCPP_ERROR(logger, "Invalid new_ip format: %s", args.new_ip.c_str());
|
RCLCPP_ERROR(logger, "Invalid new_ip format: %s", args.new_ip.c_str());
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
if (!parseIpString(args.mask, ip_config.mask)) {
|
if (!parseIpString(args.mask, ip_config.mask)) {
|
||||||
RCLCPP_ERROR(logger, "Invalid mask format: %s", args.mask.c_str());
|
RCLCPP_ERROR(logger, "Invalid mask format: %s", args.mask.c_str());
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
if (!parseIpString(args.gateway, ip_config.gateway)) {
|
if (!parseIpString(args.gateway, ip_config.gateway)) {
|
||||||
RCLCPP_ERROR(logger, "Invalid gateway format: %s", args.gateway.c_str());
|
RCLCPP_ERROR(logger, "Invalid gateway format: %s", args.gateway.c_str());
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,8 +608,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RCLCPP_ERROR(logger, "Force-ip failed (SDK returned false).");
|
RCLCPP_ERROR(logger, "Force-ip failed (SDK returned false).");
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -621,16 +621,14 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (!device->isPropertySupported(OB_PROP_DHCP_ASSIGN_IP_TIMEOUT_INT, OB_PERMISSION_WRITE)) {
|
if (!device->isPropertySupported(OB_PROP_DHCP_ASSIGN_IP_TIMEOUT_INT, OB_PERMISSION_WRITE)) {
|
||||||
RCLCPP_ERROR(logger, "Current device or firmware does not support DHCP assign IP timeout");
|
RCLCPP_ERROR(logger, "Current device or firmware does not support DHCP assign IP timeout");
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto range = device->getIntPropertyRange(OB_PROP_DHCP_ASSIGN_IP_TIMEOUT_INT);
|
auto range = device->getIntPropertyRange(OB_PROP_DHCP_ASSIGN_IP_TIMEOUT_INT);
|
||||||
if (args.dhcp_assign_ip_timeout < range.min || args.dhcp_assign_ip_timeout > range.max) {
|
if (args.dhcp_assign_ip_timeout < range.min || args.dhcp_assign_ip_timeout > range.max) {
|
||||||
RCLCPP_ERROR(logger, "Timeout %d is out of range [%d, %d]", args.dhcp_assign_ip_timeout,
|
RCLCPP_ERROR(logger, "Timeout %d is out of range [%d, %d]", args.dhcp_assign_ip_timeout,
|
||||||
range.min, range.max);
|
range.min, range.max);
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
device->setIntProperty(OB_PROP_DHCP_ASSIGN_IP_TIMEOUT_INT, args.dhcp_assign_ip_timeout);
|
device->setIntProperty(OB_PROP_DHCP_ASSIGN_IP_TIMEOUT_INT, args.dhcp_assign_ip_timeout);
|
||||||
@@ -645,16 +643,13 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
} catch (ob::Error &e) {
|
} catch (ob::Error &e) {
|
||||||
RCLCPP_ERROR(logger, "ip_config_tool: %s", orbbec_camera::formatObErrorWithStatus(e).c_str());
|
RCLCPP_ERROR(logger, "ip_config_tool: %s", orbbec_camera::formatObErrorWithStatus(e).c_str());
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
RCLCPP_ERROR(logger, "ip_config_tool: %s", e.what());
|
RCLCPP_ERROR(logger, "ip_config_tool: %s", e.what());
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
RCLCPP_ERROR(logger, "ip_config_tool: unknown error");
|
RCLCPP_ERROR(logger, "ip_config_tool: unknown error");
|
||||||
rclcpp::shutdown();
|
return reportFailure(logger);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rclcpp::shutdown();
|
rclcpp::shutdown();
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ using namespace orbbec_camera;
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr int kFirmwareLogDrainDelaySec = 5;
|
constexpr int kFirmwareLogDrainDelaySec = 5;
|
||||||
|
constexpr char kDocumentationUrl[] =
|
||||||
|
"https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/6_benchmark/"
|
||||||
|
"device_query_tools.html";
|
||||||
|
|
||||||
struct CliArgs {
|
struct CliArgs {
|
||||||
bool help = false;
|
bool help = false;
|
||||||
@@ -33,7 +36,9 @@ void printUsage() {
|
|||||||
"(default: off).\n"
|
"(default: off).\n"
|
||||||
<< " -h, --help Show this help message.\n"
|
<< " -h, --help Show this help message.\n"
|
||||||
<< "Examples:\n"
|
<< "Examples:\n"
|
||||||
<< " ros2 run orbbec_camera list_camera_profile_mode_node -- --sdk_log_level debug\n";
|
<< " ros2 run orbbec_camera list_camera_profile_mode_node -- --sdk_log_level debug\n\n"
|
||||||
|
<< "Documentation:\n"
|
||||||
|
<< " " << kDocumentationUrl << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseArgs(int argc, char** argv, CliArgs& args, std::string& error) {
|
bool parseArgs(int argc, char** argv, CliArgs& args, std::string& error) {
|
||||||
@@ -116,7 +121,8 @@ std::shared_ptr<ob::Device> initializeDevice(const std::string& serial_number) {
|
|||||||
auto context = std::make_shared<ob::Context>();
|
auto context = std::make_shared<ob::Context>();
|
||||||
auto device_list = context->queryDeviceList();
|
auto device_list = context->queryDeviceList();
|
||||||
if (!device_list || device_list->getCount() == 0) {
|
if (!device_list || device_list->getCount() == 0) {
|
||||||
std::cout << "No device found" << std::endl;
|
std::cout << "No device found\nFor usage and troubleshooting, see: " << kDocumentationUrl
|
||||||
|
<< std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,9 @@
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr int kFirmwareLogDrainDelaySec = 5;
|
constexpr int kFirmwareLogDrainDelaySec = 5;
|
||||||
|
constexpr char kDocumentationUrl[] =
|
||||||
|
"https://orbbec.github.io/OrbbecSDK_ROS2/en/source/camera_devices/6_benchmark/"
|
||||||
|
"device_query_tools.html";
|
||||||
|
|
||||||
struct CliArgs {
|
struct CliArgs {
|
||||||
bool help = false;
|
bool help = false;
|
||||||
@@ -42,7 +45,9 @@ void printUsage() {
|
|||||||
<< " --sdk_log_level LEVEL SDK file log level: debug/info/warn/error/fatal/off "
|
<< " --sdk_log_level LEVEL SDK file log level: debug/info/warn/error/fatal/off "
|
||||||
"(default: off).\n\n"
|
"(default: off).\n\n"
|
||||||
<< "Examples:\n"
|
<< "Examples:\n"
|
||||||
<< " ros2 run orbbec_camera list_devices_node -- --sdk_log_level debug\n";
|
<< " ros2 run orbbec_camera list_devices_node -- --sdk_log_level debug\n\n"
|
||||||
|
<< "Documentation:\n"
|
||||||
|
<< " " << kDocumentationUrl << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
|
bool parseArgs(int argc, char **argv, CliArgs &args, std::string &error) {
|
||||||
@@ -339,10 +344,16 @@ int main(int argc, char **argv) {
|
|||||||
} catch (ob::Error &e) {
|
} catch (ob::Error &e) {
|
||||||
RCLCPP_ERROR_STREAM(rclcpp::get_logger("list_device_node"),
|
RCLCPP_ERROR_STREAM(rclcpp::get_logger("list_device_node"),
|
||||||
orbbec_camera::formatObErrorWithStatus(e));
|
orbbec_camera::formatObErrorWithStatus(e));
|
||||||
|
RCLCPP_ERROR_STREAM(rclcpp::get_logger("list_device_node"),
|
||||||
|
"For usage and troubleshooting, see: " << kDocumentationUrl);
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
RCLCPP_ERROR_STREAM(rclcpp::get_logger("list_device_node"), e.what());
|
RCLCPP_ERROR_STREAM(rclcpp::get_logger("list_device_node"), e.what());
|
||||||
|
RCLCPP_ERROR_STREAM(rclcpp::get_logger("list_device_node"),
|
||||||
|
"For usage and troubleshooting, see: " << kDocumentationUrl);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
RCLCPP_ERROR_STREAM(rclcpp::get_logger("list_device_node"), "unknown error");
|
RCLCPP_ERROR_STREAM(rclcpp::get_logger("list_device_node"), "unknown error");
|
||||||
|
RCLCPP_ERROR_STREAM(rclcpp::get_logger("list_device_node"),
|
||||||
|
"For usage and troubleshooting, see: " << kDocumentationUrl);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user