1. 项目概述:从零打造一个会自己收拾桌面的AI机器人

最近在工作室里,看着桌面上永远理不清的线材、工具和喝了一半的咖啡杯,我就在想,要是能有个小助手帮我自动整理就好了。这个念头催生了今天要分享的项目:一个基于SOARM101机械臂和LROBOT移动底盘的桌面清洁AI机器人。这不仅仅是一个简单的“玩具”,而是一个融合了计算机视觉、机器人运动控制和端到端机器学习训练的完整系统。它能识别散落在桌面上的常见物品,比如键盘、鼠标、水杯、书本,然后规划路径,用机械臂精准抓取,并将其归类放置到指定的收纳区域。

这个项目非常适合对机器人、嵌入式AI和自动化感兴趣的开发者、学生或极客。无论你是想深入学习ROS2(机器人操作系统)的实际应用,还是想亲手搭建一个能解决实际生活小麻烦的智能体,这个从硬件组装、环境配置、模型训练到最终部署的“A-Z”全流程指南,都能给你提供一条清晰的路径。整个过程涉及的核心技术点包括:Ubuntu与ROS2 Humble的環境搭建、Python与OpenCV的图像处理、YOLOv8目标检测模型的训练与部署、以及通过MoveIt 2和导航2(Nav2)实现机械臂与移动底盘的协同控制。接下来,我会拆解每一个环节,分享其中踩过的坑和收获的经验。

2. 硬件选型与系统架构设计思路

为什么选择SOARM101和LROBOT这套组合?这是项目成功的基石。SOARM101是一款六自由度桌面级机械臂,开源程度高,社区支持好,并且原生支持ROS2。它的负载、精度和重复定位精度足以应对桌面物品抓取的需求。LROBOT则是一个两轮差速驱动的移动底盘,同样具备完善的ROS2驱动包,可以轻松实现SLAM建图和路径规划。将两者结合,就构成了一个具备“手”(操作)和“脚”(移动)的完整机器人平台。

2.1 核心硬件清单与功能考量

在项目启动前,需要准备好所有硬件。除了机械臂和移动底盘,一些关键的辅助部件决定了系统的可靠性和易用性。

  • 主控制器 :我选用的是NVIDIA Jetson Orin Nano。它的算力足以在本地实时运行YOLOv8目标检测模型,同时处理ROS2的多节点通信。相比将图像传回PC处理,边缘计算方案延迟更低,系统更独立。如果预算有限,Jetson Nano 4GB也是一个可行的起点,但模型可能需要选用更轻量的版本。
  • 视觉传感器 :采用Intel RealSense D435i深度相机。选择它有两个主要原因:一是提供彩色图像和对应的深度信息,这对于计算物品的三维位置(抓取点)至关重要;二是其ROS2驱动成熟稳定,能直接发布 /camera/color/image_raw /camera/aligned_depth_to_color/image_raw 等标准话题。
  • 末端执行器 :SOARM101标配的夹爪可能力度不足。我更换了一款基于舵机控制的平行夹爪,并为其编写了简单的ROS2动作服务器,以便通过话题控制开合角度和力度,适应抓取不同材质和形状的物品。
  • 其他 :可靠的12V/5A直流电源、为整个系统供电的电源分配板、各种长度的USB3.0数据线和杜邦线,以及一个用于固定相机和主控的轻量化支架。

这套架构的核心思想是“感知-决策-执行”的闭环。深度相机作为眼睛,持续感知桌面环境;Jetson作为大脑,运行视觉检测和决策程序;ROS2作为神经系统,协调移动底盘(LROBOT)进行导航,以及机械臂(SOARM101)执行抓取和放置动作。

2.2 软件栈与通信框架设计

软件层面,我们构建了一个分层、解耦的系统,这能极大提高开发效率和系统稳定性。

操作系统层 :在Jetson Orin Nano上安装Ubuntu 22.04 LTS,这是ROS2 Humble的官方推荐系统。务必使用NVIDIA提供的JetPack SDK镜像,它包含了优化的CUDA、cuDNN等驱动,为后续的AI推理提供硬件加速。

