
做机械臂轨迹规划的人应该都遇到过类似的痛点给定一个末端位姿你不仅要规划出一条不撞障碍物的路径还得保证关节力矩不超过上限、加速度不猛冲、末端不抖。一旦把这些动力学约束全部塞进去问题瞬间变成一个高维非线性边界值问题求解起来极其痛苦。这几年我在各种论文和项目里频繁撞见同一个概念——微分平坦Differential Flatness它在四旋翼轨迹规划里几乎封神现在正快速向机械臂规划领域蔓延。这篇是轨迹规划理论系列的第一篇专门把微分平坦这件事讲透它到底是什么、凭什么能简化轨迹规划、在机械臂场景里怎么落地、又有哪些坑等着你去踩。不管你是做机械臂的工程师、研究运动规划的学生还是对四旋翼/移动机器人感兴趣的人这篇内容都能帮你在现有规划框架里多一把趁手的工具。理解微分平坦之后你会看明白一件事很多看似复杂的轨迹优化问题本质上只是你选错了规划空间。1. 先搞懂微分平坦在说什么1.1 平地起高楼从系统方程到平坦输出先别急着记公式我们从“系统长什么样”开始。一个连续时间非线性系统通常写成状态方程形式x_dot f(x, u)其中 x 是状态向量u 是控制输入向量。对于机械臂x 常见的就是关节角和关节角速度u 就是关节力矩。轨迹规划要做的事就是找一条满足这个微分方程的状态轨迹和控制输入序列。微分平坦说的是这么一件事如果这个系统存在一组特殊的输出变量 z使得系统所有的状态 x 和控制输入 u都能由 z 以及它的有限阶导数直接表示出来那么这个系统就是微分平坦的z 就叫平坦输出。用大白话讲就是x Φ(z, z_dot, z_ddot, ..., z^(q)) u Ψ(z, z_dot, z_ddot, ..., z^(q))这里的 q 是一个有限整数意思是只需要取到平坦输出有限阶导数就够了。你不需要求解任何微分方程只需要给定一条足够光滑的 z(t) 曲线代入上面两个式子系统的全部状态和输入就全出来了。有人可能会问这不是多此一举吗本来状态就是 x你现在非要用另一个变量 z 来表示 x有什么意义关键就在这里。对于大多数非线性的欠驱动系统x 和 u 之间隔着一层非线性微分约束直接规划 x 和 u 非常难。但如果你能找到一组好的 z微分约束就被打散变成代数关系了。1.2 一个比方能听懂的平坦直觉我打个比方。假设你要让一个朋友从北京坐高铁去上海同时要求他全程不晕车、按时吃饭、手机有电。直接规划“他每一秒钟的吃饭速度、手机充电功率”是非常麻烦的因为这些东西之间相互耦合。但如果你先规划一条从北京到上海的高铁线路再根据这条线路反推每一站停多久、每一段用什么速度跑、什么时候该点外卖事情就简单多了。高铁线路就是平坦输出吃饭和充电就是由它决定的状态和控制。四旋翼是最好的例子。四旋翼一共有 12 个状态位置、速度、姿态、角速度和 4 个输入总推力 三轴力矩直接规划姿态和解算推力的过程非常绕。但如果你选位置 (x,y,z) 和偏航角 ψ 作为平坦输出剩下所有状态和输入都由它们以及它们的导数代数给出。你只需要规划出一条光滑的空间曲线和偏航角曲线推力、姿态、角速度全部自动反算出来。这就是微分平坦在四旋翼领域被广泛使用的原因。1.3 为什么轨迹规划者把它当宝贝传统轨迹规划方法多数是“打靶法”或者“直接配点法”把时间离散成一堆节点把状态和控制当作优化变量去迭代求解每一步都要反复检查系统动力学约束是否满足。这种做法有两个问题一是优化变量暴涨二是非线性约束让求解器经常陷入局部最小值。微分平坦的思路完全不同。它把问题从高维状态空间投影到低维平坦输出空间。你只需要在平坦输出空间里设计曲线然后解析地求出状态和控制量。规划一个四旋翼轨迹本质变成规划三个位置分量和偏航角的多项式规划一台吊车防摆轨迹本质变成规划负载位置的光滑曲线。原来那些动力学微分约束全部变成了平坦输出及其导数的代数校验你可以直接写进约束条件里。这种降维打击的爽感用过一次就回不去。2. 轨迹规划里的微分平坦玩法2.1 规划流程在平坦输出空间里开挂假设我们已经确认系统是微分平坦的并且找到了平坦输出 z接下来该怎么做轨迹规划我一般按四步走第一步选参数化形式。确定用多项式、B样条、贝塞尔曲线还是分段多项式来参数化平坦输出 z(t)。这一步决定了轨迹的光滑程度和优化变量数量。第二步建立约束映射。把原系统里你关心的约束全部转写成 z 及其导数的约束。比如四旋翼的推力不能为负、关节力矩不能超限、末端不能碰到障碍物这些都是可以转写为 z 的代数条件的。避障这类空间约束在平坦输出空间往往特别直观因为平坦输出通常就是你真正关心的物理量位置、末端坐标。第三步求解优化问题。在平坦输出空间里解一个带约束的优化问题目标函数可以是轨迹时间最短、加速度平方积分最小或者总能量最少。因为变量少、约束大多是代数约束求解速度比直接配点法快一个数量级。第四步反演验证。把优化得到的 z(t) 代回映射关系得到完整的状态轨迹和控制输入然后丢进仿真或者实机里验证。这套流程我实测下来最大的优势是“可解释性”特别强。你可以直接看到轨迹在物理空间里长什么样而不是面对一堆抽象的状态变量。2.2 参数化大法多项式、B样条、min-snap在平坦输出空间里参数化方式是整个规划效果的分水岭。最朴素的是单段多项式。比如让位置轨迹是一个时间 t 的 N 阶多项式给定起点和终点的位置、速度、加速度约束解线性方程就能得到系数。优点是简单缺点是轨迹自由度太小中间很难插入中间点约束还容易产生龙格振荡。工程上我更喜欢分段多项式尤其是样条。把时间轴切成多段每一段用低阶多项式拼接同时保证段间的高阶导数连续。常用于四旋翼的 minimum snap最小加加速度平方积分就是这类思路。因为四旋翼的控制输入跟加加速度、加加速度的变化率有关直接在平坦输出空间里最小化 snap反算出来的控制输入自然平滑无人机飞起来不会一顿一顿。B样条是另一个常用选项。它的好处是局部支撑你移动一个控制点只影响附近一小段轨迹不会牵一发动全身。做实时避障重规划时非常方便。代价是边界条件处理起来比分段多项式麻烦一些需要额外的预约束技巧。我做机械臂相关工作的时候通常先看问题对“实时性”的要求一次求解离线用的用分段多项式加非线性优化需要在线重规划的优先上B样条。2.3 常见平坦系统对照表我习惯遇到一个新系统时先查它是不是微分平坦的。下面这张表是我日常用的快速对照系统典型平坦输出说明四旋翼三维位置 偏航角其余状态与控制由位置和偏航的导数代数给出差速驱动小车车轮中点坐标 (x,y)线速度和角速度由位置导数反算桥式吊车吊钩/负载的水平位置可以直接规划负载路径并同时保证防摆倒立摆小车小车位置带一定组合具体平坦输出形式跟杆长和质量相关柔性关节机械臂电机侧位置或负载侧位置可以根据需要选择用于抑制残余振动全驱动串联机械臂关节角平凡情形关节角本身就是平坦输出动力学完全由力矩决定这张表只是起点。实际工程里很多系统不是天生平坦的但通过反馈线性化或者部分模型简化可以在局部近似平坦这也是一个很常用的取巧思路。3. 机械臂场景下的实操拆解3.1 全驱动串联臂为什么关节角本身就是平坦输出先聊最常见的工业机械臂。一个刚性串联机械臂每个关节都有独立的电机驱动自由度等于驱动数这类系统其实是“平凡平坦”的——你取关节角 q 作为平坦输出关节速度就是关节角的一阶导数关节加速度是二阶导数再代入动力学方程M(q) q_ddot C(q, q_dot) q_dot g(q) τ力矩 τ 可以直接由 q、q_dot、q_ddot 算出。这意味着理论上你只要规划出关节角轨迹力矩轨迹就完全确定了这就是典型的平坦输出退化情境。但这里有一个容易忽略的重点虽然关节角是平坦输出但关节角的任意光滑曲线并不一定对应物理上合理的运动。因为力矩约束、电机速度约束、加速度约束都会对 q 的光滑性提出额外要求。所以机械臂规划的核心往往不是“如何解系统微分方程”而是“如何把 q 的曲线约束到满足力矩和加加速度限制的可行空间里”。在实际做的时候我会直接把动力学模型当作一个“约束校验器”在平坦输出空间里生成候选轨迹代入动力学反算力矩看有没有超限。而没有微分平坦的人往往只能用数值积分一遍遍仿真试错。3.2 欠驱动/柔性关节平坦输出怎么找真正让微分平坦大放异彩的机械臂场景其实是欠驱动和柔性关节系统。比如带有弹性减速器的机械臂电机端和连杆端不是刚性连接存在弹簧形变。这个系统的状态比输入多得多直接控制很难。以单柔性关节臂为例电机转角 θ 驱动一个弹簧弹簧再驱动连杆。这个系统是微分平坦的平坦输出可以选电机转角的位置也可以选连杆位置。选电机转角作为平坦输出时可以通过规划电机侧的平滑转角来抑制连杆侧振动选连杆位置作为平坦输出时可以直接给定末端期望轨迹反算电机该给多大输入。我当时第一次把柔性关节臂的轨迹规划改成微分平坦方法时最大的感触是以前要处理一个二阶动态微分约束和振动抑制约束的耦合经常数值求解失败改成平坦输出之后约束变成了平坦输出四阶导数的显示表达式优化求解器基本没有不收敛的。不过要注意平坦输出的选取不是唯一的不同选取会导致映射关系复杂程度完全不同。我建议多试几个候选输出比较一下它们代数表达式的复杂度再决定用哪一个。3.3 一个可落地的仿真案例2R机械臂末端轨迹规划讲一个我做过的最小可复现案例。平面 2R 机械臂两个关节末端要沿一条直线从 A 点运动到 B 点同时保证关节力矩不大幅超限。第一步我选末端位置 (x, y) 作为“候选平坦输出”。严格说对于 2R 臂末端位置并不能全局唯一确定关节角存在腕部奇异问题所以这个方法只在非奇异区间有效。我在规划时先检查末端路径是否经过奇异点。第二步用五阶多项式参数化 x(t) 和 y(t)满足起点和终点的位置、速度、加速度约束。第三步对每个时间点用逆解求关节角 q(t)再用解析或数值微分得到 q_dot 和 q_ddot代入 2R 臂的动力学方程计算力矩。第四步检查力矩约束。如果超限就提高多项式阶数、增加中间节点或者重新分配时间。这么一套操作在 MATLAB 或者 Python 里大概一百行代码就能写完。相比直接用数值最优控制解非线性规划它的求解速度快、调试直观而且每一步你都知道问题出在轨迹的哪个段。4. 坑与排查微分平坦不是银弹4.1 平坦输出构造没有通用算法我见过最多人踩的坑就是以为系统平坦就一定能找到平坦输出。事实是微分平坦是一个性质而“找到平坦输出”是一个技术活。它没有通用的自动构造算法更多依赖物理直觉和试错。比如你要找一个新型欠驱动机械臂的平坦输出通常做法是先从系统总能量、动量、几何关系里猜候选变量然后验证是否满足状态和输入都能被有限阶导数表示的条件。这个过程没有标准脚手架理论功底和工程直觉各占一半。我的建议是先从简单的候选开始试比如位置坐标、角度组合、重心投影、能量相关量。验证时不要只做符号演算直接在仿真里丢几个不同输入看反算出来的状态是否和真实系统一致。只要一个候选输出能稳定复现状态基本就是对的。4.2 奇异点与微分同胚失效微分平坦映射本质上是平坦输出空间到状态空间的一个微分同胚但这个同胚通常不是全局成立的。当系统处于奇异位形时映射关系会退化状态和控制量可能瞬间变成无穷大。以 2R 机械臂为例末端位置作平坦输出时当机械臂完全伸直肘部伸直或完全折叠雅可比矩阵奇异关节角速度反解会爆炸。如果规划轨迹恰好穿过这个区域你再光滑的末端轨迹也会换算出一个疯狂抖动的关节轨迹。排查方法很简单在反演过程的每个时间点检查状态转换矩阵的条件数。条件数过大说明你正靠近奇异点这时候需要重新规划路径绕开奇异区或者切换到关节空间的普通插值方式。我把这个检查写成了规划器里的一个默认警报每次跑完轨迹就自动报告最大条件数。4.3 常见误区和排查速查表我整理了几条高频问题直接拿去对照症状可能原因解决办法反算出的控制输入振荡平坦输出轨迹不够光滑提高参数化阶数或改用B样条并保证高阶导数连续轨迹满足约束但实机抖动忽略了执行器带宽限制在平坦输出空间加低通滤波或加频率域约束求解器报约束无解时间分配过紧增加轨迹总时间或放宽加加速度上限奇异点附近数值爆炸映射雅可比奇异绕开奇异区或切换局部规划器优化结果对初值敏感目标函数非凸性强用分阶段优化先求可行解再优化还有一个容易出事的点是微分平坦轨迹规划虽然能精确给出前馈控制但它本质上是开环的。如果用前馈直接上机任何模型误差和外部扰动都会累积。所以工程落地时一定要搭配反馈控制器前馈负责把轨迹算准反馈负责把偏差拉回来。5. 实战心得与一点扩展5.1 和传统方法比微分平坦赢在哪输在哪赢的地方很明显建模清晰、变量少、求解快而且规划出来的轨迹物理可解释。尤其是做四旋翼和吊车这类欠驱动系统时微分平坦几乎是一个“开箱即用”的利器。输的地方同样明显它对系统结构要求苛刻不是所有系统都平坦平坦输出的构造依赖人工经验约束处理在平坦输出空间经常变成高度非线性的不等式优化求解时依然需要小心处理。所以在机械臂项目里我的选择思路是这样的如果是全驱动刚性臂普通关节空间规划器就够用微分平坦更多是给你提供一种动力学校验视角如果是柔性关节、移动机械臂这类欠驱动或者强耦合系统微分平坦就是改变游戏规则的存在。另外微分平坦还有个隐藏用法——它可以当“轨迹生成器”的前置滤波器。哪怕你最终用 RRT、MPC 这类算法也可以先在平坦输出空间里生成多条候选轨迹然后用其他算法再做避障和优化。我最近在做的移动机械臂协同规划就是把移动底座和机械臂的联合模型近似成平坦系统先出几何可行路径再用局部 MPC 修整动态约束效果比从头到尾硬解一套非线性规划好太多。5.2 我踩过的几个坑第一个坑是参数化阶数贪多。一开始我总喜欢把轨迹阶数设得很高觉得高阶光滑肯定好。结果反算出来的控制输入在边界附近剧烈抖动频域上一堆高频分量。后来才明白平坦输出空间的光滑不等于控制输入空间的平滑关键要看系统对这个输出的“相对阶”。高相对阶系统输出轨迹哪怕只抖一点点控制量也会被放大得很厉害。解决方式是限制平坦输出最高非零导数的平方积分也就是做各阶导数的加权正则化。第二个坑是忽略了模型参数的不确定性。微分平坦反演完全依赖模型参数稍微一偏前馈控制就是错的。我第一次拿柔性关节臂上真机时弹簧刚度标定偏了 5%规划轨迹看着没毛病一上电连杆直接开始震荡。之后我在规划目标函数里加了对模型误差的鲁棒项把弹簧刚度的不确定区间代入如果反算的控制量在不同刚度下差异过大就降低该处轨迹的曲率或速度。第三个坑是时间最优的诱惑。微分平坦让你很容易写出一个“时间最优”目标函数让轨迹在约束边界上飞。解出来很漂亮工程上一跑就废因为实机不是一个精确的代数系统一点摩擦、一点间隙都会让贴着约束边界的轨迹失稳。我现在做的项目几乎都改成“时间次优 约束裕量”把力矩上限的 90% 当 100% 用反而总任务时间差别不大稳定性大幅提升。最后分享一个小技巧。如果你拿到的系统不满足微分平坦别急着换方法试着做一下状态扩展把某个状态的时间导数定义成新状态有可能会让扩展后的系统变成平坦的。这也是很多仓库机器人、飞行机械臂团队常用的手段。做规划之前花一天时间在模型上找平坦输出比后面花一周调优化求解器划算得多。