
双足人形机器人这个方向很多人第一反应是强化学习、步态规划、全身控制这些偏上层的东西但真正动手做过整机仿真的人都知道最先卡住你的往往不是算法而是模型怎么搭。我前后在两个项目里分别用 Simulink/SimMechanics 和 ARX 状态空间辨识两条路线做过双足机器人的建模踩过的坑不算少也积累了一些文档里不会写的经验。这篇文章就把这两种建模方法掰开揉碎讲清楚它们各自解决什么问题、底层原理是什么、具体怎么落地、实测中会遇到哪些意外以及什么场景下该选哪条路。不管你是刚接触 Simulink 仿真的学生还是已经在做机器人控制的工程师应该都能从中找到能直接抄作业的部分。1. 为什么双足机器人建模比轮式机器人麻烦得多1.1 双足系统的本质难点欠驱动与变拓扑轮式机器人建模相对友好因为轮子始终贴地接触约束稳定运动学关系清晰。双足机器人完全不是这回事。它的核心特征是欠驱动——你只有踝、膝、髋这几个关节电机但机器人有十几个自由度支撑腿和摆动腿的角色在每一步都会互换。更麻烦的是变拓扑单脚支撑期、双脚支撑期、腾空期每个阶段的动力学方程都不一样接触点的数量和位置也在变。这就导致一个直接后果你没法用一套固定的微分方程从头描述到尾。轮式机器人可以写一个统一的状态空间模型跑到底双足机器人必须在不同相位之间切换模型还要处理切换瞬间的冲量。我第一次做双足仿真时天真地以为把关节力矩输入、关节角度输出连起来就行结果机器人走了两步就穿模了——脚陷进地面里因为接触约束根本没建对。1.2 两种建模思路的分野白盒机理 vs 黑盒辨识面对这种复杂性工程上自然分化出两条路线。第一条是白盒机理建模代表工具就是 Simulink 配合 SimMechanics现在叫 Simscape Multibody。它的思路是我知道每个连杆的质量、惯量、质心位置我知道关节怎么连接那我就能用牛顿-欧拉或者拉格朗日方法把动力学方程推出来让仿真环境去解。这是从物理第一性原理出发的路子。第二条是黑盒/灰盒辨识建模代表方法就是 ARX 模型辨识最终落到状态空间模型上。它的思路是我不完全清楚内部每个参数但我可以给系统施加激励采集输入输出数据用数学方法反推出一个能描述系统动态的模型。这是从数据出发的路子。这两条路不是对立的实际项目里经常是先用机理建模搭出仿真环境再用辨识方法去校准参数或者做控制器设计。但作为入门你得先搞清楚每条路各自怎么走通。1.3 选型前必须问自己的三个问题在动手之前我建议你先回答三个问题这直接决定你该走哪条路你的目标是做控制器设计还是做整机性能评估如果是要设计 LQR、MPC 这类基于模型的控制器状态空间模型更直接如果是要评估结构强度、能耗、关节负载机理模型更合适。你能拿到多精确的物理参数如果连杆质量、惯量、摩擦系数都能测或者能查机理建模精度有保障如果参数全靠猜辨识反而更靠谱。你的算力预算和实时性要求是什么SimMechanics 模型跑起来很吃算力做硬件在环往往跑不动ARX 辨识出来的状态空间模型阶数低、计算快更适合嵌入式部署。下面这张表是我自己总结的对比可以先有个整体印象维度SimMechanics 机理建模ARX 辨识 状态空间建模依据物理参数质量、惯量、几何输入输出实验数据前期工作量大要建几何、配参数中要设计激励实验模型可解释性强每个参数有物理意义弱系数是拟合出来的计算开销高低适合场景整机仿真、性能评估控制器设计、嵌入式部署对参数误差敏感度高低数据驱动2. SimMechanics 机理建模从连杆到整机的完整搭建链路2.1 Simscape Multibody 的建模逻辑与坐标系约定SimMechanics 的核心思想是用刚体加关节拼出机构。每个连杆是一个 Solid 模块你需要给它配置质量、惯量矩阵、几何形状关节是 Revolute转动或 Prismatic移动模块定义两个连杆之间的相对运动关系。整个模型是一棵树从基座World出发一层层连到末端。这里第一个大坑就是坐标系。SimMechanics 里每个刚体都有自己的局部坐标系关节的连接点、刚体的质心、几何形状的参考点这三者的关系必须理清楚。我见过太多人建出来的模型看起来对一动就飞八成是质心位置或者关节轴方向配错了。我的经验是先在 CAD 里把每个连杆的质心相对关节的位置量出来统一用关节坐标系描述再往 SimMechanics 里填。别在仿真环境里凭感觉调那样调一天也调不对。具体操作上一个标准的单腿建模流程是这样的建立 World 框架设置重力方向默认 -Z注意你的机器人是 Z 轴向上还是 Y 轴向上。从基座开始依次添加髋部、大腿、小腿、足部四个 Solid 模块。每两个 Solid 之间插入 Revolute Joint配置旋转轴通常是 Y 轴对应俯仰。在每个 Solid 的惯性属性里填入质量、质心坐标、惯量张量。用 Transform 模块处理关节到质心的偏移。2.2 关节驱动与接触力建模的关键参数关节建好只是骨架真正让机器人动起来的是驱动和接触。驱动这块SimMechanics 提供 Joint Actuator你可以输入力矩或者运动轨迹。做双足机器人我强烈建议用力矩驱动而不是位置驱动。位置驱动看起来省事但它相当于给关节加了无穷大的刚度物理上不真实而且一旦接触力算错整个模型会瞬间发散。力矩驱动更接近真实电机也方便你后面接控制器。接触力是双足建模里最玄学的部分。SimMechanics 有 Spatial Contact Force 模块需要配置接触刚度、阻尼、摩擦系数这几个参数。这里有个经验公式可以参考接触刚度大致按k m * g / δ估算其中 m 是机器人质量g 是重力加速度δ 是你允许的最大穿透深度一般取 1mm 到 5mm。比如一个 30kg 的机器人允许 2mm 穿透那 k ≈ 30×9.8/0.002 ≈ 147000 N/m。阻尼一般取刚度的 1% 到 10%。摩擦系数更麻烦因为它直接决定机器人会不会打滑。我一般先用 0.8 试如果发现支撑脚老是滑动就往上调如果机器人粘在地上走不动就往下调。这个参数没有理论最优值只能靠试。提示接触参数调好后一定要做一次静置测试——让机器人站着不动跑 10 秒看它会不会自己漂移或者抖动。如果会说明接触参数还没调好别急着往下做步态。2.3 从单腿到整机的装配与自由度检查单腿跑通之后装配整机就是把两条腿挂到同一个躯干上。这里要注意闭环问题双足机器人在双脚支撑期两条腿和地面构成一个闭环SimMechanics 处理闭环需要额外的约束求解容易出问题。我的做法是先做单腿跳跃仿真验证动力学正确性再做双腿但只让一条腿接触地面最后才做双脚支撑。每一步都确认模型不发散、能量守恒合理无驱动时总能量应该基本不变再往下走。自由度检查也很关键。一个 12 自由度的双足机器人每条腿 6 个关节如果模型里出现了不该有的约束仿真会报过约束错误如果少了约束机器人会像面条一样软。SimMechanics 有 Mechanics Explorer 可以可视化我一般会手动掰一掰每个关节看运动是否符合预期。2.4 实测中模型发散与穿模的排查顺序模型发散是新手最常遇到的问题现象是仿真跑几步就报错或者数值爆炸。我的排查顺序是这样的先看是不是接触力参数太硬。把接触刚度调小一个数量级试试如果发散了但慢一点说明是刚性问题。再看求解器设置。SimMechanics 默认用变步长求解器遇到刚性接触会疯狂缩小步长。可以换成定步长 ode4步长取 1ms配合接触阻尼调大一点。然后查质量惯量。惯量矩阵必须是正定的如果你填的惯量不满足三角不等式比如 Ixx Iyy Izz物理上不成立仿真必崩。最后查关节轴和坐标系。这个最隐蔽往往要打开 Mechanics Explorer 一步步看。穿模问题一般是接触刚度太小或者步长太大导致的。把步长降到 0.5ms接触刚度提上去基本能解决。但要注意步长太小仿真会非常慢一个 10 秒的仿真可能跑半小时这是机理建模的固有代价。3. ARX 辨识与状态空间模型用数据反推机器人动态3.1 ARX 模型的数学本质与适用边界ARX 是 AutoRegressive with eXogenous input 的缩写说白了就是一个差分方程y(k) a1*y(k-1) ... an*y(k-n) b1*u(k-1) ... bm*u(k-m) e(k)其中 y 是输出比如关节角度u 是输入比如关节力矩e 是噪声。这个式子的意思是当前时刻的输出由过去 n 个时刻的输出和过去 m 个时刻的输入共同决定。用最小二乘法就能把 a、b 这些系数估出来。ARX 的适用边界很明确它适合线性或者近似线性的系统。双足机器人本质是非线性的但在某个工作点附近比如站立时小幅摆动线性近似是成立的。所以 ARX 辨识通常是在特定工况下做的不能指望一个模型描述所有步态。另外ARX 对噪声比较敏感。如果采集的数据噪声大辨识出来的模型会过拟合噪声预测时反而更差。这时候可以考虑 ARMAX 或者 OE 模型它们对噪声的处理更细致。不过对于入门ARX 足够用了。3.2 激励信号设计与数据采集的实操细节辨识的质量七分靠数据三分靠算法。激励信号设计不好后面怎么调都白搭。我一般用扫频信号Chirp或者伪随机二进制序列PRBS作为激励。扫频信号从低频扫到高频能覆盖系统的整个频带PRBS 能量分布均匀适合辨识。关键是激励幅度要合适太小了信噪比不够太大了会激发非线性。我的经验是让关节在 ±10° 到 ±20° 范围内摆动这个幅度下线性近似基本成立。数据采集要注意采样率。根据奈奎斯特采样定理采样率至少是系统最高频率的两倍但实际工程里我一般取 10 倍以上。双足机器人的关节动态带宽大概在 10Hz 到 50Hz所以采样率取 1kHz 比较稳妥。采集的时候还要注意去除趋势项。如果数据里有直流偏置或者缓慢漂移辨识出来的模型会带一个虚假的积分环节。我一般先用detrend函数处理一下再做辨识。3.3 用 MATLAB 完成 ARX 辨识的完整代码路径MATLAB 的 System Identification Toolbox 做 ARX 辨识非常方便。下面是我常用的代码框架% 假设 u 是输入力矩序列y 是输出角度序列Ts 是采样周期 data iddata(y, u, Ts); data detrend(data); % 去趋势 % 划分训练集和验证集 data_train data(1:round(0.7*length(y))); data_val data(round(0.7*length(y))1:end); % 尝试不同阶数 for na 2:6 for nb 2:6 sys arx(data_train, [na nb 1]); fit compare(data_val, sys); fprintf(na%d, nb%d, fit%.2f%%\n, na, nb, fit); end end % 选最优阶数后转成状态空间 sys_ss ss(sys);这里[na nb nk]中 nk 是输入延迟一般取 1。阶数选择是个权衡阶数太低拟合不够阶数太高容易过拟合。我一般看验证集的拟合度选拟合度最高但阶数尽量低的那个。辨识完之后一定要做残差分析。如果残差是白噪声自相关函数在置信区间内说明模型把系统动态都抓住了如果残差还有明显结构说明阶数不够或者模型结构不对。3.4 辨识模型转状态空间后如何对接控制器ARX 辨识出来的是差分方程要用于控制器设计通常转成状态空间形式x(k1) A*x(k) B*u(k) y(k) C*x(k) D*u(k)MATLAB 的ss(sys)会自动完成这个转换。转完之后你就可以用lqr、dlqr这些函数设计控制器了。这里有个坑辨识出来的状态空间状态变量没有物理意义。它只是数学上的中间变量你不能说x1 是角度、x2 是角速度。所以做状态反馈的时候要么用全状态反馈假设所有状态可测要么设计观测器。我一般用输出反馈或者设计一个 Luenberger 观测器避免依赖不可测的状态。还有一个实际问题是离散化。辨识出来的是离散模型如果你的控制器是连续设计的需要先离散化反之亦然。采样周期必须一致否则会出大问题。我见过有人辨识用 1kHz控制器跑 100Hz结果系统直接震荡就是因为采样周期没对齐。4. 两条路线的交叉验证让机理模型和辨识模型互相校准4.1 用 SimMechanics 生成辨识数据的闭环思路这两条路线其实可以打通而且打通之后威力很大。具体做法是用 SimMechanics 搭一个高保真模型给它施加激励信号采集输入输出数据再用这些数据做 ARX 辨识。这样你既有了机理模型的可解释性又有了辨识模型的低阶和快速。这个思路的好处是你不需要在真机上做危险的激励实验。双足机器人摔一次可能就坏了在仿真里随便折腾。等辨识出来的模型在仿真里验证通过了再上真机做小幅度验证。具体流程在 SimMechanics 里给每个关节施加 Chirp 力矩信号。采集关节角度和角速度作为输出。导出数据到 MATLAB 工作区。按第 3 节的流程做 ARX 辨识。把辨识模型和 SimMechanics 模型做同样的输入对比输出。如果两者输出吻合度高我一般要求 90% 以上说明辨识模型可信。4.2 参数敏感性分析与模型降阶的取舍机理模型参数多但不是每个参数都重要。做敏感性分析能帮你找出关键参数把精力集中在它们身上。方法很简单把每个参数扰动 ±10%看模型输出的变化。变化大的就是敏感参数需要精确测量变化小的可以粗略估计。我做过一个双足机器人的敏感性分析发现大腿和小腿的质量、质心位置最敏感而足部的惯量影响很小。这意味着我在测量时可以把重点放在大腿小腿上。模型降阶是另一个实用技巧。SimMechanics 模型可能有几十个状态做控制器设计太复杂。可以用balred或者modred做降阶保留主要动态。降阶的代价是精度损失所以要对比降阶前后的频响确保在控制带宽内吻合。4.3 联合仿真中采样率与求解器不匹配的坑把 SimMechanics 和辨识模型放在一起做联合仿真时最容易出问题的是采样率和求解器不匹配。SimMechanics 用变步长求解器输出是连续时间辨识模型是离散的需要固定采样周期。如果直接把两者连起来Simulink 会在每个采样点之间做零阶保持引入额外延迟。这个延迟在低频时无所谓但在高频段会严重影响相位导致联合仿真结果和单独仿真对不上。我的解决办法是统一用定步长求解器步长取辨识模型的采样周期。比如辨识用 1kHz那 SimMechanics 也用 1ms 定步长。这样两者时间对齐不会有额外延迟。代价是 SimMechanics 仿真变慢但为了结果可信这个代价值得付。5. 从模型到代码C 语言部署与实时性考量5.1 Simulink 模型生成 C 代码的配置要点Simulink 的 Embedded Coder 可以把模型直接生成 C 代码这对嵌入式部署非常有用。但配置不对生成的代码可能跑不起来或者效率极低。关键配置项求解器必须用定步长变步长没法生成代码。系统目标文件选ert.tlcEmbedded Real-Time Target不要选grt.tlc。代码优化打开inline parameters和remove root level I/O能显著减小代码体积。数据类型尽量用single而不是double嵌入式平台单精度浮点通常够用而且快很多。生成代码后我一般会在 VS Code 里配好 C/C 环境把生成的代码编译一遍确认没有语法错误。这里有个常见坑生成的代码依赖一些运行时库如果目标平台没有需要手动裁剪或者替换。5.2 状态空间模型在嵌入式平台的落地方式辨识出来的状态空间模型部署起来比 SimMechanics 简单得多因为它就是一个矩阵乘法// 离散状态空间模型的一步更新 void ss_update(float *x, float u, float *y) { float x_new[N]; for (int i 0; i N; i) { x_new[i] 0; for (int j 0; j N; j) { x_new[i] A[i][j] * x[j]; } x_new[i] B[i] * u; } *y 0; for (int i 0; i N; i) { *y C[i] * x_new[i]; x[i] x_new[i]; } *y D * u; }这段代码在 Cortex-M4 上跑N4 的模型大概几微秒就能算完完全满足实时性。相比之下SimMechanics 生成的代码要解微分方程慢好几个数量级。5.3 实时性测试与常见编译错误处理部署到嵌入式平台后一定要做实时性测试用示波器或者 GPIO 翻转测量控制周期的实际执行时间。我一般要求执行时间不超过控制周期的 50%留一半余量给中断和其他任务。常见的编译错误里cannot open source file这类一般是头文件路径没配好undefined reference是链接时缺库。VS Code 里配 C/C 环境重点是把c_cpp_properties.json里的 includePath 和tasks.json里的编译参数配对。这些配置一次配好后面就省心了。6. 我在两个项目里踩过的具体坑与应对6.1 机理模型里惯量矩阵填错的隐蔽后果第一个项目里我建完模型发现机器人站着会自己慢慢倾斜最后倒下。查了两天最后发现是小腿的惯量矩阵填错了——我把 Ixx 和 Izz 填反了。这个错误很隐蔽因为仿真不会报错只是行为不对。惯量矩阵必须满足正定性和三角不等式我后来养成了习惯填完惯量后用eig函数检查特征值是否都为正。6.2 辨识数据里混入噪声导致模型失真的处理第二个项目做 ARX 辨识时采集的数据里混了电机编码器的量化噪声。辨识出来的模型在训练集上拟合度 95%但验证集只有 60%。后来我在采集端加了低通滤波并且把数据做了平滑处理验证集拟合度才上到 90%。教训是辨识前一定要看数据的频谱如果高频段全是噪声先滤波再辨识。6.3 联合仿真时步长不一致引发的数值震荡有一次做 SimMechanics 和状态空间模型的联合仿真结果系统一直高频震荡。查了半天发现是 SimMechanics 用了变步长而状态空间模型是 1ms 定步长两者时间不对齐。改成统一定步长后震荡消失。这个坑很典型凡是混合连续和离散模型的仿真都要注意时间对齐。7. 两种方法到底该怎么选场景化的决策建议7.1 教学演示与科研发论文的选型差异如果你是做教学演示SimMechanics 更直观学生能看到三维模型动起来理解动力学更轻松。如果是发论文要看你的贡献点做控制算法的用辨识模型更简洁公式好写做机构设计的用机理模型更有说服力。7.2 工程落地时精度与算力的平衡工程落地时我的建议是两条路都走一遍先用 SimMechanics 搭高保真模型做验证再用它生成数据做辨识最后把辨识模型部署到嵌入式平台。这样既有精度保障又有实时性。纯用机理模型部署算力往往扛不住纯用辨识模型又缺乏物理可解释性出了问题不好排查。7.3 给刚入门同学的一条务实路径如果你刚开始做双足机器人建模我建议的顺序是先用 SimMechanics 搭一个简单的单腿模型跑通跳跃仿真然后学 ARX 辨识用单腿模型生成数据做辨识最后把两者结合做整机的联合仿真。这个路径循序渐进每一步都有明确的验证标准不容易迷失。建模这件事说到底没有银弹。机理建模给你物理直觉辨识建模给你工程效率两者结合才是正道。我在实际项目里最大的体会是别追求一次建对要追求快速迭代。先搭个粗糙的模型跑起来再一点点加细节、调参数比一开始就追求完美要快得多。