中间件层 :ROS2 Humble是绝对的“中枢”。它采用基于DDS的通信机制,比ROS1更稳定、更安全。我们主要利用其两种通信模式:

  1. 话题(Topic) :用于流式、单向数据传输。例如,相机节点发布图像话题,视觉处理节点订阅并处理,然后发布检测结果话题。
  2. 动作(Action) :用于需要长时间运行、可抢占、有反馈的任务。例如,“导航到某个坐标点”、“执行抓取动作”都被设计为动作,方便监控状态和处理中断。

功能节点层 :这是我们的核心业务逻辑,规划了以下几个关键节点:

  • camera_driver_node :负责驱动RealSense相机,发布图像和深度信息。
  • object_detection_node :订阅图像,运行YOLOv8模型,输出物品的类别和二维边界框,并结合深度图计算三维空间坐标。
  • task_planner_node :决策中枢。它接收检测结果,根据物品类型(如“水杯”放到杯垫区,“书本”放到书架区)查询预设的放置点坐标,然后依次调用导航和抓取动作。
  • navigation_client_node :封装与LROBOT底盘Nav2堆栈的交互,向 /navigate_to_pose 动作服务器发送目标点。
  • arm_controller_node :封装与SOARM101机械臂MoveIt 2的交互,规划抓取路径、控制夹爪。

注意 :在ROS2中,节点的功能应尽可能单一。不要试图创建一个“全能”节点,这会导致代码臃肿且难以调试。清晰的节点划分使得你可以单独测试视觉、单独测试导航,大大降低了集成复杂度。

3. 开发环境搭建与基础功能配置

这是最考验耐心的一步,一个干净、正确的环境能避免后续无数诡异的问题。我强烈建议在SD卡或SSD上为Jetson安装完系统后,首先做一次完整的系统更新和备份。

3.1 ROS2 Humble与MoveIt 2安装实录

在Ubuntu 22.04上安装ROS2 Humble,官方教程很详细,但有几个细节容易出错。

# 1. 设置语言环境,确保是UTF-8
sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

# 2. 添加ROS2软件源
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y
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

# 3. 安装ROS2桌面版(包含GUI工具)和MoveIt 2
sudo apt update
sudo apt install ros-humble-desktop python3-colcon-common-extensions ros-humble-moveit -y

安装完成后,务必在 ~/.bashrc 文件末尾添加ROS2的环境变量:

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

接下来,需要为SOARM101机械臂配置MoveIt 2。通常,机械臂厂商会提供URDF(统一机器人描述格式)文件和MoveIt配置包。如果没有,你需要使用 moveit_setup_assistant 工具手动生成。这个过程比较繁琐,关键点在于:

  1. 正确导入URDF模型。
  2. 仔细定义每个关节的运动学群组(Planning Group),特别是夹爪部分。
  3. 设置好自碰撞和场景碰撞矩阵。
  4. 生成SRDF(语义机器人描述格式)文件和启动配置。

生成的配置包需要放入你的工作空间(例如 ~/ros2_ws/src )中,然后用 colcon build 编译。编译时如果遇到关于 orocos_kdl Eigen 的报错,通常是缺少某些依赖,根据错误信息用 apt 安装即可。

3.2 LROBOT底盘与RealSense相机驱动集成

LROBOT的驱动通常以一个ROS2包的形式提供。将其克隆到你的工作空间 src 目录下。在编译前,需要检查其 package.xml CMakeLists.txt ,确保依赖项都已安装。常见的依赖有 nav2_bringup , slam_toolbox , robot_localization 等。编译成功后,通过启动文件加载底盘驱动和Nav2导航栈。

对于Intel RealSense D435i,安装官方ROS2驱动是最稳妥的:

sudo apt install ros-humble-realsense2-camera

安装后,你可以通过一个启动命令来测试相机:

ros2 launch realsense2_camera rs_launch.py

