从微分平坦到轨迹生成:四旋翼无人机状态估计的降维艺术

张开发
2026/4/9 4:56:22 15 分钟阅读

分享文章

从微分平坦到轨迹生成:四旋翼无人机状态估计的降维艺术
1. 从“开飞机”到“画曲线”为什么我们需要降维打击大家好我是老张一个在无人机圈子里摸爬滚打了十来年的工程师。今天想和大家聊聊一个听起来有点“玄乎”但实际上能让你的无人机飞得又稳又准的数学魔法——微分平坦。别被这个名字吓跑咱们用大白话来说它其实就是一种“降维打击”的艺术。想象一下你要遥控一架四旋翼无人机从A点飞到B点并且要它优雅地绕过几个障碍物。你心里想的是“我要它从这里过去然后拐个弯最后稳稳地停在那里。” 你关心的是位置x, y, z和机头的朝向偏航角ψ。这就像你开车你主要关心车开到哪里车头朝哪个方向。但无人机这个“铁疙瘩”内部可复杂多了。它的“大脑”飞控需要时刻知道并控制整整12个状态量这包括位置和姿态3个位置x, y, z 3个姿态角滚转φ俯仰θ偏航ψ。线速度和角速度3个线速度ẋ, ẏ, ż 3个角速度p, q, r。这12个量互相耦合牵一发而动全身。你想直接规划出一条完美的、同时满足这12个量所有约束的轨迹其难度不亚于让你同时用12只手弹钢琴几乎是个“不可能完成的任务”。我在早期做项目时就曾一头扎进这12维的泥潭里调参调到怀疑人生轨迹不是抖就是飘。而微分平坦特性就像一位高明的翻译官。它告诉我们别管那复杂的12维状态了你只需要专心设计好4个平坦输出量——也就是你直观关心的那三个位置x, y, z和一个偏航角ψ——以及它们随时间变化的速度、加速度等导数。只要这条“平坦输出”的轨迹设计得足够光滑比如加速度、加加速度连续我就能唯一地、自动地帮你反推出那12个全状态应该是什么样子包括那些你不太直观的滚转、俯仰角应该怎么变化。这样一来问题就从一个12维空间里的“立体迷宫”降维成了一个4维空间里的“平面绘图”问题。我们从“开飞机”变成了“画曲线”难度直线下降思路瞬间清晰。这就是“降维艺术”的核心化繁为简直击本质。接下来我们就一层层剥开它的神秘面纱。2. 拆解无人机我们到底要控制什么在施展“降维艺术”之前我们得先搞清楚要控制的这个对象——四旋翼无人机——到底是怎么运动的。这可不是一个简单的质点。2.1 两个关键坐标系世界系与机体系所有状态量都必须放在某个“舞台”上描述这个舞台就是坐标系。无人机领域最核心的两个坐标系是世界坐标系W系固定在地面上的“上帝视角”。通常Z轴指向重力反方向天空X和Y轴指向水平方向。我们说的“飞到5, 10, 2米处”指的就是在世界系下的位置。机体坐标系B系牢牢“长”在无人机身上的视角。原点在无人机重心X轴指向机头方向Y轴指向机身左侧Z轴指向上方垂直于桨平面。无人机所有的运动都可以理解为机体系相对于世界系的运动。飞控的核心任务就是计算如何控制四个电机的转速来产生合适的力和力矩从而让机体系按照我们期望的方式在世界系中运动。2.2 核心运动方程力与力矩的平衡四旋翼是一个典型的欠驱动系统。什么意思它有4个控制输入四个电机的转速但却要控制6个自由度的运动3个位置3个姿态。这就像你只有油门和方向盘2个输入却想完全控制车的所有移动一样有些运动是耦合的、非独立的。其最核心的运动方程描述了无人机质心的平动m * r_ddot -m * g * z_W u1 * z_B我来翻译一下m是无人机质量。r_ddot是无人机在世界系下的加速度向量[x_ddot, y_ddot, z_ddot]。-m*g*z_W是永远向下的重力。u1 * z_B是无人机产生的总升力这个力永远沿着机体坐标系的Z轴方向。u1是四个电机产生的总拉力。这个方程揭示了一个关键事实无人机能产生的推力方向完全由它的姿态具体说是机体Z轴z_B的方向决定。你想让无人机向左加速不是直接“推”它向左而是需要它先倾斜改变姿态让推力产生一个向左的分量。所以姿态滚转φ俯仰θ本质上是为了服务位置控制而产生的“中间变量”。我们真正想直接指定的是位置轨迹x(t), y(t), z(t)和偏航角ψ(t)。而微分平坦理论正是完美地契合了这一工程直觉。3. 魔法核心微分平坦特性到底是什么说了这么多铺垫现在正式请出我们的主角微分平坦特性。它不是一个算法而是一类动态系统所具有的数学性质。如果一个系统是微分平坦的那么存在一组特殊输出称为“平坦输出”使得系统的所有状态变量和控制输入都可以用这组平坦输出及其有限阶导数的代数组合来表示而不需要任何积分操作。对于四旋翼无人机经过前人证明它就是一个微分平坦系统。而其平坦输出正是我们心心念念的那四个直观的量平坦输出 σ [x, y, z, ψ]^T也就是说只要我任意指定一条关于时间t的四维轨迹σ(t) [x(t), y(t), z(t), ψ(t)]^T并且这条轨迹足够光滑通常要求其四阶导数——加加速度——是连续的那么我就能像查字典一样直接写出任意时刻t的全部12个状态位置、姿态角、速度、角速度。全部4个控制输入总拉力u1和三个姿态力矩[u2, u3, u4]。3.1 一个生动的类比开车去旅行让我们用一个更生活的例子来理解。假设你计划一次自驾游控制无人机。平坦输出就是你规划的路线图和车头朝向。路线图就是(x(t), y(t))海拔变化就是z(t)在岔路口你想让车头指向哪个风景方向就是ψ(t)。系统状态包括你的车速、发动机转速、方向盘转角、轮胎侧偏角等等一大堆复杂的车辆动力学状态。控制输入你脚下的油门、刹车和手上的方向盘。如果没有“微分平坦”这个特性你就得是个车辆动力学专家精确计算每一秒的油门开度和方向盘转角才能勉强让车沿着大致路线走过程会非常颠簸和困难。但有了“微分平坦”特性假设车也具有这个性质事情就简单了你只需要专心设计一条平滑优美的行驶路线平坦输出轨迹。只要你设计的路线本身是合理的曲率连续、不会急转弯那么你的“自动驾驶系统”就能自动地、唯一地计算出该用多大的油门、打多少方向盘来让你的车严丝合缝地跑在这条线上。所有的发动机状态、轮胎状态都成为了这条完美路线的自然结果。在无人机上这个“自动驾驶系统”的计算公式就是通过微分平坦关系式推导出来的。3.2 从平坦输出“变”出全部状态具体是怎么“变”出来的呢我们顺着公式走一遍核心步骤大家感受一下其精妙得到加速度从而确定推力方向我们对平坦输出中的位置(x, y, z)求二阶导得到加速度a [x_ddot, y_ddot, z_ddot g]^T。注意z方向要加上重力加速度g。根据牛顿方程m*a F_thrust这个加速度方向就是总推力u1的方向。因此机体Z轴z_B的单位向量立刻可得z_B a / ||a||同时总拉力大小也出来了u1 m * ||a||。确定偏航轴从而“锁定”机体坐标系我们指定的平坦输出里包含了偏航角ψ(t)。这意味着我们知道了无人机在世界系下的偏航方向。我们可以构造出与这个偏航方向对齐的一个中间坐标系C的X轴方向x_C例如x_C [cosψ, sinψ, 0]^T。叉乘出完整的机体坐标系现在我们有了z_B推力方向和x_C期望的偏航投影方向。由于机体坐标系的Y轴y_B必须垂直于z_B和x_B而x_B又需要垂直于z_B和y_B并且我们希望x_B尽可能靠近x_C的方向即实现指定的偏航。通过一系列的向量正交化操作例如先令y_B (z_B × x_C) / ||z_B × x_C||再令x_B y_B × z_B我们就能唯一地确定出机体坐标系的X轴x_B和Y轴y_B。一切水到渠成有了[x_B, y_B, z_B]这三个单位向量把它们并排放在一起就构成了从世界系到机体系的旋转矩阵^W_R_B。从这个旋转矩阵中我们可以反解出无人机的滚转角φ和俯仰角θ。再对姿态角求导就能得到角速度(p, q, r)。而速度(ẋ, ẏ, ż)就是位置平坦输出的一阶导数。看我们从头到尾只使用了平坦输出[x, y, z, ψ]及其一阶、二阶导数通过纯粹的代数运算加减乘除、叉乘、归一化就得到了所有状态和控制量。没有积分没有求解复杂的微分方程。这就是微分平坦的威力所在——它将一个复杂的轨迹跟踪控制问题转化为了一个相对简单的平坦输出轨迹设计问题。4. 实战如何设计一条“平坦”的轨迹理论很美好但最终要落地到代码。当我们理解了微分平坦之后轨迹生成的任务就变得非常明确如何生成一条时间参数化的、足够光滑的四维曲线 σ(t) [x(t), y(t), z(t), ψ(t)]这正是Minimum Snap轨迹生成算法大显身手的地方。它的目标简单粗暴生成一条轨迹让其在满足所有位置、速度、加速度边界条件和中间路径点约束的同时“加加速度”的平方积分Snap最小。4.1 为什么是Minimum Snap我们可以从物理和工程两个角度理解物理角度Snap是加加速度的导数也就是力对时间的导数。最小化Snap的积分意味着电机推力变化最为平滑。这对于减少机载设备的振动、节省能量、提升乘坐舒适度如果有载具的话至关重要。工程角度要使平坦输出σ(t)能够通过微分平坦关系式反算出所有状态它至少需要是四阶可导的因为我们要用到加速度而加速度是位置的二阶导在反算角速度时还会用到更高阶导。Minimum Snap直接保证了轨迹的高阶光滑性。4.2 动手实现一个简单的Minimum Snap轨迹生成假设我们有一系列路径点[p0, p1, p2, ..., pn]每个点包含x, y, z坐标以及无人机到达每个点的时间[t0, t1, t2, ..., tn]。我们希望生成一条连接所有点的平滑轨迹。通常我们会对每个坐标轴x, y, z独立进行规划方法完全相同。这里以x轴为例。步骤1选择多项式表示在每一段时间区间[t_k, t_{k1}]内我们用一条高阶多项式来表示x轴的位置x_k(t) a_{k0} a_{k1}t a_{k2}t^2 ... a_{kN}t^N, 其中t ∈ [0, t_{k1}-t_k]。 通常取N7七次多项式因为它有8个系数足以满足两端各4个约束位置、速度、加速度、加加速度。步骤2构建约束方程我们需要满足的约束包括路径点约束在时间t_k多项式x_k(t)的值必须等于路径点坐标p_k.x。连续性约束在路径点连接处前后两段多项式在位置、速度、加速度、加加速度甚至Snap上应该是连续的。例如在t_k时刻x_{k-1}的终点速度必须等于x_k的起点速度。边界约束起点和终点的速度、加速度等通常可以指定例如从静止开始到静止结束。所有这些约束都是关于多项式系数a_{ki}的线性方程。步骤3构建优化问题我们的目标是最小化整个轨迹的Snap平方积分。对于一段多项式其Snap是四阶导平方积分是一个关于系数a_{ki}的二次型。整个轨迹的总代价就是各段代价之和也是一个关于所有系数的巨大二次型。因此问题转化为在满足一系列线性等式约束步骤2的前提下最小化一个二次代价函数。这在数学上称为**二次规划QP**问题。步骤4求解与得到轨迹二次规划问题有成熟高效的求解器例如OSQP, qpOASES。我们将约束矩阵和代价矩阵构建好扔给求解器就能得到最优的多项式系数a_{ki}。对于每一个时刻t我们只需找到它所属的时间段代入对应的多项式求值就能得到x(t)求导得到速度ẋ(t)、加速度x_ddot(t)等。对y, z轴重复此过程再单独为偏航角ψ设计一条平滑的轨迹可以用较低阶的多项式我们就得到了一条完整的、光滑的平坦输出轨迹σ(t)。# 一个高度简化的Minimum Snap单段轨迹示例使用numpy import numpy as np # 假设从p0到p1时间从0到T约束起点和终点的位置、速度、加速度 p0, v0, a0 0, 0, 0 # 起点状态 p1, v1, a1 10, 0, 0 # 终点状态 T 5.0 # 时间 # 对于一段5次多项式x(t) a0 a1*t a2*t^2 a3*t^3 a4*t^4 a5*t^5 # 我们有6个系数需要6个约束条件 # 约束t0时位置p0速度v0加速度a0tT时位置p1速度v1加速度a1 A np.array([ [1, 0, 0, 0, 0, 0], # t0: position [0, 1, 0, 0, 0, 0], # t0: velocity (一阶导) [0, 0, 2, 0, 0, 0], # t0: acceleration (二阶导) [1, T, T**2, T**3, T**4, T**5], # tT: position [0, 1, 2*T, 3*T**2, 4*T**3, 5*T**4], # tT: velocity [0, 0, 2, 6*T, 12*T**2, 20*T**3] # tT: acceleration ]) b np.array([p0, v0, a0, p1, v1, a1]) # 求解线性方程组 A * coeff b coeff np.linalg.solve(A, b) # coeff [a0, a1, a2, a3, a4, a5] print(多项式系数:, coeff) # 现在我们可以用这个多项式来生成轨迹了 def eval_trajectory(coeff, t): 在时间t计算位置、速度、加速度 pos np.polyval(coeff[::-1], t) # numpy多项式系数顺序是降幂 # 手动求导对于演示 vel coeff[1] 2*coeff[2]*t 3*coeff[3]*t**2 4*coeff[4]*t**3 5*coeff[5]*t**4 acc 2*coeff[2] 6*coeff[3]*t 12*coeff[4]*t**2 20*coeff[5]*t**3 return pos, vel, acc # 测试在t2.5秒时的状态 pos, vel, acc eval_trajectory(coeff, 2.5) print(f在t2.5s时: 位置{pos:.2f}, 速度{vel:.2f}, 加速度{acc:.2f})注意以上是单段、固定阶数的简化示例。真正的Minimum Snap是多段、高阶如七次的并且优化目标是Snap最小化而不是简单地解线性方程。实际应用中会使用更专业的优化库来构建和求解QP问题。5. 闭环从轨迹生成到飞控执行生成了平坦输出轨迹σ(t)并通过微分平坦关系式实时计算出了期望的全状态[x, y, z, φ, θ, ψ, ẋ, ẏ, ż, p, q, r]_des以及控制输入[u1, u2, u3, u4]_des是不是就大功告成了还不是。这仅仅是前馈部分相当于给了无人机一份完美的“剧本”。现实中无人机总会受到风扰、模型不准确、电机响应不一致等因素影响导致它无法完美地“按剧本演出”。因此我们需要反馈控制来纠正误差。一个典型的双环控制结构如下外环位置环根据期望位置(x_des, y_des, z_des)和实际位置(x, y, z)的误差通过PID等控制器计算出期望的加速度(x_ddot_cmd, y_ddot_cmd, z_ddot_cmd)。这个指令加速度会和轨迹本身提供的期望加速度结合。微分平坦转换层核心将结合后的指令加速度以及期望的偏航角ψ_des作为新的“修正后”的平坦输出代入微分平坦公式。这一步是关键它实时地、根据当前误差重新计算了无人机此时此刻“应该”有的姿态和总拉力。输入指令加速度a_cmd期望偏航ψ_des。输出期望姿态角(φ_des, θ_des)期望总拉力u1_des。内环姿态环根据微分平坦层计算出的期望姿态(φ_des, θ_des, ψ_des)和当前实际姿态(φ, θ, ψ)的误差通过姿态控制器通常比位置环快一个数量级计算出期望的机体角速率(p_des, q_des, r_des)。最内环角速率环根据期望角速率和实际角速率的误差计算出三个姿态力矩(u2, u3, u4)最终分配到四个电机的转速指令上。通过这样的前馈轨迹微分平坦反馈多环PID的结构无人机就能既跟随规划的优美轨迹又能抵抗干扰实现稳定、精准的飞行。我在实际飞控调试中发现微分平坦前馈的引入能极大地减轻反馈控制器的压力让整个系统响应更快、超调更小。尤其是在执行高速、大机动动作时没有前馈的纯反馈控制器会非常吃力而结合了微分平坦前馈后飞行品质会有质的提升。6. 避坑指南与进阶思考掌握了基本原理和流程后在实际应用中还会遇到不少坑。这里分享几个我踩过的和常见的注意事项坑1轨迹的光滑性不足这是最常见的问题。如果你的平坦输出轨迹σ(t)本身不够光滑例如加速度突变那么通过微分平坦反算出来的期望姿态和角速度就可能出现跳变甚至无穷大例如当加速度a接近零时计算z_B a/||a||会出问题。这会导致飞控发散。务必保证你生成的轨迹至少是四阶连续可导的C4连续这也是为什么Minimum Snap成为主流选择。坑2对偏航角ψ处理的忽视很多初学者只关注位置轨迹(x,y,z)对偏航角ψ随便给个固定值或简单规划。这在高动态飞行中可能有问题。剧烈的偏航变化会产生显著的角加速度消耗额外动力并可能与其他轴耦合引发震荡。一个建议是为ψ也单独生成一条平滑的低阶多项式轨迹如三次样条使其变化率偏航角速度有界。坑3忽略动力学可行性微分平坦保证了数学上的可表示性但没保证物理上的可实现性。通过平坦输出反算出的期望姿态角(φ, θ)和总拉力u1必须在无人机的物理极限内。例如最大倾斜角通常30-45度。最大可用拉力电机最大推力减去重力。最大角速度/角加速度。 在轨迹生成后或在前馈计算后必须进行检查和限幅。更高级的做法是在轨迹优化问题中直接将这些约束作为不等式条件加入。进阶思考微分平坦的局限与扩展微分平坦特性是四旋翼模型的一个“礼物”但它依赖于一个理想的刚体模型。在以下情况需要格外小心严重的气动效应在高速飞行时空气阻力不再是简单的线性项可能会破坏平坦特性。吊挂负载或机械臂系统动力学发生巨变不再是简单的四旋翼模型需要重新验证或寻找新的平坦输出。模型参数不确定质量m、转动惯量I不准确会导致前馈计算有偏差更需要依赖反馈环的鲁棒性。尽管有这些局限微分平坦理论无疑为我们提供了一把解开四旋翼控制难题的“金钥匙”。它将一个天马行空的轨迹设想与底层复杂的电机控制通过清晰优雅的数学桥梁连接了起来。当你看到无人机沿着一条计算出来的光滑曲线精准飞行时你会感受到这种“降维艺术”带来的工程之美。它让我想起一句老话好的理论不应该让问题变得更复杂而应该让它变得简单到显而易见。微分平坦对于四旋翼的轨迹生成与控制来说正是这样一个“显而易见”的利器。

更多文章