commit ad1cb49f7db0eb98f9dc8787278636129d5f712d Author: winf Date: Mon Sep 15 06:27:21 2025 +0000 deploy: orbbec/OrbbecSDK_ROS2@2460077f7c6d63a3f53f0e97d121b5adc1f36ca5 diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 00000000..297b1544 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file records the configuration used when building these files. When it is not found, a full rebuild will be done. +config: adc71f2003683a11b4d207e0b3b8cf8e +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.doctrees/README.doctree b/.doctrees/README.doctree new file mode 100644 index 00000000..9f1c4ce0 Binary files /dev/null and b/.doctrees/README.doctree differ diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle new file mode 100644 index 00000000..f056dca1 Binary files /dev/null and b/.doctrees/environment.pickle differ diff --git a/.doctrees/index.doctree b/.doctrees/index.doctree new file mode 100644 index 00000000..aae01938 Binary files /dev/null and b/.doctrees/index.doctree differ diff --git a/.doctrees/source/1_overview/introduction.doctree b/.doctrees/source/1_overview/introduction.doctree new file mode 100644 index 00000000..46a66bb3 Binary files /dev/null and b/.doctrees/source/1_overview/introduction.doctree differ diff --git a/.doctrees/source/1_overview/orbbecsdk_overview.doctree b/.doctrees/source/1_overview/orbbecsdk_overview.doctree new file mode 100644 index 00000000..50cdd388 Binary files /dev/null and b/.doctrees/source/1_overview/orbbecsdk_overview.doctree differ diff --git a/.doctrees/source/1_overview/overview.doctree b/.doctrees/source/1_overview/overview.doctree new file mode 100644 index 00000000..3fd4c64e Binary files /dev/null and b/.doctrees/source/1_overview/overview.doctree differ diff --git a/.doctrees/source/2_installation/build_the_package.doctree b/.doctrees/source/2_installation/build_the_package.doctree new file mode 100644 index 00000000..c7c5427e Binary files /dev/null and b/.doctrees/source/2_installation/build_the_package.doctree differ diff --git a/.doctrees/source/2_installation/installation.doctree b/.doctrees/source/2_installation/installation.doctree new file mode 100644 index 00000000..3017a0ab Binary files /dev/null and b/.doctrees/source/2_installation/installation.doctree differ diff --git a/.doctrees/source/2_installation/registration_script.doctree b/.doctrees/source/2_installation/registration_script.doctree new file mode 100644 index 00000000..afa9f881 Binary files /dev/null and b/.doctrees/source/2_installation/registration_script.doctree differ diff --git a/.doctrees/source/3_quickstarts/quickstart.doctree b/.doctrees/source/3_quickstarts/quickstart.doctree new file mode 100644 index 00000000..a94450ad Binary files /dev/null and b/.doctrees/source/3_quickstarts/quickstart.doctree differ diff --git a/.doctrees/source/3_quickstarts/quickstarts.doctree b/.doctrees/source/3_quickstarts/quickstarts.doctree new file mode 100644 index 00000000..01e707ec Binary files /dev/null and b/.doctrees/source/3_quickstarts/quickstarts.doctree differ diff --git a/.doctrees/source/4_application_guide/application_guide.doctree b/.doctrees/source/4_application_guide/application_guide.doctree new file mode 100644 index 00000000..fd55056a Binary files /dev/null and b/.doctrees/source/4_application_guide/application_guide.doctree differ diff --git a/.doctrees/source/4_application_guide/launch_parameters.doctree b/.doctrees/source/4_application_guide/launch_parameters.doctree new file mode 100644 index 00000000..2e76319e Binary files /dev/null and b/.doctrees/source/4_application_guide/launch_parameters.doctree differ diff --git a/.doctrees/source/4_application_guide/services.doctree b/.doctrees/source/4_application_guide/services.doctree new file mode 100644 index 00000000..6e68ed9d Binary files /dev/null and b/.doctrees/source/4_application_guide/services.doctree differ diff --git a/.doctrees/source/4_application_guide/topics.doctree b/.doctrees/source/4_application_guide/topics.doctree new file mode 100644 index 00000000..440cfe4c Binary files /dev/null and b/.doctrees/source/4_application_guide/topics.doctree differ diff --git a/.doctrees/source/5_advanced_guide/advanced_guide.doctree b/.doctrees/source/5_advanced_guide/advanced_guide.doctree new file mode 100644 index 00000000..1f9e69b9 Binary files /dev/null and b/.doctrees/source/5_advanced_guide/advanced_guide.doctree differ diff --git a/.doctrees/source/5_advanced_guide/align_depth_color.doctree b/.doctrees/source/5_advanced_guide/align_depth_color.doctree new file mode 100644 index 00000000..19116302 Binary files /dev/null and b/.doctrees/source/5_advanced_guide/align_depth_color.doctree differ diff --git a/.doctrees/source/5_advanced_guide/benchmark.doctree b/.doctrees/source/5_advanced_guide/benchmark.doctree new file mode 100644 index 00000000..e7a3712f Binary files /dev/null and b/.doctrees/source/5_advanced_guide/benchmark.doctree differ diff --git a/.doctrees/source/5_advanced_guide/building_a_Debian_Package.doctree b/.doctrees/source/5_advanced_guide/building_a_Debian_Package.doctree new file mode 100644 index 00000000..5024f2bb Binary files /dev/null and b/.doctrees/source/5_advanced_guide/building_a_Debian_Package.doctree differ diff --git a/.doctrees/source/5_advanced_guide/configuration_of_depth_NFOV_and_WFOV_modes.doctree b/.doctrees/source/5_advanced_guide/configuration_of_depth_NFOV_and_WFOV_modes.doctree new file mode 100644 index 00000000..a27927eb Binary files /dev/null and b/.doctrees/source/5_advanced_guide/configuration_of_depth_NFOV_and_WFOV_modes.doctree differ diff --git a/.doctrees/source/5_advanced_guide/depth_work_mode_switch.doctree b/.doctrees/source/5_advanced_guide/depth_work_mode_switch.doctree new file mode 100644 index 00000000..2efeca65 Binary files /dev/null and b/.doctrees/source/5_advanced_guide/depth_work_mode_switch.doctree differ diff --git a/.doctrees/source/5_advanced_guide/disparity_search_offset.doctree b/.doctrees/source/5_advanced_guide/disparity_search_offset.doctree new file mode 100644 index 00000000..1a526b1a Binary files /dev/null and b/.doctrees/source/5_advanced_guide/disparity_search_offset.doctree differ diff --git a/.doctrees/source/5_advanced_guide/efficient_intra_process_communication.doctree b/.doctrees/source/5_advanced_guide/efficient_intra_process_communication.doctree new file mode 100644 index 00000000..907f2745 Binary files /dev/null and b/.doctrees/source/5_advanced_guide/efficient_intra_process_communication.doctree differ diff --git a/.doctrees/source/5_advanced_guide/fastdds_tuning.doctree b/.doctrees/source/5_advanced_guide/fastdds_tuning.doctree new file mode 100644 index 00000000..7789f2ee Binary files /dev/null and b/.doctrees/source/5_advanced_guide/fastdds_tuning.doctree differ diff --git a/.doctrees/source/5_advanced_guide/gmsl_camera.doctree b/.doctrees/source/5_advanced_guide/gmsl_camera.doctree new file mode 100644 index 00000000..4cf3a41c Binary files /dev/null and b/.doctrees/source/5_advanced_guide/gmsl_camera.doctree differ diff --git a/.doctrees/source/5_advanced_guide/interleave_ae_mode.doctree b/.doctrees/source/5_advanced_guide/interleave_ae_mode.doctree new file mode 100644 index 00000000..fc0b3e5a Binary files /dev/null and b/.doctrees/source/5_advanced_guide/interleave_ae_mode.doctree differ diff --git a/.doctrees/source/5_advanced_guide/lower_cpu_usage.doctree b/.doctrees/source/5_advanced_guide/lower_cpu_usage.doctree new file mode 100644 index 00000000..47a8900f Binary files /dev/null and b/.doctrees/source/5_advanced_guide/lower_cpu_usage.doctree differ diff --git a/.doctrees/source/5_advanced_guide/multi_camera.doctree b/.doctrees/source/5_advanced_guide/multi_camera.doctree new file mode 100644 index 00000000..ce4577b1 Binary files /dev/null and b/.doctrees/source/5_advanced_guide/multi_camera.doctree differ diff --git a/.doctrees/source/5_advanced_guide/multi_camera_synced.doctree b/.doctrees/source/5_advanced_guide/multi_camera_synced.doctree new file mode 100644 index 00000000..dee4fd7f Binary files /dev/null and b/.doctrees/source/5_advanced_guide/multi_camera_synced.doctree differ diff --git a/.doctrees/source/5_advanced_guide/multi_camera_synced_verification_tool.doctree b/.doctrees/source/5_advanced_guide/multi_camera_synced_verification_tool.doctree new file mode 100644 index 00000000..e446665d Binary files /dev/null and b/.doctrees/source/5_advanced_guide/multi_camera_synced_verification_tool.doctree differ diff --git a/.doctrees/source/5_advanced_guide/net_camera.doctree b/.doctrees/source/5_advanced_guide/net_camera.doctree new file mode 100644 index 00000000..dedf8935 Binary files /dev/null and b/.doctrees/source/5_advanced_guide/net_camera.doctree differ diff --git a/.doctrees/source/5_advanced_guide/point_cloud.doctree b/.doctrees/source/5_advanced_guide/point_cloud.doctree new file mode 100644 index 00000000..12d7825e Binary files /dev/null and b/.doctrees/source/5_advanced_guide/point_cloud.doctree differ diff --git a/.doctrees/source/5_advanced_guide/predefined_presets.doctree b/.doctrees/source/5_advanced_guide/predefined_presets.doctree new file mode 100644 index 00000000..94fbb71a Binary files /dev/null and b/.doctrees/source/5_advanced_guide/predefined_presets.doctree differ diff --git a/.doctrees/source/6_FAQ/FAQ.doctree b/.doctrees/source/6_FAQ/FAQ.doctree new file mode 100644 index 00000000..48a210e5 Binary files /dev/null and b/.doctrees/source/6_FAQ/FAQ.doctree differ diff --git a/.doctrees/source/license.doctree b/.doctrees/source/license.doctree new file mode 100644 index 00000000..4e9e008e Binary files /dev/null and b/.doctrees/source/license.doctree differ diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/README.html b/README.html new file mode 100644 index 00000000..9f3da1bd --- /dev/null +++ b/README.html @@ -0,0 +1,393 @@ + + + + + + + + + Docs应用文档 — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Docs应用文档

+
+

编译环境

+
cd docs
+pip install -r requirements.txt
+
+
+
+
+

编译

+
make clean
+make html
+
+
+
+
+

编译结果

+