然后使用 rqt_image_view 工具查看 /camera/color/image_raw 话题,确保图像流正常。 这里有一个关键步骤 :为了后续方便地获取与彩色图像对齐的深度图,你需要在启动文件中启用对齐滤波。这可以通过在启动时设置参数 align_depth.enable:=true 来实现,这样发布的深度图话题 /camera/aligned_depth_to_color/image_raw 就和彩色图像像素一一对应了,省去了自己写代码做坐标转换的麻烦。

3.3 工作空间与项目结构初始化

良好的项目结构是团队协作和个人维护的保障。我建议采用如下结构:

~/desk_cleaner_robot/
├── ros2_ws/                 # ROS2工作空间
│   ├── src/
│   │   ├── desk_cleaner_bringup/    # 启动和配置文件
│   │   ├── desk_cleaner_description/ # 机器人URDF模型(整合了机械臂和底盘)
│   │   ├── desk_cleaner_moveit/     # MoveIt 2配置包
│   │   ├── desk_cleaner_navigation/ # Nav2配置和地图
│   │   ├── desk_cleaner_vision/     # 视觉检测节点
│   │   └── desk_cleaner_task/       # 任务规划主节点
│   ├── build/
│   ├── install/
│   └── log/
├── training_data/           # YOLO训练数据集
│   ├── images/
│   └── labels/
├── models/                  # 训练好的YOLO模型权重
└── scripts/                 # 一些有用的工具脚本

使用 colcon 构建工具。在 ros2_ws 目录下,每次修改代码后运行 colcon build --symlink-install --symlink-install 参数允许你在 install 目录中创建符号链接,而不是复制文件,这样你修改 src 下的Python脚本后无需重新编译即可生效,极大提升了开发效率。

4. 视觉感知系统的构建:YOLOv8训练与ROS2部署

视觉是机器人的眼睛。我们的目标是训练一个能精准识别桌面杂物(如键盘、鼠标、手机、水杯、遥控器、书本)的YOLOv8模型,并将其集成到ROS2节点中,实时输出物品的3D位置。

4.1 数据集准备与标注实战技巧

数据质量决定模型上限。由于是特定桌面场景,通用数据集(如COCO)的精度往往不够,必须自定义数据集。

数据采集 :将RealSense相机固定在机器人上(或一个临时位置),从多个角度、不同光照条件下拍摄桌面照片。建议采集500-1000张原始图像。为了增加数据多样性,可以在图片中加入一些轻微的旋转、缩放,或者调整亮度、对比度(数据增强可以后续在代码中做,但原始数据尽量丰富)。

数据标注 :使用 labelImg 或更现代的 CVAT 工具进行标注。标注格式选择YOLO格式( .txt 文件)。每个文本文件对应一张图片,每行代表一个物体,格式为: <class_id> <x_center> <y_center> <width> <height> ,所有坐标都是相对于图片宽度和高度的归一化值(0到1之间)。

实操心得 :标注时务必保持类别的一致性和边界框的精确性。对于“水杯”这类物体,如果把手可见,有些人会标注整个杯子,有些人会忽略把手。我建议统一标注包括把手在内的最小外接矩形。同时,创建一个清晰的 classes.txt 文件,按顺序列出所有类别,这个顺序必须与标注文件中的 class_id 严格对应。

数据集划分 :按8:1:1的比例将数据随机分为训练集、验证集和测试集。目录结构如下:

training_data/
├── images/
│   ├── train/       # 训练图片
│   ├── val/         # 验证图片
│   └── test/        # 测试图片(可选)
└── labels/
    ├── train/       # 训练标签
    ├── val/         # 验证标签
    └── test/        # 测试标签(可选)

还需要创建一个YOLO格式的数据配置文件 desk_items.yaml

path: /home/yourname/desk_cleaner_robot/training_data  # 数据集根目录
train: images/train  # 训练集相对路径
val: images/val      # 验证集相对路径

# 类别数量和名称
nc: 6  # 类别数,例如:键盘、鼠标、水杯、手机、书本、遥控器
names: ['keyboard', 'mouse', 'cup', 'phone', 'book', 'remote']

