4. 传感器选型与配置:激光雷达、深度相机、IMU、里程计、足底力传感器
人形机器人导航,说白了就是让两条腿的机器知道自己在哪、要去哪、路上有没有坑。但这事比轮式机器人难多了——轮子不会打滑到原地劈叉,人形机器人会。所以传感器选型就成了第一个大坑。
我个人习惯,先把传感器分成两类:感知外部环境的和感知自身状态的。激光雷达和深度相机管外面,IMU、里程计和足底力传感器管里面。缺一个,导航就容易翻车。
4.1 激光雷达:2D还是3D?这是个问题
人形机器人上半身晃来晃去,2D激光雷达扫出来的平面经常对不上真实地面。我在项目里吃过这个亏——机器人走着走着突然认为前方有障碍,其实只是身体前倾扫到了地板。
我的建议:预算够直接上3D激光雷达。如果只能用2D,必须加装俯仰补偿,或者把雷达装在腰部而非头部。
| 类型 | 优点 | 缺点 | 人形机器人适用场景 |
|---|---|---|---|
| 2D激光雷达 | 便宜、轻量、ROS驱动成熟 | 单平面扫描,易受姿态影响 | 室内平坦地面 + 腰部安装 |
| 3D激光雷达 | 点云丰富,可建3D地图 | 贵、重、算力要求高 | 复杂地形、上下楼梯 |
laser_scan_matcher的publish_tf设为true,实时补偿身体俯仰角。我一般用IMU的roll/pitch做动态修正。
4.2 深度相机:RGB-D的坑与填坑
深度相机能提供彩色图和深度图,对人形机器人避障和地形识别很有用。但有个问题——室外强光下深度数据直接报废。我记得有一次在下午三点测试,深度图全是黑洞,机器人差点踩空台阶。
选型要点:
- 室内首选:Intel RealSense D435/D455,近距离精度好,ROS2支持完善
- 室外可选:OAK-D Pro,带红外激光点阵投影器,抗强光能力稍强
- 避坑:Kinect v1/v2已经停产,别买二手货,驱动维护基本停了
static_transform_publisher,导致点云和激光扫描差了20厘米,机器人一直对着空气绕圈。
4.3 IMU:别只看参数,要看实际表现
IMU是人形机器人的「内耳」,负责感知姿态和角速度。但IMU有个天生毛病——积分漂移。你想想看,加速度积分一次得速度,再积分一次得位移,误差像滚雪球一样。
我选IMU的标准:
- 陀螺仪零偏稳定性 < 10°/h(低于这个值,走路5分钟就偏了)
- 加速度计量程 ±8g以上(人形机器人落地冲击轻松超过4g)
- 输出频率 ≥200Hz(低于100Hz,控制周期跟不上)
市面上常见的IMU,比如BMI088、ICM-20948,我都用过。说实话,BMI088在抗振动方面表现更好,人形机器人走路时步态冲击大,BMI088的数据更稳。
<node pkg="imu_driver" type="imu_node" name="imu_node">
<param name="port" value="/dev/ttyUSB0"/>
<param name="frame_id" value="imu_link"/>
<param name="gyro_offset_x" value="0.002"/>
<param name="gyro_offset_y" value="-0.001"/>
<param name="accel_scale" value="9.80665"/>
</node>
注意:gyro_offset必须每次上电后重新标定,我习惯写一个启动脚本自动做静态校准。
4.4 里程计:关节编码器的真相
轮式机器人的里程计很准,因为轮子不打滑。人形机器人呢?脚底和地面是点接触,每一步都有滑动。关节编码器算出来的里程,走10米误差能到30厘米。
我的做法:把关节编码器里程计当成「短时参考」,不信任它的长期积分。在ROS里,我通常把odom话题的协方差矩阵设得比较大,让融合算法(比如robot_localization)更依赖激光雷达和视觉。
| 传感器 | 短期精度 | 长期稳定性 | 融合权重建议 |
|---|---|---|---|
| 关节编码器里程计 | 高(毫秒级) | 低(漂移严重) | 0.3(低权重) |
| 激光雷达里程计 | 中 | 高 | 0.5(中权重) |
| 视觉里程计 | 中低 | 中 | 0.2(低权重) |
4.5 足底力传感器:被忽视的关键
这个传感器很多人会忽略,但我觉得它是人形机器人导航的「隐形王牌」。为什么?因为只有知道脚底受力分布,才能判断地面是否平整、是否踩到障碍物、是否要打滑。
常见方案:
- FSR(力敏电阻):便宜,但只能测压力有无,精度差。适合简单触地检测
- 六维力传感器:贵,但能测Fx/Fy/Fz和Mx/My/Mz六个分量。适合步态规划和地形估计
我曾经在一个项目里只用FSR,结果机器人踩到小石子没检测出来,直接摔倒。后来换成六维力传感器,配合卡尔曼滤波做地面反力估计,稳定性提升了一大截。
sensor_msgs/Joy或自定义消息发布,频率至少100Hz。我习惯把左右脚数据合并成一个geometry_msgs/WrenchStamped数组,方便后续处理。
4.6 传感器时间同步:最容易翻车的环节
传感器选好了,配置好了,但时间戳对不上——这是我在课程答疑里遇到最多的问题。激光雷达的时间戳是硬件触发,IMU是软件时间,深度相机又用自己的时钟。三个时间戳差个几十毫秒,融合出来的位姿就乱跳。
解决方案:
- 硬件上:用STM32或FPGA做硬件触发同步,所有传感器共用PPS信号
- 软件上:ROS2的
time_synchronizer做近似同步,设置slop参数(一般0.05秒) - 实在不行:用
tf2的BufferCore::canTransform做插值,但精度会下降
ros::Time::now()而不是硬件时间戳。记住:能用硬件时间戳就别用软件时间戳。