3、坐标系与坐标变换:车辆坐标系、全局坐标系、经纬度与UTM坐标转换、齐次变换矩阵

说实话,坐标系这个东西,刚入行时我觉得特别简单。不就是几个轴嘛,谁不会?

直到我第一次在实车上跑路径规划,车死活不走我规划的路线。排查了半天,发现是坐标系搞反了。嗯,从那以后,我再也不敢小看坐标系了。

3.1 车辆坐标系——我们最熟悉的坐标系

车辆坐标系,说白了就是「以车为中心」的坐标系。我个人习惯把它叫做车身坐标系

定义很简单:

  • x轴:指向车辆正前方
  • y轴:指向车辆左侧(也有用右侧的,看标准)
  • z轴:指向车辆正上方

原点一般放在后轴中心,或者车辆质心。我在项目中遇到过,用后轴中心更常见,因为和运动学模型好对接。

重要提醒:车辆坐标系是随车移动的。车转弯,坐标系也跟着转。这是它和全局坐标系最大的区别。

你想想看,路径规划里经常要判断「障碍物在车的左边还是右边」。这个判断就是在车辆坐标系下做的。如果搞反了左右,那避障就全乱套了。

3.2 全局坐标系——地图的「世界」

全局坐标系是固定不动的。它给整个环境一个统一的参考。

常见的全局坐标系有两种:

  • 笛卡尔坐标系:就是(x, y, z),简单直观
  • UTM坐标系:通用横轴墨卡托投影,后面细说

我记得有一次做高精地图融合,地图用的是UTM坐标,但传感器数据是经纬度。两个坐标系没对齐,结果路径规划出来的路线直接穿墙了。你说尴尬不尴尬?

所以,坐标系转换是路径规划里绕不开的坎。

3.3 经纬度与UTM坐标转换

GPS给的是经纬度,但路径规划需要的是平面坐标。这就得做投影转换。

经纬度转UTM的公式挺复杂,我一般直接用现成的库。但原理你得懂:

坐标类型 表示方式 特点
经纬度 (lat, lon) 球面坐标,单位是度
UTM (easting, northing) 平面坐标,单位是米

UTM把地球分成60个带,每个带6度。中国主要覆盖43-53带。我曾经踩过一个坑:用了错误的UTM带号,结果坐标偏移了几十公里。嗯,那次排查花了我整整一天。

我的小技巧:做转换时,先确认你所在的UTM带号。可以用在线工具查一下,别凭感觉猜。

代码示例(Python):

import utm

# 经纬度转UTM
lat, lon = 39.9042, 116.4074  # 北京天安门
easting, northing, zone_num, zone_letter = utm.from_latlon(lat, lon)
print(f"UTM: {easting:.2f}, {northing:.2f}, Zone {zone_num}{zone_letter}")

# UTM转经纬度
lat_back, lon_back = utm.to_latlon(easting, northing, zone_num, zone_letter)
print(f"经纬度: {lat_back:.4f}, {lon_back:.4f}")

3.4 齐次变换矩阵——坐标转换的「瑞士军刀」

齐次变换矩阵,说白了就是把旋转平移打包成一个4x4的矩阵。

为什么用4x4?因为3x3只能做旋转,做不了平移。加一个维度,就能统一处理了。

形式长这样:

| R   t |
| 0   1 |

其中R是3x3旋转矩阵,t是3x1平移向量。

举个例子,把车辆坐标系下的点转换到全局坐标系:

P_global = T * P_vehicle

这里的T就是齐次变换矩阵。

注意:齐次变换矩阵的乘法顺序很重要!先旋转再平移,还是先平移再旋转,结果完全不同。我见过有人搞反了顺序,路径规划出来的轨迹直接反方向跑。

我个人习惯用欧拉角来表示旋转,因为直观。但要注意万向锁问题。如果你做的是全向运动规划,建议用四元数。

3.5 坐标系转换的实战流程

在路径规划系统里,坐标系转换的流程一般是这样的:

  1. 传感器数据:先转到车辆坐标系
  2. 车辆坐标系:通过齐次变换转到全局坐标系
  3. 全局坐标系:如果是GPS路径,还要转成UTM
  4. 规划结果:再转回车辆坐标系,发给控制模块

我曾经在一个项目里,因为少做了一步坐标系转换,导致规划出来的路径和实际行驶轨迹差了2米。嗯,从那以后我每次做转换都会画个流程图,标清楚每一步。

核心要点:

  • 车辆坐标系:随车移动,用于局部感知和避障
  • 全局坐标系:固定不动,用于全局路径规划
  • 经纬度转UTM:注意带号,别搞错
  • 齐次变换矩阵:旋转+平移,顺序不能乱

最后说一句,坐标系转换看起来是基础,但它是整个路径规划系统的地基。地基不稳,上面盖的楼再漂亮也没用。我见过太多因为坐标系搞错而翻车的案例了。

你想想看,如果连「车在哪」「目标在哪」都搞不清楚,路径规划还怎么玩?