news 2026/10/6 1:28:24

Orbbec深度相机ROS2部署实战:从单设备调通到多相机配置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Orbbec深度相机ROS2部署实战:从单设备调通到多相机配置

做机器人或者三维视觉的朋友应该都遇到过这种尴尬阶段:厂家给的SDK示例跑得飞快,点云图、深度图在自家工具里显示得清清楚楚,但一到ROS2环境里就各种卡壳——要么编译不过,要么节点起来以后没有任何数据,要么多台相机一插上就相互干扰,甚至直接把整条USB总线搞崩。这些坑我几乎都踩过一遍,所以今天这篇想把OrbbecSDK深度相机在ROS2下的部署、单设备调通、多设备配置整条链路完整梳理一遍,重点放在多设备实战部分,因为这块是最容易绕弯路的。

这篇文章主要基于Ubuntu 22.04 + ROS2 Humble环境,相机以Orbbec系列深度相机为例(Femto系列、Gemini系列我都试过,部署思路一致)。内容适合正在做ROS2机器人感知、移动底盘避障、机械臂抓取、三维重建方向的朋友,尤其是那种“手头已有相机但被驱动和配置卡住”的阶段。看完以后你能得到一套从零开始可复现的流程:从SDK安装、ROS2 wrapper编译,到单相机跑通可视化,再到多相机同时接入、分别出图出点云。

1. 为什么走OrbbecSDK这条路,而不直接用普通驱动包

先说清楚整套方案的设计逻辑,不然你跟着装了一堆包,出了问题也不知道该从哪里排查。这里牵扯到深度相机接入ROS2的两种主流路径。

1.1 OrbbecSDK在方案链路中的角色

OrbbecSDK是奥比中光提供的跨平台SDK,负责最底层的硬件访问:枚举设备、启动图像流、控制深度算法参数、读取固件信息、管理多设备等。你可以把它理解为硬件和上层应用之间唯一的“翻译官”。SDK本身不依赖ROS,直接通过它就能拿到深度图、彩色图、点云数据,跨平台支持Linux、Windows和macOS。

在ROS2侧,官方仓库提供了orbbec_ros2这个wrapper包。它做的事情就是把OrbbecSDK取到的原始图像数据,转成ROS2标准消息(sensor_msgs/Image、sensor_msgs/PointCloud2),再按照ROS2话题机制发布出去。也就是说,SDK负责“让相机出声”,ROS2 wrapper负责“让ROS2生态能听懂声音”,两者缺一不可。

1.2 为什么不要自己去写底层驱动

很多人最开始尝试绕过SDK,直接通过USB协议去读相机数据,想省掉一层依赖。我劝你别这样。深度相机的数据协议非常复杂,深度图涉及伪彩映射、点云涉及内外参标定、设备端还有固件逻辑,这些细节厂商SDK已经全部处理好。自己写驱动的代价是巨大的,而且没有任何可维护性。走官方SDK + wrapper这条路,最大的好处是SDK版本升级时,ROS2侧基本不用改代码,只需要同步一下wrapper仓库就够了。

1.3 单设备和多设备的复杂度完全不是一个量级

如果你只是单台相机跑通,整个过程其实比较简单:装SDK、编译wrapper、启动节点、Rviz2里看数据,半小时能搞定。但一旦场景变成“多台相机同步工作”(比如四台相机做360度无死角感知,或者两台相机一上一下分别负责近距离抓取和远距离导航),问题就来了:

  • 多台相机默认都会发布相同的话题名(比如/camera/depth/image_raw),会互相覆盖。
  • USB带宽是共享的,多台相机同时传输高分辨率深度流和点云流,带宽很容易被打满,导致卡顿掉帧。
  • 需要根据设备序列号区分每台相机,并给每台设备分配独立的frame_id、独立话题名,否则下游算法无法区分数据来源。

这些就是多设备配置的核心挑战。下面我会一步一步展开,从环境准备开始,把每一步该做什么、为什么这样做说清楚。

2. 环境准备:从零开始搭建部署环境

