4. 逆运动学模型:给定目标速度如何解算左右轮速度
各位同学,咱们接着聊。上一节我们搞清楚了正运动学——给定左右轮速度,机器人怎么动。那反过来呢?我告诉你机器人要往哪走、走多快,你该怎么算左右轮该转多快?这就是逆运动学要干的事。
说白了,逆运动学才是实际工程中最常用的。你想想看,遥控器给的是一个前进速度和一个转弯速度,底盘得自己算出电机该跑多少。嗯,这里面的门道,我今天一次性给你讲透。
4.1 从正运动学反推逆运动学
还记得正运动学的公式吗?
V = (Vr + Vl) / 2
ω = (Vr - Vl) / L
其中 V 是线速度,ω 是角速度,Vr 和 Vl 分别是右轮和左轮速度,L 是轮距。
现在我们要解的是:已知 V 和 ω,求 Vr 和 Vl。这不就是解二元一次方程组嘛。
把上面两个式子联立:
Vr + Vl = 2V
Vr - Vl = ωL
两式相加除以2,得到右轮速度:
Vr = V + (ωL)/2
两式相减除以2,得到左轮速度:
Vl = V - (ωL)/2
这就是逆运动学公式。简单吧?但我得提醒你,公式看着简单,实际用起来坑不少。
核心公式(记住它):
Vr = V + (ω × L) / 2
Vl = V - (ω × L) / 2
其中 V 为目标线速度,ω 为目标角速度,L 为左右轮间距。
4.2 公式的物理意义
咱们来拆解一下这个公式。我习惯这么理解:
- V 是公共项:左右轮都加上 V,这是让机器人直行的分量。
- (ωL)/2 是差速项:右轮加、左轮减,产生旋转。
你想想看,如果 ω = 0,那就是纯直线运动,Vr = Vl = V,左右轮速度一样。如果 V = 0,那就是原地旋转,Vr = -Vl,左右轮速度大小相等、方向相反。
我在项目中遇到过一种情况:调试AGV小车时,发现转弯半径总是不对。查了半天,原来是轮距 L 测量有误差。L 这个参数太关键了,差个几毫米,转弯精度就全偏了。
4.3 代码实现
下面给出一段 C 语言实现,这是我在嵌入式项目里实际用过的版本:
#include <math.h>
typedef struct {
float wheel_base; // 轮距 L,单位米
float max_speed; // 最大轮速,单位 m/s
} ChassisConfig;
typedef struct {
float v; // 线速度 m/s
float w; // 角速度 rad/s
} TargetVelocity;
typedef struct {
float left_speed; // 左轮速度 m/s
float right_speed; // 右轮速度 m/s
} WheelSpeed;
WheelSpeed inverse_kinematics(ChassisConfig *cfg, TargetVelocity *target) {
WheelSpeed ws;
// 逆运动学计算
ws.right_speed = target->v + (target->w * cfg->wheel_base) / 2.0f;
ws.left_speed = target->v - (target->w * cfg->wheel_base) / 2.0f;
// 限幅处理
float max = cfg->max_speed;
if (fabs(ws.right_speed) > max) {
ws.right_speed = (ws.right_speed > 0) ? max : -max;
}
if (fabs(ws.left_speed) > max) {
ws.left_speed = (ws.left_speed > 0) ? max : -max;
}
return ws;
}
我的经验:限幅处理一定要做。我曾经遇到过电机驱动板烧毁的事故,就是因为上位机发了一个离谱的角速度,算出来的轮速超过了电机额定值。从那以后,我所有运动学代码里都加了限幅。
4.4 奇异点分析
什么叫奇异点?说白了就是公式失效的地方。逆运动学公式本身没有数学上的奇异点——分母没有变量,不会出现除零的情况。
但是!工程上有两个"软奇异点",我吃了不少亏才总结出来的:
| 奇异点类型 | 表现 | 原因 | 处理方法 |
|---|---|---|---|
| 速度饱和奇异 | 机器人转弯半径变大 | 计算出的轮速超过电机最大转速 | 等比例缩放 V 和 ω |
| 低速奇异 | 机器人抖动、走不直 | V 太小,轮速接近死区 | 设置最小速度阈值 |
速度饱和怎么处理?我建议用等比例缩放法:
// 等比例缩放处理速度饱和
float scale = 1.0f;
float max_abs = fmax(fabs(ws.left_speed), fabs(ws.right_speed));
if (max_abs > cfg->max_speed) {
scale = cfg->max_speed / max_abs;
ws.left_speed *= scale;
ws.right_speed *= scale;
// 注意:缩放后实际 V 和 ω 会变小
}
注意:等比例缩放会改变实际输出的 V 和 ω 比例,但至少保证了机器人能按正确的方向运动。如果你需要严格保持 V 或 ω 中的一个不变,那就得用更复杂的优先级策略了。
4.5 逆运动学的几何理解
我画了一张图,帮你从几何角度理解逆运动学:
从图上可以看得很清楚:右轮速度等于中心速度加上差速项,左轮速度等于中心速度减去差速项。差速项的大小取决于角速度和轮距。
4.6 实际工程中的注意事项
最后,我总结几个实际干活时容易踩的坑:
- 单位统一:V 用 m/s,ω 用 rad/s,L 用 m。我见过有人把 ω 用度每秒传进来,结果机器人原地转圈圈。
- 轮距测量:L 是左右轮接地点的距离,不是电机轴距。差一点转弯就不准。
- 电机响应延迟:算出来的轮速是目标值,实际电机响应有延迟。PID 参数没调好,逆运动学算得再准也没用。
- 死区补偿:电机在低速时可能不转,需要加一个死区补偿值。
避坑指南:我曾经在一个项目中,逆运动学算得好好的,但机器人就是走不直。排查了三天,最后发现是左右轮的直径不一样——差了0.5mm。从那以后,我每次装机都会用卡尺量一下轮子直径,左右轮必须配对使用。
好了,逆运动学就讲到这里。公式不复杂,但工程实现时细节很多。下一节我们讲电机控制的时候,会把这些细节串起来。
公众号:蓝海资料掘金营,微信deep3321