4. 边界约束的数学建模:不等式约束、软约束与硬约束、凸包与可行域
各位同学,咱们今天聊点硬核的。路径规划里,光会算路径还不够,你得让车老老实实待在路里面。这就是边界约束要干的事。
说白了,边界约束就是给车画个圈。圈里面随便跑,圈外面想都别想。但实际做起来,这里面的门道可不少。我当年刚入行时,就吃过亏——约束设得太死,车动不动就报错;设得太松,又压线。嗯,今天咱们就把这笔账算清楚。
4.1 不等式约束:最朴素的边界表达
先看最简单的。道路边界,左右两条线。车不能越过左边,也不能越过右边。用数学写出来就是:
左边界:y ≥ f_left(x)
右边界:y ≤ f_right(x)
这就是不等式约束。我习惯把道路切成一段段,每段用直线近似。比如在某个位置 x₀,左边界是 y ≥ 2.0,右边界是 y ≤ 3.5。那车的横向位置 y 就得满足:
2.0 ≤ y ≤ 3.5
你想想看,这其实就是一个上下界的问题。在优化求解时,我们把这些不等式塞进求解器里,告诉它:别让 y 跑出这个范围。
核心要点:不等式约束是路径规划中最基础的边界表达方式。每个约束对应一个不等式,所有不等式同时成立,就构成了可行域。
我在项目中遇到过一个问题:道路弯曲时,直接用全局坐标系的 y 坐标做约束会出问题。因为弯道内侧和外侧的约束方向不一样。后来我改用Frenet坐标系,用横向偏移量 d 来做约束,就顺了。这个坑,你们以后大概率也会踩到。
4.2 硬约束 vs 软约束:刚柔并济
接下来是个关键选择。约束到底要设多硬?
| 类型 | 定义 | 特点 | 典型场景 |
|---|---|---|---|
| 硬约束 | 必须满足,违反即不可行 | 严格、无商量余地 | 物理边界、安全护栏 |
| 软约束 | 尽量满足,违反有代价 | 灵活、可权衡 | 舒适性、避障优先级 |
硬约束,说白了就是红线。车绝对不能越过。比如路沿石、护栏。一旦违反,要么求解器报无解,要么车就真撞上去了。我建议对这类约束用严格不等式,比如 y ≤ 3.5,不留余地。
软约束就不一样了。它更像一个建议。比如「尽量靠中间走」。违反不会导致灾难,但会在代价函数里加惩罚。数学上通常写成:
minimize: J = J_original + w * penalty(y - y_desired)
这里的 penalty 函数,我常用二次型:
penalty = (y - y_desired)²
为什么?因为二次型可导,求解器喜欢。而且偏离越远,惩罚越大,自然就把车拉回来了。
我的经验:实际项目中,我通常把物理边界设成硬约束,把舒适性、效率等设成软约束。这样既保证安全,又给优化留了余地。有一次做泊车规划,车位很窄,硬约束设得太死导致无解。后来把车位边界改成软约束,加了个大权重,车就自己「挤」进去了。
4.3 凸包与可行域:约束的几何本质
好,现在我们把所有约束放在一起看。每个不等式约束,在空间里切一刀。所有刀切完,剩下的区域就是可行域。
但这里有个大问题:可行域的形状决定了求解难度。
如果可行域是凸集,那求解就简单。凸集的意思是:区域内任意两点连线,整条线都在区域内。比如矩形、圆形、椭圆。凸优化有成熟的算法,保证能找到全局最优解。
如果可行域是非凸集,那就麻烦了。比如一个C形区域,两点连线可能穿到外面去。这时候求解器可能陷入局部最优,甚至找不到解。
那怎么办?我们常用凸包来近似。凸包就是包含所有约束点的最小凸多边形。说白了,就是把非凸的区域「撑」成凸的。
// 伪代码:构建凸包
points = [所有道路边界点]
convex_hull = GrahamScan(points) // 用葛立恒扫描法
注意:凸包近似会丢失一些可行区域。比如一个U形弯道,凸包会把中间凹进去的部分也包进来,导致原本不可行的路径被误判为可行。我曾在高速匝道规划中吃过这个亏,后来改用分段凸包才解决。
下面这张图展示了整个知识体系的结构:
4.4 实战中的取舍
讲完理论,说说实际怎么用。我一般按这个流程来:
- 先列硬约束:物理边界、安全距离、车辆动力学极限。这些是底线。
- 再加软约束:舒适性、效率、偏好车道。这些是优化目标。
- 检查凸性:如果可行域非凸,考虑分段或凸包近似。
- 调权重:软约束的权重需要反复试。我习惯先设大权重让车「听话」,再慢慢减小。
避坑指南:我曾经在一条窄路上,把左右边界都设成硬约束。结果车稍微偏一点就无解,导致规划失败。后来我把一侧改成软约束,加了个大惩罚,车就能在极限情况下「借道」了。记住:硬约束是安全底线,软约束是优化方向。别把两者搞混。
最后说一句。边界约束这东西,看着简单,做起来全是细节。你想想看,一条路几百米,每个点的约束都不一样。还要考虑车辆尺寸、转向半径、动态响应。嗯,这就是为什么我总说:规划控制,七分在约束,三分在优化。
今天就到这。下次咱们聊聊怎么把这些约束塞进求解器里,让车真正跑起来。