这一步是后面所有工作的地基。环境出问题,后面编译和运行全都会跟着遭殃。我建议你按照这个顺序来,不要跳步。

2.1 操作系统和ROS2版本选择

我的经验是优先选择Ubuntu 22.04 + ROS2 Humble,这是目前兼容性最稳的组合。Ubuntu 20.04 + Foxy也可以用,但OrbbecSDK较新版本对Humble的适配更积极。如果你刚接触ROS2,最好直接上22.04 + Humble,因为社区资料最丰富,遇到问题也容易搜到答案。

安装ROS2 Humble时,建议用官方二进制包方式(apt安装),不要用源码编译ROS2,那种方式费时费力且容易因为依赖冲突导致失败。乌班图下安装ROS2的核心步骤大致是:

sudo apt update && sudo apt install curl sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null sudo apt update && sudo apt install ros-humble-desktop

这组命令把ROS2 Humble桌面版完整装好,里面自带Rviz2、demo节点等常用工具,省得后期一个个装。装完之后记得在~/.bashrc里source一下环境:

echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source ~/.bashrc

2.2 安装OrbbecSDK Linux版本

OrbbecSDK的Linux版本可以从奥比中光官网或者GitHub Release页面下载,一般是一个.deb安装包或者压缩包。用.deb方式最省事:

sudo dpkg -i OrbbecSDK_Linux_xxx.deb

安装完以后,SDK自带的一些工具(比如OrbbecViewer)会放到/opt/OrbbecSDK目录下。建议先打开OrbbecViewer确认相机能被识别,并且能看到图像流。这一步特别重要,它把“硬件有问题”和“软件配置有问题”在一开始就区分开了。

插上相机后,在OrbbecViewer里如果能看到实时RGB图和深度图,说明USB连接、驱动、供电都正常;如果这里都看不到画面,那就别急着折腾ROS2,先排查USB线、供电、相机固件。我的一个经验是:深度相机对USB线质量很敏感,一定要用原装或者质量好的USB 3.0线,劣质线会出现时断时续的情况,很难排查。

2.3 编译orbbec_ros2插件包

orbbec_ros2是奥比中光官方维护的ROS2 wrapper,GitHub仓库名是orbbec_ros2。需要新建一个ROS2工作空间,比如orbbec_ws,然后在这个空间的src目录下把代码拉下来:

mkdir -p ~/orbbec_ws/src cd ~/orbbec_ws/src git clone https://github.com/orbbec/OrbbecSDK_ROS2.git -b ros2-humble cd ~/orbbec_ws colcon build --symlink-install

注意这里有一个细节,不同分支对应不同ROS2版本,ros2-humble分支对应Humble,ros2-foxy分支对应Foxy。分支选错了,编译报错会让你怀疑人生。build过程中如果提示缺少ament_cmake等依赖,多半是ROS2环境没有source,先执行source /opt/ros/humble/setup.bash再编译。

编译完成之后,记得把工作空间的安装路径加入环境:

echo "source ~/orbbec_ws/install/setup.bash" >> ~/.bashrc source ~/.bashrc

到这里,环境层面就全部准备完毕了。接下来进入真正的部署环节。

3. 单设备部署:先把一条数据链路彻底跑通

多设备配置的复杂性是建立在单设备能正常工作这个基础之上的。如果单相机都没调明白就急着上多设备,出问题的时候会根本分不清是相机的问题还是配置的问题。所以我强烈建议:先在单台相机上把整个链路跑一遍,确认没问题再继续。

3.1 USB权限管理:貌不惊人却最常坑人

在Linux下使用Orbbec深度相机,必须先配置udev规则,否则跑节点的时候会报权限错误,表现是“找不到设备,No device found”。这个坑非常隐蔽,因为SDK自带的OrbbecViewer可能通过其他方式已经拿到了权限,而ROS2节点却因为权限问题起不来。

奥比中光官方提供了udev规则文件,一般在SDK安装包的misc目录下,或者可以从GitHub仓库获取。配置方式为:

