简介:这份PDF文献面向水下机器人控制方向的研究生、科研人员与无人系统开发者,聚焦外部干扰下轨迹跟踪精度难以保证的问题,给出基于干扰观测器的预定性能控制方案。资源为单篇论文,压缩包内仅含1个PDF文件,约2.12MB,内容完整呈现了从干扰观测器设计、前馈补偿到非奇异快速积分终端滑模控制器的推导过程。文中引入指数型障碍李雅普诺夫函数,使跟踪误差在有限时间内收敛至零并满足预定性能边界,同时有效抑制传统滑模的抖动现象,并附有波浪、水流及海洋生物扰动等仿真案例验证。已有93人学习,适合希望深入理解有限时间干扰观测器与预定性能控制结合思路、并借鉴其数学证明与仿真验证方法的读者参考。
1. 从一次水池试验翻车说起:预定性能控制到底在解决什么
去年秋天,我们在两米深的试验水池里跑一台六推进器作业型 ROV,任务很简单:定深两米,悬停。结果第一次下水就翻车了——深度曲线在目标值附近来回振荡,超调接近 0.4 米,稳态误差始终压不到 5 厘米以内。控制器参数调了三轮,PID 换了两套,效果都不理想。问题不在 PID 本身,而在于我们从来没告诉控制器「你要以多快的速度、允许多大的超调、最终收敛到多小的误差带」——这些指标全靠试凑,而水下机器人面对的是时变浮力、脐带缆拉力、推进器死区、水流扰动叠加的复杂工况,试凑出来的参数换个工况就失效。
这就是预定性能控制(Prescribed Performance Control, PPC)要解决的问题:把「超调不超过多少、收敛时间不超过多少、稳态误差不超过多少」写成显式的数学约束,通过一个误差变换函数把原始跟踪误差映射到新的无约束空间,让控制器在这个空间里设计,从而保证原始误差始终落在预设的性能包络内。配合干扰观测器(Disturbance Observer, DOB)估计并前馈补偿集总扰动,再叠加滑模控制的鲁棒项,就构成了「基于干扰观测器的水下机器人预定性能控制」这条技术路线。它适合谁?适合已经跑通基础 PID 或反步控制、但被工况变化和扰动搞得反复调参的从业者;也适合做水下装备控制算法研究、需要给出一套可复现仿真与水池验证流程的工程师。有限时间收敛是这条路线常见的进阶诉求,后面会单独讲怎么把收敛时间也纳入约束。
2. 干扰观测器与预定性能控制:为什么这两个模块必须一起用
2.1 水下机器人动力学里哪些项该被「观测」掉
水下机器人六自由度动力学模型可以写成:
M(η)η̈ + C(η,η̇)η̇ + D(η,η̇)η̇ + g(η) = τ + τ_d其中 M 是惯性矩阵(含附加质量),C 是科氏力与向心力,D 是水动力阻尼,g 是恢复力(重力与浮力之差),τ 是推进器推力,τ_d 是外部扰动(水流、脐带缆、负载变化)。实际工程中,M、C、D 的标称值都有误差,g 随负载和压载变化,τ_d 不可测。把这些不确定项全部归入「集总扰动」d:
d = ΔM η̈ + ΔC η̇ + ΔD η̇ + Δg + τ_d干扰观测器的作用就是在不测量 d 的前提下,用系统状态和已知输入估计出 d̂,然后在前馈通道里补偿掉。常见做法是非线性干扰观测器(NDOB):
ż = -L(z + L·M₀·η̇) - L(τ - C₀η̇ - D₀η̇ - g₀) d̂ = z + L·M₀·η̇L 是观测器增益矩阵,M₀、C₀、D₀、g₀ 是标称模型项。这个结构本质是一个扩张状态观测器的变体,把 d 当成扩张状态来估计。选它的理由很直接:不需要对 d 做任何先验假设(不需要知道它是常值还是慢变),只要 L 选得让观测器带宽高于扰动的主要频率分量,估计误差就能压到很小。
2.2 预定性能控制的核心:误差变换函数怎么选
PPC 的关键是定义一个性能函数 ρ(t) 和一个误差变换。性能函数通常取:
ρ(t) = (ρ₀ - ρ∞)·exp(-l·t) + ρ∞ρ₀ 是初始误差包络,ρ∞ 是稳态误差上界,l 是收敛速率。跟踪误差 e(t) 被约束在:
-δ·ρ(t) < e(t) < ρ(t) (δ ∈ (0,1] 是超调抑制因子)然后做误差变换,把受约束的 e 映射到无约束变量 ε:
ε = ln( (δ·ρ + e) / (ρ - e) )对 ε 求导,得到变换后的误差动态,控制器在 ε 空间里设计。这样只要 ε 有界,e 就永远落在包络内。这就是「预定性能」四个字的数学含义——性能不是调出来的,是设计进去的。
2.3 滑模控制在这里扮演什么角色
变换后的 ε 动态里仍然含有不确定项和扰动。滑模控制的作用是设计一个滑模面 s = ε̇ + λ·ε,用切换项保证 s 在有限时间内到达零。但纯滑模的切换增益必须大于扰动上界,而水下扰动上界往往估不准,增益取大了抖振严重,取小了鲁棒性不够。这就是为什么要把干扰观测器加进来:用 d̂ 做前馈补偿,滑模切换增益只需要覆盖观测误差,可以大幅降低,抖振随之减小。三者是互补关系,不是简单叠加。
2.4 最小可跑的仿真验证:MATLAB/Simulink 还是 Python
我一般先用 Python 做算法快速验证,再上 Simulink 做工程化。下面是一个单自由度(深度通道)的最小仿真骨架:
import numpy as np # 标称模型参数(深度通道简化) m0, d0, g0 = 120.0, 45.0, 8.0 # 质量、阻尼、恢复力 rho0, rho_inf, l = 0.5, 0.02, 1.2 # 性能函数参数 delta = 0.8 # 超调抑制因子 L = np.diag([30.0, 30.0]) # 观测器增益 lam = 2.0 # 滑模面系数 k_switch = 0.5 # 切换增益(有DOB后可取小) dt, T = 0.001, 30.0 steps = int(T / dt) z = np.zeros(2) # 观测器状态 eta = np.zeros(2) # [深度, 速度] d_hat = 0.0 def rho(t): return (rho0 - rho_inf) * np.exp(-l * t) + rho_inf for k in range(steps): t = k * dt # 参考轨迹:从0平滑到2米 eta_d = 2.0 * (1 - np.exp(-0.8 * t)) e = eta[0] - eta_d # 误差变换 r = rho(t) eps = np.log((delta * r + e) / (r - e)) # 滑模面 s = eps + lam * eps # 简化写法,实际需对eps求导 # 干扰观测器更新(离散化) z = z + dt * (-L @ (z + L @ (m0 * eta[1])) - L @ (tau - d0 * eta[1] - g0)) d_hat = z[0] + L[0,0] * m0 * eta[1] # 控制律:前馈补偿 + 滑模项 tau = m0 * (0.8 * 0.8 * np.exp(-0.8 * t)) + d0 * eta[1] + g0 \ - d_hat - k_switch * np.sign(s) # 真实系统(含未建模扰动) d_true = 5.0 * np.sin(0.5 * t) + 3.0 eta[1] += dt * (tau + d_true - d0 * eta[1] - g0) / m0 eta[0] += dt * eta[1]这段代码里几个参数需要重点说明。rho0决定初始包络,一般取初始误差的 1.2 到 1.5 倍,太小会导致变换函数在 t=0 附近数值爆炸;rho_inf就是你要的稳态误差上界,取 0.02 米意味着最终误差不超过 2 厘米;l控制收敛速度,但不要超过执行器带宽,否则控制量饱和。观测器增益L的选取原则是让观测器极点比控制器闭环极点快 3 到 5 倍,我一般从 20 开始试,逐步加到 50 左右。k_switch在 DOB 正常工作的情况下取 0.3 到 0.8 就够,没有 DOB 时通常要取到 5 以上,抖振会非常明显。
2.5 从仿真到水池:需要改的三个地方
仿真跑通不代表水池能跑。第一,执行器模型要加进去,推进器有死区和饱和,死区会导致小误差时控制量被吃掉,PPC 的包络在稳态段可能被突破;第二,传感器噪声要加,深度计噪声一般在 1 到 2 厘米量级,如果 rho_inf 取 2 厘米,噪声直接吃掉整个误差带,实际工程中 rho_inf 至少取噪声标准差的 3 倍;第三,离散化步长要和实际控制器一致,水池试验常用 100 Hz 到 200 Hz,仿真用 1 kHz 跑出来的结果直接搬到 100 Hz 会出问题,观测器增益需要重新整定。
3. 把控制律落到代码:从连续域到离散域的四个关键步骤
3.1 连续控制律的完整形式与各项含义
把前面几个模块拼起来,完整的控制律是:
τ = M₀·(η̈_d - λ·ε̇) + C₀η̇ + D₀η̇ + g₀ - d̂ - K_s·sat(s/Φ)第一项是标称模型前馈加滑模等效控制,第二到第四项是模型补偿,第五项是干扰前馈补偿,最后一项是滑模切换项。sat(s/Φ)是饱和函数替代符号函数,Φ 是边界层厚度,用来进一步抑制抖振。Φ 取 0.01 到 0.05 之间,太小抖振抑制不够,太大稳态误差会增加。K_s 是切换增益矩阵,对角元素根据各通道观测误差上界来定,一般取观测误差上界的 1.5 倍。
3.2 离散化时最容易出问题的两项
离散化时,误差变换函数和观测器是重灾区。误差变换里的指数项在 t 很小时变化极快,如果直接用前向欧拉离散,dt 稍大就会数值溢出。我的做法是对 ρ(t) 用解析式直接计算,不做数值积分;对 ε 的导数用后向差分,保证数值稳定。观测器离散化推荐用零阶保持或双线性变换,前向欧拉在 L 较大时会发散。下面是一个离散化后的观测器更新:
# 双线性离散化观测器(推荐) A = -L B = -L @ np.array([[0, 0], [0, 0]]) # 根据实际输入矩阵填写 # 双线性变换:Ad = (I + A*dt/2) @ inv(I - A*dt/2) I = np.eye(2) Ad = (I + A * dt / 2) @ np.linalg.inv(I - A * dt / 2) # 每步更新 z = Ad @ z + dt * (-L @ (tau_vec - C0 @ eta[1] - D0 @ eta[1] - g0)) d_hat = z + L @ (m0 * eta[1])注意tau_vec是实际控制输入向量,C0、D0、g0是标称值。双线性变换的好处是在 L 较大时仍然稳定,代价是计算量略增,但 200 Hz 下完全不是问题。
3.3 参数整定的顺序:先观测器,再滑模,最后性能函数
整定顺序错了会浪费大量时间。正确顺序是:先把性能函数放宽(rho0 取大、rho_inf 取大、l 取小),只调观测器,看 d̂ 能不能跟上真实扰动;观测器跟上了,再把滑模切换增益降到刚好能压住观测误差;最后收紧性能函数,观察控制量是否饱和。如果先收紧性能函数再调观测器,控制量会一直饱和,根本看不出观测器效果。我一般用阶跃扰动和正弦扰动两种工况分别验证观测器,阶跃看收敛速度,正弦看相位滞后。
3.4 用仿真数据反推观测器带宽是否够用
一个实用的判断方法:把 d̂ 和 d_true 画在同一张图上,看相位差。如果 d̂ 滞后 d_true 超过 30 度,说明观测器带宽不够,需要加大 L。但 L 不能无限加大,L 太大会放大测量噪声,d̂ 会变得毛刺。折中点是让观测器带宽取扰动主要频率分量的 3 到 5 倍。水下扰动的主要频率一般在 0.1 到 1 Hz,观测器带宽做到 3 到 5 Hz 就够,对应 L 大约在 20 到 50 之间。
4. 避坑与排查:水池试验里最常翻车的五个点
4.1 现象:误差在初始阶段就冲出包络,变换函数报错
原因通常是 rho0 取得太小,初始误差 e(0) 已经接近或超过 delta·rho0,变换函数分母趋近零。解决方法是把 rho0 设为初始误差的 1.5 倍以上,或者在控制器启动前先做一段开环镇定,等误差降下来再切入 PPC。
4.2 现象:稳态误差始终压不到 rho_inf 以内
先查传感器噪声,如果噪声幅值接近 rho_inf,误差带根本不可能守住。再查执行器死区,死区会导致小误差时控制量被吃掉。最后查观测器是否有稳态偏差,如果 d̂ 在稳态时和真实扰动差一个常值,说明观测器积分项没收敛,检查 L 是否太小或离散化是否用了前向欧拉。
4.3 现象:控制量抖振严重,推进器发出明显噪音
切换增益 K_s 取大了,或者边界层 Φ 取小了。有 DOB 的情况下 K_s 应该能降到 1 以下,如果还需要取到 5 以上,说明观测器没工作好。先检查 d̂ 是否真的在补偿,再检查 sat 函数的实现是否正确。另外,推进器本身的响应延迟也会导致抖振,可以在控制量后加一个一阶低通滤波,截止频率取推进器带宽的 2 到 3 倍。
4.4 现象:仿真能跑,水池跑几分钟后发散
最常见的原因是积分饱和。PPC 的变换函数在误差接近包络边界时会急剧增大,控制量随之饱和,饱和后误差继续增大,形成正反馈。解决方法是在控制量后加抗积分饱和逻辑,或者当误差接近包络边界时主动放宽包络。另一个原因是观测器增益在离散化后实际带宽下降,需要重新整定。
4.5 现象:换一个工况(负载变化、水流变化)就失效
这是没有做参数自适应的典型表现。PPC 保证的是误差在包络内,但如果扰动超出观测器带宽,d̂ 跟不上,滑模项又压不住,包络就会被突破。工程上的做法是给观测器加自适应律,让 L 随扰动频率变化调整,或者把性能函数也做成自适应的,扰动大时自动放宽 rho_inf。这属于进阶内容,但水池试验中迟早会遇到。
5. 有限时间收敛与自适应增益:把「预定时间」也写进约束
5.1 从预定性能到预定时间:性能函数换一种形式
前面用的指数型性能函数 ρ(t) = (ρ₀-ρ∞)exp(-lt)+ρ∞ 理论上要到无穷时间才收敛到 ρ∞,严格说不是有限时间。如果任务要求「10 秒内必须收敛到 2 厘米」,就需要换用有限时间性能函数:
ρ(t) = (ρ₀ - ρ∞)·((T-t)/T)^(1/n) + ρ∞, t < T ρ(t) = ρ∞, t ≥ TT 是预定收敛时间,n 是收敛阶数,一般取 2 到 4。这个函数在 t=T 时精确到达 ρ∞,之后保持不变。误差变换的形式不变,但 ε 的动态会多出一项与 (T-t) 相关的时变系数,控制器设计时需要相应调整。注意 T 不能取得比执行器物理响应时间还短,否则控制量必然饱和。
5.2 自适应滑模增益:让切换项自己找上界
固定切换增益的滑模控制需要预先知道扰动上界,而水下扰动上界往往估不准。自适应滑模的做法是让 K_s 随时间自适应调整:
K̇_s = γ·|s|, 当 |s| > ε₀ K̇_s = -σ·K_s, 当 |s| ≤ ε₀γ 是自适应增益,σ 是泄漏项系数,ε₀ 是边界层。这样 K_s 会自动增长到刚好压住扰动,扰动减小时又会缓慢下降,既保证鲁棒性又减少抖振。γ 取 0.5 到 2 之间,σ 取 0.01 到 0.1 之间。这个方法和 DOB 配合使用时,K_s 的稳态值通常能降到 0.5 以下。
5.3 验证方法:用三组工况交叉验证
算法改完后不要只跑一组工况。我一般用三组:第一组,无外部扰动,只验证标称性能;第二组,加常值扰动和正弦扰动,验证观测器和滑模的鲁棒性;第三组,改变模型参数(质量加 20%、阻尼减 30%),验证对模型误差的容忍度。三组都过了,再上水池。水池试验也分三步:先悬停,再定深,最后轨迹跟踪。每一步都记录误差曲线和控制量曲线,事后用包络线画出来,一眼就能看出有没有突破。
5.4 一个具体技巧:用误差包络反推控制器带宽
如果误差曲线在包络内但贴着上边界走,说明控制器带宽不够,需要加大 l 或加大滑模增益。如果误差曲线在包络中间但抖振明显,说明增益过大,需要减小 K_s 或加大 Φ。如果误差曲线在初始阶段冲出包络然后被拉回来,说明 rho0 太小或初始控制量饱和。这三种形态对应三种不同的整定方向,比盲调参数快得多。
我自己的习惯是每次水池试验前,先在仿真里把这三组工况跑一遍,把误差包络和控制量曲线打印出来贴在控制台旁边,试验时对照着看。这个习惯帮我省了至少三轮下水时间。希望帮到你。
本文还有配套的精品资源,点击获取