手把手教你用Matlab/Simulink搭建小车倒立摆模型(附动画脚本)

手把手教你用Matlab/Simulink搭建小车倒立摆模型(附动画脚本)
手把手教你用Matlab/Simulink搭建小车倒立摆模型附动画脚本倒立摆系统作为控制理论中的经典案例不仅在教学演示中具有重要地位更是工程实践中验证控制算法的理想平台。本文将带你从零开始一步步完成小车倒立摆的物理建模、Simulink仿真实现以及运动动画生成无需任何前置经验只需跟随操作即可获得直观的可视化结果。1. 环境准备与基础建模1.1 系统参数定义首先在Matlab脚本中定义系统物理参数建议使用.m脚本统一管理% 系统物理参数 M 0.5; % 小车质量(kg) m 0.2; % 摆杆质量(kg) b 0.1; % 小车摩擦系数(N/m/s) l 0.3; % 摆杆长度(m) g 9.8; % 重力加速度(m/s^2)1.2 动力学方程推导采用拉格朗日法建立系统动力学方程。关键推导步骤如下建立系统动能表达式小车平动动能$T_c \frac{1}{2}M\dot{x}^2$摆杆复合动能$T_p \frac{1}{2}m(\dot{x}_p^2 \dot{y}_p^2)$建立系统势能表达式$V mgl\cosθ$构造拉格朗日函数$L T - V (T_c T_p) - V$最终得到的非线性微分方程$$ \begin{cases} (Mm)\ddot{x} ml\ddotθ\cosθ - ml\dotθ^2\sinθ b\dot{x} F \ ml\ddot{x}\cosθ ml^2\ddotθ - mgl\sinθ 0 \end{cases} $$2. Simulink模型搭建2.1 非线性模型实现在Simulink中按照以下结构搭建模型[F] → [Sum] → [1/(Mm)] → [Integrator] → [Velocity] ↑ ↑ └── [Feedback Terms] ← [Theta Calculation]具体操作步骤新建Blank Model从Library Browser添加以下模块Integrator×4分别对应x, dx, θ, dθGain设置质量参数Trigonometric Function处理sin/cos项Product处理耦合项关键配置参数% 在Model Properties → Callbacks中添加初始化代码 set_param(gcs, Solver, ode45); set_param(gcs, StopTime, 10);2.2 线性化模型对比在工作空间生成线性化模型% 在平衡点附近线性化 [A,B,C,D] linmod(InvertedPendulum_Nonlinear); sys_linear ss(A,B,C,D);通过以下命令验证线性化效果% 对比非线性与线性响应 initial_angle 0.1; % 小角度验证 simOut sim(InvertedPendulum_Nonlinear); figure; plot(simOut.tout, simOut.theta); hold on; [y,t] initial(sys_linear, [0;0;initial_angle;0]); plot(t, y(:,2), --); legend(Nonlinear,Linearized);3. 控制系统设计3.1 LQR控制器实现设计状态反馈控制器% 权重矩阵设置 Q diag([10 1 100 10]); % 重点控制角度偏差 R 0.01; % 控制输入权重 % LQR求解 [K, S, e] lqr(A, B, Q, R); % 闭环系统验证 sys_cl ss(A-B*K, B, C, D); step(sys_cl);典型调试经验若小车位移响应过慢增加Q矩阵中x的权重若控制力过大减小R值角度振荡时可调整dθ的权重3.2 状态观测器设计当只有角度可测量时设计Kalman滤波器% 观测矩阵调整假设仅测量角度 C_obs [0 0 1 0]; D_obs 0; % 噪声协方差矩阵 Vd diag([0.1 0.1 0.5 0.5]); % 过程噪声 Vn 0.01; % 测量噪声 % Kalman增益计算 [Kf,P,E] lqe(A, eye(4), C_obs, Vd, Vn);4. 动画可视化实现4.1 实时动画脚本创建animate_pendulum.m脚本function animate_pendulum(t, x, theta) figure; h1 plot([0], [0], k-, LineWidth, 2); % 小车 hold on; h2 plot([0], [0], r-o, LineWidth, 2); % 摆杆 axis([-2 2 -0.5 1.5]); for k 1:length(t) % 小车位置更新 car_x [x(k)-0.2 x(k)0.2]; car_y [0 0]; set(h1, XData, car_x, YData, car_y); % 摆杆位置更新 pend_x [x(k) x(k)l*sin(theta(k))]; pend_y [0 l*cos(theta(k))]; set(h2, XData, pend_x, YData, pend_y); drawnow; pause(0.01); end end4.2 仿真结果可视化在Simulink模型最后添加To Workspace模块导出仿真数据后调用动画函数% 运行仿真 simOut sim(InvertedPendulum_Full); % 提取数据 t simOut.tout; x simOut.x.Data; theta simOut.theta.Data; % 生成动画 animate_pendulum(t, x, theta); % 保存为视频需要Image Processing Toolbox writerObj VideoWriter(pendulum_animation.mp4, MPEG-4); open(writerObj); for k 1:10:length(t) frame getframe(gcf); writeVideo(writerObj, frame); end close(writerObj);5. 常见问题排查调试过程中可能遇到的典型问题及解决方案现象可能原因解决方法仿真发散初始角度过大限制初始角度0.3rad小车跑出视野位移未限制在LQR中增加x权重动画卡顿步长过大减小Simulink Max Step Size观测器偏差大噪声参数不匹配调整Vd和Vn矩阵实际项目中发现当摆杆长度超过0.5m时需要重新调整控制器参数。一个实用的调试技巧是先用PID稳定角度再切换为LQR控制。