当前位置: 首页 > news >正文

stm32四轴飞行器BUG篇

偏航推杆导致油门失控问题分析

问题现象

当偏航(YAW)推杆推到最大值(>1820)或最小值(<1180)后,油门完全失控——油门会自动飙到最大值,用户此时只能控制油门在最大值和最小值之间切换,无法正常调节油门大小。


根本原因

pidYaw.desired(偏航角期望值)没有上限/下限限制,在偏航推杆持续处于极限位置时会无限增长/衰减,导致外环偏航PID输出暴涨,最终通过串级PID传导至电机混控,吞掉所有PWM余量,油门基线形同虚设。


详细分析

1. 问题触发路径

偏航推杆极限位 (YAW > 1820 或 YAW < 1180) ↓ FlyPidControl() 每 3ms 调用一次 ↓ pidYaw.desired 持续累加/累减 0.75(无上下限!) ↓ pidYaw.out = kp × (desired - measured) 急剧增大 ↓ pidRateZ.desired = pidYaw.out 内环期望值飙升 ↓ pidRateZ.out = kp × (pidRateZ.desired - gyro_Z) 内环输出飙升 ↓ 电机混控中 ± pidRateZ.out 成为主导项 ↓ 油门基线 (THR-1000)*0.7 被完全淹没 ↓ 油门失控

2. 关键代码位置

文件:Fly/FlyContrl.c,函数FlyPidControl(),第 220-227 行:

