tmp
@@ -0,0 +1,29 @@
|
||||
# 深度工作模式切换
|
||||
|
||||
Orbbec SDK ROS 2 支持深度工作模式切换。Gemini 2、Gemini 2 L 和 Femto 以及 Femto Bolt 相机支持深度工作模式切换。
|
||||
|
||||
- 在启动相机之前,可以为相应的 xxx.launch.py 文件的支持配置深度工作模式(depth_work_mode)。
|
||||
- Gemini 2、Gemini 2 L 和 Gemini 2 XL 相机支持深度工作模式切换。
|
||||
- xxx.launch.py 的默认深度工作模式配置是相机的默认配置。如果需要修改,可以根据需要切换到相应的模式。
|
||||
- 具体相机深度工作模式支持类型可以在深度模式的注释中找到。
|
||||
|
||||
```python
|
||||
# 深度工作模式支持如下:
|
||||
# Unbinned Dense Default
|
||||
# Unbinned Sparse Default
|
||||
# Binned Sparse Default
|
||||
# Obstacle Avoidance
|
||||
DeclareLaunchArgument('depth_work_mode', default_value='')
|
||||
```
|
||||
|
||||
- 查看深度工作模式:
|
||||
|
||||
```bash
|
||||
ros2 run orbbec_camera list_depth_work_mode_node
|
||||
```
|
||||
|
||||
* 示例:
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera gemini2L.launch.py depth_work_mode:="Unbinned Dense Default"
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
# 视差搜索偏移
|
||||
|
||||
> 本节介绍如何在 Gemini330 系列相机中使用 disparity_search_offset 功能(相机固件最低版本 [1.4.60](https://www.orbbec.com/docs/g330-firmware-release/))。Disparity_search_offset 仅对深度流的 1280×720、1280×800 和 640×400 分辨率有效。
|
||||
|
||||
## 功能介绍
|
||||
|
||||
视差搜索范围的定义:对于左图像中的任何像素 *(u_l, v)*,默认情况下,右图像中对应的视差搜索范围为 *[ (u_l - 255, v)*, *(u_l, v) ]*,其中视差搜索长度为 256,最大整数视差为 255。如果将搜索的起点调整为 *[ (u_l - 255 - offset, v)*, *(u_l - offset, v) ]*,则偏移量定义为视差偏移。因此,我们的视差搜索范围配置包括视差搜索长度和搜索位置偏移(也可称为视差偏移)。
|
||||
|
||||

|
||||
|
||||
## 参数介绍
|
||||
|
||||
disparity_search_offset 相关参数在 [gemini_330_series.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/launch/gemini_330_series.launch.py) 中设置
|
||||
|
||||
* `disparity_range_mode`:视差搜索长度,只能设置为 64、128 和 256。
|
||||
|
||||
* `disparity_search_offset`:视差搜索偏移值,可以设置为 0 到 127。
|
||||
|
||||
* `disparity_offset_config`:视差搜索偏移交错帧。
|
||||
|
||||
* `offset_index0`:帧 0 视差搜索偏移值。
|
||||
|
||||
* `offset_index1`:帧 1 视差搜索偏移值。
|
||||
|
||||
| 视差范围模式 | 视差搜索偏移 | 倾斜墙最小深度 (mm) |
|
||||
| :------------------: | :---------------------: | :---------------------------------: |
|
||||
| 64 | 85 | Gemini 335L 388-406 |
|
||||
| 64 | 127 | Gemini 335L 302-317 |
|
||||
|
||||
| 视差范围模式 | 视差搜索偏移 | 倾斜墙最小深度 (mm) |
|
||||
| :------------------: | :---------------------: | :---------------------------------------------: |
|
||||
| 128 | 0 | Gemini 335 233-249<br />Gemini 335L 453-475 |
|
||||
| 128 | 45 | Gemini 335 172-184<br />Gemini 335L 334-349 |
|
||||
| 128 | 127 | Gemini 335 117-125<br />Gemini 335L 226-236 |
|
||||
|
||||
| 视差范围模式 | 视差搜索偏移 | 倾斜墙最小深度 (mm) |
|
||||
| :------------------: | :---------------------: | :---------------------------------: |
|
||||
| 256 | 85 | Gemini 335L 169-178 |
|
||||
| 256 | 127 | Gemini 335L 151-158 |
|
||||
|
||||
## 运行启动文件
|
||||
|
||||
设置 disparity_search_offset 参数,重新 `colcon build` 并运行启动文件
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera gemini_330_series.launch.py
|
||||
```
|
||||
@@ -0,0 +1,81 @@
|
||||
# 在 Gemini330 系列相机中使用 interleave_ae
|
||||
|
||||
> 本节介绍如何在 Gemini 330 系列相机中使用 interleave_ae(相机固件最低版本 [1.4.00](https://www.orbbec.com/docs/g330-firmware-release/))
|
||||
|
||||
## 参数介绍
|
||||
|
||||
interleave_ae 相关参数在 [gemini_330_series.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/launch/gemini_330_series.launch.py) 中设置
|
||||
|
||||
* `interleave_ae_mode`:设置激光或 hdr 交错。
|
||||
|
||||
* `interleave_frame_enable`:启用交错帧模式。
|
||||
|
||||
* `interleave_skip_enable`:启用跳帧模式。
|
||||
|
||||
* `interleave_skip_index`:设置为 0 跳过图案 ir,设置为 1 跳过泛光 ir。
|
||||
|
||||
**interleave hdr**
|
||||
|
||||
当 `interleave_ae_mode` 参数设置为 `hdr` 且 `interleave_frame_enable` 设置为 `true` 时,将启用 interleave hdr
|
||||
|
||||
* `hdr_index1_laser_control`:帧 1 激光开关设置。
|
||||
|
||||
* `hdr_index1_depth_exposure`:帧 1 深度曝光值设置,非 AE 模式。
|
||||
|
||||
* `hdr_index1_depth_gain`:帧 1 深度增益值设置,非 AE 模式。
|
||||
|
||||
* `hdr_index1_ir_brightness`:帧 1 ir 增益值设置。
|
||||
|
||||
* `hdr_index1_ir_ae_max_exposure`:AE(自动曝光)中帧 1 ir 最大曝光值设置。
|
||||
|
||||
* `hdr_index0_laser_control`:帧 0 激光开关设置。
|
||||
|
||||
* `hdr_index0_depth_exposure`:帧 0 深度曝光值设置,非 AE 模式。
|
||||
|
||||
* `hdr_index0_depth_gain`:帧 0 深度增益值设置,非 AE 模式。
|
||||
|
||||
* `hdr_index0_ir_brightness`:帧 0 ir 增益值设置。
|
||||
|
||||
* `hdr_index0_ir_ae_max_exposure`:AE(自动曝光)中帧 0 ir 最大曝光值设置。
|
||||
|
||||
**interleave laser**
|
||||
|
||||
当 `interleave_ae_mode` 参数设置为 `laser` 且 `interleave_frame_enable` 设置为 `true` 时,将启用 interleave laser
|
||||
|
||||
* `laser_index1_laser_control`:帧 1 激光开关设置。
|
||||
|
||||
* `laser_index1_depth_exposure`:帧 1 深度曝光值设置,非 AE 模式。
|
||||
|
||||
* `laser_index1_depth_gain`:帧 1 深度增益值设置,非 AE 模式。
|
||||
|
||||
* `laser_index1_ir_brightness`:帧 1 ir 增益值设置。
|
||||
|
||||
* `laser_index1_ir_ae_max_exposure`:AE(自动曝光)中帧 1 ir 最大曝光值设置。
|
||||
|
||||
* `laser_index0_laser_control`:帧 0 激光开关设置。
|
||||
|
||||
* `laser_index0_depth_exposure`:帧 0 深度曝光值设置,非 AE 模式。
|
||||
|
||||
* `laser_index0_depth_gain`:帧 0 深度增益值设置,非 AE 模式。
|
||||
|
||||
* `laser_index0_ir_brightness`:帧 0 ir 增益值设置。
|
||||
|
||||
* `laser_index0_ir_ae_max_exposure`:AE(自动曝光)中帧 0 ir 最大曝光值设置。
|
||||
|
||||
## 运行启动文件
|
||||
|
||||
设置 interleave_ae 参数,重新 `colcon build` 并运行启动文件
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera gemini_330_series.launch.py
|
||||
```
|
||||
|
||||
**示例可视化**
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## Multi_camera_synced + Interleave_ae
|
||||
|
||||
请参考 [multi_camera_synced](./multi_camera_synced.md) 和 [参数介绍](#参数介绍)
|
||||
@@ -0,0 +1,99 @@
|
||||
# 网络相机
|
||||
|
||||
> 本节介绍如何在 OrbbecSDK_ROS2 中使用网络相机。目前仅支持 Femto_Mega、Gemini 335Le 和 Gemini 435Le 设备,其他网络设备将在不久的将来得到支持。
|
||||
|
||||
您可以在 [example](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples) 中找到示例使用代码。
|
||||
|
||||
## Femto Mega & Gemini 435Le & Gemini 335Le
|
||||
|
||||
**参数介绍**
|
||||
|
||||
网络设备设置:`enumerate_net_device` 设置为 true,将自动枚举网络设备。
|
||||
|
||||
如果您不想自动枚举网络设备,可以将 `enumerate_net_device` 设置为 false,将 `net_device_ip` 设置为设备的 IP 地址,并将 `net_device_port` 设置为默认值 8090。
|
||||
|
||||
* `enumerate_net_device`:启用自动枚举网络设备。
|
||||
* `net_device_ip`:设置网络设备的 IP 地址。
|
||||
* `net_device_port`:设置网络设备的端口。通常可以设置为 8090。
|
||||
|
||||
**单个网络相机**
|
||||
|
||||
> 如果您需要运行 Gemini 435Le/Gemini 335Le,只需在运行命令中将 [femto_mega.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/femto_mega.launch.py) 替换为 [gemini435_le.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/gemini435_le.launch.py)/[gemini_330_series.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/gemini_330_series.launch.py)
|
||||
|
||||
以 [femto_mega.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/launch/femto_mega.launch.py) 为例:
|
||||
|
||||
- **自动枚举网络设备:**
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera femto_mega.launch.py enumerate_net_device:=true
|
||||
```
|
||||
|
||||
- **指定 IP 地址启动设备:**
|
||||
|
||||
注意:`net_device_ip` 需要更改为设备的 IP 地址,这里是 192.168.1.10
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera femto_mega.launch.py enumerate_net_device:=false net_device_ip:=192.168.1.10 net_device_port:=8090
|
||||
```
|
||||
|
||||
**多个网络相机**
|
||||
|
||||
以 [multi_net_camera.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/examples/net_camera/multi_net_camera.launch.py) 为例:
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera multi_net_camera.launch.py
|
||||
```
|
||||
|
||||
## set_device_ip 工具
|
||||
|
||||
**`set_device_ip`** 可执行文件允许您直接从 ROS 2 配置网络相机的 IP 设置,包括在 DHCP 和静态 IP 之间切换,以及设置子网掩码和网关。这对于快速分配或更新 IP 地址而无需修改启动文件非常有用。
|
||||
|
||||
> **注意:**使用 `set_device_ip` 应用的 IP 设置是**永久性的**,如果设备断电或重启,**不会重置**。
|
||||
|
||||
**示例用法**
|
||||
|
||||
```bash
|
||||
ros2 run orbbec_camera set_device_ip --ros-args \
|
||||
-p old_ip:=192.168.1.10 \
|
||||
-p dhcp:=false \
|
||||
-p new_ip:=192.168.1.11 \
|
||||
-p mask:=255.255.255.0 \
|
||||
-p gateway:=192.168.1.1
|
||||
```
|
||||
|
||||
**参数**
|
||||
|
||||
- **`old_ip`** – 设备的当前 IP 地址。
|
||||
- **`dhcp`** – 设置为 `true` 使用 DHCP 或 `false` 使用静态 IP。
|
||||
- **`new_ip`** – 禁用 DHCP 时要分配的静态 IP 地址。
|
||||
- **`mask`** – 新 IP 的子网掩码。
|
||||
- **`gateway`** – 新 IP 的网关地址。
|
||||
|
||||
## 强制 IP 功能
|
||||
|
||||
**强制 IP** 功能允许您为网络相机分配**静态 IP 地址**,覆盖 DHCP 设置。当连接多个网络相机时,这非常有用,您需要每个设备具有固定的 IP 以实现可靠的通信。
|
||||
|
||||
> **注意:**如果设备断电或重启,强制 IP 配置**将被重置**。您需要在重启后重新应用设置。
|
||||
|
||||
**参数**
|
||||
|
||||
- **`force_ip_enable`** – 启用强制 IP 功能。**默认值:** `false`
|
||||
- **`force_ip_mac`** – 连接多个相机时的目标设备 MAC 地址(例如 `"54:14:FD:06:07:DA"`)。您可以使用 `list_devices_node` 查找每个设备的 MAC。**默认值:** `""`
|
||||
- **`force_ip_address`** – 要分配的静态 IP 地址。**默认值:** `192.168.1.10`
|
||||
- **`force_ip_subnet_mask`** – 静态 IP 的子网掩码。**默认值:** `255.255.255.0`
|
||||
- **`force_ip_gateway`** – 静态 IP 的网关地址。**默认值:** `192.168.1.1`
|
||||
|
||||
**示例用法**
|
||||
|
||||
- **为特定设备启用强制 IP:**
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera gemini_330_series.launch.py \
|
||||
force_ip_enable:=true \
|
||||
force_ip_mac:=54:14:FD:06:07:DA \
|
||||
force_ip_address:=192.168.1.50 \
|
||||
force_ip_subnet_mask:=255.255.255.0 \
|
||||
force_ip_gateway:=192.168.1.1 \
|
||||
net_device_ip:=192.168.1.50 \
|
||||
net_device_port:=8090
|
||||
```
|
||||
@@ -0,0 +1,12 @@
|
||||
# 预定义预设
|
||||
|
||||
| 预设 | 特点 | 推荐使用场景 |
|
||||
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Default | - 最佳视觉感知<br>- 在精度、填充率、微小物体等方面的整体性能良好 | - 通用场景<br>- 机器人应用 |
|
||||
| Hand | - 清晰的手部和手指边缘 | - 手势识别 |
|
||||
| High Accuracy | - 高置信度深度<br>- 几乎无噪声深度值<br>- 填充率较低 | - 避障<br>- 物体扫描 |
|
||||
| High Density | - 更高填充率<br>- 更多微小物体<br>- 可能存在噪声深度值 | - 物体识别<br>- 抓取和放置<br>- 前景和背景动画 |
|
||||
| Medium Density | - 填充率和精度的平衡性能<br>- 与 Default 相比:填充率较低,边缘质量更好 | - 通用场景和 Default 的替代方案 |
|
||||
| Custom | - 用户自定义预设<br>- 从上述预设派生,具有自定义修改,例如后处理管道的新配置、深度 AE 功能的修改平均强度设定点等 | - 通过使用自定义配置可获得比预定义预设更好的深度性能<br>- 适用于已建立的自定义配置 |
|
||||
|
||||
根据您的具体使用场景选择合适的预设名称,并将其设置为 `device_preset` 参数的值。
|
||||
@@ -0,0 +1,66 @@
|
||||
# GMSL 相机
|
||||
|
||||
> 本节介绍如何在 OrbbecSDK_ROS2 中使用 GMSL 相机。目前仅支持 Gemini 335Lg GMSL 设备,其他 GMSL 设备将在不久的将来得到支持。
|
||||
|
||||
您可以在 [example](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples) 中找到示例使用代码。
|
||||
|
||||
## 单个 GMSL 相机
|
||||
|
||||
GMSL 相机在 OrbbecSDK_ROS2 中的使用与通过 USB 的 Gemini 330 系列相机相同。
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera gemini_330_gmsl.launch.py
|
||||
```
|
||||
|
||||
## 多个 GMSL 相机
|
||||
|
||||
要获取 GMSL 相机的 `usb_port`,插入相机并在终端中运行以下命令:
|
||||
|
||||
```bash
|
||||
ros2 run orbbec_camera list_devices_node
|
||||
```
|
||||
|
||||
例如,获得的 gmsl 相机 `usb_port`:`gmsl2-1`
|
||||
|
||||
转到 [multi_gmsl_camera.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera.launch.py) 文件并更改 `usb_port`。
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera multi_gmsl_camera.launch.py
|
||||
```
|
||||
|
||||
> 注意:默认情况下,multi_gmsl_camera.launch.py 仅启动 color 和 left_ir。如果您想启动其他传感器,请转到 [camera_secondary_params.yaml](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/config/camera_secondary_params.yaml) 进行修改。
|
||||
|
||||
## 多个 GMSL 相机同步
|
||||
|
||||
首先,请查看如何使用 [multi_camera_synced](./multi_camera_synced.md)。
|
||||
|
||||
此外,GMSL 多相机同步不需要 Multi-Camera Sync Hub Pro,因此无需设置 `primary` 模式。每个 GMSL 相机都是 `secondary`。
|
||||
|
||||
**额外的参数设置**
|
||||
|
||||
* `gmsl_trigger_fps`:设置硬件 soc 触发源帧率。
|
||||
* `enable_gmsl_trigger`:启用硬件 soc 触发。
|
||||
|
||||
**运行启动文件**
|
||||
|
||||
请参考 [multi_gmsl_camera_synced.launch.py](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/examples/gmsl_camera/multi_gmsl_camera_synced.launch.py) 中的配置。
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera multi_gmsl_camera_synced.launch.py
|
||||
```
|
||||
|
||||
> 注意:默认情况下,multi_gmsl_camera_synced.launch.py 仅启动 color 和 left_ir。如果您想启动其他传感器,请转到 [camera_secondary_params.yaml](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/config/camera_secondary_params.yaml) 和 [camera_params.yaml](https://github.com/orbbec/OrbbecSDK_ROS2/blob/v2-main/orbbec_camera/config/camera_params.yaml) 进行修改。
|
||||
|
||||
## GMSL 相机的使用限制
|
||||
|
||||
GMSL 相机与各种反序列化器芯片(如 MAX9296 和 MAX92716)接口。Orbbec GMSL 相机支持多个流,包括深度、彩色、IR 和 IMU 数据,但存在某些使用限制:
|
||||
|
||||
- GMSL 仅支持 V4L2 和 YUYV 格式;不支持 MJPG 格式。RGB 输出源自 YUYV 格式转换。
|
||||
- Gemini-335Lg 的元数据通过单独的节点提供,而其他型号的元数据嵌入在视频帧中,这对用户保持透明。
|
||||
- 当使用 Max96712 作为反序列化器芯片时,由于 Max96712 芯片的特性,在 secondary_synced 模式下必须提供多机同步触发信号。否则,在切换数据流时会发生数据流中断。
|
||||
- 连接在同一个 MAX9296、MAX96712 LinkA/B 或 MAX96712 LinkC/D 上的两个相机有以下限制:
|
||||
- 在驱动程序版本 v12.02 之前,存在一个限制,即一个相机的 RGB 和另一个相机的右 IR 不能同时流式传输。在驱动程序版本 v12.02 之后,限制修改为一个相机的 RGB 和另一个相机的左 IR 不能同时流式传输。
|
||||
- 在驱动程序版本 v12.02 之前,存在一个限制,即一个相机的 DEPTH 和另一个相机的左 IR 不能同时流式传输。在驱动程序版本 v12.02 之后,限制修改为一个相机的 DEPTH 和另一个相机的右 IR 不能同时流式传输。
|
||||
- 两个相机的活动流的组合最大数量限制为四个(满足上述两个条件即可确保合规)。
|
||||
|
||||
有关更多已知限制,请参考 [Orbbec GMSL 相机的使用限制](https://github.com/orbbec/MIPI_Camera_Platform_Driver/blob/main/doc/Instructions%20for%20Using%20GMSL%20Camera.md)
|
||||
@@ -0,0 +1,55 @@
|
||||
# 多相机同步说明
|
||||
|
||||
> 本文档的目的是说明如何在 OrbbecSDK_ROS2 中使用多相机同步
|
||||
|
||||
### 设置说明
|
||||
|
||||
* 请阅读多相机同步设置指南:[多相机同步设置](https://www.orbbec.com/docs/set-up-cameras-for-external-synchronization_v1-2/)
|
||||
* 确保相机正确连接到多相机同步器。
|
||||
|
||||

|
||||
|
||||
### 使用 OrbbecSDK_ROS2 检查相机端口
|
||||
|
||||
```bash
|
||||
ros2 run orbbec_camera list_devices_node
|
||||
```
|
||||
|
||||
### OrbbecSDK_ROS2 多相机同步配置
|
||||
|
||||
打开 multi_camera_synced.launch.py,并按照下面所示配置相机设置:
|
||||
|
||||

|
||||
|
||||
1. `gemini_330_series.launch.py` 是用于启动相机的启动文件。
|
||||
|
||||
2. 将 `camera_name` 设置为 `G330_0`。例如,发布的彩色图像话题将是 `/G330_0/color/image_raw`。
|
||||
|
||||
3. 将 `usb_port` 设置为 `2-2`,表示正在使用端口 `2-2` 上的相机设备。此值可以在 `ros2 run orbbec_camera list_devices_node` 命令的输出中找到。
|
||||
|
||||
4. 将 `device_num` 设置为 `2`,表示将使用两个相机。
|
||||
|
||||
5. 将 `sync_mode` 设置为 `primary`,表示 `2-7` 相机设备处于主模式。多相机同步模式选项可以在下图中找到。
|
||||
|
||||
6. 来自 `config_file_path` 的参数可以覆盖在 `gemini_330_series.launch.py` 中设置的参数(可选)。
|
||||
|
||||
7. 对于从属相机,将 `trigger_out_enabled` 设置为 false。
|
||||
|
||||
| **模式名称** | **设置效果说明** |
|
||||
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| free_run | - 支持不同的帧率设置<br />- 8 针同步接口不支持外部输出同步相关信号 |
|
||||
| standalone(默认) | ● 默认与 Primary 相同<br />● 内置 RGBD 帧同步<br />● 8 针同步接口默认不向外部输出信号 |
|
||||
| primary | ● 设置为主相机<br />● 8 针同步接口向外部设备输出信号 |
|
||||
| secondary | ● 设置为从属(被动同步;当外部有硬件连续触发信号输入且连续触发信号与当前设置的帧率匹配时,根据外部触发信号采集图像;当没有外部触发信号时,停止流)<br />● 8 针同步接口向外部设备输出信号 |
|
||||
| secondary_synced | ● 设置为从属同步(被动同步;当外部有硬件连续触发信号输入且连续触发信号与当前设置的帧率匹配时,根据外部触发信号采集图像;当没有外部触发信号时,根据设置的帧率的内部触发信号采集图像)<br />● 8 针同步接口向外部设备输出信号 |
|
||||
| hardware_triggering | ● 设置为硬件触发(被动触发;当外部有硬件触发信号输入且触发信号时间间隔不小于当前上限时,根据外部触发信号采集图像;当没有外部触发信号时,不采集图像)<br />● 8 针同步接口向外部设备输出信号 |
|
||||
| software_triggering | ● 设置为软件触发(被动触发;当主机有触发命令输入且触发命令时间间隔不小于当前上限时,根据触发命令采集图像;当没有触发命令时,不采集图像)<br />● 8 针同步接口向外部设备输出信号 |
|
||||
|
||||
* 主相机应该最后启动。
|
||||
* 理想情况下,启动每个相机之间应该有 2 秒的延迟。
|
||||
|
||||
### 运行以下命令启动多相机同步
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera multi_camera_synced.launch.py
|
||||
```
|
||||
@@ -0,0 +1,161 @@
|
||||
# 多相机同步验证工具
|
||||
|
||||
> 本文将介绍如何验证多相机同步的同步精度。
|
||||
>
|
||||
> 首先,请查看如何使用 [multi_camera_synced](./multi_camera_synced.md)。
|
||||
|
||||
您可以在 [example](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples) 中找到示例使用代码。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```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`:单相机运行启动文件,为 multi_camera_synced_verify.launch.py 提供相机运行节点。
|
||||
* `multi_camera_synced_verify.launch.py`:多相机同步 + save_rgbir 工具的启动文件。
|
||||
|
||||
**output**
|
||||
|
||||
> `ouput` 文件夹是相机图片输出的文件夹
|
||||
|
||||
在提供的输出示例中
|
||||
|
||||
* `20250218102900`:表示在 2025 年 2 月 18 日 10:29:00 收集的相机图像信息。
|
||||
* `TotalModeFrames`:相机图像信息存储目录。
|
||||
* `results-2025-02-25_163648`:分析和匹配 TotalModeFrames 图像信息后的结果。
|
||||
* `DevicesInfo.txt`:相机设备基本信息(需要修改)。
|
||||
* `StreamProfileInfo.txt`:相机视频流信息(无需修改)。
|
||||
|
||||
**Python**
|
||||
|
||||
* `Config.ini`:Python 分析脚本的配置文件(需要修改)。
|
||||
|
||||
## 运行准备
|
||||
|
||||
**save_rgbir 节点**
|
||||
|
||||
编辑 multi_camera_synced_verify.launch.py 并填写激活的相机设备,我们可以看到 save_rgbir 在最后启动。
|
||||
|
||||
> 重要
|
||||
>
|
||||
> 如果您使用 ROS 2 Foxy,需要先启动 save_rgbir 节点。
|
||||
|
||||
```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 是一个用于保存图像的工具。该工具的配置文件在 [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`:时间戳类型
|
||||
* `usb_ports`:"primary"、"secondary 1"、"secondary 2"、"secondary 3",根据相机数量填写 usb_ports
|
||||
* `camera_name`:相机设置的名称,例如:camera_01
|
||||
|
||||
**DevicesInfo.txt**
|
||||
|
||||
编辑 DevicesInfo.txt。只需要更改 `primarySerialNumber`、`index` 和 `serialNumber` 参数。其他参数不需要更改。请参考 [20250218102900](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool/multicamera_sync/output/20250218102900) 的示例。
|
||||
|
||||
* `primarySerialNumber`:主相机的 SN 序列号
|
||||
* `index`:相机索引
|
||||
* `serialNumber`:相机的 SN 序列号
|
||||
|
||||
**Config.ini**
|
||||
|
||||
编辑 Config.ini。修改 `frameRate` 和 `tspRangeThreshold`。
|
||||
|
||||
## 运行此示例
|
||||
|
||||
**运行启动文件并保存相机图片**
|
||||
|
||||
* 第一个终端
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera multi_camera_synced_verify.launch.py
|
||||
```
|
||||
|
||||
* 第二个终端
|
||||
|
||||
```bash
|
||||
ros2 service call /save_rgbir/start_capture orbbec_camera_msgs/srv/SetInt32 '{data: 100}'
|
||||
```
|
||||
|
||||
当终端显示"over"时,图像已保存。将在工作空间下生成一个新的 multicamera_sync 文件夹。
|
||||
|
||||
**相机图片命名格式**
|
||||
|
||||
以 [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) 为例
|
||||
|
||||
* `color`:此图像是彩色流的快照。
|
||||
* `SNCP1E5420006D`:相机的 SN 序列号是 CP1E5420006D。
|
||||
* `Index0`:相机 0(通常指主相机)。
|
||||
* `g1739874543227`:"g"表示全局时间戳,意味着此帧的全局时间戳是 1739874543227。
|
||||
* `f0`:此相机彩色流采集的第 0 张图片。
|
||||
* `s1739874543327`:"s"表示当前系统的时间戳,意味着此帧的当前系统时间戳是 1739874543327。
|
||||
* `e50`:此帧的曝光为 50。
|
||||
* `d16`:此帧的增益为 16。
|
||||
|
||||
**分析相机图像数据**
|
||||
|
||||
您需要将修改后的 [Python 文件夹](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples/multi_camera_synced_verification_tool//multicamera_sync/Python) 复制到新的 multi_camera_synced 子目录,并将修改后的 [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) 和 [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) 复制到与 TotalModeFrames 文件夹同级的目录。
|
||||
|
||||
* 最后一切准备就绪,运行 python 脚本
|
||||
|
||||
```bash
|
||||
cd multicamera_sync/Python
|
||||
python3 SyncFramesMain.py
|
||||
```
|
||||
|
||||
操作成功后,您可以在 `results 文件夹` 中查看同步效果
|
||||
|
||||
## 需要更改的文件
|
||||
|
||||
**分析工具**
|
||||
|
||||
* [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_params.yaml](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/config/camera_params.yaml)(相机启动参数设置)
|
||||
|
||||
[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)
|
||||
@@ -0,0 +1,39 @@
|
||||
# 高效的进程内通信:
|
||||
|
||||
### 简介
|
||||
|
||||
如果我们的ROS2封装器节点与订阅者节点加载在同一进程中,它支持零拷贝通信。这可以减少图像/点云话题的拷贝时间,特别是在大帧分辨率和高FPS的情况下。
|
||||
|
||||
您需要启动一个组件容器,并将我们的节点作为组件与其他组件节点一起启动。有关"在单个进程中组合多个节点"的更多详细信息,请参见 [此处](https://docs.ros.org/en/rolling/Tutorials/Composition.html)。
|
||||
|
||||
有关高效进程内通信的更多详细信息,请参见 [此处](https://docs.ros.org/en/humble/Tutorials/Intra-Process-Communication.html#efficient-intra-process-communication)。
|
||||
|
||||
### 示例
|
||||
|
||||
**手动将多个组件加载到同一进程中**
|
||||
|
||||
* 启动组件:
|
||||
|
||||
```bash
|
||||
ros2 run rclcpp_components component_container
|
||||
```
|
||||
|
||||
* 添加封装器:
|
||||
|
||||
```bash
|
||||
ros2 component load /ComponentManager orbbec_camera orbbec_camera::OBCameraNodeDriver -e use_intra_process_comms:=true
|
||||
```
|
||||
|
||||
以相同方式加载其他组件节点(封装器话题的消费者)。
|
||||
|
||||
**使用启动文件**
|
||||
|
||||
```bash
|
||||
ros2 launch orbbec_camera gemini_intra_process_demo_launch.py
|
||||
```
|
||||
|
||||
**限制**
|
||||
|
||||
* RCLPY目前不支持节点组件
|
||||
|
||||
* 使用 `image_transport` 的压缩图像将被禁用,因为进程内通信不支持此功能
|
||||
@@ -0,0 +1,146 @@
|
||||
# 针对Orbbec相机与ROS2的Fast DDS优化
|
||||
|
||||
使用默认配置时,Fast DDS表现出次优的传输效率,导致在ROS2中使用Orbbec相机时图像传输延迟显著。本文档提供了优化Fast DDS以提高图像传输效率的指导。
|
||||
|
||||
## 调整系统参数
|
||||
|
||||
**IP分片时间**
|
||||
|
||||
- **路径**: `/proc/sys/net/ipv4/ipfrag_time`(默认值:30秒)
|
||||
- **目的**: 定义IP分片保留在内存中的持续时间。
|
||||
- **调整**: 减少此值以缩短未接收到分片的时间窗口,这有助于减少延迟。考虑到您环境的具体需求,因为此设置会影响所有传入的分片。
|
||||
|
||||
**示例**: 设置为3秒。
|
||||
|
||||
```bash
|
||||
sudo sysctl net.ipv4.ipfrag_time=3
|
||||
```
|
||||
|
||||
**IP分片内存阈值**
|
||||
|
||||
- **路径**: `/proc/sys/net/ipv4/ipfrag_high_thresh`(默认值:262144字节)
|
||||
- **目的**: 设置用于重组IP分片的最大内存。
|
||||
- **调整**: 增加此值以允许更多内存用于分片重组,这可以改善较大数据包的处理。
|
||||
|
||||
**示例**: 增加到128 MB。
|
||||
|
||||
```bash
|
||||
sudo sysctl net.ipv4.ipfrag_high_thresh=134217728
|
||||
```
|
||||
|
||||
**最大缓冲区大小**
|
||||
|
||||
- **目的**: 配置接收和发送数据的最大缓冲区大小,这对高吞吐量数据传输至关重要。
|
||||
- **调整**: 设置接收和发送操作的最大缓冲区大小。
|
||||
|
||||
**命令**:
|
||||
|
||||
```bash
|
||||
sudo sysctl -w net.core.rmem_max=2147483647
|
||||
sudo sysctl -w net.core.rmem_default=2147483647
|
||||
sudo sysctl -w net.core.wmem_max=2147483647
|
||||
sudo sysctl -w net.core.wmem_default=2147483647
|
||||
```
|
||||
|
||||
或者,通过将这些设置添加到 `/etc/sysctl.d/10-fastrtps-max.conf` 文件中使其永久生效。
|
||||
|
||||
```bash
|
||||
sudo gedit /etc/sysctl.d/10-fastrtps-max.conf
|
||||
```
|
||||
|
||||
将以下行添加到文件中:
|
||||
|
||||
```bash
|
||||
net.core.rmem_max=2147483647
|
||||
net.core.rmem_default=2147483647
|
||||
net.core.wmem_max=2147483647
|
||||
net.core.wmem_default=2147483647
|
||||
```
|
||||
|
||||
然后保存并退出文件。运行 `sudo sysctl -p` 以应用更改。
|
||||
|
||||
有关详细指导,请参考 [ROS 2 DDS调优文档](https://docs.ros.org/en/foxy/How-To-Guides/DDS-tuning.html)。
|
||||
|
||||
## Fast DDS配置
|
||||
|
||||
以下是针对Orbbec相机与ROS2使用而优化的Fast DDS配置文件示例。此配置通过调整缓冲区大小和传输设置来增强整体数据传输。
|
||||
|
||||
**配置文件:** `shm_fastdds.xml`
|
||||
|
||||
将此文件放在 `$HOME` 目录中。
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<profiles xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
|
||||
<transport_descriptors>
|
||||
<transport_descriptor>
|
||||
<transport_id>UDP_transport</transport_id>
|
||||
<type>UDPv4</type>
|
||||
<maxInitialPeersRange>10</maxInitialPeersRange>
|
||||
<maxMessageSize>65000</maxMessageSize>
|
||||
<sendBufferSize>1048576</sendBufferSize>
|
||||
<receiveBufferSize>1048576</receiveBufferSize>
|
||||
</transport_descriptor>
|
||||
</transport_descriptors>
|
||||
<participant profile_name="participant_profile_ros2" is_default_profile="true">
|
||||
<rtps>
|
||||
<name>profile_for_ros2_context</name>
|
||||
<userTransports>
|
||||
<transport_id>UDP_transport</transport_id>
|
||||
</userTransports>
|
||||
<useBuiltinTransports>false</useBuiltinTransports>
|
||||
<sendSocketBufferSize>1048576</sendSocketBufferSize>
|
||||
<listenSocketBufferSize>1048576</listenSocketBufferSize>
|
||||
<builtin>
|
||||
<initialPeersList>
|
||||
<locator>
|
||||
<udpv4>
|
||||
<address>127.0.0.1</address>
|
||||
</udpv4>
|
||||
</locator>
|
||||
</initialPeersList>
|
||||
</builtin>
|
||||
</rtps>
|
||||
</participant>
|
||||
<data_writer profile_name="default publisher profile" is_default_profile="true">
|
||||
<qos>
|
||||
<publishMode>
|
||||
<kind>ASYNCHRONOUS</kind>
|
||||
</publishMode>
|
||||
<latencyBudget>
|
||||
<duration>
|
||||
<sec>0</sec>
|
||||
<nanosec>1000000</nanosec>
|
||||
</duration>
|
||||
</latencyBudget>
|
||||
</qos>
|
||||
<historyMemoryPolicy>PREALLOCATED_WITH_REALLOC</historyMemoryPolicy>
|
||||
</data_writer>
|
||||
<data_reader profile_name="default subscription profile" is_default_profile="true">
|
||||
<qos>
|
||||
<data_sharing>
|
||||
<kind>AUTOMATIC</kind>
|
||||
</data_sharing>
|
||||
<latencyBudget>
|
||||
<duration>
|
||||
<sec>0</sec>
|
||||
<nanosec>1000000</nanosec>
|
||||
</duration>
|
||||
</latencyBudget>
|
||||
</qos>
|
||||
<historyMemoryPolicy>PREALLOCATED_WITH_REALLOC</historyMemoryPolicy>
|
||||
</data_reader>
|
||||
</profiles>
|
||||
```
|
||||
|
||||
**环境变量**
|
||||
|
||||
设置以下环境变量以使用自定义Fast DDS配置文件:
|
||||
|
||||
```bash
|
||||
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
|
||||
export FASTRTPS_DEFAULT_PROFILES_FILE=$HOME/shm_fastdds.xml
|
||||
export RMW_FASTRTPS_USE_QOS_FROM_XML=1
|
||||
```
|
||||
|
||||
此配置旨在优化数据流并减少传输延迟,提高Orbbec相机系统在ROS2环境中的响应性和可靠性。
|
||||
@@ -0,0 +1,95 @@
|
||||
## 使用Orbbec ROS包降低CPU使用率
|
||||
|
||||
您可以在 [示例](https://github.com/orbbec/OrbbecSDK_ROS2/tree/v2-main/orbbec_camera/examples) 中找到使用示例代码。
|
||||
|
||||
本文档概述了在使用 **Gemini 330系列相机** 的 **OrbbecSDK_ROS2 v2** 环境中最小化CPU使用率的策略。固件版本必须 **不低于1.4.10**,且 `device` 应设置为 **Default**。
|
||||
|
||||
### 降低CPU使用率的推荐设置
|
||||
|
||||
要在OrbbecSDK_ROS2中实现最低的CPU使用率,建议配置以下参数。
|
||||
|
||||
| 参数 | 推荐值 | 说明 |
|
||||
| :--------------: | :------------------------------------: | :--------------------------------------------: |
|
||||
| `uvc_backend` | `v4l2` | 与 `libuvc` 相比CPU使用率更低 |
|
||||
| `color_format` | `RGB` | CPU使用率低于 `MJPG` |
|
||||
| `filter` | 仅使用 `hardware_noise_removal_filter` | 其他滤波器会显著增加CPU使用率 |
|
||||
|
||||
### 用于测试的启动文件
|
||||
|
||||
* `gemini_330_series_lower_cpu_usage.launch.py`
|
||||
* `multi_camera_lower_cpu_usage.launch.py`
|
||||
|
||||
### 测试环境
|
||||
|
||||
**硬件配置**
|
||||
|
||||
* **CPU**: Intel i7-8700 @ 3.20GHz
|
||||
|
||||
* **内存**: 24 GB
|
||||
|
||||
* **存储**: Micron 2200S NVMe 256GB
|
||||
|
||||
* **GPU**: NVIDIA GeForce GTX 1660Ti
|
||||
|
||||
* **操作系统**: Ubuntu22.04
|
||||
|
||||
**ROS配置**
|
||||
|
||||
* **ROS版本**: ROS2 Humble
|
||||
|
||||
* **SDK版本**: OrbbecSDK_ROS2 v2.2.1
|
||||
|
||||
**相机设置**
|
||||
|
||||
* 设备: 2x Gemini 335, 1x Gemini 336, 1x Gemini 336L
|
||||
|
||||
* 固件版本: 1.4.10
|
||||
|
||||
|
||||
### 测试设置
|
||||
|
||||
**数据流设置:**
|
||||
|
||||
* 深度/左IR/右IR: 848×480 @ 30fps
|
||||
* 彩色: 848×480 @ 30fps
|
||||
|
||||
注意:以下CPU使用率数据重点关注 `uvc_backend`、`color_format` 和各种滤波器组合。
|
||||
|
||||
### 测试结果
|
||||
|
||||
**`uvc_backend` 对比(RGB格式)**
|
||||
|
||||
| libuvc CPU使用率 | v4l2 CPU使用率 | 绝对变化 |
|
||||
| :--------------: | :------------: | :-------------: |
|
||||
| 182.8% | 118.8% | -64.0% |
|
||||
|
||||
使用v4l2后端可以显著降低CPU使用率。在我们的实现中,v4l2无需对Linux内核进行任何补丁即可工作,允许用户轻松在v4l2和libuvc之间切换,并保持与标准Linux发行版的完全兼容性。
|
||||
|
||||
**`color_format` 对比(MJPG vs RGB)**
|
||||
|
||||
| 后端 | MJPG CPU使用率 | RGB CPU使用率 | 绝对变化 |
|
||||
| :-----: | :------------: | :-----------: | :-------------: |
|
||||
| libuvc | 347.7% | 182.8% | -164.9% |
|
||||
| v4l2 | 170.0% | 118.8% | -51.2% |
|
||||
|
||||
如果选择RGB格式而不是MJPG,可以降低CPU使用率,因为MJPG图像的解码会消耗主机CPU资源。
|
||||
|
||||
**滤波器配置影响**
|
||||
|
||||
| 应用的滤波器 | libuvc CPU使用率 | CPU使用率增加 | v4l2 CPU使用率 | CPU使用率增加 |
|
||||
| ----------------------------------------------------- | ---------------- | ------------------ | -------------- | ------------------ |
|
||||
| 无滤波器(基准) | 182.8% | 0.0%(基准) | 118.8% | 0.0%(基准) |
|
||||
| `(软件)noise_removal_filter` | 218.0% | +35.2% | 128.5% | +9.7% |
|
||||
| `(软件)noise_removal_filter + spatial_filter` | 469.6% | +286.8% | 336.7% | +217.9% |
|
||||
| `hardware_noise_removal_filter` | 186.3% | +3.5% | 115.4% | -3.4% |
|
||||
| `hardware_noise_removal_filter + spatial_filter` | 251.3% | +68.5% | 152.5% | +33.7% |
|
||||
|
||||
根据测试结果,仅使用 `hardware_noise_removal_filter` 相比无滤波器基准,对 `libuvc`(+3.5%)和 `v4l2`(-3.4%)的CPU使用率变化可以忽略不计,因为此滤波器在相机硬件内部运行。相比之下,其他滤波器在主机系统上执行。将 `spatial_filter` 添加到硬件滤波器会导致CPU使用率适度增加,而应用基于软件的 `noise_removal_filter`——无论是单独使用还是与 `spatial_filter` 结合——都会显著增加CPU负载。为保持较低的CPU使用率,建议避免使用基于软件的滤波器,仅依赖 `hardware_noise_removal_filter`。
|
||||
|
||||
### 进一步优化
|
||||
|
||||
| 参数 | 推荐值 | 说明 |
|
||||
| :----------------------------: | :----------------------------------------------: | :---------------------------------------------: |
|
||||
| `depth_registration` | `false` 或 `true` 配合 `align_mode=HW` | 软件对齐消耗更多CPU |
|
||||
| `enable_point_cloud` | `false` | 禁用点云可降低CPU使用率 |
|
||||
| `enable_colored_point_cloud` | `false` | 禁用彩色点云可降低CPU使用率 |
|
||||
@@ -0,0 +1,144 @@
|
||||
// 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');
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// Language switcher functionality
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Create language switcher button
|
||||
var languageSwitcher = document.createElement('div');
|
||||
languageSwitcher.className = 'language-switcher';
|
||||
languageSwitcher.innerHTML = `
|
||||
<button class="language-toggle" id="languageToggle">
|
||||
<span class="language-icon">🌐</span>
|
||||
<span class="language-text">中文/EN</span>
|
||||
</button>
|
||||
<div class="language-dropdown" id="languageDropdown">
|
||||
<a href="javascript:void(0)" class="language-option" data-lang="en">English</a>
|
||||
<a href="javascript:void(0)" class="language-option" data-lang="zh">中文</a>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Insert language switcher into the page
|
||||
var navbar = document.querySelector('.wy-nav-top');
|
||||
if (navbar) {
|
||||
navbar.appendChild(languageSwitcher);
|
||||
} else {
|
||||
// Fallback: insert at the beginning of body
|
||||
document.body.insertBefore(languageSwitcher, document.body.firstChild);
|
||||
}
|
||||
|
||||
// Toggle dropdown
|
||||
var toggleButton = document.getElementById('languageToggle');
|
||||
var dropdown = document.getElementById('languageDropdown');
|
||||
|
||||
toggleButton.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
dropdown.classList.toggle('show');
|
||||
});
|
||||
|
||||
// Close dropdown when clicking outside
|
||||
document.addEventListener('click', function() {
|
||||
dropdown.classList.remove('show');
|
||||
});
|
||||
|
||||
// Language switching logic
|
||||
var languageOptions = document.querySelectorAll('.language-option');
|
||||
languageOptions.forEach(function(option) {
|
||||
option.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
var targetLang = this.getAttribute('data-lang');
|
||||
switchLanguage(targetLang);
|
||||
});
|
||||
});
|
||||
|
||||
// Detect current language from URL
|
||||
detectCurrentLanguage();
|
||||
});
|
||||
|
||||
function detectCurrentLanguage() {
|
||||
var path = window.location.pathname;
|
||||
var currentLang = 'en'; // default
|
||||
|
||||
if (path.includes('/zh/')) {
|
||||
currentLang = 'zh';
|
||||
} else if (path.includes('/en/')) {
|
||||
currentLang = 'en';
|
||||
}
|
||||
|
||||
// Highlight current language
|
||||
document.querySelectorAll('.language-option').forEach(function(option) {
|
||||
if (option.getAttribute('data-lang') === currentLang) {
|
||||
option.classList.add('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function switchLanguage(targetLang) {
|
||||
var currentPath = window.location.pathname;
|
||||
var newPath;
|
||||
|
||||
// Get the base path and file path
|
||||
var pathParts = currentPath.split('/');
|
||||
var basePath = '';
|
||||
var filePath = '';
|
||||
|
||||
// Find language code in path
|
||||
var langIndex = -1;
|
||||
for (var i = 0; i < pathParts.length; i++) {
|
||||
if (pathParts[i] === 'en' || pathParts[i] === 'zh') {
|
||||
langIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (langIndex !== -1) {
|
||||
// Replace language code
|
||||
pathParts[langIndex] = targetLang;
|
||||
newPath = pathParts.join('/');
|
||||
} else {
|
||||
// Add language code
|
||||
// Assuming structure: /base/file.html -> /base/lang/file.html
|
||||
var lastSlashIndex = currentPath.lastIndexOf('/');
|
||||
if (lastSlashIndex !== -1) {
|
||||
basePath = currentPath.substring(0, lastSlashIndex);
|
||||
filePath = currentPath.substring(lastSlashIndex);
|
||||
newPath = basePath + '/' + targetLang + filePath;
|
||||
} else {
|
||||
newPath = '/' + targetLang + currentPath;
|
||||
}
|
||||
}
|
||||
|
||||
// Navigate to new URL
|
||||
window.location.href = newPath;
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 300 KiB |
@@ -0,0 +1,53 @@
|
||||
<svg width="240" height="45" viewBox="0 0 240 45" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M132.524 33.6127C132.524 33.3717 132.524 33.1909 132.524 33.0252C132.524 26.3818 132.524 19.7534 132.524 13.11C132.524 12.5074 132.524 12.5074 133.097 12.5074C138.4 12.5074 143.717 12.5074 149.02 12.5225C150.692 12.5225 152.319 12.7786 153.871 13.4113C155.016 13.8632 155.995 14.5261 156.793 15.4902C158.571 17.6444 158.36 20.4012 156.281 22.2541C156.025 22.4801 155.769 22.676 155.468 22.932C155.633 23.0676 155.769 23.1731 155.904 23.2936C158.586 25.4478 158.737 28.7921 156.251 31.1723C154.925 32.4377 153.313 33.0855 151.536 33.3566C150.496 33.5224 149.427 33.6127 148.372 33.6278C143.25 33.6579 138.128 33.6429 133.006 33.6429C132.886 33.6127 132.735 33.6127 132.524 33.6127ZM136.727 29.9822C136.953 29.9822 137.134 29.9822 137.33 29.9822C140.96 29.9822 144.606 29.9822 148.237 29.9822C148.915 29.9822 149.607 29.9671 150.285 29.8918C151.265 29.8014 152.199 29.5604 153.027 29.003C153.494 28.6867 153.856 28.2799 153.946 27.6924C154.082 26.8337 153.705 26.1106 152.831 25.6135C151.701 24.9657 150.466 24.7398 149.186 24.7398C146.052 24.7247 142.934 24.7398 139.801 24.7398C139.635 24.7398 139.469 24.7398 139.288 24.7398C139.288 23.5045 139.288 22.3295 139.288 21.1092C139.499 21.1092 139.665 21.1092 139.846 21.1092C142.828 21.1092 145.811 21.1243 148.794 21.0942C149.487 21.0942 150.195 21.049 150.873 20.9134C151.566 20.7628 152.259 20.5519 152.876 20.2204C154.383 19.407 154.368 17.8252 152.892 16.9665C152.575 16.7857 152.244 16.605 151.897 16.5447C150.858 16.379 149.803 16.153 148.749 16.153C144.922 16.1078 141.096 16.138 137.27 16.138C137.104 16.138 136.923 16.153 136.742 16.1681C136.727 20.7628 136.727 25.3273 136.727 29.9822Z" fill="#4A4F54"/>
|
||||
<path d="M183.849 22.917C184.195 23.2183 184.542 23.4895 184.843 23.8058C186.756 25.7341 186.892 28.4909 185.144 30.5848C183.879 32.0913 182.207 32.9048 180.324 33.2512C179.194 33.4621 178.019 33.5977 176.859 33.5977C171.677 33.6279 166.51 33.6128 161.328 33.6128C161.192 33.6128 161.071 33.5977 160.906 33.5977C160.891 33.417 160.876 33.2362 160.876 33.0705C160.876 26.3969 160.876 19.7384 160.876 13.0649C160.876 12.7787 160.815 12.4924 161.282 12.4924C166.675 12.5075 172.068 12.5075 177.477 12.5226C179.134 12.5226 180.746 12.7937 182.282 13.4114C183.502 13.9085 184.557 14.6466 185.34 15.7162C186.847 17.7349 186.666 20.2205 184.888 21.9981C184.587 22.3145 184.225 22.6007 183.849 22.917ZM165.079 29.9823C165.32 29.9823 165.5 29.9823 165.696 29.9823C169.342 29.9823 173.002 29.9823 176.648 29.9823C177.311 29.9823 177.989 29.9672 178.652 29.8919C179.616 29.8015 180.535 29.5605 181.363 29.0181C182.011 28.5963 182.388 28.0088 182.312 27.1953C182.237 26.3969 181.755 25.9149 181.092 25.5533C179.992 24.9507 178.802 24.7248 177.567 24.7248C174.419 24.7097 171.285 24.7248 168.137 24.7248C167.971 24.7248 167.805 24.7248 167.624 24.7248C167.624 23.4744 167.624 22.2994 167.624 21.0942C167.85 21.0942 168.016 21.0942 168.182 21.0942C171.165 21.0942 174.147 21.1093 177.13 21.0792C177.823 21.0792 178.531 21.0038 179.209 20.8984C180.038 20.7779 180.821 20.5218 181.514 20.0247C182.599 19.2262 182.599 17.9006 181.499 17.1473C181.107 16.8762 180.67 16.6352 180.203 16.5448C179.164 16.3489 178.109 16.1531 177.07 16.138C173.243 16.0928 169.417 16.123 165.591 16.123C165.425 16.123 165.259 16.138 165.064 16.1531C165.079 20.7628 165.079 25.3424 165.079 29.9823Z" fill="#4A4F54"/>
|
||||
<path d="M122.763 27.3157C124.013 28.4004 125.203 29.4248 126.378 30.4491C127.568 31.4735 128.743 32.4979 130.009 33.5826C129.828 33.6127 129.722 33.6277 129.617 33.6277C127.824 33.6277 126.032 33.6428 124.254 33.6127C124.043 33.6127 123.787 33.4922 123.606 33.3415C121.557 31.5639 119.524 29.7863 117.505 27.9936C117.249 27.7677 116.993 27.6773 116.646 27.6773C114.477 27.6923 112.308 27.6773 110.139 27.6773C109.973 27.6773 109.792 27.6773 109.596 27.6773C109.596 26.4571 109.596 25.282 109.596 24.0468C109.762 24.0468 109.928 24.0468 110.093 24.0468C113.182 24.0468 116.255 24.0468 119.343 24.0468C120.578 24.0468 121.783 23.881 122.913 23.3538C123.998 22.8567 124.841 22.1185 125.067 20.8983C125.384 19.1508 124.811 17.5992 123.064 16.8008C122.16 16.394 121.196 16.1982 120.232 16.1982C115.908 16.168 111.585 16.1831 107.276 16.1831C107.216 16.1831 107.156 16.1982 107.05 16.2132C107.05 21.998 107.05 27.7827 107.05 33.5976C105.634 33.5976 104.279 33.5976 102.893 33.5976C102.893 26.5926 102.893 19.6027 102.893 12.5827C103.013 12.5676 103.134 12.5526 103.239 12.5526C108.738 12.5526 114.236 12.5224 119.735 12.5827C122.115 12.6128 124.39 13.1552 126.453 14.4206C130.219 16.7104 130.732 22.465 127.026 25.3423C125.911 26.216 124.661 26.7885 123.29 27.1651C123.154 27.1952 123.019 27.2404 122.763 27.3157Z" fill="#4A4F54"/>
|
||||
<path d="M84.7096 33.6128C83.2333 33.6128 81.772 33.673 80.2957 33.5977C77.2979 33.4471 74.6164 32.4679 72.3869 30.404C70.1423 28.3251 69.1179 25.7491 69.133 22.7061C69.148 17.2528 73.0045 14.2851 76.6953 13.1552C78.021 12.7485 79.3919 12.5376 80.7778 12.5376C83.5195 12.5225 86.2763 12.4773 89.018 12.5527C92.0309 12.6431 94.8028 13.5168 97.1077 15.5354C99.1715 17.3432 100.166 19.633 100.286 22.3446C100.572 28.7018 95.8272 32.3323 91.5941 33.2211C90.4793 33.4471 89.3193 33.5224 88.1744 33.5826C87.0145 33.6429 85.8545 33.5977 84.6795 33.5977C84.7096 33.6278 84.7096 33.6128 84.7096 33.6128ZM84.7397 29.9822C86.0654 29.9822 87.3911 29.9973 88.7168 29.9822C89.9972 29.9521 91.2325 29.681 92.3774 29.1085C94.5166 28.0239 95.9176 26.3818 96.1435 23.9414C96.3996 21.2599 95.4355 19.1057 93.1909 17.5842C91.8502 16.6803 90.3588 16.2284 88.762 16.2133C86.0805 16.1681 83.4141 16.1681 80.7326 16.2133C79.0153 16.2435 77.4335 16.7858 76.0174 17.7951C72.402 20.3561 72.3116 26.2312 76.4091 28.7168C77.7197 29.5152 79.1358 29.937 80.6573 29.9822C81.998 30.0124 83.3689 29.9822 84.7397 29.9822Z" fill="#4A4F54"/>
|
||||
<path d="M189.137 12.5677C196.594 12.5677 204.035 12.5677 211.492 12.5677C211.492 13.7729 211.492 14.9479 211.492 16.1682C205.421 16.1682 199.38 16.1682 193.294 16.1682C193.294 20.7779 193.294 25.3575 193.294 29.9973C199.35 29.9973 205.406 29.9973 211.492 29.9973C211.492 31.2175 211.492 32.3926 211.492 33.5977C204.05 33.5977 196.609 33.5977 189.122 33.5977C189.137 26.5927 189.137 19.5878 189.137 12.5677Z" fill="#4A4F54"/>
|
||||
<path d="M239.768 12.5677C239.768 13.7879 239.768 14.963 239.768 16.1832C239.572 16.1832 239.407 16.1832 239.226 16.1832C234.752 16.1832 230.263 16.1832 225.788 16.1832C224.237 16.1832 222.761 16.5447 221.42 17.3582C219.115 18.7592 217.955 20.823 218.091 23.5346C218.226 26.3216 219.778 28.1594 222.248 29.2742C223.303 29.7562 224.433 29.9822 225.593 29.9822C230.127 29.9973 234.676 29.9973 239.211 29.9973C239.377 29.9973 239.557 29.9973 239.768 29.9973C239.768 31.2024 239.768 32.3925 239.768 33.5977C239.663 33.6127 239.572 33.6278 239.482 33.6278C234.692 33.6278 229.901 33.7182 225.126 33.5826C221.134 33.4772 217.789 31.8201 215.515 28.4306C212.788 24.3632 212.848 16.7104 220.275 13.5921C221.902 12.9142 223.604 12.5526 225.367 12.5526C230.052 12.5225 234.737 12.5376 239.422 12.5376C239.512 12.5376 239.618 12.5526 239.768 12.5677Z" fill="#4A4F54"/>
|
||||
<path d="M30.5227 11.5132C31.3965 11.7994 32.3154 12.1308 32.2552 13.2004C32.1949 14.2399 31.276 14.5261 30.3872 14.8123C30.5529 14.8876 30.7186 14.9479 30.8692 15.0232C31.6375 15.3998 31.7731 16.0175 31.2006 16.6502C31.0952 16.7707 30.9747 16.9063 30.9445 17.0419C30.583 18.5031 30.2365 19.9644 29.9804 21.0791C29.8298 20.341 29.6339 19.2262 29.3778 18.1265C29.2423 17.5239 29.1067 16.9213 28.6246 16.4543C28.2329 16.0627 28.3836 15.4902 28.8958 15.1588C29.1217 15.0082 29.3778 14.9178 29.6942 14.7521C28.7602 14.511 27.8563 14.27 27.7509 13.2607C27.6304 12.1158 28.6096 11.8296 29.4381 11.4228C29.2121 11.3626 28.9711 11.3324 28.7602 11.2571C27.7961 10.9408 26.9675 10.4738 26.7416 9.37405C26.621 8.81667 26.8169 8.34967 27.1634 7.92787C27.5852 7.41567 28.1426 7.12945 28.7753 6.94868C28.9259 6.90348 29.0615 6.85829 29.1971 6.70765C29.0012 6.66245 28.7903 6.61726 28.5945 6.57207C27.6605 6.36116 26.8018 5.98455 26.1239 5.27652C25.0092 4.14669 24.9941 2.61012 26.1089 1.46522C27.9768 -0.463032 31.9237 -0.49316 33.8219 1.40496C35.0571 2.64024 34.9818 4.35759 33.6411 5.48743C32.8577 6.15026 31.9539 6.48168 30.9596 6.64739C30.8843 6.66245 30.824 6.67752 30.7336 6.7679C30.8542 6.8131 30.9897 6.84323 31.1103 6.90348C31.6526 7.20477 32.2702 7.41568 32.7071 7.82242C33.4904 8.53044 33.4452 9.61508 32.7071 10.3834C32.1798 10.9257 31.517 11.1969 30.7939 11.3324C30.7186 11.3475 30.6583 11.3626 30.583 11.3927C30.583 11.4228 30.583 11.4379 30.5227 11.5132Z" fill="#0078F0"/>
|
||||
<path d="M29.6037 30.2383C29.2874 30.0425 28.9861 29.922 28.745 29.7111C28.3684 29.3947 28.278 28.9127 28.6095 28.5963C29.1668 28.0389 29.2874 27.3309 29.438 26.6229C29.664 25.6135 29.8447 24.5892 29.9653 23.9113C30.2364 25.0411 30.5678 26.4873 30.9143 27.9335C30.9595 28.0841 31.08 28.2348 31.2005 28.3553C31.7579 28.9578 31.6374 29.6056 30.8993 29.9672C30.7637 30.0425 30.613 30.0877 30.3569 30.1931C30.5528 30.2685 30.6582 30.2986 30.7486 30.3588C31.1102 30.5547 31.532 30.6903 31.8333 30.9614C32.4358 31.4887 32.4358 32.257 31.8333 32.7842C31.4717 33.1006 31.0047 33.2813 30.5678 33.5525C30.6733 33.5826 30.7938 33.6128 30.9143 33.673C31.4566 33.9291 32.0743 34.0948 32.5413 34.4564C33.5355 35.2397 33.5355 36.5654 32.5262 37.3337C32.014 37.7254 31.3813 37.9664 30.7787 38.2827C30.839 38.2978 30.9595 38.343 31.065 38.3731C32.1044 38.5539 33.0535 38.9305 33.8067 39.6837C35.0269 40.8889 35.0119 42.5309 33.7314 43.6758C32.4961 44.7755 31.0047 45.1069 29.3928 44.9714C28.3383 44.881 27.3742 44.5646 26.5306 43.9319C24.8283 42.6514 24.8584 40.5725 26.5908 39.3222C27.2687 38.8251 28.037 38.5388 28.8656 38.3882C28.9861 38.3581 29.1217 38.3279 29.2723 38.2978C28.6998 38.0266 28.1425 37.8459 27.6755 37.5446C26.395 36.701 26.395 35.1493 27.6755 34.3057C28.0822 34.0346 28.5944 33.899 29.0614 33.7031C29.1819 33.658 29.3326 33.6278 29.5736 33.5525C28.6396 33.2211 27.7056 32.9349 27.7508 31.8502C27.796 30.7505 28.745 30.5245 29.6037 30.2383Z" fill="#0078F0"/>
|
||||
<path d="M210.422 21.1394C210.422 22.3295 210.422 23.5045 210.422 24.7097C210.256 24.7247 210.106 24.7398 209.955 24.7398C205.165 24.7398 200.389 24.7398 195.599 24.7548C195.207 24.7548 195.072 24.6494 195.087 24.2427C195.117 23.3237 195.102 22.4199 195.087 21.5009C195.087 21.1996 195.192 21.1093 195.493 21.1093C200.359 21.1243 205.24 21.1093 210.106 21.1093C210.196 21.1093 210.302 21.1243 210.422 21.1394Z" fill="#4A4F54"/>
|
||||
<path d="M40.1493 43.0883C39.0647 43.028 37.724 42.6815 36.7749 41.4613C36.0819 40.5575 36.1271 39.4578 36.8653 38.584C37.6938 37.5898 38.8237 37.1981 40.0439 37.0926C41.3545 36.9872 42.5898 37.2583 43.6594 38.0718C45.1055 39.1715 45.1206 40.9793 43.6895 42.1091C42.8609 42.7569 41.7763 43.0883 40.1493 43.0883Z" fill="#0078F0"/>
|
||||
<path d="M15.2474 5.26147C15.2323 3.96593 15.7445 3.31816 16.4526 2.7909C18.0644 1.60081 20.8212 1.60081 22.4482 2.76077C24.1053 3.95086 24.1204 5.83392 22.4633 7.02401C20.7158 8.27436 17.8385 8.18398 16.2266 6.84324C15.5637 6.30092 15.2474 5.66821 15.2474 5.26147Z" fill="#0078F0"/>
|
||||
<path d="M49.0972 38.825C47.892 38.825 46.9128 38.5689 46.0843 37.891C44.8791 36.8968 44.864 35.4205 46.0541 34.4111C47.6058 33.0855 50.468 33.1307 51.9895 34.4865C53.1646 35.541 53.0139 37.1227 51.643 38.0718C50.8446 38.6292 49.9408 38.8552 49.0972 38.825Z" fill="#0078F0"/>
|
||||
<path d="M11.1501 11.5432C9.91481 11.5583 8.92056 11.2871 8.07695 10.5791C6.88686 9.5698 6.93205 8.03323 8.16733 7.0691C9.7491 5.83382 12.3553 5.84888 13.9069 7.09923C15.097 8.06336 15.1422 9.53967 13.9822 10.549C13.2441 11.2118 12.2197 11.5432 11.1501 11.5432Z" fill="#0078F0"/>
|
||||
<path d="M5.03392 12.643C6.4801 12.628 7.44423 12.8991 8.21251 13.6524C9.07119 14.496 9.05612 15.6258 8.19745 16.4694C6.90191 17.7499 4.19031 17.8252 2.81944 16.6201C1.67454 15.6107 1.76493 14.2097 3.04541 13.3209C3.69318 12.869 4.47653 12.643 5.03392 12.643Z" fill="#0078F0"/>
|
||||
<path d="M54.4151 27.5418C55.6052 27.5418 56.5542 27.7979 57.3225 28.536C58.2264 29.4098 58.1661 30.7053 57.202 31.5037C55.8462 32.6335 53.4359 32.6787 52.0349 31.5941C50.8448 30.6752 50.8297 29.2892 52.0047 28.3552C52.758 27.7376 53.6317 27.5267 54.4151 27.5418Z" fill="#0078F0"/>
|
||||
<path d="M3.07545 24.6193C2.14146 24.6193 1.29785 24.3934 0.604884 23.7305C-0.25379 22.902 -0.193532 21.7571 0.755528 21.0189C1.96068 20.0548 3.97932 20.0096 5.24473 20.8984C6.44989 21.7571 6.44989 23.1581 5.22967 24.0017C4.61203 24.4084 3.91906 24.6193 3.07545 24.6193Z" fill="#0078F0"/>
|
||||
<path d="M56.9307 20.4012C57.699 20.371 58.407 20.5518 59.0397 20.9736C60.3051 21.8172 60.3051 23.2634 59.0548 24.1221C57.8797 24.9205 55.9816 24.9205 54.8066 24.1221C53.5713 23.2785 53.5562 21.8474 54.7915 21.0037C55.4393 20.5518 56.1624 20.371 56.9307 20.4012Z" fill="#0078F0"/>
|
||||
<path d="M37.332 36.9118C36.5486 36.8817 35.7653 36.7009 35.1175 36.1436C34.1835 35.3451 34.2287 34.1852 35.1777 33.4169C36.3528 32.4829 38.4467 32.498 39.6067 33.447C40.5859 34.2454 40.5407 35.5109 39.5012 36.249C38.8685 36.7009 38.1454 36.8968 37.332 36.9118Z" fill="#0078F0"/>
|
||||
<path d="M22.569 12.2514C21.8911 12.2665 21.2283 12.1158 20.6257 11.7091C19.3753 10.8956 19.3753 9.4645 20.6106 8.65102C21.7405 7.91286 23.5482 7.92793 24.663 8.68115C25.8531 9.49463 25.8681 10.8203 24.7082 11.6639C24.0754 12.1158 23.3674 12.2816 22.569 12.2514Z" fill="#0078F0"/>
|
||||
<path d="M54.8522 13.0799C55.5904 13.0498 56.3135 13.2758 56.9311 13.803C57.7145 14.496 57.7295 15.4752 56.9612 16.1983C55.8917 17.1925 53.7525 17.2226 52.6528 16.2585C51.7489 15.4601 51.8393 14.3152 52.8637 13.6222C53.391 13.2456 54.0086 13.0799 54.8522 13.0799Z" fill="#0078F0"/>
|
||||
<path d="M5.41041 31.9407C4.43123 31.9407 3.70813 31.7448 3.09049 31.2176C2.26195 30.5095 2.27701 29.44 3.10555 28.7319C4.145 27.8582 6.14857 27.813 7.21815 28.6415C8.22747 29.4249 8.19734 30.63 7.14283 31.3682C6.58544 31.7749 5.93767 31.9557 5.41041 31.9407Z" fill="#0078F0"/>
|
||||
<path d="M43.373 30.1781C44.096 30.1932 44.8191 30.389 45.4067 30.9464C46.0996 31.6092 46.0695 32.5884 45.3615 33.2061C44.2919 34.1401 42.3636 34.1551 41.279 33.2512C40.4053 32.5131 40.4354 31.4586 41.3393 30.7807C41.9268 30.3438 42.5896 30.1781 43.373 30.1781Z" fill="#0078F0"/>
|
||||
<path d="M16.754 11.0914C17.4168 11.0914 18.0495 11.2571 18.5918 11.6639C19.6162 12.4171 19.6011 13.562 18.5617 14.3002C17.5524 15.0233 15.8802 15.0082 14.8558 14.3002C13.7863 13.562 13.8013 12.3267 14.886 11.6036C15.4132 11.2571 16.0158 11.0914 16.754 11.0914Z" fill="#0078F0"/>
|
||||
<path d="M11.1801 37.8759C10.3816 37.891 9.67361 37.6801 9.11623 37.1076C8.55885 36.5352 8.55885 35.797 9.10117 35.1945C10.0653 34.1249 12.2798 34.1249 13.2439 35.1794C13.7862 35.782 13.7862 36.5503 13.1987 37.1227C12.6262 37.6801 11.9333 37.891 11.1801 37.8759Z" fill="#0078F0"/>
|
||||
<path d="M48.841 10.5942C48.1179 10.6093 47.4852 10.4436 46.958 9.99167C46.1897 9.3439 46.1897 8.42497 46.9278 7.76213C47.907 6.90346 49.8353 6.91852 50.7693 7.7772C51.5074 8.4551 51.5074 9.3439 50.7241 9.99167C50.1818 10.4436 49.534 10.6244 48.841 10.5942Z" fill="#0078F0"/>
|
||||
<path d="M47.1841 29.4098C46.4309 29.3495 45.7379 29.1838 45.2107 28.6113C44.7136 28.069 44.7136 27.3459 45.1956 26.8036C46.0995 25.7943 48.2236 25.7792 49.1576 26.7735C49.715 27.361 49.6999 28.0992 49.1274 28.6716C48.5851 29.2139 47.9072 29.3495 47.1841 29.4098Z" fill="#0078F0"/>
|
||||
<path d="M12.8221 18.9551C12.0839 18.9852 11.4512 18.7894 10.9089 18.3073C10.2762 17.7198 10.2611 16.9214 10.8788 16.3188C11.7977 15.4149 13.7109 15.3999 14.6449 16.2736C15.3529 16.9214 15.3379 17.765 14.5997 18.3826C14.1026 18.8044 13.4849 18.9852 12.8221 18.9551Z" fill="#0078F0"/>
|
||||
<path d="M19.2998 41.9585C18.6972 41.9284 18.1248 41.7777 17.6427 41.3861C16.9498 40.8287 16.9498 39.9399 17.6277 39.3674C18.5315 38.6142 20.1284 38.5991 21.0322 39.3524C21.7402 39.9399 21.7252 40.8739 20.987 41.4313C20.4748 41.8079 19.9024 41.9434 19.2998 41.9585Z" fill="#0078F0"/>
|
||||
<path d="M40.7365 3.06208C41.2638 3.03195 41.8061 3.19766 42.3032 3.54414C43.0414 4.0714 43.0866 4.94513 42.4388 5.56278C41.5651 6.40638 39.7423 6.39132 38.8836 5.53265C38.3413 4.99033 38.3262 4.25217 38.8685 3.70985C39.3657 3.24285 39.9833 3.06208 40.7365 3.06208Z" fill="#0078F0"/>
|
||||
<path d="M48.8865 24.0167C48.2236 24.0317 47.6211 23.8811 47.139 23.4291C46.5665 22.8868 46.5967 22.0733 47.2143 21.5762C48.0579 20.8682 49.5644 20.8531 50.423 21.5461C51.1612 22.1336 51.1612 22.9772 50.408 23.5647C49.9711 23.9112 49.4439 24.0317 48.8865 24.0167Z" fill="#0078F0"/>
|
||||
<path d="M33.6564 32.0762C32.873 31.5942 32.9785 30.6301 33.7166 30.1028C34.5151 29.5454 35.7955 29.5454 36.5939 30.0877C37.3773 30.6301 37.4225 31.5791 36.6241 32.0913C36.2023 32.3775 34.8615 32.8295 33.6564 32.0762Z" fill="#0078F0"/>
|
||||
<path d="M24.8586 15.2944C24.2259 15.3094 23.6685 15.1739 23.2015 14.737C22.6743 14.2399 22.6743 13.5318 23.1865 13.0347C24 12.2363 25.7022 12.2514 26.5007 13.0648C26.9978 13.577 26.9978 14.2248 26.4856 14.7219C26.0337 15.1588 25.4612 15.3245 24.8586 15.2944Z" fill="#0078F0"/>
|
||||
<path d="M47.4704 18.6086C46.7473 18.6086 46.2502 18.4579 45.8284 18.0813C45.3012 17.5992 45.3162 16.9213 45.8435 16.4393C46.6118 15.7463 48.1032 15.7463 48.8564 16.4393C49.3384 16.8761 49.3686 17.554 48.9016 18.021C48.4647 18.4579 47.9073 18.6086 47.4704 18.6086Z" fill="#0078F0"/>
|
||||
<path d="M37.9194 30.0123C37.3168 29.6056 37.3469 28.7921 37.9344 28.3401C38.6726 27.7677 39.923 27.7526 40.6611 28.3251C41.2788 28.7921 41.2938 29.6357 40.631 30.0424C40.2393 30.2835 39.0342 30.645 37.9194 30.0123Z" fill="#0078F0"/>
|
||||
<path d="M20.6556 14.5563C21.2581 14.5563 21.7553 14.6768 22.162 15.0534C22.6441 15.5053 22.6441 16.123 22.1771 16.59C21.454 17.298 19.9927 17.3131 19.2546 16.6051C18.7574 16.1381 18.7725 15.4903 19.2696 15.0384C19.6764 14.6617 20.1735 14.5412 20.6556 14.5563Z" fill="#0078F0"/>
|
||||
<path d="M44.4576 12.176C44.9999 12.5225 45.015 13.2305 44.548 13.6824C43.855 14.3453 42.4691 14.3302 41.7912 13.6674C41.3543 13.2305 41.3694 12.5375 41.8966 12.1911C42.9662 11.5282 44.0961 11.935 44.4576 12.176Z" fill="#0078F0"/>
|
||||
<path d="M17.9442 19.9945C17.4471 20.0095 16.9952 19.8739 16.6336 19.5124C16.2269 19.1207 16.2269 18.6085 16.6186 18.2018C17.2663 17.5239 18.6673 17.5239 19.3151 18.2018C19.7068 18.6085 19.7068 19.1057 19.3 19.5124C18.9234 19.8739 18.4564 20.0095 17.9442 19.9945Z" fill="#0078F0"/>
|
||||
<path d="M42.0019 25.026C42.5291 25.011 42.9961 25.1164 43.3727 25.493C43.7644 25.8847 43.7644 26.412 43.3727 26.8037C42.74 27.4514 41.3691 27.4665 40.7063 26.8187C40.2845 26.3969 40.2694 25.8998 40.6912 25.478C41.0679 25.1315 41.5198 24.9959 42.0019 25.026Z" fill="#0078F0"/>
|
||||
<path d="M23.503 34.2002C24.2412 34.622 24.2412 35.4355 23.488 35.8423C22.795 36.2189 22.087 36.2038 21.4241 35.7519C20.8366 35.3602 20.8366 34.622 21.4392 34.2454C21.7706 34.0797 22.6594 33.7784 23.503 34.2002Z" fill="#0078F0"/>
|
||||
<path d="M36.2474 10.5943C35.7805 10.2328 35.8407 9.67538 36.2926 9.2837C36.8802 8.78657 37.9949 8.77151 38.6126 9.25357C39.1097 9.64525 39.17 10.2478 38.6728 10.6094C38.3414 10.8655 37.3321 11.2571 36.2474 10.5943Z" fill="#0078F0"/>
|
||||
<path d="M42.5895 23.4594C42.0623 23.2937 41.7007 22.887 41.7158 22.4953C41.7309 22.1187 42.1527 21.6969 42.6498 21.5613C43.1469 21.4257 43.629 21.4558 44.0809 21.6969C44.4123 21.8776 44.6835 22.1337 44.6684 22.5405C44.6534 22.9322 44.3822 23.2033 44.0357 23.354C43.7645 23.4745 43.3729 23.6402 42.5895 23.4594Z" fill="#0078F0"/>
|
||||
<path d="M15.7144 23.1279C15.2022 22.7663 15.2172 22.209 15.6993 21.8022C16.2717 21.3202 17.3564 21.3202 17.9288 21.8022C18.3958 22.1939 18.3958 22.8417 17.8686 23.1731C16.9496 23.7305 16.0157 23.3539 15.7144 23.1279Z" fill="#0078F0"/>
|
||||
<path d="M41.1132 19.3769C40.6914 19.0605 40.7366 18.5634 41.1433 18.232C41.6555 17.8102 42.6046 17.8102 43.1167 18.232C43.5235 18.5634 43.5837 19.0605 43.1619 19.3769C42.8908 19.5878 41.9417 19.9494 41.1132 19.3769Z" fill="#0078F0"/>
|
||||
<path d="M20.7459 30.0123C20.1132 30.0123 19.601 29.6357 19.616 29.1687C19.616 28.7318 20.1132 28.3703 20.7308 28.3552C20.7459 28.3552 20.7609 28.3552 20.776 28.3552C21.4087 28.3552 21.9209 28.7168 21.9209 29.1687C21.9209 29.6508 21.4087 30.0274 20.7459 30.0123Z" fill="#0078F0"/>
|
||||
<path d="M39.2451 15.0081C39.923 15.0081 40.4352 15.3847 40.4051 15.8667C40.375 16.3337 39.7272 16.7254 39.1246 16.6501C38.507 16.5748 38.04 16.2132 38.055 15.8065C38.0701 15.3545 38.5974 15.0081 39.2451 15.0081Z" fill="#0078F0"/>
|
||||
<path d="M24.783 30.5245C25.3554 30.5245 25.8526 30.9011 25.8224 31.2928C25.7923 31.6996 25.1445 32.0762 24.6323 31.9858C24.075 31.8954 23.7134 31.579 23.7285 31.2024C23.7435 30.8409 24.2407 30.5245 24.783 30.5245Z" fill="#0078F0"/>
|
||||
<path d="M35.2377 13.0046C35.8102 13.0046 36.3224 13.3813 36.2772 13.7729C36.2471 14.1646 35.6144 14.5412 35.1022 14.481C34.5297 14.4056 34.138 14.0592 34.1832 13.6675C34.2284 13.3059 34.7105 13.0046 35.2377 13.0046Z" fill="#0078F0"/>
|
||||
<path d="M17.9138 27.0899C17.2208 27.0748 16.6635 26.6681 16.6785 26.171C16.6785 25.6889 17.2208 25.2972 17.8987 25.2671C17.9138 25.2671 17.9289 25.2671 17.9439 25.2671C18.6369 25.2671 19.1943 25.6588 19.2093 26.171C19.1943 26.6982 18.6218 27.105 17.9138 27.0899Z" fill="#0078F0"/>
|
||||
<path d="M10.9992 23.9714C10.3364 23.9865 9.76396 23.8208 9.29696 23.3839C8.72451 22.8567 8.72451 22.1487 9.2819 21.6063C10.0954 20.8079 11.8127 20.7778 12.6563 21.5611C13.289 22.1486 13.274 22.8868 12.6111 23.4442C12.1441 23.8359 11.5868 24.0016 10.9992 23.9714Z" fill="#0078F0"/>
|
||||
<path d="M12.4758 29.0482C11.8883 29.0633 11.3911 28.9126 10.9693 28.536C10.4722 28.069 10.4571 27.4363 10.9543 26.9693C11.6774 26.2613 13.1838 26.2462 13.937 26.9241C14.4944 27.4363 14.4793 28.0992 13.9069 28.5812C13.4851 28.9277 12.988 29.0633 12.4758 29.0482Z" fill="#0078F0"/>
|
||||
<path d="M16.7089 33.206C16.1967 33.2211 15.7448 33.0855 15.3682 32.7541C14.9163 32.3473 14.9163 31.7899 15.3531 31.3681C16.0009 30.7354 17.3266 30.7204 17.9894 31.338C18.4865 31.7899 18.4715 32.3774 17.9593 32.8143C17.5977 33.1005 17.1609 33.2361 16.7089 33.206Z" fill="#0078F0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 21 KiB |
@@ -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("<div class='wy-table-responsive'></div>"),
|
||||
n("table.docutils.footnote").wrap("<div class='wy-table-responsive footnote'></div>"),
|
||||
n("table.docutils.citation").wrap("<div class='wy-table-responsive citation'></div>"),
|
||||
n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function () {
|
||||
var t = n(this);
|
||||
expand = n('<button class="toctree-expand" title="Open/close menu"></button>'),
|
||||
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) {
|
||||
// 未定义的模块体
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,292 @@
|
||||
{# TEMPLATE VAR SETTINGS #}
|
||||
{%- set url_root = pathto('', 1) %}
|
||||
{%- if url_root == '#' %}{% set url_root = '' %}{% endif %}
|
||||
{%- if not embedded and docstitle %}
|
||||
{%- set titlesuffix = " — "|safe + docstitle|e %}
|
||||
{%- else %}
|
||||
{%- set titlesuffix = "" %}
|
||||
{%- endif %}
|
||||
{%- set lang_attr = 'en' if language == None else (language | replace('_', '-')) %}
|
||||
{%- set sphinx_writer = 'writer-html5' if html5_doctype else 'writer-html4' -%}
|
||||
|
||||
{# Build sphinx_version_info tuple from sphinx_version string in pure Jinja #}
|
||||
{%- set (_ver_major, _ver_minor) = (sphinx_version.split('.') | list)[:2] | map('int') -%}
|
||||
{%- set sphinx_version_info = (_ver_major, _ver_minor, -1) -%}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html class="{{ sphinx_writer }}" lang="{{ lang_attr }}" {% if sphinx_version_info>= (7, 2) %} data-content_root="{{
|
||||
content_root }}"{% endif %}>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
{{- metatags }}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
{%- block htmltitle %}
|
||||
<title>{{ title|striptags|e }}{{ titlesuffix }}</title>
|
||||
{%- endblock -%}
|
||||
|
||||
{#- CSS #}
|
||||
{%- if sphinx_version_info
|
||||
< (4, 0) -%} <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
|
||||
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
|
||||
{%- endif %}
|
||||
{%- for css_file in css_files %}
|
||||
{%- if css_file|attr("filename") %}
|
||||
{{ css_tag(css_file) }}
|
||||
{%- else %}
|
||||
<link rel="stylesheet" href="{{ pathto(css_file, 1)|escape }}" type="text/css" />
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
|
||||
{# "extra_css_files" is a theme option and it's always a string #}
|
||||
{%- for css_file in extra_css_files %}
|
||||
<link rel="stylesheet" href="{{ pathto(css_file, 1)|escape }}" type="text/css" />
|
||||
{%- endfor -%}
|
||||
|
||||
{#- FAVICON
|
||||
favicon_url is the only context var necessary since Sphinx 4.
|
||||
In Sphinx
|
||||
<4, we use favicon but need to prepend path info. #} {%- set _favicon_url=favicon_url | default(pathto('_static/' +
|
||||
(favicon or "" ), 1)) %} {%- if favicon_url or favicon %} <link rel="shortcut icon" href="{{ _favicon_url }}" />
|
||||
{%- endif %}
|
||||
|
||||
{#- CANONICAL URL (deprecated) #}
|
||||
{%- if theme_canonical_url and not pageurl %}
|
||||
<link rel="canonical" href="{{ theme_canonical_url }}{{ pagename }}.html" />
|
||||
{%- endif -%}
|
||||
|
||||
{#- CANONICAL URL #}
|
||||
{%- if pageurl %}
|
||||
<link rel="canonical" href="{{ pageurl|e }}" />
|
||||
{%- endif -%}
|
||||
|
||||
{#- JAVASCRIPTS #}
|
||||
{%- block scripts %}
|
||||
<!--[if lt IE 9]>
|
||||
<script src="{{ pathto('_static/js/html5shiv.min.js', 1) }}"></script>
|
||||
<![endif]-->
|
||||
{%- if not embedded %}
|
||||
{# XXX Sphinx 1.8.0 made this an external js-file, quick fix until we refactor the template to inherert more blocks
|
||||
directly from sphinx #}
|
||||
{%- if sphinx_version_info >= (1, 8) -%}
|
||||
{%- if sphinx_version_info < (4, 0) -%} <script id="documentation_options" data-url_root="{{ url_root }}"
|
||||
src="{{ pathto('_static/documentation_options.js', 1) }}">
|
||||
</script>
|
||||
{%- endif -%}
|
||||
{%- for scriptfile in script_files %}
|
||||
{{ js_tag(scriptfile) }}
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
<script>
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: '{{ url_root }}',
|
||||
VERSION: '{{ release|e }}',
|
||||
LANGUAGE: '{{ language }}',
|
||||
COLLAPSE_INDEX: false,
|
||||
FILE_SUFFIX: '{{ '' if no_search_suffix else file_suffix }}',
|
||||
HAS_SOURCE: {{ has_source| lower }},
|
||||
SOURCELINK_SUFFIX: '{{ sourcelink_suffix }}'
|
||||
};
|
||||
</script>
|
||||
{%- for scriptfile in script_files %}
|
||||
<script src="{{ pathto(scriptfile, 1) }}"></script>
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
<script src="{{ pathto('_static/js/theme.js', 1) }}"></script>
|
||||
|
||||
{#- OPENSEARCH #}
|
||||
{%- if use_opensearch %}
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
|
||||
href="{{ pathto('_static/opensearch.xml', 1) }}" />
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
|
||||
{%- block linktags %}
|
||||
{%- if hasdoc('about') %}
|
||||
<link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
|
||||
{%- endif %}
|
||||
{%- if hasdoc('genindex') %}
|
||||
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
|
||||
{%- endif %}
|
||||
{%- if hasdoc('search') %}
|
||||
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
|
||||
{%- endif %}
|
||||
{%- if hasdoc('copyright') %}
|
||||
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
|
||||
{%- endif %}
|
||||
{%- if next %}
|
||||
<link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
|
||||
{%- endif %}
|
||||
{%- if prev %}
|
||||
<link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
{%- block extrahead %} {% endblock %}
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
|
||||
{%- block extrabody %} {% endblock %}
|
||||
<div class="wy-grid-for-nav">
|
||||
{#- SIDE NAV, TOGGLES ON MOBILE #}
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" {% if theme_style_nav_header_background %}
|
||||
style="background: {{theme_style_nav_header_background}}" {% endif %}>
|
||||
{%- block sidebartitle %}
|
||||
|
||||
{# the logo helper function was removed in Sphinx 6 and deprecated since Sphinx 4 #}
|
||||
{# the master_doc variable was renamed to root_doc in Sphinx 4 (master_doc still exists in later
|
||||
Sphinx versions) #}
|
||||
{%- set _logo_url = logo_url|default(pathto('_static/' + (logo or ""), 1)) %}
|
||||
{%- set _root_doc = root_doc|default(master_doc) %}
|
||||
<a href="{{ pathto(_root_doc) }}" {% if not theme_logo_only %} class="icon icon-home" {% endif %}>
|
||||
{% if not theme_logo_only %}{{ project }}{% endif %}
|
||||
{%- if logo or logo_url %}
|
||||
<img src="{{ _logo_url }}" class="logo" alt="{{ _('Logo') }}" />
|
||||
{%- endif %}
|
||||
</a>
|
||||
|
||||
{%- if theme_display_version %}
|
||||
{%- set nav_version = version %}
|
||||
{%- if READTHEDOCS and current_version %}
|
||||
{%- set nav_version = current_version %}
|
||||
{%- endif %}
|
||||
{%- if nav_version %}
|
||||
<div class="version">
|
||||
{{ nav_version }}
|
||||
</div>
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
|
||||
{%- include "searchbox.html" %}
|
||||
|
||||
{%- endblock %}
|
||||
</div>
|
||||
|
||||
{%- block navigation %}
|
||||
{#- Translators: This is an ARIA section label for the main navigation menu -#}
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation"
|
||||
aria-label="{{ _('Navigation menu') }}">
|
||||
{%- block menu %}
|
||||
{%- set toctree = toctree(maxdepth=theme_navigation_depth|int,
|
||||
collapse=theme_collapse_navigation|tobool,
|
||||
includehidden=theme_includehidden|tobool,
|
||||
titles_only=theme_titles_only|tobool) %}
|
||||
{%- if toctree %}
|
||||
{{ toctree }}
|
||||
{%- else %}
|
||||
<!-- Local TOC -->
|
||||
<div class="local-toc">{{ toc }}</div>
|
||||
{%- endif %}
|
||||
{%- endblock %}
|
||||
</div>
|
||||
{%- endblock %}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
{#- MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #}
|
||||
{#- Translators: This is an ARIA section label for the navigation menu that is visible when viewing the page
|
||||
on mobile devices -#}
|
||||
<nav class="wy-nav-top" aria-label="{{ _('Mobile navigation menu') }}" {% if
|
||||
theme_style_nav_header_background %} style="background: {{theme_style_nav_header_background}}" {% endif
|
||||
%}>
|
||||
{%- block mobile_nav %}
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="{{ pathto(master_doc) }}">{{ project }}</a>
|
||||
{%- endblock %}
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
{%- block content %}
|
||||
{%- if theme_style_external_links|tobool %}
|
||||
<div class="rst-content style-external-links">
|
||||
{%- else %}
|
||||
<div class="rst-content">
|
||||
{%- endif %}
|
||||
{% include "breadcrumbs.html" %}
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
{%- block document %}
|
||||
<div itemprop="articleBody">
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
{%- if self.comments()|trim %}
|
||||
<div class="articleComments">
|
||||
{%- block comments %}{% endblock %}
|
||||
</div>
|
||||
{%- endif%}
|
||||
</div>
|
||||
{%- endblock %}
|
||||
{% include "footer.html" %}
|
||||
</div>
|
||||
{%- endblock %}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{% include "versions.html" -%}
|
||||
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable({{ 'true' if theme_sticky_navigation | tobool else 'false' }});
|
||||
});
|
||||
</script>
|
||||
|
||||
{#- Do not conflict with RTD insertion of analytics script #}
|
||||
{%- if not READTHEDOCS %}
|
||||
{%- if theme_analytics_id %}
|
||||
<!-- Theme Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id={{ theme_analytics_id }}"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag() { dataLayer.push(arguments); }
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', '{{ theme_analytics_id }}', {
|
||||
'anonymize_ip': {{ 'true' if theme_analytics_anonymize_ip | tobool else 'false' }},
|
||||
});
|
||||
</script>
|
||||
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
|
||||
{%- block footer %} {% endblock %}
|
||||
|
||||
|
||||
|
||||
{% extends "!layout.html" %}
|
||||
|
||||
{% block body %}
|
||||
{{ super() }}
|
||||
<!-- 在这里添加你的自定义内容 -->
|
||||
{% if theme_logo %}
|
||||
<div class="logoheader">
|
||||
<a href="{{ pathto(master_doc) }}">
|
||||
<img src="{{ pathto('_static/' + theme_logo, 1) }}" alt="Logo" />
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="document-wrapper">
|
||||
<div class="document">
|
||||
<div class="body">
|
||||
{% if pagename == 'index' %}
|
||||
<h1>{{ title }}</h1>
|
||||
{% else %}
|
||||
<h2>{{ title }}</h2>
|
||||
{% endif %}
|
||||
{{ super() }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar">
|
||||
{{ sidebar }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 208 KiB |
|
After Width: | Height: | Size: 313 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 736 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 256 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 154 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 163 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 234 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 823 KiB |
|
After Width: | Height: | Size: 245 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 193 KiB |
@@ -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.
|
||||