ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

二阶倒立摆建模与LQR控制:Simulink仿真到参数调优全流程

二阶倒立摆建模与LQR控制:Simulink仿真到参数调优全流程 简介本资源是一套面向自动化、控制工程专业本科生及研究生的二阶倒立摆控制系统仿真教学实践包聚焦非线性系统建模与多种先进控制策略的对比验证。资源共6个文件含3个Simulink模型.mdl、2个MATLAB脚本.m和1个模糊推理系统文件.fis总大小仅19KB轻量易用适用于课堂演示、课程设计与算法原理验证。已有3382人学习下载反映出其在控制系统理论教学中的广泛认可度。用户可直接运行不同.mdl模型直观对比PID控制、滑模控制与自适应控制在摆角稳定、抗扰性及动态响应等方面的性能差异配套.m脚本封装核心算法逻辑.fis文件支持模糊规则调参便于深入理解控制器设计细节与参数整定思路是掌握现代控制方法落地仿真实践的优质入门材料。 第一次搭二阶倒立摆仿真时我最深的感受是这个系统比一阶倒立摆难伺候太多。一阶模型你调一个PID就能稳住二阶模型上来就是六个状态、两个相互耦合的摆臂控制器稍微给错一点方向仿真曲线立刻飞到天上去。但也正是这种“难伺候”让它成了控制理论里最经典的一块试金石——自平衡小车、双足机器人、火箭垂直着陆本质上都在和这类不稳定、欠驱动、强耦合的系统打交道。这篇文章我打算用一套完整可复现的思路把二阶倒立摆的建模、Simulink仿真、LQR控制器设计和调参过程串起来。适合正在做课程设计、毕业设计或者刚接触状态空间控制、想拿一个“够分量”的例子练手的同学。我会把每个步骤背后的原因讲清楚也会把那些初次做容易踩的坑直接摊开来说。1. 为什么二阶倒立摆是控制设计中绕不开的“试金石”先说一个容易被忽略的事实二阶倒立摆不是一个“一阶倒立摆的简单叠加”。很多人觉得反正都是倒立摆多加一节摆杆能有多难实际上一加就是质的改变。一阶倒立摆的状态通常只有四个小车位移、小车速度、摆角、摆角速度。控制器只要保证一个不稳定极点稳定就行很多经典方法都能对付。二阶倒立摆多了一个摆杆状态变成六个系统里多了一个从动环节两个摆杆之间还有耦合。这意味着你不能再靠直觉去调PID参数了必须回到状态空间的角度认真分析系统的能控性、能观性再设计状态反馈。从物理上讲二阶倒立摆的“不稳定”也更严重。最下面那根摆杆不仅要支撑自己的重力还要承受上面那根摆杆带来的力矩。如果你只盯着下摆想办法上摆稍微偏一点整个系统就会像叠积木一样倒掉。这就带来了一个很现实的需求你需要一个多变量控制器同时关注多个状态的偏差而不是像单回路PID那样盯一个输出。再往实际工程靠一靠。自平衡车、机械臂的平衡控制、双足机器人的步态稳定、甚至一些精密平台的隔振控制都有二阶倒立摆的影子。它的核心难点并不在于“倒立”而在于“欠驱动”和“不稳定”。你只有一个输入却要控制三个自由度本质上是在做一场资源分配。LQR这类现代控制方法之所以在这里成为首选正是因为它的代价函数可以明确告诉控制器你更在乎哪个状态愿意付出多少控制能量。所以如果你刚学完状态空间想找一个既能验证理论又不过度复杂的例子二阶倒立摆特别合适。它不会简单到索然无味也不会复杂到让你一天之内失去信心。更关键的是做完这个仿真之后你后续理解滑模控制、鲁棒控制、模型预测控制都会有更扎实的直觉。2. 建模从拉格朗日方程开始推导思路与必要的参数约定搞仿真之前必须先把模型搞清楚不然控制器设计就是空中楼阁。二阶倒立摆的标准结构是一个小车在水平导轨上移动小车上方依次铰接两根摆杆两根摆杆都只能在竖直平面内摆动。为了把问题简化成工程中最常用的形式我用集中质量假设摆杆质量集中在末端质点摆杆长度分别是 (l_1)、(l_2)末端质量分别是 (m_1)、(m_2)小车质量为 (M)。广义坐标选三个小车位移 (x)、下摆角 (\theta_1)、上摆角 (\theta_2)。角度都以竖直向上为0顺时针为正。这个约定非常重要后面线性化和LQR的符号都依赖它一定要固定下来再往下走。建模我用拉格朗日方程。系统的动能来自三部分小车平移动能、下摆质点动能、上摆质点动能。经过展开整理代入拉格朗日方程最后一定可以写成标准的机器人动力学形式[ M(q)\ddot{q}C(q,\dot{q})\dot{q}G(q)\tau ]其中 (q[x,\theta_1,\theta_2]^T)(\tau[F,0,0]^T)(F) 是小车上的水平控制力。如果你只做线性控制器设计不用急着展开完整的非线性项。我们关注的是直立平衡点附近的行为也就是 (\theta_1)、(\theta_2) 都在零附近的小偏差场景。把质量矩阵在直立点取值忽略二阶以上的项系统会变成一组线性微分方程。这里我直接给出一个便于验证的标准参数组后面所有仿真都用它(M1\text{kg})(m_11\text{kg})(m_21\text{kg})(l_11\text{m})(l_21\text{m})(g9.81\text{m/s}^2)在这组参数下直立平衡点处的质量矩阵是[ M_0\begin{bmatrix} 321\ 221\ 111 \end{bmatrix} ]重力项线性化后为[ K\begin{bmatrix} 000\ 0-19.620\ 00-9.81 \end{bmatrix} ]最终反解出 (\ddot{q}M_0^{-1}(\tau-Kq))得到状态空间方程。取状态向量 (x_s[x,\dot{x},\theta_1,\dot{\theta}_1,\theta_2,\dot{\theta}_2]^T)控制输入为 (F)则[ A\begin{bmatrix} 010000\ 0019.62000\ 000100\ 0039.240-9.810\ 000001\ 00-19.62019.620 \end{bmatrix} ][ B\begin{bmatrix} 0\1\0\-1\0\0 \end{bmatrix} ]这份A、B矩阵就是我后面搭建Simulink模型的基础。眼尖的同学会发现系统里没有 (x) 和 (\dot{x}) 直接对 (\theta) 的耦合项水平位移只通过加速度作用到摆杆上这正好体现了欠驱动系统的典型特征你没法直接控制摆角只能通过加减速“骗”摆杆维持在直立状态。如果你用的是自己的物理装置不要直接抄这组A、B矩阵一定要把实际参数代入 (M_0) 和 (K)重新算一遍状态空间。后面第4节里我会给出通用的计算流程你只需要把质量和长度换掉即可。3. Simulink建模线性模型落地与两种搭建方式有了状态空间矩阵Simulink建模其实就变得非常清爽。最直接的方式是用库里的State-Space模块把上面A、B、C、D填进去一个带初始扰动的系统就出来了。在MATLAB脚本里先写好参数和矩阵M 1; m1 1; m2 1; l1 1; l2 1; g 9.81; A [0 1 0 0 0 0; 0 0 19.62 0 0 0; 0 0 0 1 0 0; 0 0 39.24 0 -9.81 0; 0 0 0 0 0 1; 0 0 -19.62 0 19.62 0]; B [0;1;0;-1;0;0]; C eye(6); D zeros(6,1);然后拖动State-Space块到模型里A填成 6×6 矩阵B填成 6×1 列向量C填成单位阵这样方便把六个状态全部输出出来观察D填成 6×1 零矩阵。初始条件设置很关键。我在第一次做的时候没给任何初始偏差结果仿真曲线平平无奇控制器看起来“稳如老狗”实际上什么都没干。要验证控制器的能力必须在State-Space模块的初始条件里给出让系统失衡的扰动。比如x0 [0; 0; 0.2; 0; -0.3; 0];这表示下摆初始偏了0.2弧度上摆反向偏了0.3弧度。这是一个足以暴露问题的初始扰动。除了State-Space模块还有两种更贴近“真实系统”的搭建方式也值得一说。第一种是用积分器搭微分方程。当你有完整的六维微分方程 (\dot{x}_s f(x_s,u)) 时可以用6个积分器串联。把每个状态的一阶导输入积分器积分器输出就是状态本身。这种方式的好处是后续如果要替换成非线性模型只需要改积分器输入端的信号计算不需要重新搭建整个模型结构。第二种是直接在MATLAB Function块里写微分方程。对于小角度模型你完全可以把A、B矩阵搬进函数里然后只写一行xdot A*x B*u。这种方式调试起来非常灵活尤其是你需要在仿真过程中动态修改权重矩阵的时候。我个人建议第一版仿真直接用State-Space块把精力集中在控制器设计上。等到控制器跑通了再考虑把线性模型换成非线性模型或者引入Simscape Multibody做多体动力学验证。一步步来别一上来就挑战最复杂的方案。3.1 为什么推荐从线性模型开始而不是直接上非线性我知道有人会质疑真实系统明明是非线性的你用一个线性近似模型做控制器是不是偷懒原因很简单线性模型是控制设计的“第一性原理工具”。LQR、极点配置、状态反馈这些东西全部建立在线性系统理论之上。你先在直立平衡点附近做线性化设计出一个能稳定平衡点的控制器再去复杂模型里验证这本身就是标准工程流程。直接把非线性模型丢给控制器设计反而会因为系统太复杂而难以看清核心矛盾。只要你的初始扰动控制在 ±0.3 弧度以内即大约 ±17°小角度线性化的误差是完全可以接受的。实际物理装置上的倒立摆通常也是在很小的角度范围内做平衡控制很少出现大幅度摆动。真要做大幅度摆起控制的那是另一个话题需要用到能量控制和分段控制策略复杂度完全不同。4. LQR控制器设计与极点配置的选择逻辑线性模型搭好后下一步就是设计控制器。我在这里选LQR原因很明确二阶倒立摆有多个状态你不可能只用一两个PID环路覆盖所有状态。LQR通过代价函数把“状态偏差”和“控制能量”同时放进优化目标一次性得到全部状态反馈增益思路非常匹配多变量不稳定系统。LQR的目标函数是[ J\int_0^\infty \left(x_s^TQx_su^TRu\right)dt ]其中 (Q) 是对角权重矩阵(R) 是控制输入的权重。(Q) 的物理含义是你有多在乎某个状态不偏离零点。某个状态对应权重越大控制器就越拼命把它拉回去。(R) 越大控制器就越不愿意动用大力气控制。我的第一版权重设置经验是Q diag([10, 1, 100, 10, 100, 10]); R 0.1; K lqr(A, B, Q, R);为什么这样设我解释一下(Q(1,1)10)小车位移不能完全不管但不用太苛刻。仿真区域有限推车漂太远当然不行。(Q(3,3)100)、(Q(5,5)100)两个摆角是最核心的稳定目标权重必须最重。速度项给1或10主要是增加阻尼感让控制器在拉回角度时不会震荡。(R0.1)意味着控制器可以放心使用较大的控制力适合仿真阶段验证能力。如果后面要接真实电机需要根据执行机构饱和范围把 (R) 调大。设计完增益后必须做一件事验证闭环系统稳定性。eig(A - B*K)你会看到所有特征值的实部都是负数系统已经稳定。还可以画个零极点图figure; pzmap(ss(A-B*K, B, eye(6), 0));这一步很重要它能直观告诉你闭环极点落在哪里阻尼和响应速度大概是什么水平。在Simulink里接入LQR控制器的办法很简单因为 (u-Kx_s)只需要把State-Space模块输出的六维状态接到一个矩阵增益块增益填 (-K)然后反馈给输入。如果你用的是Gain模块注意把增益设置为矩阵乘法模式因为 (K) 是 1×6 的行向量。还要提醒一点(K) 是从MATLAB工作区里读的变量。如果Simulink模型运行时找不到这个变量模型会直接报错。最简单的做法是在模型参数里把矩阵增益块的值直接写-K并确保工作区里已经有这个变量。4.1 极点配置和LQR到底选哪个很多课程里也会碰到极点配置的设计方法。极点配置的逻辑很直白你指定闭环极点然后反推增益。二阶倒立摆系统是能控的所以任意指定极点都能配出对应的增益。但这里有一个工程上的大坑极点配置需要你“凭直觉”选极点位置而极点的位置又和系统响应速度、控制能量、执行机构饱和深度绑定。选快了控制量爆表选慢了系统软绵绵在小扰动下都像喝醉了。LQR的高明之处在于它把极点选择的隐性问题转化为权重选择的显性问题。(Q) 和 (R) 的物理含义更直观而且能够通过调整权重让控制量的峰值受控。所以我的建议非常明确如果是做课程设计LQR远比手动极点配置好使如果你追求的是对控制系统原理的深入理解可以两个都试试对比一下不同设计方法得到的增益和响应差异。4.2 通用参数下LQR计算的完整流程如果你的物理参数不是上面那组标准参数这里给出通用的计算流程% 输入你的参数 M 1.5; m1 0.8; m2 0.6; l1 0.6; l2 0.5; g 9.81; % 质量矩阵 M0 [Mm1m2, (m1m2)*l1, m2*l2; (m1m2)*l1, (m1m2)*l1^2, m2*l1*l2; m2*l2, m2*l1*l2, m2*l2^2]; % 重力线性化项 Kmat zeros(3,3); Kmat(2,2) -(m1m2)*g*l1; Kmat(3,3) -m2*g*l2; % B矩阵输入F作用在第一个广义坐标x上 Bvec [0; 1; 0]; % 由 M0*qdd Kmat*q [F;0;0] 推出状态空间 Minv inv(M0); A22 Minv * (-Kmat); A22(1,1) 0; % x不出现 A [0 1 0 0 0 0; 0 0 0 0 0 0; 0 0 0 1 0 0; 0 0 0 0 0 0; 0 0 0 0 0 1; 0 0 0 0 0 0;]; A(2,1:6) [0, 0, A22(1,1), 0, A22(1,3), 0]; A(4,1:6) [0, 0, A22(2,1), 0, A22(2,3), 0]; A(6,1:6) [0, 0, A22(3,1), 0, A22(3,3), 0]; B [0; Minv(1,1); 0; Minv(2,1); 0; Minv(3,1)]; Q diag([10, 1, 100, 10, 100, 10]); R 0.1; K lqr(A, B, Q, R);这段流程比直接给矩阵更有普适性也方便你验证不同参数下的系统行为。注意A矩阵第二、四、六行的构造我把 (A_{22}-M_0^{-1}K) 的位移列去掉因为角度到位移的耦合是通过加速度实现的位移本身不直接进入角度动态。5. 仿真结果怎么看参数调试、抗扰测试、常见坑与解决办法我刚搭好仿真第一次跑通的时候以为重点是“系统没发散就行”后来发现这个想法太天真。仿真曲线不仅要收敛还要收敛得漂亮。你至少要关注三个核心指标调节时间、超调量、控制输入的峰值。调节时间看的是角度曲线多久回到零附近超调量看第一波往回拉扯时角度会不会冲过头控制输入峰值看的是控制器有没有在某一瞬间要求一个夸张的力。如果控制力峰值几百牛而物理系统只能提供几十牛那仿真再漂亮也没有工程意义。所以我的建议是跑完仿真后把控制力信号也拉出来看。具体做法是在反馈环路上加一个scope从State-Space模块的输入端引出去。你会看到权重 (R) 越小控制力越大角度收敛越快(R) 越大控制力被压下来但角度恢复变慢还可能出现明显的欠阻尼振荡。5.1 抗扰测试怎么做真实系统永远有干扰仿真里不能只知道“初始扰动能稳住”。我的习惯是在仿真中间给信号通道加一个短时脉冲模拟一阵风或者一次意外的推力。在Simulink里可以这样搭在控制力信号通道上用Sum块叠加一路Pulse Generator脉冲时间设置在1秒左右持续0.1秒幅值可以给5牛。如果LQR设计得足够稳角度曲线应该在短暂偏差后再次回到零点。这个测试通过说明控制器不只对初始条件有效对持续性扰动也有抑制能力。5.2 我踩过的几个坑按排查链路一步步说第一个坑是仿真一开始就跑飞。现象是模型运行不到0.1秒角度直接飙到几十弧度曲线清一色溢出。我当时第一个反应是“参数错了”但其实原因是状态空间矩阵填错了。排查链路是这样走的先检查开环系统eig(A)。如果开环存在正实部特征值正常如果全在左半平面反而说明模型有问题。检查A矩阵的维度size(A)必须是 6×6B 必须是 6×1。很多报错都源自矩阵少了一行。检查初始扰动方向。反向的位移加上错误的控制符号会让控制器“好心办坏事”越拉越歪。检查LQR增益符号。LQR返回的K已经是对应 (u-Kx) 的形式如果此时再在Simulink里加一个负号取反系统必然发散。第二个坑更隐蔽角度曲线看起来稳住了小车却一直往一个方向跑。原因是Q矩阵里位移权重太小控制器把全部精力都放在稳定摆角上完全不管推车在哪。LQR本质上是个调节器不是跟踪器你不给位移惩罚它就认为 (x10) 和 (x0) 一样好。解决办法是把 (Q(1,1)) 加到50甚至100或者在反馈中引入 (x-\text{ref})变成跟踪问题。第三个坑是仿真结果对步长极其敏感。同一个模型默认步长跑出来是振荡发散把步长上限改成0.001就稳住了。这不一定说明模型没问题而是在提醒你系统本身有较大的刚性特征数值积分步长必须足够小。推荐在求解器设置里把Max step size设为 (0.005) 或者更小同时尽量选ode15s这类刚性求解器而不是默认的ode45。第四个坑也是最多人忽略的角度除以180再乘π的单位混乱。你会在模型里顺手填一个 (0.2\text{deg}) 的初始条件结果系统几乎感觉不到扰动以为控制器很牛。实际上要在Simulink里用弧度作为统一单位。如果外部给你的角度是度数先转换再进模型否则后面所有增益设计都会被误导。最后分享一个我自己的检查方法仿真结束后在MATLAB工作区把六个状态全部拉出来比较一下收敛顺序。通常情况下角度会先回来速度次之位移最后回归。如果发现某个状态迟迟不收敛不要急着改Q先去检查LQR的可控性rank(ctrb(A,B))如果小于6说明系统模型有问题或者状态变量选取出现问题这时候调参数是没用的。这些坑并不复杂但在仿真过程中一环扣一环很容易让人焦头烂额。我现在做二阶倒立摆仿真已经习惯了“先验证开环特征值、再验证可控性、再跑闭环”这三步安检。每一步都确认没问题之后再往下走基本不会出现那种让人摸不着头脑的随机发散。本文还有配套的精品资源点击获取
返回列表