cd /opt/OrbbecSDK/misc sudo cp 99-orbec.rules /etc/udev/rules.d/ sudo udevadm control --reload-rules sudo udevadm trigger

配置完成后,重新插拔一次USB,确保设备节点权限生效。

3.2 启动单目相机节点

orbbec_ros2包提供了一个标准的launch文件,名字一般是orbbec_camera.launch.py。启动方式:

ros2 launch orbbec_camera orbbec_camera.launch.py

默认情况下,这个launch文件会启动相机节点,并且发布一系列话题。用ros2 topic list可以查看当前有哪些话题:

ros2 topic list

正常情况下应该能看到类似下面的输出:

/camera/color/image_raw /camera/depth/image_raw /camera/pointcloud/cloud /camera/depth/camera_info /camera/color/camera_info

这里出现的/camera/pointcloud/cloud就是点云话题,类型是sensor_msgs/PointCloud2。如果你只需要深度图不想要点云,或者反过来,可以通过launch文件的参数把不需要的流关掉,这样可以节省USB带宽和CPU资源。

3.3 用Rviz2验证数据流

启动Rviz2,添加PointCloud2显示组件,并选择/camera/pointcloud/cloud话题,就能看到点云。这一步是验证整条链路是否通畅的关键:

rviz2

在Rviz2界面中,左侧Display面板点击Add,选择By topic,展开/camera/pointcloud/cloud,点击添加到显示列表。Fixed Frame需要设置为相机的frame_id,默认一般是camera_link或者camera_depth_frame,可以从话题消息里查看实际值。

如果能看到点云数据在Rviz2里显示,并且旋转视角时点云会跟着变化,那么单设备部署就完成了。点云呈现的密度跟相机分辨率、深度算法模式有关,这些都可以在参数里调整,后面会详细说。

3.4 单相机运行时的关键参数调优

在orbbec_camera.launch.py中,有几个参数值得重点关注:

  • depth_width/depth_height:深度图分辨率,默认可能是640x480,如果下游算法对分辨率要求不高,用默认值就好,分辨率越高对USB带宽和CPU占用越大。
  • color_width/color_height:彩色图分辨率。
  • depth_fps:深度帧率,常用15或30 FPS。
  • enable_pointcloud:是否启用点云生成,默认可能是true。如果不需要点云,建议关闭,能显著降低CPU占用。
  • enable_colored_pointcloud:是否生成带RGB颜色的点云,这个功能非常实用,但代价是更高的CPU占用和更大的数据传输量。

一个经验是:点云生成是在CPU端完成的,因此开启点云后CPU占用会有一个明显的跳升。如果主控是树莓派或者低功耗工控机,建议尽量降低点云分辨率或者关闭点云,把数据以深度图形式输出,在下游模块内部再单独做点云转换。

4. 多设备配置实战:从“一台能跑”到“多台协同”

多台相机的场景在实际项目中非常普遍。比如移动机器人需要前后左右全方位感知,通常会安装2到4台相机;机械臂抓取工站需要用多台相机从不同角度观察工件。下面重点讲多设备配置的完整流程。

4.1 多设备接入的第一道门槛:USB带宽账必须算清楚

开始配置之前,先说USB带宽相关的计算。这属于经验教训,我在实际项目中因为没算好带宽,浪费了很多排查时间。

USB 3.0的理论带宽是5Gbps,实际有效带宽大约在3.2Gbps左右(考虑协议开销),USB 3.1/3.2更高一些。而一台深度相机以1080p、30FPS的深度图传输时,每帧数据量约为1920x1080x2字节(深度值一般16位,两个字节),也就是约4MB,乘以帧率30就是120MB/s,约等于1Gbps。再加上彩色图,一台相机就要占掉接近1Gbps的带宽。两台相机同时跑1080p@30FPS,带宽就快满了。这还是纯图像部分,如果再叠加点云流、彩色点云流,带宽压力更大。

