简介:这份资源围绕比例式自动驾驶仪的设计与实现展开,面向航空自动控制、飞行器控制及相关专业的学生与工程技术人员,帮助读者理解俯仰角比例控制的基本原理与工程落地方法。压缩包共4个文件,约629KB,包含pdf与docx两类文档,分别用于理论阐述与案例分析,另有m脚本与slx仿真模型,便于在MATLAB环境中复现控制回路、调整比例增益并观察系统响应。资源重点讨论比例控制策略、比例增益对稳定性的影响以及静态误差等典型问题,读者可据此搭建仿真、验证控制器参数,并对照文档中的数学模型与稳定性分析思路排查设计缺陷。目前已有624人学习下载,适合作为课程设计、毕业设计或自学飞行控制时的参考材料。
1. 比例式自动驾驶仪:从飞控回路到可复现的工程落地
比例式自动驾驶仪这个词,第一次听到的人多半会以为是某种整机产品,其实它描述的是一类控制律结构——把姿态或航向偏差按比例系数直接映射成舵面/推力指令,回路里没有积分项、没有微分项,只有一路增益。它常见于小型固定翼、多旋翼的增稳内环,也常被拿来做飞控入门的第一课,因为结构足够简单,参数足够少,出问题时能一眼看出是哪一环在捣乱。真正让从业者头疼的不是“比例”两个字,而是比例系数怎么定、采样周期怎么配、执行机构延迟怎么补。这篇笔记就围绕这三个问题展开,从回路结构讲到可复现的仿真与实机调试步骤,适合刚接触飞控回路、想自己搭一套增稳逻辑的开发者,也适合已经用过现成飞控、想搞清楚内部那几行控制代码到底在干什么的人。
比例式自动驾驶仪的核心价值在于“可解释”。串级 PID 调参时,内环外环互相耦合,一个参数动全身;而纯比例回路里,你改 Kp,响应快慢和超调量几乎线性变化,调参过程像拧一个旋钮。代价是稳态误差——比例项天生消不掉恒定扰动带来的偏差,所以它通常只做增稳,不做精确航迹跟踪。理解这个边界,比背公式重要得多。
2. 比例式自动驾驶仪的回路结构与选型理由
2.1 为什么先做比例回路而不是直接上 PID
很多飞控教程一上来就讲 PID,结果新手把三个参数一起调,飞机在天上画龙。比例式自动驾驶仪的思路是先把问题简化:假设执行机构响应足够快、传感器噪声足够小,那么姿态偏差和舵面偏转之间就是一个纯增益关系。先把这一层调稳,再考虑要不要加积分消静差、加微分抑制超调。
从控制理论看,纯比例控制器的传递函数是 C(s)=Kp,闭环带宽大致由 Kp 和对象增益的乘积决定。Kp 太小,飞机对扰动反应迟钝,阵风来了要好几秒才回正;Kp 太大,回路相位裕度下降,出现等幅振荡甚至发散。这个边界在仿真里很容易复现,实机上却因为延迟和噪声变得模糊,所以选型顺序应该是:先仿真定 Kp 量级,再实机微调。
常见做法是给滚转、俯仰、偏航三个通道各配一个独立的比例增益,通道之间不交叉。这样每个通道可以单独测试:只给滚转通道增益,手动施加滚转扰动,看回正速度。多旋翼上这套逻辑通常跑在 400Hz 到 1kHz 的内环里,固定翼可以低一些,200Hz 到 500Hz 足够。
2.2 回路里必须明确的三个物理量
搭比例式自动驾驶仪之前,先把这三个量定义清楚,否则后面调参全是玄学。
第一个是误差定义。姿态误差是“期望角减实际角”还是反过来,直接决定 Kp 的符号。我一般统一成“期望减实际”,这样正 Kp 对应正舵面修正,符号不会乱。
第二个是执行机构映射。比例回路输出的是一个归一化指令,比如 -1 到 1,需要再映射到舵机 PWM 占空比或电机推力差。映射关系如果是非线性的,比例回路的线性假设就不成立,调出来的 Kp 只在一个小范围内有效。
第三个是采样与延迟。传感器采样、滤波、控制计算、执行机构响应,每一环都引入延迟。纯比例回路对延迟的容忍度比 PID 低,因为没有任何相位超前补偿。经验上,如果总延迟超过回路期望响应时间的十分之一,Kp 就调不上去,飞机要么软要么振。
下面这张表是我在选型时用来快速判断的参考,数值来自常见小型平台的量级,不是绝对标准。
| 物理量 | 典型范围 | 对比例回路的影响 |
|---|---|---|
| 内环采样率 | 200-1000 Hz | 低于 200Hz 时延迟占比大,Kp 上限被压低 |
| 传感器滤波截止 | 20-80 Hz | 截止太低引入相位滞后,太高噪声进回路 |
| 舵机/电调响应 | 10-30 ms | 超过 30ms 时比例回路容易振荡 |
| 期望姿态带宽 | 1-3 Hz | 决定 Kp 的初始量级 |
2.3 用 Python 搭一个最小比例回路仿真
仿真不是为了发论文,是为了在炸机之前把 Kp 的量级摸清楚。下面这段代码用一阶对象加纯延迟模拟一个滚转通道,比例控制器直接输出舵面指令,跑阶跃响应看超调和稳态误差。
import numpy as np import matplotlib.pyplot as plt # 一阶对象:滚转角速度对舵面指令的响应 # tau 为时间常数,delay_steps 为纯延迟步数 tau = 0.15 # 对象时间常数,单位秒 delay_steps = 3 # 纯延迟,单位控制步 dt = 0.005 # 控制周期 5ms,对应 200Hz T = 2.0 # 仿真时长 steps = int(T / dt) # 比例增益,先给一个中间值 Kp = 2.5 # 状态初始化 rate = 0.0 cmd_history = [0.0] * delay_steps rate_history = [] for k in range(steps): # 期望角速度,1秒时给阶跃 ref = 1.0 if k * dt >= 1.0 else 0.0 # 比例控制:误差乘增益 error = ref - rate cmd = Kp * error # 延迟队列 cmd_history.append(cmd) delayed_cmd = cmd_history.pop(0) # 一阶对象离散更新 rate += (delayed_cmd - rate) * dt / tau rate_history.append(rate) # 画图看响应 t = np.arange(steps) * dt plt.plot(t, rate_history, label='actual rate') plt.axhline(y=1.0, color='r', linestyle='--', label='reference') plt.xlabel('time (s)') plt.ylabel('roll rate') plt.legend() plt.title('Proportional autopilot step response, Kp=2.5') plt.grid(True) plt.show()这段代码里,tau和delay_steps是两个关键参数。tau越大,对象越迟钝,同样的 Kp 下响应越慢;delay_steps越大,比例回路的相位裕度越低,Kp 稍大就振荡。跑一遍之后把 Kp 从 1 调到 8,你会看到一条清晰的分界线:Kp 小于 3 时响应软但稳定,3 到 5 之间超调明显,超过 6 开始等幅振荡。这个分界线的位置会随延迟变化,所以实机上不能照搬仿真值,但量级是对的。
提示:仿真里对象是一阶的,真实飞机滚转通道接近二阶,超调会比仿真更大。实机 Kp 一般从仿真值的 60% 开始试。
3. 从仿真到实机:比例式自动驾驶仪的部署步骤
3.1 传感器数据链路与姿态解算的对接
比例回路吃的是姿态角或角速度,所以第一步是把传感器数据整理成回路能用的格式。常见做法是 IMU 原始数据先过姿态解算,输出滚转/俯仰/偏航角和对应角速度,再送进比例控制器。这里有两个容易翻车的点:坐标系方向和单位。
坐标系方向必须和误差定义一致。如果姿态解算输出的是“实际角”,而你的误差是“期望减实际”,那 Kp 的符号就取决于期望角的定义方向。我一般会在代码里加一个符号常量,实机测试时先给一个小 Kp,手动倾斜飞机,看舵面修正方向对不对,不对就翻符号,不要靠猜。
单位方面,角速度用度每秒还是弧度每秒,直接决定 Kp 的数值。仿真里如果用弧度,实机代码用度,Kp 会差 57 倍。建议全链路统一用弧度,显示的时候再转成度。
下面是一个姿态数据对接的伪代码结构,展示数据怎么从传感器流到比例控制器。
# 假设 imu 提供角速度,attitude 提供姿态角 # 统一用弧度制 def control_loop(imu, attitude, setpoint, Kp, dt): # 取当前姿态和角速度 roll = attitude.roll # 弧度 roll_rate = imu.gyro_x # 弧度每秒 # 期望滚转角,来自遥控或上层指令 roll_ref = setpoint.roll # 弧度 # 比例控制:姿态误差乘增益,再减去角速度阻尼 # 这里用姿态比例加角速度比例,本质还是比例回路 error = roll_ref - roll cmd = Kp * error - 0.1 * roll_rate # 限幅,防止指令超出执行机构范围 cmd = max(-1.0, min(1.0, cmd)) return cmd这段代码里Kp是姿态比例增益,后面那个0.1是角速度阻尼系数,严格说它引入了微分作用,但在工程上常被当作比例回路的一部分来调。如果你要纯比例,把角速度项去掉,只用Kp * error,但实机上纯姿态比例容易振荡,加一点角速度反馈是常见做法。dt参数在这里没直接用到,但实际部署时控制周期必须稳定,否则等效增益会随周期波动。
3.2 比例增益的实机调试流程
实机调试比例式自动驾驶仪,我一般分四步走,每一步只改一个变量。
第一步,地面测试。飞机固定,电机不转或怠速,手动给遥控指令,看舵面/电机响应方向是否正确,幅值是否合理。这一步能抓出符号错误和映射错误。
第二步,低增益悬停或滑跑。Kp 取仿真值的 30%,起飞后只做小幅度滚转/俯仰指令,观察飞机回正速度。如果飞机反应迟钝但稳定,说明 Kp 偏低;如果出现高频抖动,说明 Kp 偏高或延迟太大。
第三步,逐步加增益。每次加 20%,重复小幅度扰动测试,直到出现轻微振荡,然后回退到上一个稳定值。这个值就是实机可用上限。
第四步,加扰动测试。在阵风或手动拨杆扰动下看恢复时间,如果恢复太慢但又不振荡,说明 Kp 受延迟限制,需要考虑降低滤波延迟或提高采样率,而不是继续加 Kp。
整个流程里,最容易被忽略的是第三步的“轻微振荡”判断。实机上高频抖动可能被机身振动掩盖,建议用日志记录角速度波形,看是否有等幅振荡分量。光靠手感容易把噪声当振荡,把 Kp 调得过低。
3.3 参数表与安全限幅设置
比例式自动驾驶仪的参数不多,但每个都要有明确的物理意义和限幅。下面这张表是我在部署时用的检查清单,参数名是通用叫法,具体代码里可能不同。
| 参数 | 含义 | 典型值 | 限幅建议 |
|---|---|---|---|
| Kp_roll | 滚转比例增益 | 0.8-2.5 | 不超过仿真振荡值的 70% |
| Kp_pitch | 俯仰比例增益 | 0.6-2.0 | 俯仰通道通常比滚转低 |
| Kp_yaw | 偏航比例增益 | 0.3-1.2 | 偏航响应慢,增益不宜高 |
| cmd_limit | 指令限幅 | ±1.0 | 必须小于执行机构物理极限 |
| rate_damp | 角速度阻尼 | 0.05-0.2 | 抑制姿态比例带来的振荡 |
限幅设置是安全底线。比例回路在误差大时输出会很大,如果不限幅,舵面打满可能导致飞机进入危险姿态。我一般把cmd_limit设在执行机构物理行程的 80%,留 20% 余量给控制回路。
注意:偏航通道的比例增益不要照搬滚转通道。偏航力矩通常更弱,同样的 Kp 下响应慢,但增益给大了又容易和滚转耦合,出现荷兰滚。
4. 比例式自动驾驶仪避坑:五条血泪经验
4.1 现象:飞机高频抖动,降低 Kp 后消失,但响应变软
原因:高频抖动不一定是 Kp 太大,也可能是传感器噪声进回路。比例回路对噪声没有抑制能力,噪声乘 Kp 直接变成舵面抖动。降低 Kp 只是把噪声幅值压下去了,代价是响应变慢。
解决:先看角速度波形,如果抖动频率接近传感器滤波截止频率,说明是噪声问题。把滤波截止降低,或者加一个低通滤波在控制输出上,再重新调 Kp。不要一味降 Kp。
4.2 现象:仿真里稳定的 Kp,实机上振荡
原因:仿真对象是一阶加纯延迟,实机是二阶甚至更高阶,相位滞后更大。另外实机还有执行机构动态、机身弹性、传感器安装误差,这些在仿真里都没建模。
解决:实机 Kp 从仿真值的 50%-60% 开始,不要直接照搬。如果实机振荡频率明显低于仿真,说明延迟比仿真大,优先查传感器滤波和舵机响应。
4.3 现象:飞机回正后总有一个固定偏差,消不掉
原因:比例回路天生有稳态误差。恒定扰动(比如重心偏移、侧风)需要持续的控制指令来抵消,而比例控制器的输出正比于误差,误差为零时输出为零,所以必须保留一个误差才能产生抵消指令。
解决:这是比例回路的固有特性,不是 bug。如果偏差不可接受,加积分项,但加积分会引入新的调参维度。我的习惯是先用比例回路把动态响应调好,再决定要不要加积分,不要一开始就上 PID。
4.4 现象:改了一个通道的 Kp,另一个通道也跟着振
原因:通道间耦合。滚转和偏航在气动上耦合,俯仰和油门也可能耦合。比例回路没有解耦能力,一个通道的增益变化会通过耦合路径影响另一个通道。
解决:先调耦合最弱的通道,通常先调俯仰,再调滚转,最后调偏航。如果耦合严重,考虑在控制输出上加解耦项,但那已经超出纯比例回路的范围了。
4.5 现象:日志里角速度波形正常,但飞机就是不稳
原因:控制周期不稳定。比例回路的等效增益和周期强相关,如果控制循环偶尔被其他任务打断,周期从 5ms 变成 10ms,等效 Kp 就翻倍,回路可能瞬间进入振荡。
解决:把控制循环放在高优先级任务里,或者用硬件定时器触发。检查日志里控制周期的时间戳,如果抖动超过 20%,先解决调度问题,再调 Kp。
5. 比例式自动驾驶仪的进阶技巧:用频域方法快速定位 Kp 上限
调参调到后面,靠试凑效率太低。我后来习惯用频域方法先估一个 Kp 上限,再去实机微调。具体做法是:给飞机或仿真对象一个扫频激励,记录输入输出,估计开环频率响应,找到相位裕度 45 度对应的频率,那个频率处的增益就是 Kp 的参考上限。
实机上做扫频不太方便,但可以在仿真里做,或者用飞行日志里的扰动数据做离线估计。下面这段代码演示怎么从仿真数据里估计相位裕度,思路是用 FFT 算频率响应,再找相位穿越频率。
import numpy as np # 假设已经采集到输入指令和输出角速度 # u 为输入,y 为输出,dt 为采样周期 # 这里用仿真生成一段数据做示例 dt = 0.005 T = 5.0 steps = int(T / dt) t = np.arange(steps) * dt # 输入用扫频信号,频率从 0.5Hz 到 20Hz u = np.sin(2 * np.pi * (0.5 + 3.9 * t / T) * t) # 假设对象是一阶加延迟,输出用简单模型生成 tau = 0.15 delay = 3 y = np.zeros(steps) for k in range(delay, steps): y[k] = y[k-1] + (u[k-delay] - y[k-1]) * dt / tau # 用 FFT 估计频率响应 U = np.fft.rfft(u) Y = np.fft.rfft(y) freqs = np.fft.rfftfreq(steps, dt) H = Y / (U + 1e-12) # 找相位穿越 -180 度的频率,对应增益裕度 phase = np.angle(H) # 只关心 0.5 到 20Hz mask = (freqs > 0.5) & (freqs < 20) # 找相位最接近 -pi 的点 idx = np.argmin(np.abs(phase[mask] - (-np.pi))) gain_at_cross = np.abs(H[mask][idx]) print('gain margin:', 1.0 / (gain_at_cross + 1e-12))这段代码里,gain margin就是 Kp 还能放大的倍数。如果增益裕度是 2,说明当前 Kp 还能乘 2 才到振荡边界,实机上取一半,也就是乘 1,留足安全余量。这个方法比纯试凑快,但依赖数据质量,扫频信号幅值不能太大,否则对象非线性会污染结果。
我自己的习惯是:新飞机先用仿真扫频定 Kp 量级,实机从 50% 开始试,每次加 20%,同时记录角速度波形。如果波形里出现等幅振荡,不管手感如何,都回退一步。这个习惯帮我省了不少后悔药,也让我对比例回路的边界有了更具体的感知。比例式自动驾驶仪看起来简单,但简单的东西往往最考验对物理量的理解,希望帮到你。
本文还有配套的精品资源,点击获取