4. 运动学模型:差速驱动运动学
做机器人底盘,绕不开的就是运动学模型。说白了,就是搞清楚「轮子怎么转,机器人怎么动」这件事。差速驱动是两轮机器人最经典的结构,我最早接触它是在大学做智能车竞赛的时候,那时候还没意识到这东西有多重要,直到后来做AGV项目,才真正体会到——运动学模型没搞透,后面里程计、控制全是空中楼阁。
4.1 差速驱动结构
差速驱动,顾名思义,靠左右轮的速度差来实现转向。两个独立驱动的轮子,加上一个或两个万向轮做支撑,就构成了最基本的底盘结构。
我习惯把这种结构想象成「坦克转向」——左右履带速度不同,车体就会转弯。只不过轮式底盘更灵活,也更敏感。
核心参数:
- 轮距(Wheelbase):左右轮中心之间的距离,记作
L - 轮半径:驱动轮的物理半径,记作
r - 左右轮转速:
ω_L和ω_R,单位 rad/s
你想想看,如果左右轮转速一样,机器人就走直线。如果左轮比右轮快,机器人就向右转。这个直觉是对的,但具体怎么算,我们需要一套数学工具。
4.2 正运动学解算
正运动学,就是「已知轮速,求机器人速度」。这是里程计计算的基础,也是我调试底盘时最常调用的函数。
差速驱动的正运动学公式其实很简单:
v = (v_R + v_L) / 2
ω = (v_R - v_L) / L
其中:
v:机器人线速度(m/s)ω:机器人角速度(rad/s)v_R = ω_R * r:右轮线速度v_L = ω_L * r:左轮线速度L:轮距
嗯,这里要注意:v_R - v_L 的符号决定了转向方向。如果右轮比左轮快,差值为正,机器人逆时针旋转(从上方看)。
我的经验:在实际项目中,轮距 L 的测量误差对里程计影响很大。我曾经因为轮距量错了2毫米,导致机器人转一圈后位置偏差了十几厘米。建议用多次旋转标定法来精确测量轮距。
正运动学在ROS里通常放在 odometry 节点中。每次收到轮速编码器数据,就调用这个公式,然后积分得到位置和姿态。
4.3 逆运动学解算
逆运动学正好反过来——「已知目标速度,求左右轮速」。这是运动控制的核心,说白了就是告诉电机:「你要转多快」。
公式也很直观:
v_R = v + (ω * L) / 2
v_L = v - (ω * L) / 2
然后转换成轮子角速度:
ω_R = v_R / r
ω_L = v_L / r
举个例子:假设机器人想以 0.5 m/s 的速度前进,同时以 0.3 rad/s 的角速度左转,轮距 0.4m,轮半径 0.05m:
v_R = 0.5 + (0.3 * 0.4) / 2 = 0.56 m/s
v_L = 0.5 - (0.3 * 0.4) / 2 = 0.44 m/s
ω_R = 0.56 / 0.05 = 11.2 rad/s
ω_L = 0.44 / 0.05 = 8.8 rad/s
避坑指南:我曾经在逆运动学里忘记除以轮半径,直接把线速度发给电机驱动器,结果机器人原地打转。后来我养成了一个习惯——在代码里加一个单位检查函数,确保输入输出都是物理单位。
4.4 轮速与机器人速度转换
这个转换其实包含两个方向:
- 编码器 → 轮速 → 机器人速度(正运动学)
- 目标速度 → 轮速 → 电机控制(逆运动学)
在ROS中,我们通常用 geometry_msgs/Twist 消息来表示机器人速度,用 std_msgs/Float64 或自定义消息来表示轮速。
我习惯把转换逻辑封装成一个类,这样代码复用性高:
class DifferentialDriveKinematics:
def __init__(self, wheel_radius, wheel_base):
self.r = wheel_radius
self.L = wheel_base
def forward(self, w_left, w_right):
"""正运动学:轮速 -> 机器人速度"""
v_left = w_left * self.r
v_right = w_right * self.r
v = (v_left + v_right) / 2.0
omega = (v_right - v_left) / self.L
return v, omega
def inverse(self, v, omega):
"""逆运动学:机器人速度 -> 轮速"""
v_right = v + (omega * self.L) / 2.0
v_left = v - (omega * self.L) / 2.0
w_right = v_right / self.r
w_left = v_left / self.r
return w_left, w_right
这个类我在好几个项目里都用过,从两轮平衡车到四轮差速底盘,核心逻辑都一样。
4.5 知识体系总览
为了让你更直观地理解这一章的内容,我画了一张流程图:
这张图把正运动学和逆运动学的关系讲得很清楚。左边是「感知」方向——从轮速推算机器人状态;右边是「控制」方向——从目标速度反推轮速。两者构成了一个闭环。
4.6 实际项目中的注意事项
最后,分享几个我在实际项目中踩过的坑:
- 轮距不是固定值:轮胎气压、负载变化都会影响有效轮距。我一般在每次启动时做一次标定。
- 编码器分辨率:分辨率太低会导致低速时速度跳变。我建议至少每转500脉冲以上。
- 控制频率:ROS中/cmd_vel的发布频率建议在20-50Hz,太低会导致运动不平滑。
差速驱动运动学看起来简单,但真正做好并不容易。把基础打牢,后面的里程计融合才能事半功倍。
小技巧:调试时可以在ROS中用 rqt_plot 实时观察左右轮速和机器人速度,能快速发现运动学模型中的问题。