4.2 YOLOv8模型训练与优化策略

YOLOv8的易用性令人印象深刻。我们使用其Python接口进行训练。

首先安装Ultralytics包: pip install ultralytics 。然后,准备一个Python训练脚本 train_yolo.py

from ultralytics import YOLO

# 加载一个预训练模型,这里选择中等大小的 yolov8m.pt
model = YOLO('yolov8m.pt')

# 开始训练
results = model.train(
    data='/path/to/your/desk_items.yaml',
    epochs=100,               # 训练轮数,根据数据集大小调整
    imgsz=640,                # 输入图像尺寸
    batch=16,                 # 批次大小,取决于GPU显存
    device='0',               # 使用GPU 0,如果是Jetson,可能是 'cuda:0'
    workers=4,                # 数据加载线程数
    project='desk_cleaner',   # 项目名称
    name='yolov8m_train',     # 实验名称
    save_period=10,           # 每10轮保存一次检查点
    pretrained=True           # 使用预训练权重
)

训练过程会在 desk_cleaner/yolov8m_train 目录下生成所有结果,包括最终的权重文件 best.pt last.pt 关键优化点

  1. 学习率 :如果训练损失下降很慢或震荡,可以尝试减小 lr0 (初始学习率)。YOLOv8有自动调整学习率的功能,但手动微调有时效果更好。
  2. 数据增强 :YOLOv8默认启用了Mosaic、MixUp等增强。对于桌面场景,可以增加 hsv_h (色调)、 hsv_s (饱和度)的增强幅度,以模拟不同光照。但 hsv_v (明度)增强要谨慎,避免产生不真实的过亮或过暗图像。
  3. 早停(Early Stopping) :设置 patience=20 ,如果验证集指标在20个epoch内没有提升,则自动停止训练,防止过拟合。

训练完成后,使用验证集评估模型: model.val() ,重点关注 mAP50-95 (平均精度)和每个类别的精确率(Precision)、召回率(Recall)。如果某个类别(比如“遥控器”)的召回率很低,说明数据集中该类别样本不足或标注质量不高,需要针对性补充数据。

4.3 将模型集成到ROS2节点并计算3D坐标

训练好的 best.pt 需要被一个ROS2节点调用。我们创建 desk_cleaner_vision 功能包,并在其中编写 object_detection_node.py

这个节点的核心工作流是:

  1. 订阅图像 :订阅 /camera/color/image_raw (彩色图)和 /camera/aligned_depth_to_color/image_raw (对齐的深度图)。
  2. 运行推理 :对彩色图进行预处理(缩放、归一化),送入YOLOv8模型进行推理。
  3. 发布结果 :将检测到的物体类别、2D边界框信息发布到一个自定义的消息话题,例如 /detected_objects
  4. 计算3D位置 :对于每个检测框,取其底部中心点的像素坐标 (u, v) 。查询同一位置的深度图,获取深度值 z (单位:米)。然后利用相机内参(可通过 /camera/color/camera_info 话题获得),将像素坐标 (u, v) 和深度 z 反投影到相机坐标系下的3D点 (x, y, z) 。这个 (x, y, z) 就是物体相对于相机的位置。
# 代码片段示例:反投影计算
def pixel_to_camera(u, v, z, fx, fy, cx, cy):
    """将像素坐标和深度转换为相机坐标系下的3D点"""
    x = (u - cx) * z / fx
    y = (v - cy) * z / fy
    return (x, y, z)

这里有一个 极其重要的细节 :深度相机测得的深度值 z ,是物体表面到相机成像平面的垂直距离。而我们计算出的 (x, y) 是基于针孔相机模型,在距离相机 z 米处的平面上,该像素点对应的实际物理位置。这个坐标还需要通过机器人底盘和机械臂的标定,转换到机器人基坐标系(base_link)下,才能用于导航和抓取规划。这个坐标转换涉及多个坐标系(camera_link -> base_link -> arm_base),通常通过ROS2的TF2库来管理和查询。

5. 机器人运动规划与控制:导航与抓取协同

