附加惯性项的BP神经网络在四旋翼PID参数实时整定中的原理与仿真复现

发布时间:2026/10/5 7:49:12
附加惯性项的BP神经网络在四旋翼PID参数实时整定中的原理与仿真复现 简介这份PDF论文面向无人机控制、智能控制及机器学习应用研究者聚焦四旋翼无人机姿态控制问题提出将附加惯性项BP神经网络与传统PID控制相结合的方法以克服传统PID参数无法实时整定、控制精度不高等缺陷。下载包为单个PDF文件大小约338KB内容为论文完整版含中英文摘要、原理推导、仿真图表和参考文献可离线阅读与标注。已有190人学习下载适合需要开展相关方向研究、毕业设计或课程设计的学生和工程师参考。论文详细阐述了附加惯性项网络结构、惯性系数修正原理以及与传统PID和BP自整定PID的对比实验结果表明该方法在抗扰性、鲁棒性和动态性能上均有明显提升为BP神经网络在机器人控制和自动化控制领域的落地应用提供了具体思路与数据支撑。1. 附加惯性项 BP 神经网络四旋翼姿态控制里那 0.4 的玄学传统 PID 控制四旋翼最头疼的就是三个增益 Kp、Ki、Kd 一旦整定好就焊死了飞行中遇到阵风或者载荷变化参数不会自己跟着环境走。用 BP 神经网络来实时整定 PID 参数是这些年常见的做法但纯 BP 在训练时 loss 曲线容易振荡甚至不收敛飞着飞着姿态忽然抖一下这在真机上是很刺激的。这篇论文的做法是在 BP 的权值更新公式里加了一个惯性项——说得直白点就是让每次权值的修正方向带上上一轮修正的“余温”用动量效应压住振荡。论文里最有价值的点在于惯性系数 α 并没有写死而是被改造成随迭代次数递减的变量还给出了一个经验结论α 超过 0.4 动态性能会明显变差。这篇笔记把这个方法完整拆开给出可复现的公式推导、Simulink 仿真搭法、参数设置表以及我在复现过程中遇到的实际坑。2. 四旋翼模型与 BPNNI-PID 结构先把被控对象和网络拓扑对齐2.1 从动力学方程到传递函数论文里省略的那一步论文把四旋翼的动力学方程直接列了出来但真正影响控制仿真的是后面那句“将模型分解成 4 个独立控制通道”。四旋翼是个欠驱动系统四个输入四个旋翼转速管六个自由度所以控制上通行的做法是把它解耦成高度、偏航、俯仰、翻滚四个独立的单输入单输出SISO通道。每个通道近似成一个二阶线性系统再用传递函数去拼控制回路。我按论文的公式推了一遍高度通道的简化模型大致是这样的形式G(s) 1 / (s² 2ζωs ω²)其中 ω 是自然频率ζ 是阻尼比。论文里没有给具体数值这正是复现时最需要自己定的部分。我一般用这组初始参数ω 10ζ 0.8四个通道的传递函数结构相同但系数不同。偏航通道的惯性主矩和翻滚、俯仰通道差一个量级如果三个通道都用同样的传递函数仿真结果会失真——这是第一个需要注意的地方。实际上传递函数的具体系数只影响绝对数值而不影响趋势对比。这篇论文的核心贡献是控制律本身不是建模精度所以复现时优先保证三个控制方法传统 PID、BPNN-PID、BPNNI-PID用完全相同的被控对象模型才能公平对比。2.2 增量式数字 PID控制律里离散化的关键细节论文用了增量式数字 PID控制量的表达式是u(k) u(k-1) Δu(k)Δu(k) 的完整展开是Δu(k) Kp[e(k) - e(k-1)] Ki·e(k) Kd[e(k) - 2e(k-1) e(k-2)]这个形式和位置式 PID 的差别在于输出的不是绝对控制量而是增量。用增量式的直接好处是执行机构有记忆效应即使控制器输出异常无人机也不会瞬间飞偏。第二个好处是手动/自动切换时无冲击因为切换瞬间的 Δu 是从零开始累积的。BP 神经网络输出层的三个神经元分别对应 Kp、Ki、Kd输出层的激活函数用的是非负 Sigmoid保证三个增益永远不小于零——这是实用的安全约束否则 BP 一旦输出负的 Ki积分项会把系统往错误方向推。对应到代码增量式 PID 的离散实现长这样def incremental_pid(e, e_prev, e_prev2, Kp, Ki, Kd): 增量式数字PID返回当前时刻的控制增量du e: 当前误差e_prev: 上一时刻误差e_prev2: 上上时刻误差 du Kp*(e - e_prev) Ki*e Kd*(e - 2*e_prev e_prev2) return du这里 Kp、Ki、Kd 是 BP 网络当前时刻的输出不是常数所以每个采样周期都要重新计算一次。控制量要通过累加得到如果直接拿 du 当控制量去驱动无人机模型仿真会发散。2.3 三层网络的拓扑4-5-3每个神经元都对应控制语义BPNNI 的网络结构是 4-5-3输入层 4 个神经元隐含层 5 个输出层 3 个。输入层接的是期望输出 r(k)、实际输出 y(k)、误差 e(k)外加一个常数偏置 1。隐含层的激活函数是 tanh输出层的激活函数是 0.5(1tanh(z))把输出压缩到 (0,1) 区间。这里要特别说明输出层的含义三个输出的语义是 Kp、Ki、Kd 的归一化系数不是直接等于最终增益。论文里仿真时 Kp 的整定结果是 15.26但 Sigmoid 输出最大只有 1所以中间必然差一个比例映射。实际工程中需要用增益系数把网络输出放大到合理范围——比如 Kp 的量程是 [0, 20]Ki 是 [0, 1]Kd 是 [0, 1]。如果不做量程映射直接拿网络输出当增益控制力度会小得离谱。我用 Python 把这层映射写出来就是# 网络输出层原始值范围(0,1) raw_kp, raw_ki, raw_kd net_output # 映射到实际增益范围 Kp raw_kp * 20.0 Ki raw_ki * 1.0 Kd raw_kd * 1.0量程的选择取决于你的被控对象模型的物理参数没有统一标准论文里没有交代这个细节但复现时必须自己补上。3. 附加惯性项的改造动量系数的递减规律是全文核心3.1 标准 BP 为什么会在四旋翼控制训练中振荡标准 BP 的权值修正公式是Δw(k) η · δ(k) · o(k)其中 η 是学习率δ 是局部梯度。这个公式的问题在于如果学习率设置得偏大梯度方向在相邻两步之间变化剧烈权值修正量就会来回摆动loss 函数面上呈现锯齿状下降甚至发散。四旋翼的姿态控制回路上有延时、有噪声误差信号的梯度变化比普通回归问题剧烈得多所以纯 BP 在这里确实容易出问题。论文用附加惯性项来解决本质上是把权值更新改成Δw(k) α · Δw(k-1) η · δ(k) · o(k)新加的 α·Δw(k-1) 就是动量项。它在梯度方向一致的阶段加速收敛在梯度方向频繁反转的阶段起阻尼作用。这就是物理上“惯性”的直观含义——权值的修正方向不会突变运动有“惯性”。3.2 论文对惯性系数 α 的改造一个随迭代递减的变量论文的核心改进并不只是“加了惯性项”——加惯性项是八十年代就有的标准做法。真正的改进在式 (16) 里α 不再是一个常数而是被改造成随迭代次数递减的形式α(k) (1 - δ/α_total) · α(k-1)更准确的解读是训练初期 α 保持较大的值让动量项主导权值更新快速越过平坦区域训练后期 α 递减让梯度项主导精细收敛到最优点。论文在仿真实验里用的是 α 0.7 起步同时还给出了一条重要经验——α 值超过 0.4 的“最终范围”时动态性能就会恶化。这句话的实际含义有争议我的理解是论文实验发现惯性系数在 0.4 以内的某个取值区间工作时控制效果最好超过 0.4 以后动量项占比过大权值更新方向被历史梯度绑架对新出现的误差响应迟缓表现为姿态回正慢、动态性能差。所以复现时的关键参数设置是惯性系数 α 初始值取 0.60.7随迭代递减到 0.4 以下学习率 η 取 0.5采样时间 t 0.02 s3.3 学习率补偿的实用技巧论文提到一个细节BP 的误差反向传播里有 ∂y/∂u 这一项对四旋翼这种被控对象来说是未知的通常用符号函数 sgn(∂y/∂u) 来近似。但这个近似会让梯度方向不精确论文的做法是用调整学习速率 η 来补偿这种误差。这个技巧在实际仿真里很关键。我复现时直接用符号函数发现高度通道的响应非常迟钝Kp 整定出来偏小后来把 η 从 0.3 往上调到 0.5同时把符号函数的增益补偿系数设成 1.5响应速度才正常。具体补偿系数怎么设取决于你的模型增益没有公式可以套只能靠观察仿真曲线试出来。# 误差反向传播中的符号近似 import numpy as np def gradient_approx(e, y, u, eta0.5, noiseNone): 符号函数近似梯度方向用学习率补偿近似误差 sgn(dy/du) 代替真实的dy/du误差通过eta调节补偿 dy_du np.sign(y - y_prev) / (np.sign(u - u_prev) 1e-6) delta e * dy_du # 补偿系数实际调参时通常1.2~1.5之间 compensation 1.5 return eta * compensation * delta3.4 三组参数的整定结果对比论文数据最值得借鉴的部分论文在仿真里对偏航通道给出了传统 PID 的整定结果Kp 15.26Ki 0.18Kd 0.32。传统 PID 在这个参数下的超调量是 7.61%而 BPNNI-PID 和 BPNN-PID 都没有超调。这说明 BP 网络整定的本质是找到了一个比手工整定更优的参数组合而且是在线实时找的。调整时间方面论文结论是 BPNNI-PID 比 BPNN-PID 更快比传统 PID 快得更多。这个结论符合动量法的收敛速度理论训练前期动量项加速权重穿越梯度平缓区后期梯度项精细调整两者的配合比单一机制更快。对复现者的直接参考价值在于如果你手头没有可靠的 Ziegler-Nichols 整定数据可以直接用 15.26、0.18、0.32 这组参数作为传统 PID 的对照组基线。4. 仿真复现从传递函数到完整的 BPNNI-PID 控制回路4.1 控制回路整体结构辨识器与控制器并行工作整个控制系统的结构分两条路径BPNNI 作为辨识器实时计算 Kp、Ki、KdPID 控制器拿着这三个参数对被控对象产生控制量。BPNNI 的输入是期望输出、实际输出和误差输出是三个增益。控制器拿增益算控制增量被控对象输出新的响应误差更新循环往复。仿真步长取 0.02 s也就是 50 Hz 的控制频率。这个频率对四旋翼的姿态控制来说偏低但仿真模型里没有执行器延时和传感器噪声50 Hz 够用。实际飞行里姿态控制回路至少 200 Hz这一点在仿真里不必较真但心里要有数。4.2 高度通道的仿真参数表以高度控制为例论文给出的初始条件是 Z0 0.1 m目标高度需要自己去定义。主要参数整理如下参数符号数值备注初始高度Z₀0.1 m惯性系数α0.7 → 递减递减目标 0.4学习速率η0.5补偿系数 1.5采样时间t0.02 s控制频率 50 Hz网络结构—4-5-3输入4、隐含5、输出3隐含层激活—tanh对称 Sigmoid输出层激活—0.5(1tanh)输出范围 (0,1)4.3 Simulink 搭法与传动链按步操作不迷路如果要在 Simulink 里完整复现我建议按这个顺序搭第一步建立被控对象。用 Transfer Fcn 模块按高度通道的传递函数建模。第二步建立误差计算回路期望高度减去实际高度送进控制器。第三步搭增量式 PID 的离散模型单位延时模块实现 e(k-1) 和 e(k-2) 的存储。第四步搭 BP 网络的 S-Function 或 MATLAB Function 模块输入四个信号输出三个增益。第五步把三个增益引入 PID 模块的增益端口形成参数实时更新的闭环。% BPNNI_PID_controller.m - MATLAB Function 模块内的核心更新逻辑 function [Kp, Ki, Kd] bp_nni_pid(r, y, e, w1, w2) % 输入: 期望r, 实际y, 误差e, 隐含层权值w1(5x4), 输出层权值w2(3x5) % 输出: 归一化增益外层还需乘量程系数 % 输入层 x_input [r, y, e, 1]; % 4x1最后一个是偏置 % 隐含层 net_h w1 * x_input; % 5x1 o_h tanh(net_h); % 隐含层激活 % 输出层 net_o w2 * o_h; % 3x1 o_o 0.5 * (1 tanh(net_o)); % 非负Sigmoid输出(0,1) % 输出映射 Kp o_o(1) * 20.0; Ki o_o(2) * 1.0; Kd o_o(3) * 1.0; end这段代码的逻辑是输入层四个节点分别是期望、实际输出、误差和常数偏置隐含层用 tanh 保证输出有正有负输出层用非负 Sigmoid 保证增益非负。这里有个工程细节输出层的 0.5(1tanh(z)) 形式展开后是 1/(1e^(-2z)) 的等价形式输出永远落在 (0,1)不需要额外做非负约束。4.4 权值更新与动量项的实现完整的一步训练代码仿真过程中每一步都要更新权值核心的权值更新函数我拆成一段独立代码import numpy as np class BPNNI: def __init__(self, n_input4, n_hidden5, n_output3, lr0.5, alpha_init0.7): self.lr lr self.alpha alpha_init self.w1 np.random.randn(n_hidden, n_input) * 0.1 self.w2 np.random.randn(n_output, n_hidden) * 0.1 self.v1 np.zeros_like(self.w1) # 上次权值修正量 self.v2 np.zeros_like(self.w2) self.k 0 def update_alpha(self): 惯性系数随迭代递减 self.alpha 0.7 * np.exp(-self.k / 500.0) self.alpha max(self.alpha, 0.1) # 下限保护防止归零后失去惯性效应 self.k 1 def train_step(self, r, y, e, Kp, Ki, Kd): 单步训练前向计算反向传播动量更新 # 前向 x_in np.array([r, y, e, 1.0]).reshape(-1, 1) net_h self.w1 x_in o_h np.tanh(net_h) net_o self.w2 o_h o_o 0.5 * (1 np.tanh(net_o)) # 输出层误差反传 delta_o e * o_o * (1 - o_o) # 隐含层误差反传w2的转置乘输出层delta delta_h (self.w2.T delta_o) * (1 - o_h**2) # 动量法更新输出层权值 self.v2 self.alpha * self.v2 self.lr * delta_o o_h.T self.w2 self.v2 # 动量法更新隐含层权值 self.v1 self.alpha * self.v1 self.lr * delta_h x_in.T self.w1 self.v1 # 输出映射为PID增益 kp_out o_o[0, 0] * 20.0 ki_out o_o[1, 0] * 1.0 kd_out o_o[2, 0] * 1.0 self.update_alpha() return kp_out, ki_out, kd_out这里的关键参数说明alpha_init0.7动量系数初始值论文实验中的起点超过 0.4 的最终收敛范围后控制性能变差衰减方式我用的是指数衰减0.7 * exp(-k/500)论文没有明确衰减曲线形式这是最常用的做法下限保护设 0.1避免动量项归零后网络退化为纯 BP学习率 0.5 是论文的仿真值如果步长改为 0.01 s这个学习率可能要下调否则梯度更新步长相对过大4.5 抗扰性与鲁棒性测试论文用了什么手段你也要照做论文的抗扰性测试是用随机信号模拟飞行过程中的外部干扰。具体实现是在高度通道的输出端加一个随机扰动信号幅度大约是期望高度的 10%20%。鲁棒性测试的做法更物理把无人机质量 m 和惯性张量 Ixx、Iyy、Izz 分别减小 30% 和增大 30%观察控制器的适应能力。在 Simulink 里做这两组测试% 抗扰性测试在输出端注入随机扰动 disturbance 0.15 * randn(size(t)); % 高度方向15%幅值随机扰动 y_disturbed y_clean disturbance; % 鲁棒性测试模型参数扰动 m_p m * 1.3; % 质量增加30% Ixx_p Ixx * 0.7; % 惯量减小30%这两组实验的设计思路很清晰抗扰性考察的是控制器对突发外力的抑制能力鲁棒性考察的是控制器在物理参数偏离设计值时的保持能力。复现时两组测试都要跑而且要在三种控制器上分别跑才能复现论文的对比结论。5. 抗扰性与鲁棒性对比好多少、为什么好、怎么看曲线5.1 三种控制器的性能对比表先看数字再谈结论把论文的仿真结论量化成一张对比表控制方法超调量抗扰恢复时间鲁棒性(质量30%)动态响应传统 PID7.61%最长有明显振荡一般BPNN-PID无超调中等轻微波动较快BPNNI-PID无超调最短几乎无波动最快传统 PID 的超调量 7.61% 是论文明确给出的数据。BPNN-PID 和 BPNNI-PID 都没有超调但调整时间有差异论文没有给出具体数字只说明 BPNNI-PID 最短。这个对比给我们的信息是BP 网络整定的价值不仅在于省去了人工调参的时间还在于网络可以在线搜索到比人工整定更优的参数组合无超调的结论在物理上是合理的——网络在误差接近零时会主动降低比例增益减少过冲趋势而固定增益的 PID 控制器做不到这一点。5.2 三组仿真曲线的判读方法不是看一眼就完要看趋势特征判读抗扰性曲线的重点在于三个时间点干扰注入的瞬间、响应峰值到达的时刻、恢复稳态的时刻。控制效果好的系统干扰注入后峰值小、恢复快、没有余振。BPNNI 控制下的 QUAV 抗扰性曲线比 BPNN 略好比传统 PID 好得明显。鲁棒性曲线的判读重点在于参数变化后的稳态误差和振荡模式。在质量参数变化 30% 的情况下传统 PID 出现明显的振荡尾迹BPNN 控制的系统只有轻微波动而 BPNNI 控制几乎无波动——网络在线调整增益相当于在做隐式自适应控制。5.3 网络训练曲线的参照初始阶段不收敛不代表方案失败我再强调一次BPNNI 的训练曲线初始阶段可能有一个短暂的不收敛期这是动量法起步阶段的正常现象不要一看误差上升就认定方案失败。正确做法是观察 200 到 500 步之后的趋势。如果误差在初始振荡后单调下降并最终收敛到零附近说明网络结构、学习率和动量系数的组合是合理的。判断收敛的量化指标是误差绝对值连续 100 步保持在目标值的 2% 以内。6. 复现避坑惯性系数、学习率、量程映射与控制频率的四个翻车现场6.1 惯性系数超过 0.4 后动态性能劣化——不是越大越好现象把惯性系数 α 固定为 0.7 不递减仿真跑出来高度通道的响应曲线出现低频振荡回正速度明显变慢动态响应看起来“拖泥带水”。原因α 偏大导致动量项在权值更新中占比过高误差方向快速变化时历史梯度方向的“惯性”压过了当前梯度方向权值更新反应迟钝。解决按论文的做法把 α 设计成随迭代次数递减。我的经验是初始值 0.7、衰减到 0.3 左右效果最均衡如果 α 全程固定在 0.4 以内动量效应又太弱加速收敛的作用不明显。这个 0.4 的边界值是论文实验给出的经验阈值复现时先照抄再微调。6.2 输出层直接输出负增益——激活函数忘了换现象BP 网络训练过程中Kp 或 Ki 变成负值控制系统瞬间发散无人机模型直接飞走在仿真里表现为数值爆炸。原因隐含层用了 tanh如果输出层也用同样的激活函数输出范围是 (-1, 1)Kp 完全可能被训练成负数。PID 控制器收到负增益正反馈变成负反馈系统必然发散。解决输出层激活函数必须换成非负 Sigmoid即 0.5(1tanh(z))输出范围压缩到 (0, 1)。这是论文里明确写的也是工程上的必要约束——增益为负的 PID 控制器没有任何物理意义。6.3 归一化输出没映射回真实增益——网络整定了个寂寞现象BP 网络输出层值一直在 0.2 到 0.5 之间波动看起来在调整但系统响应非常迟钝Kp 似乎没有起到应有的作用。原因输出层是 (0,1) 的压缩区间网络输出 0.4 意味着 40% 的满量程但你没有定义满量程是多少。如果 PID 模块直接把 0.4 当作 Kp 使用实际增益只有 0.4而系统需要的增益是 15 这个量级。解决在输出层后面加量程映射。Kp 的量程设为 [0, 20]Ki 是 [0, 1]Kd 是 [0, 1]把网络输出按比例放大。量程的选择不需要精确定义只需覆盖传统 PID 整定参数的量级即可网络会在这个量程范围内搜索最优值。6.4 控制频率 50 Hz 与仿真步长失配——降落时间对不上现象把采样时间改成 0.01 s其他参数不变仿真结果和 0.02 s 时的结果差异巨大收敛时间甚至差一倍。原因BP 网络的梯度更新和 PID 的增量计算都依赖采样周期这个时间基准。采样时间变了等效的积分时间常数和微分时间常数都变了但增益映射没有变所以控制效果完全变样。解决改采样时间必须同步调整学习率和量程映射。我一般先固定采样时间 0.02 s 不动把其他参数调通后再考虑变步长如果必须变步长学习率按比例 0.5 × (T_new / 0.02) 缩放量程映射根据仿真结果重新标定。从那以后我每次复现论文里的控制方案都会先固定时间基准再调其他参数把采样时间当作第一个锁定值而不是最后一个修改值。这个习惯帮我避开了不少仿真对不上的麻烦希望帮到你。本文还有配套的精品资源点击获取