if(FlyRecData.YAW>1820){pidYaw.desired-=0.75f;// 每3ms减0.75,每秒减250度!}elseif(FlyRecData.YAW<1180){pidYaw.desired+=0.75f;// 每3ms加0.75,每秒加250度!}

问题:pidYaw.desired没有任何Limit()约束。如果偏航推杆持续在极限位置 1 秒,期望值就会漂移±250 度;持续 4 秒就是±1000 度

3. 定量推算失控过程

假设偏航推杆推到最大值(YAW > 1820)持续 3 秒:

时间pidYaw.desiredpidYaw.out (kp=6.0)pidRateZ.out (kp=2.0)
0s000
0.5s-125-750-1500
1.0s-250-1500-3000
2.0s-500-3000-6000
3.0s-750-4500-9000

电机混控公式(FlyContrl_Motor_3ms()第 44-47 行):

MOTOR1+=+pidRateX.out-pidRateY.out-pidRateZ.out;// -(-9000) = +9000 → 限幅到1000MOTOR2+=+pidRateX.out+pidRateY.out+pidRateZ.out;// +(-9000) = -9000 → 限幅到0MOTOR3+=-pidRateX.out+pidRateY.out-pidRateZ.out;// -(-9000) = +9000 → 限幅到1000MOTOR4+=-pidRateX.out-pidRateY.out+pidRateZ.out;// +(-9000) = -9000 → 限幅到0

结果:电机1和3满转(1000),电机2和4停转(0),油门基线(THR-1000)*0.7(最大仅700)完全被 ±9000 级别的PID输出淹没。无论用户如何操作油门推杆,电机输出都被死死限制在 0 或 1000。

4. 为什么"只能控制油门在最大值到最小值"?

因为Limit()函数将每个电机PWM限制在[0, 1000]范围内。当pidRateZ.out绝对值超过 1000 后,电机输出就变成了纯开关量——不是 0 就是 1000,中间没有任何过渡。用户推油门时,只能看到电机从 0 跳到 1000(或反之),中间没有任何线性控制区间。


修复方案

方案一:限制pidYaw.desired的范围(推荐)

FlyPidControl()中,对pidYaw.desired添加限幅:

// 在 FlyPidControl() 的 case 2 中,偏航期望值计算后添加if(FlyRecData.YAW>1820){pidYaw.desired-=0.75f;}elseif(FlyRecData.YAW<1180){pidYaw.desired+=0.75f;}// ★ 添加以下限幅代码 ★if(pidYaw.desired>360.0f)pidYaw.desired=360.0f;if(pidYaw.desired<-360.0f)pidYaw.desired=-360.0f;

偏航角正常情况下不需要超过 ±360 度的期望值,合理限幅即可。

方案二:将偏航期望值改为绝对位置映射(更优)

当前的累加模式存在漂移问题。更好的做法是将摇杆位置直接映射为偏航角速度期望值:

// 替换当前的累加逻辑if(FlyRecData.YAW>1820){pidRateZ.desired=150.0f;// 直接设定期望角速度(度/秒),而不是不断累加角度}elseif(FlyRecData.YAW<1180){pidRateZ.desired=-150.0f;}else{pidRateZ.desired=0.0f;}

这样做的好处:

  • 偏航期望值不会无限累加
  • 摇杆回中后偏航立即停止
  • 移除外环偏航角PID,简化控制结构
  • 这是大多数穿越机/无人机飞控的通用做法——偏航直接控制角速度,而非角度

方案三:对PID输出增加总限幅(兜底保护)

无论采用哪种方案,建议在pidUpdate()函数中增加输出限幅:

voidpidUpdate(PidObject*pid,constfloatdt){// ... 原有计算 ...pid->out=pid->kp*error+pid->ki*pid->integ+pid->kd*deriv;// ★ 增加输出限幅 ★if(pid->out>500.0f)pid->out=500.0f;if(pid->out<-500.0f)pid->out=-500.0f;pid->prevError=error;}

同时在pidRest()中也要重置desiredmeasured

voidpidRest(PidObject**pid,constuint8_tlen){uint8_ti;for(i=0;i<len;i++){pid[i]->integ=0;pid[i]->prevError=0;pid[i]->out=0;pid[i]->desired=pid[i]->measured;// ★ 复位时期望值同步到当前测量值 ★}}

额外发现:解锁/锁定逻辑的竞争条件

FlyContrl_Unlock_10ms()第 98 行,立即锁定条件是:

if(FlyRecData.THR<1100&&(FlyRecData.YAW<1100||FlyRecData.YAW>1900))

这意味着只有当油门同时也处于低位时,偏航极限位才会触发锁定。如果用户在飞行中(油门较高时)推偏航到极限,此条件不满足,飞机不会锁定,但pidYaw.desired已经开始疯狂漂移——这正是本次bug的触发场景。

建议增加一个飞行中偏航极限位的保护逻辑,例如检测到pidYaw.desired超过阈值时自动钳位,而不是依赖解除锁定。


总结

项目内容
问题根因pidYaw.desired无限累加,无上下限保护
影响范围偏航推杆极限位时油门完全失控
严重程度严重- 飞行中触发会导致炸机
推荐修复方案一 + 方案三(双重保护),长远考虑方案二(重构偏航控制策略)
修复文件Fly/FlyContrl.cFlyPidControl函数)、Fly/pid.cpidUpdatepidRest函数)
http://www.jsqmd.com/news/1119319/

相关文章:

  • 终极DLSS切换秘籍:3步解锁游戏性能新境界
  • CentOS8.0编译源码安装nginx和防火墙使用
  • 政企汇报宣传片为什么离不开 3D 动画?
  • PCB设计中孤铜现象的影响与AD18处理技巧
  • 奇门取号报“订单号不一致”?一次 trade_order_list 的排查实录
  • 《唤醒你的AI同事:WorkBuddy从零上手》034:提示词编写技巧
  • YOLO11全任务适配指南:检测、分割、姿态估计的性能调优技巧
  • 48. OrCAD在创建封装库时,管脚数目很多的元器件应该怎么合理?I Cadence Allegro 电子设计 快问快答
  • 设备单元级(L1)实施路径
  • 批量压缩图片还在用在线工具?这款648KB小软件,画质不变体积暴减
  • 不用喂食不用换水的“水族箱”、逆向净水器的智能水龙头,接入 Home Assistant、用 RF 破解把吊扇接入智能家居|DF创客周刊(第178期)
  • 星火X1 0725 vs 豆包:办公场景下AI模型精准能力实测
  • 混凝土裂隙数据集 建筑物裂缝分割数据集 1000张yolo数据集
  • 【AI编程代码审查黄金标准】:20年资深架构师亲授5大质量保障铁律,错过再等十年?
  • JMeter分布式压测实战:突破单机瓶颈,模拟海量并发
  • 高速PMSM无感控制三大难题与工程解决方案
  • ShadingModel与Lighting
  • ClaudeAPI 医疗场景落地指南:适用边界、提示词与审核流程
  • C++语言基础1:作用域解析运算符“::”详细讲解
  • Scrum落地避坑指南:一个技术负责人踩过的5个流程管理深坑与解法
  • 云服务器已进入黑暗森林时代
  • 【Linux网络】深入 HTTP 协议(一):从初识到 URL 编解码底层探索
  • 【AVRCP】规范精讲[38]:本地调节音量,控制器如何同步感知与更新
  • 演唱会、音乐会适合用的Tally灯
  • DLSS Swapper终极指南:如何智能切换DLSS版本提升游戏帧率
  • 《唤醒你的AI同事:WorkBuddy从零上手》035:工作流程优化
  • 【C++】008、sizeof与strlen的区别
  • 无刷电机控制系统架构与优化实践
  • Kimi K2.5 vs GPT-5.4编程实测:长文本与推理能力硬核对比
  • 如何快速打造个性化桌面:Ark-Pets开源桌宠完整指南