7,832
社区成员
发帖
与我相关
我的任务
分享适用场景:基于犀牛派 X1 边缘计算平台,控制中科深谷开源六轴机械臂,完成 Diffusion Policy 的采集—训练—部署—真机闭环全流程。
| 类别 | 设备 | 数量 | 说明 |
|---|---|---|---|
| 计算平台 | 犀牛派 X1 | 1 | QCS8550,48 TOPS INT8,16GB LPDDR5X,板载 CAN 接口 |
| 从动机械臂 | 中科深谷六轴 3kg 机械臂 | 1 | 含控制器、稳压电源(48V)、CAN 通信线 |
| 主控臂(可选) | U-Arm(3D 打印) | 1 | 需 6 个 45 元舵机 + 3D 打印结构件 |
| 摄像头 | USB 摄像头或 CSI 摄像头 | 2~3 | 建议一路全局视角 + 一路腕部视角,640×480@30fps 即可 |
| CAN 适配线 | 犀牛派 40PIN 转 CAN 接线 | 1 | 犀牛派板载 CAN,无需额外 USB-CAN 适配器 |
| 电源 | DC 12V 5A | 1 | 犀牛派 X1 供电 |
| 网线/USB | 用于调试和文件传输 |
若干 |
中科深谷机械臂已完成零点标定,各关节 CAN ID 已按手册第 30 页配置(Joint 1-3 → CAN-B,ID 1-3;Joint 4-6 → CAN-A,ID 4-6)
犀牛派 X1 已刷好 Ubuntu 22.04 系统(推荐使用纯 Ubuntu 版本,便于 ROS2 部署)
一台 PC(Ubuntu 22.04)用于模型训练,配备 NVIDIA GPU
bash
# 基础环境
conda create -n lerobot python=3.10 -y
conda activate lerobot
# LeRobot 核心
pip install lerobot
# 扩散策略训练依赖
pip install torch torchvision diffusers accelerate wandb
# 数据处理
pip install h5py pandas opencv-python
# ROS2 数据转换(如需从 ROS bag 转 LeRobot 格式)
pip install rosbags
LeRobot 官方提供了 Diffusion Policy 在真实数据集上的完整训练示例,可作为起点。
# 系统级
sudo apt update
sudo apt install -y python3-pip python3-colcon-common-extensions can-utils
# Python 依赖
pip3 install torch --index-url https://download.pytorch.org/whl/cpu
pip3 install opencv-python numpy python-can
# ROS2(如使用 Ubuntu 22.04 + ROS2 Humble)
sudo apt install -y ros-humble-ros-base ros-humble-cv-bridge
CAN 通信使用 Python 的 python-can 库,配合 SocketCAN 接口即可直接操作板载 CAN。
犀牛派 X1 的核心接口包括 USB 3.0 ×4、CAN、SPI、I2C、PWM、UART、LAN/WAN 等,以及 3 路 CSI 摄像头接口。
关键接线步骤:
CAN 接线:从中科深谷机械臂控制器的 CAN 输出端,连接到犀牛派 X1 的板载 CAN 接口(需确认 CAN_H/CAN_L 引脚对应关系)。中科深谷机械臂采用双 CAN 总线,Joint 1-3 走 CAN-B,Joint 4-6 走 CAN-A,你需要将两路 CAN 分别接入。
摄像头:将全局视角摄像头通过 USB 接入犀牛派,腕部摄像头可通过 CSI 接口接入(需确认犀牛派 CSI 接口的排线兼容性)。
网络:通过 LAN 口或 WiFi 7 接入局域网,用于远程调试和数据传输。
供电:犀牛派使用 DC 12V 5A 独立供电;机械臂使用 48V 稳压电源独立供电。
3.2 CAN 接口启用
# 查看 CAN 设备
ip -br link
# 启用 can0,比特率 1000000(中科深谷驱动器 CAN 波特率为 1000Kbps)
sudo ip link set can0 down 2>/dev/null
sudo ip link set can0 type can bitrate 1000000
sudo ip link set can0 up
# 验证
ip -details link show can0
中科深谷技术手册第 21 页明确:CAN 通信波特率为 1000Kbps,暂时不能修改。因此必须将犀牛派 CAN 接口配置为相同的比特率。
部署端架构:
┌─────────────────────────────────────┐
│ ROS2 节点 │
│ ├── 摄像头采集节点 (usb_cam/csi) │
│ ├── 模型推理节点 (ONNX Runtime) │
│ └── CAN 控制节点 (python-can) │
│ │
│ 数据流:摄像头 → 推理 → 关节角度 │
│ → CAN 帧 → 机械臂 │
└─────────────────────────────────────┘
犀牛派 X1 支持 AidLux 融合系统(Android 13 + Ubuntu 22.04)或纯 Ubuntu 22.04 系统。强烈建议刷纯 Ubuntu 22.04,避免 Android 层引入的兼容性问题。
刷机步骤参考官方文档:
下载犀牛派 X1 的 LE 系统镜像
使用 USB Type-C 连接设备,执行 adb shell reboot edl 切换刷机模式
在 QFIL 中选择 9008 端口,加载镜像文件
点击 Download,等待约 5 分钟后出现 "successful"
Diffusion Policy 需要以 10Hz 以上的频率输出动作。犀牛派 X1 的 CPU 主频最高 3.2GHz,配合 48 TOPS NPU,具备实时推理能力。
# CPU 调频为性能模式
sudo cpupower frequency-set -g performance
# 关闭不需要的后台服务
sudo systemctl disable bluetooth
# CAN 接口启用后,使用小批量非阻塞读写
# 在 Python 中使用 can.Bus 的 receive(timeout=0) 避免阻塞
⚠️ CAN 通信关键点:中科深谷驱动器兼容 Elmo 的 CAN 简易通信指令。核心指令包括:MO(电机启用)、UM(运行模式设置)、PA(PTP 绝对目标位置)、SP(最大速度)、BG(启动运行)。发送位置指令前,必须先发送 MO 启用电机,再发送 UM 设置位置模式。
⚠️ 安全操作:机械臂上电后需等待至少 4 秒再发送控制指令。实验前必须安装防撞条,确保机械臂工作空间内无人员。做轨迹规划时,必须先确认目标位姿在机械臂工作空间内且不在奇异点。
⚠️ 模型量化风险:VLA/扩散策略模型从 PyTorch 导出为 ONNX 或 TensorRT 时,量化可能导致动作精度下降。建议先用 FP16 精度验证,确认效果后再尝试 INT8。
⚠️ 数据同步:采集数据时,图像和关节角度必须严格时间对齐。建议在同一个 ROS2 节点中同时采集图像和 CAN 关节角度,使用统一的时间戳。
# 将训练好的 Diffusion Policy 导出为 ONNX
import torch
from lerobot.common.policies.diffusion.modeling_diffusion import DiffusionPolicy
policy = DiffusionPolicy.from_pretrained("outputs/train/your_model")
policy.eval()
# 构造示例输入:图像 + 关节状态
dummy_image = torch.randn(1, 3, 480, 640)
dummy_state = torch.randn(1, 6)
torch.onnx.export(
policy,
(dummy_image, dummy_state),
"diffusion_policy.onnx",
opset_version=17,
input_names=["image", "state"],
output_names=["action"]
)
import can
import cv2
import numpy as np
import onnxruntime as ort
# 加载 ONNX 模型
session = ort.InferenceSession("diffusion_policy.onnx")
# 初始化 CAN 总线
bus = can.interface.Bus(channel='can0', bustype='socketcan', bitrate=1000000)
def send_joint_positions(angles):
"""将关节角度转换为中科深谷 CAN 指令"""
for i, angle in enumerate(angles):
joint_id = i + 1 # CAN ID 1-6
# 按中科深谷协议打包 PA 指令
# 具体数据格式参考技术手册第 4.2 节
msg = can.Message(
arbitration_id=joint_id,
data=pack_pa_command(angle),
is_extended_id=False
)
bus.send(msg)
def inference_loop():
cap = cv2.VideoCapture(0) # 全局摄像头
# 启用电机(首次运行)
enable_motors(bus)
while True:
ret, frame = cap.read()
if not ret:
continue
# 预处理图像
img = cv2.resize(frame, (640, 480))
img = img.transpose(2, 0, 1).astype(np.float32) / 255.0
img = np.expand_dims(img, 0)
# 读取当前关节角度(从 CAN 反馈)
current_state = read_joint_states(bus)
state = np.array(current_state, dtype=np.float32).reshape(1, -1)
# 模型推理
action = session.run(None, {"image": img, "state": state})[0]
# 发送到机械臂
send_joint_positions(action[0])
# 控制频率约 10Hz
cv2.waitKey(100)
if __name__ == "__main__":
inference_loop()