视觉系统告诉我们“目标在哪里”,运动控制系统则要解决“如何过去并抓起来”的问题。这分为移动导航和机械臂运动规划两部分,通过任务规划节点串联。

5.1 LROBOT底盘与Nav2导航栈配置

Nav2是ROS2中强大的导航框架。我们需要为LROBOT配置它。关键步骤包括:

  1. 创建地图 :首先,让机器人在地图模式下,手动遥控(或通过 teleop 节点)在桌面区域内移动,同时运行SLAM算法(如 slam_toolbox )来构建地图。命令如下:

    ros2 launch slam_toolbox online_async_launch.py
    

    遥控机器人走遍所有可通行区域后,保存地图: ros2 run nav2_map_server map_saver_cli -f ~/ros2_ws/src/desk_cleaner_navigation/maps/my_desktop 。这会生成 my_desktop.pgm (地图图像)和 my_desktop.yaml (地图描述文件)。

  2. 配置Nav2参数 :Nav2的行为由大量参数文件控制。最重要的两个是:

    • nav2_params.yaml :全局参数,如代价地图插件、控制器、规划器、恢复行为的选择与参数。
    • tb3_nav2_config/ 下的各个yaml文件:针对机器人型号的细化配置。你需要根据LROBOT的实际尺寸(半径、轮廓)、传感器话题名称来修改这些文件。例如,在 local_costmap_params.yaml global_costmap_params.yaml 中,要正确设置 robot_base_frame (通常是 base_link )和 obstacle_layer observation_sources (例如,如果用了激光雷达,就配置scan话题)。
  3. 启动导航 :编写一个启动文件 bringup_launch.py ,依次启动:

    • 机器人状态发布者( robot_state_publisher
    • LROBOT底盘驱动节点
    • 地图服务器( map_server
    • 生命周期管理器( lifecycle_manager
    • AMCL定位节点(用于在地图中定位机器人)
    • Nav2核心节点( controller_server , planner_server 等)

启动后,通过RVIZ2可视化工具,可以看到地图、机器人位置、激光扫描点(如果有)、全局路径和局部路径。你可以使用RVIZ2的“2D Pose Estimate”按钮来初始化机器人的位置,然后用“2D Nav Goal”按钮指定目标点,机器人应该能自主规划并移动到该点。

5.2 SOARM101机械臂MoveIt 2运动规划与抓取动作

MoveIt 2负责机械臂的运动规划。我们之前已经生成了配置包。现在需要编写一个ROS2节点( arm_controller_node )来调用MoveIt 2的API,控制机械臂移动和抓取。

核心操作流程

  1. 连接到MoveIt 2 :使用 MoveGroupInterface 连接到我们为机械臂定义的规划组(planning group),例如 “arm” “gripper”
  2. 设置目标姿态 :视觉节点给出的物体3D坐标是相对于机器人基坐标的。我们需要将其转换为机械臂末端执行器(夹爪)的目标姿态(一个包含位置和方向的 Pose 消息)。这里的方向(四元数)需要根据抓取策略来设定。例如,垂直抓取水杯,末端姿态的Z轴可能朝下;水平抓取书本,末端姿态的X轴可能朝前。
  3. 规划与执行 :调用 move_group.setPoseTarget(target_pose) 设置目标,然后调用 move_group.plan() move_group.execute() 进行规划和执行。MoveIt 2会自动进行碰撞检测,并规划出一条无碰撞的运动轨迹。
  4. 控制夹爪 :抓取动作通常分解为:a) 移动到物体上方预抓取点;b) 直线下降到抓取点;c) 闭合夹爪;d) 抬起到运输高度。夹爪的控制通过另一个规划组 “gripper” 来实现,设置夹爪关节的目标位置即可控制其开合。
# 代码片段示例:控制夹爪
from moveit_msgs.msg import GripperTranslation
# ... 初始化 move_group_gripper ...
gripper_joint_positions = [0.02, 0.02]  # 闭合位置,具体值取决于你的夹爪
move_group_gripper.set_joint_value_target(gripper_joint_positions)
move_group_gripper.plan()
move_group_gripper.execute()

