第二节:Frenet坐标系——轨迹规划的“本地语言”
做轨迹规划这些年,我越来越觉得Frenet坐标系是个被低估的工具。很多新手一上来就死磕笛卡尔坐标系,结果弯道规划搞得一团糟。其实说白了,Frenet坐标系就是专门为道路场景设计的“本地语言”。
你想想看,在笛卡尔坐标系里描述一条弯曲道路,你得用一堆复杂的曲线方程。但在Frenet坐标系里,道路就是一条直线——嗯,至少看起来是。这就是它的魔力所在。
2.1 Frenet坐标系原理
Frenet坐标系的核心思想很简单:沿着道路走。它由两个轴组成:
- s轴(纵向):沿着道路中心线的弧长距离。说白了就是“你走了多远”。
- d轴(横向):垂直于道路中心线的偏移距离。也就是“你偏离中心线多少”。
我在项目中遇到过这样一个场景:高速公路上有个大曲率的弯道,用笛卡尔坐标系描述车辆位置时,x和y的变化率完全不一样,控制起来特别别扭。换成Frenet坐标系后,s和d的变化就平滑多了,控制器的参数也更好调。
核心优势:Frenet坐标系将二维道路问题解耦为两个一维问题——纵向速度控制和横向偏移控制。这就像把复杂的立体拼图拆成了两个平面拼图,难度直接降了一个维度。
为什么会这样?因为道路本身是有结构的。车辆沿着道路行驶时,纵向行为(加速、减速)和横向行为(变道、转向)本质上是独立的。Frenet坐标系恰好抓住了这个特性。
2.2 与笛卡尔坐标系的转换
转换公式看起来有点吓人,但别怕。我刚开始学的时候也觉得头大,后来发现只要理解了“投影”这个概念,一切都顺了。
从笛卡尔到Frenet:
- 找到道路中心线上离车辆最近的点(投影点)
- s = 从道路起点到投影点的弧长
- d = 车辆到投影点的有向距离(左正右负)
从Frenet到笛卡尔:
- 根据s找到道路中心线上的对应点
- 沿着该点的法线方向移动d的距离
我的小技巧:实际工程中,我们很少手动算这些公式。一般会预计算道路中心线的s→(x,y)映射表,然后做插值。这样既快又准,还省得你推导那些复杂的微分几何公式。
我曾经踩过一个坑:在高速变道场景下,直接用解析公式做转换,结果因为道路曲率变化剧烈,投影点跳来跳去,导致轨迹出现抖动。后来改用分段三次样条插值,问题就解决了。
2.3 在轨迹规划中的应用
Frenet坐标系在轨迹规划中主要有三个应用场景:
- 路径-速度解耦:先规划横向路径d(s),再规划纵向速度s(t)。两个问题独立求解,复杂度从O(n²)降到O(n)。
- 变道轨迹生成:在Frenet坐标系中,变道就是d从0变到3.5(车道宽度),s从当前值变到目标值。用五次多项式就能生成平滑轨迹。
- 避障轨迹优化:障碍物在Frenet坐标系中表现为(s, d)区域,约束条件变得非常直观。
实战经验:我在做L4级自动驾驶项目时,所有轨迹规划都在Frenet坐标系中完成。只有在最后输出控制指令时,才转回笛卡尔坐标系。这样做的好处是——你永远不用担心轨迹会跑到路外面去,因为d轴天然约束了横向范围。
嗯,这里要注意一点:Frenet坐标系不是万能的。当道路曲率过大(比如掉头弯)或者道路拓扑变化(比如分叉路口)时,投影点的唯一性会出问题。这时候需要结合拓扑地图来做处理。
避坑指南:我曾经在一个多车道汇入的场景中,直接用Frenet坐标系规划轨迹,结果因为投影点歧义,车辆在汇入点附近反复横跳。后来加了一个“投影点连续性约束”,才把这个问题解决。所以记住——Frenet坐标系好用,但别忘了检查投影点的连续性。
最后分享一个我个人的习惯:在调试轨迹规划算法时,我会同时可视化Frenet坐标系和笛卡尔坐标系下的轨迹。这样能快速定位问题——如果Frenet坐标系下的轨迹很平滑,但笛卡尔坐标系下出现抖动,那多半是转换环节出了问题。
| 特性 | Frenet坐标系 | 笛卡尔坐标系 |
|---|---|---|
| 道路表示 | 直线(s轴) | 曲线 |
| 横向约束 | 天然满足(d轴范围) | 需要额外约束 |
| 计算复杂度 | 低(解耦后) | 高(耦合问题) |
| 适用场景 | 结构化道路 | 任意场景 |
说白了,Frenet坐标系就是为道路场景量身定做的。如果你做的是结构化道路上的轨迹规划,不用Frenet坐标系,那真是跟自己过不去。