跳转至

机器人动力学

引言

运动学只描述"怎么动",动力学(Dynamics)回答"为什么这样动"——它把关节力矩与运动联系起来,引入质量、惯量、重力与摩擦。低速运动时可以忽略动力学,用位置环加减速度前馈就足够;但一旦机器人高速运动、负载变化、或需要力控与柔顺交互,动力学模型就成为必需品。它同时也是强化学习仿真环境、模型预测控制与全身控制的核心。

动力学方程

标准形式

自由度机器人的运动方程可以写成统一的矩阵形式:

各项的含义:

维度 物理意义
质量矩阵(惯量矩阵),对称正定
科氏力与离心力
重力项
摩擦力矩
关节驱动力矩
外部接触力折算到关节的力矩

其中科氏力(Coriolis Force)与离心力(Centrifugal Force)都是速度的二次项: 中含 )的是科氏力,含 的是离心力。它们的存在意味着关节之间存在耦合:转动一个关节会对其他关节产生力矩扰动。这正是独立关节 PID 控制在高速时精度下降的原因。

两类问题

  • 逆动力学(Inverse Dynamics):已知 。这是"容易"的方向,递推牛顿-欧拉法可在 时间内完成,用于力矩前馈控制。
  • 正动力学(Forward Dynamics):已知 。这是"困难"的方向,朴素实现需 ,Featherstone 的关节体算法(Articulated Body Algorithm,ABA)可降至 。仿真器需要正动力学。

重要性质

这些性质是控制器设计与稳定性证明的基础:

质量矩阵对称正定,因此总是可逆,正动力学总有唯一解。 即系统动能。

斜对称性:适当选取 的形式(Christoffel 符号形式)后,矩阵 是斜对称的:

这条性质反映了能量守恒(科氏力不做功),是基于 Lyapunov 方法证明 PD 加重力补偿控制器与自适应控制器稳定性的关键工具。

参数线性性:动力学方程关于惯性参数(质量、质心、惯量张量)是线性的:

其中 是回归矩阵(Regressor), 是惯性参数向量(每个连杆 10 个参数:质量 1 个、一阶矩 3 个、惯量张量 6 个)。这使得参数辨识可以用最小二乘完成,也是自适应控制的基础。

拉格朗日方法

基本框架

拉格朗日方法(Lagrangian Formulation)从能量出发,适合符号推导与理解结构。定义拉格朗日量为动能减势能:

运动方程由拉格朗日方程给出:

系统动能是各连杆动能之和,每个连杆的动能包含平动与转动两部分:

利用连杆质心的雅可比 (把关节速度映射为该连杆质心的线速度与角速度),可以把动能写成关节速度的二次型,从而直接读出质量矩阵:

势能则为 ,重力项为其梯度

科氏与离心项由 Christoffel 符号给出:

这一形式保证了上述斜对称性成立。

示例:平面两连杆机械臂

设两连杆质量为 ,长度为 ,质心在连杆中点,绕质心的转动惯量为 。质量矩阵为:

其中

科氏与离心项为:

第一行中 是科氏项, 是离心项。

这个例子清楚显示了动力学的两个关键特征: 随位形变化 项,手臂伸展时等效惯量最大),以及关节间存在耦合(非对角元不为零, 的运动会对关节 1 产生力矩)。

拉格朗日方法的问题是计算量随自由度增长极快(),六自由度以上手工推导几乎不可行,通常借助 SymPy 等符号计算工具。

牛顿-欧拉方法

递推公式

递推牛顿-欧拉法(Recursive Newton-Euler Algorithm,RNEA)对每个连杆逐一应用牛顿第二定律与欧拉方程,通过两次遍历完成逆动力学计算,复杂度仅为