避坑技巧 :MoveIt 2的规划有时会失败,尤其是在空间狭窄或起点/终点姿态奇异时。在实践中,我增加了以下策略:

  1. 设置多个备选目标姿态 :如果垂直抓取规划失败,尝试稍微倾斜一个角度。
  2. 使用“位姿目标”而非“关节目标” :位姿目标给予规划器更多自由度。
  3. 调整规划时间 :增加 move_group.setPlanningTime(5.0) ,给规划器更多时间寻找解。
  4. 允许重规划 :设置 move_group.allowReplanning(True)

5.3 任务规划器:串联视觉、导航与机械臂

task_planner_node 是这个多节点系统的“指挥家”。它采用有限状态机(FSM)的设计模式,逻辑清晰,易于调试和扩展。

状态机的基本状态包括:

  • IDLE :空闲状态,等待启动命令。
  • SCANNING :控制机器人原地旋转(或移动到一个预定义的扫描点),同时视觉节点进行物体检测。收集所有检测到的物品及其位置。
  • PLANNING :对检测到的物品进行排序(例如,按距离、按优先级),并为每个物品生成一个任务序列: [导航到物品附近 -> 机械臂抓取物品 -> 导航到放置区 -> 机械臂放置物品]
  • EXECUTING_NAV :向 navigation_client_node 发送动作目标,并监控执行状态。
  • EXECUTING_PICK :物品抓取状态。调用 arm_controller_node 执行抓取动作序列。
  • EXECUTING_PLACE :物品放置状态。
  • ERROR :错误处理状态。

这个节点通过ROS2动作客户端与服务客户端,与导航、机械臂节点进行异步通信。例如,发送导航目标:

from geometry_msgs.msg import PoseStamped
from nav2_msgs.action import NavigateToPose

goal_msg = NavigateToPose.Goal()
goal_msg.pose.header.frame_id = ‘map’
goal_msg.pose.pose.position.x = target_x
goal_msg.pose.pose.position.y = target_y
goal_msg.pose.pose.orientation.w = 1.0  # 默认朝向

self._nav_action_client.send_goal_async(goal_msg, feedback_callback=self._nav_feedback_callback)

通过回调函数来接收动作的反馈(如当前状态、剩余距离)和最终结果(成功/失败),从而决定状态机的跳转。

6. 系统集成、调试与性能优化实录

当所有模块单独测试通过后,真正的挑战——系统集成开始了。问题往往出现在模块间的接口、时序和资源竞争上。

6.1 多节点启动与系统联调

我编写了一个顶层的启动文件 desk_cleaner.launch.py ,用于一键启动所有节点。启动顺序很重要:

  1. 首先启动底盘驱动、相机驱动和URDF模型发布。
  2. 接着启动Nav2相关节点和MoveIt 2节点。
  3. 最后启动我们的业务节点:视觉检测、任务规划、导航客户端、机械臂控制器。

使用 ros2 launch 命令启动后,通过 rqt_graph 查看节点和话题连接图,确保所有预期的连接都已建立。然后,在RVIZ2中加载机器人模型、地图、相机图像、检测框可视化等,进行可视化调试。

常见集成问题与解决

  • 问题1:TF变换缺失或时间不同步 。表现为在RVIZ2中看不到机器人模型,或者机械臂的位姿飘忽不定。
    • 排查 :运行 ros2 run tf2_tools view_frames 生成TF树图,检查 base_link , camera_link , arm_base 等关键坐标系之间的变换链是否完整。
    • 解决 :确保每个发布TF变换的节点(如机器人状态发布者、相机驱动)的时间戳是同步的。可以使用 use_sim_time 参数或在代码中使用 ros2 的时钟。
  • 问题2:动作服务器连接失败 。任务规划器无法调用导航或机械臂动作。
    • 排查 :使用 ros2 action list 查看动作服务器是否已启动。检查动作名称是否匹配。
    • 解决 :确保动作服务器节点先于客户端启动,并在代码中增加连接等待逻辑,例如使用 action_client.wait_for_server(timeout_sec=5.0)
  • 问题3:视觉检测延迟导致抓取位置不准 。机器人移动到地点时,物体可能已被移走,或者计算出的3D坐标是过时的。
    • 解决 :在抓取前,让机械臂先移动到物体上方的一个“观察点”,然后视觉节点再进行一次快速的“最终确认”检测,用最新的检测结果微调抓取位置。这增加了一个步骤,但大大提高了抓取成功率。