所以在这个阶段要做两个动作:

  1. 把多台相机同时接入同一个USB控制器时,留意控制器通道数。通常用一个USB 3.0 Hub扩展多个口,其实是共享同一个控制器的带宽,4台相机全插一个Hub上是很危险的。有条件的话,把相机分散接到主板的不同USB控制器上。在Linux下可以用lsusb -t查看不同USB控制器上的设备分布情况。

  2. 不要盲目追求最高分辨率。多设备场景下,最常见的策略是把每台相机的分辨率降下来。比如双相机方案,一边用640x480@30FPS,一边用1280x720@15FPS,这个配置是经过我多次实验验证过的,稳定不丢帧。具体怎么选,要结合你的下游算法需求来权衡。

4.2 区分设备:序列号才是硬道理

多设备配置的第一个核心难点,就是如何在代码层区分两台相机。USB设备插入的顺序、被系统识别的先后都会变化,靠/dev/video0这种方式区分设备是完全不可靠的。正确的方式是通过设备的序列号来区分。

获取设备序列号的方式很简单,在OrbbecViewer的界面中,每台相机的信息栏里会显示SN号;也可以通过SDK工具列出所有设备的序列号。序列号是每台相机出厂就固化好的,唯一且不变。

在orbbec_ros2中,每个launch文件里通过camera_name、serial_number等参数来指定具体使用哪一台相机。

4.3 多相机launch文件配置示范

下面是我实际用过的双相机launch文件配置示例。假设有两台相机,SN分别为SN1234567890和SN0987654321,分别命名为front_camera和back_camera。

在launch文件中可以这样写:

from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): return LaunchDescription([ Node( package='orbbec_camera', executable='orbbec_camera_node', name='front_camera', namespace='front_camera', parameters=[{ 'serial_number': 'SN1234567890', 'color_format': 'RGB', 'color_width': 640, 'color_height': 480, 'color_fps': 30, 'depth_width': 640, 'depth_height': 480, 'depth_fps': 30, 'enable_pointcloud': True, 'pointcloud_qos': 'SENSOR_DATA', 'frame_id': 'front_camera_link', }], ), Node( package='orbbec_camera', executable='orbbec_camera_node', name='back_camera', namespace='back_camera', parameters=[{ 'serial_number': 'SN0987654321', 'color_format': 'RGB', 'color_width': 640, 'color_height': 480, 'color_fps': 30, 'depth_width': 640, 'depth_height': 480, 'depth_fps': 30, 'enable_pointcloud': True, 'pointcloud_qos': 'SENSOR_DATA', 'frame_id': 'back_camera_link', }], ), ])

把这个文件保存为dual_camera.launch.py,放到orbbec_ws/src/OrbbecSDK_ROS2/orbbec_camera/launch/目录下,然后重新编译工作空间:

cd ~/orbbec_ws colcon build --symlink-install source install/setup.bash

启动方式:

ros2 launch orbbec_camera dual_camera.launch.py

启动完成后,用ros2 topic list验证一下话题是否按照预期进行了区分:

/front_camera/camera/color/image_raw /front_camera/camera/depth/image_raw /front_camera/camera/pointcloud/cloud /back_camera/camera/color/image_raw /back_camera/camera/depth/image_raw /back_camera/camera/pointcloud/cloud

这里有个细节特别值得留意:namespace设置为front_camera后,话题名会自动带上namespace前缀,而frame_id则单独设置为front_camera_link。这两个概念不能混淆。namespace决定了话题路径,frame_id决定了TF树里的坐标系名称。在Rviz2里查看点云时,需要把Fixed Frame切换成front_camera_link才能正常显示这台相机的数据,切换到back_camera_link则显示另一台。

4.4 多相机同时可视化的验证方法

多相机配置完成后,建议通过Rviz2来验证是否真的“两路都通了”。在Rviz2中同时添加两个PointCloud2显示组件,一个选择/front_camera/camera/pointcloud/cloud,另一个选择/back_camera/camera/pointcloud/cloud。

