用OpenMV+STM32F103做小车跟踪,我是怎么调PID让后车稳稳跟住前车的?

张开发
2026/4/21 3:45:47 15 分钟阅读

分享文章

用OpenMV+STM32F103做小车跟踪,我是怎么调PID让后车稳稳跟住前车的?
STM32OpenMV视觉跟踪小车的PID调参实战指南当你的视觉跟踪小车开始像醉汉一样左右摇摆或是反应迟钝得像个树懒问题往往出在PID参数的设置上。我花了整整三个周末烧坏了两个电机驱动模块才摸透了这套让小车乖乖听话的调参方法论。1. 理解视觉跟踪中的PID控制逻辑在OpenMV与STM32组成的跟踪系统中PID控制器实际上在处理两个维度的误差距离误差Z轴方向和位置误差X轴方向。OpenMV通过识别二维码返回的Tx_num和Tz_num就是这两个误差的原始数据。典型的控制流程是这样的OpenMV检测前车二维码计算中心点偏移量将X轴偏移量传给x_PID()Z轴距离传给PID()两个PID输出分别控制转向力矩和行进速度电机驱动模块执行合成后的控制量// 典型的位置式PID实现 float PID(float KP, float KI, float KD, float target, float current) { error current - target; integral error; derivative error - last_error; output KP*error KI*integral KD*derivative; last_error error; return output; }2. 诊断常见跟踪问题的技巧2.1 振荡现象的破解方法当小车像钟摆一样来回摆动说明系统存在过阻尼。去年电赛中有支队伍的小车甚至因为振荡太剧烈直接翻车。通过串口打印误差变化曲线可以清晰看到三种典型问题模式现象波形特征主要问题参数低频大幅摆动正弦波状周期长KP过大KD不足高频小幅抖动锯齿状快速波动KD过大KP偏高单向偏移后振荡阶梯状上升后波动KI设置不当提示使用OLED实时显示error和output值比单纯看串口数据更直观2.2 响应迟钝的优化策略遇到小车反应慢半拍的情况先检查OpenMV的图像处理帧率# OpenMV帧率测试代码 import time clock time.clock() while(True): clock.tick() img sensor.snapshot() # ...图像处理代码... print(clock.fps())如果帧率低于20fps可能需要降低图像分辨率关闭不必要的图像特效优化二维码检测算法3. 参数整定的实战步骤3.1 比例系数KP的黄金法则我总结的KP调参三步法先将KI和KD设为0KP从较小值开始如5.0观察小车响应完全没反应以50%幅度递增KP出现轻微振荡记录此时KP值为临界值Kp_max最终KP取临界值的60-70%// 调试示例KP阶梯测试 float KP_test[] {5.0, 7.5, 10.0, 15.0, 20.0}; // 测试序列 for(int i0; i5; i){ KP KP_test[i]; printf(Testing KP%.1f\n, KP); HAL_Delay(3000); // 每个参数测试3秒 }3.2 微分项KD的整定技巧KD的引入是为了抑制振荡但过大的KD会导致电机呻吟现象——电机发出高频嗡嗡声。我的经验公式KD初始值 KP × 采样周期 × 0.1例如当KP20OpenMV帧率为30fps周期≈0.033s时KD 20 × 0.033 × 0.1 ≈ 0.0663.3 积分项KI的注意事项积分项是许多调参新手的噩梦。我曾见过一个KI设太大的案例小车直接加速撞上前车。安全实践初始值设为KP/100增加积分限幅// 带限幅的积分项 integral error; if(integral 1000) integral 1000; if(integral -1000) integral -1000;加入积分分离——仅当误差较小时启用积分4. 高级调试手段4.1 串口数据可视化用Python matplotlib实时绘制参数曲线# 数据可视化代码示例 import matplotlib.pyplot as plt import serial ser serial.Serial(COM3, 115200) plt.ion() fig, ax plt.subplots(3) while True: data ser.readline().decode().strip().split(,) error, output, pwm map(float, data) ax[0].plot(error, r-) ax[1].plot(output, b-) ax[2].plot(pwm, g-) plt.pause(0.01)4.2 电机死区补偿低价直流电机常有死区问题表现为低速时不转超过某个PWM值突然启动。补偿方法// 死区补偿函数 int applyDeadband(int pwm, int threshold){ if(abs(pwm) threshold) return 0; else if(pwm 0) return pwm threshold; else return pwm - threshold; }4.3 动态参数调整根据跟踪距离自动调节参数if(Tz_num 30.0){ // 近距离 KP 15.0; KD 0.5; }else{ // 远距离 KP 25.0; KD 0.3; }调参到最后我发现最稳定的参数组合往往是KP占主导70-80%KD适量15-20%KI仅微量5-10%。但记住没有放之四海皆准的完美参数关键是要理解每个参数对系统动态特性的影响规律。

更多文章