MATLAB直线倒立摆一阶倒立摆LQR控制仿真,小车倒立摆起摆和平衡控制,附带参考文献

% 系统参数(单位全部国际标准制)
M = 0.5;    % 小车质量
m = 0.2;    % 摆杆质量
l = 0.3;    % 摆杆半长
g = 9.81;   % 重力加速度

% 状态空间模型推导
denominator = M + m*(1 - 3/4*cos(theta)^2); % 分母项
A = [0 1 0 0; 
    0 0 (-3*m*l*g)/(4*(M+m)) 0;
    0 0 0 1;
    0 0 (3*g)/(4*l) 0]; % 线性化后的状态矩阵
B = [0; 4/(4*M + m); 0; -3/(l*(4*M + m))]; % 输入矩阵

这里有个坑:很多人直接抄书上的状态方程,结果仿真时发现摆杆往反方向倒。注意第三行(3g)/(4l)这个项的正负号,取决于你定义摆角θ的正方向是不是和重力方向相同。

LQR控制器设计才是重头戏,权重矩阵Q和R的选取直接决定控制效果:

Q = diag([10, 1, 100, 10]);  % 状态权重
R = 0.1;                     % 输入权重
[K, S, CLP] = lqr(A, B, Q, R); % 求解Riccati方程

% 验证可控性
Co = ctrb(A, B);
if rank(Co) == size(A,1)
    disp('系统完全可控') 
else
    error('别玩了,这系统控不住')
end

这里有个骚操作:把摆杆角度θ的权重设为100,而小车位置只给10。相当于告诉控制器"宁可让小车多跑几步,也要先把杆子立住"。实际调试时可以听到电机声音明显不同——当Q矩阵里角度权重不够时,电机会发出神经质的高频震动。

起摆控制比较有意思,这里用了个取巧的办法——给摆杆加个初始脉冲:

% 起摆阶段参数
swing_up_gain = 15;  % 震荡增益
if abs(theta) < pi/6  % 进入平衡区切换控制器
    u = -K*x; 
else
    u = swing_up_gain*theta; % 粗暴但有效的起摆策略
end

这个震荡起摆策略虽然比不上能量法优雅,但在实际快速原型开发中特别管用。曾经在实验室试过,用这种简单PID震荡起摆,配合LQR平衡控制,五分钟就能让摆杆立起来。

仿真结果跑起来之后注意看两个现象:1.小车会先往后挪一步再前进,这是用水平位移换角动量守恒;2.稳态时控制力会有微小震荡,主要是因为我们没考虑电机死区特性。想要更丝滑的效果可以试试抗积分饱和:

% 抗饱和补偿
integral_term = integral_term + Ki*(x(1) - ref);
if abs(u) > u_max
    integral_term = integral_term - sign(u)*0.1; % 反向补偿
end

最后扔几个经典参考,搞这行的应该都见过:

1.《现代控制工程》第五版,Ogata著,LQR部分讲得透彻

2.《基于MATLAB的控制系统仿真》有个倒立摆专题

  1. IEEE那篇《Swing-up Control of Inverted Pendulum》讲起摆策略

仿真文件里记得加动画显示,看着摆杆晃晃悠悠立起来的时候,你会想起第一次骑自行车不摔跤的成就感——虽然只是个仿真模型,但那种掌控物理规律的感觉,爽!

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