资讯动态

用Simscape物理建模搭建二阶倒立摆及LQR控制

发布时间:2026/10/2 19:12:04 来源:尧图企业网站定制
刚入坑 Simulink 的朋友十有八九都绕不过倒立摆这道坎——但一上来就直接从 Simulink 基础库开始搭二阶倒立摆确实容易劝退。今天分享一种更省心的玩法用 Simscape 物理建模工具基本不用手推复杂微分方程就能把二阶倒立摆的机械本体“搭积木”一样搭出来再配合简单控制器实现稳定控制。这篇内容会覆盖从模型架构、工具箱选择、刚体搭建、参数配置到控制闭环与常见报错排查的完整过程适合刚接触 Simulink/Simscape、又想做二阶倒立摆仿真的小白直接参考复现文末附整套可用的参数配置。1. 为什么选 Simscape 搭倒立摆先搞懂它和普通 Simulink 的区别1.1 物理建模 vs 信号建模选对工具少走一半弯路很多新手第一次接触 Simulink 时接触的都是信号流建模也就是把微分方程拆成一堆积分、增益、求和模块用信号线连起来。比如二阶倒立摆的状态方程里有 sin 和 cos 项就把角度信号接入 Trigonometric Function 模块再乘个系数一路连下去。这套方式的好处是直观但坏处也明显一旦系统结构变化比如从单摆改成双摆或者从直线导轨改成旋转底座整个信号流图基本要推翻重来。Simscape 则完全不同。它走的是物理网络建模路线模块之间的连线不代表信号而代表能量流动。你用 Simscape Multibody 里的 Solid 模块定义摆杆的几何和质量用 Revolute Joint 定义旋转关节用 Prismatic Joint 定义小车的滑动导轨系统会自动根据物理连接生成对应的运动方程。这就像搭积木一样结构的修改成本远低于信号流建模。我用一个实际体会来说明之前我用纯 Simulink 搭过一个单级倒立摆光是把运动学方程从拉格朗日方程推导到可编程的 Simulink 模块形式就花了大半天。后来改用 Simscape Multibody 搭同样的模型真正动手搭建时间不超过一小时而且模型的可维护性和可读性明显更好。1.2 二阶倒立摆为什么要用 Simscape二阶倒立摆指的是在直线导轨上有一个小车小车上方通过旋转关节连接第一个摆杆第一个摆杆顶端再通过第二个旋转关节连接第二个摆杆。目标是让两级摆杆同时直立不倒。它比单级倒立摆难的地方在于系统自由度从 2 个变为 3 个小车位移、下摆角、上摆角且存在严重的欠驱动特性和非线性耦合。纯 Simulink 信号流建模需要推导两组耦合微分方程推导过程极其容易出错而 Simscape 直接在三维物理空间里定义刚体和关节系统会自动处理约束方程和耦合项。另外Simscape 模型天然带有物理单位角度、质量、长度、转动惯量都可以按真实物理量填写。这意味着你可以把模型参数直接换成任何一套实际装置的参数仿真结果与实验的对应关系非常紧密后续如果要做硬件在环或者实际台架测试Simscape 模型的迁移成本也低很多。2. 模型整体架构与搭建顺序先画好物理拓扑再动手连线2.1 明确系统组成的四个层级在打开 MATLAB 之前先把二阶倒立摆的物理结构在脑子里拆成四个层级。第一层是基座层包括地面坐标系和导轨小车在导轨上做一维直线运动第二层是小车层包括车体质量、驱动轮/丝杠传动的等效推力或位置输入第三层是下摆层通过旋转关节安装在小车上第四层是上摆层通过第二个旋转关节安装在下摆末端。这四个层级对应到 Simscape Multibody 里就是一条从 World Frame 开始的刚体链导轨 → 小车刚体 → 下摆刚体 → 上摆刚体。搞清楚这条链的顺序非常重要因为后续所有坐标系、关节、传感器都会挂在这条链上。搭模型时只要保持这个物理拓扑不变中间某个刚体的具体尺寸、质量怎么改都不会破坏整体结构。2.2 工具箱选择与模型库认知搭建前先确认安装了 Simscape Multibody 工具箱。在命令行输入 ver 查找或者在 MATLAB 的 Home 页面的 Add-Ons 里搜索“Simscape Multibody”安装即可。除了 Simscape Multibody还需要基础 Simscape 工具箱和 Simulink Control Design用于线性化分析和控制器设计。这三件套基本是控制类仿真项目的标准配置。启动 Simulink 后在 Library Browser 左侧找到 Simscape 目录展开后能看到 Multibody、Electrical、Fluids 等子库。我们只用 Multibody 子库中的几个模块World Frame、Mechanism Configuration、Solid、Revolute Joint、Prismatic Joint、Rigid Transform、Bushing Joint、Transform Sensor、Joint Sensor 等。这些模块已经足够搭建完整的二阶倒立摆机械系统。对于第一次接触 Multibody 的新手我建议先花十分钟浏览一下 Multibody 子库的模块分类。Solid 模块负责定义刚体的几何、质量和惯性Joint 模块定义刚体之间的约束关系Rigid Transform 模块负责定义刚体内部的参考坐标系变换World Frame 和 Mechanism Configuration 是每个模型必需的“锚点”和“全局配置”。理解这几类模块的作用搭建过程就不会迷路。3. 用 Simscape Multibody 搭建机械结构纯实操3.1 新建模型并放置全局模块首先在 MATLAB 命令行输入smnew或者手动新建 Simulink 模型然后从 Simscape Multibody Frames 和 Utilities 中拖入两个必备模块World Frame 和 Mechanism Configuration。前者是全局大地坐标系所有机械链的起点后者用来设置重力加速度等全局参数。双击 Mechanism Configuration在 Gravity 向量里填[0 -9.81 0]。这里选择 Y 轴负方向为重力方向是 Multibody 世界坐标系的常见约定机械臂和移动机器人模型里也普遍采用这个方向。接着在 Multibody Bodies 中拖入两个 Solid 模块一个作为小车一个作为下摆杆再复制出第二个 Solid 作为上摆杆。这里我习惯先把三个刚体的名称改成 Car、LowerPendulum、UpperPendulum方便后续查找。改名的操作在模块属性窗口的 General 选项卡里修改 Name 字段即可名称最好用英文且不要带空格否则后续脚本和控制器引用容易出问题。3.2 定义刚体几何、质量与惯性参数双击 Solid 模块进入 Geometry 选项卡。小车用默认的 Box 形状长宽高分别设为 0.3m、0.15m、0.05m这样看起来比较稳定质量密度设为 2000 kg/m³软件会自动计算质量约 4.5kg。为了方便手动指定参数我一般把 Type 从“By density”切换为“By mass”直接填质量这样后续调参更直观。你也可以保持密度方式软件自动计算惯性张量这通常是更物理准确的做法。下摆杆选择 Cylinder 形状半径 0.02m长度 0.5m。这里要注意一个关键点Solid 模块的几何中心默认在自身坐标系的零点。对于圆柱体如果直接摆在小车上方它的几何中心会出现在旋转关节位置导致旋转轴其实穿过圆柱中心。这其实是符合物理直觉的——单摆的旋转轴确实在杆的中心不对倒立摆的旋转轴在杆的底部端点。所以需要做一次坐标系变换让圆柱的一端对准旋转关节。具体做法是在 Solid 模块的 Geometry 选项卡中将 Cylinder 的 Length Direction 设置为 Z 轴并在 Frame 选项卡中新增一个参考坐标系Frame位置设置为[0 0 -0.25]。这意味着 Solid 的质心在自身坐标系原点而参考坐标系位于杆的底端这样后续把这个参考坐标系与 Revolute Joint 连接时旋转轴就落在杆的底端端点。这个操作是整个建模中最容易忽略的细节很多新手搭出来的倒立摆看起来怪怪的模型里杆绕着自己的质心旋转根本不是绕底部转大概率就是漏了这一步。上摆杆参数类似半径为 0.018m长度为 0.4m同样在 Frame 选项卡中设置[0 0 -0.2]的参考坐标系偏移。上下摆的质量都不必太大0.3kg 左右比较合适后续控制器整定的工作量也小一些。3.3 搭建运动链导轨、关节与刚体连接从 Multibody Joints 中拖入一个 Prismatic Joint 作为小车的直线导轨一个 Revolute Joint 作为下摆的旋转关节另一个 Revolute Joint 作为上摆的旋转关节。连接顺序为World Frame → Prismatic Joint → Car Solid → Rigid Transform → Revolute Joint 1 → LowerPendulum Solid → Rigid Transform → Revolute Joint 2 → UpperPendulum Solid。这里的 Rigid Transform 模块是用来调整连接点位置的。先想清楚小车 Solid 的底面中心应该落在导轨上。小车 Solid 的默认坐标系在几何中心也就是高度 0.025m 处连接 Prismatic Joint 时要把旋转/平移轴放到小车底面。可以在 Car Solid 的 Frame 选项卡里设置[0 -0.025 0]的偏移或者加一个 Rigid Transform 模块来对齐。我实际操作时更倾向于改 Solid 的 Frame 偏移模块数量越少模型越清爽。连接好之后双击 Prismatic Joint设置轴的方向为 X 轴。这意味着小车只能沿 X 轴平动。再双击第一个 Revolute Joint设置旋转轴为 Z 轴确保摆杆在 XY 平面内摆动。第二个 Revolute Joint 同样轴设为 Z 轴。这样整个系统就限制在二维平面内符合典型二阶倒立摆的物理模型假设。还有一个默认配置被很多人忽略Revolute Joint 的模式默认是 Automatically computed意思是软件会根据连接的刚体自动决定运动范围。建议把 Mode 改为 State Target并在 Sensor 选项卡中勾选 Position 和 Velocity 的测量。这样后续控制器可以直接读取角度和角速度无需额外加传感器。对倒立摆来说下摆角和上摆角的实时测量是控制系统反馈的基础省掉这个勾选后续会很麻烦。3.4 添加驱动输入与外部接口小车的直线运动需要一个力或速度输入。在 Simscape Multibody 中最常用的做法是用一个 Velocity Source 或 Force Source 驱动 Prismatic Joint。更标准的做法是在 Prismatic Joint 的 Actuation 选项卡中把 Actuation 设置为 Provided by Input然后从 Simscape Foundation Library Mechanical Translational Sources 中拖入一个 Force Source 模块连接到 Prismatic Joint 的物理输入端口。这一步牵涉到一个 Multibody 新手经常困惑的点Simscape Multibody 关节输入是物理端口而控制器输出是普通 Simulink 数值信号二者需要用 Simulink-PS Converter 进行转换。同样地从关节传感器出来的物理信号要进入 Simulink 软件控制器需要用 PS-Simulink Converter 转换。我把这些转换模块统一放在一个子系统里方便管理。在 Prismatic Joint 的属性窗口把 Actuation 选项卡中的 Force 选为 Provided by Input然后在 Simscape Utilities 中拖入 Simulink-PS Converter其物理端连到 Prismatic Joint 的 Force 物理端口信号端连到控制器的输出。Simulink-PS Converter 的参数页里有输入输出单位设置我这里统一设置为 N牛。最后用一个 Inport 模块作为整个模型的控制器输入接口一个 Outport 作为状态输出接口整个机械部分就算搭完了。到此二阶倒立摆的“本体模型”已经闭环。可以先用一个 Constant 模块给小车加一个固定的 0 力设置好所有初值后运行一次看模型能否正常初始化。如果初始化报错多数情况是刚体连接顺序或坐标系变换有问题先排除这些再往下走。4. 参数配置与初始化从物理装置到仿真模型的关键映射4.1 机械参数的完整配置表经常有读者问“倒立摆模型到底要用什么参数”我的建议是先用一组稳妥的初始参数跑通再逐步调节到对应实际装置。下面这组参数是我基于实验室常见的直线一级/二级倒立摆装置适配后的典型值完全适合仿真验证参数名称数值说明小车质量 M0.5 kg含导轨上滑动部分的质量下摆质量 m10.2 kg下摆杆质量上摆质量 m20.15 kg上摆杆质量下摆长度 l10.5 m从旋转轴到下摆质心的距离上摆长度 l20.4 m从旋转轴到上摆质心的距离下摆转动惯量 J10.004 kg·m²绕质心轴的转动惯量上摆转动惯量 J20.002 kg·m²绕质心轴的转动惯量重力加速度 g9.81 m/s²方向指向 -Y导轨摩擦系数 b0.1 N·s/m小车与导轨之间的等效阻尼关节阻尼 c1, c20.01 N·m·s/rad旋转关节阻尼初始下摆角0.1 rad约 5.7°不要太大会增加调参难度初始上摆角-0.1 rad初始时两级摆处于近乎直立但微偏的状态4.2 转动惯量的两种配置方式在 Solid 模块中转动惯量的填写有两种方式。如果你选择了“By mass”模式则软件会根据几何形状自动计算惯性张量你只需要填质量。对标准圆柱体自动计算的惯性张量一般准确可用。如果你需要手动指定则在 Solid 的 Inertia 选项卡中取消勾选“Automatically compute”然后手动输入惯性矩阵。一个比较隐蔽的坑是惯性张量矩阵必须相对于 Solid 的质心坐标系输入。如果你的参考坐标系经过了偏移手动填写的惯性张量却仍然以参考坐标系为基准那动力学就会出错。稳妥的办法是先用自动计算模式在仿真结果正常后再考虑是否手动微调。我建模时几乎总是用自动计算只在需要建模“配重块”“偏心块”等特殊刚体时才手动指定。4.3 关节阻尼与摩擦参数的设定很多人会把模型里的关节阻尼全部设为零结果仿真出来的系统很难收敛控制器要输出很大的力才能稳住。这不符合真实物理系统。我在 Prismatic Joint 的属性窗口中将 Internal Mechanics 选项卡里的 Viscous Friction 设为 0.1 N·s/m在两个 Revolute Joint 中将 Viscous Friction 设为 0.01 N·m·s/rad。阻尼的作用相当于在运动方程中加入线性的能量耗散项数值不大但对数值稳定性和后续控制器的增益整定都有帮助。这里原理上补充一句倒立摆是一个典型的非最小相位系统阻尼项的存在不会改变系统的本质不稳定性但可以减小仿真过程中高频振荡的幅度。对 Simulink 求解器来说这能有效避免不必要的步长缩减和收敛失败。4.4 初始条件设定在 Simscape Multibody 中关节的初始角度不能通过给 Solid 模块改初始位置实现而是必须在关节模块的 State Target 选项卡中设定。双击第一个 Revolute Joint下摆展开 State Targets 选项卡把 Position 的 Value 设置为-0.1 rad注意正负号取决于你的坐标轴方向定义Velocity 设置为 0。这里如果你之前把 x、y、z 轴的定义搞反了初始角度的正负号也会跟着反仿真结果会表现为摆锤直接倒下——这是很常见的“模型看着对但一仿真就塌”的原因之一。第二个 Revolute Joint 同理初始位置设置为0.1 rad。初始速度都为 0。小车初始位置设置 0速度 0。设置完之后整个机械系统就有了一个微小的初始偏移这比完全直立0 度更有验证意义——如果控制器能在有初始偏差的情况下把摆拉回平衡点那说明控制算法真正有效。如果完全从 0 度开始即使控制器失效模型也可能在数值误差的驱动下过一段时间才倒下反而不利于调试。5. 控制系统搭建从 PID 到状态反馈控制的取舍5.1 为什么纯 PID 容易让二阶倒立摆失控很多初学者的第一反应是用 PID 控制器稳住倒立摆。但二阶倒立摆是一个四阶系统状态量包括小车位移、下摆角、上摆角以及对应速度两个输出角度一个输入力。用一个 PID 控制器同时控制两个角度本质上是把一个多输入多输出MIMO系统强行当作单输入单输出SISO系统来处理。这样做不是完全不行但增益调节极其困难一个通道的反馈会影响另一个通道的稳定性很容易出现“下摆稳住了、上摆开始抖”的尴尬局面。我个人的经验是如果只是仿真验证先用一个简化方案——状态反馈控制极点配置或 LQR把两个角度和小车位移都引入反馈最简单的模型就能稳定。后面如果想要更贴近工程实际再在状态反馈基础上加积分项来消除稳态误差。5.2 LQR 控制器的 Simulink 实现这里推荐用 LQR 控制器因为它的参数配置有明确的物理含义不需要凭直觉调增益。LQR 的目标是设计状态反馈增益矩阵 K使得二次型性能指标达到最小。在 MATLAB 命令行中先运行模型生成了状态空间矩阵 A、B再调用lqr函数计算 K。二阶倒立摆的线性化状态方程可以写为dx/dt A x B u其中状态向量 x [X dX θ1 dθ1 θ2 dθ2]θ1 是下摆角θ2 是上摆角。在我的仿真中取 Q 矩阵为对角阵对角线对应各个状态变量的权重小车位移权重 100小车速度权重 10下摆角权重 1000下摆角速度权重 50上摆角权重 1000上摆角速度权重 50。R 取 1。调用的命令为Q diag([100 10 1000 50 1000 50]); R 1; K lqr(A, B, Q, R);计算出的 K 就是一个 1x6 的矩阵对应六个状态量的反馈增益。在 Simulink 中搭建一个增益矩阵模块Gain把 K 填进去输入为六个状态量输出为控制量 u。这里需要特别注意从 Simscape 传感器出来的物理信号角度、角速度、位移、速度需要通过 PS-Simulink Converter 转换为纯数值信号然后借助 Demux 或 Bus Selector 按状态向量顺序排列再进入 Gain 模块。5.3 控制量限幅与执行器饱和任何实际执行器都有输出上限。我设置控制力限幅为 ±50N这在实际小型倒立摆装置上已经算是比较大的驱动力。实现方式很简答在 Gain 模块输出后串联一个 Saturation 模块上下限分别设为 50 和 -50。这一步看似简单但如果没有限幅LQR 在初始偏差较大时可能输出上百牛的力仿真曲线看起来非常“理想”但对应到实际台架上根本无法实现等于白做。5.4 仿真求解器配置双击模型空白处打开 Model Settings在 Solver 选项卡中将求解器类型设为 Variable-step求解器选 ode45Dormand-Prince。Max Step Size 设置为 0.001s仿真时间先设 10s。Simscape 模型默认使用自动步长但 max step 设得太大时关节碰撞和高速摆动的数值会出现明显不连续导致结果震荡。0.001s 是一个安全而有效的默认选择兼顾仿真速度和精度。另外一个必须注意的选项是 Simscape 模型的“Local Solver”配置。双击 Mechanism Configuration 模块或者进入 Model Settings Simscape Multibody把“Do not use local solver”保持默认。新手往往会在求解器报错后试图开启 Local Solver但本地求解器主要用于大型多体动力学系统的加速对倒立摆这种规模不大的模型反而可能引入额外的数值误差。6. 搭建过程中最常踩的坑报错排查与仿真调优6.1 Simscape 初值一致性检查失败这是新手遇到频率最高的问题。模型搭建完成后点击运行直接弹出类似“Initial conditions are not consistent”的报错。原因通常有几种刚体之间互相穿透未检测到、关节初始位置和机械约束矛盾、或者两个刚体重合导致自由度约束重叠。排查方法分三步先检查是否有两个 Solid 模块的位置几何关系有重叠。双击每个 Solid 查看几何尺寸特别关注同一位置的上下摆连接处。比如下摆长 0.5m上摆长 0.4m两级之间的 Rigid Transform 偏移必须和杆长匹配否则会出现“杆已经插入小车内”这种几何冲突。再检查关节方向是否和实际物理运动匹配。如果 Revolute Joint 的旋转轴设成 X 轴而摆杆的设置沿 Z 轴伸展那么初始时刻关节角为 0 时摆杆“横着”而不是“竖着”系统为了满足约束会给出不一致初值。这里我的经验是先不管运动学细节把摆杆的初始几何设置为与重力方向一致竖直再在关节里设一个小角度偏移这样模型初始化最稳定。还要检查 Rigid Transform 的位移单位是不是填错了。Simscape 默认单位是米如果有人在 Transform 里把 0.5 写成了 5那整个模型会放大十倍初值检查大概率失败。6.2 仿真发散NaN的排查顺序模型初始化正常但仿真跑到一秒钟左右数值直接发散曲线变成一条竖线。这个问题多数和三个因素有关初值过大、控制增益过大、求解器最大步长过大。先把初始角度从 0.1 rad 减到 0.05 rad如果模型能稳住说明控制器在较大初始偏移下饱和了可以适当增大控制力限幅或者重新调节 LQR 权重。把 Max Step Size 从 0.001 改为 0.0005观察发散时间点是否明显延后。如果是说明原步长下的数值积分误差已经影响了系统稳定性减少步长即可。检查 Saturation 限幅是否合理。如果 LQR 算出的控制量常常顶在限幅值上说明系统已经饱和需要重新设计控制器或者放宽限幅。6.3 角度传感器输出一直抖传感器输出极其毛糙、充满高频噪声这个在 Simscape 仿真里往往和被控对象的阻尼设置有关。查看关节模块的 Viscous Friction 是否为 0如果是给两个旋转关节各加 0.01 的阻尼。物理意义上任何真实转动副多少都有阻尼零阻尼模型等同于理想刚体转动数值求解时更容易激发高频模态。另外检查传感器转换模块 PS-Simulink Converter 输出端口的数据类型和采样时间设置。把 Sample Time 设为 0 或 -1继承避免因信号采样时间不匹配产生人为的阶梯状波形。如果输出信号仍有高频毛刺可以在控制器前加一个低通滤波器截止频率设为 50Hz 左右这在实际嵌入式系统中也常见。6.4 如何快速判断模型动力学是否正确这一步很关键。在搭好模型、还没接入控制器之前先做一个“自由落体测试”把两个关节初始角度设为 45°Simulink-PS Converter 输入力设为 0运行 2 秒观察两个摆杆角度曲线。如果模型动力学正确摆杆会自然倒下并在导轨上来回滑动曲线平滑、符合能量守恒且有因摩擦阻尼导致的轻微衰减。如果曲线出现剧烈跳动或者明显不连续说明刚体连接、坐标系方向或关节方向存在错误先修这步再谈控制。这个“先本体、后控制”的思路适用于所有 Simscape 机械模型。很多新手把机械模型和控制器一次性搭好出问题时很难分清是物理建模错误还是控制参数问题。分开验证定位效率高得多。7. 调参经验和后续扩展几点个人体会第一次跑通模型时不要急着上复杂算法。先把 LQR 的权重 Q、R 按照“角度权重 位置权重 速度权重”的经验设置仿真时间 5 秒足够看出趋势。如果下摆稳了但上摆还在小幅震荡就增大上摆角对应的 Q 权重如果小车一直漂移回不到原点就增大小车位移的 Q 权重。LQR 的优势在于Q 矩阵对角元素每次只动一个增益矩阵变化可控调试过程远比手动调 PID 直观。另外在 Simscape Multibody 模型基础上可以继续做很多扩展把直线导轨换成圆弧导轨、把刚性杆换成柔性杆、加入弹簧阻尼器模拟实际关节间隙、甚至导成 FMU 模型用于联合仿真。这也是我为什么强调一定要用 Simscape 建模——它的模型天然支持这些扩展而纯信号流模型每改一次结构都要重新推导并重搭一大片模块。最后再提醒一句做这类控制仿真最重要的不是模型本身而是你对系统物理特性的理解。Simscape 帮你省下了推导微分方程的时间但也意味着你更要清楚每个参数在自己的真实装置上对应什么零部件。模型跑通之后试着把初始角度调到 0.2 rad看看控制器能不能拉回来再把阻尼调到接近零看看模型会不会发散。多折腾几次你会对这个系统真正建立起直觉。这台模型是可以玩很久的试验台祝各位都能顺利把两级摆“立”起来。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