外推(Outward Iteration,:从基座向末端传播运动量。

由质心加速度得到作用在连杆上的合力与合力矩:

内推(Inward Iteration,:从末端向基座传播力。

关节力矩即力矩在关节轴上的投影:

实现技巧:把重力加速度作为基座的初始加速度 代入,就自动包含了重力项,不需要单独计算

用 RNEA 提取各项

RNEA 直接给出 的数值,不显式给出 。但可以通过特定输入组合把它们提取出来:

  • (含重力)
  • 的第 (不含重力, 为单位向量)
  • (不含重力)

调用 次 RNEA 即可得到完整的动力学各项,这是标准做法(称为 Composite Rigid Body Algorithm 的简化版本)。

摩擦模型

刚体动力学假设关节无摩擦,但真实机器人的摩擦力矩可占额定力矩的 10%–30%,尤其在使用谐波减速器的协作机器人上。常用的摩擦模型按复杂度递增:

库仑加粘滞摩擦(最常用):

参数少、易辨识,缺点是在 处不连续,仿真中会引起数值抖振,实现时常用 平滑。

Stribeck 模型:在低速区加入从静摩擦到库仑摩擦的过渡:

能解释低速爬行(Stick-Slip)现象,是精密力控与低速跟踪必须考虑的。

LuGre 模型:引入鬃毛(Bristle)内部状态描述预滑移位移,能刻画摩擦滞后与静摩擦的动态特性,用于高精度力控,但参数辨识困难。

工程上还需注意摩擦随温度、润滑状态、磨损而变化——刚开机与运行数小时后的摩擦参数可能相差 20% 以上,因此纯前馈补偿总要配合反馈控制。

动力学参数辨识

CAD 模型给出的惯性参数往往不准确(未建模的线缆、减速器、涂层),实际项目通常需要辨识。利用参数线性性:

沿一条激励轨迹采集 组数据,堆叠成最小二乘问题:

实施要点:

  • 只有基参数可辨识 个惯性参数中有相当一部分对力矩没有影响或只以线性组合出现(如基座连杆绕固定轴的惯量)。应先通过 QR 分解或符号分析确定最小参数集(Base Parameters),否则 奇异。
  • 激励轨迹要优化。以回归矩阵的条件数为目标,优化有限傅里叶级数轨迹的系数,使各参数都被充分激励。随意选取的轨迹会导致某些参数的估计方差极大。
  • 加速度要滤波 通常由位置二阶差分得到,噪声极大,必须使用零相位滤波(如 filtfilt)以避免引入相位延迟。
  • 物理可行性约束。辨识结果应满足质量为正、惯量张量正定且满足三角不等式。可以把辨识写成带线性矩阵不等式约束的半定规划,保证参数物理可实现。

动力学在控制中的应用

重力补偿

最简单也最常用的应用:在控制律中加入 抵消重力,使 PD 控制器不必用稳态误差换取重力平衡:

可以证明(利用斜对称性构造 Lyapunov 函数),只要 正定且重力补偿准确,该控制律对定点镇定是全局渐近稳定的,且不依赖于 的准确性。这解释了为什么重力补偿是性价比最高的动力学应用——它也是协作机器人"手动拖动示教"功能的实现基础。

计算力矩控制

计算力矩控制(Computed Torque Control)用完整动力学模型做反馈线性化:

其中 。代入动力学方程后,若模型完全准确,闭环误差动力学变为解耦的线性系统:

于是可以用极点配置直接设定每个关节的响应特性。实践中模型误差不可避免,需要配合鲁棒项或自适应控制;且该方法要求机器人支持力矩控制接口,多数位置控制型工业机械臂无法使用。

操作空间控制

Khatib 的操作空间公式(Operational Space Formulation)把动力学投影到笛卡尔空间:

称为操作空间惯量矩阵,描述末端在各方向的等效惯量。控制律为:

其中 分别为操作空间的科氏项与重力项,第二项是零空间力矩,用于冗余机械臂的次要任务。这是阻抗控制与人形机器人全身控制的理论框架,详见 雅可比矩阵与奇异性 中的静力学对偶讨论。

代码实现

用 Pinocchio 计算

Pinocchio 是目前性能最好的开源刚体动力学库,实现了 RNEA、ABA、CRBA 及其解析导数:

import pinocchio as pin
import numpy as np

model = pin.buildModelFromUrdf('robot.urdf')
data = model.createData()

q = pin.randomConfiguration(model)
v = np.random.randn(model.nv) * 0.5
a = np.random.randn(model.nv) * 0.5

# 逆动力学:RNEA,O(n)
tau = pin.rnea(model, data, q, v, a)

# 质量矩阵:CRBA
M = pin.crba(model, data, q)

# 重力项
g = pin.computeGeneralizedGravity(model, data, q)

# 非线性项 C(q,v)v + g(q)
nle = pin.nonLinearEffects(model, data, q, v)

# 正动力学:ABA,O(n)
a_fd = pin.aba(model, data, q, v, tau)

print('逆动力学-正动力学一致性误差:', np.abs(a_fd - a).max())
print('分解式误差:', np.abs(M @ a + nle - tau).max())

# 验证质量矩阵对称正定
print('对称性误差:', np.abs(M - M.T).max())
print('最小特征值:', np.linalg.eigvalsh(M).min())

平面两连杆的显式动力学

import numpy as np


class TwoLinkArm:
    def __init__(self, m1=1.0, m2=1.0, l1=0.5, l2=0.4,
                 I1=0.02, I2=0.015, g=9.81):
        self.lc1, self.lc2 = l1 / 2, l2 / 2
        self.m1, self.m2, self.l1, self.g = m1, m2, l1, g
        self.alpha = I1 + I2 + m1 * self.lc1 ** 2 + m2 * (l1 ** 2 + self.lc2 ** 2)
        self.beta = m2 * l1 * self.lc2
        self.delta = I2 + m2 * self.lc2 ** 2

    def mass_matrix(self, q):
        c2 = np.cos(q[1])
        return np.array([
            [self.alpha + 2 * self.beta * c2, self.delta + self.beta * c2],
            [self.delta + self.beta * c2,     self.delta],
        ])

    def coriolis(self, q, dq):
        s2 = np.sin(q[1])
        return np.array([
            -self.beta * s2 * (2 * dq[0] * dq[1] + dq[1] ** 2),
            self.beta * s2 * dq[0] ** 2,
        ])

    def gravity(self, q):
        m1, m2, l1, g = self.m1, self.m2, self.l1, self.g
        return np.array([
            (m1 * self.lc1 + m2 * l1) * g * np.cos(q[0])
            + m2 * self.lc2 * g * np.cos(q[0] + q[1]),
            m2 * self.lc2 * g * np.cos(q[0] + q[1]),
        ])

    def inverse_dynamics(self, q, dq, ddq):
        return self.mass_matrix(q) @ ddq + self.coriolis(q, dq) + self.gravity(q)

    def forward_dynamics(self, q, dq, tau):
        rhs = tau - self.coriolis(q, dq) - self.gravity(q)
        return np.linalg.solve(self.mass_matrix(q), rhs)


if __name__ == '__main__':
    arm = TwoLinkArm()
    q = np.array([0.3, 0.8])
    dq = np.array([0.5, -0.4])
    ddq = np.array([1.0, 0.7])

    tau = arm.inverse_dynamics(q, dq, ddq)
    print('所需关节力矩 (N·m):', np.round(tau, 4))
    print('往返一致性:', np.abs(arm.forward_dynamics(q, dq, tau) - ddq).max())

    # 重力补偿演示:静止时抵消重力所需力矩
    print('重力补偿力矩 (N·m):', np.round(arm.gravity(q), 4))

仿真器中的动力学

不同仿真器在动力学求解上的取舍不同,直接影响 sim-to-real 的效果:

仿真器 求解器 接触模型 特点
MuJoCo 广义坐标 + 凸优化 软接触(Soft Contact) 接触求解稳定、可微,适合强化学习与轨迹优化
PyBullet 广义坐标(Featherstone) LCP / 顺序冲量 开源易用,接触参数需仔细调节
Gazebo ODE / Bullet / DART 刚性接触 与 ROS 集成最好,物理精度依赖后端
Isaac Sim / Isaac Lab PhysX(GPU) 刚性接触 GPU 并行数千环境,适合大规模 RL 训练
Drake 广义坐标 + 凸接触 水弹性(Hydroelastic) 接触面而非接触点,物理保真度高

需要注意的是:接触动力学是 sim-to-real 差距的主要来源。刚体动力学本身(无接触时)在各仿真器中高度一致,但摩擦系数、恢复系数、接触刚度等参数难以准确标定,这也是抓取与行走任务的策略难以直接迁移到实机的原因,相关的域随机化方法见 强化学习在机器人中的部署

参考资料

  1. Craig, J. J. (2005). Introduction to Robotics: Mechanics and Control (3rd ed.). Pearson Prentice Hall. — 第 6 章推导拉格朗日与牛顿-欧拉方法。
  2. Featherstone, R. (2008). Rigid Body Dynamics Algorithms. Springer. — RNEA、ABA、CRBA 的权威论述。
  3. Siciliano, B., Sciavicco, L., Villani, L. & Oriolo, G. (2010). Robotics: Modelling, Planning and Control. Springer. — 第 7、8 章讨论动力学与运动控制。
  4. Khatib, O. (1987). A Unified Approach for Motion and Force Control of Robot Manipulators: The Operational Space Formulation. IEEE Journal of Robotics and Automation, 3(1), 43-53.
  5. Khosla, P. K. & Kanade, T. (1985). Parameter Identification of Robot Dynamics. IEEE Conference on Decision and Control, 1754-1760.
  6. Gautier, M. & Khalil, W. (1990). Direct Calculation of Minimum Set of Inertial Parameters of Serial Robots. IEEE Transactions on Robotics and Automation, 6(3), 368-373.
  7. Olsson, H., Åström, K. J., Canudas de Wit, C., Gäfvert, M. & Lischinsky, P. (1998). Friction Models and Friction Compensation. European Journal of Control, 4(3), 176-195.
  8. Carpentier, J., et al. (2019). The Pinocchio C++ Library. IEEE/SICE International Symposium on System Integration.