资讯详情

LQR一阶倒立摆完整实战:建模、仿真调参与实物部署闭环

📅 2026/10/15 11:53:43 | 华诺云谱 👁 阅读
LQR一阶倒立摆完整实战:建模、仿真调参与实物部署闭环
简介这是一份面向控制理论与自动化初学者的LQR一阶倒立摆MATLAB源码包聚焦倒立摆系统建模、非线性线性化与LQR最优控制器设计问题。压缩包共5个文件以4个.m脚本和1个.asv辅助脚本为主整体仅3KB其中演示脚本提供完整可运行设计流程平台与摆杆模型脚本分别刻画系统动力学另有算法实现与数据辅助文件支撑二次开发。已有1724人学习使用。读者可通过演示示例逐步掌握状态空间模型构建、Riccati方程求解和控制器增益计算直观理解LQR算法对不稳定平衡点的镇定作用通过修改质量、杆长等模型参数还能进一步观察控制输入与系统状态响应的动态变化为后续鲁棒控制、约束优化等扩展研究打下基础。1. 从 LQR 到一阶倒立摆控制律设计、仿真与实物部署的完整闭环倒立摆是控制理论里最经典的验证平台而 LQR线性二次型调节器又是把倒立摆稳住的最短路径之一。这份「LQR 一阶倒立摆」资料核心价值不在于给你一段能跑的代码而在于它把建模、状态反馈、权重调参、Simulink 仿真到实物部署的完整链路串了起来。如果你正在做课程设计、毕业设计或者刚接触状态空间控制想找个能落地的练手项目这套东西能帮你少走大量弯路。我拆过几套类似的资源坦白说很多资料只给一个 .m 脚本和一张仿真截图参数怎么来的、换了硬件还能不能稳、抗扰能力如何全是黑匣子。这套资源至少把关键推导步骤和调参路径留出来了下面我按自己的拆解顺序给你过一遍。2. 一阶倒立摆的建模与 LQR 原理先把状态方程写对后面才不会翻车2.1 从牛顿力学到状态空间方程为什么一阶模型也要认真推导倒立摆的物理模型看起来简单——一根摆杆装在电机驱动的滑块上目标是让摆杆保持竖直。但真正动手建模时第一个坑就是坐标系和符号约定。常见的一阶倒立摆也叫一级直线倒立摆包含小车质量 M、摆杆质量 m、摆杆长度 l、转动惯量 J、摩擦系数 b以及小车驱动力 F。我一般习惯按以下步骤推导先单独分析小车水平方向受力再分析摆杆绕质心的转动联立后做小角度近似sinθ≈θcosθ≈1然后消除中间变量得到四个状态小车位移 x、小车速度 dx、摆杆角度 θ、摆杆角速度 dθ的状态方程。推导结果的标准形式是dx/dt Ax Bu y Cx Du其中状态向量 x [x; dx; θ; dθ]。资料里给出的 A 矩阵和 B 矩阵是经过小角度线性化后的结果我把它整理成代码里可以直接用的形式。2.2 LQR 核心公式与权重矩阵 Q、R 的物理意义LQR 的目标是设计一个状态反馈增益 K使得控制量 u -Kx 能够最小化如下代价函数J ∫(xQx uRu) dt这里的 Q 矩阵是半正定状态权重矩阵R 是正定控制权重矩阵。Q 的对角元素分别对应四个状态的重要性Q11 对应小车位置、Q22 对应小车速度、Q33 对应摆杆角度、Q44 对应摆杆角速度。R 对应电机驱动力控制量的惩罚。实际调参经验是如果摆杆稳不住优先加大 Q33角度权重如果小车位移漂移太远加大 Q11如果控制量饱和或电机抖动厉害则加大 R。资料提供的初始权重一般是 Q diag([100, 10, 100, 10])、R 0.1 这种量级但换一套硬件后必须重新调。了解原理后直接去调参容易没有方向感建议先跑通下面这段 MATLAB 脚本把 K 算出来看看量级。% 倒立摆状态空间模型参数SI单位 M 0.5; % 小车质量 kg m 0.2; % 摆杆质量 kg b 0.1; % 小车摩擦系数 N/(m/s) l 0.3; % 摆杆质心到转轴距离 m注意是半长 I 0.006; % 摆杆转动惯量 kg*m^2 g 9.8; % 重力加速度 % 线性化后的状态空间矩阵 % 状态: x1小车位移, x2小车速度, x3摆杆角度, x4摆杆角速度 p I*(Mm)M*m*l^2; A [0 1 0 0; 0 -(Im*l^2)*b/p (m^2*g*l^2)/p 0; 0 0 0 1; 0 -(m*l*b)/p m*g*l*(Mm)/p 0]; B [0; (Im*l^2)/p; 0; m*l/p]; C [1 0 0 0; 0 0 1 0]; D [0; 0]; % 检查可控性 co ctrb(A,B); if rank(co) size(A,1) error(系统不可控检查建模参数); end % LQR 权重矩阵 Q diag([100, 10, 100, 10]); R 0.1; % 求解状态反馈增益 K lqr(A,B,Q,R); disp(LQR 增益 K ); disp(K);这段代码的意图是先在 MATLAB 里把模型参数固化成变量然后通过lqr函数直接求得状态反馈矩阵 K。ctrb可控性检查是非常容易被忽略的一步——很多资料直接跳过但如果你改了模型参数后发现lqr报错或仿真发散多半是系统在某个参数组合下不可控。参数层面的注意点摆杆长度 l 这里用的是质心到转轴的距离也就是摆杆总长的一半左右。如果你用的摆杆是均匀杆转动惯量 I 可以按 1/3 * m * L^2 估算L 是摆杆总长。很多新手在这里用总长去代导致模型参数和实物不一致仿真能稳住、实物一上电就摔杆。2.3 从 K 矩阵看 LQR 的控制律本质求得 K 之后控制量 u -Kx 的物理意义就很直观了。假设 K [k1, k2, k3, k4]那么实际输出到电机的电压或力矩为u -k1*x - k2*dx - k3*θ - k4*dθ每一项都有明确的物理角色-k1x 是位置反馈把小车拉回原点-k2dx 是速度阻尼防止小车来回振荡-k3θ 是角度反馈这是稳定摆杆的核心项当摆杆向右倾斜时输出反向力矩-k4dθ 是角速度阻尼抑制摆杆的快速摆动。一个非常实用的观察方法是看 K 里各项的数量级。如果你发现 k3 比其他项小了 1 到 2 个数量级说明摆杆角度的权重设置过小抗扰动能力会很差。反之如果 k4 过大控制量会频繁饱和电机容易过热。资料里给出的 Simulink 仿真模型通常把 K 封装成 Gain 模块四个状态通过 Mux 汇总后乘以 K。这里我要强调一个常见错误Simulink 里的状态顺序必须和 A 矩阵定义的状态顺序保持一致否则 K 矩阵应用到错误的状态上仿真结果看起来像随机噪声。3. 仿真环境搭建与 LQR 参数整定在 Simulink 里把系统跑稳3.1 从零搭建 LQR 控制仿真框图每个模块的作用和连接方式拿到状态方程和 K 矩阵后下一步就是把控制回路在 Simulink 里搭出来。常见做法是使用状态空间模块State-Space作为被控对象前面接一个 Gain 模块实现反馈再加上一个 Reference 输入用于给定目标位置。一个最基本的 LQR 闭环框图包含以下模块State-Space 模块输入为 u控制量输出为状态向量 x。A、B、C、D 直接填入 2.2 节代码算出的矩阵。Gain 模块反馈增益增益值设为 K输入为状态 x输出为 -Kx。Sum 模块将参考输入 r 与反馈量合并。注意这里不是直接把 r 和 -Kx 相加而是根据控制目标决定是否引入前馈。Scope 模块观察四个状态随时间的变化曲线。我用文字描述一下典型连接关系参考信号 r比如方波幅值 0.2m 的位移指令通过一个 K_r 模块参考前馈增益进入 Sum然后和 -Kx 汇合后作为 State-Space 的输入 u。State-Space 的输出端接一个 Demux 拆出四个状态一路送到 Scope另一路反馈回 Gain。如果你对前馈增益 K_r 怎么算没把握有个偷懒但有效的做法直接把参考信号加在 x小车位移上然后用 K 矩阵里的第一个元素做比例补偿。更严谨的推导是用零状态误差条件去解 K_r但仿真阶段不需要做到这一步只要保证系统能跟踪阶跃即可。3.2 参数整定的三种路径手动试错、自动寻优、经验公式LQR 参数整定是倒立摆项目里最耗时间、也最容易让人血压飙升的环节。我给三条路径按效率从低到高排列。第一种是纯手动试错先固定 R 不动依次增大 Q33角度权重直到摆杆能稳定然后再调 Q11 控制位移回中。每次改变权重后重新运行lqr函数求解 K观察 Scope 波形。这个方法优点是直观、帮助理解权重作用缺点是效率低尤其是在参数交互影响明显时容易陷入局部调参怪圈。第二种是脚本化批量仿真用一个 MATLAB 脚本把 Q 的候选值写成数组循环求解 K 并运行 Simulink最后自动提取超调量和调节时间用表格或曲线对比。这段脚本虽然简单但能大大减少手工重复劳动。% 批量扫描 Q33 权重对系统响应的影响 Q33_list [10, 50, 100, 200, 500]; results zeros(length(Q33_list), 3); for i 1:length(Q33_list) Q diag([100, 10, Q33_list(i), 10]); K lqr(A,B,Q,R); % 更新 Simulink 模型中的增益参数假设模型名为 pendulum_lqr set_param(pendulum_lqr/Feedback Gain, Gain, mat2str(K)); % 运行仿真并获取输出假设输出到工作区变量 simout simOut sim(pendulum_lqr); y simOut.yout{1}.Values.Data; t simOut.yout{1}.Values.Time; % 提取小车位移的峰值时间和稳态误差 % 这里用简单指标角度最大偏差和调节时间 angle y(:,2); % 假设输出中第一列是位移第二列是角度 max_angle_dev max(abs(angle)); % 找到调节时间角度进入 ±5% 区间后不再超出 idx_settle find(abs(angle) 0.05*abs(angle(1)), 1, first); if isempty(idx_settle) settle_time inf; else settle_time t(idx_settle); end results(i,:) [Q33_list(i), max_angle_dev, settle_time]; end % 打印对比表 disp(Q33 最大角度偏差 调节时间); disp(results);这段脚本的核心思路是通过set_param动态修改 Simulink 中的 Gain 参数然后批量运行得到性能指标。我通常会额外记录控制量 u 的最大值因为电机饱和往往是实物部署翻车的主要原因。如果simOut.yout结构和你模型里的输出配置不一致需要先检查 To Workspace 模块的变量名和采样时间。第三种是使用 MATLAB 的 Response Optimizer 或 Control System Tuner 工具自动调整 Q 和 R 来满足超调量、稳定时间等设计约束。这个方法适合熟手因为工具给出的中间解往往物理意义不清晰你很难解释为什么某个权重是最优的答辩时容易被老师问住。我建议新手至少完整手动调一次再考虑自动寻优。3.3 仿真结果判读稳定、临界振荡、发散三种形态的信号特征仿真跑完之后最关键的是能读懂 Scope 波形。我把常见的几种波形形态和对应的调参建议列出来方便你对照波形形态典型特征调参方向稳定收敛摆角从初始偏移比如 5 度平滑衰减到 0无振荡当前参数可用可继续优化性能临界振荡摆角持续等幅振荡不衰减也不发散加大 Q33 或 Q44或减小 R发散摆角单调增大或振荡幅度快速增大检查系统可控性、K 符号、状态顺序响应迟缓摆角恢复很慢像没吃饭一样减小 R 或增大 Q33提高控制力度一个容易被忽视的指标是控制量的饱和程度。如果 u 的波形经常撞到 ±10V或电机额定力矩说明 LQR 求出的理想控制量在物理上根本不可达。这时无论你怎么调 Q 和 R实物都会在剧烈抖动后倒下因为执行器的输出饱和了。我看到过很多人在这一步卡住反复调 Q 但始终改不了波形发散的问题。后来发现是状态空间模块里的 C 矩阵设置不对输出的是 [x, dx] 而不是 [x, θ]。这种低级错误通过检查模块内部的矩阵和观察波形形状就能快速定位——如果波形发散得毫无规律优先怀疑矩阵填错而不是权重不合适。4. 避坑指南LQR 倒立摆从仿真到实物最常见的四个翻车点4.1 现象仿真波形完美实物上电后摆杆直接倒下原因仿真中的模型参数与实物严重不符尤其是摩擦系数 b 和转动惯量 I。仿真里 b0.1 用得很顺手但实物导轨的摩擦力可能明显更大导致实际阻尼和模型不一致。解决拿到实物后先做开环测试给电机一个已知的阶跃电压记录小车的加速度曲线反推实际摩擦系数和等效质量。不要直接沿用课件或资料给的模型参数至少用 10 分钟把实物参数标定一遍。4.2 现象调参时 Q 和 R 反复修改系统始终有低频抖动原因LQR 本身是连续时间控制器但实物控制是离散采样同时编码器反馈存在量化噪声。如果采样频率过低比如 100Hz或编码器分辨率不够控制信号会带上明显的噪声成分。解决检查控制周期是否足够快一般建议至少 500Hz 以上。编码器分辨率至少 1024 线以上角度测量推荐用增量式编码器配合正交解码。若抖动明显可在反馈通道上加一阶低通滤波但要注意延迟对稳定性的影响。4.3 现象小车位移发散但摆杆角度稳定原因这是一个非常经典的权重设置误区。Q 矩阵里小车位置权重 Q11 过小LQR 认为让小车漂移比花力气把车推回原点更“划算”。从代价函数的角度看控制量对位移几乎没有惩罚系统放松了对位置约束。解决增大 Q11让位置权重比角度权重高一个数量级。也可以把状态空间模型里的角度单位从弧度改为度但我不推荐这种方式因为它只改变数值尺度不改变物理约束的实质。4.4 现象Simulink 仿真速度极慢或者仿真结果不稳定原因模型中使用了连续状态空间模块但仿真步长设置过大导致数值积分不收敛尤其在小角度近似失效的瞬间模型会出现应急性发散。另外如果你在模型中添加了非线性摩擦或限幅模块步长过大会引入数值刚性。解决将求解器设置为ode45并限制最大步长为 1e-3 秒或者使用固定的ode4步长 1ms。检查模型中是否有代数环——当反馈信号直接没有经过延迟或状态模块就回到输入端时Simulink 会报代数环警告实际仿真结果也不可靠。这里我想单独提一句很多人遇到实物倒立摆稳住后左右缓慢漂移第一反应是继续调 Q但其实问题已经不在 LQR 参数上而是位置环没有积分作用。LQR 是比例状态反馈对恒值扰动比如导轨轻微倾斜、电机死区存在稳态误差需要引入积分型 LQR 或外环 PID 来消除。这个坑在资料里容易被忽略因为纯仿真里不存在摩擦死区和导轨倾角的影响。5. 进阶验证与部署技巧从仿真到实物的最后一步5.1 通过扰动测试验证 LQR 的鲁棒性边界在仿真环境里最有效的验证方法是加入脉冲扰动。比如在摆杆处于平衡点时给角度状态一个突变的初值模拟手推一下或者在小车上施加一个短时外力模拟绳子拉拽。通过观察系统能否恢复到平衡位置就能判断 LQR 的稳定裕量。具体的操作是在气隙时刻用 MATLAB 直接修改状态空间模块的内部状态或者加一个 Pulse Generator 信号叠加到控制输入端。我强烈建议你做一组不同扰动幅值的测试记录系统从扰动到恢复的时间。如果你的摆杆在 10 度扰动下能 2 秒内回稳但在 15 度扰动下发散说明工作范围在 10 度附近这在实际项目中是很有价值的信息。5.2 前馈补偿与积分型 LQR 的实际结合对于位置环稳态误差问题我通常会在 LQR 反馈基础上再加一个外环积分器将角度保持和位置跟踪分离。常见结构是内环用 LQR 稳定摆杆外环用 PI 控制小车位置。这样调试起来思路更清晰——先保证内环在任意小车位置都能稳定摆杆再调外环让小车回中。在代码层面状态向量的维度需要从 4 维扩展到 5 维加入积分状态 x_i ∫(x - x_ref) dt。对应的扩展状态矩阵和 LQR 求解方式在控理论文里都有标准推导核心是把积分状态也纳入 Q 矩阵中赋权重。5.3 实物控制器参数核对清单实物部署前如果条件允许先用 MATLAB/Simulink Desktop Real-Time 或 xPC Target 这一类的中间层跑一下验证。我自己的习惯是整理一份参数核对表确认每一项都与仿真设置一致再上电。核对表包括这几个关键项控制周期与仿真的固定步长是否一致实物控制器一般用 1ms 或 2ms。状态量顺序编码器读出的角度微分是否对应状态方程的第三、第四个状态。输出限幅控制量是否经过限幅限幅方向和仿真中的 Saturation 模块是否一致。反馈极性基座标定的角速度方向与状态方程定义是否一致很多人栽在这里表现是角度能稳住但连续振荡。在拉线调试之前最好先用虚拟偏置测试控制方向逻辑手动把摆杆推到一侧观察控制量输出是否朝相反方向作用。这一步看似简单却能避免上电后因为正负号错误导致摆杆加速倒下的尴尬。从那以后我每次搭倒立摆项目都强制要求自己先写完状态方程和参数标定表再进入仿真和调参环节最后拉实物时按核对表逐项确认。这套流程虽然看起来慢但实际能帮你省下大量摔杆重试的时间。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