旋转倒立摆是电子设计竞赛中的经典控制类题目,也是验证PID算法效果的绝佳实验平台。这个系统由旋转臂、摆杆、电机和角度传感器构成,核心挑战在于通过电机控制旋转臂运动,使自由摆动的摆杆保持倒立状态。我去年带队参加省赛时,完整实现了包括PID稳定控制、60度规律摆动和圆周运动三大功能模块,整套系统从机械结构到控制算法全部自主设计,最终获得省级一等奖。
这个项目的难点在于动力学建模的准确性和控制算法的实时性。摆杆的运动遵循非线性动力学规律,而电机响应存在滞后性,必须通过精确的数学模型和快速的控制循环才能实现稳定。我们采用STM32F407作为主控芯片,配合高精度编码器和直流减速电机,控制周期严格控制在5ms以内。下面我将从硬件设计、算法实现和调试技巧三个维度,详细拆解这个项目的技术要点。
旋转倒立摆的机械结构直接影响控制效果。我们的设计采用6061铝合金作为旋转臂材料(长度30cm,重量控制在120g以内),摆杆使用碳纤维管(长度50cm,末端配重50g)。关键设计参数包括:
重要提示:摆杆重心位置必须精确测量,我们使用三点悬挂法测得实际重心与理论计算相差3mm,这个误差会导致数学模型失效。
控制系统的硬件架构遵循实时性原则:
code复制[编码器] → [STM32F407] → [DRV8833电机驱动] → [直流减速电机]
↑
[OLED显示屏] ← [MPU6050]
倒立摆的动力学方程推导基于拉格朗日方程:
code复制θ'' = (mgl sinθ - bθ' + mlx'' cosθ)/(ml²)
其中m为摆杆质量,l为重心到转轴距离,b为阻尼系数。我们在MATLAB Simulink中搭建了非线性模型,通过PID Tuner工具获得初始参数:
核心控制代码采用位置式PID算法:
c复制// 在定时器中断服务函数中执行
void TIM3_IRQHandler(void) {
static float last_error = 0, integral = 0;
float error = target_angle - current_angle;
integral += error * dt;
if(integral > 300) integral = 300; // 抗积分饱和
if(integral < -300) integral = -300;
float derivative = (error - last_error) / dt;
output = Kp*error + Ki*integral + Kd*derivative;
last_error = error;
set_motor_pwm(output);
}
功能一:60度规律摆动
mermaid复制stateDiagram
[*] --> 正向加速
正向加速 --> 匀速运动: 达到30度位置
匀速运动 --> 减速制动: 达到50度位置
减速制动 --> 反向加速: 达到60度位置
反向加速 --> 匀速运动: 回到30度位置
功能二:圆周运动控制
通过坐标变换将旋转角度φ和摆杆角度θ转换为极坐标控制:
code复制F = Kp1*(R - r) + Kp2*(θ - π)
其中R为期望圆周半径,r为实际投影半径。
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 摆杆无法立起 | 电机力矩不足 | 检查电源电压≥12V |
| 周期性振荡 | 微分项过小 | 增加Kd 10% |
| 偏向一侧 | 机械不平衡 | 重新校准重心 |
| 响应迟钝 | 控制周期过长 | 优化代码至<5ms |
当编码器出现丢脉冲时,采用卡尔曼滤波融合MPU6050数据:
c复制// 预测步骤
x_hat = A * x_hat + B * u;
P = A * P * A' + Q;
// 更新步骤
K = P * H' * inv(H * P * H' + R);
x_hat = x_hat + K * (z - H * x_hat);
P = (I - K * H) * P;
针对非线性特性,我们试验了模糊控制规则:
code复制IF error is PB AND d_error is NS THEN output is PM
实际测试表明在快速摆动时改善明显,但增加了8%的CPU负载。
整套系统从机械装配到算法调试共耗时3周,最大的收获是认识到理论建模与实际系统的差异。例如我们发现电机死区电压达到1.2V,必须在代码中加入死区补偿:
c复制if(output > 0) output += 1.2;
else if(output < 0) output -= 1.2;
这种实战经验才是电赛真正的价值所在。