1360 字
7 分钟
用 PyBullet 模拟机械臂抓取:从视觉到动作
项目概述
这是一个智能机械臂抓取系统,在 PyBullet 物理仿真环境中控制 Franka Panda 7 自由度机械臂,实现从图像检测物体、自动规划抓取路径、并按不同风格整理桌面。
系统融合了三大技术:
- 计算机视觉:YOLO + CLIP 物体检测
- 强化学习:SAC / PPO / HER 算法
- 经典机器人学:逆运动学 + 任务规划
系统架构
图片输入 → 物体检测(YOLO+CLIP) → 场景重建(2D→3D) → 任务规划 → 抓取执行 ↓ PyBullet 物理仿真 ↓ Franka Panda 7-DOF 机械臂两大工作模式
模式 A:交互式抓取整理
- 加载一张桌面照片
- 检测照片中的物体(颜色、形状、位置)
- 在仿真环境中重建场景
- 机械臂自动抓取并按指定风格整理
六种整理风格:
- 按颜色分组
- 按大小排列
- 网格布局
- 排成直线
- 围成圆圈
- 堆叠
模式 B:强化学习训练
提供 Gymnasium 兼容的环境,训练 RL 智能体学习抓取技能。
多后端视觉检测
系统实现了四层检测,自动降级:
| 层级 | 方法 | 精度 | 速度 |
|---|---|---|---|
| 1 | YOLO + CLIP | 最高 | 较慢 |
| 2 | YOLO-only | 高 | 中 |
| 3 | CLIP-only | 中 | 中 |
| 4 | HSV 颜色检测 | 基础 | 最快 |
YOLO + CLIP 的工作流程:
# 1. YOLO 检测边界框boxes = yolo_model(image)
# 2. CLIP 对每个裁剪区域进行零样本分类for box in boxes: crop = image[box] color = clip_classify(crop, ["red", "blue", "green", "yellow"]) shape = clip_classify(crop, ["cube", "sphere", "cylinder"])自然语言命令解析(支持中英文):
"把红色方块放到左边" → action=move, color=red, shape=cube, position=left"grab the blue sphere" → action=grab, color=blue, shape=sphere抓取动作序列
每个抓取-放置动作包含 9 个步骤:
1. 移动到物体上方安全高度2. 打开夹爪3. 下降到抓取高度4. 关闭夹爪(带力限制)5. 提升到安全高度6. 移动到目标上方7. 下降到放置高度8. 打开夹爪(速度控制快速释放)9. 提升离开所有运动都通过逆运动学将末端执行器的笛卡尔坐标转换为 7 个关节的角度。
强化学习训练
环境设计
ReachEnv(到达任务)
- 观测空间:23 维(末端位置 + 速度 + 关节位置 + 速度 + 目标位置)
- 动作空间:4 维(dx, dy, dz, 夹爪)
- 奖励:负距离 + 成功奖励
PickAndPlaceEnv(抓取放置任务)
- 观测空间:25 维
- 分阶段奖励设计:
接近阶段:距离物体的负距离抓取阶段:夹爪闭合奖励提升阶段:物体高度奖励放置阶段:距离目标的负距离成功:+100 奖励
三种算法
SAC(Soft Actor-Critic)
# 自动温度调节alpha = learnable_parameterloss = -E[Q(s,a) + alpha * H(π)]# 双 Q 网络 + 软目标更新PPO(Proximal Policy Optimization)
# GAE 优势估计A = GAE(returns, values)# 裁剪目标函数loss = min(r*A, clip(r, 1-ε, 1+ε)*A)SAC + HER(Hindsight Experience Replay)
HER 的核心思想:即使没有达成目标,也可以把「实际到达的位置」当作「原本的目标」来学习:
# 原始经验experience = (s, a, r=-1, s', goal=original_goal)
# HER 替换(future 策略)her_experience = (s, a, r=+100, s', goal=actual_position)这让稀疏奖励任务变得更容易学习。
课程学习
CurriculumTrainer 实现了难度递增:
- 简单:物体在机械臂附近
- 中等:物体随机分布
- 困难:物体有遮挡和堆叠
当成功率超过阈值时自动升级难度。
性能数据
| 物体类型 | 抓取成功率 |
|---|---|
| 方块 | 95% |
| 圆柱 | 90% |
| 球体 | 88% |
| 物体数量 | 整理时间 |
|---|---|
| 4 个 | ~20 秒 |
| 8 个 | ~45 秒 |
场景持久化
检测到的场景可以保存为 JSON:
{ "objects": [ { "position": [0.5, 0.2, 0.45], "color": "red", "shape": "cube", "size": 0.03, "mass": 0.1, "friction": 0.5 } ]}支持精确重建场景,方便调试和复现。
工作空间约束
机械臂有严格的工作空间限制:
- X: [0.2, 0.8](前后)
- Y: [-0.4, 0.4](左右)
- Z: [0.42, 0.8](上下)
物体尺寸必须在 1.5cm ~ 3.2cm 之间才能被夹爪抓取(夹爪最大开口 8cm)。
技术栈
| 组件 | 技术 |
|---|---|
| 物理仿真 | PyBullet |
| RL 环境 | Gymnasium |
| 深度学习 | PyTorch |
| RL 算法 | SAC / PPO / SAC+HER |
| 物体检测 | YOLOv8 + CLIP |
| 视觉语言 | GPT-4o 适配器 |
| GUI | Tkinter |
| 配置 | PyYAML |
设计亮点
- 优雅降级:YOLO 装不了就用 CLIP,CLIP 也不行就用颜色检测,总能跑起来
- 中英双语:UI、日志、命令解析全部支持中英文
- 模块化设计:视觉、控制、规划、RL 各自独立,方便替换和扩展
- 场景快照:检测结果可序列化,支持保存/加载/复现
遇到的坑
- 逆运动学不唯一:7 自由度有冗余解,PyBullet 的 IK 有时给出奇怪的关节构型
- 夹爪力控制:力太小抓不住,力太大物体会被弹飞,需要反复调试
- 球体抓取:球体容易从夹爪中滑出,需要在接触点施加足够的摩擦力
- RL 训练不稳定:抓取任务的奖励很稀疏,HER 是解决这个问题的关键
项目地址:asl_ywh(Gitee)
做这个项目最深的体会:仿真环境里”看起来能抓”和”稳定能抓”之间隔着无数细节——IK 的冗余解、夹爪的力控、球体的摩擦力,每一项都要反复调。而 HER 让我第一次直观看到,同样的失败轨迹换个”目标”定义,就能变成有效经验。
用 PyBullet 模拟机械臂抓取:从视觉到动作
https://theywh.me/posts/pybullet-franka-grasping/