这里有一个实操上的坑:当你同时显示两个不同坐标系的点云时,如果相机的TF变换没有发布,或者Fixed Frame设置不统一,两片点云会叠在一起,看起来就像一个点云,无法直观确认两路数据是否都正常。解决办法有几种:一种是在Rviz2里把Fixed Frame固定到map或者odom(前提是有TF树),另一种是简单粗暴地把两台相机的frame_id设置为同一个坐标系(但这样做会影响后续标定算法的准确度),还有一种是暂时把其中一路点云的颜色改成不同颜色来区分。

我的建议是,在纯验证阶段,先在Rviz2的Global Options里面,把Fixed Frame分别切换一次,分别确认每一路的数据都更新正常。这样能确保数据链路没有断。至于两路点云的空间变换关系,那是后续要做相机标定时才需要考虑的问题。

4.5 多设备模式下的常见参数坑

在实际多设备配置中,有几个参数特别容易踩坑,我挨个说一下。

第一个是pointcloud_qos。ROS2的QoS策略如果设置不一致,订阅方和发布方之间可能完全收不到数据,而且不会有任何报错。在单相机场景下,orbbec_camera默认的QoS可能正好能被某些订阅者接收;但多相机同时启动时,资源占用增加,QoS不匹配的问题更容易暴露。表现为Rviz2里点云组件一直转圈但不出数据。这时候把点云话题的QoS改为SENSOR_DATA(即Best Effort + 大队列长度),基本能解决。

第二个是enable_colored_pointcloud。这个参数在多相机模式下要慎重开启,因为它需要同步彩色图和深度图并进行像素级对齐,极其消耗CPU。我实际测过,在四相机配置中全部开启彩色点云,CPU占用会直接过半,而且帧率明显下降。多数情况下,只开启普通点云就够了,颜色信息可以单独使用彩色图话题获取,不需要在点云里带颜色。

第三个是sync_mode。多相机同时启动时,各台相机的帧时序是独立的,如果需要多相机之间的深度图或点云在时间上对齐(例如做点云融合),需要在SDK层面开启多设备同步模式(硬件同步)。orbbec_camera中提供了相关参数,但使用硬件同步需要相机支持并连接同步线缆。如果只靠软件时间戳对齐,误差会在几十毫秒级,这对高速运动的物体来说会导致明显的点云错位。

5. 实际部署中的常见问题与排查清单

这部分把我在实际部署里遇到过的、以及社群朋友反馈过的高频问题整理了一下。这些问题不成系统,但每一个都真实存在,值得留个备忘。

5.1 节点能启动但话题里没有数据

这个现象很经典:节点起来了,进程也没崩,ros2 topic echo去看话题却什么都没有。最可能的原因是QoS不匹配。我的排查顺序是:先在OrbbecViewer里确认相机有画面输出,排除硬件问题;再执行ros2 topic info /camera/color/image_raw -v查看发布端的QoS设置;然后检查订阅端(比如Rviz2)使用的QoS是不是Reliable而发布端是Best Effort,导致收不到。

针对这个情况,一个快速验证方法是启动一个简易的订阅脚本,显式指定sensor_dataQoS:

rclpy.init() node = rclpy.create_node('qos_test') sub = node.create_subscription( Image, '/front_camera/camera/color/image_raw', callback, qos_profile=QoSProfile(depth=10, reliability=QoSReliabilityPolicy.BEST_EFFORT) )

能收到数据,基本就是把QoS调整一下就行。这个问题的排查思路对所有基于DDS的传感器接入场景都适用。

5.2 USB带宽不足导致画面撕裂或帧率下降

多相机跑起来后,如果出现彩色图、深度图不同步,或者Rviz2中点云跳变、闪烁,最大的嫌疑就是USB带宽不够。排查方法分两种:软件层看帧率,在ros2 topic hz /front_camera/camera/depth/image_raw查看实际发布频率,如果远低于配置的FPS比如配置的30但实际只有10几帧,就是带宽瓶颈了;硬件层用lsusb -t看多个设备是否挂在同一个USB控制器下。

解决方案从低到高有几种:降低分辨率或帧率,这是成本最低的;将不同相机分散到不同的USB控制器(提高硬件成本);开启图像压缩选项,如果相机支持的话,但实时性要求高的场景慎用。

