第二章:数据采集基础——传感器选型与硬件平台搭建
大家好,我是你们的老朋友。今天咱们聊聊数据采集这个环节。说实话,很多做具身智能的朋友,一上来就急着调算法、训模型,结果数据质量不行,后面全白干。我踩过这个坑,所以这一章,咱们把传感器选型和硬件平台搭建讲透。
2.1 传感器选型:你得知道“看、摸、动”分别用什么
数据采集,说白了就是给机器人装“眼睛”、“皮肤”和“平衡感”。这三样东西,分别对应RGB-D相机、触觉传感器和IMU。我一个个说。
2.1.1 RGB-D相机:机器人的“眼睛”
RGB-D相机能同时输出彩色图像和深度图。你想想看,机器人要抓杯子,光知道颜色没用,还得知道杯子离自己多远、形状什么样。
主流方案对比:
| 传感器型号 | 深度原理 | 有效距离 | 典型场景 |
|---|---|---|---|
| Intel RealSense D435 | 双目立体视觉 | 0.1m - 10m | 桌面抓取、室内导航 |
| Microsoft Azure Kinect | ToF(飞行时间) | 0.5m - 5.46m | 人体姿态、大场景 |
| Orbbec Astra Pro | 结构光 | 0.4m - 8m | 低成本方案、教育 |
2.1.2 触觉传感器:让机器人“摸得到”
视觉再强,也解决不了“抓鸡蛋”和“抓铁块”的区别。触觉传感器就是干这个的。
目前主流的有两类:
- 电阻式/电容式阵列传感器:比如GelSight、Tactile。能输出高分辨率压力分布图,适合精细操作。
- 单点力传感器:比如ATI Mini45。装在夹爪根部,测的是整体夹持力,适合重载场景。
2.1.3 IMU:机器人的“平衡感”
IMU(惯性测量单元)提供加速度和角速度。你可能觉得它不重要,但实际上一旦机械臂快速运动,底盘晃动,RGB-D的数据就全飘了。IMU就是用来做运动补偿的。
选型要点:
- 消费级(如MPU6050):便宜,但零偏大,适合静态场景。
- 工业级(如ADIS16470):贵,但温漂小,适合动态采集。
我个人建议,做数据采集至少用工业级。数据质量差,后面标定、训练全白费。
2.2 数据采集硬件平台搭建
传感器选好了,怎么装到一起?这里我画了一张图,帮你理清整体架构。
2.2.1 机械臂 + 夹爪:动作执行的核心
机械臂选型,我主要看两个参数:负载和重复定位精度。
- 负载:夹爪+目标物体的总重量,留出30%余量。比如抓一个500g的杯子,夹爪200g,那机械臂负载至少1kg。
- 重复定位精度:做数据采集,至少±0.1mm。精度太低,动作复现时误差会累积。
夹爪方面,二指夹爪最常用,结构简单、控制方便。但如果你要抓异形件,可以考虑三指或吸盘。
2.2.2 移动底盘:让机器人“走起来”
移动底盘分两种:
- 轮式底盘:速度快、控制简单,适合室内平地。
- 履带底盘:越障能力强,适合复杂地形。
数据采集时,底盘主要提供里程计信息(位置、速度)。我建议底盘自带编码器,否则你得额外装轮式里程计。
2.2.3 硬件集成与同步
所有硬件装到一起,最头疼的是时间同步。RGB-D数据30fps,IMU数据200Hz,机械臂状态100Hz。如果时间对不齐,后面动作复现就是“鸡同鸭讲”。
我的做法是:
- 所有传感器通过ROS的
tf和message_filters做时间戳对齐。 - IMU和RGB-D用硬件触发线同步,精度能到微秒级。
- 工控机用实时内核(RT_PREEMPT),减少抖动。
rosbag record --split --duration=60,自动按时间分段存数据,避免单个bag文件太大。
2.3 数据采集流程示例
说了这么多,咱们看一段实际代码。假设你有一个UR5机械臂、一个D435相机、一个二指夹爪。采集“抓取杯子”的数据,流程如下:
# 伪代码:数据采集主循环
import rospy
from sensor_msgs.msg import JointState, Image
from geometry_msgs.msg import Pose
def collect_grasp_data():
rospy.init_node('data_collector')
# 初始化传感器
camera = RGBDCamera() # 封装D435驱动
gripper = Gripper() # 封装夹爪控制
arm = UR5Arm() # 封装机械臂控制
# 记录数据
bag = rosbag.Bag('grasp_data.bag', 'w')
for i in range(100): # 采集100次
# 1. 移动到预抓取位置
arm.move_to(Pose(x=0.3, y=0.0, z=0.2))
# 2. 打开夹爪
gripper.open()
# 3. 记录当前状态
joint_states = arm.get_joint_states()
camera_data = camera.get_rgbd()
# 4. 执行抓取
arm.move_to(Pose(x=0.3, y=0.0, z=0.05))
gripper.close()
# 5. 记录抓取后状态
post_grasp_pose = arm.get_end_effector_pose()
force = gripper.get_force()
# 6. 写入bag
bag.write('/joint_states', joint_states)
bag.write('/camera/rgb', camera_data[0])
bag.write('/camera/depth', camera_data[1])
bag.write('/gripper/force', force)
# 7. 复位
arm.move_to_home()
bag.close()
2.4 我的避坑清单
最后,分享几个我踩过的坑,你遇到了直接绕开:
- 供电不足:机械臂+工控机+传感器一起上,普通USB口带不动。我建议用独立电源或POE供电。
- 线缆缠绕:机械臂转几圈,线就缠死了。用螺旋电缆或无线方案(如WiFi传RGB-D数据)。
- 数据冗余:别什么都录。只录你需要的topic,否则一个bag文件几十GB,处理起来想哭。
好了,这一章的内容就是这些。传感器选型、硬件搭建、时间同步,这三件事做好了,数据采集就成功了一半。剩下的,就是动手去试了。