torchcodec 无法安装在犀牛派(ARM64)上安装 LeRobot 时,torchcodec 因 glibc/二进制兼容性问题无法安装,LeRobot 自动回退到 pyav 解码视频。
解决方案:这是已知的 ARM64 平台限制。有用户在 Jetson Orin(同为 ARM64)上遇到了完全相同的问题:模型在 x86_64 上正常,在 ARM64 上因视频解码后端不同(pyav vs torchcodec)导致推理输出错误动作。
在训练端统一使用 pyav 作为解码后端:既然犀牛派上只能用 pyav,那么在 PC 训练时也强制使用 pyav 解码,确保训练和推理的数据预处理一致。
验证解码一致性:检查 pyav 和 torchcodec 在色彩通道顺序(RGB vs BGR)、像素值范围(0-255 vs 0-1)、帧裁剪/缩放行为上是否存在差异。
如果 pyav 仍不可用,考虑在犀牛派上用 OpenCV 直接读摄像头(绕过 LeRobot 的视频解码层),自行构造模型输入。
在犀牛派上直接加载 PyTorch 模型,推理速度极慢或报错。
解决方案:犀牛派 X1 的 NPU(48 TOPS INT8)需要通过 QNN(Qualcomm Neural Processing SDK) 调用。标准流程是:PyTorch → ONNX → AIMO 平台一键转换为 QNN 格式 → 部署到 NPU。AIMO 平台是阿加犀提供的模型转换工具,可自动化完成量化与格式转换。