5.3 编译orbbec_ros2时提示找不到依赖

编译时遇到Could not find a package configuration file provided by "orbbec_camera"之类的错误,多数是环境没有source正确。还有一个很常见的错误是rosdep没有安装完整。处理方式是:

sudo apt install python3-rosdep python3-colcon-common-extensions

然后确认/opt/ros/humble/setup.bash和~/orbbec_ws/install/setup.bash两次source都执行了。如果是在IDE里编译,还要确认IDE使用的shell环境有没有继承.bashrc。

5.4 多相机frame_id冲突导致TF树错误

这属于一个相对隐蔽的问题。如果多个相机节点都默认使用camera_link作为frame_id,那么在多相机启动后,TF树里会出现多个同名的坐标系,导致依赖TF的下游模块(比如导航、避障)出现坐标系错乱。目前orbbec_camera支持通过参数设置frame_id,多设备配置时务必给每台相机单独设置frame_id,这是第一批要改的参数,不要等出了问题再回来看。

5.5 ROS2通信性能下降的综合排查建议

如果多相机话题数据量很大,DDS的默认配置可能造成吞吐量瓶颈。我的经验是可以做三件事:将RMW实现切换为rmw_cyclonedds_cpp,在某些场景下吞吐性能更好;增大系统网络缓冲区,修改/etc/sysctl.conf中的net.core.rmem_max和net.core.wmem_max;避免在同一台机器上同时运行多个重CPU负载的节点,尤其是点云处理和图像显示主节点,尽量使用异步的回调方式减少阻塞。

这里多说一句关于ROS2回调机制的注意事项。多个相机话题以高频回调同时到达时,如果全部订阅在一个节点中且没有合理分配CallbackGroup,图像回调之间会相互阻塞,导致处理延迟。多传感器融合节点建议为每个图像话题单独创建ReentrantCallbackGroup,这是ROS2多数据流应用的一个基础优化手段。

6. 从部署到工程落地的几条经验

文章最后,分享一些这个项目在工程落地层面的经验,都是我实际过程中摸索出来的。

第一,部署OrbbecSDK深度相机到ROS2时,建议从一开始就把设备序列号、话题命名、frame_id命名规范定好,做成配置文件统一管理。不然后期扩展相机数量时,改代码的成本会非常高。而且规范化的命名对下游做多传感器融合、录制数据集、调试算法都有很大好处。

第二,不要过度依赖可视化验证。Rviz2能看到点云不代表数据质量没问题。我在做机械臂抓取项目时,曾经因为深度图里有一圈边缘噪点,导致抓取位姿计算偶尔失败。这种问题在Rviz2里看整体点云根本发现不了,需要单独对深度图像的像素值分布做统计。建议部署阶段就写一个简单的数据质量检查脚本,定期统计深度图的无效像素比例、点云噪声水平等。

第三,多设备场景下,相机的物理安装位置和朝向要提前考虑TF配置。相机的frame_id虽然可以随便取,但最好跟实际安装位置对应,比如front_camera_link、rear_camera_link。这样后续做相机外参标定时,配置关系一目了然。

OrbbecSDK + ROS2的部署这条路,说简单确实简单,说复杂也确实有很多细节。核心思路就是把逐层问题拆开:先确认硬件、再确认SDK、最后确认ROS2 wrapper,逐层定位,会省掉无数时间。希望这篇文章能帮正在折腾深度相机的朋友少走点弯路。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 1:27:28

ADXL355高精度加速度计寄存器配置与工业级数据采集实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 1:26:05

FPGA实战:基于XC7A50T从零打造LED控制器

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 1:25:41

PCB过孔工艺全解析:通孔、盲孔、埋孔选型与成本控制指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 1:24:11

XC6206P332MR LDO芯片详解:从丝印识别到应用选型

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 1:23:44

PADS Layout导出DXF保姆级教程:从图层映射到AutoCAD兼容性全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 1:23:33

庐山派K230开发板实战:CanMV下YOLO目标检测从模型转换到部署

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华