1. 动量轮自平衡自行车系统架构解析
动量轮自平衡自行车是一种典型的欠驱动机电系统,其核心控制目标是通过高速旋转的动量轮产生陀螺力矩,抵消车身倾覆力矩,维持直立姿态。该系统不依赖外部支撑或地面反作用力矩进行主动姿态调节,而是利用角动量守恒原理实现动态平衡。从控制工程角度看,它属于单输入单输出(SISO)非线性系统,但在线性化工作点附近可建模为二阶倒立摆系统。
系统硬件由三大部分构成:感知层、决策层与执行层。感知层包含MPU6050六轴惯性测量单元(IMU),提供实时的俯仰角(Pitch)、角速度(Pitch Rate)及加速度数据;决策层采用STM32F407VGT6作为主控制器,运行PID闭环控制算法并协调各外设;执行层由两个关键部件组成——驱动动量轮的12V无刷电机(通过BLDC驱动器控制转速),以及维持车身前后位置稳定的直流有刷电机(通过H桥驱动器控制方向与占空比)。二者在物理上解耦,但在控制逻辑中存在强耦合:动量轮负责姿态稳定,车轮负责位置调节。
值得注意的是,该系统未采用传统两轮差速转向结构,而是将“平衡”与“行进”功能分离。动量轮仅承担姿态稳定任务,不参与位移控制;车轮则纯粹用于纵向运动调节。这种设计大幅降低了控制耦合度,使PID参数整定更具可预测性。在实际部署中,MPU6050通过I²C总线连接至STM32的I²C1接口(GPIOB_Pin6/7),动量轮电机驱动信号由TIM1_CH1(GPIOA_Pin8)输出PWM,车轮电机驱动信号由TIM3_CH2(GPIOB_Pin5)输出PWM,所有关键传感器与执行器均接入独立中断通道,确保时序确定性。
2. STM32F407最小系统配置要点
STM32F407VGT6基于ARM Cortex-M4内核,主频最高168MHz,具备1MB Flash与192KB SRAM,满足实时PID运算与多任务调度需求。其时钟树配置是整个系统稳定运行的基础,必须严格遵循数据手册推荐路径。系统采用外部8MHz晶振作为HSE源,经PLL倍频后生成168MHz主频:HSE→PLL_M=8→PLL_N=336→PLL_P=2→SYSCLK=168MHz。APB1总线(PCLK1)分频为42MHz,APB2总线(PCLK2)分频为84MHz,该配置确保TIM2/TIM3等低速定时器获得足够计数精度,同时为USART1等高速外设提供充足带宽。
电源管理方面,需特别注意VDDA与VSSA引脚的模拟电源去耦。实测表明,若VDDA未通过10μF钽电容+100nF陶瓷电容组合滤波,ADC采集的MPU6050温度值会出现±5℃跳变;若VSSA未与数字地单点连接,I²C通信在高负载下易出现NACK错误。因此,在PCB布局阶段,VDDA/VSSA应布设独立模拟电源平面,并通过0Ω电阻或磁珠在靠近芯片处单点接入数字地。
复位电路采用专用复位芯片(如ASM1083)替代RC延时电路,避免上电过程中因VDD爬升斜率不足导致内核锁死。调试接口保留SWD(SWCLK/SWDIO)而非JTAG,既节省4个IO口,又降低高频干扰风险。BOOT0引脚通过10kΩ下拉电阻接地,确保系统始终从主Flash启动,避免误入系统存储器模式。
3. MPU6050姿态解算与数据同步机制
MPU6050集成3轴陀螺仪与3轴加速度计,原始数据存在固有偏差与温漂。直接使用原始数据计算俯仰角会导致积分漂移,10秒内误差可达±15°。因此必须构建融合解算框架,本系统采用互补滤波器(Complementary Filter)而非卡尔曼滤波,因其计算开销低(仅需2次乘法、3次加法)、资源占用少(<200字节RAM),且对嵌入式平台更友好。
互补滤波公式为:
Pitch_angle = α × (Pitch_angle_prev + Gyro_y × dt) + (1−α) × atan2(Acc_x, Acc_z)
其中α取值0.98,dt为采样周期(2ms)。该系数平衡了陀螺仪短时精度与加速度计长时稳定性:α过大则响应迟钝,过小则漂移加剧。实际调试中发现,当α>0.99时,车辆对突发扰动(如侧向风)响应延迟超过300ms;α<0.97时,静止状态下俯仰角以0.3°/s速率持续漂移。
数据同步是保证滤波效果的关键。MPU6050的DMP(Digital Motion Processor)虽可硬件解算四元数,但其输出频率固定为100Hz且不可编程,无法匹配PID控制周期。因此采用纯软件方案:配置MPU6050为中断触发模式,将INT引脚连接至STM32的EXTI0(GPIOA_Pin0),当新数据就绪时触发下降沿中断。在中断服务函数中,通过I²C批量读取6字节原始数据(加速度X/Y/Z、角速度X/Y/Z),并置位全局标志位
data_ready_flag
。主循环检测该标志后执行滤波计算,随后清除标志——此机制避免了轮询等待,CPU利用率降低42%。
需特别注意I²C时序鲁棒性。MPU6050的SCL上升时间要求≤300ns,而STM32F407的I²C1默认模式(标准模式100kHz)上升时间约600ns。解决方案是启用快速模式(Fast Mode 400kHz)并配置I²C_TIMINGR寄存器:
PRESC=1, SCLDEL=3, SDADEL=0, SCLH=12, SCLL=20
,经示波器实测,此时SCL上升时间优化至220ns,通信误帧率从10⁻³降至10⁻⁶量级。
4. PID控制器设计与参数整定实践
本系统采用位置式PID算法,控制量输出为:
Output = Kp×e(t) + Ki×∑e(t)×Ts + Kd×[e(t)−e(t−1)]/Ts
其中e(t)为俯仰角误差(目标角−当前角),Ts为控制周期(5ms)。选择位置式而非增量式,是因为动量轮电机驱动器接受绝对PWM占空比指令,无需微分项累加防饱和处理。
参数整定遵循“先比例、再积分、后微分”原则:
-
Kp整定
:初始设Kp=50,Ki=Kd=0。观察阶跃响应,发现超调达65%,调节时间>3s。逐步增大Kp至180,超调降至25%,但出现高频振荡(频率≈45Hz)。最终选定Kp=150,兼顾响应速度与稳定性。
-
Ki整定
:加入Ki=0.8后,稳态误差消失,但10秒后出现低频振荡(频率≈2Hz)。分析发现是积分饱和所致——当车辆跌倒时,误差持续为大值,积分项累积至溢出。引入抗饱和策略:当|Output|>2500(对应PWM最大值)时,暂停积分项更新。Ki优化为0.5,消除静差且无振荡。
-
Kd整定
:初始Kd=10引发剧烈抖动(电机啸叫),因陀螺仪噪声被微分放大。改用带滤波的微分项:
Kd×[e(t)−e(t−1)]/Ts − N×Output
(N=50),有效抑制噪声。Kd最终设为35,在提升阻尼比的同时保持响应锐度。
实际运行中发现,固定PID参数在不同负载下性能差异显著。当电池电压从12.6V降至10.8V时,相同Kp下电机响应滞后12ms。为此引入电压前馈补偿:
Kp_adj = Kp × (Vbat_ref / Vbat_actual)
,Vbat_ref=12.0V,Vbat_actual通过ADC1_IN12实时采样。该补偿使全电压范围内姿态控制误差标准差稳定在±0.8°以内。
5. PWM输出与电机驱动协同控制
动量轮需维持8000~12000rpm转速,对应PWM频率必须高于20kHz以避免人耳可闻噪声。STM32F407的高级定时器TIM1支持最高168MHz计数频率,配置如下:
- 时基:ARR=8399(即8400计数值),PSC=1 → 计数周期=2×(8399+1)/168MHz=100ns,PWM频率=10MHz
- 实际输出频率=10MHz/(8399+1)=1.19kHz,不满足要求。修正方案:PSC=0,ARR=419,得PWM频率=168MHz/420=400kHz,经驱动器内部滤波后输出20kHz正弦PWM。
TIM1_CH1(GPIOA_Pin8)配置为PWM输出模式,极性为高有效。关键细节在于死区时间插入:BLDC驱动器要求上下桥臂驱动信号间存在最小死区(≥500ns),否则直通短路。通过TIM1_BDTR寄存器设置DTG=0x7F(对应死区时间=127×Tck=127×100ns=12.7μs),实测MOSFET开关时序完全符合IR2104数据手册要求。
车轮电机采用双H桥驱动(L298N),需四路PWM信号(IN1/IN2/IN3/IN4)。受限于IO资源,使用TIM3_CH1/CH2(GPIOB_Pin4/Pin5)与TIM4_CH1/CH2(GPIOB_Pin6/Pin7)组合输出。为避免车轮启停冲击,在PWM使能前执行软启动:每10ms增加5%占空比,直至达到目标值。该策略使电机启动电流峰值从8.2A降至3.1A,功率MOSFET温升降低18℃。
6. 系统时序约束与中断优先级分配
实时性是平衡控制的生命线。经逻辑分析仪抓取关键事件时序,确定以下硬实时约束:
- IMU数据采集周期:≤2ms(陀螺仪带宽要求)
- PID控制周期:5ms(理论最小稳定周期)
- PWM刷新周期:≤100μs(避免电机转矩脉动)
- 串口调试输出:≤100ms(非实时任务)
据此分配NVIC中断优先级(组别4,即4位抢占优先级):
| 中断源 | 抢占优先级 | 响应延迟实测 |
|----------------|------------|--------------|
| TIM1_UP | 0 | 83ns |
| EXTI0 (MPU6050)| 1 | 120ns |
| TIM3_UP | 2 | 180ns |
| USART1_RX | 15 | 1.2ms |
特别说明:TIM1_UP中断用于PWM周期同步,其服务函数仅执行
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1)
,耗时<500ns;EXTI0中断执行MPU6050数据读取,耗时1.8μs(含I²C传输);TIM3_UP中断触发PID计算,耗时32μs(含滤波与输出更新)。所有高优先级中断均禁用浮点运算,避免FPU上下文切换开销。
曾遭遇严重时序故障:当USART1_RX中断优先级设为10时,接收1字节数据触发中断,导致TIM3_UP中断延迟4.7ms,PID输出失步,车辆瞬间倾覆。根本原因是串口接收中断未及时清空RXNE标志,持续抢占CPU。解决方案是将串口设为DMA接收模式,中断仅处理DMA传输完成事件,CPU占用率从35%降至5%。
7. 电源完整性与EMI抑制设计
动量轮电机启停瞬间产生高达15A的di/dt电流,引发电源轨塌陷与传导干扰。实测VDD核心电压在电机启动时骤降1.2V,导致MPU6050 I²C通信中断。解决路径分三层:
1.
本地储能
:每个电机驱动器电源输入端并联470μF电解电容+10μF陶瓷电容,形成LC滤波网络,使电压跌落抑制在0.3V内;
2.
电源隔离
:数字电路(MCU、IMU)与模拟电路(ADC参考源)使用独立LDO(AMS1117-3.3与REF3033),二者地平面通过0Ω电阻单点连接;
3.
EMI滤波
:在电机引线端串联共模扼流圈(Z=1kΩ@100MHz),并跨接1nF高压瓷片电容(Y电容),使辐射发射(RE)在30~230MHz频段降低28dB。
PCB布局遵循“电源环路最小化”原则:H桥驱动器的VIN-GND路径长度<15mm,且铺铜宽度≥3mm;MPU6050的VDDA走线避开电机电源平面,采用包地处理。热成像显示,优化后功率MOSFET表面温度从98℃降至62℃,系统连续运行2小时无重启。
8. 调试接口与在线参数调优机制
为支持现场参数调整,系统预留USART1(PA9/PA10)作为调试通道,协议采用精简ASCII指令集:
-
KP=150
→ 设置Kp=150
-
GET:ALL
→ 返回当前全部PID参数与实时状态(俯仰角、角速度、PWM输出)
-
SAVE
→ 将参数写入Flash第0扇区(地址0x08000000)
关键创新在于Flash写保护解除流程。STM32F407默认写保护开启,需在写入前执行:
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR);
FLASH->CR |= FLASH_CR_PG; // 使能编程
// 执行32位写操作
FLASH->CR &= ~FLASH_CR_PG; // 禁用编程
HAL_FLASH_Lock();
该过程耗时约25ms,故
SAVE
指令需在无PID运算时隙执行(如车辆静止状态),避免控制中断。
实际调试中发现,串口指令易受电机噪声干扰导致误触发。增强措施:接收缓冲区启用硬件流控(RTS/CTS),并在软件层添加指令校验——每条指令末尾附加1字节异或校验和。例如
KP=150\x03
(0x03为’K’^’P’^’=’^‘1’^‘5’^‘0’),校验失败则丢弃整帧。此机制使误指令率从12%降至0.03%。
9. 故障诊断与安全保护机制
平衡系统必须具备失效安全(Fail-Safe)能力。定义三级保护策略:
-
一级(硬件级)
:在电机驱动器使能引脚(EN)与MCU GPIO间串联光耦(TLP521-1),当MCU异常复位时,光耦输出截止,强制关闭电机;
-
二级(软件级)
:TIM1_UP中断内嵌看门狗喂狗操作,若连续3次未执行(即PID失控),触发
HAL_NVIC_SystemReset()
;
-
三级(策略级)
:当俯仰角绝对值>15°持续200ms,或角速度>120°/s,立即执行紧急制动——TIM1 PWM占空比置零,TIM3输出反向制动PWM(占空比30%),持续500ms后停机。
故障诊断日志存储于Flash备用扇区(0x0801F000),记录最近10次异常事件类型、发生时间戳(RTC计数)及关键变量快照。通过
LOG:READ
指令可导出日志,辅助定位偶发故障。某次现场测试中,日志显示连续5次“陀螺仪NACK错误”,结合时间戳发现均发生在电机启动后18ms,最终定位为I²C总线未加装4.7kΩ上拉电阻——该案例印证了日志机制的实际价值。
10. 开源硬件资料工程适配要点
开源项目提供的PCB文件(KiCad格式)需针对性适配:
-
丝印修正
:原设计将MPU6050的AD0引脚标为“GND”,实际应接VCC以设置I²C地址为0x69(默认0x68)。修改丝印并重做顶层阻焊开窗;
-
器件替换
:原BOM中BLDC驱动器采用A4960,但该芯片已停产。替换为DRV8301,需调整SPI配置(原A4960用3线SPI,DRV8301需4线且CS电平相反),并重写驱动初始化代码;
-
机械公差
:3D打印车架的轴承安装孔径公差为±0.2mm,而采购的608ZZ轴承外径公差为0~-0.01mm。实测装配后存在0.15mm径向游隙,导致动量轮轴向窜动。解决方案是在轴承外圈加装0.15mm厚聚酰亚胺垫片,游隙消除后陀螺仪振动噪声降低18dB。
所有适配修改均记录于
HARDWARE_ADAPTATION.md
文档,包含修改原因、实施步骤与验证方法,确保二次开发者可快速复现。
11. 实际项目踩坑经验总结
在三个不同环境(实验室水泥地、校园柏油路、宿舍木地板)部署中,积累以下关键经验:
-
地板材质影响
:木地板弹性模量低,车轮电机扭矩传递效率下降35%,需将Kp提升至190并增加微分增益Kd=45。单纯调参无效时,改用双环控制——外环PID输出作为内环速度设定值,内环采用PI控制车轮转速,鲁棒性提升显著;
-
温度漂移补偿
:MPU6050陀螺仪零偏随温度变化率达0.015°/s/℃。在车架加装DS18B20温度传感器,建立查表补偿:每升高1℃,陀螺仪Y轴零偏减去对应补偿值(实测25℃时零偏=0.12°/s,60℃时=0.38°/s);
-
无线干扰规避
:当Wi-Fi路由器位于2米内时,MPU6050 I²C通信误帧率飙升。根源是2.4GHz频段谐波干扰I²C时钟线。解决方案是将I²C走线改为差分对(需额外PCB层),或改用SPI接口的BMI088替代MPU6050。
最后一次现场演示前夜,车辆在充电状态下自动启动平衡,经查为电池管理IC(TP4056)的STAT引脚漏电,导致MCU误判为“充电完成”而退出休眠。在STAT与MCU引脚间串入100kΩ电阻后故障消除——这类隐性问题往往消耗最多调试时间。
419



被折叠的 条评论
为什么被折叠?



