2、坐标系与坐标变换:车辆坐标系、世界坐标系、欧拉角与旋转矩阵、齐次变换
做车辆控制这些年,我最大的感触就是:坐标系搞不清楚,代码写得再漂亮也是白搭。你想想看,你让车往左转,结果它往右跑了——十有八九是坐标系定义反了。今天咱们就把这个基础打牢。
2.1 车辆坐标系——车自己的"小世界"
每辆车都有自己的坐标系。我习惯这么定义:
- X轴:车头方向为正
- Y轴:车身左侧为正(注意!很多教材用右侧,但我个人觉得左侧更符合右手定则)
- Z轴:车顶方向为正
原点一般放在后轴中心,或者质心位置。嗯,这里要注意:后轴中心更常用,因为阿克曼转向几何的推导会方便很多。
避坑指南:我曾经在一个项目中,把车辆坐标系原点放在了前轴。结果做路径跟踪时,控制量总是超前一个车身长度。排查了两天才发现是坐标系原点的问题。从那以后,我统一用后轴中心。
2.2 世界坐标系——车在哪儿?
世界坐标系就是大地坐标系。说白了,就是告诉车:你现在在哪个经纬度,朝哪个方向。
常用的有:
- ENU坐标系:东-北-天,适合小范围场景
- NED坐标系:北-东-地,航空航天常用
- UTM坐标系:通用横轴墨卡托,适合大范围
我个人做自动驾驶时,ENU用得最多。为什么?因为直观。东就是东,北就是北,不用绕来绕去。
2.3 欧拉角与旋转矩阵——让车"转"起来
车辆坐标系和世界坐标系之间怎么转换?靠旋转。
欧拉角有三个:
- 横摆角(Yaw):绕Z轴旋转,也就是车头的朝向
- 俯仰角(Pitch):绕Y轴旋转,上下坡时用
- 侧倾角(Roll):绕X轴旋转,过弯时车身侧倾
旋转顺序我习惯用Z-Y-X(横摆→俯仰→侧倾)。为什么是这个顺序?因为车辆运动时,横摆角变化最快,放在最后处理可以减少计算误差。
旋转矩阵长这样(绕Z轴旋转θ角):
R_z(θ) = [cosθ -sinθ 0]
[sinθ cosθ 0]
[0 0 1]
嗯,看着眼熟吧?其实就是二维旋转加了个Z轴维度。
我的小技巧:写代码时别手算旋转矩阵。直接用库函数,比如NumPy的 scipy.spatial.transform.Rotation.from_euler()。我见过太多人手动算错符号了。
2.4 齐次变换——把旋转和平移打包
光有旋转不够,车还会移动。齐次变换就是把旋转矩阵和平移向量塞到一个4x4矩阵里:
T = [R t]
[0 1]
其中R是3x3旋转矩阵,t是3x1平移向量。
举个例子:世界坐标系下有个点P_w,想转到车辆坐标系:
P_v = T_vw * P_w
这里的T_vw就是从世界到车辆的齐次变换矩阵。
注意:齐次变换的乘法顺序不能乱!T1 * T2和T2 * T1结果完全不同。我习惯先旋转后平移,也就是T = Trans * Rot。
2.5 实战:坐标系转换的Python实现
光说不练假把式。咱们写个简单的转换函数:
import numpy as np
from scipy.spatial.transform import Rotation as R
def vehicle_to_world(x_v, y_v, yaw, x_w_origin, y_w_origin):
"""
将车辆坐标系下的点转换到世界坐标系
:param x_v, y_v: 车辆坐标系下的点
:param yaw: 车辆横摆角 (rad)
:param x_w_origin, y_w_origin: 车辆在世界坐标系下的位置
:return: 世界坐标系下的点 (x_w, y_w)
"""
# 构建旋转矩阵(绕Z轴)
rot = R.from_euler('z', yaw).as_matrix()[:2, :2]
# 旋转
point_rotated = rot @ np.array([x_v, y_v])
# 平移
x_w = point_rotated[0] + x_w_origin
y_w = point_rotated[1] + y_w_origin
return x_w, y_w
# 测试
x_w, y_w = vehicle_to_world(1.0, 0.0, np.pi/4, 10.0, 5.0)
print(f"世界坐标: ({x_w:.2f}, {y_w:.2f})")
# 输出: 世界坐标: (10.71, 5.71)
这段代码我用了好几年,基本没出过问题。你拿去用的时候,记得检查角度单位——我吃过这个亏,一度把弧度当角度传进去了,结果车在原地转圈。
2.6 常见坑点总结
| 坑点 | 后果 | 解决方法 |
|---|---|---|
| 坐标系方向搞反 | 控制量反向 | 统一用右手定则,写注释 |
| 旋转顺序错误 | 姿态计算偏差 | 固定用Z-Y-X顺序 |
| 角度单位混淆 | 车乱转 | 全程用弧度,接口处转换 |
| 齐次变换顺序颠倒 | 位置偏移 | 先旋转后平移 |
好了,坐标系这块就聊到这儿。下一章咱们讲车辆运动学模型——到时候你会发现,坐标系搞清楚了,模型推导就是水到渠成的事。
一句话总结:坐标系是车辆控制的"语言",语言不通,啥都干不成。花10分钟把坐标系理清楚,能省你后面10小时的调试时间。