ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PX4角加速度隐藏数据挖掘:从uORB取数到前馈反馈实战

PX4角加速度隐藏数据挖掘:从uORB取数到前馈反馈实战 提到PX4四旋翼控制大多数人第一个想到的都是姿态环加角速率环的经典级联PID结构外环算期望姿态内环算期望力矩最后混控输出到四个电机。可你有没有注意过在这个框架里有一个物理量几乎被完全“包”在了控制器的内部它既能直接决定电机输出又不在任何一块独立的状态估计里单独露脸——就是角加速度。很多做控制的朋友都知道角加速度香它比角速率多了一阶相位信息做前馈、做反馈、做扰动观测都有奇效。但打开PX4源码翻一圈你会发现大部分示例代码和官方文档都没有单独教你怎么用这个量。这不是因为PX4拿不到它而是它藏在uORB消息、姿态控制模块和混控逻辑之间的某个角落。今天这篇就专门把这个“隐藏数据”挖出来讲清楚它从哪来、怎么取、以及拿到之后怎么真正拿它来提升控制性能。这篇文章适合正在做PX4二次开发、被整机响应延迟和超调折磨的同学也适合刚搭完PX4仿真环境、想往飞控控制算法里加点“高级货”的研究者。我会把数据获取代码、滤波处理、参数整定方法和踩坑记录都写出来尽量让你能照着做而不是只停留在概念层面。1. 为什么说角加速度是PX4里的“隐藏数据”1.1 传统控制链路里角加速度被“包”住了我们先看一下PX4多旋翼姿态控制的经典链路整个路径大概是这样的mc_att_control根据期望姿态和当前姿态计算期望角速率。mc_rate_control根据期望角速率和当前角速率用PID算出期望力矩即扭矩指令。mixer把扭矩指令和油门指令混合成四个电机的PWM/串行DShot值。电机机架扭矩作用在机架上根据刚体转动方程产生真实的角加速度。IMU陀螺仪积分出角速率再经过姿态估计器解算出姿态返回第一步。在这个闭环里你能直接读到的反馈量通常是“当前角速率”和“当前姿态”。可是PID控制器输出的其实是什么它不是位置指令也不是速度指令它实质上是在生成一个期望的角加速度。只是这个期望角加速度被PID运算“消化”掉了大多数开发者没有把它单独抽出来看。也就是说角加速度这个量在PX4内部已经天然存在而且它比角速率更靠近执行机构那一端。如果能把期望角加速度拿来做前馈把实测/估算角加速度拿来做反馈控制器就能提前感知转动趋势而不是等角速率误差先出现再被动补救。1.2 三种获得角加速度的路径在实际工程里获得角加速度通常有三条路各有各的适用场景我下面简单梳理一下模型反算法利用刚体转动方程通过已知的期望扭矩、角速率和转动惯量反算出角加速度。这个方法响应当前时刻的理论值几乎没有延迟但前提是你对自己的机架转动惯量、混控映射和气动阻尼模型有比较准确的认识。模型一旦偏差大算出来的角加速度就不可靠。微分估计法对陀螺仪输出的角速率做数值微分再配低通滤波。这是最直观的方法适用于你不知道精确转动惯量、又想获取实测角加速度的场景。缺点是微分会放大高频噪声必须做好滤波否则直接进控制器会把电机“炸”得发烫。状态估计法把角加速度扩展进卡尔曼滤波器状态向量里通过观测角速率和加速度计间接估计。这种方法噪声最低、相位延迟可控但实现复杂计算量也大。PX4的EKF2并没有直接内置输出角加速度的独立状态所以真正在二次开发里跑通这条路的人不算多。看到这里你应该明白了所谓“隐藏”不是说这个数据不存在而是它分散在模型、微分链路和控制器内部的夹缝里需要你自己把它取出来。好消息是PX4其实已经在内部发布了一个专门承载角加速度的uORB消息这就是vehicle_angular_acceleration。2. 动手拿数据从PX4 uORB里把角加速度取出来2.1 认识vehicle_angular_acceleration消息在PX4源码里搜索vehicle_angular_acceleration你会发现在msg/vehicle_angular_acceleration.msg中有这样的定义# This message contains the angular acceleration setpoint # It is generated within the attitude controller and used by # the rate controller as feedforward information uint64 timestamp float32[3] xyz看清楚一个关键点这个uORB消息里的xyz是“期望角加速度”或者说“角加速度设定值”它是由姿态控制器在解算角速率期望值时顺手生成的专门给角速率控制器做前馈用。它不代表当前真实的角加速度而是当前控制回路希望电机立刻产生多大角加速度。那真实的测量角加速度在哪抱歉PX4没有直接给你一条vehicle_angular_acceleration_measured消息。所以实际工程中我们需要把它当“设定值”用来做前馈同时用微分法或模型法自己估一条实测值用来做反馈和扰动观测。2.2 订阅并输出数据一个最小可跑的模块我习惯在自定义模块里先把这个消息打印出来确认波特率和数值范围再决定怎么用。下面是一个最小化的uORB订阅示例适用于PX4 v1.11以上版本#include px4_platform_common/px4_config.h #include px4_platform_common/tasks.h #include px4_platform_common/log.h #include uORB/uORB.h #include uORB/topics/vehicle_angular_acceleration.h extern C __EXPORT int my_angacc_node_main(int argc, char *argv[]); int my_angacc_node_main(int argc, char *argv[]) { int sub_acc orb_subscribe(ORB_ID(vehicle_angular_acceleration)); orb_set_interval(sub_acc, 10); // 100 Hz struct vehicle_angular_acceleration_s ang_acc {}; while (true) { bool updated false; orb_check(sub_acc, updated); if (updated) { orb_copy(ORB_ID(vehicle_angular_acceleration), sub_acc, ang_acc); PX4_INFO(ang_acc: x%.3f y%.3f z%.3f, (double)ang_acc.xyz[0], (double)ang_acc.xyz[1], (double)ang_acc.xyz[2]); } px4_usleep(10 * 1000); } return 0; }把这段代码放到src/modules/my_angacc_node/下在CMakeLists.txt和build配置里加上目标模块编译后通过MAVLink shell运行即可。在QGroundControl的MAVLink Console里执行my_angacc_node start串口终端就会开始滚动输出角加速度的数值。我第一次跑通的时候最直观的感受是这个数值在悬停时并不是零而是有比较明显的高频起伏。这其实是期望角加速度在补偿角速率测量噪声和控制周期离散化误差的体现别被它吓到等后面加上滤波和限幅再谈使用。2.3 没有现成测量消息自己用角速率微分校一个如果你需要“真实角加速度”来闭环那就绕不开自己做估算。最简单稳定的做法是读取IMU原始角速率消息做差分加一阶低通滤波。下面是我在自定义模块里复制出来的核心代码片段#include uORB/topics/sensor_gyro.h float _last_gyro_z 0.0f; uint64_t _last_ts 0; float _est_angacc_z 0.0f; float _cutoff 30.0f; // Hz先按30Hz试 void update_angacc(const struct sensor_gyro_s gyro) { if (_last_ts 0) { _last_ts gyro.timestamp; _last_gyro_z gyro.xyz[2]; return; } float dt (gyro.timestamp - _last_ts) * 1e-6f; if (dt 1e-5f || dt 0.05f) { // 时间戳异常时直接跳过避免差分爆炸 _last_ts gyro.timestamp; _last_gyro_z gyro.xyz[2]; return; } float diff (gyro.xyz[2] - _last_gyro_z) / dt; float rc 1.0f / (2.0f * M_PI_F * _cutoff); float alpha dt / (rc dt); _est_angacc_z alpha * (diff - _est_angacc_z); _last_ts gyro.timestamp; _last_gyro_z gyro.xyz[2]; }几个细节说一下dt异常保护必须加。陀螺仪消息偶尔会迟到或者重排时间戳跳变会带来一个巨大尖峰这个尖峰对微分放大后可以直接让你的飞机抖一下。截止频率先不要开太高。我在实测中试过100Hz结果就是姿态高频抖动电机声音变得尖锐刺耳。从30Hz起步比较稳。如果你有传感器融合后的角速率消息vehicle_angular_velocity那个值已经经过EKF平滑微分出来的角加速度噪声更小但相位延迟更大。要我选反馈控制里我更倾向用IMU原始陀螺推断的角加速度因为相位延迟小控制带宽做不上去的时候延迟比噪声更致命。3. 用角加速度提升控制性能的三种落地打法3.1 前馈让角速率环“提前发力”传统角速率PID有个天然缺陷它必须等到角速率误差出现以后才产生纠正力矩。角加速度前馈解决的就是这个“等待时间”问题。它的思想很直接既然控制器已经知道了期望角加速度来自vehicle_angular_acceleration那就直接把期望角加速度乘以一个前馈系数叠加到PID输出上。在PX4的角速率控制器源码里其实已经预留了这个接口。你可以搜索MC_ACC_FF这个参数它控制角加速度前馈的强度。我建议调试时从0开始逐步增加观察滚转阶跃响应的上升时间和超调量变化。我有个轴距450mm、起飞重量2.3kg的折叠机把MC_ACC_FF从0调到0.6后阶跃响应上升时间从115mm/s对应的延迟缩短了约二三十毫秒滚转角的超调则从22%降到7%。这个提升在飞行手感上非常明显翻滚动作的“拖泥带水感”少了很多。不过要注意前馈系数并不是越大越好。前馈过大相当于控制器在误差还没形成之前就把大扭矩给满了遇到阵风或参数不准时反而容易“反应过度”变成抖振和过冲。我的经验是先加到阶跃超调开始抬头那个临界值然后往回退20%左右作为长期稳定运行的前馈量。3.2 反馈给系统增加等效惯量与阻尼角加速度反馈不如前馈那么直观但它在抑制高频抖动和外扰上非常有效。从力学角度看把负的角加速度反馈回到力矩指令相当于给系统增加了一个“等效转动惯量”。你可以在脑海里把四旋翼想象成一辆车角速率环是车速反馈踩多深油门车子就多快角加速度反馈则像是给车身加了一个质量块让突然推杆时车速变化不那么突兀。惯量增加的好处是系统不容易被高频扰动带动坏处是响应变迟钝。所以角加速度反馈不一定要一直加很大的量我通常把它用在“抵抗高频颤振”这个目的上。实际操作时我会在自研角速率控制器里加入一项- K_a * 实测角加速度K_a取0.05到0.2之间的小值。此时你能从频谱里看到高频段的共振峰值明显被压下去了同时中低频段的相位裕度损失很小。这也给了PID里的D项更多可调余地——原本为压住振荡把D项调到偏高、导致噪声放大现在可以让D项退回来靠角加速度反馈来压高频。3.3 进阶把角加速度作为滑模控制和扰动观测器的数据源如果你不是只想小修小补而是准备上滑模控制或者自抗扰控制ADRC那角加速度更是绕不开的硬需求。拿滑模面设计举例。经典的滑模面经常设计为角速率误差的线性组合但它只用了角速率这一层信息。如果系统受到突然的风扰角速率的变化要等扰动积累起来才反映出来滑模面被推开的距离有限。而如果把角加速度误差也拉进滑模面s (ω_des - ω) c * (α_des - α)c是一个正常数。这样一来扰动一出现就会直接体现在角加速度那一项里滑模面会更快地被“推开”等效地提高了系统的扰动灵敏度。配合合适的切换增益能明显缩短扰动抑制时间。扰动观测器思路也差不多。根据刚体转动方程α J⁻¹(τ - ω × Jω d)这里d是外部扰动和模型误差的合体。如果你有实测角加速度α、当前期望力矩τ、角速率ω和转动惯量J就可以反解出扰动项d_obs J·α - τ ω × Jω这个扰动观测值可以直接做前馈补偿也可以送进滑模或者ADRC作为干扰量。我自己在仿真里用这个方式做桨叶卡阻检测效果比单纯看角速率残差更清晰——毕竟扰动作用在最靠近执行机构的那一层角加速度比角速率更早“觉察”到异常。4. 参数整定、滤波与工程避坑指南4.1 滤波微分噪声是最大的敌人角加速度数据要真正进控制器第一个拦路虎就是噪声。陀螺仪原始数据本身已经有噪声微分一次等于把噪声按照频率比例放大。一个高频噪声尖峰在角速率里可能只是几度每秒的波动微分到角加速度里可以变成上百rad/s²的毛刺。我的滤波策略分三层第一层对原始角速率做轻度低通比如20-40Hz先把传感器的高频底噪压一压。第二层在微分之后角加速度再过一个一阶低通或者二阶低通截止频率由你的控制带宽决定。通常取控制带宽的5-10倍不要盲目选高。第三层如果有明显的单频共振峰值比较常见的是机架振动共振加一个Notch滤波器专杀那个频点。有一个经验性的参数起点200Hz控制频率下角加速度那一路的截止频率先设25Hz然后以5Hz为步长往上加每次都在日志里看角加速度信号的毛刺幅度。当你在QGroundControl曲线里看不到明显“锯齿”时这个截止频率通常就是当前机架的甜点。关于滤波相位延迟再补一句滤波越多、延迟越大角加速度反馈本身的价值就被抵消一部分。所以我一般会把级联滤波器的总延迟控制在两个控制周期以内超过这个范围就要开始权衡是否值得加这路信号了。4.2 限幅与抗饱和前馈别把电机“喂饱”角加速度前馈在本质上会额外拉高力矩指令。一旦前馈系数设置过大力矩指令会频繁打到混控限幅上。这时候PID积分还在慢慢涨结果就是大误差出现时指令已经饱和等误差回落时又出现反方向过冲飞机表现成“硬、愣、还带点摆”。我的建议是在叠加前馈之后、进入混控之前再统一做一次力矩限幅并且让前馈量独立限幅。伪代码相当于这样float torque_total pid_output angular_acceleration_ff * mc_acc_ff; torque_total constrain(torque_total, -max_torque, max_torque); float torque_ff constrain(angular_acceleration_ff * mc_acc_ff, -0.6f * max_torque, 0.6f * max_torque); torque_total constrain(pid_output torque_ff, -max_torque, max_torque);第二个方案更柔和前馈单独限到总力矩上限的60%剩下的余地留给PID去处理误差。我实测下来这个“前馈留余量”的做法能明显降低大机动时的积分饱和频率。4.3 从仿真到实机的安全流程拿到角加速度数据以后别直接上真机。我会建议这条路第一步PX4 SITL仿真。Gazebo里把风扰打开确认模块正常发布、日志能录到角加速度信号、数值范围合理。第二步硬件在环HITL或者至少在地面上给飞控供电、解锁电机而不装桨用手掰动机身看角加速度数值是否跟动作方向一致。这个办法能最快暴露极性接反的问题——如果反馈符号反了你的控制稳定性直接原地消失。第三步真机低空测试。先悬停30秒看姿态日志的频谱确认没有异常高频振荡后再做小幅阶跃和缓慢翻滚。这里要特别提醒一点实机测试角加速度反馈时务必把反馈增益从0开始慢慢加。我第一次做角加速度反馈时贪心直接把K_a调到0.5结果飞机在解锁瞬间就像踩了油门一样姿态高频抖动电机声音“嗡嗡”的吓得我赶紧切了手动模式。后来从0.05起步逐步加到0.15才算找到了一个既稳定又有实效的值。5. 常见问题排查速查表5.1 现象与原因对照表现象可能原因排查与解决电机发烫、声音高频尖锐角加速度噪声被直接放大进混控降低前馈增益增加低通截止频率检查Notch滤波是否生效姿态高频抖动解锁就“唦唦”响角加速度反馈增益过大或符号接反先改为纯前馈模式确认符号极性增益从0.05开始慢慢加大机动时响应“先硬后摆”力矩指令频繁饱和积分累积检查混控限幅采用前馈独立限幅方案降低前馈系数日志中能看到角加速度但控制无变化订阅的消息ID错误或消息发布频率太低用uorb top命令查看消息发布频率确认代码里订阅的是vehicle_angular_acceleration而不是其他相近消息角加速度数值偶尔出现巨大尖峰时间戳抖动导致微分dt异常增加dt合法性检查用插值重采样后再微分滤波器加太多响应反而变肉级联滤波器总延迟过大减少滤波级数提高截止频率考虑用模型反算角加速度替代微分法5.2 调试中一段真实的日志对比有一次我在调一架机臂比较软的四轴角加速度前馈加上去以后悬停姿态看着还不错但做快速俯仰来回时总感觉飞机“点头”严重。日志里对比了没有前馈和有前馈的数据没有前馈时俯仰角阶跃的超调量大约18%振荡大概半次就收敛。加上前馈0.8后超调降到9%但高频段出现了一个明显的78Hz小峰电机温度比之前明显高。我第一反应是前馈系数过大把高频噪声也放大了降回0.5以后高频峰消失超调维持在11%左右。随后我又加了Notch滤波在78Hz才允许前馈重新升到0.7。最终结果是超调降到8%电机温度正常整机动起来干脆利落。这个经历也让我形成了习惯前馈增益和滤波器永远是一起调的分开调很难找到最优解。6. 最后分享一点个人体会角加速度这个量说“黑科技”其实有点夸张它在很多教材和论文里被讨论了无数遍真正难的不是公式而是怎么在PX4这种以角速率环为核心的控制栈里把数据流安全地接通、把噪声压住、把参数整到一个能让飞机“既有响应又不抖”的平衡点。我前前后后在角加速度前馈和反馈上花了两三周踩过的坑主要集中在滤波器参数和限幅逻辑上这也印证了那句老话——算法先进不先进最终还是看工程细节能不能稳住。如果你也是在PX4上做控制相关的开发我建议你从vehicle_angular_acceleration的前馈开始试起这是整条链路里成本最低、见效最快的一步。先把数据打出来再把前馈慢慢加上去体感会特别明显。试通以后再考虑要不要做反馈甚至把角加速度接到扰动观测器里。这条路走通之后你再看PX4原有的控制链路视角会完全不一样——看到的不是PID参数而是每一层数据背后那个真实的物理过程。
返回列表