附加惯性项BP神经网络在四旋翼姿态控制中的设计与仿真

发布时间:2026/10/30 0:35:21
附加惯性项BP神经网络在四旋翼姿态控制中的设计与仿真 简介一份2017年发表在《广西师范大学学报自然科学版》的学术论文PDF面向四旋翼无人机姿态控制、智能算法及机器人控制领域的工程师、研究人员和研究生。论文针对传统PID控制参数无法实时整定、控制精度不高等问题提出将附加惯性项的BP神经网络与PID控制相结合的姿态控制方法并对惯性系数进行修正以提升无人机在外部扰动下的姿态稳定性与动态性能。包体仅含1个PDF文件共338KB涵盖摘要、关键词、方法推导、仿真实验与分析、参考文献等完整内容适合用于论文写作参考、控制模型复现及不同PID改进方案的横向对比。目前已有190人学习下载。该资料融合BP神经网络参数自整定、PID控制优化和无人机动力学建模等核心知识点对深入理解智能控制融合思路、提高系统抗扰性与鲁棒性具有较好的参考价值。1. 四旋翼姿态控制里的BP神经网络加附加惯性项是为了治什么病四旋翼无人机的姿态控制是要让机身绕三个轴快速且平稳地转到期望姿态角。悬停时常规PID就能压住但出现突风、急转弯、载重变化时PID那组固定增益就不够用了——超调拉大震荡不停甚至发散。这也是基于附加惯性项BP神经网络的四旋翼无人机姿态控制研究这类方案出现的原因用BP神经网络逼近姿态控制里的非线性映射把姿态误差和角速度映射为控制力矩。但标准BP神经网络有两个短板收敛慢且容易陷入局部极小同时它默认所有动力学规律都要靠样本自己学出来。标题里的附加惯性项就是在给这两个短板动手术一是在权值更新规则中加入动量惯性项让权值修正顺着历史梯度方向保持惯性二是在网络输入特征中显式注入四旋翼的惯性耦合项。这篇笔记从动力学建模开始把网络设计、训练代码、Simulink仿真到参数避坑的流程走一遍。2. 姿态动力学建模先把附加惯性项的物理来源写进状态方程2.1 欧拉角表示的姿态运动学为什么绕不过万向锁在设计神经网络控制器之前先得把被控对象的状态方程写清楚。姿态控制里最常用的状态量是ZYX欧拉角即偏航角、俯仰角和滚转角。姿态运动学描述的是欧拉角速率与机体角速度之间的关系用矩阵形式写就是p φ̇ − ψ̇ sinθq θ̇ cosφ ψ̇ sinφ cosθr −θ̇ sinφ ψ̇ cosφ cosθ其中(φ, θ, ψ)对应滚转、俯仰和偏航角它们是状态量(p, q, r)是机体坐标系下的角速度是高速状态量。姿态控制器要做的就是根据当前的欧拉角误差和角速度误差给出合理的力矩指令。这里有一个在选择表示方式时就必须明确的坑直接用欧拉角做动力学仿真当θ接近±90°时公式里的tanθ项会趋向无穷大这就是常说的万向锁问题。在姿态控制训练数据生成阶段我一般把俯仰角限制在±60°以内避免数据里出现接近奇异值的极端姿态样本。如果要做全姿态机动唯一出路是改用四元数表示但四元数的误差定义和坐标变换比欧拉角繁琐得多。对大多数悬停加小范围机动的场景欧拉角加角度限幅完全够用代价就是需要给姿态角单独画一条保护逻辑。所以下面的仿真模型都用欧拉角但训练数据里不含大俯仰角样本这个限制必须在控制器部署时用姿态角限幅来兜底。2.2 刚体欧拉方程里的惯性耦合项改写状态方程看四旋翼姿态动力学把机身视为刚体用欧拉方程描述I·ω̇ ω×(I·ω) τ d这里的ω×(I·ω)就是惯性耦合项也就是标题里附加惯性项的物理本体。不少论文为了让数学好看会把这一项忽略掉但在四旋翼高速机动时角速度越大这一项贡献的力矩就越显著。忽略它等于让控制器面对一个缺失关键状态量的系统。把方程展开成三轴标量形式Iₓṗ (I_y − I_z)·q·r τ_φ d_φI_yq̇ (I_z − I_x)·p·r τ_θ d_θI_zṙ (I_x − I_y)·p·q τ_ψ d_ψ这三个等式右边的第一项就是惯性耦合项。当四旋翼做横滚同时偏航时横滚角速度和偏航角速度会在俯仰轴上产生一个额外的力矩这个力矩如果不加补偿飞控就会在混控指令里漏掉一部分。实现如下function x_dot attitude_dynamics(x, tau, I, d) % 状态x [phi; theta; psi; p; q; r] % tau [tau_phi; tau_theta; tau_psi] 三轴控制力矩 % d [d_phi; d_theta; d_psi] 三轴外部扰动力矩 phi x(1); theta x(2); psi x(3); p x(4); q x(5); r x(6); Ix I(1); Iy I(2); Iz I(3); % 运动学部分欧拉角速率与角速度的非线性映射 phi_dot p q * sin(phi) * tan(theta) r * cos(phi) * tan(theta); theta_dot q * cos(phi) - r * sin(phi); psi_dot (q * sin(phi) r * cos(phi)) / cos(theta); % 动力学部分惯性耦合项 (Iy-Iz)/Ix*q*r 显式保留 p_dot (Iy - Iz) / Ix * q * r tau(1) / Ix d(1) / Ix; q_dot (Iz - Ix) / Iy * p * r tau(2) / Iy d(2) / Iy; r_dot (Ix - Iy) / Iz * p * q tau(3) / Iz d(3) / Iz; x_dot [phi_dot; theta_dot; psi_dot; p_dot; q_dot; r_dot]; end这段代码的状态积分变量是真实的欧拉角和角速度控制输入为三轴力矩。每次调用前需要将角速度和角度累加推荐用固定步长四阶龙格-库塔RK4来离散积分。步长取0.001秒刚好覆盖姿态环的带宽又不至于因为步长过大引入数值误差。仿真时如果发现姿态角在高角速度下数值跳变第一步先检查是不是RK4步长偏大而不是急着调网络参数。2.3 状态方程离散化与仿真参数转动惯量怎么选姿态控制仿真里转动惯量是决定控制难度的重要参数。以常见的轴距450毫米级别四旋翼为例整机质量约1.2公斤经验取值如下表参数符号经验值单位横滚转动惯量Ix0.020kg·m²俯仰转动惯量Iy0.021kg·m²偏航转动惯量Iz0.040kg·m²转动惯量的选取直接影响惯性耦合项的量级。Ix和Iy接近的飞机横滚和俯仰两个方向的耦合项近似对称控制器容易收敛如果载荷偏心导致Ix和Iy相差超过30%惯性耦合项的失衡会让神经网络经常看到横滚-俯仰联动的不对称模式训练收敛变慢。仿真的目的是验证控制算法不建议把转动惯量取到极端值否则大部分训练时间都会耗在吃透一个实际中很少出现的动力学模式上。生成训练数据可以和Simulink模型解耦单独出一份MAT文件。下面这段脚本生成的是姿态误差角速度误差惯性耦合项组成的训练样本% 生成姿态控制训练数据集 % x0 [phi theta psi p q r] 初始状态 dt 0.001; N 20000; data zeros(N, 9 3); % 9个输入特征 3个力矩标签 % 按工作点附近随机撒点模拟各种姿态偏差 for k 1:N-1 phi_e randn * 0.2; % 滚转误差 ±0.2 rad theta_e randn * 0.2; % 俯仰误差 ±0.2 rad psi_e randn * 0.3; % 偏航误差 ±0.3 rad p_e randn * 0.5; % 横滚角速度误差 q_e randn * 0.5; % 俯仰角速度误差 r_e randn * 0.5; % 偏航角速度误差 % 惯性耦合项作为附加特征 inertial_phi (0.021 - 0.040) / 0.020 * q_e * r_e; inertial_theta (0.040 - 0.020) / 0.021 * p_e * r_e; inertial_psi (0.020 - 0.021) / 0.040 * p_e * q_e; % 近似逆模型标签线性组合近似期望力矩 tau_phi 5 * phi_e 2 * p_e; tau_theta 5 * theta_e 2 * q_e; tau_psi 3 * psi_e 1.5 * r_e; data(k, 1:9) [phi_e theta_e psi_e p_e q_e r_e ... inertial_phi inertial_theta inertial_psi]; data(k, 10:12) [tau_phi tau_theta tau_psi]; end save(attitude_training_data.mat, data);这段代码里的标签用的是逆模型近似值。工程上更稳的做法是先标定一组还不错的PID增益用PID的输出作为网络标签训练一个模仿PID但能学习耦合补偿的控制器。数据分布是关键如果只在零点附近撒点网络学到的映射就在小误差范围内成立一旦阶跃增大就会出现外推失效。3. 附加惯性项BP神经网络网络结构、输入特征与权值更新规则3.1 标准BP的固有缺陷梯度消失与局部极小BP神经网络也就是反向传播神经网络它的权值更新本质上就是梯度下降。误差对每层权值的偏导从输出层向输入层逐层传播每经过一个非线性激活函数梯度就要乘一次激活函数导数值。以Sigmoid为例它的导数最大值只有0.25多层传播之后梯度以指数级衰减这就是梯度消失现象。在姿态控制这种需要对角速度误差做毫秒级响应的场景里梯度衰减会让权值更新慢到难以收敛控制器还没达到期望性能飞行器就已经在仿真里翻了。另一个缺陷是权值空间里存在大量局部极小点。标准BP在误差曲面上沿最陡方向下降一旦落入一块平坦区域梯度的范数趋近于零网络就卡死在非最优点。姿态控制训练数据中占优的是线性成分网络容易找到一个看起来能用、实际没抓住耦合关系的局部解。这就是我见过不少复现项目最终姿态角跟踪误差偏大的根本原因不是网络结构不对而是梯度下降本身没穿出那个平坦区。3.2 惯性项的引入动量项修正与动力学特征注入标题里附加惯性项的实现分两个层面。第一层是权值更新规则Δw(t) −η·∂E/∂w α·Δw(t−1)这个公式里第一项是梯度下降项第二项是附加的上一次更新量也就是惯性项也叫动量项。权值更新带上惯性后如果连续几次梯度方向一致累加会让收敛加速如果梯度方向振荡惯性项会抵消部分来回摆动。这个机制对局部极小有缓解作用但控制不好也会自己引入震荡第5.1节会专门讲α的边界。第二层是把惯性耦合项直接注入输入特征。常见做法是把上一章计算出的三个惯性耦合项与姿态误差、角速度误差拼接组成9维输入。这样做的好处是网络不需要费劲从数据里学出一个复杂的乘法模式物理规律直接作为先验给了它。我在多个对比中发现加入这个特征后同样的训练步数下跟踪精度能提升5%到10%训练过程也更稳定。用配置文件来管理网络结构# 神经网络结构配置 config { input_dim: 9, # 姿态误差3 角速度误差3 惯性耦合项3 hidden_dim: 12, # 隐藏层节点数 output_dim: 3, # 三轴控制力矩 activation: tanh, # 隐藏层激活函数 output_activation: linear, # 输出层线性激活 momentum: 0.7, # 惯性项系数 alpha learning_rate: 0.01, # 学习率 batch_size: 64, # 批量大小 epochs: 500 }这就是一张bp神经网络结构图的文字版9个输入节点经过12个隐藏节点最后输出3个力矩节点。输入维度不是随手定的——少一个维度网络就补不齐惯性耦合的补偿信号多一个维度训练所需的样本量又要上一个台阶对后续嵌入式部署也不友好。3.3 网络结构与初始化9-12-3还是9-15-3隐藏层节点数取多少是个靠经验定的问题。输入9个节点时隐藏层取12到15个节点比较合理。隐藏层太少网络拟合不了非线性映射太多则容易过拟合且在线推理时矩阵乘法的计算量增加。一个经验规则是隐藏层节点数取输入维数的1.5到2倍9维输入对应14到18个区间12是保守选择15是偏拟合的选择。权值初始化用均匀分布U(−0.5, 0.5)。为什么不用全零初始化因为全零初始化会让隐藏层所有神经元在第一次前向传播时产生完全相同的激活值梯度完全对称网络就退化成一个线性模型。均匀分布的范围不宜过大权值初始值太大会让tanh直接饱和梯度消失提前到来。4. 从训练到仿真用Python训练网络在Simulink里验证4.1 训练数据怎么来输入输出对的构造与时间对齐第三章节已经把网络输入定下来了接下来要解决的是标签问题。训练采用离线监督学习标签的选择很关键。如果动力学参数精确可以直接用逆模型生成力矩标签工程上更稳的做法是用一组调好的PID控制器把它的输出作为期望力矩。这样训练出的网络扮演的是PID增强控制器角色但比PID多了一项耦合补偿能力。构造输入输出对时要注意时间对齐。以1kHz采样为例输入向量是当前时刻的姿态误差、角速度误差和惯性耦合项标签是当前时刻的力矩指令。两者在时间戳上必须严格一致否则网络学到的是一个带相位延迟的映射。我见过有人直接拿Simulink的仿真输出拼接数据结果输入和标签差了三个采样周期仿真时姿态持续震荡还以为是网络结构出了问题。4.2 BP网络训练代码附加惯性项的Python实现训练主逻辑用Python写比MATLAB神经网络工具箱更透明至少每一步在做什么都看得见。标准BP的更新规则是权值增量等于负学习率乘以梯度加入惯性项后变成权值增量等于负学习率乘当前梯度加上惯性系数乘上一次增量。完整训练代码整理如下import numpy as np class BPWithInertia: 带惯性项动量项的BP神经网络控制器 def __init__(self, n_in9, n_hidden12, n_out3, alpha0.7, eta0.01): # 权值初始化均匀分布 U(-0.5, 0.5) self.w1 np.random.uniform(-0.5, 0.5, (n_in, n_hidden)) self.b1 np.zeros(n_hidden) self.w2 np.random.uniform(-0.5, 0.5, (n_hidden, n_out)) self.b2 np.zeros(n_out) # 保存上一次权值增量作为惯性项的记忆 self.vw1 np.zeros_like(self.w1) self.vb1 np.zeros_like(self.b1) self.vw2 np.zeros_like(self.w2) self.vb2 np.zeros_like(self.b2) self.alpha alpha # 惯性项系数 self.eta eta # 学习率 self.history [] # 记录损失便于观察收敛 def forward(self, x): 前向计算输入1x9向量返回1x3力矩指令 self.z1 x self.w1 self.b1 self.a1 np.tanh(self.z1) self.z2 self.a1 self.w2 self.b2 return self.z2.flatten() def train_step(self, x_batch, y_batch): 单步批量训练含惯性项修正的权值更新 m x_batch.shape[0] # 前向传播 z1 x_batch self.w1 self.b1 a1 np.tanh(z1) z2 a1 self.w2 self.b2 # 均方误差 loss np.mean((z2 - y_batch) ** 2) # 反向传播输出层误差隐藏层误差 delta2 (z2 - y_batch) / m delta1 (delta2 self.w2.T) * (1 - a1 ** 2) # 计算梯度 grad_w2 a1.T delta2 grad_b2 np.sum(delta2, axis0) grad_w1 x_batch.T delta1 grad_b1 np.sum(delta1, axis0) # 带惯性项的权值更新 # 当前更新 -学习率*当前梯度 惯性系数*上一次更新量 vw2 -self.eta * grad_w2 self.alpha * self.vw2 vb2 -self.eta * grad_b2 self.alpha * self.vb2 vw1 -self.eta * grad_w1 self.alpha * self.vw1 vb1 -self.eta * grad_b1 self.alpha * self.vb1 self.w1 vw1 self.b1 vb1 self.w2 vw2 self.b2 vb2 # 将本次增量存入记忆供下一步使用 self.vw1, self.vb1 vw1, vb1 self.vw2, self.vb2 vw2, vb2 self.history.append(loss) return loss关键点在vw2这些变量上第一次训练时它们全初始化因此第一次更新等价于普通梯度下降从第二步开始更新量里掺入了上一次的梯度信息。如果连续几步梯度方向一致更新量会累积变大相当于给收敛加了速。训练时batch size取64学习率0.01数据反复跑500轮。训练结束后把权值保存下来再转成Simulink能读的MAT格式# 保存权值 np.savez(bp_attitude_weights.npz, w1net.w1, b1net.b1, w2net.w2, b2net.b2) # 用 scipy 写成 .mat 供 Simulink 读取 from scipy.io import savemat savemat(bp_weights.mat, {w1: net.w1, b1: net.b1, w2: net.w2, b2: net.b2})这一步必须确保权值数组维度与配置一致Simulink侧报维度错误基本就是这里没对齐。4.3 Simulink联合仿真把训练好的网络装进控制器在Simulink里搭控制回路常见做法是用MATLAB Function封装训练好的网络接口代码很短function y bp_attitude_controller(x, w1, b1, w2, b2) % x: 1x9 输入向量 % [phi_e theta_e psi_e p_e q_e r_e % inertia_phi inertia_theta inertia_psi] % 前向传播与Python训练时的网络结构保持一致 a1 tanh(x * w1 b1); y a1 * w2 b2; end注意Simulink的MATLAB Function里直接使用tanh就行不需要手写近似。然后把九路输入接入控制器模块输出三路力矩接到动力学模型的三个轴上。电机转速部分控制器输出的是力矩指令要经过执行器模型映射到PWM。我一般先做一个简化执行器模型一阶惯性环节时间常数20ms输出脉宽再经过混控矩阵映射到四个电机。如果跳过这个环节直接用力矩控制仿真网络输出会显得过于完美实际情况里有电机响应延迟控制器容易超前。仿真步长和训练数据生成保持一致固定1ms。到这里回路就闭环了。从示波器里能看到三轴姿态角跟踪曲线接下来进入参数调优和翻车现场。5. 参数调优与避坑指南惯性系数、过拟合和姿态跳变5.1 惯性项系数α的取值边界发散与震荡的分界线惯性项系数α是最容易踩坑的参数之一。现象是训练前期loss下降尚可中期突然抖动或者训练到最后loss不降反升加大学习率后直接出现NaN。原因是α取得过大权值更新历史占比太高梯度方向变化时惯性项把本次更新拖向相反一侧导致发散。我试验过的组合里固定η0.01时α超过0.85的发散概率急剧上升如果把η下调到0.005α可以放到0.9。最终常用的稳健组合是η0.01、α0.7。如果确实想用大α加速收敛可以做两段式调整# 惯性项系数两段式调整 if epoch 100: net.alpha 0.5 else: net.alpha 0.8前100轮用较小α先把权值从均匀分布拉到合理区域再用大α加速收敛这是我在训练里常用的手段。调参时先固定α0.5确认loss曲线稳定后再往上加每次加0.05直到震荡出现再回调0.05。5.2 训练集分布不合理导致控制器局部记忆现象仿真里悬停控制效果很好给一个大角度阶跃后姿态剧烈震荡甚至反向翻转。原因是生成训练数据时误差只在±0.2rad范围内随机撒点网络学到的映射只在小误差区间成立大角度下网络把外推当作内插使用给出错误力矩。解决办法是扩大采样范围按幅值分层。误差分布从单一均匀分布改成多个区间分别采样同时在真实动力学模型上多跑几段大角度机动把过程中的状态记录作为额外训练样本。大角度样本也要限制在第2章提到的俯仰角±60°内避免触发万向锁区域。数据覆盖是整个方案里最花时间的部分但数据不覆盖到位后面所有仿真曲线都是虚的。5.3 欧拉角跳变与归一化陷阱偏航角在±180°附近跳变是姿态控制训练里最常见的老大难。现象是偏航误差从5°突然变成355°网络输入突变输出力矩猛增姿态在边界来回穿越。原因很简单角度差的取值范围没有回绕到(-π, π]。解决办法是训练前把所有角度误差都经过回绕处理def wrap_to_pi(angle): # 角度回绕把任意角度映射到 (-π, π] 区间 while angle np.pi: angle - 2 * np.pi while angle -np.pi: angle 2 * np.pi return angle处理之后输入网络的角度误差永远是最短路径不再出现355°这种看似大误差实为小误差的假象。另一个坑是归一化参数没有固化。训练时用训练集的min和max做了归一化仿真推理时却不做归一化或者归一化参数不一致网络看到超出训练区间的数据输出力矩直接发散。解决办法是把归一化用的min、max保存下来在Simulink控制器里同样套用。这一步属于后悔药级别的细节漏掉了就得全部重新训练。5.4 惯性耦合特征与角速度的量纲不匹配现象是网络训练收敛正常仿真时滚转轴响应却异常迟钝。排查后发现问题出在输入特征量级上角速度误差的范围在0.1到1之间惯性耦合项的范围只有0.001到0.01相差两个数量级。在tanh激活函数下幅值过小的特征对神经元输出的贡献微乎其微反向传播时对应的梯度也小网络实际上根本看不见这几个附加特征。解决办法是分别缩放让惯性耦合项乘一个常数增益K比如100把它拉大到与角速度相近的数量级再送入网络。这不是归一化到[0,1]而是让同一数量级。注意增益K要在训练和推理时保持一致。血泪经验是加了附加惯性项但没调量级等于没加。6. 鲁棒性验证与进阶别只盯着跟踪曲线6.1 三种验证场景阶跃、风扰、载荷突变姿态控制器的好坏不能只看阶跃跟踪一条曲线至少要跑三个场景。阶跃响应验证基本性能期望姿态角从0°跳到30°看超调量和调节时间风扰验证抗干扰能力在动力学模型的扰动项d上叠加正弦或方波信号幅值0.05N·m频率5Hz载荷突变验证参数变化下的适应性在仿真中途把转动惯量突增20%看姿态角能否拉回稳态。6.2 评价指标与数据记录技巧记录数据时别只存姿态角角速度、力矩指令、惯性耦合项都一起存。用ITAE指标衡量综合性能计算公式为∫t·|e(t)|dtITAE越小说明快速性和稳定性兼顾得越好。阶跃响应的超调量控制在10%以内调节时间小于0.5秒稳态误差小于1度这个组合可以作为一套基础验收线。6.3 我在最终项目中固定的参数训练参数η0.01α0.7batch size64隐藏层12个节点惯性耦合项缩放增益K100。这个组合在三个验证场景下都通过。额外一个习惯是每轮训练结束先做一次开环推理测试输入一组随机状态看输出力矩是否在合理范围内再决定是否继续训练。这个习惯帮我挡掉了好几次权值初始值过大导致的前期发散。姿态控制控制器落地必须上下极限保护训练数据里没有的错误输入一定会在某个时刻出现。希望这些参数和踩坑记录帮到你少走几段我走过的弯路。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询