6.2 性能瓶颈分析与优化策略

在Jetson Orin Nano上运行整个系统,资源是紧张的。需要持续监控和优化。

  1. CPU/GPU/内存监控 :使用 htop , jetson_stats ( jtop ) 工具实时监控资源占用。发现视觉检测节点是GPU和CPU的大户。
  2. 视觉节点优化
    • 模型量化 :将训练好的YOLOv8模型从FP32精度转换为FP16甚至INT8精度,可以显著提升推理速度,几乎不影响精度。Ultralytics YOLOv8支持导出为TensorRT引擎,这是Jetson平台上的终极优化方案。
    • 图像降采样 :如果检测距离固定(如桌面),可以将相机分辨率从1280x720降低到640x480,大幅减少需要处理的数据量。
    • 推理频率控制 :不需要每帧图像都检测。可以设置为每5帧处理一帧(约10Hz),这对于缓慢移动的桌面机器人来说足够了。
  3. ROS2通信优化
    • 使用高效的消息类型 :对于图像,使用 sensor_msgs/msg/Image 的编码格式为 ‘rgb8’ ;对于检测结果,自定义紧凑的消息结构,避免嵌套过深的大数组。
    • 调整QoS策略 :对于相机图像,使用 SensorDataQoS (尽力保留最新数据);对于动作目标,使用 ReliableQoS (保证送达)。不恰当的QoS会导致数据丢失或延迟。
  4. 运动规划优化
    • 缓存规划结果 :对于重复性的动作,如“从A点抓取姿势回到运输高度”,如果环境没变,其运动轨迹是相同的。可以在第一次规划成功后缓存该轨迹,下次直接执行,节省规划时间。
    • 简化碰撞矩阵 :在MoveIt的规划场景中,精确计算所有连杆之间的碰撞非常耗时。可以适当简化机器人的碰撞几何体(用简单的包围盒代替复杂模型),并忽略一些永远不可能碰撞的连杆对。

6.3 可靠性提升与异常处理机制

一个成熟的系统必须能处理异常。我们为任务规划器的状态机增加了丰富的错误处理分支。

  • 导航失败 :如果导航动作返回失败(例如,目标点被阻挡、规划超时),状态机不应直接崩溃。可以尝试:a) 重新规划到同一目标;b) 规划到一个附近的备用目标点;c) 记录该物品为“暂时不可达”,跳过它处理下一个。
  • 抓取失败 :机械臂抓取动作可能因为物体滑脱、位置偏差而失败。通过在夹爪上安装一个简单的触觉传感器(或通过电机电流检测夹爪是否空载)来判断抓取是否成功。如果失败,则尝试:a) 调整抓取位置后重试;b) 换一种抓取姿态(如从顶部抓改为侧面夹);c) 如果多次失败,则标记该物体需要人工干预。
  • 系统状态监控 :增加一个“心跳”机制。每个关键节点定期发布一个“活跃”消息。任务规划器监控这些心跳,如果某个节点长时间无响应,则触发系统暂停并报警。

经过这些优化和加固,我的桌面清洁机器人已经可以稳定地完成从识别、导航到抓取、放置的全流程。虽然速度还不算快,处理一个物品可能需要一两分钟,但看着它有条不紊地把杂乱的桌面归位,那种成就感远超项目本身的技术价值。这个项目就像一个微缩版的智能仓储机器人,其中涉及的模块化设计、系统集成思维和问题排查方法,对于从事更复杂机器人系统的开发有着直接的借鉴意义。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