平衡小车转向环PID调优实战:从编码器到陀螺仪的融合策略

张开发
2026/4/16 12:40:15 15 分钟阅读

分享文章

平衡小车转向环PID调优实战:从编码器到陀螺仪的融合策略
1. 平衡小车转向环的核心作用刚接触平衡小车时很多朋友会疑惑为什么有了平衡环和速度环还需要转向环我最初调试小车时也遇到过这个问题——明明给了两个电机相同的PWM值小车却像喝醉酒一样歪歪扭扭走不了直线。后来拆开电机才发现即使是同型号的减速电机实际转速也可能有5%-10%的差异。转向环就像个智能交警实时协调两个轮子的转速差。这里有个实际案例去年帮学生调试参赛小车时未启用转向环的情况下10米直线行驶能偏移2米多。加入P控制转向环后偏移缩小到20厘米内。但遇到瓷砖接缝处车轮打滑时单纯依赖编码器的方案又会失效。这就是为什么我们需要融合编码器与陀螺仪数据——前者反映轮速差位置偏差后者感知车身偏转角速度两者互补能应对更多复杂场景。转向环通常不需要积分项I参数主要原因有三偏航角存在累积误差车轮打滑时会产生错误积分转向控制对静差容忍度较高实际工程中PWM合成公式要注意符号处理。比如我的硬件配置中正向旋转时编码器值递增那么PWM合成公式应该是Moto1 Balance_Pwm Velocity_Pwm - Turn_Pwm; // 左电机 Moto2 Balance_Pwm Velocity_Pwm Turn_Pwm; // 右电机如果小车转向方向反了不要急着改代码先把Turn_Pwm前的正负号调换试试这种问题我调试时遇到过至少三次。2. 纯P控制的两种实现方案2.1 编码器差值方案用左右编码器差值作为偏差源是最直观的方案我在早期版本中这样实现过int turn_encoder_only(int encoder_left, int encoder_right) { int bias encoder_left - encoder_right; // 右轮快时bias为负 return Kp_turn * bias; // Kp_turn建议从0.3开始尝试 }这个方案的优点是响应直接我在实验室光滑地板上测试时直线精度能达到±5cm/米。但带到室外就暴露问题当一侧车轮压在石子路上打滑时编码器读数失效小车会突然转向。后来用纸板模拟打滑测试发现最大会有30度的方向偏差。参数调试要点Kp_turn过大时会出现蛇形走位建议先用0.2-0.5范围的值调试时可以用胶带暂时固定小车手动转动一侧轮子观察PWM响应2.2 陀螺仪方案改用MPU6050的Z轴陀螺仪后抗打滑能力明显提升。这里有个细节陀螺仪原始数据需要换算为度/秒。我的校准方法是静止放置传感器记录200ms的原始值平均值作为零偏手动旋转小车360°记录最大值对应比例系数int turn_gyro_only(int gyro_z) { float dps (gyro_z - zero_offset) * scale_factor; // 度/秒 return Kp_turn * dps; }实测发现纯陀螺仪方案在低速时会有持续偏航Yaw Drift就像我测试时的小车1分钟后能偏出15度角。这时需要配合编码器做数据融合。3. PD控制与传感器融合实战3.1 融合策略设计经过多次迭代我总结出这个融合方案编码器差值积分→反映累计偏航角P项陀螺仪瞬时值→反映当前角速度D项具体实现时要注意三个坑编码器差值需要限幅处理陀螺仪数据需要低通滤波两者量纲不同需要归一化这是我的改进版代码#define TURN_MAX_BIAS 50 // 对应约5度偏航角 int turn_pd_fusion(int encoder_left, int encoder_right, int gyro_z) { static float bias_integral 0; float gyro_dps (gyro_z - 150) / 131.0; // MPU6050换算公式 // 更新偏差积分(限幅处理) float delta_bias (encoder_left - encoder_right) * 0.01f; // 缩放因子 bias_integral constrain(bias_integral delta_bias, -TURN_MAX_BIAS, TURN_MAX_BIAS); // 二阶巴特沃斯滤波(截止频率10Hz) static Filter gyro_filter; float filtered_dps filter_update(gyro_filter, gyro_dps); return Kp * bias_integral Kd * filtered_dps; }3.2 参数整定技巧调试PD参数时我习惯用这个流程先将Kd设为0按纯P模式调试给小车一个初始偏转观察回正过程欠阻尼缓慢振荡回正 → 增大Kp过阻尼回正速度慢 → 减小Kd加入D项抑制振荡实测参数范围参考Kp0.5-2.0每度偏航角对应的PWM增量Kd8-15每度/秒角速度对应的PWM增量有个小技巧在调试时用蓝牙模块实时发送数据到手机我用这个方式发现当Kd20时电机会出现高频震颤。4. 抗干扰优化策略4.1 打滑检测机制去年比赛时我们加入了打滑判断逻辑bool is_wheel_slipping(int encoder_diff, float gyro_dps) { float expected_dps encoder_diff * WHEEL_RADIUS / TRACK_WIDTH; return fabs(gyro_dps - expected_dps) SLIP_THRESHOLD; }当检测到打滑时临时提高陀螺仪权重这个改进让小车在湿滑路面上的控制精度提升了60%。4.2 动态参数调整进阶方案可以引入参数自整定void dynamic_adjust(float speed) { // 速度越高减小Kp增大Kd Kp BASE_KP * (1 - speed/MAX_SPEED); Kd BASE_KD * (1 speed/MAX_SPEED); }这个策略的实测效果在1m/s速度下转向超调量从35%降到12%。5. 常见问题排查遇到转向异常时建议按这个顺序检查传感器数据是否正常编码器计数方向是否正确陀螺仪零偏是否校准控制量极性是否正确正偏差是否导致正确的PWM调整机械结构问题轮胎是否打滑电机安装是否对称最近调试的一个案例小车总是单方向转向过度最终发现是电机减速箱齿轮间隙过大更换电机后问题解决。硬件问题往往比软件问题更隐蔽这是我多年调试最深的体会。

更多文章