系统建模——从物理方程到数学模型

📅 2026/8/17 23:53:31
系统建模——从物理方程到数学模型
上篇聊了反馈控制的基本原理讲了闭环为什么比开环好。但在你设计任何控制器之前有一件事必须先做——给你的被控对象建一个数学模型。说白了你得先搞清楚你要控制的东西到底是怎么动的才能设计控制器让它按你的意愿动。系统建模这件事很多教科书讲得特别枯燥——一上来就是拉格朗日方程、哈密顿原理。今天我们换个思路从最直观的物理系统出发一步步把数学模型推出来让你理解建模到底在干嘛面试的时候能讲清楚。为什么要建模你可能觉得建模是多此一举——我直接调PID不就行了讲真不调模型直接调PID确实能跑但效果往往不好。为什么因为你不知道你的系统响应有多快、惯量有多大、阻尼是多少。你调参数全靠试试到一组能用的参数可能要花几个小时甚至几天。如果你有一个靠谱的模型你可以先用仿真确定一组初始参数然后在实际系统上微调。这个流程比盲调快得多。之前做一个机械臂关节的控制同事直接上PID盲调搞了两天还是震荡。我花了一个下午测了关节的转动惯量和摩擦系数建了一个简单的二阶模型在仿真里算了一组参数上去之后十分钟就调好了。建模不是浪费时间是省时间。从牛顿定律到微分方程建模的第一步是列物理方程。对于机械系统最基础的工具就是牛顿第二定律Fma。拿一个简单的弹簧-质量-阻尼系统来说。一个质量块m连着一个弹簧弹性系数k连着一个阻尼器阻尼系数b你施加一个外力F(t)。根据牛顿第二定律对质量块列力平衡方程m*a F(t) - k*x - b*v其中a是加速度v是速度x是位移。把a写成x的二阶导数v写成x的一阶导数# 弹簧-质量-阻尼系统的微分方程 # m*x b*x k*x F(t) # 这就是一个二阶线性常微分方程 import numpy as np from scipy.integrate import solve_ivp import matplotlib.pyplot as plt m 1.0 # 质量 (kg) b 0.5 # 阻尼系数 (N·s/m) k 2.0 # 弹簧系数 (N/m) def mass_spring_damper(t, y, F): 状态方程: y [x, v] x, v y dxdt v dvdt (F - b*v - k*x) / m return [dxdt, dvdt] # 施加1N的阶跃力 sol solve_ivp(mass_spring_damper, [0, 20], [0, 0], args(1.0,), max_step0.01) print(f稳态位移: {sol.y[0, -1]:.3f}m)这个微分方程就是系统的数学模型。它描述了输入F(t)和输出x(t)之间的关系。有了这个方程你就可以分析系统的特性——响应速度、超调量、稳态误差。状态空间表示法上面那个二阶微分方程可以拆成两个一阶微分方程写成矩阵形式。这就是状态空间表示法。选状态变量x1x位移x2v速度则# 状态空间模型 # x1 x2 # x2 (-k/m)*x1 (-b/m)*x2 (1/m)*F import numpy as np m, b, k 1.0, 0.5, 2.0 A np.array([[0, 1], [-k/m, -b/m]]) # 系统矩阵 B np.array([[0], [1/m]]) # 输入矩阵 C np.array([[1, 0]]) # 输出矩阵观测位移 D np.array([[0]]) # 直通矩阵 # 状态方程: dx/dt Ax Bu # 输出方程: y Cx Du # 仿真 x np.array([0, 0]) # 初始状态 u 1.0 # 输入力 dt 0.01 for i in range(2000): x_dot A x B * u x x x_dot * dt print(f稳态状态: 位移{x[0]:.3f}m, 速度{x[1]:.3f}m/s)状态空间表示法的好处是通用——任何阶数的微分方程都能转化为一阶矩阵方程计算机处理矩阵运算非常高效。而且多输入多输出系统也能用同样的框架描述只需要扩展矩阵的维度。模型简化别追求完美实际工程中一个重要的原则是模型够用就行别追求完美。你建一个极其精确的模型考虑了摩擦非线性、弹性变形、温度效应、齿轮间隙结果模型本身复杂到你根本没法用它设计控制器。这种模型除了发论文没啥实际用处。工程建模的核心思路是抓主要矛盾。对于低频运动高频的动态特性可以忽略。对于小范围运动非线性可以线性化。对于耦合很弱的通道可以解耦成独立的单变量系统。比如一个机械臂完整的动力学模型包含科里奥利力、离心力、重力项非常复杂。但如果你只关心单个关节在小范围内的运动可以把其他关节锁定把这个关节简化成一个弹簧-质量-阻尼系统。这个简化模型虽然不完美但足够你设计一个能用的控制器了。记住一个原则控制器设计用的模型不需要完美但需要抓住系统的主要动态特性。什么叫主要动态特性就是决定系统响应速度和稳定性的那些因素——惯量、阻尼、刚度。次要因素比如微小的非线性摩擦可以先忽略等控制器跑起来了再补偿。之前面试一家做四足机器人的公司面试官问你怎么给机器人的腿建模。我说先用简化的单腿模型一个二阶系统来设计控制器然后在完整的多体动力学模型上验证和微调。面试官点头说这就是他们实际的做法。系统辨识当物理建模太难的时候有些系统你很难用物理定律直接建模——比如一个液压系统、一个化学反应过程、甚至一个复杂的电路。这时候可以用系统辨识的方法给系统施加已知的输入信号测量输出响应然后用数学方法拟合出模型参数。最常见的做法是施加一个阶跃信号记录系统的阶跃响应曲线然后从曲线的特征上升时间、超调量、稳态值反推出模型参数。这个方法在工业界用得非常多后面讲PID调参的时候还会提到。# 简单的系统辨识从阶跃响应估计一阶系统参数 # 假设系统是一阶的: G(s) K / (tau*s 1) # 从阶跃响应中可以估计K和tau import numpy as np # 假设测量的阶跃响应数据 t_data np.array([0, 0.5, 1.0, 1.5, 2.0, 3.0, 5.0, 10.0]) y_data np.array([0, 0.39, 0.63, 0.78, 0.86, 0.95, 0.99, 1.0]) # 稳态增益K y_ss / u_step K y_data[-1] / 1.0 # 假设阶跃幅值为1 # 时间常数tau: y(tau) 0.632 * y_ss # 从数据中插值找到y0.632对应的时间 tau np.interp(0.632 * K, y_data, t_data) print(f估计增益K{K:.2f}, 时间常数tau{tau:.2f}s)面试的时候如果面试官问你怎么给一个未知系统建模你可以说两条路一是物理建模从牛顿定律或基尔霍夫定律出发列方程二是系统辨识从输入输出数据拟合模型。两条路各有适用场景实际工程中经常结合使用。分享一个我在项目中做系统建模的经验。当时给一台差速移动机器人建运动学模型一开始用理想差速运动学两个轮子纯滚动无滑动模型很简单但预测精度不够——机器人走直线时预测轨迹和实际轨迹偏差越来越大。排查后发现主要原因是轮子有轻微打滑尤其是转弯时内侧轮会滑动。我们在理想模型基础上加了一个滑动补偿系数——通过实验测量不同转弯半径下的实际位移和理论位移的比值拟合出一个补偿函数。加上补偿后轨迹预测精度提升了约40%。这个经验告诉我建模不能追求完美——先用简单模型跑起来再根据实际数据逐步添加修正项这种渐进式的建模方法在工程中最实用面试时候讲出来也能体现你的工程思维。下一篇讲传递函数——用拉普拉斯变换把微分方程变成代数方程这是经典控制理论最核心的工具之一也是面试中经常考到的知识点。如果这篇文章对你有帮助欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。「机器人软件开发面试·从入门到精通」连载系列上一篇第177篇 反馈控制原理——闭环为什么比开环好 下一篇预告第178篇 系统建模——从物理方程到数学模型有任何问题欢迎评论区留言我会尽量回复。