用浏览器打开 _build/html/index.html查看编译结果

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/_images/Default_Flowchart.png b/_images/Default_Flowchart.png new file mode 100644 index 00000000..3190cc1e Binary files /dev/null and b/_images/Default_Flowchart.png differ diff --git a/_images/Soft_Architecture.png b/_images/Soft_Architecture.png new file mode 100644 index 00000000..91ad16c8 Binary files /dev/null and b/_images/Soft_Architecture.png differ diff --git a/_images/Standard_Flowchart.png b/_images/Standard_Flowchart.png new file mode 100644 index 00000000..9e8b397d Binary files /dev/null and b/_images/Standard_Flowchart.png differ diff --git a/_images/image3.png b/_images/image3.png new file mode 100644 index 00000000..58322895 Binary files /dev/null and b/_images/image3.png differ diff --git a/_images/image4.jpg b/_images/image4.jpg new file mode 100644 index 00000000..b204c845 Binary files /dev/null and b/_images/image4.jpg differ diff --git a/_images/image5.jpg b/_images/image5.jpg new file mode 100644 index 00000000..03b65e9b Binary files /dev/null and b/_images/image5.jpg differ diff --git a/_images/image6.jpg b/_images/image6.jpg new file mode 100644 index 00000000..29b1aad8 Binary files /dev/null and b/_images/image6.jpg differ diff --git a/_images/interleave_ae0.jpeg b/_images/interleave_ae0.jpeg new file mode 100644 index 00000000..7655e93f Binary files /dev/null and b/_images/interleave_ae0.jpeg differ diff --git a/_images/interleave_ae1.jpeg b/_images/interleave_ae1.jpeg new file mode 100644 index 00000000..ac4a770d Binary files /dev/null and b/_images/interleave_ae1.jpeg differ diff --git a/_images/multi_camera_synced1.png b/_images/multi_camera_synced1.png new file mode 100644 index 00000000..87f2cbd5 Binary files /dev/null and b/_images/multi_camera_synced1.png differ diff --git a/_images/multi_camera_synced2.png b/_images/multi_camera_synced2.png new file mode 100644 index 00000000..9c883b87 Binary files /dev/null and b/_images/multi_camera_synced2.png differ diff --git a/_images/search_offset0.png b/_images/search_offset0.png new file mode 100644 index 00000000..27237215 Binary files /dev/null and b/_images/search_offset0.png differ diff --git a/_sources/README.md.txt b/_sources/README.md.txt new file mode 100644 index 00000000..b9535954 --- /dev/null +++ b/_sources/README.md.txt @@ -0,0 +1,19 @@ +# Docs应用文档 + +## 编译环境 + +```bash +cd docs +pip install -r requirements.txt +``` + +## 编译 + +```bash +make clean +make html +``` + +## 编译结果 + +用浏览器打开 `_build/html/index.html`查看编译结果 diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 00000000..d6d711e2 --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,18 @@ +.. OrbbecSDK V2 ROS2 Wrapper documentation master file, created by + sphinx-quickstart on Tue Sep 9 21:55:16 2025. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +OrbbecSDK V2 ROS2 Wrapper documentation +======================================= + +.. 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_FAQ/FAQ.rst diff --git a/_sources/source/1_overview/introduction.md.txt b/_sources/source/1_overview/introduction.md.txt new file mode 100644 index 00000000..80b3367f --- /dev/null +++ b/_sources/source/1_overview/introduction.md.txt @@ -0,0 +1,39 @@ +# Introduction + +OrbbecSDK ROS2 Wrapper provides seamless integration of Orbbec cameras with ROS 2 environment. It supports ROS2 Foxy, Humble, and Jazzy distributions. + +With a major update in October 2024, we release the [OrbbecSDK ROS2 Wrapper v2](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main) connected to the open source [OrbbecSDK v2](https://github.com/orbbec/OrbbecSDK_v2/releases) with enhanced flexibility and extensibility. This update ensures compatibility with all Orbbec USB products adhering to UVC standard. However, it no longer supports Orbbec's traditional OpenNI protocol devices. We strongly encourage you to use the v2-main branch if your device is supported. + +If you are a user in China, it is recommended to use [gitee Repo](https://gitee.com/orbbecdeveloper/OrbbecSDK_ROS2). + +## Support Hardware Products + +The following devices are supported by the OrbbecSDK ROS2 Wrapper v2-main branch. More devices support will be added in the near future. If you can not find your device in the table below, try the [main](https://github.com/orbbec/OrbbecSDK_ROS2) branch. + +For optimal performance, we strongly recommend updating to the latest firmware version. This ensures that you benefit from the most recent enhancements and bug fixes. + +| Product List | Minimal Firmware Version | **Launch File** | +| :------------- | :----------------------- | :-------------------------- | +| Gemini 435Le | 1.2.04 | gemini435_le.launch.py | +| Gemini 335 | 1.2.20 | gemini_330_series.launch.py | +| Gemini 336 | 1.2.20 | gemini_330_series.launch.py | +| Gemini 335L | 1.2.20 | gemini_330_series.launch.py | +| Gemini 336L | 1.2.20 | gemini_330_series.launch.py | +| Gemini 335Lg | 1.3.46 | gemini_330_series.launch.py | +| Gemini 335Le | 1.5.31 | gemini_330_series.launch.py | +| Gemini 330 | 1.2.20 | gemini_330_series.launch.py | +| Gemini 330L | 1.2.20 | gemini_330_series.launch.py | +| Gemini 2 | 1.4.92 | gemini2.launch.py | +| Gemini 2 L | 1.4.53 | gemini2L.launch.py | +| Femto Bolt | 1.1.2 | femto_bolt.launch.py | +| Femto Mega | 1.3.0 | femto_mega.launch.py | +| Astra 2 | 2.8.20 | astra2.launch.py | +| Astra Mini Pro | 2.0.01 | astra.launch.py | + +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. + +## Support Platforms + +- Linux x64: tested on Ubuntu 22.04 +- Linux ARM64: tested on NVIDIA Jetson AGX Orin , NVIDIA Jetson Orin NX , NVIDIA Jetson Orin Nano , NVIDIA Jetson AGX Xavier , NVIDIA Jetson Xavier NX diff --git a/_sources/source/1_overview/orbbecsdk_overview.md.txt b/_sources/source/1_overview/orbbecsdk_overview.md.txt new file mode 100644 index 00000000..81fd64a4 --- /dev/null +++ b/_sources/source/1_overview/orbbecsdk_overview.md.txt @@ -0,0 +1,116 @@ +# Orbbec SDK Overview + +This section introduces the Orbbec SDK in C++. Its architecture and concepts are consistent with those of the Python Wrapper. + +## Terms + +| ID | Name | Explain | +| --- | --- | --- | +| 1 | USB | Universal Serial Bus | +| 2 | UVC | USB Video Class | +| 3 | Firmware | Firmware of 3D camera | +| 4 | Disparity | Disparity is to observe the direction difference of the same target from two points with a certain distance. | +| 5 | D2D (Disparity to depth) | Disparity to depth is an image processing technique used to convert disparity information into depth information. | +| 6 | Hardware D2D | Disparity to depth is implemented internally in the device, without occupying the computational power of the host computer. | +| 7 | Software D2D | Disparity to depth, implemented in Orbbec SDK | +| 8 | Depth point cloud | Depth point cloud, the coordinates of points in a three-dimensional world coordinate system, can be transformed into a point cloud using the intrinsic parameters of a Depth camera. | +| 9 | RGBD point cloud | Point cloud with overlaid RGB information | +| 10 | D2C | The translation of "Depth to Color" is a feature that performs per-pixel geometric transformation on a depth image. Its result is aligning the depth image with its corresponding color image through the D2C transformation, allowing us to locate the depth information of a color pixel by using the same image coordinate position of that pixel in the transformed depth image. After the D2C transformation, we generate a depth image of the same size as the target color image, where the image content represents depth data in the coordinate system of the color camera. In other words, it reconstructs a depth image "captured" using the origin and dimensions of the color camera, where each pixel matches the corresponding pixel coordinates of the color camera. | +| 11 | Hardware D2C | Hardware D2C refers to the functionality of performing Depth to Color transformation within the camera itself, with the camera directly outputting the result of the D2C transformation. | +| 12 | Software D2C | Performing D2C computation on the host computer side using an SDK. | +| 13 | Frame aggregation (FrameSet) | Combining Depth, IR, and Color frames into a Frameset and invoking it through a pipeline. | +| 14 | C2D | The translation of "Color to Depth" is a feature that performs per-pixel geometric transformation on a color image. Its result is aligning the color image with its corresponding depth image through the C2D transformation. | +| 15 | MetaData | Frame metadata is a set of parameters (or attributes) that provide a snapshot of the sensor configuration and/or system state present during the frame’s generation. | +| 16 | HDR | High Dynamic Range (HDR) imaging allows imaging systems to capture images in extremely dark and bright scenes alike. We propose a software solution running on the host CPU to implement this feature. It utilizes data from two consecutive frames and directly synthesizes these two depth images, thereby enhances the dynamic range of 16-bit depth images. | +| 17 | LDP | Laser close-range protection | + +## Orbbec SDK v2 Architecture Overview + +![OrbbecSDK v2 Soft Architecture](../image/Soft_Architecture.png) + +- Application + +OrbbecViewer, Sample, and User Application Implementation. + +- Interfaces and Encapsulation Layer + +OrbbecSDK Interface Encapsulation and Wrapper Encapsulation. + +- High-level Layer + +HighLevel encapsulates the core business components and provides interfaces to the outside using a pipeline. + +- Basic business layer + +The realization of the core business logic framework. + +- Platform abstraction layer + +Cross-platform components abstract operating system differences and provide a unified access interface. + + +- Platform implementation layer + +The driver implementation of each platform. + +## SDK Concept Overview + +- Context + + +Context which provides a set of settings includes settings such as device state change callbacks, log levels, and more. The Context can access multiple devices. + +- Device + + +One actual hardware device corresponds to one Device object, which is used to obtain relevant information of the device and control its attributes. + +- Pipeline + + +The HighLevel corresponding object encapsulates the interface for quick access to the SDK. It has simple functions that allow users to quickly get started and use the SDK. + +- Config + + +Provides configuration for enabling data streams, alignment modes, and frame aggregation modes, It is used to control the behavior of the data output. + +- StreamProfile + + +Stream configuration that defines parameters such as resolution, frame rate, and encoding format, It also provides management of camera parameters. + +- Frame + + +Represents a frame of data in the Stream, and also contains relevant information about that frame of data, such as timestamp, type, etc. + +- Filter + + +It mainly refers to some algorithmic processing modules for the composite stream FrameSet, such as point cloud algorithm processing. + +- Record + + +Recording functionality that captures data streams and saves them as files for later analysis or playback. + +- Playback + + +Playback functionality that plays recorded files and supports control over playback speed and other related parameters. + + +## SDK Programming Model + +Here is the C++ programming logic flow chart. Python's programming logic is the same as it. + +- Standard Flowchart: + +![image.png](../image/Standard_Flowchart.png) + +The standard flowchart demonstrates how to create a device from the device list, set and get parameters, and apply post-processing filters. + +- Flowchart using default configuration (stream acquisition based on the default settings in OrbbecSDKConfig.xml): + +![image](../image/Default_Flowchart.png) diff --git a/_sources/source/1_overview/overview.rst.txt b/_sources/source/1_overview/overview.rst.txt new file mode 100644 index 00000000..a79b9f4c --- /dev/null +++ b/_sources/source/1_overview/overview.rst.txt @@ -0,0 +1,11 @@ +Overview +====================================================== + +This chapter provides an overview of the Orbbec SDK, including supported products, main features, and architecture. + +.. toctree:: + :maxdepth: 2 + + introduction.md + orbbecsdk_overview.md + diff --git a/_sources/source/2_installation/build_the_package.md.txt b/_sources/source/2_installation/build_the_package.md.txt new file mode 100644 index 00000000..324469db --- /dev/null +++ b/_sources/source/2_installation/build_the_package.md.txt @@ -0,0 +1,49 @@ +### Build from Source + +#### Environment + +Install ROS 2 according to the official guide: + +* [ROS 2 installation (Ubuntu)](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html) + +Enable ROS 2 auto-completion: + +```bash +eval "$(register-python-argcomplete3 ros2)" +eval "$(register-python-argcomplete3 colcon)" +``` + +Create a `colcon` workspace: + +```bash +mkdir -p ~/ros2_ws/src +``` + +#### Linux ROS2 Wrapper Compilation + +Clone source and checkout `v2-main` branch: + +```bash +cd ~/ros2_ws/src +git clone https://github.com/orbbec/OrbbecSDK_ROS2.git +cd OrbbecSDK_ROS2 +git checkout v2-main +``` + +Install dependencies: + +```bash +sudo apt install libgflags-dev nlohmann-json3-dev libgoogle-glog-dev libgoogle-glog0v5 libssl-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-backward-ros libdw-dev +``` + +Build: + +```bash +cd ~/ros2_ws +colcon build --event-handlers console_direct+ --cmake-args -DCMAKE_BUILD_TYPE=Release +``` + diff --git a/_sources/source/2_installation/installation.rst.txt b/_sources/source/2_installation/installation.rst.txt new file mode 100644 index 00000000..a603dbd1 --- /dev/null +++ b/_sources/source/2_installation/installation.rst.txt @@ -0,0 +1,11 @@ +Installation +====================================================== + +This chapter explains how to install the Orbbec ROS2 Python SDK, including building from source, installing dependencies, and using registration scripts. + +.. toctree:: + :maxdepth: 2 + + build_the_package.md + registration_script.md + diff --git a/_sources/source/2_installation/registration_script.md.txt b/_sources/source/2_installation/registration_script.md.txt new file mode 100644 index 00000000..f7da5f01 --- /dev/null +++ b/_sources/source/2_installation/registration_script.md.txt @@ -0,0 +1,13 @@ +## Registration script (required) + +To allow the Orbbec cameras to be recognized correctly on Linux, install the udev rules: + +```bash +cd ~/ros2_ws/src/OrbbecSDK_ROS2/orbbec_camera/scripts +sudo bash install_udev_rules.sh +sudo udevadm control --reload-rules && sudo udevadm trigger +``` + +This step is **mandatory** for Linux users. + +`Notes:` If this script is not executed, open the device will fail due to permission issues. You need to run the sample with sudo (administrator privileges). diff --git a/_sources/source/3_quickstarts/quickstart.md.txt b/_sources/source/3_quickstarts/quickstart.md.txt new file mode 100644 index 00000000..722fba59 --- /dev/null +++ b/_sources/source/3_quickstarts/quickstart.md.txt @@ -0,0 +1,92 @@ +## QuickStarts + +### Introduction + +This section provides a quick start to using the Orbbec ROS 2 wrapper. +You will learn how to: + +* Launch a camera node. +* Visualize depth/color streams in **RViz2**. +* Interact with topics and services using **ROS 2 CLI tools**. + +--- + +### Build your First Camera Application + +#### Step 1: Source ROS 2 and Workspace + +Make sure ROS 2 and your workspace environment are sourced: + +```bash +source /opt/ros/$ROS_DISTRO/setup.bash +source ~/ros2_ws/install/setup.bash +``` + +#### Step 2: Launch the Camera Node + +- On terminal 1 + +```bash +. ./install/setup.bash +ros2 run orbbec_camera list_devices_node #Check if the camera is connected +ros2 launch orbbec_camera gemini_330_series.launch.py # Or other launch file, see below table +``` + +If you have multiple cameras connected, you can specify the **serial number**: + +```bash +ros2 launch orbbec_camera gemini_330_series.launch.py serial_number:= +``` + +#### Step 3: Visualize in RViz2 + +Launch RViz2 and load the default config: + +- On terminal 2 + +```bash +rviz2 +``` + +* Add an **Image** display, set topic to `/camera/color/image_raw`. +* Add another **Image** display for `/camera/depth/image_raw`. +* Optionally, add a **PointCloud2** display for `/camera/depth/points`. + +You should now see the color stream, depth stream, and 3D point cloud in RViz2. + +--- + +### Sample Features + +After the node is running, try some ROS 2 CLI commands: + +#### List available topics / services/ parameters + +```bash +ros2 topic list +ros2 service list +ros2 param list +``` + +#### Echo a topic + +View depth camera data: + +```bash +ros2 topic echo /camera/depth/camera_info +``` + +#### Call a service + +For example, get device Information: + +```bash +ros2 service call /camera/get_device_info orbbec_camera_msgs/srv/GetDeviceInfo '{}' +``` + +#### Record with rosbag2 + +```bash +ros2 bag record /camera/color/image_raw /camera/depth/image_raw +``` + diff --git a/_sources/source/3_quickstarts/quickstarts.rst.txt b/_sources/source/3_quickstarts/quickstarts.rst.txt new file mode 100644 index 00000000..d245876e --- /dev/null +++ b/_sources/source/3_quickstarts/quickstarts.rst.txt @@ -0,0 +1,10 @@ +Quickstarts +====================================================== + +This chapter provides quick start guides for the SDK, allowing users to run basic example programs quickly. + +.. toctree:: + :maxdepth: 2 + + quickstart.md + diff --git a/_sources/source/4_application_guide/application_guide.rst.txt b/_sources/source/4_application_guide/application_guide.rst.txt new file mode 100644 index 00000000..ca9ddb30 --- /dev/null +++ b/_sources/source/4_application_guide/application_guide.rst.txt @@ -0,0 +1,12 @@ +Application Guide +====================================================== + +This chapter introduces application development with the SDK, including launch parameter configuration, ROS2 services, and topics usage. + +.. toctree:: + :maxdepth: 2 + + launch_parameters.md + services.md + topics.md + diff --git a/_sources/source/4_application_guide/launch_parameters.md.txt b/_sources/source/4_application_guide/launch_parameters.md.txt new file mode 100644 index 00000000..2514b56f --- /dev/null +++ b/_sources/source/4_application_guide/launch_parameters.md.txt @@ -0,0 +1,264 @@ +# Launch parameters + +> If you are not sure how to set the parameters, you can connect the orbbec camera and open the [OrbbecViewer](https://github.com/orbbec/OrbbecSDK/releases). + +The following are the launch parameters available: + +### Core & Stream Configuration + +* **`camera_name`** + * Start the node namespace. + +* **`depth_registration`** + * Enable alignment of the depth frame to the color frame. This field is required when the `enable_colored_point_cloud` is set to `true`. + +* **`serial_number`** + * The serial number of the camera. This is required when multiple cameras are used. + +* **`usb_port`** + * The USB port of the camera. This is required when multiple cameras are used. + +* **`device_num`** + * The number of devices. This must be filled in if multiple cameras are required. + +* **`[color|depth|left_ir|right_ir|ir]_[width|height|fps|format]`** + * The resolution and frame rate of the sensor stream. + +* **`[color|depth|left_ir|right_ir|ir]_rotation`** + * Set stream image rotation. + * The possible values are `0`, `90`, `180`, `270`. + +* **`[color|depth|left_ir|right_ir|ir]_flip`** + * Enable the stream image flip. + +* **`[color|depth|left_ir|right_ir|ir]_mirror`** + * Enable the stream image mirror. + +* **`enable_point_cloud`** + * Enable the point cloud. + +* **`enable_colored_point_cloud`** + * Enable the RGB point cloud. + +* **`cloud_frame_id`** + * Modify the `frame_id` name within the ros message. + +* **`ordered_pc`** + * Enable filtering of invalid point clouds. + +* **`align_mode`** + * The alignment mode to be used. Options are `HW` for hardware alignment and `SW` for software alignment. + +* **`align_target_stream`** + * Set align target stream mode. + * The possible values are `COLOR`, `DEPTH`. + * `COLOR`: Align depth to color. + * `DEPTH`: Align color to depth. + +* **`point_cloud_qos`, `[stream]_qos`, `[stream]_camera_info_qos`** + * ROS 2 Message Quality of Service (QoS) settings. The possible values are `SYSTEM_DEFAULT`, `DEFAULT`, `PARAMETER_EVENTS`, `SERVICES_DEFAULT`, `PARAMETERS`, `SENSOR_DATA` and are case-insensitive. These correspond to `rmw_qos_profile_system_default`, `rmw_qos_profile_default`, `rmw_qos_profile_parameter_events`, `rmw_qos_profile_services_default`, `rmw_qos_profile_parameters`, and `SENSOR_DATA`, respectively. + +### Sensor Controls + +#### Color Stream +* **`enable_color_auto_exposure`** + * Enable the Color auto exposure. +* **`enable_color_auto_exposure_priority`** + * Enable the Color auto exposure priority. +* **`color_exposure`** + * Set the Color exposure. +* **`color_gain`** + * Set the Color gain. +* **`enable_color_auto_white_balance`** + * Enable the Color auto white balance. +* **`color_white_balance`** + * Set the Color white balance. +* **`color_ae_max_exposure`** + * Set the maximum exposure value for Color auto exposure. +* **`color_brightness`**, **`color_sharpness`**, **`color_gamma`**, **`color_saturation`**, **`color_contrast`**, **`color_hue`** + * Set the Color brightness, sharpness, gamma, saturation, contrast, and hue. +* **`enable_color_backlight_compensation`** + * Enable the Color backlight compensation. +* **`color_powerline_freq`** + * Set the power line freq. The possible values are `disable`, `50hz`, `60hz`, `auto`. +* **`enable_color_decimation_filter`** / **`color_decimation_filter_scale`** + * Enable the Color decimation filter and set its scale. +* **`color_ae_roi_[left|right|top|bottom]`** + * Set Color auto exposure ROI. + +#### Depth Stream +* **`enable_depth_auto_exposure_priority`** + * Enable the Depth auto exposure priority. +* **`mean_intensity_set_point`** + * Set the target mean intensity of the Depth image. For example: `mean_intensity_set_point:=100`. + > **Note:** This replaces the deprecated `depth_brightness`, which is still supported for backward compatibility. +* **`enable_depth_scale`** + * Enable the depth scale. +* **`depth_precision`** + * The depth precision should be in the format `1mm`. The default value is `1mm`. +* **`depth_ae_roi_[left|right|top|bottom]`** + * Set Depth auto exposure ROI. + +#### IR Stream +* **`enable_ir_auto_exposure`** + * Enable the IR auto exposure. +* **`ir_exposure`** / **`ir_gain`** + * Set the IR exposure and gain. +* **`ir_ae_max_exposure`** + * Set the maximum exposure value for IR auto exposure. +* **`ir_brightness`** + * Set the IR brightness. + +#### Laser / LDP +* **`enable_laser`** + * Enable the laser. The default value is `true`. +* **`laser_energy_level`** + * Set the laser energy level. +* **`enable_ldp`** / **`ldp_power_level`** + * Enable the LDP and set its power level. + +### Device, Sync & Advanced Features + +#### Multi-Camera Synchronization +* **`sync_mode`** + * Set sync mode. The default value is `standalone`. +* **`depth_delay_us`** / **`color_delay_us`** + * The delay time (microseconds) of the depth/color image capture after receiving the capture command or trigger signal. +* **`trigger2image_delay_us`** + * The delay time (microseconds) of the image capture after receiving the capture command or trigger signal. Us +* **`trigger_out_delay_us`** + * The delay time (microseconds) of the trigger signal output after receiving the capture command or trigger signal. +* **`trigger_out_enabled`** + * Enable the trigger out signal. +* **`software_trigger_enabled`** / **`software_trigger_period`** + * Enable the software trigger out signal / set the software trigger period in ms. +* **`frames_per_trigger`** + * The frame number of each stream after each trigger in triggering mode. + +> Used for [multi camera synced](../5_advanced_guide/multi_camera_synced.md). + +#### Network Cameras +* **`enumerate_net_device`** + * Enable automatically enumerate network devices. +* **`net_device_ip`** / **`net_device_port`** + * Set net device's IP address and port (Usually `8090`). + +> Used for [net camera](../5_advanced_guide/net_camera.md). + +#### Device-Specific +* **`device_preset`** + * The default value is `Default`. Only the G330 series is supported. For more information, refer to the [G330 documentation](https://www.orbbec.com/docs/g330-use-depth-presets/). The value should be one of the preset names listed [in the table](../5_advanced_guide/predefined_presets.md). +* **`enable_gmsl_trigger`** / **`gmsl_trigger_fps`** + * Enable the gmsl trigger out signal / set gmsl trigger fps. Used for [gmsl camera](../5_advanced_guide/gmsl_camera.md). + +#### Disparity +* **`disparity_to_depth_mode`** + * `HW`: use hardware disparity to depth conversion. `SW`: use software disparity to depth conversion. +* **`disparity_range_mode`**, **`disparity_search_offset`**, **`disparity_offset_config`** + * Parameters for disparity search offset. Used for [disparity search offset](../5_advanced_guide/disparity_search_offset.md). + +#### Interleave AE Mode +* **`interleave_ae_mode`** + * Set `laser` or `hdr` interleave. +* **`interleave_frame_enable`**, **`interleave_skip_enable`**, **`interleave_skip_index`** + * Parameters to control interleave frame mode. +* **`[hdr|laser]_index[0|1]_[...]`** + * In interleave frame mode, set the 0th and 1st frame parameters of hdr or laser interleaving frames. +* *All interleave parameters are used for [interleave ae mode](../5_advanced_guide/interleave_ae_mode.md).* + +### Basic & General Parameters + +#### Firmware & Backend +* **`upgrade_firmware`** + * The input parameter is the firmware path. +* **`preset_firmware_path`** + * The input parameter is the preset firmware path. If multiple paths are input, each path needs to be separated by `,` and a maximum of 3 firmware paths can be input. +* **`uvc_backend`** + * Optional values: `v4l2`, `libuvc`. +* **`connection_delay`** + * The delay time in milliseconds for reopening the device. Some devices, such as Astra mini, require a longer time to initialize and reopening the device immediately can cause firmware crashes when hot plugging. +* **`retry_on_usb3_detection_failure`** + * If the camera is connected to a USB 2.0 port and is not detected, the system will attempt to reset the camera up to three times. It is recommended to set this parameter to `false` when using a USB 2.0 connection to avoid unnecessary resets. + +#### TF, Extrinsics & Calibration +* **`publish_tf`** / **`tf_publish_rate`** + * Enable the TF publish and set its publication rate. +* **`enable_publish_extrinsic`** + * Enable the extrinsics publish. +* **`ir_info_url`** / **`color_info_url`** + * Set URL of the IR/color camera info. +* **`enable_color_undistortion`** + * Enable the Color undistortion. + +#### Time Synchronization +* **`enable_sync_host_time`** + * Enable synchronization of the host time with the camera time. The default value is `true`. If using global time, set to `false`. +* **`time_domain`** + * Select timestamp type: `device`, `global`, and `system`. +* **`time_sync_period`** + * Interval (in seconds) for synchronizing the camera time with the host system. + > **Note**: This parameter only needs to be set when **`enable_sync_host_time = true`** and **`time_domain = device`**. +* **`enable_ptp_config`** + * Enable PTP time synchronization. Only for Gemini 335Le. Requires `enable_sync_host_time` to be `false`. +* **`enable_frame_sync`** + * Enable the frame synchronization. + +#### Logging & Diagnostics +* **`log_level`** + * SDK log level. Default is `info`. Optional values: `debug`, `info`, `warn`, `error`, `fatal`. +* **`diagnostic_period`** + * Diagnostic period in seconds. +* **`enable_heartbeat`** + * Enable the heartbeat function. Default is `false`. If `true`, the camera node will send heartbeat signals to the firmware. + +#### Miscellaneous +* **`config_file_path`** + * The path to the YAML configuration file. Default is `""`. If not specified, default parameters from the launch file will be used. +* **`frame_aggregate_mode`** + * Set frame aggregate output mode. Optional values: `full_frame`, `color_frame`, `ANY`, `disable`. +* **`enable_d2c_viewer`** + * Publishes the D2C overlay image (for testing only). + +### IMU + +* **`enable_accel`** / **`enable_gyro`** + * Enable the Accelerometer/gyroscope and output its info topic data. +* **`enable_sync_output_accel_gyro`** + * Enable the sync `accel_gyro`, and output IMU topic real-time data. +* **`accel_rate`** / **`gyro_rate`** + * The frequency of the accelerometer/gyroscope. Values range from `1.5625hz` to `32khz`. +* **`accel_range`** / **`gyro_range`** + * The range of the accelerometer (`2g`, `4g`, `8g`, `16g`) and gyroscope (`16dps` to `2000dps`). +* **`enable_accel_data_correction`** / **`enable_gyro_data_correction`** + * Enable data correction for the accelerometer/gyroscope. +* **`linear_accel_cov`** / **`angular_vel_cov`** + * Covariance of the linear acceleration and angular velocity. + +### Depth Filters + +* **`enable_decimation_filter`** + * Enable the Depth decimation filter. Set with `decimation_filter_scale`. +* **`enable_hdr_merge`** + * Enable the Depth hdr merge filter. Set with `hdr_merge_exposure_1`, etc. +* **`enable_sequence_id_filter`** + * Enable the Depth sequence id filter. Set with `sequence_id_filter_id`. +* **`enable_threshold_filter`** + * Enable the Depth threshold filter. Set with `threshold_filter_max`, `threshold_filter_min`. +* **`enable_hardware_noise_removal_filter`** + * Enable the Depth hardware noise removal filter. +* **`enable_noise_removal_filter`** + * Enable the Depth software noise removal filter. Set with `noise_removal_filter_min_diff`, etc. +* **`enable_spatial_filter`** + * Enable the Depth spatial filter. Set with `spatial_filter_alpha`, etc. +* **`enable_temporal_filter`** + * Enable the Depth temporal filter. Set with `temporal_filter_diff_threshold`, etc. +* **`enable_hole_filling_filter`** + * Enable the Depth hole filling filter. Set with `hole_filling_filter_mode`. +* **`enable_spatial_fast_filter`** + * Enable the Depth spatial fast filter. Set with `spatial_fast_filter_radius`. +* **`enable_spatial_moderate_filter`** + * Enable the Depth spatial moderate filter. Set with `spatial_moderate_filter_diff_threshold`, etc. + +--- + +> **_IMPORTANT_**: Please carefully read the instructions regarding software filtering settings at [this link](https://www.orbbec.com/docs/g330-use-depth-post-processing-blocks/). If you are uncertain, do not modify these settings. diff --git a/_sources/source/4_application_guide/services.md.txt b/_sources/source/4_application_guide/services.md.txt new file mode 100644 index 00000000..a2cc7f34 --- /dev/null +++ b/_sources/source/4_application_guide/services.md.txt @@ -0,0 +1,209 @@ +# All available services for camera control + +> **Note:** Services related to a specific stream (e.g., `/camera/set_color_*`) are only available if that stream is enabled in the launch file (e.g., `enable_color:=true`). + +### Stream Control + +#### Color Stream +* `/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: [Left, Right, Top, Bottom] + ros2 service call /camera/set_color_ae_roi orbbec_camera_msgs/srv/SetArrays '{data_param: [0,1279,0,719]}' + ``` + +#### Depth Stream +* `/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: [Left, Right, Top, Bottom] + ros2 service call /camera/set_depth_ae_roi orbbec_camera_msgs/srv/SetArrays '{data_param: [0,847,0,479]}' + ``` + +#### IR Stream +* `/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_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/switch_ir` + ```bash + ros2 service call /camera/switch_ir orbbec_camera_msgs/srv/SetString '{data: left}' + ``` + +#### All Streams +* `/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}' + ``` + +### Sensor & Emitter Control + +* `/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/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_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}' + ``` + +### Device Information & Management + +* `/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 '{}' + ``` + +### Synchronization & Triggering + +* `/camera/send_software_trigger` + ```bash + ros2 service call /camera/send_software_trigger std_srvs/srv/SetBool '{data: true}' + ```* `/camera/set_reset_timestamp` + ```bash + # Only available when time_domain param is set to device + ros2 service call /camera/set_reset_timestamp std_srvs/srv/SetBool '{data: true}' + ``` +* `/camera/set_sync_interleaverlaser` + ```bash + # Only available if interleave_ae_mode is 'laser' and interleave_frame_enable is true + ros2 service call /camera/set_sync_interleaverlaser orbbec_camera_msgs/srv/SetInt32 '{data: 0}' + ``` + +### Depth Filter Configuration + +* `/camera/set_filter` + ```bash + # Set DecimationFilter + ros2 service call /camera/set_filter orbbec_camera_msgs/srv/SetFilter '{filter_name: DecimationFilter, filter_enable: false, filter_param: [5]}' + # Set 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]}' + ``` + +### Data Capture & Calibration Management + +* `/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 '{}' + ``` + +> **Note**: The following services are currently supported only on the 435Le module. Each service can store only one set of data or string at a time. + +* `/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 '{}' + ``` diff --git a/_sources/source/4_application_guide/topics.md.txt b/_sources/source/4_application_guide/topics.md.txt new file mode 100644 index 00000000..b9fbd3d9 --- /dev/null +++ b/_sources/source/4_application_guide/topics.md.txt @@ -0,0 +1,67 @@ +# Available Topics + +Topics are organized by stream and function. By default, all topics are published under the `/camera` namespace, which can be changed with the `camera_name` launch parameter. + +> **Note:** Topics for a specific stream (e.g., `/camera/color/...`) are only published if their corresponding launch parameter (e.g., `enable_color`) is set to `true`. + +### Image Streams + +These topics provide the raw image data and corresponding calibration information for each enabled camera stream. The pattern is consistent for `color`, `depth`, `ir`, `left_ir`, and `right_ir` streams. + +* `/camera/color/image_raw` + * Raw image data from the color stream. +* `/camera/color/camera_info` + * Camera calibration data and metadata for the color stream. +* `/camera/color/metadata` + * Low-level metadata from the color stream firmware. + +* `/camera/depth/image_raw` + * Raw image data from the depth stream. +* `/camera/depth/camera_info` + * Camera calibration data and metadata for the depth stream. +* `/camera/depth/metadata` + * Low-level metadata from the depth stream firmware. + +* `/camera/ir/image_raw` + * Raw image data from the infrared (IR) stream. +* `/camera/ir/camera_info` + * Camera calibration data and metadata for the IR stream. +* `/camera/ir/metadata` + * Low-level metadata from the IR stream firmware. + +### Point Cloud Topics + +* `/camera/depth/points` + * Point cloud data generated from the depth stream. + * **Condition:** Published only when `enable_point_cloud` is `true`. + +* `/camera/depth_registered/points` + * Colored point cloud data, where the depth points are registered to the color image frame. + * **Condition:** Published only when `enable_colored_point_cloud` is `true`. + +### IMU Topics + +The Inertial Measurement Unit (IMU) topics provide accelerometer and gyroscope data. Their behavior depends on the synchronization setting. + +* `/camera/accel/sample` + * Individual accelerometer data stream. + * **Condition:** Published when `enable_accel` is `true` AND `enable_sync_output_accel_gyro` is `false`. + +* `/camera/gyro/sample` + * Individual gyroscope data stream. + * **Condition:** Published when `enable_gyro` is `true` AND `enable_sync_output_accel_gyro` is `false`. + +* `/camera/gyro_accel/sample` + * Synchronized data stream containing both accelerometer and gyroscope data in a single message. + * **Condition:** Published when `enable_sync_output_accel_gyro` is `true`. + +### Device Status & Diagnostics + +* `/camera/device_status` + * Reports the current status of the camera device. + +* `/camera/depth_filter_status` + * Reports the status of the depth sensor's post-processing filters. + +* `/diagnostics` + * Publishes diagnostic information about the camera node. Currently, this includes the device temperature. diff --git a/_sources/source/5_advanced_guide/advanced_guide.rst.txt b/_sources/source/5_advanced_guide/advanced_guide.rst.txt new file mode 100644 index 00000000..1555edf2 --- /dev/null +++ b/_sources/source/5_advanced_guide/advanced_guide.rst.txt @@ -0,0 +1,26 @@ +Advanced Guide +====================================================== + +This chapter covers advanced features of the SDK, including multi-camera synchronization, depth-color alignment, performance tuning, and more. + +.. toctree:: + :maxdepth: 2 + + align_depth_color.md + benchmark.md + building_a_Debian_Package.md + configuration_of_depth_NFOV_and_WFOV_modes.md + depth_work_mode_switch.md + disparity_search_offset.md + efficient_intra_process_communication.md + fastdds_tuning.md + gmsl_camera.md + interleave_ae_mode.md + lower_cpu_usage.md + multi_camera.md + multi_camera_synced.md + multi_camera_synced_verification_tool.md + net_camera.md + point_cloud.md + predefined_presets.md + diff --git a/_sources/source/5_advanced_guide/align_depth_color.md.txt b/_sources/source/5_advanced_guide/align_depth_color.md.txt new file mode 100644 index 00000000..673458f1 --- /dev/null +++ b/_sources/source/5_advanced_guide/align_depth_color.md.txt @@ -0,0 +1,39 @@ +## Aligning Depth to Color in ROS 2 + +This section explains how to align depth images with color images to create an overlay image using ROS 2. This is particularly useful for applications requiring synchronized visual information from different sensor modalities. + +### Commands to Align and View Depth and Color Images + +1. **Basic Depth to Color Alignment:** + + To simply align the depth image to the color image, use the following command: + + ```bash + ros2 launch orbbec_camera gemini_330_series.launch.py depth_registration:=true + ``` + + This command activates the depth registration feature without opening a viewer. +2. **Viewing Depth to Color Overlay:** + + If you wish to view the depth to color overlay, you need to enable the viewer by using the command below: + + ```bash + ros2 launch orbbec_camera gemini_330_series.launch.py depth_registration:=true enable_d2c_viewer:=true + ``` + + This launches the camera node with depth to color registration and opens a viewer to display the overlay image. + +### Selecting Topics in RViz2 + +To visualize the aligned images in RViz2: + +1. Launch RViz2 after running one of the above commands. +2. Select the topic for the depth to color overlay image. An example topic selection is shown here: + + ![Topic Selection for Depth to Color Overlay](../image/align_depth_color/image3.png) + +### Example of Depth to Color Overlay + +After selecting the appropriate topic in RViz2, you will be able to see the depth to color overlay image. Here's what it might look like: + +![Depth to Color Overlay Image](../image/align_depth_color/image4.jpg) diff --git a/_sources/source/5_advanced_guide/benchmark.md.txt b/_sources/source/5_advanced_guide/benchmark.md.txt new file mode 100644 index 00000000..fb3090d4 --- /dev/null +++ b/_sources/source/5_advanced_guide/benchmark.md.txt @@ -0,0 +1,51 @@ +# Ob_benchmark tool + +> The goal of this tool is to benchmark the performance of various OrbbecSDK_ROS2 camera configurations. The benchmark results depend on the camera and settings used.(Currently only works with ROS2 Humble) + +## Usage Instructions + +### Tool Configuration ([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`: Names of the cameras to be configured. Example: `"camera_01"`, `"camera_02"`, etc. +* `process_name`: The name of the process to be monitored. For example, `"component_conta"` will monitor the data of the container process. +* `switch_cycle`: The cycle time for switching configurations, in seconds. For example, setting it to `300` means the configuration will switch every 300 seconds. +* `test_cycle`: The testing cycle, in seconds. For example, setting it to `1` means the tool will collect data for the monitored process every 1 second. +* `skip_number`: The number of data points to skip. For example, setting it to `30` means that the first 30 data points will be ignored. + +### Camera configuration (launch files) + +In the launch folder, there are multiple\.launch.py files (`ob_benchmark_0.launch.py`, `ob_benchmark_1.launch.py`, ..., `ob_benchmark_19.launch.py`). Each file corresponds to a different camera configuration. + +### Running the ob_benchmark tool + +To run the tool, use the following commands: + +```bash +source install/setup.bash +ros2 run orbbec_camera ob_benchmark_node +``` + +### Output Data Files + +The output data files will be stored in the ob_benchmark folder with filenames like `0.csv`, `1.csv`, ..., 19.csv. For example: + +* `0.csv` contains data from the `ob_benchmark_0.launch.py` configuration. +* `1.csv` contains data from the `ob_benchmark_1.launch.py` configuration. diff --git a/_sources/source/5_advanced_guide/building_a_Debian_Package.md.txt b/_sources/source/5_advanced_guide/building_a_Debian_Package.md.txt new file mode 100644 index 00000000..7441bfca --- /dev/null +++ b/_sources/source/5_advanced_guide/building_a_Debian_Package.md.txt @@ -0,0 +1,45 @@ +# Building a Debian Package + +## Preparing the Environment + +Before starting, install the required tools: + +```bash +sudo apt install debhelper fakeroot python3-bloom +``` + +## Configuring ROS Dependencies + +Add the following YAML file to your system at `/etc/ros/rosdep/sources.list.d/00-orbbec.yaml`. Make sure to +replace `focal` with the codename of your Ubuntu version and `humble` with your ROS2 distribution name: + +```yaml +orbbec_camera_msgs: + ubuntu: + focal: [ ros-humble-orbbec-camera-msgs ] +``` + +Next, create a new file `/etc/ros/rosdep/sources.list.d/50-orbbec.list` and add this line to specify the path to the +YAML file: + +```bash +yaml file:///etc/ros/rosdep/sources.list.d/00-orbbec.yaml +``` + +Update the rosdep database to reflect these changes: + +```bash +rosdep update +``` + +## Building the Package + +Navigate to your workspace and build the project: + +```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 +``` diff --git a/_sources/source/5_advanced_guide/configuration_of_depth_NFOV_and_WFOV_modes.md.txt b/_sources/source/5_advanced_guide/configuration_of_depth_NFOV_and_WFOV_modes.md.txt new file mode 100644 index 00000000..ad4312c3 --- /dev/null +++ b/_sources/source/5_advanced_guide/configuration_of_depth_NFOV_and_WFOV_modes.md.txt @@ -0,0 +1,13 @@ +# Configuration of depth NFOV and WFOV modes + +For the Femto Mega and Femto Bolt devices, the NFOV and WFOV modes are implemented by configuring the resolution of +Depth and IR in the launch file. +In launch file, depth_width, depth_height, ir_width, ir_height represents the resolution of the depth and the resolution of +the IR. +The frame fps and resolution of IR must be consistent with the depth. The correspondence between different modes and +resolutions is as follows: + +- NFOV unbinned: 640 x 576. +- NFOV binned: 320 x 288. +- WFOV unbinned: 1024 x 1024. +- WFOV binned: 512 x 512. diff --git a/_sources/source/5_advanced_guide/depth_work_mode_switch.md.txt b/_sources/source/5_advanced_guide/depth_work_mode_switch.md.txt new file mode 100644 index 00000000..bdd82bb8 --- /dev/null +++ b/_sources/source/5_advanced_guide/depth_work_mode_switch.md.txt @@ -0,0 +1,32 @@ +# Depth work mode switch + +Orbbec SDK ROS 2 supports the depth work mode switch. The depth work mode switch is supported by Gemini 2, Gemini 2 L, +and Femto and Femto Bolt cameras. + +- Before starting the camera, depth work mode (depth_work_mode) can be configured for the corresponding xxx.launch.py + file's support. +- The depth work mode switch is supported by Gemini 2, Gemini 2 L, and Gemini 2 XL cameras. +- The default depth work mode configuration of xxx.launch.py is the camera's default configuration. If you need to + modify it, you can switch to the corresponding mode as needed. +- The specific camera depth work mode support types can be found in the comments of the depth mode. + +```python +# Depth work mode support is as follows: +# Unbinned Dense Default +# Unbinned Sparse Default +# Binned Sparse Default +# Obstacle Avoidance +DeclareLaunchArgument('depth_work_mode', default_value='') +``` + +- View depth work modes: + +```bash +ros2 run orbbec_camera list_depth_work_mode_node +``` + +* Example: + +```bash +ros2 launch orbbec_camera gemini2L.launch.py depth_work_mode:="Unbinned Dense Default" +``` diff --git a/_sources/source/5_advanced_guide/disparity_search_offset.md.txt b/_sources/source/5_advanced_guide/disparity_search_offset.md.txt new file mode 100644 index 00000000..382bbe03 --- /dev/null +++ b/_sources/source/5_advanced_guide/disparity_search_offset.md.txt @@ -0,0 +1,47 @@ +# Disparity_search_offset + +> This section describes how to use the disparity_search_offset function in the Gemini330 series cameras (minimum camera firmware version [1.4.60](https://www.orbbec.com/docs/g330-firmware-release/)).Disparity_search_offset is effective only for1280×720, 1280×800 and 640×400 resolutions of depth stream. + +## Function Introduction + +The definition of disparity search range: For any pixel *(u_l, v)* in the left image, by default, the corresponding disparity search range in the right image is *[ (u_l - 255, v)*, *(u_l, v) ]*, where the disparity search length is 256 and the maximum integer disparity is 255. If the starting point of the search is adjusted to *[ (u_l - 255 - offset, v)*, *(u_l - offset, v) ]*, the offset is defined as the disparity shift. Therefore, our disparity search range configuration includes both the disparity search length and the search position offset (which can also be referred to as the disparity shift). + +![Depth Point Cloud Visualization](../image/disparity_search_offset/search_offset0.png) + +## Parameter Introduction + +The disparity_search_offset related parameters are set in [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` : Disparity search length,can only be set to 64, 128 and 256. + +* `disparity_search_offset` : Disparity search offset value,Disparity search offset value, can be set from 0 to 127. + +* `disparity_offset_config` : Disparity search offset interleave frames. + +* `offset_index0` : Frame 0 disparity search offset value. + +* `offset_index1` : Frame 1 disparity search offset value. + +| disparity range mode | disparity search offset | Minimum depth of inclined wall (mm) | +| :------------------: | :---------------------: | :---------------------------------: | +| 64 | 85 | Gemini 335L  388-406 | +| 64 | 127 | Gemini 335L  302-317 | + +| disparity range mode | disparity search offset | Minimum depth of inclined wall (mm) | +| :------------------: | :---------------------: | :---------------------------------------------: | +| 128 | 0 | Gemini 335  233-249
Gemini 335L  453-475 | +| 128 | 45 | Gemini 335  172-184
Gemini 335L  334-349 | +| 128 | 127 | Gemini 335  117-125
Gemini 335L  226-236 | + +| disparity range mode | disparity search offset | Minimum depth of inclined wall (mm) | +| :------------------: | :---------------------: | :---------------------------------: | +| 256 | 85 | Gemini 335L  169-178 | +| 256 | 127 | Gemini 335L  151-158 | + +## Run the launch + +Setting the disparity_search_offset parameter,`colcon build` again and run launch + +```bash +ros2 launch orbbec_camera gemini_330_series.launch.py +``` diff --git a/_sources/source/5_advanced_guide/efficient_intra_process_communication.md.txt b/_sources/source/5_advanced_guide/efficient_intra_process_communication.md.txt new file mode 100644 index 00000000..c2b11638 --- /dev/null +++ b/_sources/source/5_advanced_guide/efficient_intra_process_communication.md.txt @@ -0,0 +1,35 @@ +# Efficient intra-process communication: + +Our ROS2 Wrapper node supports zero-copy communications if loaded in the same process as a subscriber node. This can reduce copy times on image/pointcloud topics, especially with big frame resolutions and high FPS. + +You will need to launch a component container and launch our node as a component together with other component nodes. Further details on "Composing multiple nodes in a single process" can be found [here](https://docs.ros.org/en/rolling/Tutorials/Composition.html). + +Further details on efficient intra-process communication can be found [here](https://docs.ros.org/en/humble/Tutorials/Intra-Process-Communication.html#efficient-intra-process-communication). + +## Example + +### Manually loading multiple components into the same process + +* Start the component: + + ```bash + ros2 run rclcpp_components component_container + ``` +* Add the wrapper: + + ```bash + ros2 component load /ComponentManager orbbec_camera orbbec_camera::OBCameraNodeDriver -e use_intra_process_comms:=true + ``` + + Load other component nodes (consumers of the wrapper topics) in the same way. + +### Using a launch file + +```bash +ros2 launch orbbec_camera gemini_intra_process_demo_launch.py +``` + +### Limitations + +* Node components are currently not supported on RCLPY +* Compressed images using `image_transport` will be disabled as this isn't supported with intra-process communication diff --git a/_sources/source/5_advanced_guide/fastdds_tuning.md.txt b/_sources/source/5_advanced_guide/fastdds_tuning.md.txt new file mode 100644 index 00000000..03f94d85 --- /dev/null +++ b/_sources/source/5_advanced_guide/fastdds_tuning.md.txt @@ -0,0 +1,154 @@ +# Fast DDS Optimization for Orbbec Camera with ROS2 + +When operating with the default configuration, Fast DDS exhibits suboptimal transmission efficiency, resulting in +significant image transmission delays when used with the Orbbec camera in ROS2. This document provides guidance on +optimizing Fast DDS to enhance image transfer efficiency. + +## Adjusting System Parameters + +### IP Fragmentation Time + +- **Path**: `/proc/sys/net/ipv4/ipfrag_time` (default: 30 seconds) +- **Purpose**: Defines the duration that IP fragments are kept in memory. +- **Adjustment**: Decrease this value to reduce the time window where no fragments are received, which can help reduce + delays. Consider the specific needs of your environment as this setting affects all incoming fragments. + + **Example**: Set to 3 seconds. + + ```bash + sudo sysctl net.ipv4.ipfrag_time=3 + ``` + +### IP Fragmentation Memory Threshold + +- **Path**: `/proc/sys/net/ipv4/ipfrag_high_thresh` (default: 262144 bytes) +- **Purpose**: Sets the maximum memory used to reassemble IP fragments. +- **Adjustment**: Increase this value to allow more memory for fragment reassembly, which can improve handling of larger + data packets. + + **Example**: Increase to 128 MB. + + ```bash + sudo sysctl net.ipv4.ipfrag_high_thresh=134217728 + ``` + +### Maximum Buffer Sizes + +- **Purpose**: Configures the maximum buffer sizes for receiving and sending data, which is critical for high-throughput + data transmission. +- **Adjustment**: Set the maximum buffer sizes for both receiving and sending operations. + + **Commands**: + + ```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 + ``` + +Alternatively, make these settings permanent by adding them to the `/etc/sysctl.d/10-fastrtps-max.conf` file. + +```bash +sudo gedit /etc/sysctl.d/10-fastrtps-max.conf +``` + +add blow lines to the file: + +```bash +net.core.rmem_max=2147483647 +net.core.rmem_default=2147483647 +net.core.wmem_max=2147483647 +net.core.wmem_default=2147483647 +``` + +then save and exit the file. run `sudo sysctl -p` to apply the changes. + +For detailed guidance, refer +to [ROS 2 DDS Tuning Documentation](https://docs.ros.org/en/foxy/How-To-Guides/DDS-tuning.html). + +## Fast DDS Configuration + +Below is an example of a Fast DDS configuration file optimized for ROS2 usage with the Orbbec camera. This configuration +enhances the overall data transmission by adjusting buffer sizes and transport settings. + +### Configuration File: `shm_fastdds.xml` + +Place this file in the `$HOME` directory. + +```xml + + + + + UDP_transport + UDPv4 + 10 + 65000 + 1048576 + 1048576 + + + + + profile_for_ros2_context + + UDP_transport + + false + 1048576 + 1048576 + + + + +
127.0.0.1
+
+
+
+
+
+
+ + + + ASYNCHRONOUS + + + + 0 + 1000000 + + + + PREALLOCATED_WITH_REALLOC + + + + + AUTOMATIC + + + + 0 + 1000000 + + + + PREALLOCATED_WITH_REALLOC + +
+``` + +### Environment Variables + +Set the following environment variables to use the custom Fast DDS profile: + +```bash +export RMW_IMPLEMENTATION=rmw_fastrtps_cpp +export FASTRTPS_DEFAULT_PROFILES_FILE=$HOME/shm_fastdds.xml +export RMW_FASTRTPS_USE_QOS_FROM_XML=1 +``` + +This configuration aims to optimize the data flow and reduce transmission delays, improving the responsiveness and +reliability of the Orbbec camera system in a ROS2 environment. diff --git a/_sources/source/5_advanced_guide/gmsl_camera.md.txt b/_sources/source/5_advanced_guide/gmsl_camera.md.txt new file mode 100644 index 00000000..6a80a059 --- /dev/null +++ b/_sources/source/5_advanced_guide/gmsl_camera.md.txt @@ -0,0 +1,50 @@ +# GMSL_camera + +> This section describes how to use GMSL camera in OrbbecSDK_ROS2.Currently, only Gemini 335Lg GMSL devices are supported, and other GMSL devices will be supported in the near future. + +## Single GMSL camera + +The usage of GMSL camera in OrbbecSDK_ROS2 is the same as that of Gemini 330 series camera via USB. + +```bash +ros2 launch orbbec_camera gemini_330_gmsl.launch.py +``` + +## Multi GMSL camera + +To get the `usb_port` of the GMSL camera, plug in the camera and run the following command in the terminal: + +```bash +ros2 run orbbec_camera list_devices_node +``` + +For example, the obtained gmsl camera `usb_port`: `gmsl2-1` + +Go to the [multi_gmsl_camera.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera.launch.py) file and change the `usb_port`. + +```bash +ros2 launch orbbec_camera multi_gmsl_camera.launch.py +``` + +> Note: By default, multi_gmsl_camera.launch.py only starts color and left_ir. If you want to start other sensors, please go to [camera_secondary_params.yaml](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/config/camera_secondary_params.yaml) to modify them. + +## Multi GMSL camera synced + +First, please see how to use [multi_camera_synced](./multi_camera_synced.md). + +In addition, GMSL multi-camera synced does not require Multi-Camera Sync Hub Pro, so there is no need to set the `primary` mode. Each GMSL camera is `secondary`. + +### Additional Parameter Settings + +* `gmsl_trigger_fps` : set hardware soc trigger source frame rate. +* `enable_gmsl_trigger` : enable hardware soc trigger. + +### Run the launch + +Please refer to the configuration in [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 +``` + +> Note: By default, multi_gmsl_camera_synced.launch.py only starts color and left_ir. If you want to start other sensors, please go to [camera_secondary_params.yaml](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/config/camera_secondary_params.yaml) and [camera_params.yaml](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/config/camera_params.yaml) to modify them. diff --git a/_sources/source/5_advanced_guide/interleave_ae_mode.md.txt b/_sources/source/5_advanced_guide/interleave_ae_mode.md.txt new file mode 100644 index 00000000..99baedcf --- /dev/null +++ b/_sources/source/5_advanced_guide/interleave_ae_mode.md.txt @@ -0,0 +1,81 @@ +# Using interleave_ae with Gemini330 series cameras + +> This section describes how to use interleave_ae in Gemini 330 series cameras (minimum camera firmware version [1.4.00](https://www.orbbec.com/docs/g330-firmware-release/)) + +## Parameter Introduction + +The interleave_ae related parameters are set in [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` : Set laser or hdr interleave. + +* `interleave_frame_enable` : enable interleave frame mode. + +* `interleave_skip_enable` : enable skip frame mode. + +* `interleave_skip_index` : Set 0 for skip pattern ir, set 1 for skip flood ir. + +### interleave hdr + +When the `interleave_ae_mode` parameter is set to `hdr` and `interleave_frame_enable `is set to `true`, interleave hdr will be enabled + +* `hdr_index1_laser_control` : Frame 1 laser switch settings. + +* `hdr_index1_depth_exposure` : Frame 1 depth exposure value setting, not in AE mode. + +* `hdr_index1_depth_gain` : Frame 1 depth gain value setting, not in AE mode. + +* `hdr_index1_ir_brightness` : Frame 1 ir gain value setting. + +* `hdr_index1_ir_ae_max_exposure` : Frame 1 ir maximum exposure value setting in AE (auto exposure). + +* `hdr_index0_laser_control`: Frame 0 laser switch settings. + +* `hdr_index0_depth_exposure`: Frame 0 depth exposure value setting, not in AE mode. + +* `hdr_index0_depth_gain` : Frame 0 depth gain value setting, not in AE mode. + +* `hdr_index0_ir_brightness` : Frame 0 ir gain value setting. + +* `hdr_index0_ir_ae_max_exposure` : Frame 0 ir maximum exposure value setting in AE (auto exposure). + +### interleave laser + +When the `interleave_ae_mode` parameter is set to `laser` and `interleave_frame_enable `is set to `true`, interleave laser will be enabled + +* `laser_index1_laser_control` : Frame 1 laser switch settings. + +* `laser_index1_depth_exposure` : Frame 1 depth exposure value setting, not in AE mode. + +* `laser_index1_depth_gain` : Frame 1 depth gain value setting, not in AE mode. + +* `laser_index1_ir_brightness` : Frame 1 ir gain value setting. + +* `laser_index1_ir_ae_max_exposure` : Frame 1 ir maximum exposure value setting in AE (auto exposure). + +* `laser_index0_laser_control` : Frame 0 laser switch settings. + +* `laser_index0_depth_exposure` : Frame 0 depth exposure value setting, not in AE mode. + +* `laser_index0_depth_gain` : Frame 0 depth gain value setting, not in AE mode. + +* `laser_index0_ir_brightness` : Frame 0 ir gain value setting. + +* `laser_index0_ir_ae_max_exposure` : Frame 0 ir maximum exposure value setting in AE (auto exposure). + +## Run the launch + +Setting the interleave_ae parameter,`colcon build` again and run launch + +```bash +ros2 launch orbbec_camera gemini_330_series.launch.py +``` + +#### Example Visualization + +![Depth Point Cloud Visualization](../image/interleave_ae_mode/interleave_ae0.jpeg) + +![Depth Point Cloud Visualization](../image/interleave_ae_mode/interleave_ae1.jpeg) + +## Multi_camera_synced + Interleave_ae + +Please refer to [multi_camera_synced](./multi_camera_synced.md) and [Parameter Introduction](#parameter-introduction) diff --git a/_sources/source/5_advanced_guide/lower_cpu_usage.md.txt b/_sources/source/5_advanced_guide/lower_cpu_usage.md.txt new file mode 100644 index 00000000..9ef453ac --- /dev/null +++ b/_sources/source/5_advanced_guide/lower_cpu_usage.md.txt @@ -0,0 +1,86 @@ +## Reducing CPU Usage with Orbbec ROS Package + +This document outlines strategies for minimizing CPU usage in the **OrbbecSDK_ROS2 v2** environment when using **Gemini 330 series cameras**. The firmware version must be **no lower than 1.4.10**, and `device` should be set to **Default**. + +### Recommended Settings for Lower CPU Usage + +To achieve the lowest possible CPU usage in OrbbecSDK_ROS2, it is recommended to configure the following parameters. + +| Parameter | Recommendation | Note | +| :--------------: | :------------------------------------: | :--------------------------------------------: | +| `uvc_backend` | `v4l2` | Lower CPU usage compared to `libuvc` | +| `color_format` | `RGB` | Lower CPU usage than `MJPG` | +| `filter` | Only `hardware_noise_removal_filter` | Other filters significantly increase CPU usage | + +### Launch Files Used for Testing + +* `gemini_330_series_lower_cpu_usage.launch.py` +* `multi_camera_lower_cpu_usage.launch.py` + +### Test environment + +#### Hardware Configuration + +* **CPU**: Intel i7-8700 @ 3.20GHz +* **Memory**: 24 GB +* **Storage**: Micron 2200S NVMe 256GB +* **GPU**: NVIDIA GeForce GTX 1660Ti +* **OS**: Ubuntu22.04 + +#### ROS Configuration + +* **ROS Version**: ROS2 Humble +* **SDK Version**: OrbbecSDK_ROS2 v2.2.1 + +#### Camera Setup + +* Devices: 2x Gemini 335, 1x Gemini 336, 1x Gemini 336L +* Firmware Version: 1.4.10 + +### Test Setup + +* **Stream Settings:** + * Depth / IR Left / IR Right: 848×480 @ 30fps + * Color: 848×480 @ 30fps + +Note: The following CPU usage data focuses on `uvc_backend`, `color_format` and various filter combinations. + +### Test Results + +#### `uvc_backend` Comparison (RGB format) + +| libuvc CPU Usage | v4l2 CPU Usage | Absolute Change | +| :--------------: | :------------: | :-------------: | +| 182.8% | 118.8% | -64.0% | + +The CPU usage can be significantly reduced with v4l2 backend. In our implementation, v4l2 works without requiring any patches to the Linux kernel, allowing users to easily switch between v4l2 and libuvc and maintaining full compatibility with standard Linux distributions. + +#### `color_format` Comparison (MJPG vs RGB) + +| Backend | MJPG CPU Usage | RGB CPU Usage | Absolute Change | +| :-----: | :------------: | :-----------: | :-------------: | +| libuvc | 347.7% | 182.8% | -164.9% | +| v4l2 | 170.0% | 118.8% | -51.2% | + +The CPU usage can be reduced if the RGB format is selected instead of MJPG, since the decoding of MJPG image will consume the host CPU resource. + +#### Filter Configuration Impact + +| Filters Applied | libuvc CPU Usage | CPU Usage Increase | v4l2 CPU Usage | CPU Usage Increase | +| ----------------------------------------------------- | ---------------- | ------------------ | -------------- | ------------------ | +| No Filter (benchmark) | 182.8% | 0.0%(benchmark) | 118.8% | 0.0%(benchmark) | +| `(software)noise_removal_filter` | 218.0% | +35.2% | 128.5% | +9.7% | +| `(software)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% | + +Based on the test results, using only the `hardware_noise_removal_filter` results in a negligible change in CPU usage for both `libuvc` (+3.5%) and `v4l2` (-3.4%) compared to the no-filter benchmark, as this filter runs internally on the camera hardware. In contrast, other filters execute on the host system. Adding the `spatial_filter` to the hardware filter leads to a moderate increase in CPU usage, while applying the software-based `noise_removal_filter` —either alone or combined with `spatial_filter` —significantly increases CPU load. To maintain low CPU usage, it is recommended to avoid software-based filters and rely solely on the `hardware_noise_removal_filter`. + +### Further Optimizationa + +| Parameter | Recommendation | Note | +| :----------------------------: | :----------------------------------------------: | :---------------------------------------------: | +| `depth_registration` | `false` or `true` with `align_mode=HW` | Software alignment consumes more CPU | +| `enable_point_cloud` | `false` | Disabling point cloud reduces CPU usage | +| `enable_colored_point_cloud` | `false` | Disabling colored point cloud reduces CPU usage | + diff --git a/_sources/source/5_advanced_guide/multi_camera.md.txt b/_sources/source/5_advanced_guide/multi_camera.md.txt new file mode 100644 index 00000000..82b05b37 --- /dev/null +++ b/_sources/source/5_advanced_guide/multi_camera.md.txt @@ -0,0 +1,91 @@ +# Multi-Camera + +- To get the `usb_port` of the camera, plug in the camera and run the following command in the terminal: + +```bash +ros2 run orbbec_camera list_devices_node +``` + +- Set the `device_num` parameter to the number of cameras you have. +- Go to the `OrbbecSDK_ROS2/launch/multi_xxx.launch.py` file and change the `usb_port`. +- Don't forget to put the `include` tag inside the `group` tag. + Otherwise, the parameter values of different cameras may become contaminated. + +```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 + +``` + +- To launch the cameras, run the following command: + +```bash +ros2 launch orbbec_camera multi_camera.launch.py +``` + +## No Data Stream from Multiple Cameras + +**Insufficient Power Supply**: + +- Ensure that each camera is connected to a separate hub. +- Use a powered hub to provide sufficient power to each camera. + +**High Resolution**: + +- Try lowering the resolution to resolve data stream issues. + +**Increase usbfs_memory_mb Value**: + +- Increase the `usbfs_memory_mb` value to 128MB (this is a reference value and can be adjusted based on your system’s needs) + by running the following command: + +```bash + echo 128 | sudo tee /sys/module/usbcore/parameters/usbfs_memory_mb +``` + +- To make this change permanent, check [this link](https://github.com/OpenKinect/libfreenect2/issues/807). + +## Image topic frame rate too low from Multiple Cameras + +Refer to the [Fast DDS Configuration](./fastdds_tuning.md) file. diff --git a/_sources/source/5_advanced_guide/multi_camera_synced.md.txt b/_sources/source/5_advanced_guide/multi_camera_synced.md.txt new file mode 100644 index 00000000..572fe3b6 --- /dev/null +++ b/_sources/source/5_advanced_guide/multi_camera_synced.md.txt @@ -0,0 +1,55 @@ +# Multi_camera synced Instructions + +> The purpose of this document is to explain how to use multi-camera synced with OrbbecSDK_ROS2 + +## Setup instructions + +* Please read the Multi-Camera Synchronization Setup Guide:[Multi-Camera Synchronization Setup](https://www.orbbec.com/docs/set-up-cameras-for-external-synchronization_v1-2/) +* Make sure the camera is correctly connected to the multi-camera synchronizer. + +![Depth Point Cloud Visualization](../image/multi_camera_synced/multi_camera_synced1.png) + +### Checking camera port with OrbbecSDK_ROS2 + +```bash +ros2 run orbbec_camera list_devices_node +``` + +### OrbbecSDK_ROS2 multi-camera synced configuration + +Open multi_camera_synced.launch.py, and configure the camera settings as shown below: + +![Depth Point Cloud Visualization](../image/multi_camera_synced/multi_camera_synced2.png) + +1. `gemini_330_series.launch.py` is the launch file for starting the camera. + +2. Set `camera_name` to `G330_0`. For example, the published color image topic will be `/G330_0/color/image_raw`. + +3. Set `usb_port` to `2-2`, indicating that the camera device on port `2-2` is being used. This value can be found in the output of the `ros2 run orbbec_camera list_devices_node` command. + +4. Set `device_num` to `2`, meaning two cameras will be used. + +5. Set `sync_mode` to `primary` to indicate that the `2-7` camera device is in primary mode. The multi-camera sync mode options can be found in the figure below. + +6. Parameters from the `config_file_path` can override the parameters set in `gemini_330_series.launch.py` (optional). + +7. For slave cameras, set `trigger_out_enabled` to false. + +| **Pattern Nam**e | **Setting effect description** | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| free_run | -Support different frame rate settings
The -8-pin synchronization interface does not support external output of synchronization-related signals | +| standalone(default) | ● Same as Primary by default
● Built-in RGBD frame synchronization
● 8-pin synchronous interface does not output signals to the outside by default | +| primary | ● Set as primary camera
● 8-pin synchronous interface output signal to external device | +| secondary | ● Set as secondary (passive synchronization; When there is a hardware continuous trigger signal input from the outside and the continuous trigger signal matches the currently set frame rate, the image is collected according to the external trigger signal; When there is no external trigger signal, the flow is stopped)
● 8-pin synchronous interface output signal to external device | +| secondary_synced | ● Set to secondary synchronization (passive synchronization; When there is a hardware continuous trigger signal input from the outside and the continuous trigger signal matches the currently set frame rate, the image is collected according to the external trigger signal; When there is no external trigger signal, the image is collected according to the internal trigger signal at the set frame rate)
● 8-pin synchronous interface output signal to external device | +| hardware_triggering | ● Set as hardware trigger (passive trigger; When there is a hardware trigger signal input from the outside and the trigger signal time interval is not less than the current upper limit, the image is collected according to the external trigger signal; When there is no external trigger signal, the image is not collected)
● 8-pin synchronous interface output signal to external device | +| software_triggering | ● Set as software trigger (passive trigger; When there is a trigger command input from the host computer and the trigger command time interval is not less than the current upper limit, the image is collected according to the trigger command; When there is no trigger command, the image is not collected)
● 8-pin synchronous interface output signal to external device | + +* The master camera should be launched last. +* Ideally, there should be a 2-second delay between starting each camera. + +### Run the following command to start the multi-camera synced + +```bash +ros2 launch orbbec_camera multi_camera_synced.launch.py +``` diff --git a/_sources/source/5_advanced_guide/multi_camera_synced_verification_tool.md.txt b/_sources/source/5_advanced_guide/multi_camera_synced_verification_tool.md.txt new file mode 100644 index 00000000..08492f79 --- /dev/null +++ b/_sources/source/5_advanced_guide/multi_camera_synced_verification_tool.md.txt @@ -0,0 +1,159 @@ +# Multi_camera_synced_verification_tool + +> This article will introduce how to verify the synchronization accuracy of multi-camera synchronization. +> +> First, please see how to use [multi_camera_synced](./multi_camera_synced.md). + +## Directory Structure + +```plaintext +. +├── multicamera_sync/ +│ ├── output/ +│ ├──20250218102900/ +│ ├──DevicesInfo.txt +│ ├──StreamProfileInfo.txt +│ ├── Python/ +│ ├──Config.ini +├── gemini_330_series_synced_verify.launch.py +├── multi_camera_synced_verify.launch.py +``` + +### multicamera_sync + +* `gemini_330_series_synced_verify.launch.py` : Single camera runs launch, which provides the camera running node for multi_camera_synced_verify.launch.py. +* `multi_camera_synced_verify.launch.py` : Multi camer synced + launch of save_rgbir tool. + +#### output + +> The `ouput` folder is the folder where the camera pictures are output + +In the output example provided + +* `20250218102900` : Represents the camera image information collected at 10:29:00 on February 18, 2025. +* `TotalModeFrames` : Camera image information storage directory. +* `results-2025-02-25_163648` : The result after analyzing and matching the image information of TotalModeFrames. +* `DevicesInfo.txt` : Camera equipment basic information (need to be modified). +* `StreamProfileInfo.txt` : Camera video stream information (no need to modify). + +#### Python + +* `Config.ini` : Configuration file for Python analysis script (need to be modified). + +## Preparation for operation + +### save_rgbir node + +Edit multi_camera_synced_verify.launch.py and fill in the activated camera device,we can find that save_rgbir is started at the end. + +> IMPORTANT +> +> If you are using ROS 2 Foxy, you need to launch the save_rgbir node first. + +```python +# Launch description + ld = LaunchDescription( + [ + shared_orbbec_container, + TimerAction(period=0.0, actions=[GroupAction([launch2_include])]), + TimerAction(period=2.0, actions=[GroupAction([launch1_include])]), + # The primary camera should be launched at last + TimerAction(period=6.0, actions=[GroupAction([save_rgbir])]), + # save_rgbir is synced verification tool + ] + ) + + return ld +``` + +save_rgbir is a tool for saving images. The configuration file of this tool is in [multi_save_rgbir_params.json](../../config/tools/multisavergbir/multi_save_rgbir_params.json). + +```json +{ + "save_rgbir_params": { + "time_domain": "global", + "usb_ports": [ + "2-1", + "2-3" + ], + "camera_name": [ + "camera_01", + "camera_02" + ] + } +} +``` + +* `time_domain` : Timestamp Type +* `usb_ports` : "primary", "secondary 1", "secondary 2", "secondary 3", fill in as many usb_ports as there are cameras +* `camera_name` : The name of the camera setting, for example: camera_01 + +### DevicesInfo.txt + +Edit DevicesInfo.txt. Only the `primarySerialNumber`, `index` and `serialNumber` parameters need to be changed. Other parameters do not need to be changed.Refer to the example of [20250218102900](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool/multicamera_sync/output/20250218102900). + +* `primarySerialNumber` : The SN serial number of the primary camera +* `index` : Camera index +* `serialNumber` : The SN serial number of the camera + +### Config.ini + +Edit Config.ini.Modify `frameRate` and `tspRangeThreshold`. + +## Run this example + +### Run launch and save camera pictures + +* First terminal + +```bash +ros2 launch orbbec_camera multi_camera_synced_verify.launch.py +``` + +* Second terminal + +```bash +ros2 service call /save_rgbir/start_capture orbbec_camera_msgs/srv/SetInt32 '{data: 100}' +``` + +When the terminal displays "over", the image is saved.A new multicamera_sync folder will be generated under the workspace. + +### Camera pictures naming format + +Take [color_SNCP1E5420006D_Index0_g1739874543227_f0_s1739874543327_e50_d16_.jpg](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool/multicamera_sync/output/20250218102900/TotalModeFrames/SNCP1E5420006D_Index0/color_SNCP1E5420006D_Index0_g1739874543227_f0_s1739874543327_e50_d16_.jpg) as an example + +* `color` : This image is a snapshot of the color stream. +* `SNCP1E5420006D` : The camera's SN serial number is CP1E5420006D. +* `Index0` : Camera 0 (usually referred to primary camera). +* `g1739874543227` : “g” represents the global timestamp, which means the global timestamp of this frame is 1739874543227. +* `f0` : The 0th picture of the color stream acquisition of this camera. +* `s1739874543327` : "s" represents the timestamp of the current system, which means the current system timestamp of this frame is 1739874543327. +* `e50` : The exposure of this frame is 50. +* `d16` : The gain of this frame is 16. + +### Analyzing camera image data + +You need to copy the modified [Python folder](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool//multicamera_sync/Python) to the new multi_camera_synced subdirectory, and copy the modified [DevicesInfo.txt ](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool/multicamera_sync/output/20250218102900/DevicesInfo.txt)and [StreamProfileInfo.txt](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool//multicamera_sync/output/20250218102900/StreamProfileInfo.txt) to the same level directory as the TotalModeFrames folder. + +* Finally everything is ready, run the python script + +```bash +cd multicamera_sync/Python +python3 SyncFramesMain.py +``` + +After the operation is successful, you can view the synchronization effect in the `results folder` + +## Files that need to be changed + +### Analysis tools + +* [multi_save_rgbir_params.json](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/config/tools/multisavergbir/multi_save_rgbir_params.json) +* [DevicesInfo.txt ](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool//multicamera_sync/output/20250218102900/DevicesInfo.txt) +* [Config.ini](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool//multicamera_sync/Python/Config.ini) + +### Camera Configuration + +[camera_params.yaml](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/config/camera_params.yaml)(Camera startup parameter settings) + +[multi_camera_synced_verify.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool//multi_camera_synced_verify.launch.py) diff --git a/_sources/source/5_advanced_guide/net_camera.md.txt b/_sources/source/5_advanced_guide/net_camera.md.txt new file mode 100644 index 00000000..c91d2e35 --- /dev/null +++ b/_sources/source/5_advanced_guide/net_camera.md.txt @@ -0,0 +1,69 @@ +# Net_camera + +> This section describes how to use Net camera in OrbbecSDK_ROS2.Currently, only Femto_Mega, Gemini 335Le and Gemini 435Le devices are supported, and other Net devices will be supported in the near future. + +## Femto Mega & Gemini 435Le + +### Parameter Introduction + +Network device settings: `enumerate_net_device` is set to true, which will automatically enumerate network devices. + +If you do not want to automatically enumerate network devices,you can set `enumerate_net_device` to false, `net_device_ip` to the device's IP address, and `net_device_port` to the default value of 8090. + +* `enumerate_net_device` : Enable automatically enumerate network devices. +* `net_device_ip` : Setting net device's IP address. +* `net_device_port` : Setting net device's port.Usually, you can set it to 8090. + +### Single Net camera + +> If you need to run Gemini 435Le, you only need to replace [femto_mega.launch.py ](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/femto_mega.launch.py)in the run command with [gemini435_le.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/gemini435_le.launch.py) + +For [femto_mega.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/femto_mega.launch.py) as an example: + +- **automatically enumerate network devices:** + +```bash +ros2 launch orbbec_camera femto_mega.launch.py enumerate_net_device:=true +``` + +- **Specify IP address to start the device:** + +Note: `net_device_ip` needs to be changed to the IP address of the device, here it is 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 +``` + +## Gemini 335Le + +Network device settings: `enumerate_net_device` must be set to true, set `net_device_ip` to the IP address of the device, and set `net_device_port` to the default value of 8090. + +* `enumerate_net_device` : Enable automatically enumerate network devices. +* `net_device_ip` : Setting net device's IP address. +* `net_device_port` : Setting net device's port.Usually, you can set it to 8090. + +### Single Net camera + +For [gemini_330_series.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/gemini_330_series.launch.py) as an example: + +- **automatically enumerate network devices:** + +```bash +ros2 launch orbbec_camera gemini_330_series.launch.py enumerate_net_device:=true +``` + +- **Specify IP address to start the device:** + +Note: `net_device_ip` needs to be changed to the IP address of the device, here it is 192.168.1.10 + +```bash +ros2 launch orbbec_camera gemini_330_series.launch.py enumerate_net_device:=true net_device_ip:=192.168.1.10 net_device_port:=8090 +``` + +## Multi Net camera + +For [multi_net_camera.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/examples/net_camera/multi_net_camera.launch.py) as an example: + +```bash +ros2 launch orbbec_camera multi_net_camera.launch.py +``` diff --git a/_sources/source/5_advanced_guide/point_cloud.md.txt b/_sources/source/5_advanced_guide/point_cloud.md.txt new file mode 100644 index 00000000..99422b55 --- /dev/null +++ b/_sources/source/5_advanced_guide/point_cloud.md.txt @@ -0,0 +1,53 @@ +## Enabling and Visualizing Point Cloud in ROS 2 + +This section demonstrates how to enable point cloud data output from the camera node and visualize it using RViz2. + +### Enabling Depth Point Cloud + +#### Command to Enable Depth Point Cloud + +To activate the point cloud data stream for depth information, use the following command: + +```bash +ros2 launch orbbec_camera gemini_330_series.launch.py enable_point_cloud:=true +``` + +#### Visualizing Depth Point Cloud in RViz2 + +After running the above command, perform the following steps to visualize the depth point cloud: + +1. Open RViz2. +2. Add a `PointCloud2` display. +3. Select the `/camera/depth/points` topic for visualization. +4. Set the fixed frame to `camera_link` to properly align the data. + +- **Example Visualization** + +Here is what the depth point cloud might look like in RViz2: + +![Depth Point Cloud Visualization](../image/point_cloud/image5.jpg) + +### Enabling Colored Point Cloud + +#### Command to Enable Colored Point Cloud + +To enable the colored point cloud feature, enter the following command: + +```bash +ros2 launch orbbec_camera gemini_330_series.launch.py enable_colored_point_cloud:=true +``` + +#### Visualizing Colored Point Cloud in RViz2 + +To visualize the colored point cloud data: + +1. Launch RViz2 following the command execution. +2. Add a `PointCloud2` display panel. +3. Choose the `/camera/depth_registered/points` topic from the list. +4. Ensure the fixed frame is set to `camera_link`. + +- **Example Visualization** + +The result of the colored point cloud in RViz2 should look similar to this: + +![Colored Point Cloud Visualization](../image/point_cloud/image6.jpg) diff --git a/_sources/source/5_advanced_guide/predefined_presets.md.txt b/_sources/source/5_advanced_guide/predefined_presets.md.txt new file mode 100644 index 00000000..ba40063c --- /dev/null +++ b/_sources/source/5_advanced_guide/predefined_presets.md.txt @@ -0,0 +1,15 @@ +# Predefined presets + +| Preset | Features | Recommended use cases | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Default | - Best visual perception``- Overall good performance in accuracy, fill rate, tiny objects, etc. | - Generic `
`- Robotics | +| Hand | - Clear hand and finger edges | - Gesture recognition | +| High Accuracy | - Depth of high confidence `
`- Barely noise depth values `
`- Lower fill rate | - Collision avoidance `
`- Object scanning | +| High Density | - Higher fill rate `
`- More tiny objects `
`- May suffer from noise depth values | - Object recognition `
`- Pick & place `
`- Foreground & background animation | +| Medium Density | - Balanced performance in fill rate and accuracy `
`- In comparison to Default: lower fill rate, better edge quality | - Generic and alternative to Default | +| Custom | - User defined Preset `
`- Derived from Presets above, with customized modifications, e.g. a new configuration for the post-processing pipeline, modified mean intensity set point of depth AE function, etc. | - Better depth performance achieved using customized configurations in comparison to using predefined presets `
`- For well-established custom configurations | + +Choose the appropriate preset name based on your specific use case and set it as the value for the `device_preset` +parameter. + + diff --git a/_sources/source/6_FAQ/FAQ.md.txt b/_sources/source/6_FAQ/FAQ.md.txt new file mode 100644 index 00000000..a5a02a96 --- /dev/null +++ b/_sources/source/6_FAQ/FAQ.md.txt @@ -0,0 +1,36 @@ +# Frequently Asked Questions + +### Unexpected Crash + +If the camera node crashes unexpectedly, it will generate a crash log in the current running directory: `Log/camera_crash_stack_trace_xx.log`. Please send this log to the support team or submit it to a GitHub issue for further assistance. + +### No Data Stream from Multiple Cameras + +**Insufficient Power Supply**: + +- Ensure that each camera is connected to a separate hub. +- Use a powered hub to provide sufficient power to each camera. + +**High Resolution**: + +- Try lowering the resolution to resolve data stream issues. + +**Increase usbfs_memory_mb Value**: + +- Increase the `usbfs_memory_mb` value to 128MB (this is a reference value and can be adjusted based on your system’s needs) by running the following command: + +``` + echo 128 | sudo tee /sys/module/usbcore/parameters/usbfs_memory_mb +``` + +- To make this change permanent, check [this link](https://github.com/OpenKinect/libfreenect2/issues/807). + +### Additional Troubleshooting + +- If you encounter other issues, set the `log_level` parameter to `debug`. This will generate an SDK log file in the running directory: `Log/OrbbecSDK.log.txt`. Please provide this file to the support team for further assistance. +- If firmware logs are required, set `enable_heartbeat` to `true` to activate this feature. + +### Why Are There So Many Launch Files? + +- Different cameras have varying default resolutions and image formats. +- To simplify usage, each camera has its own launch file. \ No newline at end of file diff --git a/_sources/source/license.md.txt b/_sources/source/license.md.txt new file mode 100644 index 00000000..30afe30a --- /dev/null +++ b/_sources/source/license.md.txt @@ -0,0 +1,14 @@ +## License + +Copyright 2024 Orbbec INC. + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with +the License. You may obtain a copy of the License at + +[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an " +AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific +language governing permissions and limitations under the License. + +Other names and brands may be claimed as the property of others. diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 00000000..81415803 --- /dev/null +++ b/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 00000000..4738b2ed --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,906 @@ +/* + * Sphinx stylesheet -- basic theme. + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin-top: 10px; +} + +ul.search li { + padding: 5px 0; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/css/badge_only.css b/_static/css/badge_only.css new file mode 100644 index 00000000..88ba55b9 --- /dev/null +++ b/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff b/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff2 b/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff b/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff2 b/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/_static/css/fonts/fontawesome-webfont.eot b/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/_static/css/fonts/fontawesome-webfont.svg b/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_static/css/fonts/fontawesome-webfont.ttf b/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/_static/css/fonts/fontawesome-webfont.woff b/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/_static/css/fonts/fontawesome-webfont.woff2 b/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/_static/css/fonts/lato-bold-italic.woff b/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff differ diff --git a/_static/css/fonts/lato-bold-italic.woff2 b/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/_static/css/fonts/lato-bold.woff b/_static/css/fonts/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/_static/css/fonts/lato-bold.woff differ diff --git a/_static/css/fonts/lato-bold.woff2 b/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/_static/css/fonts/lato-bold.woff2 differ diff --git a/_static/css/fonts/lato-normal-italic.woff b/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff differ diff --git a/_static/css/fonts/lato-normal-italic.woff2 b/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/_static/css/fonts/lato-normal.woff b/_static/css/fonts/lato-normal.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/_static/css/fonts/lato-normal.woff differ diff --git a/_static/css/fonts/lato-normal.woff2 b/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/_static/css/fonts/lato-normal.woff2 differ diff --git a/_static/css/theme.css b/_static/css/theme.css new file mode 100644 index 00000000..0f14f106 --- /dev/null +++ b/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/_static/custom.css b/_static/custom.css new file mode 100644 index 00000000..7ec1e6fc --- /dev/null +++ b/_static/custom.css @@ -0,0 +1,109 @@ +/* 让表格自动拉伸到满宽度 */ +table { + width: 100%; + margin-left: auto; + margin-right: auto; +} + +/* 让表格中的每个 和 也自动拉伸 */ +th, +td { + width: auto; +} + +ul { + width: 100%; + /* 列表宽度占满整个容器 */ + } + + +/* 修改 Sphinx Theme 项目标题的字体大小 Book和rtd 均OK */ +.wy-side-nav-search>a { + font-size: 16px; + /* 你可以根据需要调整这个值 */ +} + +/* 修改项目标题的字体大小 Book和rtd 均OK*/ +.wy-side-nav-search>div.version { + font-size: 16px; + /* 你可以根据需要调整这个值 */ +} + + +.sidebar-logo { + width: 500px; + /* 或者使用百分比 */ + height: auto; + max-width: 90%; + max-height: 90%; +} + + +.sidebar-content { + line-height: 1.0; + /* 行间距是字体大小的1.5倍 */ +} + +.sidebar { + padding: 20px; + /* 内边距 */ + margin-bottom: 20px; + /* 外边距 */ +} + +.sidebar-text { + font-size: 30px; +} +/* 修改侧边栏的背景颜色 */ +.wy-nav-side { + background-color: #cecece !important; +} + +/* 针对导航栏链接的选择器 */ +.wy-nav-side a { + color: #000000; + /* 修改为您需要的颜色 */ +} + +/* 如果需要,您可以添加 hover 和 active 状态的样式 */ +.wy-nav-side a:hover { + color: #fffcfc; +} + +.wy-nav-side .current>a { + color: #108bf0 !important; + font-weight: bold !important; + /* 设置为粗体 */ + /* 当前活动项的颜色 */ +} + +/* 提示:不同版本的 Sphinx 主题生成的 HTML 结构可能有所不同,请根据实际情况调整选择器 */ +h1.wy-banner-title { + color: #0267da !important; + /* 将此处的颜色替换为您希望的颜色 */ +} + +/* 如果也需要修改小标题 */ +h2.wy-banner-subtitle { + color: #7b7b7b !important; + /* 替换为希望的颜色 */ +} + +.wy-side-nav-search>a { + color: #ffffff !important; + /* 将 #your-color 替换为你想要颜色的十六进制代码 */ +} + + +/* 调整最大宽度 OK */ +.wy-nav-content { + max-width: 960px; + +} + + +/* 可选:调整侧边栏宽度 */ +/* .wy-side-scroll { + width: 300px; + +} */ \ No newline at end of file diff --git a/_static/custom.js b/_static/custom.js new file mode 100644 index 00000000..f405b0d4 --- /dev/null +++ b/_static/custom.js @@ -0,0 +1,34 @@ +// custom.js 可以禁止自动折叠,但不能跳转 +// document.addEventListener('DOMContentLoaded', function () { +// // 展开所有侧边栏目录项 +// var toctreeItems = document.querySelectorAll('.toctree-l1'); +// toctreeItems.forEach(function (item) { +// item.classList.add('current'); +// }); + +// // 监听点击事件,确保点击标题时不会折叠其他标题,并且能够跳转到相应的文档部分 +// document.querySelectorAll('.toctree-l1 a').forEach(function (link) { +// link.addEventListener('click', function (event) { +// // 阻止默认的折叠行为 +// event.preventDefault(); +// // 展开点击的标题 +// var parentLi = this.closest('li'); +// parentLi.classList.add('current'); +// // 移除其他同级目录项的 'current' 类 +// parentLi.parentElement.children.forEach(function (sibling) { +// if (sibling !== parentLi) { +// sibling.classList.remove('current'); +// } +// }); +// // 跳转到相应的文档部分 +// var target = this.getAttribute('href'); +// if (target.startsWith('#')) { +// document.querySelector(target).scrollIntoView(); +// } else { +// // 如果链接不是锚点,则在新窗口或当前窗口打开链接 +// window.open(target, '_blank'); +// } +// }); +// }); +// }); + diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 00000000..0398ebb9 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,149 @@ +/* + * Base JavaScript utilities for all Sphinx HTML documentation. + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 00000000..7e4c114f --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/_static/file.png differ diff --git a/_static/fonts/Lato/lato-bold.eot b/_static/fonts/Lato/lato-bold.eot new file mode 100644 index 00000000..3361183a Binary files /dev/null and b/_static/fonts/Lato/lato-bold.eot differ diff --git a/_static/fonts/Lato/lato-bold.ttf b/_static/fonts/Lato/lato-bold.ttf new file mode 100644 index 00000000..29f691d5 Binary files /dev/null and b/_static/fonts/Lato/lato-bold.ttf differ diff --git a/_static/fonts/Lato/lato-bold.woff b/_static/fonts/Lato/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/_static/fonts/Lato/lato-bold.woff differ diff --git a/_static/fonts/Lato/lato-bold.woff2 b/_static/fonts/Lato/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/_static/fonts/Lato/lato-bold.woff2 differ diff --git a/_static/fonts/Lato/lato-bolditalic.eot b/_static/fonts/Lato/lato-bolditalic.eot new file mode 100644 index 00000000..3d415493 Binary files /dev/null and b/_static/fonts/Lato/lato-bolditalic.eot differ diff --git a/_static/fonts/Lato/lato-bolditalic.ttf b/_static/fonts/Lato/lato-bolditalic.ttf new file mode 100644 index 00000000..f402040b Binary files /dev/null and b/_static/fonts/Lato/lato-bolditalic.ttf differ diff --git a/_static/fonts/Lato/lato-bolditalic.woff b/_static/fonts/Lato/lato-bolditalic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/_static/fonts/Lato/lato-bolditalic.woff differ diff --git a/_static/fonts/Lato/lato-bolditalic.woff2 b/_static/fonts/Lato/lato-bolditalic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/_static/fonts/Lato/lato-bolditalic.woff2 differ diff --git a/_static/fonts/Lato/lato-italic.eot b/_static/fonts/Lato/lato-italic.eot new file mode 100644 index 00000000..3f826421 Binary files /dev/null and b/_static/fonts/Lato/lato-italic.eot differ diff --git a/_static/fonts/Lato/lato-italic.ttf b/_static/fonts/Lato/lato-italic.ttf new file mode 100644 index 00000000..b4bfc9b2 Binary files /dev/null and b/_static/fonts/Lato/lato-italic.ttf differ diff --git a/_static/fonts/Lato/lato-italic.woff b/_static/fonts/Lato/lato-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/_static/fonts/Lato/lato-italic.woff differ diff --git a/_static/fonts/Lato/lato-italic.woff2 b/_static/fonts/Lato/lato-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/_static/fonts/Lato/lato-italic.woff2 differ diff --git a/_static/fonts/Lato/lato-regular.eot b/_static/fonts/Lato/lato-regular.eot new file mode 100644 index 00000000..11e3f2a5 Binary files /dev/null and b/_static/fonts/Lato/lato-regular.eot differ diff --git a/_static/fonts/Lato/lato-regular.ttf b/_static/fonts/Lato/lato-regular.ttf new file mode 100644 index 00000000..74decd9e Binary files /dev/null and b/_static/fonts/Lato/lato-regular.ttf differ diff --git a/_static/fonts/Lato/lato-regular.woff b/_static/fonts/Lato/lato-regular.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/_static/fonts/Lato/lato-regular.woff differ diff --git a/_static/fonts/Lato/lato-regular.woff2 b/_static/fonts/Lato/lato-regular.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/_static/fonts/Lato/lato-regular.woff2 differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot new file mode 100644 index 00000000..79dc8efe Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf new file mode 100644 index 00000000..df5d1df2 Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot new file mode 100644 index 00000000..2f7ca78a Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf new file mode 100644 index 00000000..eb52a790 Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 differ diff --git a/_static/jquery.js b/_static/jquery.js new file mode 100644 index 00000000..c4c6022f --- /dev/null +++ b/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t a.language.name.localeCompare(b.language.name)); + + const languagesHTML = ` +
+
Languages
+ ${languages + .map( + (translation) => ` +
+ ${translation.language.code} +
+ `, + ) + .join("\n")} +
+ `; + return languagesHTML; + } + + function renderVersions(config) { + if (!config.versions.active.length) { + return ""; + } + const versionsHTML = ` +
+
Versions
+ ${config.versions.active + .map( + (version) => ` +
+ ${version.slug} +
+ `, + ) + .join("\n")} +
+ `; + return versionsHTML; + } + + function renderDownloads(config) { + if (!Object.keys(config.versions.current.downloads).length) { + return ""; + } + const downloadsNameDisplay = { + pdf: "PDF", + epub: "Epub", + htmlzip: "HTML", + }; + + const downloadsHTML = ` +
+
Downloads
+ ${Object.entries(config.versions.current.downloads) + .map( + ([name, url]) => ` +
+ ${downloadsNameDisplay[name]} +
+ `, + ) + .join("\n")} +
+ `; + return downloadsHTML; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const flyout = ` +
+ + Read the Docs + v: ${config.versions.current.slug} + + +
+
+ ${renderLanguages(config)} + ${renderVersions(config)} + ${renderDownloads(config)} +
+
On Read the Docs
+
+ Project Home +
+
+ Builds +
+
+ Downloads +
+
+
+
Search
+
+
+ +
+
+
+
+ + Hosted by Read the Docs + +
+
+ `; + + // Inject the generated flyout into the body HTML element. + document.body.insertAdjacentHTML("beforeend", flyout); + + // Trigger the Read the Docs Addons Search modal when clicking on the "Search docs" input from inside the flyout. + document + .querySelector("#flyout-search-form") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); + }) +} + +if (themeLanguageSelector || themeVersionSelector) { + function onSelectorSwitch(event) { + const option = event.target.selectedIndex; + const item = event.target.options[option]; + window.location.href = item.dataset.url; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const versionSwitch = document.querySelector( + "div.switch-menus > div.version-switch", + ); + if (themeVersionSelector) { + let versions = config.versions.active; + if (config.versions.current.hidden || config.versions.current.type === "external") { + versions.unshift(config.versions.current); + } + const versionSelect = ` + + `; + + versionSwitch.innerHTML = versionSelect; + versionSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + + const languageSwitch = document.querySelector( + "div.switch-menus > div.language-switch", + ); + + if (themeLanguageSelector) { + if (config.projects.translations.length) { + // Add the current language to the options on the selector + let languages = config.projects.translations.concat( + config.projects.current, + ); + languages = languages.sort((a, b) => + a.language.name.localeCompare(b.language.name), + ); + + const languageSelect = ` + + `; + + languageSwitch.innerHTML = languageSelect; + languageSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + else { + languageSwitch.remove(); + } + } + }); +} + +document.addEventListener("readthedocs-addons-data-ready", function (event) { + // Trigger the Read the Docs Addons Search modal when clicking on "Search docs" input from the topnav. + document + .querySelector("[role='search'] input") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); +}); \ No newline at end of file diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 00000000..c7fe6c6f --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,192 @@ +/* + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 00000000..d96755fd Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/orbbec-light_no_colour.svg b/_static/orbbec-light_no_colour.svg new file mode 100644 index 00000000..a3b6a754 --- /dev/null +++ b/_static/orbbec-light_no_colour.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/orbbec_footerlogo_3d_world.svg b/_static/orbbec_footerlogo_3d_world.svg new file mode 100644 index 00000000..7f702a6d --- /dev/null +++ b/_static/orbbec_footerlogo_3d_world.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_static/orbbec_logo.png b/_static/orbbec_logo.png new file mode 100644 index 00000000..7a60b4c3 Binary files /dev/null and b/_static/orbbec_logo.png differ diff --git a/_static/orbbec_logo2.png b/_static/orbbec_logo2.png new file mode 100644 index 00000000..3cd81012 Binary files /dev/null and b/_static/orbbec_logo2.png differ diff --git a/_static/orbbec_logo4.png b/_static/orbbec_logo4.png new file mode 100644 index 00000000..92f681ca Binary files /dev/null and b/_static/orbbec_logo4.png differ diff --git a/_static/orbbec_only_english_logo.svg b/_static/orbbec_only_english_logo.svg new file mode 100644 index 00000000..775cbc0b --- /dev/null +++ b/_static/orbbec_only_english_logo.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 00000000..7107cec9 Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 00000000..6f8b210a --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #F00 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666 } /* Operator */ +.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #9C6500 } /* Comment.Preproc */ +.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #E40000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #008400 } /* Generic.Inserted */ +.highlight .go { color: #717171 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #04D } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #687822 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */ +.highlight .no { color: #800 } /* Name.Constant */ +.highlight .nd { color: #A2F } /* Name.Decorator */ +.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #00F } /* Name.Function */ +.highlight .nl { color: #767600 } /* Name.Label */ +.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #BBB } /* Text.Whitespace */ +.highlight .mb { color: #666 } /* Literal.Number.Bin */ +.highlight .mf { color: #666 } /* Literal.Number.Float */ +.highlight .mh { color: #666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666 } /* Literal.Number.Oct */ +.highlight .sa { color: #BA2121 } /* Literal.String.Affix */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #A45A77 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #00F } /* Name.Function.Magic */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .vm { color: #19177C } /* Name.Variable.Magic */ +.highlight .il { color: #666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 00000000..91f4be57 --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,635 @@ +/* + * Sphinx JavaScript utilities for the full-text search. + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename, kind] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename, kind] = item; + + let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + SearchResultKind.title, + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + SearchResultKind.object, + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + // find documents, if any, containing the query word in their text/title term indices + // use Object.hasOwnProperty to avoid mismatching against prototype properties + const arr = [ + { files: terms.hasOwnProperty(word) ? terms[word] : undefined, score: Scorer.term }, + { files: titleTerms.hasOwnProperty(word) ? titleTerms[word] : undefined, score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, new Map()); + const fileScores = scoreMap.get(file); + fileScores.set(word, record.score); + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file).get(w))); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + SearchResultKind.text, + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 00000000..8a96c69a --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/_static/theme.js b/_static/theme.js new file mode 100644 index 00000000..966d5ee6 --- /dev/null +++ b/_static/theme.js @@ -0,0 +1,212 @@ +// 创建一个自执行的函数,用于封装模块定义和执行逻辑 +!function (n) { + // 定义模块存储对象和模块导出相关函数 + var e = {}; + function t(i) { + // 模块缓存逻辑,避免重复执行 + if (e[i]) return e[i].exports; + var o = e[i] = { i: i, l: !1, exports: {} }; + // 执行模块定义函数并缓存结果 + return n[i].call(o.exports, o, o.exports, t), + o.l = !0, + o.exports + } + // 初始化模块系统,定义模块数组、缓存对象、导出函数等 + t.m = n, + t.c = e, + t.d = function (n, e, i) { + t.o(n, e) || Object.defineProperty(n, e, { enumerable: !0, get: i }) + }, + t.r = function (n) { + "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }), + Object.defineProperty(n, "__esModule", { value: !0 }) + }, + t.t = function (n, e) { + if (1 & e && (n = t(n)), 8 & e) return n; + if (4 & e && "object" == typeof n && n && n.__esModule) return n; + var i = Object.create(null); + if (t.r(i), Object.defineProperty(i, "default", { enumerable: !0, value: n }), + 2 & e && "string" != typeof n) for (var o in n) + t.d(i, o, function (e) { return n[e] }.bind(null, o)); + return i + }, + t.n = function (n) { + var e = n && n.__esModule ? function () { return n.default } : function () { return n }; + return t.d(e, "a", e), e + }, + t.o = function (n, e) { return Object.prototype.hasOwnProperty.call(n, e) }, + t.p = "", + // 执行入口模块 + t(t.s = 0) +}([ + // 定义模块数组,每个模块是一个函数 + function (n, e, t) { + // 执行依赖模块并导出结果 + t(1), + n.exports = t(3) + }, + function (n, e, t) { + // 根据环境获取jQuery对象 + (function () { + var e = "undefined" != typeof window ? window.jQuery : t(2); + // 定义并导出ThemeNav对象 + n.exports.ThemeNav = { + navBar: null, + win: null, + winScroll: !1, + winResize: !1, + linkScroll: !1, + winPosition: 0, + winHeight: null, + docHeight: null, + isRunning: !1, + // 启用导航栏功能 + enable: function (n) { + var t = this; + void 0 === n && (n = !0), + t.isRunning || (t.isRunning = !0, + e((function (e) { + t.init(e), + t.reset(), + t.win.on("hashchange", t.reset), + n && t.win.on("scroll", (function () { + t.linkScroll || t.winScroll || (t.winScroll = !0, + requestAnimationFrame((function () { + t.onScroll() + }))) + })), + t.win.on("resize", (function () { + t.winResize || (t.winResize = !0, + requestAnimationFrame((function () { + t.onResize() + }))) + })), + t.onResize() + }))) + }, + // 启用粘性导航栏 + enableSticky: function () { + this.enable(!0) + }, + // 初始化导航栏 + init: function (n) { + n(document); + var e = this; + this.navBar = n("div.wy-side-scroll:first"), + this.win = n(window), + n(document).on("click", "[data-toggle='wy-nav-top']", (function () { + n("[data-toggle='wy-nav-shift']").toggleClass("shift"), + n("[data-toggle='rst-versions']").toggleClass("shift") + })).on("click", ".wy-menu-vertical .current ul li a", (function () { + var t = n(this); + n("[data-toggle='wy-nav-shift']").removeClass("shift"), + n("[data-toggle='rst-versions']").toggleClass("shift"), + e.toggleCurrent(t), + e.hashChange() + })).on("click", "[data-toggle='rst-current-version']", (function () { + n("[data-toggle='rst-versions']").toggleClass("shift-up") + })), + n("table.docutils:not(.field-list,.footnote,.citation)").wrap("
"), + n("table.docutils.footnote").wrap("
"), + n("table.docutils.citation").wrap("
"), + n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function () { + var t = n(this); + expand = n(''), + expand.on("click", (function (n) { + return e.toggleCurrent(t), + n.stopPropagation(), + !1 + })), + t.prepend(expand) + })) + }, + // 重置导航栏状态 + reset: function () { + var n = encodeURI(window.location.hash) || "#"; + try { + var e = $(".wy-menu-vertical"), + t = e.find('[href="' + n + '"]'); + if (0 === t.length) { + var i = $('.document [id="' + n.substring(1) + '"]').closest("div.section"); + 0 === (t = e.find('[href="#' + i.attr("id") + '"]')).length && (t = e.find('[href="#"]')) + } + if (t.length > 0) { + $(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded", "false"), + t.addClass("current").attr("aria-expanded", "true"), + t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded", "true"); + for (let n = 1; n <= 10; n++) + t.closest("li.toctree-l" + n).addClass("current").attr("aria-expanded", "true"); + t[0].scrollIntoView() + } + } catch (n) { + console.log("Error expanding nav for anchor", n) + } + }, + // 滚动事件处理 + onScroll: function () { + this.winScroll = !1; + var n = this.win.scrollTop(), + e = n + this.winHeight, + t = this.navBar.scrollTop() + (n - this.winPosition); + n < 0 || e > this.docHeight || (this.navBar.scrollTop(t), + this.winPosition = n) + }, + // 窗口大小变化事件处理 + onResize: function () { + this.winResize = !1, + this.winHeight = this.win.height(), + this.docHeight = $(document).height() + }, + // hash变化事件处理 + hashChange: function () { + this.linkScroll = !0, + this.win.one("hashchange", (function () { + this.linkScroll = !1 + })) + }, + // 切换当前导航项 + toggleCurrent: function (n) { + var e = n.closest("li"); + // 20201030 a + e.siblings("li.current").removeClass("current").attr("aria-expanded", "false"), + e.siblings().find("li.current").removeClass("current").attr("aria-expanded", "false"); + var t = e.find("> ul li"); + t.length && (t.removeClass("current").attr("aria-expanded", "false"), + e.toggleClass("current").attr("aria-expanded", (function (n, e) { + return "true" == e ? "false" : "true" + }))) + } + }, + "undefined" != typeof window && (window.SphinxRtdTheme = { + Navigation: n.exports.ThemeNav, + StickyNav: n.exports.ThemeNav + }), + // 实现跨浏览器的requestAnimationFrame和cancelAnimationFrame方法 + function () { + for (var n = 0, e = ["ms", "moz", "webkit", "o"], t = 0; t < e.length && !window.requestAnimationFrame; ++t) + window.requestAnimationFrame = window[e[t] + "RequestAnimationFrame"], + window.cancelAnimationFrame = window[e[t] + "CancelAnimationFrame"] || window[e[t] + "CancelRequestAnimationFrame"]; + window.requestAnimationFrame || (window.requestAnimationFrame = function (e, t) { + var i = (new Date).getTime(), + o = Math.max(0, 16 - (i - n)), + r = window.setTimeout((function () { + e(i + o) + }), o); + return n = i + o, + r + }), + window.cancelAnimationFrame || (window.cancelAnimationFrame = function (n) { + clearTimeout(n) + }) + }() + }).call(window) + }, + function (n, e) { + // 导出jQuery对象 + n.exports = jQuery + }, + function (n, e, t) { + // 未定义的模块体 + } +]); + diff --git a/genindex.html b/genindex.html new file mode 100644 index 00000000..35fe89c3 --- /dev/null +++ b/genindex.html @@ -0,0 +1,376 @@ + + + + + + + + Index — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..88aefbb5 --- /dev/null +++ b/index.html @@ -0,0 +1,535 @@ + + + + + + + + + OrbbecSDK V2 ROS2 Wrapper documentation — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

OrbbecSDK V2 ROS2 Wrapper documentation

+
+ +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 00000000..fd38ea1a Binary files /dev/null and b/objects.inv differ diff --git a/search.html b/search.html new file mode 100644 index 00000000..f2b1119d --- /dev/null +++ b/search.html @@ -0,0 +1,391 @@ + + + + + + + + Search — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 00000000..89d43889 --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles":{"Additional Parameter Settings":[[23,"additional-parameter-settings"]],"Additional Troubleshooting":[[32,"additional-troubleshooting"]],"Adjusting System Parameters":[[22,"adjusting-system-parameters"]],"Advanced Guide":[[14,null]],"Aligning Depth to Color in ROS 2":[[15,null]],"All Streams":[[12,"all-streams"]],"All available services for camera control":[[12,null]],"Analysis tools":[[28,"analysis-tools"]],"Analyzing camera image data":[[28,"analyzing-camera-image-data"]],"Application Guide":[[10,null]],"Available Topics":[[13,null]],"Basic & General Parameters":[[11,"basic-general-parameters"]],"Build from Source":[[5,null]],"Build your First Camera Application":[[8,"build-your-first-camera-application"]],"Building a Debian Package":[[17,null]],"Building the Package":[[17,"building-the-package"]],"Call a service":[[8,"call-a-service"]],"Camera Configuration":[[28,"camera-configuration"]],"Camera Setup":[[25,"camera-setup"]],"Camera configuration (launch files)":[[16,"camera-configuration-launch-files"]],"Camera pictures naming format":[[28,"camera-pictures-naming-format"]],"Checking camera port with OrbbecSDK_ROS2":[[27,"checking-camera-port-with-orbbecsdk-ros2"]],"Color Stream":[[11,"color-stream"],[12,"color-stream"]],"Command to Enable Colored Point Cloud":[[30,"command-to-enable-colored-point-cloud"]],"Command to Enable Depth Point Cloud":[[30,"command-to-enable-depth-point-cloud"]],"Commands to Align and View Depth and Color Images":[[15,"commands-to-align-and-view-depth-and-color-images"]],"Config.ini":[[28,"config-ini"]],"Configuration File: shm_fastdds.xml":[[22,"configuration-file-shm-fastdds-xml"]],"Configuration of depth NFOV and WFOV modes":[[18,null]],"Configuring ROS Dependencies":[[17,"configuring-ros-dependencies"]],"Core & Stream Configuration":[[11,"core-stream-configuration"]],"Data Capture & Calibration Management":[[12,"data-capture-calibration-management"]],"Depth Filter Configuration":[[12,"depth-filter-configuration"]],"Depth Filters":[[11,"depth-filters"]],"Depth Stream":[[11,"depth-stream"],[12,"depth-stream"]],"Depth work mode switch":[[19,null]],"Device Information & Management":[[12,"device-information-management"]],"Device Status & Diagnostics":[[13,"device-status-diagnostics"]],"Device, Sync & Advanced Features":[[11,"device-sync-advanced-features"]],"Device-Specific":[[11,"device-specific"]],"DevicesInfo.txt":[[28,"devicesinfo-txt"]],"Directory Structure":[[28,"directory-structure"]],"Disparity":[[11,"disparity"]],"Disparity_search_offset":[[20,null]],"Docs\u5e94\u7528\u6587\u6863":[[0,null]],"Echo a topic":[[8,"echo-a-topic"]],"Efficient intra-process communication:":[[21,null]],"Enabling Colored Point Cloud":[[30,"enabling-colored-point-cloud"]],"Enabling Depth Point Cloud":[[30,"enabling-depth-point-cloud"]],"Enabling and Visualizing Point Cloud in ROS 2":[[30,null]],"Environment":[[5,"environment"]],"Environment Variables":[[22,"environment-variables"]],"Example":[[21,"example"]],"Example Visualization":[[24,"example-visualization"]],"Example of Depth to Color Overlay":[[15,"example-of-depth-to-color-overlay"]],"Fast DDS Configuration":[[22,"fast-dds-configuration"]],"Fast DDS Optimization for Orbbec Camera with ROS2":[[22,null]],"Femto Mega & Gemini 435Le":[[29,"femto-mega-gemini-435le"]],"Files that need to be changed":[[28,"files-that-need-to-be-changed"]],"Filter Configuration Impact":[[25,"filter-configuration-impact"]],"Firmware & Backend":[[11,"firmware-backend"]],"Frequently Asked Questions":[[32,null]],"Function Introduction":[[20,"function-introduction"]],"Further Optimizationa":[[25,"further-optimizationa"]],"GMSL_camera":[[23,null]],"Gemini 335Le":[[29,"gemini-335le"]],"Hardware Configuration":[[25,"hardware-configuration"]],"IMU":[[11,"imu"]],"IMU Topics":[[13,"imu-topics"]],"IP Fragmentation Memory Threshold":[[22,"ip-fragmentation-memory-threshold"]],"IP Fragmentation Time":[[22,"ip-fragmentation-time"]],"IR Stream":[[11,"ir-stream"],[12,"ir-stream"]],"Image Streams":[[13,"image-streams"]],"Image topic frame rate too low from Multiple Cameras":[[26,"image-topic-frame-rate-too-low-from-multiple-cameras"]],"Installation":[[6,null]],"Interleave AE Mode":[[11,"interleave-ae-mode"]],"Introduction":[[2,null],[8,"introduction"]],"Laser / LDP":[[11,"laser-ldp"]],"Launch Files Used for Testing":[[25,"launch-files-used-for-testing"]],"Launch parameters":[[11,null]],"License":[[33,null]],"Limitations":[[21,"limitations"]],"Linux ROS2 Wrapper Compilation":[[5,"linux-ros2-wrapper-compilation"]],"List available topics / services/ parameters":[[8,"list-available-topics-services-parameters"]],"Logging & Diagnostics":[[11,"logging-diagnostics"]],"Manually loading multiple components into the same process":[[21,"manually-loading-multiple-components-into-the-same-process"]],"Maximum Buffer Sizes":[[22,"maximum-buffer-sizes"]],"Miscellaneous":[[11,"miscellaneous"]],"Multi GMSL camera":[[23,"multi-gmsl-camera"]],"Multi GMSL camera synced":[[23,"multi-gmsl-camera-synced"]],"Multi Net camera":[[29,"multi-net-camera"]],"Multi-Camera":[[26,null]],"Multi-Camera Synchronization":[[11,"multi-camera-synchronization"]],"Multi_camera synced Instructions":[[27,null]],"Multi_camera_synced + Interleave_ae":[[24,"multi-camera-synced-interleave-ae"]],"Multi_camera_synced_verification_tool":[[28,null]],"Net_camera":[[29,null]],"Network Cameras":[[11,"network-cameras"]],"No Data Stream from Multiple Cameras":[[26,"no-data-stream-from-multiple-cameras"],[32,"no-data-stream-from-multiple-cameras"]],"Ob_benchmark tool":[[16,null]],"Orbbec SDK Overview":[[3,null]],"Orbbec SDK v2 Architecture Overview":[[3,"orbbec-sdk-v2-architecture-overview"]],"OrbbecSDK V2 ROS2 Wrapper documentation":[[1,null]],"OrbbecSDK_ROS2 multi-camera synced configuration":[[27,"orbbecsdk-ros2-multi-camera-synced-configuration"]],"Output Data Files":[[16,"output-data-files"]],"Overview":[[4,null]],"Parameter Introduction":[[20,"parameter-introduction"],[24,"parameter-introduction"],[29,"parameter-introduction"]],"Point Cloud Topics":[[13,"point-cloud-topics"]],"Predefined presets":[[31,null]],"Preparation for operation":[[28,"preparation-for-operation"]],"Preparing the Environment":[[17,"preparing-the-environment"]],"Python":[[28,"python"]],"QuickStarts":[[8,null]],"Quickstarts":[[9,null]],"ROS Configuration":[[25,"ros-configuration"]],"Recommended Settings for Lower CPU Usage":[[25,"recommended-settings-for-lower-cpu-usage"]],"Record with rosbag2":[[8,"record-with-rosbag2"]],"Reducing CPU Usage with Orbbec ROS Package":[[25,null]],"Registration script (required)":[[7,null]],"Run launch and save camera pictures":[[28,"run-launch-and-save-camera-pictures"]],"Run the following command to start the multi-camera synced":[[27,"run-the-following-command-to-start-the-multi-camera-synced"]],"Run the launch":[[20,"run-the-launch"],[23,"run-the-launch"],[24,"run-the-launch"]],"Run this example":[[28,"run-this-example"]],"Running the ob_benchmark tool":[[16,"running-the-ob-benchmark-tool"]],"SDK Concept Overview":[[3,"sdk-concept-overview"]],"SDK Programming Model":[[3,"sdk-programming-model"]],"Sample Features":[[8,"sample-features"]],"Selecting Topics in RViz2":[[15,"selecting-topics-in-rviz2"]],"Sensor & Emitter Control":[[12,"sensor-emitter-control"]],"Sensor Controls":[[11,"sensor-controls"]],"Setup instructions":[[27,"setup-instructions"]],"Single GMSL camera":[[23,"single-gmsl-camera"]],"Single Net camera":[[29,"single-net-camera"],[29,"id1"]],"Step 1: Source ROS 2 and Workspace":[[8,"step-1-source-ros-2-and-workspace"]],"Step 2: Launch the Camera Node":[[8,"step-2-launch-the-camera-node"]],"Step 3: Visualize in RViz2":[[8,"step-3-visualize-in-rviz2"]],"Stream Control":[[12,"stream-control"]],"Support Hardware Products":[[2,"support-hardware-products"]],"Support Platforms":[[2,"support-platforms"]],"Synchronization & Triggering":[[12,"synchronization-triggering"]],"TF, Extrinsics & Calibration":[[11,"tf-extrinsics-calibration"]],"Terms":[[3,"terms"]],"Test Results":[[25,"test-results"]],"Test Setup":[[25,"test-setup"]],"Test environment":[[25,"test-environment"]],"Time Synchronization":[[11,"time-synchronization"]],"Tool Configuration (start_benchmark_params.json)":[[16,"tool-configuration-start-benchmark-params-json"]],"Unexpected Crash":[[32,"unexpected-crash"]],"Usage Instructions":[[16,"usage-instructions"]],"Using a launch file":[[21,"using-a-launch-file"]],"Using interleave_ae with Gemini330 series cameras":[[24,null]],"Visualizing Colored Point Cloud in RViz2":[[30,"visualizing-colored-point-cloud-in-rviz2"]],"Visualizing Depth Point Cloud in RViz2":[[30,"visualizing-depth-point-cloud-in-rviz2"]],"Why Are There So Many Launch Files?":[[32,"why-are-there-so-many-launch-files"]],"color_format Comparison (MJPG vs RGB)":[[25,"color-format-comparison-mjpg-vs-rgb"]],"interleave hdr":[[24,"interleave-hdr"]],"interleave laser":[[24,"interleave-laser"]],"multicamera_sync":[[28,"multicamera-sync"]],"output":[[28,"output"]],"save_rgbir node":[[28,"save-rgbir-node"]],"uvc_backend Comparison (RGB format)":[[25,"uvc-backend-comparison-rgb-format"]],"\u7f16\u8bd1":[[0,"id2"]],"\u7f16\u8bd1\u73af\u5883":[[0,"id1"]],"\u7f16\u8bd1\u7ed3\u679c":[[0,"id3"]]},"docnames":["README","index","source/1_overview/introduction","source/1_overview/orbbecsdk_overview","source/1_overview/overview","source/2_installation/build_the_package","source/2_installation/installation","source/2_installation/registration_script","source/3_quickstarts/quickstart","source/3_quickstarts/quickstarts","source/4_application_guide/application_guide","source/4_application_guide/launch_parameters","source/4_application_guide/services","source/4_application_guide/topics","source/5_advanced_guide/advanced_guide","source/5_advanced_guide/align_depth_color","source/5_advanced_guide/benchmark","source/5_advanced_guide/building_a_Debian_Package","source/5_advanced_guide/configuration_of_depth_NFOV_and_WFOV_modes","source/5_advanced_guide/depth_work_mode_switch","source/5_advanced_guide/disparity_search_offset","source/5_advanced_guide/efficient_intra_process_communication","source/5_advanced_guide/fastdds_tuning","source/5_advanced_guide/gmsl_camera","source/5_advanced_guide/interleave_ae_mode","source/5_advanced_guide/lower_cpu_usage","source/5_advanced_guide/multi_camera","source/5_advanced_guide/multi_camera_synced","source/5_advanced_guide/multi_camera_synced_verification_tool","source/5_advanced_guide/net_camera","source/5_advanced_guide/point_cloud","source/5_advanced_guide/predefined_presets","source/6_FAQ/FAQ","source/license"],"envversion":{"sphinx":65,"sphinx.domains.c":3,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":9,"sphinx.domains.index":1,"sphinx.domains.javascript":3,"sphinx.domains.math":2,"sphinx.domains.python":4,"sphinx.domains.rst":2,"sphinx.domains.std":2},"filenames":["README.md","index.rst","source/1_overview/introduction.md","source/1_overview/orbbecsdk_overview.md","source/1_overview/overview.rst","source/2_installation/build_the_package.md","source/2_installation/installation.rst","source/2_installation/registration_script.md","source/3_quickstarts/quickstart.md","source/3_quickstarts/quickstarts.rst","source/4_application_guide/application_guide.rst","source/4_application_guide/launch_parameters.md","source/4_application_guide/services.md","source/4_application_guide/topics.md","source/5_advanced_guide/advanced_guide.rst","source/5_advanced_guide/align_depth_color.md","source/5_advanced_guide/benchmark.md","source/5_advanced_guide/building_a_Debian_Package.md","source/5_advanced_guide/configuration_of_depth_NFOV_and_WFOV_modes.md","source/5_advanced_guide/depth_work_mode_switch.md","source/5_advanced_guide/disparity_search_offset.md","source/5_advanced_guide/efficient_intra_process_communication.md","source/5_advanced_guide/fastdds_tuning.md","source/5_advanced_guide/gmsl_camera.md","source/5_advanced_guide/interleave_ae_mode.md","source/5_advanced_guide/lower_cpu_usage.md","source/5_advanced_guide/multi_camera.md","source/5_advanced_guide/multi_camera_synced.md","source/5_advanced_guide/multi_camera_synced_verification_tool.md","source/5_advanced_guide/net_camera.md","source/5_advanced_guide/point_cloud.md","source/5_advanced_guide/predefined_presets.md","source/6_FAQ/FAQ.md","source/license.md"],"indexentries":{},"objects":{},"objnames":{},"objtypes":{},"terms":{"":[2,3,11,13,15,19,26,28,29,32],"0":[2,11,12,16,20,22,24,25,28,33],"00":[17,24,28],"0002965621242765337":12,"0003024190664291382":12,"0003368517500348389":12,"0012007878394797444":12,"001202247804030776":12,"004874417092651129":12,"004874777048826218":12,"01":[2,28],"01115430984646082":12,"02":28,"023897956848144532":12,"03131488710641861":12,"032955970615148544":12,"04":[2,25],"05":12,"06":12,"096559369936585e":12,"0th":[11,28],"1":[2,3,11,12,16,20,22,23,24,25,26,28,29],"10":[3,22,25,28,29],"100":[11,28],"1000000":22,"1024":18,"1048576":22,"11":3,"115":25,"117":20,"118":25,"12":3,"125gemini":20,"127":[20,22],"1279":12,"128":[20,22,25,26,32],"1280":20,"128mb":[26,32],"13":3,"134217728":22,"14":3,"15":3,"151":20,"152":25,"158":20,"16":[3,28],"160":12,"164":25,"1660ti":25,"168":29,"169":20,"16dp":11,"16g":11,"17":3,"170":25,"172":20,"1739874543227":28,"1739874543327":28,"178":20,"18":28,"180":[11,12],"182":25,"184gemini":20,"186":25,"19":16,"192":29,"1mm":11,"1st":11,"1x":25,"2":[1,2,3,5,11,14,19,22,25,26,27,28,33],"20":2,"2000dp":11,"2024":[2,33],"2025":28,"20250218102900":28,"20ghz":25,"2147483647":22,"217":25,"218":25,"22":2,"2200":25,"226":20,"233":20,"236":20,"24":25,"249gemini":20,"251":25,"255":20,"256":20,"256gb":25,"25_163648":28,"262144":22,"270":11,"2800":12,"286":25,"288":18,"29":28,"2g":11,"2x":25,"3":[2,3,11,22,25,28],"30":[16,22],"300":16,"3000":12,"302":20,"30fp":25,"31":2,"317":20,"320":18,"32khz":11,"33":25,"330":[2,20,23,24,25,29],"330l":2,"334":20,"335":[2,20,25],"335l":[2,20],"335le":[1,2,11,14],"335lg":[2,23],"336":[2,25],"336l":[2,25],"347":25,"349":20,"35":25,"388":20,"391":12,"3d":[3,8],"4":[2,3,20,24,25,26],"400":20,"406":20,"407470703125":12,"435le":[1,2,12,14],"439220279455185e":12,"45":20,"453":20,"46":2,"469":25,"475":20,"479":12,"480":25,"4g":11,"5":[2,3,12,25],"50":[17,28],"50hz":11,"51":25,"512":18,"53":2,"5625hz":11,"576":18,"6":[3,12,25,26,28],"60":20,"60hz":11,"614":12,"634":12,"64":[12,20,25],"640":[18,20],"65000":22,"65771484375":12,"68":25,"7":[3,25,27],"719":12,"720":20,"8":[2,3,12,22,25,27],"800":20,"804073229432106e":12,"8090":[11,29],"847":12,"848":25,"85":20,"8700":25,"8g":11,"9":[3,12,25],"90":11,"91552734375":12,"92":2,"9613647460938":12,"9999874234199524":12,"9999880790710449":12,"9999992251396179":12,"A":28,"AND":13,"AS":33,"By":[13,23],"For":[2,8,11,16,18,20,22,23,27,29,31],"If":[2,7,8,11,15,19,20,23,26,28,29,32],"In":[3,11,16,18,23,25,28,31],"It":[2,3,11],"Its":3,"No":[1,14,25],"OF":33,"OR":33,"On":8,"One":3,"Or":8,"The":[2,3,11,12,13,16,18,19,20,23,24,25,27,28,30],"Their":13,"There":1,"These":[11,13],"To":[7,15,16,23,25,26,30,32],"With":2,"_":[1,11,14,16,18,19,20,23,24,25,26,27,28,29,32],"_build":0,"_camera_info_qo":11,"_flip":11,"_index":11,"_mirror":11,"_qo":11,"_rotat":11,"abl":15,"about":[3,13],"abov":[15,30,31],"absolut":25,"abstract":3,"accel":13,"accel_gyro":11,"accel_r":11,"accel_rang":11,"acceler":11,"acceleromet":[11,13],"access":3,"accord":[5,27],"accuraci":[28,31],"achiev":[25,31],"acquisit":[3,28],"action":[26,28],"activ":[15,28,30,32],"actual":3,"ad":[2,22,25],"add":[8,17,21,22,26,30],"addit":1,"address":[11,22,29],"adher":2,"adjust":[1,2,14,20,26,32],"administr":7,"advanc":[1,10],"ae":[1,14,24,31],"affect":22,"after":[3,8,11,15,28,30],"again":[20,24],"aggreg":[3,11],"agre":33,"agx":2,"aim":22,"algorithm":3,"align":[1,3,11,14,25,30],"align_mod":[11,25],"align_target_stream":11,"alik":3,"all":[1,2,10,11,13,22],"allow":[3,7,9,22,25],"alon":25,"also":[3,20],"altern":[22,31],"ament_index_python":26,"amp":31,"an":[3,4,8,15,22,28,29,32,33],"analysi":3,"angular":11,"angular_vel_cov":11,"ani":[11,20,25,33],"anim":31,"anoth":8,"apach":33,"appli":[3,22,25],"applic":[1,3,9,15,33],"appropri":[15,31],"apt":[5,17],"ar":[1,2,3,8,11,12,13,16,18,20,21,22,23,24,28,29],"architectur":[1,4],"arg":[5,17],"argcomplete3":5,"arm64":2,"articl":28,"ask":1,"assist":32,"astra":[2,11],"astra2":2,"asynchron":22,"attempt":11,"attent":2,"attribut":3,"auto":[5,11,24],"automat":[11,22,29],"avail":[1,10,11],"avoid":[11,19,25,31],"backend":25,"background":31,"backlight":11,"backward":[5,11],"bag":8,"balanc":[11,31],"bare":31,"base":[3,25,26,31,32],"bash":[7,8,12,16,17],"basi":33,"basic":[1,3,9,10,15,28],"becom":26,"befor":[17,19],"behavior":[3,13],"being":[2,27],"below":[2,8,15,22,27],"benchmark":[1,14,16,25],"benefit":2,"best":31,"better":31,"between":[18,25,27],"big":21,"bin":[18,19],"bit":3,"bloom":17,"blow":22,"bolt":[2,18,19],"both":[13,20,22,25],"bottom":[11,12],"br":31,"branch":[2,5],"brand":33,"bright":[3,11],"bu":3,"bug":2,"build":[1,6,9,14,20,24],"built":27,"builtin":22,"busi":3,"byte":22,"c":3,"c2d":3,"calibr":[1,10,13],"call":[12,28],"callback":3,"camer":28,"camera":[1,2,3,5,7,9,10,13,14,15,17,19,20,30],"camera_01":[16,26,28],"camera_02":[16,26,28],"camera_03":16,"camera_04":16,"camera_crash_stack_trace_xx":32,"camera_info":[8,13],"camera_link":30,"camera_nam":[11,13,16,26,27,28],"can":[2,3,8,11,12,13,19,20,21,22,25,26,27,28,29,32],"captur":[1,3,10,11],"carefulli":[2,11],"case":[11,31],"caus":11,"cd":[0,5,7,17,28],"certain":3,"chang":[1,3,13,14,17,22,23,25,26,29,32],"chapter":[4,6,9,10,14],"chart":3,"check":[8,26,32],"checkout":5,"china":2,"choos":[30,31],"claim":33,"class":3,"clean":0,"clear":31,"cli":8,"clone":5,"close":3,"cloud":[1,3,8,10,11,14,25],"cloud_frame_id":11,"cmake":[5,17],"codenam":17,"colcon":[5,17,20,24],"collect":[16,27,28],"collis":31,"color":[1,3,8,13,14,23,25,27,28],"color_ae_max_exposur":11,"color_ae_roi_":11,"color_bright":11,"color_contrast":11,"color_decimation_filter_scal":11,"color_delay_u":11,"color_exposur":11,"color_fram":11,"color_gain":11,"color_gamma":11,"color_hu":11,"color_info_url":11,"color_powerline_freq":11,"color_satur":11,"color_sharp":11,"color_white_bal":11,"com":[5,22],"combin":[3,25],"command":[1,8,11,14,16,22,23,26,29,32],"comment":19,"commun":[1,14],"compar":25,"comparison":31,"compat":[2,11,25],"compens":11,"compil":[1,6],"complet":5,"complianc":33,"compon":3,"component_conta":16,"component_contain":21,"componentmanag":21,"compos":21,"composit":3,"compress":[5,21],"comput":[3,27],"concept":[1,4],"condit":[13,33],"conf":22,"confid":31,"config":[3,8],"config_file_path":[11,27],"configur":[1,3,10,14,19,20,23,26,31],"connect":[2,8,11,26,27,32],"connection_delai":11,"consecut":3,"consid":22,"consist":[3,13,18],"console_direct":[5,17],"consum":[21,25],"contain":[3,13,16,21],"contamin":26,"content":3,"context":3,"continu":27,"contrast":[11,25],"control":[1,3,7,10],"convers":11,"convert":3,"coordin":3,"copi":[21,28,33],"copyright":33,"core":[1,3,10,22],"correct":11,"correctli":[7,27],"correspond":[3,11,13,16,18,19,20],"covari":11,"cover":14,"cp1e5420006d":28,"cpu":[1,3,14],"crash":[1,11],"creat":[3,5,15,17],"critic":22,"cross":3,"csv":16,"current":[12,13,16,21,23,27,28,29,32],"custom":[22,31],"cycl":16,"d":[12,17,22],"d16":28,"d2c":[3,11],"d2d":3,"dark":3,"data":[1,3,8,10,11,13,14,22,25,30],"data_param":12,"data_read":22,"data_shar":22,"data_writ":22,"databas":17,"dcmake_build_typ":[5,17],"dd":[1,14,26],"debhelp":17,"debian":[1,14],"debug":[11,32],"decim":11,"decimation_filter_scal":11,"decimationfilt":12,"declarelaunchargu":[19,26],"decod":25,"decreas":22,"def":26,"default":[2,3,8,11,13,19,20,22,23,25,27,29,31,32],"default_valu":19,"defin":[3,20,22,31],"definit":20,"delai":[11,22,27],"demonstr":[3,30],"dens":19,"densiti":31,"depend":[1,5,6,13,14,16],"deprec":11,"depth":[1,3,8,10,13,14,20,24,25,31],"depth_ae_roi_":11,"depth_bright":11,"depth_delay_u":11,"depth_filter_statu":13,"depth_precis":11,"depth_regist":[13,30],"depth_registr":[11,15,25],"depth_work_mod":19,"deriv":31,"describ":[20,23,24,29],"descript":[26,27,28],"detail":[21,22],"detect":11,"dev":5,"develop":10,"devic":[1,2,3,7,8,10,18,23,25,27,28,29],"device_num":[11,26,27],"device_preset":[11,31],"device_statu":13,"diagnost":[1,5,10],"diagnostic_period":11,"differ":[2,3,15,16,18,26,27,32],"dimens":3,"dimension":3,"direct":3,"directli":3,"directori":[1,14,22,32],"disabl":[11,21,25],"dispar":[1,3,14,20],"disparity_offset_config":[11,20],"disparity_range_mod":[11,20],"disparity_search_offset":11,"disparity_to_depth_mod":11,"displai":[8,15,28,30],"distanc":3,"distribut":[2,17,25,33],"do":[11,28,29],"doc":0,"document":[11,22,25,27],"doe":[23,27],"don":26,"driver":3,"due":7,"durat":22,"dure":3,"dynam":3,"e":[12,13,21,31],"e50":28,"each":[3,11,12,13,16,23,26,27,32],"easili":25,"echo":[26,32],"edg":31,"edit":28,"effect":[20,27,28],"effici":[1,14,22],"either":[25,33],"emitt":[1,10],"empti":12,"enabl":[1,3,5,11,12,13,14,15,23,24,29],"enable_accel":[11,13],"enable_accel_data_correct":11,"enable_color":[12,13],"enable_color_auto_exposur":11,"enable_color_auto_exposure_prior":11,"enable_color_auto_white_bal":11,"enable_color_backlight_compens":11,"enable_color_decimation_filt":11,"enable_color_undistort":11,"enable_colored_point_cloud":[11,13,25,30],"enable_d2c_view":[11,15],"enable_decimation_filt":11,"enable_depth_auto_exposure_prior":11,"enable_depth_scal":11,"enable_frame_sync":11,"enable_gmsl_trigg":[11,23],"enable_gyro":[11,13],"enable_gyro_data_correct":11,"enable_hardware_noise_removal_filt":11,"enable_hdr_merg":11,"enable_heartbeat":[11,32],"enable_hole_filling_filt":11,"enable_ir_auto_exposur":11,"enable_las":11,"enable_ldp":11,"enable_noise_removal_filt":11,"enable_point_cloud":[11,13,25,30],"enable_ptp_config":11,"enable_publish_extrins":11,"enable_sequence_id_filt":11,"enable_spatial_fast_filt":11,"enable_spatial_filt":11,"enable_spatial_moderate_filt":11,"enable_sync_host_tim":11,"enable_sync_output_accel_gyro":[11,13],"enable_temporal_filt":11,"enable_threshold_filt":11,"encapsul":3,"encod":[3,22],"encount":[2,32],"encourag":2,"end":28,"energi":11,"enhanc":[2,3,22],"ensur":[2,26,30,32],"enter":30,"enumer":[11,29],"enumerate_net_devic":[11,29],"environ":[1,2,6,8,14],"eprosima":22,"equip":28,"error":11,"especi":21,"essenti":2,"establish":31,"etc":[3,11,16,17,22,31],"eval":5,"event":[5,17],"everi":16,"everyth":28,"exampl":[1,8,9,11,14,16,19,22,23,27,29,30],"except":33,"execut":[7,25,30],"executeprocess":26,"exhibit":22,"exit":22,"explain":[3,6,15,27],"export":22,"exposur":[11,24,28],"express":33,"extens":2,"extern":27,"extrem":3,"f0":28,"fail":7,"failur":2,"fakeroot":17,"fals":[11,12,13,22,25,27,29],"fast":[1,11,14,26],"fastrtp":22,"fastrtps_default_profiles_fil":22,"fastrtps_profil":22,"fatal":11,"featur":[1,3,4,9,10,14,15,30,31,32],"februari":28,"femto":[1,2,14,18,19],"femto_bolt":2,"femto_mega":[2,29],"field":11,"figur":27,"file":[1,2,3,8,11,12,14,17,18,19,23,26,27],"filenam":16,"fill":[11,28,31],"filter":[1,3,10,13],"filter_en":12,"filter_nam":12,"filter_param":12,"final":28,"find":[2,28],"finger":31,"firmwar":[2,3,13,20,24,25,32],"first":[1,9,16,23,28],"fix":[2,30],"flexibl":2,"flip":11,"flood":24,"flow":[3,22,27],"flowchart":3,"focal":17,"focus":25,"folder":[16,28],"follow":[2,11,12,15,16,17,18,19,22,23,25,26,30,32],"for1280":20,"foreground":31,"forget":26,"format":[3,11,32],"found":[19,21,27],"foxi":[2,28],"fp":[11,18,21],"frame":[1,3,11,13,14,18,20,21,23,24,27,28,30],"frame_aggregate_mod":11,"frame_id":11,"framer":28,"frames_per_trigg":11,"frameset":3,"framework":3,"free_run":27,"freq":11,"frequenc":11,"frequent":1,"from":[1,2,3,6,11,13,14,15,16,20,27,30,31],"full":25,"full_fram":11,"function":[1,3,11,13,14,31],"further":[1,14,21,32],"futur":[2,23,29],"g":[12,13,28,31],"g1739874543227":28,"g330":11,"g330_0":27,"gain":[11,24,28],"gamma":11,"gb":25,"gedit":22,"geforc":25,"gemini":[1,2,11,14,19,20,23,24,25],"gemini2":2,"gemini2l":[2,19,26],"gemini330":[1,14,20],"gemini435":29,"gemini435_l":2,"gemini_330_gmsl":23,"gemini_330_seri":[2,8,15,20,24,27,29,30],"gemini_330_series_lower_cpu_usag":25,"gemini_330_series_synced_verifi":28,"gemini_intra_process_demo_launch":21,"gener":[1,3,10,13,28,31,32],"generate_launch_descript":26,"geometr":3,"gestur":31,"get":[3,8,23,26],"get_auto_white_bal":12,"get_color_exposur":12,"get_color_gain":12,"get_depth_exposur":12,"get_depth_gain":12,"get_device_info":[8,12],"get_ir_exposur":12,"get_ir_gain":12,"get_ldp_statu":12,"get_package_share_directori":26,"get_sdk_vers":12,"get_streams_en":12,"get_user_calib_param":12,"get_white_bal":12,"getbool":12,"getdeviceinfo":[8,12],"getint32":12,"getstr":12,"getusercalibparam":12,"git":5,"gite":2,"github":[5,32],"global":[11,28],"glog":5,"glog0v5":5,"gmsl":[1,11,14],"gmsl2":23,"gmsl_trigger_fp":[11,23],"go":[23,26],"goal":16,"good":31,"govern":33,"gpu":25,"group":26,"groupact":[26,28],"gt":31,"gtx":25,"guid":[1,5,9,27],"guidanc":22,"gyro":13,"gyro_accel":13,"gyro_r":11,"gyro_rang":11,"gyroscop":[11,13],"ha":[3,32],"hand":31,"handl":22,"handler":[5,17],"hardwar":[1,3,4,11,23,27],"hardware_noise_removal_filt":25,"hardware_trigg":27,"have":[8,26,32],"hdr":[3,11],"hdr_index0_depth_exposur":24,"hdr_index0_depth_gain":24,"hdr_index0_ir_ae_max_exposur":24,"hdr_index0_ir_bright":24,"hdr_index0_laser_control":24,"hdr_index1_depth_exposur":24,"hdr_index1_depth_gain":24,"hdr_index1_ir_ae_max_exposur":24,"hdr_index1_ir_bright":24,"hdr_index1_laser_control":24,"hdr_merge_exposure_1":11,"heartbeat":11,"height":[11,18],"help":22,"here":[3,15,21,26,29,30],"high":[3,21,22,26,31,32],"higher":31,"highlevel":3,"historymemorypolici":22,"hole":11,"hole_filling_filter_mod":11,"home":22,"host":[3,11,25,27],"hot":11,"how":[3,6,8,11,15,20,23,24,27,28,29,30],"howev":2,"html":0,"http":[5,22,33],"hub":[23,26,32],"hue":11,"humbl":[2,16,17,25],"hw":[11,25],"i":[2,3,7,8,11,12,13,15,16,18,19,20,22,23,24,25,26,27,28,29,30,32,33],"i7":25,"id":[3,11],"ideal":27,"ignor":16,"imag":[1,3,5,8,10,11,14,20,21,22,25,27,32],"image_raw":[8,13,27],"image_transport":21,"immedi":11,"implement":[3,18,25],"impli":33,"import":[11,26,28],"improv":22,"imu":[1,10],"inc":33,"inclin":20,"includ":[3,4,6,10,13,14,20,26],"includelaunchdescript":26,"incom":22,"increas":[22,25,26,32],"index":[0,28],"index0":28,"indic":27,"individu":13,"inerti":13,"info":[5,11],"inform":[1,3,8,10,11,13,15,28,30],"infrar":13,"initi":11,"initialpeerslist":22,"input":[11,27],"insensit":11,"insid":26,"instal":[0,1,5,7,8,16,17],"install_udev_rul":7,"instead":25,"instruct":[1,11,14],"insuffici":[26,32],"integ":20,"integr":2,"intel":25,"intens":[11,31],"interact":8,"interfac":[3,27],"interleav":[1,14,20],"interleave_ae_mod":[11,12,24],"interleave_frame_en":[11,12,24],"interleave_skip_en":[11,24],"interleave_skip_index":[11,24],"intern":[3,25,27],"interv":[11,27],"intra":[1,14],"intrins":3,"introduc":[3,10,28],"introduct":[1,4,9,14],"invalid":11,"invok":3,"ip":[11,29],"ipfrag_high_thresh":22,"ipfrag_tim":22,"ipv4":22,"ir":[3,13,18,23,24,25],"ir_ae_max_exposur":11,"ir_bright":11,"ir_exposur":11,"ir_gain":11,"ir_info_url":11,"is_default_profil":22,"isn":21,"issu":[7,26,32],"item":26,"its":[3,11,32],"itself":3,"jazzi":2,"jetson":2,"join":26,"jpg":28,"json":28,"json3":5,"just":26,"k":12,"kept":22,"kernel":25,"kind":[22,33],"l":[2,19,20],"languag":33,"larger":22,"laser":[3,12],"laser_energy_level":11,"laser_index0_depth_exposur":24,"laser_index0_depth_gain":24,"laser_index0_ir_ae_max_exposur":24,"laser_index0_ir_bright":24,"laser_index0_laser_control":24,"laser_index1_depth_exposur":24,"laser_index1_depth_gain":24,"laser_index1_ir_ae_max_exposur":24,"laser_index1_ir_bright":24,"laser_index1_laser_control":24,"last":[27,28],"latencybudget":22,"later":3,"latest":2,"launch":[1,2,10,12,13,14,15,18,19,26,27,29,30],"launch1_includ":[26,28],"launch2_includ":[26,28],"launch_argu":26,"launch_description_sourc":26,"launch_file_dir":26,"launch_includ":26,"launch_ro":26,"launchdescript":[26,28],"law":33,"layer":3,"ld":[26,28],"ldp":3,"ldp_power_level":11,"le":29,"lead":25,"learn":8,"left":[11,12,20,23,25],"left_ir":[11,13],"length":20,"less":27,"level":[3,11,13,28],"libdw":5,"libgflag":5,"libgoogl":5,"libssl":5,"libuvc":[11,25],"like":[15,16,30],"limit":[27,33],"line":[11,17,22],"linear":11,"linear_accel_cov":11,"link":[11,26,32],"linux":[1,2,6,7,25],"list":[2,3,11,17,30],"list_depth_work_mode_nod":19,"list_devices_nod":[8,23,26,27],"listensocketbuffers":22,"load":[8,25],"locat":[3,22],"log":[3,32],"log_level":[11,32],"logic":3,"longer":[2,11],"look":[15,30],"low":[1,13,14,25],"lower":[1,14,26,31,32],"lowest":25,"lt":31,"m":11,"mai":[2,26,31,33],"main":[2,4,5],"mainli":3,"maintain":25,"major":2,"make":[0,8,17,22,26,27,32],"make_deb":17,"manag":[1,3,5,10],"mandatori":7,"mani":[1,28],"manual":2,"master":27,"match":[3,27,28],"max":22,"maximum":[11,20,24],"maxinitialpeersrang":22,"maxmessages":22,"mb":[22,26,32],"mean":[11,16,27,28,31],"mean_intensity_set_point":11,"measur":13,"medium":31,"mega":[1,2,14,18],"memori":[25,26,32],"merg":11,"messag":[11,13],"metadata":[3,13],"micron":25,"microsecond":11,"might":[15,30],"millisecond":11,"mini":[2,11],"minim":[2,25],"minimum":[20,24],"mirror":11,"mkdir":5,"mm":20,"modal":15,"mode":[1,3,14,20,23,24,27],"model":[1,2,4],"moder":[11,25],"modif":31,"modifi":[11,19,23,28,31],"modul":[3,12,26,32],"monitor":16,"more":[2,3,11,14,22,25,26,31],"most":2,"msg":[5,17],"multi":[1,14,24,28],"multi_camera":26,"multi_camera_lower_cpu_usag":25,"multi_camera_sync":[23,27,28],"multi_camera_synced_verifi":28,"multi_gmsl_camera":23,"multi_gmsl_camera_sync":23,"multi_net_camera":29,"multi_xxx":26,"multicamera":28,"multipl":[1,3,8,11,14,16],"must":[11,18,25,29],"name":[3,11,16,17,22,27,31,33],"namespac":[11,13],"nano":2,"nanosec":22,"navig":17,"need":[1,7,11,14,15,19,21,22,23,26,29,32],"neglig":25,"net":[1,11,14,22],"net_device_ip":[11,29],"net_device_port":[11,29],"network":29,"new":[17,28,31],"next":17,"nfov":[1,14],"nlohmann":5,"node":[11,13,15,21,26,30,32],"nois":[11,31],"noise_removal_filt":25,"noise_removal_filter_min_diff":11,"note":[7,11,12,13,23,25,29],"now":8,"number":[8,11,16,26,28],"nvidia":[2,25],"nvme":25,"nx":2,"o":[25,26],"ob":[1,14,16],"ob_benchmark_0":16,"ob_benchmark_1":16,"ob_benchmark_19":16,"ob_benchmark_nod":16,"obcameranodedriv":21,"object":[3,31],"observ":3,"obstacl":19,"obtain":[3,23,33],"occupi":3,"octob":2,"offici":5,"offset":[1,11,14,20],"offset_index0":20,"offset_index1":20,"one":[3,11,12,15],"onli":[11,12,13,16,20,23,25,28,29],"open":[2,7,11,15,27,30],"openni":2,"oper":[1,3,14,22],"opt":8,"optim":[1,2,14],"optimizationa":[1,14],"option":[8,11,27],"orbbec":[1,2,4,5,6,7,8,11,14,17,19,33],"orbbec_camera":[7,8,15,16,19,20,21,23,24,26,27,28,29,30],"orbbec_camera_msg":[8,12,17,28],"orbbecsdk":[2,3,16,23,25,27,29,32],"orbbecsdk_ros2":[5,7,17,26],"orbbecsdkconfig":3,"orbbecview":[3,11],"ordered_pc":11,"org":33,"organ":13,"origin":3,"orin":2,"other":[2,3,8,21,23,25,28,29,32,33],"otherwis":26,"ouput":28,"our":[20,21,25],"out":11,"outlin":25,"output":[3,11,27,30],"outsid":[3,27],"over":[3,28],"overal":[22,31],"overlai":[1,11,14],"overlaid":3,"overrid":27,"overview":1,"own":32,"p":[5,22],"packag":[1,14,26],"package_dir":26,"packet":22,"pai":2,"panel":30,"param":[8,12,16,23,28],"paramet":[1,2,3,10,13,14,25,26,27,28,31,32],"parameter_ev":11,"particip":22,"participant_profile_ros2":22,"particularli":15,"passiv":27,"patch":25,"path":[11,17,22,26],"pattern":[13,24,27],"per":3,"percept":31,"perform":[2,3,14,16,30,31],"period":[11,28],"perman":[22,26,32],"permiss":[7,33],"pick":31,"pin":27,"pip":0,"pipelin":[3,31],"pixel":[3,20],"place":[22,31],"plai":3,"platform":[1,3,4],"playback":3,"pleas":[2,11,23,24,27,28,32],"plug":[11,23,26],"plugin":5,"point":[1,3,8,10,11,14,16,20,25,31],"point_cloud_qo":11,"pointcloud":21,"pointcloud2":[8,30],"port":[11,26,28,29],"posit":[3,20],"possibl":[11,25],"post":[3,13,31],"power":[3,11,26,32],"preallocated_with_realloc":22,"precis":11,"predefin":[1,14],"prepar":[1,14],"present":3,"preset":[1,11,14],"preset_firmware_path":11,"primari":[2,23,27,28],"primaryserialnumb":28,"prioriti":11,"privileg":7,"pro":[2,23],"proc":22,"process":[1,3,13,14,16,31],"process_nam":16,"product":[1,4],"profil":22,"profile_for_ros2_context":22,"profile_nam":22,"program":[1,4,9],"project":[17,33],"properli":30,"properti":33,"propos":3,"protect":3,"protocol":2,"provid":[2,3,4,8,9,13,22,26,28,32],"ptp":11,"public":11,"publish":[5,11,13,22,27],"publish_tf":11,"publishmod":22,"purpos":[22,27],"put":26,"py":[2,8,15,16,19,20,21,23,24,25,26,27,28,29,30],"python":[3,5,6],"python3":[17,28],"pythonlaunchdescriptionsourc":26,"qo":[11,22],"qualiti":[11,31],"question":1,"quick":[3,8,9],"quickli":[3,9],"quickstart":1,"r":0,"rang":[3,11,20],"rate":[1,3,11,14,23,27,31],"raw":13,"rclcpp_compon":21,"rclpy":21,"read":[11,27],"read_customer_data":12,"readi":28,"real":11,"realiz":3,"reassembl":22,"reassembli":22,"reboot_devic":12,"receiv":[11,22],"receivebuffers":22,"recent":2,"recogn":7,"recognit":31,"recommend":[1,2,11,14,31],"reconstruct":3,"record":3,"reduc":[1,14,21,22],"refer":[3,11,20,22,23,24,26,28,32],"reflect":17,"regard":11,"regist":[5,13],"registr":[1,6,15],"relat":[3,12,20,24,27],"releas":[2,5,17],"relev":3,"reli":25,"reliabl":22,"reload":7,"remov":11,"reopen":11,"replac":[11,17,26,29],"repo":2,"report":13,"repres":[3,18,28],"requir":[0,1,2,6,11,15,17,23,25,32,33],"reset":11,"resolut":[2,3,11,18,20,21,26,32],"resolv":[26,32],"resourc":25,"respect":11,"respons":22,"result":[1,3,14,16,22,28,30],"retry_on_usb3_detection_failur":11,"return":[26,28],"review":2,"rgb":[3,11],"rgbd":[3,27],"rgbir":28,"right":[11,12,20,25],"right_ir":[11,13],"rmem_default":22,"rmem_max":22,"rmw_fastrtps_cpp":22,"rmw_fastrtps_use_qos_from_xml":22,"rmw_implement":22,"rmw_qos_profile_default":11,"rmw_qos_profile_paramet":11,"rmw_qos_profile_parameter_ev":11,"rmw_qos_profile_services_default":11,"rmw_qos_profile_system_default":11,"ro":[1,2,5,11,14,19,22,28],"robot":31,"roi":11,"ros2":[2,6,8,10,12,14,15,16,17,19,20,21,23,24,25,26,27,28,29,30],"ros2_w":[5,7,8,17],"ros_distro":[5,8],"rosdep":17,"rotat":[11,12],"rtp":22,"rule":7,"run":[1,3,7,8,9,14,15,19,21,22,25,26,29,30,32],"rviz2":[1,14],"s1739874543327":28,"same":[2,3,23,27,28],"sampl":[1,3,7,9,13],"satur":11,"save":[3,22],"save_imag":12,"save_point_cloud":12,"save_rgbir_param":28,"scale":11,"scan":31,"scene":3,"script":[1,6,28],"sdk":[1,4,6,9,10,11,14,19,25,32],"seamless":2,"search":[1,11,14,20],"sec":22,"second":[11,16,22,27,28],"secondari":[23,27,28],"secondary_sync":27,"section":[3,8,15,20,23,24,29,30],"see":[8,15,23,28,33],"select":[1,11,14,25,30],"send":[11,22,32],"send_software_trigg":12,"sendbuffers":22,"sendsocketbuffers":22,"sensor":[1,3,10,13,15,23],"sensor_data":11,"separ":[11,26,32],"sequenc":11,"sequence_id_filter_id":11,"seri":[1,2,11,14,20,23,25,29],"serial":[3,8,11,28],"serial_numb":[8,11],"serialnumb":28,"servic":[1,10,11,28],"services_default":11,"set":[1,2,3,8,11,12,13,14,16,20,22,24,26,27,28,29,30,31,32],"set_auto_white_bal":12,"set_color_":12,"set_color_ae_roi":12,"set_color_auto_exposur":12,"set_color_exposur":12,"set_color_flip":12,"set_color_gain":12,"set_color_mirror":12,"set_color_rot":12,"set_depth_ae_roi":12,"set_depth_auto_exposur":12,"set_depth_exposur":12,"set_depth_flip":12,"set_depth_gain":12,"set_depth_mirror":12,"set_depth_rot":12,"set_fan_work_mod":12,"set_filt":12,"set_floor_en":12,"set_ir_auto_exposur":12,"set_ir_exposur":12,"set_ir_gain":12,"set_laser_en":12,"set_ldp_en":12,"set_reset_timestamp":12,"set_streams_en":12,"set_sync_interleaverlas":12,"set_user_calib_param":12,"set_white_bal":12,"setarrai":12,"setbool":12,"setfilt":12,"setint32":[12,28],"setstr":12,"settingsth":27,"setup":[1,8,14,16,17],"setusercalibparam":12,"sh":[7,17],"shared_orbbec_contain":28,"sharp":11,"shift":20,"should":[8,11,25,27,28,30],"shown":[15,27],"side":3,"signal":[11,27],"signific":22,"significantli":25,"similar":[2,30],"simpl":3,"simpli":15,"simplifi":32,"sinc":25,"singl":[1,13,14,21,28],"size":3,"skip":[16,24],"skip_numb":16,"slave":27,"sn":28,"snapshot":[3,28],"sncp1e5420006d":28,"so":[1,23],"soc":23,"softwar":[3,11,25,27,33],"software_trigg":27,"software_trigger_en":11,"software_trigger_period":11,"sole":25,"solut":3,"some":[3,8,11],"sourc":[1,2,6,16,17,23],"spars":19,"spatial":11,"spatial_fast_filter_radiu":11,"spatial_filt":25,"spatial_filter_alpha":11,"spatial_moderate_filter_diff_threshold":11,"spatialadvancedfilt":12,"special":2,"specif":[2,12,13,19,22,31,33],"specifi":[8,11,17,29],"speed":3,"src":[5,7,17],"srv":[8,12,28],"standalon":[11,27],"standard":[2,3,25],"start":[3,8,9,11,16,17,19,20,21,23,28,29],"start_captur":28,"startup":[2,28],"state":3,"statist":5,"statu":[1,10],"std_srv":12,"step":[7,30],"still":11,"stop":27,"storag":[25,28],"store":[12,16],"strategi":25,"stream":[1,3,8,10,14,20,25,28,30],"streamprofil":3,"streamprofileinfo":28,"string":12,"strongli":2,"structur":[1,14],"subdirectori":28,"submit":32,"suboptim":22,"subscrib":21,"subscript":22,"success":28,"sudo":[5,7,17,22,26,32],"suffer":31,"suffici":[26,32],"suppli":[26,32],"support":[1,3,4,11,12,19,21,23,27,29,32],"sure":[8,11,17,27],"sw":11,"switch":[1,14,16,24,25],"switch_cycl":16,"switch_ir":12,"sy":[22,26,32],"sync":[1,10,14,24,28],"sync_mod":[11,27],"syncframesmain":28,"synchron":[1,10,13,14,15,27,28],"synthes":3,"sysctl":22,"system":[1,3,11,14,17,25,26,28,32],"system_default":11,"t":[21,26],"tabl":[2,8,11],"tag":26,"take":28,"target":[3,11],"team":32,"techniqu":3,"tee":[26,32],"temperatur":13,"tempor":11,"temporal_filter_diff_threshold":11,"term":[1,4],"termin":[8,23,26,28],"test":[1,2,11,14,16],"test_cycl":16,"tf_publish_r":11,"than":[25,27],"them":[3,22,23],"therebi":3,"therefor":20,"thi":[1,2,3,4,6,7,8,9,10,11,13,14,15,16,17,20,21,22,23,24,25,26,27,29,30,32,33],"those":3,"three":[3,11],"threshold":11,"threshold_filter_max":11,"threshold_filter_min":11,"through":3,"throughput":22,"time":[12,16,21,27],"time_domain":[11,12,28],"time_sync_period":11,"timeract":28,"timestamp":[3,11,28],"tini":31,"togeth":21,"toggle_color":12,"toggle_depth":12,"toggle_ir":12,"too":[1,14],"tool":[1,8,14,17],"top":[11,12],"topic":[1,10,11,14,21,27,30],"totalmodefram":28,"tradit":2,"transfer":22,"transform":3,"translat":[3,12],"transmiss":22,"transport":[5,22],"transport_descriptor":22,"transport_id":22,"trigger":[1,7,10,11,23,27],"trigger2image_delay_u":11,"trigger_out_delay_u":11,"trigger_out_en":[11,27],"troubleshoot":1,"true":[11,12,13,15,21,22,24,25,29,30,32],"try":[2,8,26,32],"tsprangethreshold":28,"tune":[14,22],"two":[3,27],"txt":[0,32],"type":[3,11,19,22,28],"u":[3,11,20],"ubuntu":[2,5,17],"ubuntu22":25,"udev":7,"udevadm":7,"udp_transport":22,"udpv4":22,"unbin":[18,19],"uncertain":11,"under":[13,28,33],"undistort":11,"unexpect":1,"unexpectedli":32,"unifi":3,"unit":13,"univers":3,"unless":33,"unnecessari":11,"up":11,"updat":[2,5,17],"upgrade_firmwar":11,"upper":27,"url":11,"us":[1,2,3,6,8,11,14,15,16,20,22,23,26,27,28,29,30,31,32,33],"usag":[1,10,14,22,23,32],"usb":[2,3,11,23,26,28],"usb_port":[11,23,26,27,28],"usbcor":[26,32],"usbf":[26,32],"usbfs_memory_mb":[26,32],"use_intra_process_comm":21,"usebuiltintransport":22,"user":[2,3,7,9,25,31],"usertransport":22,"usual":[11,28,29],"utf":22,"util":3,"uvc":[2,3],"uvc_backend":11,"v":20,"v2":[2,4,5,25],"v4l2":[11,25],"valu":[2,11,20,22,24,26,27,29,31,32],"vari":32,"variou":[16,25],"veloc":11,"verif":[1,14,28],"verifi":28,"version":[2,17,20,22,24,25,33],"versu":2,"via":23,"video":[3,28],"view":[1,8,14,19,28],"viewer":15,"visual":[1,14,15,31],"w":22,"wai":21,"wall":20,"want":[23,29],"warn":11,"warranti":33,"we":[2,3,28],"well":[2,31],"wfov":[1,14],"what":[15,30],"when":[11,12,13,22,24,25,27,28],"where":[3,13,20,22,28],"which":[3,11,13,20,22,28,29],"while":25,"white":11,"why":1,"width":[11,18],"window":22,"wish":15,"within":[2,3,11],"without":[3,15,25,33],"wmem_default":22,"wmem_max":22,"word":3,"work":[1,14,16,25],"workspac":[5,17,28],"world":3,"wrapper":[2,3,6,8,21],"write":33,"write_customer_data":12,"www":[22,33],"x":18,"x64":2,"xavier":2,"xl":19,"xml":3,"xmln":22,"xmlschema":22,"xxx":19,"yaml":[11,17,23,28],"you":[2,7,8,11,15,19,21,23,26,28,29,32,33],"your":[1,2,9,17,22,26,31,32],"yourcamerasn":8,"zero":21,"\u67e5\u770b\u7f16\u8bd1\u7ed3\u679c":0,"\u7528\u6d4f\u89c8\u5668\u6253\u5f00":0},"titles":["Docs\u5e94\u7528\u6587\u6863","OrbbecSDK V2 ROS2 Wrapper documentation","1.1. Introduction","1.2. Orbbec SDK Overview","1. Overview","2.1. Build from Source","2. Installation","2.2. Registration script (required)","3.1. QuickStarts","3. Quickstarts","4. Application Guide","4.1. Launch parameters","4.2. All available services for camera control","4.3. Available Topics","5. Advanced Guide","5.1. Aligning Depth to Color in ROS 2","5.2. Ob_benchmark tool","5.3. Building a Debian Package","5.4. Configuration of depth NFOV and WFOV modes","5.5. Depth work mode switch","5.6. Disparity_search_offset","5.7. Efficient intra-process communication:","5.8. Fast DDS Optimization for Orbbec Camera with ROS2","5.9. GMSL_camera","5.10. Using interleave_ae with Gemini330 series cameras","5.11. Reducing CPU Usage with Orbbec ROS Package","5.12. Multi-Camera","5.13. Multi_camera synced Instructions","5.14. Multi_camera_synced_verification_tool","5.15. Net_camera","5.16. Enabling and Visualizing Point Cloud in ROS 2","5.17. Predefined presets","6. Frequently Asked Questions","License"],"titleterms":{"1":8,"2":[8,15,30],"3":8,"335le":29,"435le":29,"No":[26,32],"There":32,"addit":[23,32],"adjust":22,"advanc":[11,14],"ae":11,"align":15,"all":12,"analysi":28,"analyz":28,"applic":[8,10],"ar":32,"architectur":3,"ask":32,"avail":[8,12,13],"backend":11,"basic":11,"buffer":22,"build":[5,8,17],"calibr":[11,12],"call":8,"camera":[8,11,12,16,22,23,24,25,26,27,28,29,32],"captur":12,"chang":28,"check":27,"cloud":[13,30],"color":[11,12,15,30],"color_format":25,"command":[15,27,30],"commun":21,"comparison":25,"compil":5,"compon":21,"concept":3,"config":28,"configur":[11,12,16,17,18,22,25,27,28],"control":[11,12],"core":11,"cpu":25,"crash":32,"data":[12,16,26,28,32],"dd":22,"debian":17,"depend":17,"depth":[11,12,15,18,19,30],"devic":[11,12,13],"devicesinfo":28,"diagnost":[11,13],"directori":28,"dispar":11,"disparity_search_offset":20,"docs\u5e94\u7528\u6587\u6863":0,"document":1,"echo":8,"effici":21,"emitt":12,"enabl":30,"environ":[5,17,22,25],"exampl":[15,21,24,28],"extrins":11,"fast":22,"featur":[8,11],"femto":29,"file":[16,21,22,25,28,32],"filter":[11,12,25],"firmwar":11,"first":8,"follow":27,"format":[25,28],"fragment":22,"frame":26,"frequent":32,"from":[5,26,32],"function":20,"further":25,"gemini":29,"gemini330":24,"gener":11,"gmsl":23,"gmsl_camera":23,"guid":[10,14],"hardwar":[2,25],"hdr":24,"imag":[13,15,26,28],"impact":25,"imu":[11,13],"inform":12,"ini":28,"instal":6,"instruct":[16,27],"interleav":[11,24],"interleave_a":24,"intra":21,"introduct":[2,8,20,24,29],"ip":22,"ir":[11,12],"json":16,"laser":[11,24],"launch":[8,11,16,20,21,23,24,25,28,32],"ldp":11,"licens":33,"limit":21,"linux":5,"list":8,"load":21,"log":11,"low":26,"lower":25,"manag":12,"mani":32,"manual":21,"maximum":22,"mega":29,"memori":22,"miscellan":11,"mjpg":25,"mode":[11,18,19],"model":3,"multi":[11,23,26,27,29],"multi_camera":27,"multi_camera_sync":24,"multi_camera_synced_verification_tool":28,"multicamera_sync":28,"multipl":[21,26,32],"name":28,"need":28,"net":29,"net_camera":29,"network":11,"nfov":18,"node":[8,28],"ob_benchmark":16,"oper":28,"optim":22,"optimizationa":25,"orbbec":[3,22,25],"orbbecsdk":1,"orbbecsdk_ros2":27,"output":[16,28],"overlai":15,"overview":[3,4],"packag":[17,25],"paramet":[8,11,20,22,23,24,29],"pictur":28,"platform":2,"point":[13,30],"port":27,"predefin":31,"prepar":[17,28],"preset":31,"process":21,"product":2,"program":3,"python":28,"question":32,"quickstart":[8,9],"rate":26,"recommend":25,"record":8,"reduc":25,"registr":7,"requir":7,"result":25,"rgb":25,"ro":[8,15,17,25,30],"ros2":[1,5,22],"rosbag2":8,"run":[16,20,23,24,27,28],"rviz2":[8,15,30],"same":21,"sampl":8,"save":28,"save_rgbir":28,"script":7,"sdk":3,"select":15,"sensor":[11,12],"seri":24,"servic":[8,12],"set":[23,25],"setup":[25,27],"shm_fastdd":22,"singl":[23,29],"size":22,"so":32,"sourc":[5,8],"specif":11,"start":27,"start_benchmark_param":16,"statu":13,"step":8,"stream":[11,12,13,26,32],"structur":28,"support":2,"switch":19,"sync":[11,23,27],"synchron":[11,12],"system":22,"term":3,"test":25,"tf":11,"thi":28,"threshold":22,"time":[11,22],"too":26,"tool":[16,28],"topic":[8,13,15,26],"trigger":12,"troubleshoot":32,"txt":28,"unexpect":32,"us":[21,24,25],"usag":[16,25],"uvc_backend":25,"v":25,"v2":[1,3],"variabl":22,"view":15,"visual":[8,24,30],"wfov":18,"why":32,"work":19,"workspac":8,"wrapper":[1,5],"xml":22,"your":8,"\u7f16\u8bd1":0,"\u7f16\u8bd1\u73af\u5883":0,"\u7f16\u8bd1\u7ed3\u679c":0}}) \ No newline at end of file diff --git a/source/1_overview/introduction.html b/source/1_overview/introduction.html new file mode 100644 index 00000000..1ba30b78 --- /dev/null +++ b/source/1_overview/introduction.html @@ -0,0 +1,483 @@ + + + + + + + + + 1.1. Introduction — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

1.1. Introduction

+

OrbbecSDK ROS2 Wrapper provides seamless integration of Orbbec cameras with ROS 2 environment. It supports ROS2 Foxy, Humble, and Jazzy distributions.

+

With a major update in October 2024, we release the OrbbecSDK ROS2 Wrapper v2 connected to the open source OrbbecSDK v2 with enhanced flexibility and extensibility. This update ensures compatibility with all Orbbec USB products adhering to UVC standard. However, it no longer supports Orbbec’s traditional OpenNI protocol devices. We strongly encourage you to use the v2-main branch if your device is supported.

+

If you are a user in China, it is recommended to use gitee Repo.

+
+

1.1.1. Support Hardware Products

+

The following devices are supported by the OrbbecSDK ROS2 Wrapper v2-main branch. More devices support will be added in the near future. If you can not find your device in the table below, try the main branch.

+

For optimal performance, we strongly recommend updating to the latest firmware version. This ensures that you benefit from the most recent enhancements and bug fixes.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Product ListMinimal Firmware VersionLaunch File
Gemini 435Le1.2.04gemini435_le.launch.py
Gemini 3351.2.20gemini_330_series.launch.py
Gemini 3361.2.20gemini_330_series.launch.py
Gemini 335L1.2.20gemini_330_series.launch.py
Gemini 336L1.2.20gemini_330_series.launch.py
Gemini 335Lg1.3.46gemini_330_series.launch.py
Gemini 335Le1.5.31gemini_330_series.launch.py
Gemini 3301.2.20gemini_330_series.launch.py
Gemini 330L1.2.20gemini_330_series.launch.py
Gemini 21.4.92gemini2.launch.py
Gemini 2 L1.4.53gemini2L.launch.py
Femto Bolt1.1.2femto_bolt.launch.py
Femto Mega1.3.0femto_mega.launch.py
Astra 22.8.20astra2.launch.py
Astra Mini Pro2.0.01astra.launch.py

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.

+
+
+

1.1.2. Support Platforms

+
    +
  • Linux x64: tested on Ubuntu 22.04

  • +
  • Linux ARM64: tested on NVIDIA Jetson AGX Orin , NVIDIA Jetson Orin NX , NVIDIA Jetson Orin Nano , NVIDIA Jetson AGX Xavier , NVIDIA Jetson Xavier NX

  • +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/1_overview/orbbecsdk_overview.html b/source/1_overview/orbbecsdk_overview.html new file mode 100644 index 00000000..65ad106b --- /dev/null +++ b/source/1_overview/orbbecsdk_overview.html @@ -0,0 +1,560 @@ + + + + + + + + + 1.2. Orbbec SDK Overview — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

1.2. Orbbec SDK Overview

+

This section introduces the Orbbec SDK in C++. Its architecture and concepts are consistent with those of the Python Wrapper.

+
+

1.2.1. Terms

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDNameExplain
1USBUniversal Serial Bus
2UVCUSB Video Class
3FirmwareFirmware of 3D camera
4DisparityDisparity is to observe the direction difference of the same target from two points with a certain distance.
5D2D (Disparity to depth)Disparity to depth is an image processing technique used to convert disparity information into depth information.
6Hardware D2DDisparity to depth is implemented internally in the device, without occupying the computational power of the host computer.
7Software D2DDisparity to depth, implemented in Orbbec SDK
8Depth point cloudDepth point cloud, the coordinates of points in a three-dimensional world coordinate system, can be transformed into a point cloud using the intrinsic parameters of a Depth camera.
9RGBD point cloudPoint cloud with overlaid RGB information
10D2CThe translation of "Depth to Color" is a feature that performs per-pixel geometric transformation on a depth image. Its result is aligning the depth image with its corresponding color image through the D2C transformation, allowing us to locate the depth information of a color pixel by using the same image coordinate position of that pixel in the transformed depth image. After the D2C transformation, we generate a depth image of the same size as the target color image, where the image content represents depth data in the coordinate system of the color camera. In other words, it reconstructs a depth image "captured" using the origin and dimensions of the color camera, where each pixel matches the corresponding pixel coordinates of the color camera.
11Hardware D2CHardware D2C refers to the functionality of performing Depth to Color transformation within the camera itself, with the camera directly outputting the result of the D2C transformation.
12Software D2CPerforming D2C computation on the host computer side using an SDK.
13Frame aggregation (FrameSet)Combining Depth, IR, and Color frames into a Frameset and invoking it through a pipeline.
14C2DThe translation of "Color to Depth" is a feature that performs per-pixel geometric transformation on a color image. Its result is aligning the color image with its corresponding depth image through the C2D transformation.
15MetaDataFrame metadata is a set of parameters (or attributes) that provide a snapshot of the sensor configuration and/or system state present during the frame’s generation.
16HDRHigh Dynamic Range (HDR) imaging allows imaging systems to capture images in extremely dark and bright scenes alike. We propose a software solution running on the host CPU to implement this feature. It utilizes data from two consecutive frames and directly synthesizes these two depth images, thereby enhances the dynamic range of 16-bit depth images.
17LDPLaser close-range protection
+
+

1.2.2. Orbbec SDK v2 Architecture Overview

+

OrbbecSDK v2 Soft Architecture

+
    +
  • Application

  • +
+

OrbbecViewer, Sample, and User Application Implementation.

+
    +
  • Interfaces and Encapsulation Layer

  • +
+

OrbbecSDK Interface Encapsulation and Wrapper Encapsulation.

+
    +
  • High-level Layer

  • +
+

HighLevel encapsulates the core business components and provides interfaces to the outside using a pipeline.

+
    +
  • Basic business layer

  • +
+

The realization of the core business logic framework.

+
    +
  • Platform abstraction layer

  • +
+

Cross-platform components abstract operating system differences and provide a unified access interface.

+
    +
  • Platform implementation layer

  • +
+

The driver implementation of each platform.

+
+
+

1.2.3. SDK Concept Overview

+
    +
  • Context

  • +
+

Context which provides a set of settings includes settings such as device state change callbacks, log levels, and more. The Context can access multiple devices.

+
    +
  • Device

  • +
+

One actual hardware device corresponds to one Device object, which is used to obtain relevant information of the device and control its attributes.

+
    +
  • Pipeline

  • +
+

The HighLevel corresponding object encapsulates the interface for quick access to the SDK. It has simple functions that allow users to quickly get started and use the SDK.

+
    +
  • Config

  • +
+

Provides configuration for enabling data streams, alignment modes, and frame aggregation modes, It is used to control the behavior of the data output.

+
    +
  • StreamProfile

  • +
+

Stream configuration that defines parameters such as resolution, frame rate, and encoding format, It also provides management of camera parameters.

+
    +
  • Frame

  • +
+

Represents a frame of data in the Stream, and also contains relevant information about that frame of data, such as timestamp, type, etc.

+
    +
  • Filter

  • +
+

It mainly refers to some algorithmic processing modules for the composite stream FrameSet, such as point cloud algorithm processing.

+
    +
  • Record

  • +
+

Recording functionality that captures data streams and saves them as files for later analysis or playback.

+
    +
  • Playback

  • +
+

Playback functionality that plays recorded files and supports control over playback speed and other related parameters.

+
+
+

1.2.4. SDK Programming Model

+

Here is the C++ programming logic flow chart. Python’s programming logic is the same as it.

+
    +
  • Standard Flowchart:

  • +
+

image.png

+

The standard flowchart demonstrates how to create a device from the device list, set and get parameters, and apply post-processing filters.

+
    +
  • Flowchart using default configuration (stream acquisition based on the default settings in OrbbecSDKConfig.xml):

  • +
+

image

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/1_overview/overview.html b/source/1_overview/overview.html new file mode 100644 index 00000000..f7ddb275 --- /dev/null +++ b/source/1_overview/overview.html @@ -0,0 +1,397 @@ + + + + + + + + + 1. Overview — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

1. Overview

+

This chapter provides an overview of the Orbbec SDK, including supported products, main features, and architecture.

+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/2_installation/build_the_package.html b/source/2_installation/build_the_package.html new file mode 100644 index 00000000..7b7b6701 --- /dev/null +++ b/source/2_installation/build_the_package.html @@ -0,0 +1,420 @@ + + + + + + + + + 2.1. Build from Source — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

2.1. Build from Source

+
+

2.1.1. Environment

+

Install ROS 2 according to the official guide:

+ +

Enable ROS 2 auto-completion:

+
eval "$(register-python-argcomplete3 ros2)"
+eval "$(register-python-argcomplete3 colcon)"
+
+
+

Create a colcon workspace:

+
mkdir -p ~/ros2_ws/src
+
+
+
+
+

2.1.2. Linux ROS2 Wrapper Compilation

+

Clone source and checkout v2-main branch:

+
cd ~/ros2_ws/src
+git clone https://github.com/orbbec/OrbbecSDK_ROS2.git
+cd OrbbecSDK_ROS2
+git checkout v2-main
+
+
+

Install dependencies:

+
sudo apt install libgflags-dev nlohmann-json3-dev libgoogle-glog-dev libgoogle-glog0v5 libssl-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-backward-ros libdw-dev
+
+
+

Build:

+
cd ~/ros2_ws
+colcon build --event-handlers console_direct+ --cmake-args -DCMAKE_BUILD_TYPE=Release
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/2_installation/installation.html b/source/2_installation/installation.html new file mode 100644 index 00000000..63f31f79 --- /dev/null +++ b/source/2_installation/installation.html @@ -0,0 +1,391 @@ + + + + + + + + + 2. Installation — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

2. Installation

+

This chapter explains how to install the Orbbec ROS2 Python SDK, including building from source, installing dependencies, and using registration scripts.

+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/2_installation/registration_script.html b/source/2_installation/registration_script.html new file mode 100644 index 00000000..b04862bf --- /dev/null +++ b/source/2_installation/registration_script.html @@ -0,0 +1,389 @@ + + + + + + + + + 2.2. Registration script (required) — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

2.2. Registration script (required)

+

To allow the Orbbec cameras to be recognized correctly on Linux, install the udev rules:

+
cd  ~/ros2_ws/src/OrbbecSDK_ROS2/orbbec_camera/scripts
+sudo bash install_udev_rules.sh
+sudo udevadm control --reload-rules && sudo udevadm trigger
+
+
+

This step is mandatory for Linux users.

+

Notes: If this script is not executed, open the device will fail due to permission issues. You need to run the sample with sudo (administrator privileges).

+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/3_quickstarts/quickstart.html b/source/3_quickstarts/quickstart.html new file mode 100644 index 00000000..3807ee3f --- /dev/null +++ b/source/3_quickstarts/quickstart.html @@ -0,0 +1,467 @@ + + + + + + + + + 3.1. QuickStarts — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

3.1. QuickStarts

+
+

3.1.1. Introduction

+

This section provides a quick start to using the Orbbec ROS 2 wrapper. +You will learn how to:

+
    +
  • Launch a camera node.

  • +
  • Visualize depth/color streams in RViz2.

  • +
  • Interact with topics and services using ROS 2 CLI tools.

  • +
+
+
+
+

3.1.2. Build your First Camera Application

+
+

3.1.2.1. Step 1: Source ROS 2 and Workspace

+

Make sure ROS 2 and your workspace environment are sourced:

+
source /opt/ros/$ROS_DISTRO/setup.bash
+source ~/ros2_ws/install/setup.bash
+
+
+
+
+

3.1.2.2. Step 2: Launch the Camera Node

+
    +
  • On terminal 1

  • +
+
. ./install/setup.bash
+ros2 run orbbec_camera list_devices_node #Check if the camera is connected
+ros2 launch orbbec_camera gemini_330_series.launch.py # Or other launch file, see below table
+
+
+

If you have multiple cameras connected, you can specify the serial number:

+
ros2 launch orbbec_camera gemini_330_series.launch.py serial_number:=<YourCameraSN>
+
+
+
+
+

3.1.2.3. Step 3: Visualize in RViz2

+

Launch RViz2 and load the default config:

+
    +
  • On terminal 2

  • +
+
rviz2
+
+
+
    +
  • Add an Image display, set topic to /camera/color/image_raw.

  • +
  • Add another Image display for /camera/depth/image_raw.

  • +
  • Optionally, add a PointCloud2 display for /camera/depth/points.

  • +
+

You should now see the color stream, depth stream, and 3D point cloud in RViz2.

+
+
+
+
+

3.1.3. Sample Features

+

After the node is running, try some ROS 2 CLI commands:

+
+

3.1.3.1. List available topics / services/ parameters

+
ros2 topic list
+ros2 service list
+ros2 param list
+
+
+
+
+

3.1.3.2. Echo a topic

+

View depth camera data:

+
ros2 topic echo /camera/depth/camera_info
+
+
+
+
+

3.1.3.3. Call a service

+

For example, get device Information:

+
ros2 service call /camera/get_device_info orbbec_camera_msgs/srv/GetDeviceInfo '{}'
+
+
+
+
+

3.1.3.4. Record with rosbag2

+
ros2 bag record /camera/color/image_raw /camera/depth/image_raw
+
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/3_quickstarts/quickstarts.html b/source/3_quickstarts/quickstarts.html new file mode 100644 index 00000000..1791a955 --- /dev/null +++ b/source/3_quickstarts/quickstarts.html @@ -0,0 +1,391 @@ + + + + + + + + + 3. Quickstarts — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

3. Quickstarts

+

This chapter provides quick start guides for the SDK, allowing users to run basic example programs quickly.

+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/4_application_guide/application_guide.html b/source/4_application_guide/application_guide.html new file mode 100644 index 00000000..7a684952 --- /dev/null +++ b/source/4_application_guide/application_guide.html @@ -0,0 +1,410 @@ + + + + + + + + + 4. Application Guide — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+ +
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/4_application_guide/launch_parameters.html b/source/4_application_guide/launch_parameters.html new file mode 100644 index 00000000..570417c6 --- /dev/null +++ b/source/4_application_guide/launch_parameters.html @@ -0,0 +1,965 @@ + + + + + + + + + 4.1. Launch parameters — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

4.1. Launch parameters

+
+

If you are not sure how to set the parameters, you can connect the orbbec camera and open the OrbbecViewer.

+
+

The following are the launch parameters available:

+
+

4.1.1. Core & Stream Configuration

+
    +
  • camera_name

    +
      +
    • Start the node namespace.

    • +
    +
  • +
  • depth_registration

    +
      +
    • Enable alignment of the depth frame to the color frame. This field is required when the enable_colored_point_cloud is set to true.

    • +
    +
  • +
  • serial_number

    +
      +
    • The serial number of the camera. This is required when multiple cameras are used.

    • +
    +
  • +
  • usb_port

    +
      +
    • The USB port of the camera. This is required when multiple cameras are used.

    • +
    +
  • +
  • device_num

    +
      +
    • The number of devices. This must be filled in if multiple cameras are required.

    • +
    +
  • +
  • [color|depth|left_ir|right_ir|ir]_[width|height|fps|format]

    +
      +
    • The resolution and frame rate of the sensor stream.

    • +
    +
  • +
  • [color|depth|left_ir|right_ir|ir]_rotation

    +
      +
    • Set stream image rotation.

    • +
    • The possible values are 0, 90, 180, 270.

    • +
    +
  • +
  • [color|depth|left_ir|right_ir|ir]_flip

    +
      +
    • Enable the stream image flip.

    • +
    +
  • +
  • [color|depth|left_ir|right_ir|ir]_mirror

    +
      +
    • Enable the stream image mirror.

    • +
    +
  • +
  • enable_point_cloud

    +
      +
    • Enable the point cloud.

    • +
    +
  • +
  • enable_colored_point_cloud

    +
      +
    • Enable the RGB point cloud.

    • +
    +
  • +
  • cloud_frame_id

    +
      +
    • Modify the frame_id name within the ros message.

    • +
    +
  • +
  • ordered_pc

    +
      +
    • Enable filtering of invalid point clouds.

    • +
    +
  • +
  • align_mode

    +
      +
    • The alignment mode to be used. Options are HW for hardware alignment and SW for software alignment.

    • +
    +
  • +
  • align_target_stream

    +
      +
    • Set align target stream mode.

    • +
    • The possible values are COLOR, DEPTH.

    • +
    • COLOR: Align depth to color.

    • +
    • DEPTH: Align color to depth.

    • +
    +
  • +
  • point_cloud_qos, [stream]_qos, [stream]_camera_info_qos

    +
      +
    • ROS 2 Message Quality of Service (QoS) settings. The possible values are SYSTEM_DEFAULT, DEFAULT, PARAMETER_EVENTS, SERVICES_DEFAULT, PARAMETERS, SENSOR_DATA and are case-insensitive. These correspond to rmw_qos_profile_system_default, rmw_qos_profile_default, rmw_qos_profile_parameter_events, rmw_qos_profile_services_default, rmw_qos_profile_parameters, and SENSOR_DATA, respectively.

    • +
    +
  • +
+
+
+

4.1.2. Sensor Controls

+
+

4.1.2.1. Color Stream

+
    +
  • enable_color_auto_exposure

    +
      +
    • Enable the Color auto exposure.

    • +
    +
  • +
  • enable_color_auto_exposure_priority

    +
      +
    • Enable the Color auto exposure priority.

    • +
    +
  • +
  • color_exposure

    +
      +
    • Set the Color exposure.

    • +
    +
  • +
  • color_gain

    +
      +
    • Set the Color gain.

    • +
    +
  • +
  • enable_color_auto_white_balance

    +
      +
    • Enable the Color auto white balance.

    • +
    +
  • +
  • color_white_balance

    +
      +
    • Set the Color white balance.

    • +
    +
  • +
  • color_ae_max_exposure

    +
      +
    • Set the maximum exposure value for Color auto exposure.

    • +
    +
  • +
  • color_brightness, color_sharpness, color_gamma, color_saturation, color_contrast, color_hue

    +
      +
    • Set the Color brightness, sharpness, gamma, saturation, contrast, and hue.

    • +
    +
  • +
  • enable_color_backlight_compensation

    +
      +
    • Enable the Color backlight compensation.

    • +
    +
  • +
  • color_powerline_freq

    +
      +
    • Set the power line freq. The possible values are disable, 50hz, 60hz, auto.

    • +
    +
  • +
  • enable_color_decimation_filter / color_decimation_filter_scale

    +
      +
    • Enable the Color decimation filter and set its scale.

    • +
    +
  • +
  • color_ae_roi_[left|right|top|bottom]

    +
      +
    • Set Color auto exposure ROI.

    • +
    +
  • +
+
+
+

4.1.2.2. Depth Stream

+
    +
  • enable_depth_auto_exposure_priority

    +
      +
    • Enable the Depth auto exposure priority.

    • +
    +
  • +
  • mean_intensity_set_point

    +
      +
    • Set the target mean intensity of the Depth image. For example: mean_intensity_set_point:=100.

    • +
    +
    +

    Note: This replaces the deprecated depth_brightness, which is still supported for backward compatibility.

    +
    +
  • +
  • enable_depth_scale

    +
      +
    • Enable the depth scale.

    • +
    +
  • +
  • depth_precision

    +
      +
    • The depth precision should be in the format 1mm. The default value is 1mm.

    • +
    +
  • +
  • depth_ae_roi_[left|right|top|bottom]

    +
      +
    • Set Depth auto exposure ROI.

    • +
    +
  • +
+
+
+

4.1.2.3. IR Stream

+
    +
  • enable_ir_auto_exposure

    +
      +
    • Enable the IR auto exposure.

    • +
    +
  • +
  • ir_exposure / ir_gain

    +
      +
    • Set the IR exposure and gain.

    • +
    +
  • +
  • ir_ae_max_exposure

    +
      +
    • Set the maximum exposure value for IR auto exposure.

    • +
    +
  • +
  • ir_brightness

    +
      +
    • Set the IR brightness.

    • +
    +
  • +
+
+
+

4.1.2.4. Laser / LDP

+
    +
  • enable_laser

    +
      +
    • Enable the laser. The default value is true.

    • +
    +
  • +
  • laser_energy_level

    +
      +
    • Set the laser energy level.

    • +
    +
  • +
  • enable_ldp / ldp_power_level

    +
      +
    • Enable the LDP and set its power level.

    • +
    +
  • +
+
+
+
+

4.1.3. Device, Sync & Advanced Features

+
+

4.1.3.1. Multi-Camera Synchronization

+
    +
  • sync_mode

    +
      +
    • Set sync mode. The default value is standalone.

    • +
    +
  • +
  • depth_delay_us / color_delay_us

    +
      +
    • The delay time (microseconds) of the depth/color image capture after receiving the capture command or trigger signal.

    • +
    +
  • +
  • trigger2image_delay_us

    +
      +
    • The delay time (microseconds) of the image capture after receiving the capture command or trigger signal. Us

    • +
    +
  • +
  • trigger_out_delay_us

    +
      +
    • The delay time (microseconds) of the trigger signal output after receiving the capture command or trigger signal.

    • +
    +
  • +
  • trigger_out_enabled

    +
      +
    • Enable the trigger out signal.

    • +
    +
  • +
  • software_trigger_enabled / software_trigger_period

    +
      +
    • Enable the software trigger out signal / set the software trigger period in ms.

    • +
    +
  • +
  • frames_per_trigger

    +
      +
    • The frame number of each stream after each trigger in triggering mode.

    • +
    +
  • +
+
+
+
+
+

4.1.3.2. Network Cameras

+
    +
  • enumerate_net_device

    +
      +
    • Enable automatically enumerate network devices.

    • +
    +
  • +
  • net_device_ip / net_device_port

    +
      +
    • Set net device’s IP address and port (Usually 8090).

    • +
    +
  • +
+
+

Used for net camera.

+
+
+
+

4.1.3.3. Device-Specific

+
    +
  • device_preset

    +
      +
    • The default value is Default. Only the G330 series is supported. For more information, refer to the G330 documentation. The value should be one of the preset names listed in the table.

    • +
    +
  • +
  • enable_gmsl_trigger / gmsl_trigger_fps

    +
      +
    • Enable the gmsl trigger out signal / set gmsl trigger fps. Used for gmsl camera.

    • +
    +
  • +
+
+
+

4.1.3.4. Disparity

+
    +
  • disparity_to_depth_mode

    +
      +
    • HW: use hardware disparity to depth conversion. SW: use software disparity to depth conversion.

    • +
    +
  • +
  • disparity_range_mode, disparity_search_offset, disparity_offset_config

    + +
  • +
+
+
+

4.1.3.5. Interleave AE Mode

+
    +
  • interleave_ae_mode

    +
      +
    • Set laser or hdr interleave.

    • +
    +
  • +
  • interleave_frame_enable, interleave_skip_enable, interleave_skip_index

    +
      +
    • Parameters to control interleave frame mode.

    • +
    +
  • +
  • [hdr|laser]_index[0|1]_[...]

    +
      +
    • In interleave frame mode, set the 0th and 1st frame parameters of hdr or laser interleaving frames.

    • +
    +
  • +
  • All interleave parameters are used for interleave ae mode.

  • +
+
+
+
+

4.1.4. Basic & General Parameters

+
+

4.1.4.1. Firmware & Backend

+
    +
  • upgrade_firmware

    +
      +
    • The input parameter is the firmware path.

    • +
    +
  • +
  • preset_firmware_path

    +
      +
    • The input parameter is the preset firmware path. If multiple paths are input, each path needs to be separated by , and a maximum of 3 firmware paths can be input.

    • +
    +
  • +
  • uvc_backend

    +
      +
    • Optional values: v4l2, libuvc.

    • +
    +
  • +
  • connection_delay

    +
      +
    • The delay time in milliseconds for reopening the device. Some devices, such as Astra mini, require a longer time to initialize and reopening the device immediately can cause firmware crashes when hot plugging.

    • +
    +
  • +
  • retry_on_usb3_detection_failure

    +
      +
    • If the camera is connected to a USB 2.0 port and is not detected, the system will attempt to reset the camera up to three times. It is recommended to set this parameter to false when using a USB 2.0 connection to avoid unnecessary resets.

    • +
    +
  • +
+
+
+

4.1.4.2. TF, Extrinsics & Calibration

+
    +
  • publish_tf / tf_publish_rate

    +
      +
    • Enable the TF publish and set its publication rate.

    • +
    +
  • +
  • enable_publish_extrinsic

    +
      +
    • Enable the extrinsics publish.

    • +
    +
  • +
  • ir_info_url / color_info_url

    +
      +
    • Set URL of the IR/color camera info.

    • +
    +
  • +
  • enable_color_undistortion

    +
      +
    • Enable the Color undistortion.

    • +
    +
  • +
+
+
+

4.1.4.3. Time Synchronization

+
    +
  • enable_sync_host_time

    +
      +
    • Enable synchronization of the host time with the camera time. The default value is true. If using global time, set to false.

    • +
    +
  • +
  • time_domain

    +
      +
    • Select timestamp type: device, global, and system.

    • +
    +
  • +
  • time_sync_period

    +
      +
    • Interval (in seconds) for synchronizing the camera time with the host system.

    • +
    +
    +

    Note: This parameter only needs to be set when enable_sync_host_time = true and time_domain = device.

    +
    +
  • +
  • enable_ptp_config

    +
      +
    • Enable PTP time synchronization. Only for Gemini 335Le. Requires enable_sync_host_time to be false.

    • +
    +
  • +
  • enable_frame_sync

    +
      +
    • Enable the frame synchronization.

    • +
    +
  • +
+
+
+

4.1.4.4. Logging & Diagnostics

+
    +
  • log_level

    +
      +
    • SDK log level. Default is info. Optional values: debug, info, warn, error, fatal.

    • +
    +
  • +
  • diagnostic_period

    +
      +
    • Diagnostic period in seconds.

    • +
    +
  • +
  • enable_heartbeat

    +
      +
    • Enable the heartbeat function. Default is false. If true, the camera node will send heartbeat signals to the firmware.

    • +
    +
  • +
+
+
+

4.1.4.5. Miscellaneous

+
    +
  • config_file_path

    +
      +
    • The path to the YAML configuration file. Default is "". If not specified, default parameters from the launch file will be used.

    • +
    +
  • +
  • frame_aggregate_mode

    +
      +
    • Set frame aggregate output mode. Optional values: full_frame, color_frame, ANY, disable.

    • +
    +
  • +
  • enable_d2c_viewer

    +
      +
    • Publishes the D2C overlay image (for testing only).

    • +
    +
  • +
+
+
+
+

4.1.5. IMU

+
    +
  • enable_accel / enable_gyro

    +
      +
    • Enable the Accelerometer/gyroscope and output its info topic data.

    • +
    +
  • +
  • enable_sync_output_accel_gyro

    +
      +
    • Enable the sync accel_gyro, and output IMU topic real-time data.

    • +
    +
  • +
  • accel_rate / gyro_rate

    +
      +
    • The frequency of the accelerometer/gyroscope. Values range from 1.5625hz to 32khz.

    • +
    +
  • +
  • accel_range / gyro_range

    +
      +
    • The range of the accelerometer (2g, 4g, 8g, 16g) and gyroscope (16dps to 2000dps).

    • +
    +
  • +
  • enable_accel_data_correction / enable_gyro_data_correction

    +
      +
    • Enable data correction for the accelerometer/gyroscope.

    • +
    +
  • +
  • linear_accel_cov / angular_vel_cov

    +
      +
    • Covariance of the linear acceleration and angular velocity.

    • +
    +
  • +
+
+
+

4.1.6. Depth Filters

+
    +
  • enable_decimation_filter

    +
      +
    • Enable the Depth decimation filter. Set with decimation_filter_scale.

    • +
    +
  • +
  • enable_hdr_merge

    +
      +
    • Enable the Depth hdr merge filter. Set with hdr_merge_exposure_1, etc.

    • +
    +
  • +
  • enable_sequence_id_filter

    +
      +
    • Enable the Depth sequence id filter. Set with sequence_id_filter_id.

    • +
    +
  • +
  • enable_threshold_filter

    +
      +
    • Enable the Depth threshold filter. Set with threshold_filter_max, threshold_filter_min.

    • +
    +
  • +
  • enable_hardware_noise_removal_filter

    +
      +
    • Enable the Depth hardware noise removal filter.

    • +
    +
  • +
  • enable_noise_removal_filter

    +
      +
    • Enable the Depth software noise removal filter. Set with noise_removal_filter_min_diff, etc.

    • +
    +
  • +
  • enable_spatial_filter

    +
      +
    • Enable the Depth spatial filter. Set with spatial_filter_alpha, etc.

    • +
    +
  • +
  • enable_temporal_filter

    +
      +
    • Enable the Depth temporal filter. Set with temporal_filter_diff_threshold, etc.

    • +
    +
  • +
  • enable_hole_filling_filter

    +
      +
    • Enable the Depth hole filling filter. Set with hole_filling_filter_mode.

    • +
    +
  • +
  • enable_spatial_fast_filter

    +
      +
    • Enable the Depth spatial fast filter. Set with spatial_fast_filter_radius.

    • +
    +
  • +
  • enable_spatial_moderate_filter

    +
      +
    • Enable the Depth spatial moderate filter. Set with spatial_moderate_filter_diff_threshold, etc.

    • +
    +
  • +
+
+
+

IMPORTANT: Please carefully read the instructions regarding software filtering settings at this link. If you are uncertain, do not modify these settings.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/4_application_guide/services.html b/source/4_application_guide/services.html new file mode 100644 index 00000000..118caa37 --- /dev/null +++ b/source/4_application_guide/services.html @@ -0,0 +1,648 @@ + + + + + + + + + 4.2. All available services for camera control — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

4.2. All available services for camera control

+
+

Note: Services related to a specific stream (e.g., /camera/set_color_*) are only available if that stream is enabled in the launch file (e.g., enable_color:=true).

+
+
+

4.2.1. Stream Control

+
+

4.2.1.1. Color Stream

+
    +
  • /camera/toggle_color

    +
    ros2 service call /camera/toggle_color std_srvs/srv/SetBool '{data: true}'
    +
    +
    +
  • +
  • /camera/get_color_exposure & /camera/get_color_gain

    +
    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

    +
    ros2 service call /camera/set_color_auto_exposure std_srvs/srv/SetBool '{data: true}'
    +
    +
    +
  • +
  • /camera/set_color_exposure & /camera/set_color_gain

    +
    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

    +
    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

    +
    # data_param: [Left, Right, Top, Bottom]
    +ros2 service call /camera/set_color_ae_roi orbbec_camera_msgs/srv/SetArrays '{data_param: [0,1279,0,719]}'
    +
    +
    +
  • +
+
+
+

4.2.1.2. Depth Stream

+
    +
  • /camera/toggle_depth

    +
    ros2 service call /camera/toggle_depth std_srvs/srv/SetBool '{data: true}'
    +
    +
    +
  • +
  • /camera/get_depth_exposure & /camera/get_depth_gain

    +
    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

    +
    ros2 service call /camera/set_depth_auto_exposure std_srvs/srv/SetBool '{data: true}'
    +
    +
    +
  • +
  • /camera/set_depth_exposure & /camera/set_depth_gain

    +
    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

    +
    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

    +
    # data_param: [Left, Right, Top, Bottom]
    +ros2 service call /camera/set_depth_ae_roi orbbec_camera_msgs/srv/SetArrays '{data_param: [0,847,0,479]}'
    +
    +
    +
  • +
+
+
+

4.2.1.3. IR Stream

+
    +
  • /camera/toggle_ir

    +
    ros2 service call /camera/toggle_ir std_srvs/srv/SetBool '{data: true}'
    +
    +
    +
  • +
  • /camera/get_ir_exposure & /camera/get_ir_gain

    +
    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_auto_exposure

    +
    ros2 service call /camera/set_ir_auto_exposure std_srvs/srv/SetBool '{data: true}'
    +
    +
    +
  • +
  • /camera/set_ir_exposure & /camera/set_ir_gain

    +
    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/switch_ir

    +
    ros2 service call /camera/switch_ir orbbec_camera_msgs/srv/SetString '{data: left}'
    +
    +
    +
  • +
+
+
+

4.2.1.4. All Streams

+
    +
  • /camera/get_streams_enable & /camera/set_streams_enable

    +
    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}'
    +
    +
    +
  • +
+
+
+
+

4.2.2. Sensor & Emitter Control

+
    +
  • /camera/set_auto_white_balance & /camera/get_auto_white_balance

    +
    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

    +
    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

    +
    ros2 service call /camera/set_laser_enable std_srvs/srv/SetBool '{data: true}'
    +
    +
    +
  • +
  • /camera/set_ldp_enable & /camera/get_ldp_status

    +
    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_fan_work_mode

    +
    ros2 service call /camera/set_fan_work_mode orbbec_camera_msgs/srv/SetInt32 '{data: 0}'
    +
    +
    +
  • +
  • /camera/set_floor_enable

    +
    ros2 service call /camera/set_floor_enable std_srvs/srv/SetBool '{data: true}'
    +
    +
    +
  • +
+
+
+

4.2.3. Device Information & Management

+
    +
  • /camera/get_device_info

    +
    ros2 service call /camera/get_device_info orbbec_camera_msgs/srv/GetDeviceInfo
    +
    +
    +
  • +
  • /camera/get_sdk_version

    +
    ros2 service call /camera/get_sdk_version orbbec_camera_msgs/srv/GetString
    +
    +
    +
  • +
  • /camera/reboot_device

    +
    ros2 service call /camera/reboot_device std_srvs/srv/Empty '{}'
    +
    +
    +
  • +
+
+
+

4.2.4. Synchronization & Triggering

+
    +
  • /camera/send_software_trigger

    +
    ros2 service call /camera/send_software_trigger std_srvs/srv/SetBool '{data: true}'
    +```*   `/camera/set_reset_timestamp`
    +```bash
    +# Only available when time_domain param is set to device
    +ros2 service call /camera/set_reset_timestamp std_srvs/srv/SetBool '{data: true}'
    +
    +
    +
  • +
  • /camera/set_sync_interleaverlaser

    +
    # Only available if interleave_ae_mode is 'laser' and interleave_frame_enable is true
    +ros2 service call /camera/set_sync_interleaverlaser orbbec_camera_msgs/srv/SetInt32 '{data: 0}'
    +
    +
    +
  • +
+
+
+

4.2.5. Depth Filter Configuration

+
    +
  • /camera/set_filter

    +
    # Set DecimationFilter
    +ros2 service call /camera/set_filter orbbec_camera_msgs/srv/SetFilter '{filter_name: DecimationFilter, filter_enable: false, filter_param: [5]}'
    +# Set 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]}'
    +
    +
    +
  • +
+
+
+

4.2.6. Data Capture & Calibration Management

+
    +
  • /camera/save_images

    +
    ros2 service call /camera/save_images std_srvs/srv/Empty '{}'
    +
    +
    +
  • +
  • /camera/save_point_cloud

    +
    ros2 service call /camera/save_point_cloud std_srvs/srv/Empty '{}'
    +
    +
    +
  • +
+
+

Note: The following services are currently supported only on the 435Le module. Each service can store only one set of data or string at a time.

+
+
    +
  • /camera/write_customer_data & /camera/read_customer_data

    +
    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

    +
    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 '{}'
    +
    +
    +
  • +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/4_application_guide/topics.html b/source/4_application_guide/topics.html new file mode 100644 index 00000000..d6b05b33 --- /dev/null +++ b/source/4_application_guide/topics.html @@ -0,0 +1,497 @@ + + + + + + + + + 4.3. Available Topics — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

4.3. Available Topics

+

Topics are organized by stream and function. By default, all topics are published under the /camera namespace, which can be changed with the camera_name launch parameter.

+
+

Note: Topics for a specific stream (e.g., /camera/color/...) are only published if their corresponding launch parameter (e.g., enable_color) is set to true.

+
+
+

4.3.1. Image Streams

+

These topics provide the raw image data and corresponding calibration information for each enabled camera stream. The pattern is consistent for color, depth, ir, left_ir, and right_ir streams.

+
    +
  • /camera/color/image_raw

    +
      +
    • Raw image data from the color stream.

    • +
    +
  • +
  • /camera/color/camera_info

    +
      +
    • Camera calibration data and metadata for the color stream.

    • +
    +
  • +
  • /camera/color/metadata

    +
      +
    • Low-level metadata from the color stream firmware.

    • +
    +
  • +
  • /camera/depth/image_raw

    +
      +
    • Raw image data from the depth stream.

    • +
    +
  • +
  • /camera/depth/camera_info

    +
      +
    • Camera calibration data and metadata for the depth stream.

    • +
    +
  • +
  • /camera/depth/metadata

    +
      +
    • Low-level metadata from the depth stream firmware.

    • +
    +
  • +
  • /camera/ir/image_raw

    +
      +
    • Raw image data from the infrared (IR) stream.

    • +
    +
  • +
  • /camera/ir/camera_info

    +
      +
    • Camera calibration data and metadata for the IR stream.

    • +
    +
  • +
  • /camera/ir/metadata

    +
      +
    • Low-level metadata from the IR stream firmware.

    • +
    +
  • +
+
+
+

4.3.2. Point Cloud Topics

+
    +
  • /camera/depth/points

    +
      +
    • Point cloud data generated from the depth stream.

    • +
    • Condition: Published only when enable_point_cloud is true.

    • +
    +
  • +
  • /camera/depth_registered/points

    +
      +
    • Colored point cloud data, where the depth points are registered to the color image frame.

    • +
    • Condition: Published only when enable_colored_point_cloud is true.

    • +
    +
  • +
+
+
+

4.3.3. IMU Topics

+

The Inertial Measurement Unit (IMU) topics provide accelerometer and gyroscope data. Their behavior depends on the synchronization setting.

+
    +
  • /camera/accel/sample

    +
      +
    • Individual accelerometer data stream.

    • +
    • Condition: Published when enable_accel is true AND enable_sync_output_accel_gyro is false.

    • +
    +
  • +
  • /camera/gyro/sample

    +
      +
    • Individual gyroscope data stream.

    • +
    • Condition: Published when enable_gyro is true AND enable_sync_output_accel_gyro is false.

    • +
    +
  • +
  • /camera/gyro_accel/sample

    +
      +
    • Synchronized data stream containing both accelerometer and gyroscope data in a single message.

    • +
    • Condition: Published when enable_sync_output_accel_gyro is true.

    • +
    +
  • +
+
+
+

4.3.4. Device Status & Diagnostics

+
    +
  • /camera/device_status

    +
      +
    • Reports the current status of the camera device.

    • +
    +
  • +
  • /camera/depth_filter_status

    +
      +
    • Reports the status of the depth sensor’s post-processing filters.

    • +
    +
  • +
  • /diagnostics

    +
      +
    • Publishes diagnostic information about the camera node. Currently, this includes the device temperature.

    • +
    +
  • +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/advanced_guide.html b/source/5_advanced_guide/advanced_guide.html new file mode 100644 index 00000000..ccdcb5de --- /dev/null +++ b/source/5_advanced_guide/advanced_guide.html @@ -0,0 +1,467 @@ + + + + + + + + + 5. Advanced Guide — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5. Advanced Guide

+

This chapter covers advanced features of the SDK, including multi-camera synchronization, depth-color alignment, performance tuning, and more.

+
+ +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/align_depth_color.html b/source/5_advanced_guide/align_depth_color.html new file mode 100644 index 00000000..d66ab859 --- /dev/null +++ b/source/5_advanced_guide/align_depth_color.html @@ -0,0 +1,416 @@ + + + + + + + + + 5.1. Aligning Depth to Color in ROS 2 — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.1. Aligning Depth to Color in ROS 2

+

This section explains how to align depth images with color images to create an overlay image using ROS 2. This is particularly useful for applications requiring synchronized visual information from different sensor modalities.

+
+

5.1.1. Commands to Align and View Depth and Color Images

+
    +
  1. Basic Depth to Color Alignment:

    +

    To simply align the depth image to the color image, use the following command:

    +
    ros2 launch orbbec_camera gemini_330_series.launch.py depth_registration:=true
    +
    +
    +

    This command activates the depth registration feature without opening a viewer.

    +
  2. +
  3. Viewing Depth to Color Overlay:

    +

    If you wish to view the depth to color overlay, you need to enable the viewer by using the command below:

    +
    ros2 launch orbbec_camera gemini_330_series.launch.py depth_registration:=true enable_d2c_viewer:=true
    +
    +
    +

    This launches the camera node with depth to color registration and opens a viewer to display the overlay image.

    +
  4. +
+
+
+

5.1.2. Selecting Topics in RViz2

+

To visualize the aligned images in RViz2:

+
    +
  1. Launch RViz2 after running one of the above commands.

  2. +
  3. Select the topic for the depth to color overlay image. An example topic selection is shown here:

    +

    Topic Selection for Depth to Color Overlay

    +
  4. +
+
+
+

5.1.3. Example of Depth to Color Overlay

+

After selecting the appropriate topic in RViz2, you will be able to see the depth to color overlay image. Here’s what it might look like:

+

Depth to Color Overlay Image

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/benchmark.html b/source/5_advanced_guide/benchmark.html new file mode 100644 index 00000000..951972a5 --- /dev/null +++ b/source/5_advanced_guide/benchmark.html @@ -0,0 +1,433 @@ + + + + + + + + + 5.2. Ob_benchmark tool — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.2. Ob_benchmark tool

+
+

The goal of this tool is to benchmark the performance of various OrbbecSDK_ROS2 camera configurations. The benchmark results depend on the camera and settings used.(Currently only works with ROS2 Humble)

+
+
+

5.2.1. Usage Instructions

+
+

5.2.1.1. Tool Configuration (start_benchmark_params.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: Names of the cameras to be configured. Example: "camera_01", "camera_02", etc.

  • +
  • process_name: The name of the process to be monitored. For example, "component_conta" will monitor the data of the container process.

  • +
  • switch_cycle: The cycle time for switching configurations, in seconds. For example, setting it to 300 means the configuration will switch every 300 seconds.

  • +
  • test_cycle: The testing cycle, in seconds. For example, setting it to 1 means the tool will collect data for the monitored process every 1 second.

  • +
  • skip_number: The number of data points to skip. For example, setting it to 30 means that the first 30 data points will be ignored.

  • +
+
+
+

5.2.1.2. Camera configuration (launch files)

+

In the launch folder, there are multiple.launch.py files (ob_benchmark_0.launch.py, ob_benchmark_1.launch.py, …, ob_benchmark_19.launch.py). Each file corresponds to a different camera configuration.

+
+
+

5.2.1.3. Running the ob_benchmark tool

+

To run the tool, use the following commands:

+
source install/setup.bash
+ros2 run orbbec_camera ob_benchmark_node
+
+
+
+
+

5.2.1.4. Output Data Files

+

The output data files will be stored in the ob_benchmark folder with filenames like 0.csv, 1.csv, …, 19.csv. For example:

+
    +
  • 0.csv contains data from the ob_benchmark_0.launch.py configuration.

  • +
  • 1.csv contains data from the ob_benchmark_1.launch.py configuration.

  • +
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/building_a_Debian_Package.html b/source/5_advanced_guide/building_a_Debian_Package.html new file mode 100644 index 00000000..94ac3954 --- /dev/null +++ b/source/5_advanced_guide/building_a_Debian_Package.html @@ -0,0 +1,418 @@ + + + + + + + + + 5.3. Building a Debian Package — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.3. Building a Debian Package

+
+

5.3.1. Preparing the Environment

+

Before starting, install the required tools:

+
sudo apt install debhelper fakeroot python3-bloom
+
+
+
+
+

5.3.2. Configuring ROS Dependencies

+

Add the following YAML file to your system at /etc/ros/rosdep/sources.list.d/00-orbbec.yaml. Make sure to +replace focal with the codename of your Ubuntu version and humble with your ROS2 distribution name:

+
orbbec_camera_msgs:
+  ubuntu:
+    focal: [ ros-humble-orbbec-camera-msgs ]
+
+
+

Next, create a new file /etc/ros/rosdep/sources.list.d/50-orbbec.list and add this line to specify the path to the +YAML file:

+
yaml file:///etc/ros/rosdep/sources.list.d/00-orbbec.yaml
+
+
+

Update the rosdep database to reflect these changes:

+
rosdep update
+
+
+
+
+

5.3.3. Building the Package

+

Navigate to your workspace and build the project:

+
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
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/configuration_of_depth_NFOV_and_WFOV_modes.html b/source/5_advanced_guide/configuration_of_depth_NFOV_and_WFOV_modes.html new file mode 100644 index 00000000..0a17d242 --- /dev/null +++ b/source/5_advanced_guide/configuration_of_depth_NFOV_and_WFOV_modes.html @@ -0,0 +1,393 @@ + + + + + + + + + 5.4. Configuration of depth NFOV and WFOV modes — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.4. Configuration of depth NFOV and WFOV modes

+

For the Femto Mega and Femto Bolt devices, the NFOV and WFOV modes are implemented by configuring the resolution of +Depth and IR in the launch file. +In launch file, depth_width, depth_height, ir_width, ir_height represents the resolution of the depth and the resolution of +the IR. +The frame fps and resolution of IR must be consistent with the depth. The correspondence between different modes and +resolutions is as follows:

+
    +
  • NFOV unbinned: 640 x 576.

  • +
  • NFOV binned: 320 x 288.

  • +
  • WFOV unbinned: 1024 x 1024.

  • +
  • WFOV binned: 512 x 512.

  • +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/depth_work_mode_switch.html b/source/5_advanced_guide/depth_work_mode_switch.html new file mode 100644 index 00000000..fa88175e --- /dev/null +++ b/source/5_advanced_guide/depth_work_mode_switch.html @@ -0,0 +1,411 @@ + + + + + + + + + 5.5. Depth work mode switch — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.5. Depth work mode switch

+

Orbbec SDK ROS 2 supports the depth work mode switch. The depth work mode switch is supported by Gemini 2, Gemini 2 L, +and Femto and Femto Bolt cameras.

+
    +
  • Before starting the camera, depth work mode (depth_work_mode) can be configured for the corresponding xxx.launch.py +file’s support.

  • +
  • The depth work mode switch is supported by Gemini 2, Gemini 2 L, and Gemini 2 XL cameras.

  • +
  • The default depth work mode configuration of xxx.launch.py is the camera’s default configuration. If you need to +modify it, you can switch to the corresponding mode as needed.

  • +
  • The specific camera depth work mode support types can be found in the comments of the depth mode.

  • +
+
# Depth work mode support is as follows:
+# Unbinned Dense Default
+# Unbinned Sparse Default
+# Binned Sparse Default
+# Obstacle Avoidance
+DeclareLaunchArgument('depth_work_mode', default_value='')
+
+
+
    +
  • View depth work modes:

  • +
+
ros2 run orbbec_camera list_depth_work_mode_node
+
+
+
    +
  • Example:

  • +
+
ros2 launch orbbec_camera gemini2L.launch.py depth_work_mode:="Unbinned Dense Default"
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/disparity_search_offset.html b/source/5_advanced_guide/disparity_search_offset.html new file mode 100644 index 00000000..9af37f21 --- /dev/null +++ b/source/5_advanced_guide/disparity_search_offset.html @@ -0,0 +1,472 @@ + + + + + + + + + 5.6. Disparity_search_offset — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.6. Disparity_search_offset

+
+

This section describes how to use the disparity_search_offset function in the Gemini330 series cameras (minimum camera firmware version 1.4.60).Disparity_search_offset is effective only for1280×720, 1280×800 and 640×400 resolutions of depth stream.

+
+
+

5.6.1. Function Introduction

+

The definition of disparity search range: For any pixel (u_l, v) in the left image, by default, the corresponding disparity search range in the right image is [ (u_l - 255, v), (u_l, v) ], where the disparity search length is 256 and the maximum integer disparity is 255. If the starting point of the search is adjusted to [ (u_l - 255 - offset, v), (u_l - offset, v) ], the offset is defined as the disparity shift. Therefore, our disparity search range configuration includes both the disparity search length and the search position offset (which can also be referred to as the disparity shift).

+

Depth Point Cloud Visualization

+
+
+

5.6.2. Parameter Introduction

+

The disparity_search_offset related parameters are set in gemini_330_series.launch.py

+
    +
  • disparity_range_mode : Disparity search length,can only be set to 64, 128 and 256.

  • +
  • disparity_search_offset : Disparity search offset value,Disparity search offset value, can be set from 0 to 127.

  • +
  • disparity_offset_config : Disparity search offset interleave frames.

  • +
  • offset_index0 : Frame 0 disparity search offset value.

  • +
  • offset_index1 : Frame 1 disparity search offset value.

  • +
+ + + + + + + + + + + + + + + + + + + + +
disparity range modedisparity search offsetMinimum depth of inclined wall (mm)
6485Gemini 335L  388-406
64127Gemini 335L  302-317
+ + + + + + + + + + + + + + + + + + + + + + + + +
disparity range modedisparity search offsetMinimum depth of inclined wall (mm)
1280Gemini 335  233-249
Gemini 335L  453-475
12845Gemini 335  172-184
Gemini 335L  334-349
128127Gemini 335  117-125
Gemini 335L  226-236
+ + + + + + + + + + + + + + + + + + + +
disparity range modedisparity search offsetMinimum depth of inclined wall (mm)
25685Gemini 335L  169-178
256127Gemini 335L  151-158
+
+

5.6.3. Run the launch

+

Setting the disparity_search_offset parameter,colcon build again and run launch

+
ros2 launch orbbec_camera gemini_330_series.launch.py
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/efficient_intra_process_communication.html b/source/5_advanced_guide/efficient_intra_process_communication.html new file mode 100644 index 00000000..feedb186 --- /dev/null +++ b/source/5_advanced_guide/efficient_intra_process_communication.html @@ -0,0 +1,416 @@ + + + + + + + + + 5.7. Efficient intra-process communication: — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.7. Efficient intra-process communication:

+

Our ROS2 Wrapper node supports zero-copy communications if loaded in the same process as a subscriber node. This can reduce copy times on image/pointcloud topics, especially with big frame resolutions and high FPS.

+

You will need to launch a component container and launch our node as a component together with other component nodes. Further details on “Composing multiple nodes in a single process” can be found here.

+

Further details on efficient intra-process communication can be found here.

+
+

5.7.1. Example

+
+

5.7.1.1. Manually loading multiple components into the same process

+
    +
  • Start the component:

    +
    ros2 run rclcpp_components component_container
    +
    +
    +
  • +
  • Add the wrapper:

    +
    ros2 component load /ComponentManager orbbec_camera orbbec_camera::OBCameraNodeDriver -e use_intra_process_comms:=true
    +
    +
    +

    Load other component nodes (consumers of the wrapper topics) in the same way.

    +
  • +
+
+
+

5.7.1.2. Using a launch file

+
ros2 launch orbbec_camera gemini_intra_process_demo_launch.py
+
+
+
+
+

5.7.1.3. Limitations

+
    +
  • Node components are currently not supported on RCLPY

  • +
  • Compressed images using image_transport will be disabled as this isn’t supported with intra-process communication

  • +
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/fastdds_tuning.html b/source/5_advanced_guide/fastdds_tuning.html new file mode 100644 index 00000000..30910d11 --- /dev/null +++ b/source/5_advanced_guide/fastdds_tuning.html @@ -0,0 +1,528 @@ + + + + + + + + + 5.8. Fast DDS Optimization for Orbbec Camera with ROS2 — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.8. Fast DDS Optimization for Orbbec Camera with ROS2

+

When operating with the default configuration, Fast DDS exhibits suboptimal transmission efficiency, resulting in +significant image transmission delays when used with the Orbbec camera in ROS2. This document provides guidance on +optimizing Fast DDS to enhance image transfer efficiency.

+
+

5.8.1. Adjusting System Parameters

+
+

5.8.1.1. IP Fragmentation Time

+
    +
  • Path: /proc/sys/net/ipv4/ipfrag_time (default: 30 seconds)

  • +
  • Purpose: Defines the duration that IP fragments are kept in memory.

  • +
  • Adjustment: Decrease this value to reduce the time window where no fragments are received, which can help reduce +delays. Consider the specific needs of your environment as this setting affects all incoming fragments.

    +

    Example: Set to 3 seconds.

    +
    sudo sysctl net.ipv4.ipfrag_time=3
    +
    +
    +
  • +
+
+
+

5.8.1.2. IP Fragmentation Memory Threshold

+
    +
  • Path: /proc/sys/net/ipv4/ipfrag_high_thresh (default: 262144 bytes)

  • +
  • Purpose: Sets the maximum memory used to reassemble IP fragments.

  • +
  • Adjustment: Increase this value to allow more memory for fragment reassembly, which can improve handling of larger +data packets.

    +

    Example: Increase to 128 MB.

    +
    sudo sysctl net.ipv4.ipfrag_high_thresh=134217728
    +
    +
    +
  • +
+
+
+

5.8.1.3. Maximum Buffer Sizes

+
    +
  • Purpose: Configures the maximum buffer sizes for receiving and sending data, which is critical for high-throughput +data transmission.

  • +
  • Adjustment: Set the maximum buffer sizes for both receiving and sending operations.

    +

    Commands:

    +
    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
    +
    +
    +
  • +
+

Alternatively, make these settings permanent by adding them to the /etc/sysctl.d/10-fastrtps-max.conf file.

+
sudo gedit /etc/sysctl.d/10-fastrtps-max.conf
+
+
+

add blow lines to the file:

+
net.core.rmem_max=2147483647
+net.core.rmem_default=2147483647
+net.core.wmem_max=2147483647
+net.core.wmem_default=2147483647
+
+
+

then save and exit the file. run sudo sysctl -p to apply the changes.

+

For detailed guidance, refer +to ROS 2 DDS Tuning Documentation.

+
+
+
+

5.8.2. Fast DDS Configuration

+

Below is an example of a Fast DDS configuration file optimized for ROS2 usage with the Orbbec camera. This configuration +enhances the overall data transmission by adjusting buffer sizes and transport settings.

+
+

5.8.2.1. Configuration File: shm_fastdds.xml

+

Place this file in the $HOME directory.

+
<?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>
+
+
+
+
+

5.8.2.2. Environment Variables

+

Set the following environment variables to use the custom Fast DDS profile:

+
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
+export FASTRTPS_DEFAULT_PROFILES_FILE=$HOME/shm_fastdds.xml
+export RMW_FASTRTPS_USE_QOS_FROM_XML=1
+
+
+

This configuration aims to optimize the data flow and reduce transmission delays, improving the responsiveness and +reliability of the Orbbec camera system in a ROS2 environment.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/gmsl_camera.html b/source/5_advanced_guide/gmsl_camera.html new file mode 100644 index 00000000..0d8db40f --- /dev/null +++ b/source/5_advanced_guide/gmsl_camera.html @@ -0,0 +1,428 @@ + + + + + + + + + 5.9. GMSL_camera — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.9. GMSL_camera

+
+

This section describes how to use GMSL camera in OrbbecSDK_ROS2.Currently, only Gemini 335Lg GMSL devices are supported, and other GMSL devices will be supported in the near future.

+
+
+

5.9.1. Single GMSL camera

+

The usage of GMSL camera in OrbbecSDK_ROS2 is the same as that of Gemini 330 series camera via USB.

+
ros2 launch orbbec_camera gemini_330_gmsl.launch.py
+
+
+
+
+

5.9.2. Multi GMSL camera

+

To get the usb_port of the GMSL camera, plug in the camera and run the following command in the terminal:

+
ros2 run orbbec_camera list_devices_node
+
+
+

For example, the obtained gmsl camera usb_port: gmsl2-1

+

Go to the multi_gmsl_camera.launch.py file and change the usb_port.

+
ros2 launch orbbec_camera multi_gmsl_camera.launch.py
+
+
+
+

Note: By default, multi_gmsl_camera.launch.py only starts color and left_ir. If you want to start other sensors, please go to camera_secondary_params.yaml to modify them.

+
+
+
+

5.9.3. Multi GMSL camera synced

+

First, please see how to use multi_camera_synced.

+

In addition, GMSL multi-camera synced does not require Multi-Camera Sync Hub Pro, so there is no need to set the primary mode. Each GMSL camera is secondary.

+
+

5.9.3.1. Additional Parameter Settings

+
    +
  • gmsl_trigger_fps : set hardware soc trigger source frame rate.

  • +
  • enable_gmsl_trigger : enable hardware soc trigger.

  • +
+
+
+

5.9.3.2. Run the launch

+

Please refer to the configuration in multi_gmsl_camera_synced.launch.py.

+
ros2 launch orbbec_camera multi_gmsl_camera_synced.launch.py
+
+
+
+

Note: By default, multi_gmsl_camera_synced.launch.py only starts color and left_ir. If you want to start other sensors, please go to camera_secondary_params.yaml and camera_params.yaml to modify them.

+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/interleave_ae_mode.html b/source/5_advanced_guide/interleave_ae_mode.html new file mode 100644 index 00000000..d872cc92 --- /dev/null +++ b/source/5_advanced_guide/interleave_ae_mode.html @@ -0,0 +1,442 @@ + + + + + + + + + 5.10. Using interleave_ae with Gemini330 series cameras — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.10. Using interleave_ae with Gemini330 series cameras

+
+

This section describes how to use interleave_ae in Gemini 330 series cameras (minimum camera firmware version 1.4.00)

+
+
+

5.10.1. Parameter Introduction

+

The interleave_ae related parameters are set in gemini_330_series.launch.py

+
    +
  • interleave_ae_mode : Set laser or hdr interleave.

  • +
  • interleave_frame_enable : enable interleave frame mode.

  • +
  • interleave_skip_enable : enable skip frame mode.

  • +
  • interleave_skip_index : Set 0 for skip pattern ir, set 1 for skip flood ir.

  • +
+
+

5.10.1.1. interleave hdr

+

When the interleave_ae_mode parameter is set to hdr and interleave_frame_enable is set to true, interleave hdr will be enabled

+
    +
  • hdr_index1_laser_control : Frame 1 laser switch settings.

  • +
  • hdr_index1_depth_exposure : Frame 1 depth exposure value setting, not in AE mode.

  • +
  • hdr_index1_depth_gain : Frame 1 depth gain value setting, not in AE mode.

  • +
  • hdr_index1_ir_brightness : Frame 1 ir gain value setting.

  • +
  • hdr_index1_ir_ae_max_exposure : Frame 1 ir maximum exposure value setting in AE (auto exposure).

  • +
  • hdr_index0_laser_control: Frame 0 laser switch settings.

  • +
  • hdr_index0_depth_exposure: Frame 0 depth exposure value setting, not in AE mode.

  • +
  • hdr_index0_depth_gain : Frame 0 depth gain value setting, not in AE mode.

  • +
  • hdr_index0_ir_brightness : Frame 0 ir gain value setting.

  • +
  • hdr_index0_ir_ae_max_exposure : Frame 0 ir maximum exposure value setting in AE (auto exposure).

  • +
+
+
+

5.10.1.2. interleave laser

+

When the interleave_ae_mode parameter is set to laser and interleave_frame_enable is set to true, interleave laser will be enabled

+
    +
  • laser_index1_laser_control : Frame 1 laser switch settings.

  • +
  • laser_index1_depth_exposure : Frame 1 depth exposure value setting, not in AE mode.

  • +
  • laser_index1_depth_gain : Frame 1 depth gain value setting, not in AE mode.

  • +
  • laser_index1_ir_brightness : Frame 1 ir gain value setting.

  • +
  • laser_index1_ir_ae_max_exposure : Frame 1 ir maximum exposure value setting in AE (auto exposure).

  • +
  • laser_index0_laser_control : Frame 0 laser switch settings.

  • +
  • laser_index0_depth_exposure : Frame 0 depth exposure value setting, not in AE mode.

  • +
  • laser_index0_depth_gain : Frame 0 depth gain value setting, not in AE mode.

  • +
  • laser_index0_ir_brightness : Frame 0 ir gain value setting.

  • +
  • laser_index0_ir_ae_max_exposure : Frame 0 ir maximum exposure value setting in AE (auto exposure).

  • +
+
+
+
+

5.10.2. Run the launch

+

Setting the interleave_ae parameter,colcon build again and run launch

+
ros2 launch orbbec_camera gemini_330_series.launch.py
+
+
+
+

5.10.2.1. Example Visualization

+

Depth Point Cloud Visualization

+

Depth Point Cloud Visualization

+
+
+
+

5.10.3. Multi_camera_synced + Interleave_ae

+

Please refer to multi_camera_synced and Parameter Introduction

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/lower_cpu_usage.html b/source/5_advanced_guide/lower_cpu_usage.html new file mode 100644 index 00000000..a6287820 --- /dev/null +++ b/source/5_advanced_guide/lower_cpu_usage.html @@ -0,0 +1,585 @@ + + + + + + + + + 5.11. Reducing CPU Usage with Orbbec ROS Package — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.11. Reducing CPU Usage with Orbbec ROS Package

+

This document outlines strategies for minimizing CPU usage in the OrbbecSDK_ROS2 v2 environment when using Gemini 330 series cameras. The firmware version must be no lower than 1.4.10, and device should be set to Default.

+ +
+

5.11.2. Launch Files Used for Testing

+
    +
  • gemini_330_series_lower_cpu_usage.launch.py

  • +
  • multi_camera_lower_cpu_usage.launch.py

  • +
+
+
+

5.11.3. Test environment

+
+

5.11.3.1. Hardware Configuration

+
    +
  • CPU: Intel i7-8700 @ 3.20GHz

  • +
  • Memory: 24 GB

  • +
  • Storage: Micron 2200S NVMe 256GB

  • +
  • GPU: NVIDIA GeForce GTX 1660Ti

  • +
  • OS: Ubuntu22.04

  • +
+
+
+

5.11.3.2. ROS Configuration

+
    +
  • ROS Version: ROS2 Humble

  • +
  • SDK Version: OrbbecSDK_ROS2 v2.2.1

  • +
+
+
+

5.11.3.3. Camera Setup

+
    +
  • Devices: 2x Gemini 335, 1x Gemini 336, 1x Gemini 336L

  • +
  • Firmware Version: 1.4.10

  • +
+
+
+
+

5.11.4. Test Setup

+
    +
  • Stream Settings:

    +
      +
    • Depth / IR Left / IR Right: 848×480 @ 30fps

    • +
    • Color: 848×480 @ 30fps

    • +
    +
  • +
+

Note: The following CPU usage data focuses on uvc_backend, color_format and various filter combinations.

+
+
+

5.11.5. Test Results

+
+

5.11.5.1. uvc_backend Comparison (RGB format)

+ + + + + + + + + + + + + + + +
libuvc CPU Usagev4l2 CPU UsageAbsolute Change
182.8%118.8%-64.0%

The CPU usage can be significantly reduced with v4l2 backend. In our implementation, v4l2 works without requiring any patches to the Linux kernel, allowing users to easily switch between v4l2 and libuvc and maintaining full compatibility with standard Linux distributions.

+
+
+

5.11.5.2. color_format Comparison (MJPG vs RGB)

+ + + + + + + + + + + + + + + + + + + + + + + +
BackendMJPG CPU UsageRGB CPU UsageAbsolute Change
libuvc347.7%182.8%-164.9%
v4l2170.0%118.8%-51.2%

The CPU usage can be reduced if the RGB format is selected instead of MJPG, since the decoding of MJPG image will consume the host CPU resource.

+
+
+

5.11.5.3. Filter Configuration Impact

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Filters Appliedlibuvc CPU UsageCPU Usage Increasev4l2 CPU UsageCPU Usage Increase
No Filter (benchmark)182.8%0.0%(benchmark)118.8%0.0%(benchmark)
(software)noise_removal_filter218.0%+35.2%128.5%+9.7%
(software)noise_removal_filter + spatial_filter469.6%+286.8%336.7%+217.9%
hardware_noise_removal_filter186.3%+3.5%115.4%-3.4%
hardware_noise_removal_filter + spatial_filter251.3%+68.5%152.5%+33.7%

Based on the test results, using only the hardware_noise_removal_filter results in a negligible change in CPU usage for both libuvc (+3.5%) and v4l2 (-3.4%) compared to the no-filter benchmark, as this filter runs internally on the camera hardware. In contrast, other filters execute on the host system. Adding the spatial_filter to the hardware filter leads to a moderate increase in CPU usage, while applying the software-based noise_removal_filter —either alone or combined with spatial_filter —significantly increases CPU load. To maintain low CPU usage, it is recommended to avoid software-based filters and rely solely on the hardware_noise_removal_filter.

+
+
+
+

5.11.6. Further Optimizationa

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterRecommendationNote
depth_registrationfalse or true with align_mode=HWSoftware alignment consumes more CPU
enable_point_cloudfalseDisabling point cloud reduces CPU usage
enable_colored_point_cloudfalseDisabling colored point cloud reduces CPU usage
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/multi_camera.html b/source/5_advanced_guide/multi_camera.html new file mode 100644 index 00000000..9bb13b6c --- /dev/null +++ b/source/5_advanced_guide/multi_camera.html @@ -0,0 +1,471 @@ + + + + + + + + + 5.12. Multi-Camera — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.12. Multi-Camera

+
    +
  • To get the usb_port of the camera, plug in the camera and run the following command in the terminal:

  • +
+
ros2 run orbbec_camera list_devices_node
+
+
+
    +
  • Set the device_num parameter to the number of cameras you have.

  • +
  • Go to the OrbbecSDK_ROS2/launch/multi_xxx.launch.py file and change the usb_port.

  • +
  • Don’t forget to put the include tag inside the group tag. +Otherwise, the parameter values of different cameras may become contaminated.

  • +
+
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
+
+
+
    +
  • To launch the cameras, run the following command:

  • +
+
ros2 launch orbbec_camera multi_camera.launch.py
+
+
+
+

5.12.1. No Data Stream from Multiple Cameras

+

Insufficient Power Supply:

+
    +
  • Ensure that each camera is connected to a separate hub.

  • +
  • Use a powered hub to provide sufficient power to each camera.

  • +
+

High Resolution:

+
    +
  • Try lowering the resolution to resolve data stream issues.

  • +
+

Increase usbfs_memory_mb Value:

+
    +
  • Increase the usbfs_memory_mb value to 128MB (this is a reference value and can be adjusted based on your system’s needs) +by running the following command:

  • +
+
    echo 128 | sudo tee /sys/module/usbcore/parameters/usbfs_memory_mb
+
+
+
    +
  • To make this change permanent, check this link.

  • +
+
+
+

5.12.2. Image topic frame rate too low from Multiple Cameras

+

Refer to the Fast DDS Configuration file.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/multi_camera_synced.html b/source/5_advanced_guide/multi_camera_synced.html new file mode 100644 index 00000000..0f363154 --- /dev/null +++ b/source/5_advanced_guide/multi_camera_synced.html @@ -0,0 +1,459 @@ + + + + + + + + + 5.13. Multi_camera synced Instructions — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.13. Multi_camera synced Instructions

+
+

The purpose of this document is to explain how to use multi-camera synced with OrbbecSDK_ROS2

+
+
+

5.13.1. Setup instructions

+
    +
  • Please read the Multi-Camera Synchronization Setup Guide:Multi-Camera Synchronization Setup

  • +
  • Make sure the camera is correctly connected to the multi-camera synchronizer.

  • +
+

Depth Point Cloud Visualization

+
+

5.13.1.1. Checking camera port with OrbbecSDK_ROS2

+
ros2 run orbbec_camera list_devices_node
+
+
+
+
+

5.13.1.2. OrbbecSDK_ROS2 multi-camera synced configuration

+

Open multi_camera_synced.launch.py, and configure the camera settings as shown below:

+

Depth Point Cloud Visualization

+
    +
  1. gemini_330_series.launch.py is the launch file for starting the camera.

  2. +
  3. Set camera_name to G330_0. For example, the published color image topic will be /G330_0/color/image_raw.

  4. +
  5. Set usb_port to 2-2, indicating that the camera device on port 2-2 is being used. This value can be found in the output of the ros2 run orbbec_camera list_devices_node command.

  6. +
  7. Set device_num to 2, meaning two cameras will be used.

  8. +
  9. Set sync_mode to primary to indicate that the 2-7 camera device is in primary mode. The multi-camera sync mode options can be found in the figure below.

  10. +
  11. Parameters from the config_file_path can override the parameters set in gemini_330_series.launch.py (optional).

  12. +
  13. For slave cameras, set trigger_out_enabled to false.

  14. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Pattern NameSetting effect description
free_run-Support different frame rate settings
The -8-pin synchronization interface does not support external output of synchronization-related signals
standalone(default)● Same as Primary by default
● Built-in RGBD frame synchronization
● 8-pin synchronous interface does not output signals to the outside by default
primary● Set as primary camera
● 8-pin synchronous interface output signal to external device
secondary● Set as secondary (passive synchronization; When there is a hardware continuous trigger signal input from the outside and the continuous trigger signal matches the currently set frame rate, the image is collected according to the external trigger signal; When there is no external trigger signal, the flow is stopped)
● 8-pin synchronous interface output signal to external device
secondary_synced● Set to secondary synchronization (passive synchronization; When there is a hardware continuous trigger signal input from the outside and the continuous trigger signal matches the currently set frame rate, the image is collected according to the external trigger signal; When there is no external trigger signal, the image is collected according to the internal trigger signal at the set frame rate)
● 8-pin synchronous interface output signal to external device
hardware_triggering● Set as hardware trigger (passive trigger; When there is a hardware trigger signal input from the outside and the trigger signal time interval is not less than the current upper limit, the image is collected according to the external trigger signal; When there is no external trigger signal, the image is not collected)
● 8-pin synchronous interface output signal to external device
software_triggering● Set as software trigger (passive trigger; When there is a trigger command input from the host computer and the trigger command time interval is not less than the current upper limit, the image is collected according to the trigger command; When there is no trigger command, the image is not collected)
● 8-pin synchronous interface output signal to external device
    +
  • The master camera should be launched last.

  • +
  • Ideally, there should be a 2-second delay between starting each camera.

  • +
+
+
+

5.13.1.3. Run the following command to start the multi-camera synced

+
ros2 launch orbbec_camera multi_camera_synced.launch.py
+
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/multi_camera_synced_verification_tool.html b/source/5_advanced_guide/multi_camera_synced_verification_tool.html new file mode 100644 index 00000000..25ddf46b --- /dev/null +++ b/source/5_advanced_guide/multi_camera_synced_verification_tool.html @@ -0,0 +1,548 @@ + + + + + + + + + 5.14. Multi_camera_synced_verification_tool — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.14. Multi_camera_synced_verification_tool

+
+

This article will introduce how to verify the synchronization accuracy of multi-camera synchronization.

+

First, please see how to use multi_camera_synced.

+
+
+

5.14.1. Directory Structure

+
.
+├── multicamera_sync/
+│   ├── output/
+│       ├──20250218102900/
+│          ├──DevicesInfo.txt
+│          ├──StreamProfileInfo.txt
+│   ├── Python/
+│       ├──Config.ini
+├── gemini_330_series_synced_verify.launch.py
+├── multi_camera_synced_verify.launch.py
+
+
+
+

5.14.1.1. multicamera_sync

+
    +
  • gemini_330_series_synced_verify.launch.py : Single camera runs launch, which provides the camera running node for multi_camera_synced_verify.launch.py.

  • +
  • multi_camera_synced_verify.launch.py : Multi camer synced + launch of save_rgbir tool.

  • +
+
+

5.14.1.1.1. output

+
+

The ouput folder is the folder where the camera pictures are output

+
+

In the output example provided

+
    +
  • 20250218102900 : Represents the camera image information collected at 10:29:00 on February 18, 2025.

  • +
  • TotalModeFrames : Camera image information storage directory.

  • +
  • results-2025-02-25_163648 : The result after analyzing and matching the image information of TotalModeFrames.

  • +
  • DevicesInfo.txt : Camera equipment basic information (need to be modified).

  • +
  • StreamProfileInfo.txt : Camera video stream information (no need to modify).

  • +
+
+
+

5.14.1.1.2. Python

+
    +
  • Config.ini : Configuration file for Python analysis script (need to be modified).

  • +
+
+
+
+
+

5.14.2. Preparation for operation

+
+

5.14.2.1. save_rgbir node

+

Edit multi_camera_synced_verify.launch.py and fill in the activated camera device,we can find that save_rgbir is started at the end.

+
+

IMPORTANT

+

If you are using ROS 2 Foxy, you need to launch the save_rgbir node first.

+
+
# Launch description
+    ld = LaunchDescription(
+        [
+            shared_orbbec_container,
+            TimerAction(period=0.0, actions=[GroupAction([launch2_include])]),
+            TimerAction(period=2.0, actions=[GroupAction([launch1_include])]),
+            # The primary camera should be launched at last
+            TimerAction(period=6.0, actions=[GroupAction([save_rgbir])]),
+            # save_rgbir is synced verification tool
+        ]
+    )
+
+    return ld
+
+
+

save_rgbir is a tool for saving images. The configuration file of this tool is in multi_save_rgbir_params.json.

+
{
+  "save_rgbir_params": {
+      "time_domain": "global",
+      "usb_ports": [
+          "2-1",
+          "2-3"
+      ],
+      "camera_name": [
+          "camera_01",
+          "camera_02"
+      ]
+  }
+}
+
+
+
    +
  • time_domain : Timestamp Type

  • +
  • usb_ports : “primary”, “secondary 1”, “secondary 2”, “secondary 3”, fill in as many usb_ports as there are cameras

  • +
  • camera_name : The name of the camera setting, for example: camera_01

  • +
+
+
+

5.14.2.2. DevicesInfo.txt

+

Edit DevicesInfo.txt. Only the primarySerialNumber, index and serialNumber parameters need to be changed. Other parameters do not need to be changed.Refer to the example of 20250218102900.

+
    +
  • primarySerialNumber : The SN serial number of the primary camera

  • +
  • index : Camera index

  • +
  • serialNumber : The SN serial number of the camera

  • +
+
+
+

5.14.2.3. Config.ini

+

Edit Config.ini.Modify frameRate and tspRangeThreshold.

+
+
+
+

5.14.3. Run this example

+
+

5.14.3.1. Run launch and save camera pictures

+
    +
  • First terminal

  • +
+
ros2 launch orbbec_camera multi_camera_synced_verify.launch.py
+
+
+
    +
  • Second terminal

  • +
+
ros2 service call /save_rgbir/start_capture orbbec_camera_msgs/srv/SetInt32 '{data: 100}'
+
+
+

When the terminal displays “over”, the image is saved.A new multicamera_sync folder will be generated under the workspace.

+
+
+

5.14.3.2. Camera pictures naming format

+

Take color_SNCP1E5420006D_Index0_g1739874543227_f0_s1739874543327_e50_d16_.jpg as an example

+
    +
  • color : This image is a snapshot of the color stream.

  • +
  • SNCP1E5420006D : The camera’s SN serial number is CP1E5420006D.

  • +
  • Index0 : Camera 0 (usually referred to primary camera).

  • +
  • g1739874543227 : “g” represents the global timestamp, which means the global timestamp of this frame is 1739874543227.

  • +
  • f0 : The 0th picture of the color stream acquisition of this camera.

  • +
  • s1739874543327 : “s” represents the timestamp of the current system, which means the current system timestamp of this frame is 1739874543327.

  • +
  • e50 : The exposure of this frame is 50.

  • +
  • d16 : The gain of this frame is 16.

  • +
+
+
+

5.14.3.3. Analyzing camera image data

+

You need to copy the modified Python folder to the new multi_camera_synced subdirectory, and copy the modified DevicesInfo.txt and StreamProfileInfo.txt to the same level directory as the TotalModeFrames folder.

+
    +
  • Finally everything is ready, run the python script

  • +
+
cd multicamera_sync/Python
+python3 SyncFramesMain.py
+
+
+

After the operation is successful, you can view the synchronization effect in the results folder

+
+
+
+

5.14.4. Files that need to be changed

+
+

5.14.4.1. Analysis tools

+ +
+
+

5.14.4.2. Camera Configuration

+

camera_params.yaml(Camera startup parameter settings)

+

multi_camera_synced_verify.launch.py

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/net_camera.html b/source/5_advanced_guide/net_camera.html new file mode 100644 index 00000000..91bb47eb --- /dev/null +++ b/source/5_advanced_guide/net_camera.html @@ -0,0 +1,450 @@ + + + + + + + + + 5.15. Net_camera — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.15. Net_camera

+
+

This section describes how to use Net camera in OrbbecSDK_ROS2.Currently, only Femto_Mega, Gemini 335Le and Gemini 435Le devices are supported, and other Net devices will be supported in the near future.

+
+
+

5.15.1. Femto Mega & Gemini 435Le

+
+

5.15.1.1. Parameter Introduction

+

Network device settings: enumerate_net_device is set to true, which will automatically enumerate network devices.

+

If you do not want to automatically enumerate network devices,you can set enumerate_net_device to false, net_device_ip to the device’s IP address, and net_device_port to the default value of 8090.

+
    +
  • enumerate_net_device : Enable automatically enumerate network devices.

  • +
  • net_device_ip : Setting net device’s IP address.

  • +
  • net_device_port : Setting net device’s port.Usually, you can set it to 8090.

  • +
+
+
+

5.15.1.2. Single Net camera

+
+

If you need to run Gemini 435Le, you only need to replace femto_mega.launch.py in the run command with gemini435_le.launch.py

+
+

For femto_mega.launch.py as an example:

+
    +
  • automatically enumerate network devices:

  • +
+
ros2 launch orbbec_camera femto_mega.launch.py enumerate_net_device:=true
+
+
+
    +
  • Specify IP address to start the device:

  • +
+

Note: net_device_ip needs to be changed to the IP address of the device, here it is 192.168.1.10

+
ros2 launch orbbec_camera femto_mega.launch.py enumerate_net_device:=false net_device_ip:=192.168.1.10 net_device_port:=8090
+
+
+
+
+
+

5.15.2. Gemini 335Le

+

Network device settings: enumerate_net_device must be set to true, set net_device_ip to the IP address of the device, and set net_device_port to the default value of 8090.

+
    +
  • enumerate_net_device : Enable automatically enumerate network devices.

  • +
  • net_device_ip : Setting net device’s IP address.

  • +
  • net_device_port : Setting net device’s port.Usually, you can set it to 8090.

  • +
+
+

5.15.2.1. Single Net camera

+

For gemini_330_series.launch.py as an example:

+
    +
  • automatically enumerate network devices:

  • +
+
ros2 launch orbbec_camera gemini_330_series.launch.py enumerate_net_device:=true
+
+
+
    +
  • Specify IP address to start the device:

  • +
+

Note: net_device_ip needs to be changed to the IP address of the device, here it is 192.168.1.10

+
ros2 launch orbbec_camera gemini_330_series.launch.py enumerate_net_device:=true net_device_ip:=192.168.1.10 net_device_port:=8090
+
+
+
+
+
+

5.15.3. Multi Net camera

+

For multi_net_camera.launch.py as an example:

+
ros2 launch orbbec_camera multi_net_camera.launch.py
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/point_cloud.html b/source/5_advanced_guide/point_cloud.html new file mode 100644 index 00000000..1b1e8fde --- /dev/null +++ b/source/5_advanced_guide/point_cloud.html @@ -0,0 +1,432 @@ + + + + + + + + + 5.16. Enabling and Visualizing Point Cloud in ROS 2 — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.16. Enabling and Visualizing Point Cloud in ROS 2

+

This section demonstrates how to enable point cloud data output from the camera node and visualize it using RViz2.

+
+

5.16.1. Enabling Depth Point Cloud

+
+

5.16.1.1. Command to Enable Depth Point Cloud

+

To activate the point cloud data stream for depth information, use the following command:

+
ros2 launch orbbec_camera gemini_330_series.launch.py enable_point_cloud:=true
+
+
+
+
+

5.16.1.2. Visualizing Depth Point Cloud in RViz2

+

After running the above command, perform the following steps to visualize the depth point cloud:

+
    +
  1. Open RViz2.

  2. +
  3. Add a PointCloud2 display.

  4. +
  5. Select the /camera/depth/points topic for visualization.

  6. +
  7. Set the fixed frame to camera_link to properly align the data.

  8. +
+
    +
  • Example Visualization

  • +
+

Here is what the depth point cloud might look like in RViz2:

+

Depth Point Cloud Visualization

+
+
+
+

5.16.2. Enabling Colored Point Cloud

+
+

5.16.2.1. Command to Enable Colored Point Cloud

+

To enable the colored point cloud feature, enter the following command:

+
ros2 launch orbbec_camera gemini_330_series.launch.py enable_colored_point_cloud:=true
+
+
+
+
+

5.16.2.2. Visualizing Colored Point Cloud in RViz2

+

To visualize the colored point cloud data:

+
    +
  1. Launch RViz2 following the command execution.

  2. +
  3. Add a PointCloud2 display panel.

  4. +
  5. Choose the /camera/depth_registered/points topic from the list.

  6. +
  7. Ensure the fixed frame is set to camera_link.

  8. +
+
    +
  • Example Visualization

  • +
+

The result of the colored point cloud in RViz2 should look similar to this:

+

Colored Point Cloud Visualization

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/5_advanced_guide/predefined_presets.html b/source/5_advanced_guide/predefined_presets.html new file mode 100644 index 00000000..e407c480 --- /dev/null +++ b/source/5_advanced_guide/predefined_presets.html @@ -0,0 +1,423 @@ + + + + + + + + + 5.17. Predefined presets — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

5.17. Predefined presets

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PresetFeaturesRecommended use cases
Default- Best visual perception``- Overall good performance in accuracy, fill rate, tiny objects, etc.- Generic <br>- Robotics
Hand- Clear hand and finger edges- Gesture recognition
High Accuracy- Depth of high confidence <br>- Barely noise depth values <br>- Lower fill rate- Collision avoidance <br>- Object scanning
High Density- Higher fill rate <br>- More tiny objects <br>- May suffer from noise depth values- Object recognition <br>- Pick & place <br>- Foreground & background animation
Medium Density- Balanced performance in fill rate and accuracy <br>- In comparison to Default: lower fill rate, better edge quality- Generic and alternative to Default
Custom- User defined Preset <br>- Derived from Presets above, with customized modifications, e.g. a new configuration for the post-processing pipeline, modified mean intensity set point of depth AE function, etc.- Better depth performance achieved using customized configurations in comparison to using predefined presets <br>- For well-established custom configurations

Choose the appropriate preset name based on your specific use case and set it as the value for the device_preset +parameter.

+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/6_FAQ/FAQ.html b/source/6_FAQ/FAQ.html new file mode 100644 index 00000000..4fcc4d7e --- /dev/null +++ b/source/6_FAQ/FAQ.html @@ -0,0 +1,418 @@ + + + + + + + + + 6. Frequently Asked Questions — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

6. Frequently Asked Questions

+
+

6.1. Unexpected Crash

+

If the camera node crashes unexpectedly, it will generate a crash log in the current running directory: Log/camera_crash_stack_trace_xx.log. Please send this log to the support team or submit it to a GitHub issue for further assistance.

+
+
+

6.2. No Data Stream from Multiple Cameras

+

Insufficient Power Supply:

+
    +
  • Ensure that each camera is connected to a separate hub.

  • +
  • Use a powered hub to provide sufficient power to each camera.

  • +
+

High Resolution:

+
    +
  • Try lowering the resolution to resolve data stream issues.

  • +
+

Increase usbfs_memory_mb Value:

+
    +
  • Increase the usbfs_memory_mb value to 128MB (this is a reference value and can be adjusted based on your system’s needs) by running the following command:

  • +
+
    echo 128 | sudo tee /sys/module/usbcore/parameters/usbfs_memory_mb
+
+
+
    +
  • To make this change permanent, check this link.

  • +
+
+
+

6.3. Additional Troubleshooting

+
    +
  • If you encounter other issues, set the log_level parameter to debug. This will generate an SDK log file in the running directory: Log/OrbbecSDK.log.txt. Please provide this file to the support team for further assistance.

  • +
  • If firmware logs are required, set enable_heartbeat to true to activate this feature.

  • +
+
+
+

6.4. Why Are There So Many Launch Files?

+
    +
  • Different cameras have varying default resolutions and image formats.

  • +
  • To simplify usage, each camera has its own launch file.

  • +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/source/license.html b/source/license.html new file mode 100644 index 00000000..eeff9221 --- /dev/null +++ b/source/license.html @@ -0,0 +1,383 @@ + + + + + + + + + License — OrbbecSDK V2 ROS2 Wrapper documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

License

+

Copyright 2024 Orbbec INC.

+

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this project except in compliance with +the License. You may obtain a copy of the License at

+

http://www.apache.org/licenses/LICENSE-2.0

+

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “ +AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific +language governing permissions and limitations under the License.

+

Other names and brands may be claimed as the property of others.

+
+ + +
+
+
+ +
+ +
+

© Copyright 2025, ORBBEC INC. www.orbbec.com.. + Last updated on 2025-09-15 06:27:18. +

+
+ + + +
+
+
+
+
+ + + + \ No newline at end of file