Part II · 第 8 章 动力学 · 8.2Part II · Ch. 8 Dynamics · 8.2

牛顿-欧拉递推Recursive Newton–Euler

机器人仿真器和 1 kHz 的力矩控制器每个周期都要回答同一个问题:关节要出多大力矩,才能让每根连杆按指定的加速度运动?拉格朗日方程给出了答案,但符号展开会随自由度爆炸。递推牛顿-欧拉算法 (RNEA) 换了一种想法:把牛顿第二定律和欧拉方程逐根连杆写下来,先从基座向末端把速度和加速度一级一级传出去,再从末端向基座把力和力矩一级一级收回来,计算量只与关节数 \(n\) 成正比。 A robot simulator and a 1 kHz torque controller ask the same question every cycle: what torque must each joint supply so that every link moves with the prescribed acceleration? The Lagrange equations answer it, but their symbolic expansion explodes with the number of joints. The recursive Newton–Euler algorithm (RNEA) takes another route: write Newton's second law and Euler's equation link by link, pass velocities and accelerations outward from the base one link at a time, then pass forces and moments back inward from the tip, at a cost proportional to the number of joints \(n\).

约 35 分钟~35 min 前置:1.8 叉积 · 5.8 伴随 · 5.10 PoE · 7.4 速度运动学 · 7.6 静力学与 wrench · 8.1 拉格朗日动力学Prereqs: 1.8 Cross Product · 5.8 Adjoint · 5.10 PoE · 7.4 Velocity Kinematics · 7.6 Statics & Wrenches · 8.1 Lagrangian Dynamics 6 个交互6 interactives

    1为什么机器人需要它Why robots need this

    8.1 节用拉格朗日方程得到了动力学方程 \(M(\mathbf q)\ddot{\mathbf q}+C(\mathbf q,\dot{\mathbf q})\dot{\mathbf q}+\mathbf g(\mathbf q)=\boldsymbol\tau\)(第 8 章始终用 \(\mathbf q=(\theta_1,\dots,\theta_n)\) 表示关节坐标,偏置项记作 \(\mathbf b=C\dot{\mathbf q}+\mathbf g\))。真实的机器人软件需要的是它的两种"算法形式":

    • 逆动力学 \(\boldsymbol\tau=\mathrm{ID}(\mathbf q,\dot{\mathbf q},\ddot{\mathbf q})\):给定想要的运动,算出需要的力矩。力矩前馈、计算力矩控制(Part IV)、重力补偿、从关节电流估计接触力,用的都是它。
    • 正动力学 \(\ddot{\mathbf q}=\mathrm{FD}(\mathbf q,\dot{\mathbf q},\boldsymbol\tau)\):给定力矩,算出机器人会怎么动。物理仿真器每个时间步都在积分它。

    7 自由度的机械臂要在 1 kHz 下算,30 多个自由度的人形机器人也一样。对一个 6 轴机械臂手推拉格朗日方程,\(M\)、\(C\) 的符号展开已经要写满好几页;自由度再多,项数增长得更快,没有人会把它们手抄进控制器。递推牛顿-欧拉算法(Luh–Walker–Paul,1980)的特点是:没有任何符号展开,每根连杆只做固定次数的向量运算,所以总计算量是 \(O(n)\)。

    它的思想朴素到几乎是常识:每根连杆都是一个刚体,刚体满足 \(\mathbf F=m\mathbf a\) 和欧拉方程;连杆之间的相互作用力只通过关节传递。于是先向外传运动,再向内传力,一趟就算完。

    Lesson 8.1 derived the equations of motion \(M(\mathbf q)\ddot{\mathbf q}+C(\mathbf q,\dot{\mathbf q})\dot{\mathbf q}+\mathbf g(\mathbf q)=\boldsymbol\tau\) from the Lagrange equations (throughout Chapter 8, \(\mathbf q=(\theta_1,\dots,\theta_n)\) collects the joint coordinates and \(\mathbf b=C\dot{\mathbf q}+\mathbf g\) is the bias term). Real robot software needs two algorithmic forms of them:

    • Inverse dynamics \(\boldsymbol\tau=\mathrm{ID}(\mathbf q,\dot{\mathbf q},\ddot{\mathbf q})\): given the motion you want, compute the torques it takes. Torque feed-forward, computed-torque control (Part IV), gravity compensation and estimating contact forces from motor currents all use it.
    • Forward dynamics \(\ddot{\mathbf q}=\mathrm{FD}(\mathbf q,\dot{\mathbf q},\boldsymbol\tau)\): given the torques, compute how the robot will move. A physics simulator integrates it at every time step.

    A 7-joint arm must evaluate these at 1 kHz, and so must a humanoid with 30-odd joints. Expanding \(M\) and \(C\) symbolically for a 6-axis arm already fills pages, and the number of terms grows faster still with more joints; nobody copies that into a controller. The recursive Newton–Euler algorithm (Luh–Walker–Paul, 1980) has no symbolic expansion at all: every link costs a fixed number of vector operations, so the total cost is \(O(n)\).

    The idea is almost common sense. Every link is a rigid body obeying \(\mathbf F=m\mathbf a\) and Euler's equation, and neighbouring links interact only through the joint between them. So pass the motion outward, then pass the forces inward, and you are done in one sweep each way.

    2直觉:向外传运动,向内传力Intuition: motion goes out, force comes back

    先想一条鞭子。你抖动手腕(关节 1),整根鞭子的运动是一级一级传下去的:第 \(i\) 段的运动,等于第 \(i-1\) 段已经有的运动,再加上关节 \(i\) 自己多转的那一部分。这就是向前递推 (forward pass),只涉及运动学:角速度 \(\omega_i\)、角加速度 \(\alpha_i\)、质心加速度 \(\mathbf a_{c_i}\)。

    质心加速度怎么来的?7.4 节和 1.8 节的刚体速度公式再求一次导:刚体上离参考点 \(\mathbf r\) 处的一点,加速度是

    Think of a whip. You flick your wrist (joint 1), and the motion travels down the whip one segment at a time: segment \(i\) does whatever segment \(i-1\) is already doing, plus whatever joint \(i\) adds by turning. This is the forward pass, and it is pure kinematics: angular velocity \(\omega_i\), angular acceleration \(\alpha_i\), and the acceleration \(\mathbf a_{c_i}\) of the link's centre of mass.

    Where does the centre-of-mass acceleration come from? Differentiate the rigid-body velocity formula of Lessons 7.4 and 1.8 once more: for a point at offset \(\mathbf r\) from a reference point of a rigid body, the acceleration is

    $$ \mathbf a_{p} \;=\; \hl{inh}{\mathbf a_{o}} \;+\; \hl{euler}{\alpha\,\hat{\mathbf z}\times\mathbf r} \;-\; \hl{centri}{\omega^{2}\,\mathbf r}. $$

    三项各有各的含义:继承项(参考点自己的加速度)、欧拉项(角加速度造成的切向加速度,垂直于 \(\mathbf r\))、向心项(匀速转动也有,指向转轴)。下面的 FIG 1 用三根箭头把这三项接在一起,合成的琥珀色箭头就是质心加速度。点"下一步",让递推从基座走到末端。

    The three terms mean three different things: the inherited term (the reference point's own acceleration), the Euler term (tangential, caused by angular acceleration, perpendicular to \(\mathbf r\)) and the centripetal term (present even at constant spin, pointing at the axis). FIG 1 chains the three arrows head to tail, and the amber arrow they add up to is the centre-of-mass acceleration. Press "Next" to let the recursion walk from the base to the tip.

    FIG 1向前递推:速度与加速度逐级外传Forward pass: velocities and accelerations go outward
    平面三连杆臂,均匀细杆:长度 1.0 / 0.8 / 0.5 m,质量 2.0 / 1.6 / 1.0 kg(密度 2 kg/m),质心在杆的中点。灰色箭头是继承的加速度,紫色是欧拉项 \(\alpha\hat{\mathbf z}\times\mathbf r_c\),蓝色是向心项 \(-\omega^2\mathbf r_c\),琥珀色虚线箭头是三者之和 \(\mathbf a_c\),青色细箭头是质心速度。加速度箭头的比例尺显示在读数里。圆弧是 \(\omega_i\)。拖动关节上的圆圈改变姿态。 A planar three-link arm of uniform rods: lengths 1.0 / 0.8 / 0.5 m, masses 2.0 / 1.6 / 1.0 kg (2 kg/m), centres of mass at the midpoints. Grey is the inherited acceleration, purple the Euler term \(\alpha\hat{\mathbf z}\times\mathbf r_c\), blue the centripetal term \(-\omega^2\mathbf r_c\); the dashed amber arrow is their sum \(\mathbf a_c\), the thin cyan arrow the centre-of-mass velocity. The arrow scale is shown in the readout, and the arc is \(\omega_i\). Drag the circles on the joints to change the posture.
    试一试Try this
    • 点"下一步",一直走到第 3 根连杆。外面的连杆为什么一直"带着"里面所有关节的角速度?Press "Next" until the recursion reaches link 3. Why does an outer link always "carry" the angular velocities of every joint inside it?
    • 把所有 \(\ddot\theta\) 设为 0(按钮"θ̈ = 0"),而让第 3 根连杆的质心仍有大于 0.5 m/s² 的加速度。没有任何东西在加速,加速度从哪来?Set every \(\ddot\theta\) to 0 (the "θ̈ = 0" button) while the centre of mass of link 3 still accelerates by more than 0.5 m/s². Nothing is speeding up, so where does the acceleration come from?
    核心洞见Key insight

    向前递推只需要"上一根连杆的结果"和"本关节的 \(\theta,\dot\theta,\ddot\theta\)",每根连杆做固定多的运算。不管链有多长,每一级都只看它的邻居,所以总代价与 \(n\) 成正比。

    The forward pass needs only "the result for the previous link" and "this joint's \(\theta,\dot\theta,\ddot\theta\)", and does a fixed amount of work per link. However long the chain, each stage looks only at its neighbour, so the total cost is proportional to \(n\).

    3动手玩:向后递推,一根连杆一张受力图Play: the backward pass, one free-body diagram per link

    运动都知道了,质心加速度 \(\mathbf a_{c_i}\) 和角加速度 \(\alpha_i\) 已经在手里。现在反过来,从末端往基座走。取出第 \(i\) 根连杆,只看它受到的力:

    • 关节 \(i\) 处,前一根连杆通过关节推它:力 \(\mathbf f_i\),力矩 \(\boldsymbol\mu_i\);
    • 关节 \(i+1\) 处,后一根连杆反推它:由牛顿第三定律,是 \(-\mathbf f_{i+1}\) 和 \(-\boldsymbol\mu_{i+1}\);
    • 重力 \(m_i\mathbf g\) 作用在质心。

    这条连杆做 \(\mathbf a_{c_i}\) 的运动,所以三个力之和必须等于 \(m_i\mathbf a_{c_i}\):只有 \(\mathbf f_i\) 是未知的,立刻解出。力矩平衡同理解出 \(\boldsymbol\mu_i\)。而关节 \(i\) 的电机在转轴方向上出的力矩,正好就是 \(\tau_i=\mu_i\)。算完 \(\mathbf f_i,\boldsymbol\mu_i\),它们就是下一根(更靠近基座的)连杆要用的 \(\mathbf f_{i+1},\boldsymbol\mu_{i+1}\)。末端是递推的起点:手爪对环境施加的力 \(\mathbf F_{\text{tip}}\) 就是 \(\mathbf f_{n+1}\)(空载时为 0)。

    The motion is known: we hold every \(\mathbf a_{c_i}\) and \(\alpha_i\). Now walk the other way, from the tip toward the base. Cut out link \(i\) and look only at the forces on it:

    • at joint \(i\), the previous link pushes on it: force \(\mathbf f_i\), moment \(\boldsymbol\mu_i\);
    • at joint \(i+1\), the next link pushes back: by Newton's third law, \(-\mathbf f_{i+1}\) and \(-\boldsymbol\mu_{i+1}\);
    • gravity \(m_i\mathbf g\) acts at the centre of mass.

    The link moves with \(\mathbf a_{c_i}\), so the three forces must add up to \(m_i\mathbf a_{c_i}\): only \(\mathbf f_i\) is unknown, so solve for it at once. Moment balance gives \(\boldsymbol\mu_i\) the same way. The motor at joint \(i\) supplies, about the joint axis, exactly \(\tau_i=\mu_i\). Once \(\mathbf f_i,\boldsymbol\mu_i\) are known they play the role of \(\mathbf f_{i+1},\boldsymbol\mu_{i+1}\) for the next link inward. The tip starts the recursion: the force \(\mathbf F_{\text{tip}}\) that the gripper exerts on the environment is \(\mathbf f_{n+1}\) (zero when the arm carries nothing).

    FIG 2向后递推:受力图与关节力矩Backward pass: free-body diagrams and joint torques
    τ₁
    τ₂
    τ₃
    同一条三连杆臂。"下一步"从末端开始,逐根连杆画出受力图:关节 \(i\) 处的 \(\mathbf f_i\)(用关节的颜色),关节 \(i+1\) 处的 \(-\mathbf f_{i+1}\),质心处的重力(紫色)和合力 \(m\mathbf a\)(青色虚线)。圆弧是力矩 \(\mu_i\) 与 \(-\mu_{i+1}\) 的方向。拖动琥珀色手柄设定手爪施加给环境的力 \(\mathbf F_{\text{tip}}\)(1 m ↔ 10 N),拖动关节圆圈改变姿态,滑块设定 \(\dot\theta,\ddot\theta\)。"全部显示"画出每个关节处的 \(\mathbf f_i\)。手爪力为 0 时琥珀色手柄与第 3 个关节圆圈重合(优先抓到力的手柄),先把它拖开。 The same three-link arm. "Next" starts at the tip and draws one free-body diagram at a time: \(\mathbf f_i\) at joint \(i\) (in the joint's colour), \(-\mathbf f_{i+1}\) at joint \(i+1\), gravity at the centre of mass (purple) and the net force \(m\mathbf a\) (dashed cyan). The arcs show the directions of \(\mu_i\) and \(-\mu_{i+1}\). Drag the amber handle to set the force \(\mathbf F_{\text{tip}}\) that the tip exerts on the environment (1 m ↔ 10 N), drag the joint circles to change the posture, and use the sliders for \(\dot\theta,\ddot\theta\). "Show all" draws \(\mathbf f_i\) at every joint. When the force is 0 the amber handle sits on the joint-3 circle (and gets grabbed first), so drag it away first.
    • 点"下一步",从末端走到关节 1,让三个力矩都出现。哪个关节的力矩最大?为什么?Press "Next" from the tip to joint 1 until all three torques appear. Which joint carries the largest torque, and why?
    • 按"静止"(\(\dot\theta=\ddot\theta=0\)),手爪力为 0,打开重力,把手臂摆成竖直向上。三个力矩都应当接近 0(\(\max|\tau|<0.3\))。这是稳定平衡吗?Press "At rest" (\(\dot\theta=\ddot\theta=0\)), keep the tip force at 0, gravity on, and stand the arm straight up. All three torques should be near 0 (\(\max|\tau|<0.3\)). Is that a stable equilibrium?
    • 用手爪力把 \(\tau_1\) 调到几乎为 0(\(|\tau_1|<0.4\)),同时 \(\|\mathbf F_{\text{tip}}\|\ge 1\) N。\(\mathbf F_{\text{tip}}\) 对基座的力矩在抵消什么?(提示:先按“静止”,姿态接近竖直时重力力矩小,手爪力够用。)Use the tip force to bring \(\tau_1\) almost to 0 (\(|\tau_1|<0.4\)) while \(\|\mathbf F_{\text{tip}}\|\ge 1\) N. What is the moment of \(\mathbf F_{\text{tip}}\) about the base cancelling? (Hint: press “At rest” first; near an upright posture the gravity torque is small enough for the tip force to cancel.)
    静力学是它的特例Statics is a special case

    令 \(\dot\theta=\ddot\theta=0\),向后递推就只剩重力和手爪力。读数里的"\(\mathrm{RNEA}(\mathbf F)-\mathrm{RNEA}(0)-J^\top\mathbf F\)"检验了这一点:手爪力引起的力矩恰好是 3.4 节的 \(J^\top\mathbf F\)(7.6 节把它推广到 wrench)。RNEA 对 \(\mathbf F_{\text{tip}}\) 是线性的,所以这个差在任何运动状态下都成立。

    Set \(\dot\theta=\ddot\theta=0\) and the backward pass is left with only gravity and the tip force. The readout "\(\mathrm{RNEA}(\mathbf F)-\mathrm{RNEA}(0)-J^\top\mathbf F\)" checks this: the torque caused by the tip force is exactly Lesson 3.4's \(J^\top\mathbf F\) (7.6 extends it to wrenches). RNEA is linear in \(\mathbf F_{\text{tip}}\), so the difference holds in any state of motion.

    4第二、第三视角:它就是拉格朗日方程Second and third views: it is the Lagrange equation

    递推 = 拉格朗日?Recursion = Lagrange?

    牛顿-欧拉从"力平衡"出发,拉格朗日从"能量"出发,两条路没有共同的中间步骤,却应当给出同一个 \(\boldsymbol\tau\)。FIG 3 把它们放在一起比:一边是 RNEA 的递推结果,另一边是完全独立写成的 \(M(\mathbf q)\ddot{\mathbf q}+C(\mathbf q,\dot{\mathbf q})\dot{\mathbf q}+\mathbf g(\mathbf q)\),其中 \(M=\sum_i\big(m_iJ_{c_i}^\top J_{c_i}+I_iJ_{\omega_i}^\top J_{\omega_i}\big)\)(质心雅可比,8.3 节详细讲)、\(C\) 由 \(M\) 的偏导数(Christoffel 符号)得到、\(\mathbf g=\sum_i m_iJ_{c_i}^\top(0,g)^\top\)。右图把力矩拆成三块:惯性 \(M\ddot{\mathbf q}\)、速度项 \(C\dot{\mathbf q}\)、重力 \(\mathbf g\),三块首尾相接,应当恰好落在 RNEA 的琥珀色菱形上。两连杆时还会和 8.1 节的闭式解比较。

    Newton–Euler starts from force balance and Lagrange from energy; the two routes share no intermediate step, yet they must give the same \(\boldsymbol\tau\). FIG 3 sets them side by side: on one side the RNEA result; on the other a fully independent evaluation of \(M(\mathbf q)\ddot{\mathbf q}+C(\mathbf q,\dot{\mathbf q})\dot{\mathbf q}+\mathbf g(\mathbf q)\), with \(M=\sum_i\big(m_iJ_{c_i}^\top J_{c_i}+I_iJ_{\omega_i}^\top J_{\omega_i}\big)\) (centre-of-mass Jacobians, detailed in Lesson 8.3), \(C\) from the partial derivatives of \(M\) (Christoffel symbols) and \(\mathbf g=\sum_i m_iJ_{c_i}^\top(0,g)^\top\). The right panel splits the torque into three pieces: inertia \(M\ddot{\mathbf q}\), velocity terms \(C\dot{\mathbf q}\) and gravity \(\mathbf g\); chained head to tail they must land exactly on RNEA's amber diamond. For two links the closed form from Lesson 8.1 is checked as well.

    FIG 3RNEA = 拉格朗日RNEA = Lagrange
    姿态(拖动圆圈)POSTURE (drag the circles)
    右图每行一个关节:红色是 \(M\ddot{\mathbf q}\),紫色是 \(C\dot{\mathbf q}\),蓝色是 \(\mathbf g\),沿水平方向(N·m)首尾相接;琥珀色菱形是 RNEA 给出的 \(\tau_i\)。"最大差"是 RNEA 与独立拉格朗日计算之间的最大绝对误差,只来自浮点舍入。"随机状态"每次随机抽取 \(\mathbf q,\dot{\mathbf q},\ddot{\mathbf q}\)。 One row per joint on the right: red is \(M\ddot{\mathbf q}\), purple \(C\dot{\mathbf q}\), blue \(\mathbf g\), chained horizontally (N·m); the amber diamond is RNEA's \(\tau_i\). "Max difference" is the largest absolute gap between RNEA and the independent Lagrangian evaluation, which is only floating-point rounding. "Random state" draws fresh \(\mathbf q,\dot{\mathbf q},\ddot{\mathbf q}\) each time.
    • 连按 5 次"随机状态"。每次两种算法都吻合到 \(10^{-10}\) 以内吗?Press "Random state" five times. Do the two algorithms agree to within \(10^{-10}\) every time?
    • 关掉重力,设 \(\ddot\theta=0\),让各关节以非零速度转动,使 \(\|\boldsymbol\tau\|>0.3\)。没有加速度、没有重力,为什么还需要力矩?Switch gravity off, set \(\ddot\theta=0\) and let the joints spin with nonzero rates so that \(\|\boldsymbol\tau\|>0.3\). With no acceleration and no gravity, why is any torque needed?

    用 RNEA 一列一列地造出质量矩阵Building the mass matrix from RNEA, one column at a time

    RNEA 是 \(\boldsymbol\tau\) 的黑盒,而 \(\boldsymbol\tau=M\ddot{\mathbf q}+\mathbf b\),其中 \(\mathbf b=C\dot{\mathbf q}+\mathbf g\) 与 \(\ddot{\mathbf q}\) 无关。令 \(\dot{\mathbf q}=0\),再令 \(\ddot{\mathbf q}=\mathbf e_j\)(只有关节 \(j\) 单位加速),有 \(\mathrm{RNEA}(\mathbf q,0,\mathbf e_j)=M\mathbf e_j+\mathbf g\),也就是 \(M\) 的第 \(j\) 列加上重力项;再算一次 \(\mathrm{RNEA}(\mathbf q,0,0)=\mathbf g\),相减:

    RNEA is a black box for \(\boldsymbol\tau\), and \(\boldsymbol\tau=M\ddot{\mathbf q}+\mathbf b\) with \(\mathbf b=C\dot{\mathbf q}+\mathbf g\) independent of \(\ddot{\mathbf q}\). Set \(\dot{\mathbf q}=0\) and \(\ddot{\mathbf q}=\mathbf e_j\) (unit acceleration of joint \(j\) only): \(\mathrm{RNEA}(\mathbf q,0,\mathbf e_j)=M\mathbf e_j+\mathbf g\), the \(j\)-th column of \(M\) plus the gravity term. One more call, \(\mathrm{RNEA}(\mathbf q,0,0)=\mathbf g\), and subtract:

    $$ M(\mathbf q)\,\mathbf e_j \;=\; \mathrm{RNEA}(\mathbf q,\,0,\,\mathbf e_j)\;-\;\mathrm{RNEA}(\mathbf q,\,0,\,0),\qquad j=1,\dots,n. $$

    这就是 Walker–Orin(1982)的想法:用 \(n\) 次(关掉重力就只要 \(n\) 次,开着重力是 \(n+1\) 次)\(O(n)\) 的 RNEA 调用拼出 \(M\),再解线性方程 \(M\ddot{\mathbf q}=\boldsymbol\tau-\mathbf b\),就得到正动力学,其中 \(\mathbf b=\mathrm{RNEA}(\mathbf q,\dot{\mathbf q},0)\)。FIG 4 一列一列地做这件事。

    This is the Walker–Orin (1982) idea: assemble \(M\) from \(n\) calls of the \(O(n)\) RNEA (\(n\) if gravity is off, \(n+1\) with gravity on), then solve the linear system \(M\ddot{\mathbf q}=\boldsymbol\tau-\mathbf b\) with \(\mathbf b=\mathrm{RNEA}(\mathbf q,\dot{\mathbf q},0)\) and you have forward dynamics. FIG 4 does it column by column.

    FIG 4逐列拼出 \(M(\mathbf q)\)Filling in \(M(\mathbf q)\) column by column
    M₁ⱼ
    M₂ⱼ
    M₃ⱼ
    左图:让关节 \(j\) 以 \(1\ \mathrm{rad/s^2}\) 加速、其余关节不加速(\(\dot\theta=0\)),琥珀色箭头是各连杆质心此时的加速度(0.5 m ↔ 1 m/s²),紫色圆弧是关节 \(j\) 的加速度。右侧的三个条是这次实验所需的关节力矩减去重力项,即 \(M\) 的第 \(j\) 列。切换"重力"可以看到:开着重力时,两次调用的重力项相互抵消,\(M\) 不变。 Left: joint \(j\) accelerates at \(1\ \mathrm{rad/s^2}\) while the others do not (\(\dot\theta=0\)); the amber arrows are the resulting accelerations of the link centres of mass (0.5 m ↔ 1 m/s²) and the purple arc is joint \(j\)'s acceleration. The three bars on the right are the joint torques of this experiment minus the gravity term: column \(j\) of \(M\). Toggle gravity: with it on, the gravity terms of the two calls cancel and \(M\) does not change.
    • 依次点出三列,让矩阵完整。核对:它是对称的吗?Reveal all three columns until the matrix is complete. Check: is it symmetric?
    • 拖动关节,把手臂折叠起来,使 \(M\) 出现一个小于 \(-0.1\) 的非对角元,同时最小特征值仍是正的。惯性耦合的符号为什么会变?Drag the joints and fold the arm so that an off-diagonal entry of \(M\) drops below \(-0.1\) while the smallest eigenvalue stays positive. Why does the sign of an inertial coupling change?
    一个思想,几种看法One idea, several views

    力的视角:每根连杆受力平衡,力沿着链向内累加(RNEA)。能量的视角:写出总动能 \(T=\tfrac12\dot{\mathbf q}^\top M\dot{\mathbf q}\) 和势能,求导(拉格朗日,8.1 节)。矩阵的视角:同一个映射 \((\mathbf q,\dot{\mathbf q},\ddot{\mathbf q})\mapsto\boldsymbol\tau\),对 \(\ddot{\mathbf q}\) 是仿射的,斜率就是 \(M\)。计算的视角:RNEA 是一个"黑盒函数",有了函数就能用有限次调用恢复出 \(M\),这是现代库(Pinocchio、RBDL、Drake)里"一个核心,多个接口"的设计原因。

    Force view: every link is in force balance and forces accumulate inward along the chain (RNEA). Energy view: write the total kinetic energy \(T=\tfrac12\dot{\mathbf q}^\top M\dot{\mathbf q}\) and the potential energy, then differentiate (Lagrange, Lesson 8.1). Matrix view: the same map \((\mathbf q,\dot{\mathbf q},\ddot{\mathbf q})\mapsto\boldsymbol\tau\) is affine in \(\ddot{\mathbf q}\), and its slope is \(M\). Computational view: RNEA is a black-box function, and a finite number of calls recovers \(M\); that is why modern libraries (Pinocchio, RBDL, Drake) are built as "one core, many interfaces".

    5再看数学The math

    提示:把鼠标悬停在公式中带底色的符号上,FIG 1 与 FIG 2 里对应的箭头会被加粗。Tip: hover the highlighted symbols in the formulas; the matching arrows in FIG 1 and FIG 2 are drawn thicker.

    平面 RNEA 全貌The planar RNEA in full

    平面 \(n\) 连杆臂,所有转轴垂直于纸面,\(\theta_i\) 是关节角。第 \(i\) 根连杆:质量 \(m_i\),质心处的转动惯量 \(I_i\)(均匀细杆是 \(m_il_i^2/12\)),\(\mathbf r_i\) 为关节 \(i\) 指向关节 \(i+1\) 的向量,\(\mathbf r_{c_i}\) 为关节 \(i\) 指向质心的向量。所有向量都写在世界系里。角量是标量,叉积 \(\mathbf a\times\mathbf b=a_xb_y-a_yb_x\) 也是标量。记 \(\omega_0=\alpha_0=0\),\(\mathbf a_1\) 是关节 1(基座)的加速度,先取 \(\mathbf a_1=(0,\,g)\)(原因见下面的"重力技巧")。

    向前(\(i=1\to n\)):

    A planar \(n\)-link arm with every axis perpendicular to the page and joint angles \(\theta_i\). Link \(i\) has mass \(m_i\) and moment of inertia \(I_i\) about its centre of mass (\(m_il_i^2/12\) for a uniform rod); \(\mathbf r_i\) points from joint \(i\) to joint \(i+1\) and \(\mathbf r_{c_i}\) from joint \(i\) to the centre of mass. All vectors are written in the world frame. Angular quantities are scalars, and so is the cross product \(\mathbf a\times\mathbf b=a_xb_y-a_yb_x\). Take \(\omega_0=\alpha_0=0\), let \(\mathbf a_1\) be the acceleration of joint 1 (the base), and for now set \(\mathbf a_1=(0,\,g)\) (the reason is in "the gravity trick" below).

    Forward (\(i=1\to n\)):

    $$ \begin{aligned} \hl{omega}{\omega_i} &= \omega_{i-1}+\dot\theta_i, \qquad \alpha_i = \alpha_{i-1}+\ddot\theta_i,\\ \mathbf a_{c_i} &= \hl{inh}{\mathbf a_i} + \hl{euler}{\alpha_i\hat{\mathbf z}\times\mathbf r_{c_i}} - \hl{centri}{\omega_i^2\,\mathbf r_{c_i}},\\ \mathbf a_{i+1} &= \mathbf a_i + \alpha_i\hat{\mathbf z}\times\mathbf r_i - \omega_i^2\,\mathbf r_i . \end{aligned} $$

    向后(\(i=n\to1\)):起点 \(\mathbf f_{n+1}=\mathbf F_{\text{tip}}\)(手爪施加给环境的力),\(\mu_{n+1}=0\)。

    Backward (\(i=n\to1\)): start from \(\mathbf f_{n+1}=\mathbf F_{\text{tip}}\) (the force the tip exerts on the environment) and \(\mu_{n+1}=0\).

    $$ \begin{aligned} \hl{force}{\mathbf f_i} &= \mathbf f_{i+1} + m_i\,\mathbf a_{c_i},\\ \hl{moment}{\mu_i} &= \mu_{i+1} + I_i\alpha_i + \mathbf r_{c_i}\times\mathbf f_i + (\mathbf r_i-\mathbf r_{c_i})\times\mathbf f_{i+1},\\ \tau_i &= \mu_i . \end{aligned} $$

    来源。第 \(i\) 根连杆受到 \(\mathbf f_i\)(作用在关节 \(i\))、\(-\mathbf f_{i+1}\)(作用在关节 \(i+1\))和重力 \(m_i\mathbf g\)。牛顿第二定律:\(\mathbf f_i-\mathbf f_{i+1}+m_i\mathbf g=m_i\mathbf a^{\text{真实}}_{c_i}\)。把重力移到右边,\(\mathbf f_i-\mathbf f_{i+1}=m_i(\mathbf a^{\text{真实}}_{c_i}-\mathbf g)\),括号里就是上面递推里的 \(\mathbf a_{c_i}\)(见下)。对质心取矩(欧拉方程):\(I_i\alpha_i=\mu_i-\mu_{i+1}+(-\mathbf r_{c_i})\times\mathbf f_i+(\mathbf r_i-\mathbf r_{c_i})\times(-\mathbf f_{i+1})\),移项就是上面的 \(\mu_i\);重力过质心,不产生力矩。

    重力技巧。令 \(\mathbf g=(0,-g)\),把基座当作以 \(\mathbf a_1=-\mathbf g=(0,+g)\) 向上加速。这样每根连杆的质心加速度都多出一个 \(-\mathbf g\),而 \(m_i(\mathbf a^{\text{真实}}_{c_i}-\mathbf g)\) 正好就是 \(m_i\mathbf a_{c_i}\):重力不再需要单独处理。好像你在一部以 \(g\) 向上加速的电梯里,重力和"电梯加速"无法区分。

    平行轴定理。递推用的是质心惯量 \(I_i\)。一根均匀杆绕自己端点的惯量是 \(ml^2/3=ml^2/12+m(l/2)^2\),多出来的 \(m(l/2)^2\) 在递推里已经由叉积项 \(\mathbf r_{c_i}\times m_i\mathbf a_{c_i}\) 提供,不能再算一次。

    检验。静止时(\(\omega=\alpha=0\),\(\mathbf F_{\text{tip}}=0\))\(\mathbf f_i=\sum_{k\ge i}m_k(0,g)\),关节 \(i\) 要托住它外面所有连杆的重量;一根水平的均匀杆 \(\tau=\mathbf r_c\times\mathbf f=(l/2)\,mg\)。

    Where it comes from. Link \(i\) feels \(\mathbf f_i\) (at joint \(i\)), \(-\mathbf f_{i+1}\) (at joint \(i+1\)) and gravity \(m_i\mathbf g\). Newton's second law: \(\mathbf f_i-\mathbf f_{i+1}+m_i\mathbf g=m_i\mathbf a^{\text{true}}_{c_i}\). Moving gravity to the right, \(\mathbf f_i-\mathbf f_{i+1}=m_i(\mathbf a^{\text{true}}_{c_i}-\mathbf g)\), and the bracket is the \(\mathbf a_{c_i}\) of the recursion above (see below). Euler's equation about the centre of mass: \(I_i\alpha_i=\mu_i-\mu_{i+1}+(-\mathbf r_{c_i})\times\mathbf f_i+(\mathbf r_i-\mathbf r_{c_i})\times(-\mathbf f_{i+1})\), which rearranges to the \(\mu_i\) above; gravity acts through the centre of mass and makes no moment.

    The gravity trick. With \(\mathbf g=(0,-g)\), let the base accelerate upward at \(\mathbf a_1=-\mathbf g=(0,+g)\). Every link's centre of mass then picks up an extra \(-\mathbf g\), and \(m_i(\mathbf a^{\text{true}}_{c_i}-\mathbf g)\) is exactly \(m_i\mathbf a_{c_i}\): gravity no longer needs separate handling. It is the elevator argument: in a lift accelerating upward at \(g\), you cannot tell gravity from the acceleration.

    Parallel-axis theorem. The recursion uses the inertia about the centre of mass, \(I_i\). A uniform rod about its end has \(ml^2/3=ml^2/12+m(l/2)^2\); the extra \(m(l/2)^2\) is already supplied by the cross-product term \(\mathbf r_{c_i}\times m_i\mathbf a_{c_i}\) and must not be counted a second time.

    Sanity check. At rest (\(\omega=\alpha=0\), \(\mathbf F_{\text{tip}}=0\)), \(\mathbf f_i=\sum_{k\ge i}m_k(0,g)\): joint \(i\) holds up the weight of everything beyond it; for a horizontal uniform rod, \(\tau=\mathbf r_c\times\mathbf f=(l/2)\,mg\).

    空间版本(Modern Robotics 的写法)The spatial version (the Modern Robotics form)

    三维里角速度、速度、力、力矩都是三维向量,惯量是 \(3\times3\) 矩阵。把它们成对地装进 6 维向量,递推就和平面版长得一样了。约定(与全课一致):twist \(\mathcal V=(\boldsymbol\omega,\mathbf v)\) 角部分在前,wrench \(\mathcal F=(\boldsymbol\mu,\mathbf f)\) 力矩在前。坐标系 \(\{0\}\) 固定在基座;\(\{i\}\) 固定在连杆 \(i\) 上,原点在它的质心;\(M_{i-1,i}\) 是零位 (\(\mathbf q=0\)) 时 \(\{i\}\) 相对 \(\{i-1\}\) 的位姿;\(\mathcal A_i\) 是关节 \(i\) 的螺旋轴在 \(\{i\}\) 系中的表示(5.10 节的 \(S_i\) 经 \(\mathrm{Ad}_{M_{0,i}^{-1}}\) 变到 \(\{i\}\) 中)。则

    In 3D, angular velocity, velocity, force and moment are 3-vectors and the inertia is a \(3\times3\) matrix. Stack them in pairs into 6-vectors and the recursion looks just like the planar one. Conventions (as everywhere in this course): a twist \(\mathcal V=(\boldsymbol\omega,\mathbf v)\) has the angular part first, a wrench \(\mathcal F=(\boldsymbol\mu,\mathbf f)\) the moment first. Frame \(\{0\}\) is fixed to the base; \(\{i\}\) is fixed to link \(i\) with its origin at the centre of mass; \(M_{i-1,i}\) is the pose of \(\{i\}\) in \(\{i-1\}\) at \(\mathbf q=0\); \(\mathcal A_i\) is the screw axis of joint \(i\) expressed in \(\{i\}\) (Lesson 5.10's \(S_i\) carried into \(\{i\}\) by \(\mathrm{Ad}_{M_{0,i}^{-1}}\)). Then

    $$ T_{i,i-1}=e^{-[\mathcal A_i]\theta_i}\,M_{i,i-1}, \qquad \mathcal V_0=0,\quad \dot{\mathcal V}_0=(\mathbf 0,\,-\mathbf g). $$ $$ \begin{aligned} \text{forward:}\quad \mathcal V_i &= \mathrm{Ad}_{T_{i,i-1}}\mathcal V_{i-1} + \mathcal A_i\dot\theta_i,\\ \dot{\mathcal V}_i &= \mathrm{Ad}_{T_{i,i-1}}\dot{\mathcal V}_{i-1} + \mathrm{ad}_{\mathcal V_i}\mathcal A_i\,\dot\theta_i + \mathcal A_i\ddot\theta_i,\\[4pt] \text{backward:}\quad \mathcal F_i &= \mathrm{Ad}_{T_{i+1,i}}^{\top}\mathcal F_{i+1} + \mathcal G_i\dot{\mathcal V}_i - \mathrm{ad}_{\mathcal V_i}^{\top}\mathcal G_i\mathcal V_i,\\ \tau_i &= \mathcal F_i^{\top}\mathcal A_i,\qquad \mathcal G_i=\begin{bmatrix}\mathcal I_i&0\\0&m_i\mathbf 1_3\end{bmatrix}. \end{aligned} $$

    其中 \(\mathcal F_{n+1}\) 是末端坐标系 \(\{n+1\}\) 中手爪对环境的 wrench,\(T_{n+1,n}\) 是常量。各项来源:

    • \(\mathrm{Ad}_{T_{i,i-1}}\mathcal V_{i-1}\):把前一根连杆的 twist 从 \(\{i-1\}\) 搬到 \(\{i\}\)(5.8 节的伴随);\(\mathcal A_i\dot\theta_i\):本关节自己多转出的 twist。这是平面里 \(\omega_i=\omega_{i-1}+\dot\theta_i\) 的 6 维版本。
    • \(\mathrm{ad}_{\mathcal V}\)是 twist 的李括号矩阵:对 \(\mathcal V=(\boldsymbol\omega,\mathbf v)\) 和任意 twist \(\mathcal W\),\([\mathcal V,\mathcal W]=\mathrm{ad}_{\mathcal V}\mathcal W\), \(\mathrm{ad}_{\mathcal V}=\begin{bmatrix}[\boldsymbol\omega]_\times&0\\ [\mathbf v]_\times&[\boldsymbol\omega]_\times\end{bmatrix}\)。它也是伴随的导数:若 \(T(t)=e^{-[\mathcal A]\theta(t)}M\),则 \(\tfrac{d}{dt}\mathrm{Ad}_T=-\dot\theta\,\mathrm{ad}_{\mathcal A}\mathrm{Ad}_T\)。
    • \(\dot{\mathcal V}_i\) 的来源:把 \(\mathcal V_i\) 的式子对时间求导,\(\dot{\mathcal V}_i=\mathrm{Ad}_T\dot{\mathcal V}_{i-1}-\dot\theta_i\,\mathrm{ad}_{\mathcal A_i}\mathrm{Ad}_T\mathcal V_{i-1}+\mathcal A_i\ddot\theta_i\)。用 \(\mathrm{Ad}_T\mathcal V_{i-1}=\mathcal V_i-\mathcal A_i\dot\theta_i\)、\(\mathrm{ad}_{\mathcal A}\mathcal A=0\) 和 \(\mathrm{ad}_{\mathcal X}\mathcal Y=-\mathrm{ad}_{\mathcal Y}\mathcal X\),得到 \(-\dot\theta_i\,\mathrm{ad}_{\mathcal A_i}\mathcal V_i=\mathrm{ad}_{\mathcal V_i}\mathcal A_i\dot\theta_i\),这一项在平面里就是向心项(\(\hat z\times\) 的二次叠加)。
    • \(\mathcal G_i\dot{\mathcal V}_i-\mathrm{ad}^\top_{\mathcal V_i}\mathcal G_i\mathcal V_i\):单个刚体在自身质心系里的牛顿-欧拉方程。把 \(\mathcal V=(\boldsymbol\omega,\mathbf v)\) 代入,它等于 \((\mathcal I\dot{\boldsymbol\omega}+\boldsymbol\omega\times\mathcal I\boldsymbol\omega,\; m(\dot{\mathbf v}+\boldsymbol\omega\times\mathbf v))\):第一项是欧拉方程(含陀螺项 \(\boldsymbol\omega\times\mathcal I\boldsymbol\omega\)),第二项是 \(m\mathbf a\)(体坐标里的真实加速度是 \(\dot{\mathbf v}+\boldsymbol\omega\times\mathbf v\))。平面里陀螺项消失,只剩 \(I\alpha\) 与 \(m\mathbf a\)。
    • \(\mathrm{Ad}^\top_{T_{i+1,i}}\mathcal F_{i+1}\):把后一根连杆通过关节 \(i+1\) 传来的 wrench 换算到 \(\{i\}\) 中。为什么是伴随的转置?功率不变:\(\mathcal F_{i+1}^\top\mathcal V_{i+1}=\mathcal F_{i+1}^\top\mathrm{Ad}_{T_{i+1,i}}\mathcal V_i=(\mathrm{Ad}^\top\mathcal F_{i+1})^\top\mathcal V_i\)(7.6 节)。
    • \(\tau_i=\mathcal F_i^\top\mathcal A_i\):电机沿螺旋轴做功,\(\tau_i\dot\theta_i=\mathcal F_i^\top(\mathcal A_i\dot\theta_i)\)。

    数值核对。我们把平面三连杆臂嵌入三维(转轴沿 \(z\),连杆沿 \(x\) 放置,\(\mathcal A_i=(0,0,1,\,0,\,l_i/2,\,0)\),\(\mathcal I_i=\mathrm{diag}(0,0,m_il_i^2/12)\),平面运动只用到 \(zz\) 分量),随机抽取 300 个状态和手爪力,空间递推与平面递推的 \(\boldsymbol\tau\) 在 \(3\times10^{-14}\) 内一致;平面递推又与独立的拉格朗日公式(FIG 3)在同样的量级内一致。

    树与浮动基座。树结构只要把"上一根"换成"父连杆",向后一步对所有子连杆的 \(\mathrm{Ad}^\top\mathcal F\) 求和。8.3 节会看到 \(M(\mathbf q)=\sum_iJ_i^\top\mathcal G_iJ_i\)(\(J_i\) 是连杆 \(i\) 质心系的体雅可比)。

    Here \(\mathcal F_{n+1}\) is the wrench the tip exerts on the environment, written in the tip frame \(\{n+1\}\), and \(T_{n+1,n}\) is constant. Where each term comes from:

    • \(\mathrm{Ad}_{T_{i,i-1}}\mathcal V_{i-1}\) carries the previous link's twist from \(\{i-1\}\) into \(\{i\}\) (the adjoint of Lesson 5.8); \(\mathcal A_i\dot\theta_i\) is the extra twist from this joint's own motion. Together they are the 6-D version of \(\omega_i=\omega_{i-1}+\dot\theta_i\).
    • \(\mathrm{ad}_{\mathcal V}\) is the Lie-bracket matrix of twists: for \(\mathcal V=(\boldsymbol\omega,\mathbf v)\) and any twist \(\mathcal W\), \([\mathcal V,\mathcal W]=\mathrm{ad}_{\mathcal V}\mathcal W\), with \(\mathrm{ad}_{\mathcal V}=\begin{bmatrix}[\boldsymbol\omega]_\times&0\\ [\mathbf v]_\times&[\boldsymbol\omega]_\times\end{bmatrix}\). It is also the derivative of the adjoint: if \(T(t)=e^{-[\mathcal A]\theta(t)}M\), then \(\tfrac{d}{dt}\mathrm{Ad}_T=-\dot\theta\,\mathrm{ad}_{\mathcal A}\mathrm{Ad}_T\).
    • Origin of \(\dot{\mathcal V}_i\): differentiate the \(\mathcal V_i\) equation in time, \(\dot{\mathcal V}_i=\mathrm{Ad}_T\dot{\mathcal V}_{i-1}-\dot\theta_i\,\mathrm{ad}_{\mathcal A_i}\mathrm{Ad}_T\mathcal V_{i-1}+\mathcal A_i\ddot\theta_i\). Using \(\mathrm{Ad}_T\mathcal V_{i-1}=\mathcal V_i-\mathcal A_i\dot\theta_i\), \(\mathrm{ad}_{\mathcal A}\mathcal A=0\) and \(\mathrm{ad}_{\mathcal X}\mathcal Y=-\mathrm{ad}_{\mathcal Y}\mathcal X\) gives \(-\dot\theta_i\,\mathrm{ad}_{\mathcal A_i}\mathcal V_i=\mathrm{ad}_{\mathcal V_i}\mathcal A_i\dot\theta_i\). In the plane this is the centripetal term (\(\hat z\times\) applied twice).
    • \(\mathcal G_i\dot{\mathcal V}_i-\mathrm{ad}^\top_{\mathcal V_i}\mathcal G_i\mathcal V_i\) is the Newton–Euler equation of a single rigid body in its own centre-of-mass frame. Substituting \(\mathcal V=(\boldsymbol\omega,\mathbf v)\) it equals \((\mathcal I\dot{\boldsymbol\omega}+\boldsymbol\omega\times\mathcal I\boldsymbol\omega,\; m(\dot{\mathbf v}+\boldsymbol\omega\times\mathbf v))\): the first part is Euler's equation (with the gyroscopic term \(\boldsymbol\omega\times\mathcal I\boldsymbol\omega\)), the second is \(m\mathbf a\) (the true acceleration in body coordinates is \(\dot{\mathbf v}+\boldsymbol\omega\times\mathbf v\)). In the plane the gyroscopic term vanishes, leaving \(I\alpha\) and \(m\mathbf a\).
    • \(\mathrm{Ad}^\top_{T_{i+1,i}}\mathcal F_{i+1}\) converts the wrench arriving through joint \(i+1\) into frame \(\{i\}\). Why the transpose of the adjoint? Power is invariant: \(\mathcal F_{i+1}^\top\mathcal V_{i+1}=\mathcal F_{i+1}^\top\mathrm{Ad}_{T_{i+1,i}}\mathcal V_i=(\mathrm{Ad}^\top\mathcal F_{i+1})^\top\mathcal V_i\) (Lesson 7.6).
    • \(\tau_i=\mathcal F_i^\top\mathcal A_i\): the motor does work along the screw axis, \(\tau_i\dot\theta_i=\mathcal F_i^\top(\mathcal A_i\dot\theta_i)\).

    Numerical check. We embedded the planar three-link arm in 3D (axes along \(z\), links laid along \(x\), \(\mathcal A_i=(0,0,1,\,0,\,l_i/2,\,0)\); only the \(zz\) entry of \(\mathcal I_i=m_il_i^2/12\) matters for planar motion) and drew 300 random states and tip forces: the spatial and planar recursions give the same \(\boldsymbol\tau\) to \(3\times10^{-14}\), and the planar one agrees with the independent Lagrangian formulas (FIG 3) to the same order.

    Trees and floating bases. For a tree, replace "previous link" by "parent" and let the backward step sum \(\mathrm{Ad}^\top\mathcal F\) over all children. Lesson 8.3 shows that \(M(\mathbf q)=\sum_iJ_i^\top\mathcal G_iJ_i\), with \(J_i\) the body Jacobian of link \(i\)'s centre-of-mass frame.

    平面 ↔ 空间Planar ↔ spatial

    \(\omega,\alpha,\mathbf a_c\;\leftrightarrow\;\mathcal V,\dot{\mathcal V}\);\(\mathbf f,\mu\;\leftrightarrow\;\mathcal F\);\((m,I)\;\leftrightarrow\;\mathcal G\);"\(\alpha\hat z\times\mathbf r-\omega^2\mathbf r\)" \(\leftrightarrow\) "\(\mathrm{Ad}\,\dot{\mathcal V}+\mathrm{ad}_{\mathcal V}\mathcal A\dot\theta\)"。两套公式是同一个算法在两种记号下的写法:平面版适合看清物理,空间版适合写代码,因为没有分情况,也不需要明确地写出每个叉积。

    \(\omega,\alpha,\mathbf a_c\;\leftrightarrow\;\mathcal V,\dot{\mathcal V}\); \(\mathbf f,\mu\;\leftrightarrow\;\mathcal F\); \((m,I)\;\leftrightarrow\;\mathcal G\); "\(\alpha\hat z\times\mathbf r-\omega^2\mathbf r\)" \(\leftrightarrow\) "\(\mathrm{Ad}\,\dot{\mathcal V}+\mathrm{ad}_{\mathcal V}\mathcal A\dot\theta\)". The two sets of formulas are one algorithm in two notations: the planar one shows the physics, the spatial one suits code since it has no special cases and never writes a cross product explicitly.

    6机器人中的它:仿真与计算量In robotics: simulation and cost

    用 RNEA 做正动力学:让三连杆臂掉下来Forward dynamics from RNEA: let the three-link arm fall

    仿真需要的是正动力学。把 FIG 4 的办法接上 2.5 节的 ODE 积分:每个时间步里,先用 RNEA 算出偏置项 \(\mathbf b=\mathrm{RNEA}(\mathbf q,\dot{\mathbf q},0)=C\dot{\mathbf q}+\mathbf g\),再逐列拼出 \(M\),解 \(M\ddot{\mathbf q}=\boldsymbol\tau-\mathbf b\),然后用四阶 Runge–Kutta 积分。电机不出力(\(\boldsymbol\tau=0\),可加粘性摩擦 \(-b\dot{\mathbf q}\)),手臂在重力下自由摆动。无摩擦的保守系统总能量 \(E=T+V\) 应当不变,漂移的大小反映积分器的误差,是对整个动力学模型和积分器的一次体检。

    A simulator needs forward dynamics. Combine FIG 4's trick with the ODE integration of Lesson 2.5: at every time step compute the bias \(\mathbf b=\mathrm{RNEA}(\mathbf q,\dot{\mathbf q},0)=C\dot{\mathbf q}+\mathbf g\) with RNEA, assemble \(M\) column by column, solve \(M\ddot{\mathbf q}=\boldsymbol\tau-\mathbf b\), and integrate with fourth-order Runge–Kutta. The motors apply no torque (\(\boldsymbol\tau=0\), optionally with viscous friction \(-b\dot{\mathbf q}\)) and the arm swings freely under gravity. Without friction the total energy \(E=T+V\) of this conservative system must stay constant, so its drift measures the integrator error: a health check of the dynamics model and the integrator together.

    FIG 5由 RNEA 驱动的正动力学仿真Forward-dynamics simulation driven by RNEA
    能量 (J) 随时间 (s)ENERGY (J) vs TIME (s)
    拖动关节圆圈摆出初始姿态(只能在时间为 0 时拖动),点"放手"开始仿真。右图:动能 \(T\)(红)、势能 \(V\)(蓝,以基座高度为 0)、总能量 \(E\)(琥珀色)。读数里的"漂移"是 \(\max|E-E_0|/|E_0|\)(仅在 \(b=0\) 时有意义)。步长 \(\Delta t\) 是积分步长;第 3 根杆很轻,绕质心的转动惯量只有 0.021 kg·m²,对步长最敏感。 Drag the joint circles to pick the initial posture (only possible at time 0) and press "Release" to start. Right: kinetic energy \(T\) (red), potential energy \(V\) (blue, zero at the base height) and total \(E\) (amber). "Drift" in the readout is \(\max|E-E_0|/|E_0|\) (meaningful only for \(b=0\)). \(\Delta t\) is the integration step; link 3 is light, with an inertia of only 0.021 kg·m² about its centre of mass, and is the most sensitive to it.
    • 放手,让仿真至少运行 3 s(\(b=0\))。能量漂移是多少?Release and let the simulation run for at least 3 s (\(b=0\)). How large is the energy drift?
    • 把步长加大,直到能量漂移超过 1%(\(b=0\))。这是物理失真还是数值失真?Increase the step until the energy drift exceeds 1% (\(b=0\)). Is that physics going wrong or numerics going wrong?

    为什么不直接用拉格朗日公式?计算量Why not just use the Lagrange formulas? The operation count

    FIG 6 数出了这一页上几种实现的乘加次数(把每个 rnea、lagr 内部的标量运算累加起来,这是一个计数模型,不是计时 benchmark;真实库的常数项完全不同,但增长的阶不变)。四条线:① RNEA 求逆动力学;② 调用 \(n\) 次 RNEA 拼出 \(M\);③ 在 ② 基础上再解线性方程,得到正动力学;④ 先显式算 \(M\)、\(\partial M/\partial\mathbf q\)、\(C\)、\(\mathbf g\),再相乘求逆动力学。④ 的阶是 \(n^4\)(单独算 \(M\) 是 \(n^3\)),①是 \(n\)。链越长,差距越大。

    FIG 6 counts the multiply-adds of several implementations on this page (the scalar operations inside each rnea and lagr call are tallied up). It is a count model, not a timing benchmark: real libraries have entirely different constants, but the growth rates are the same. Four curves: ① RNEA for inverse dynamics; ② \(n\) RNEA calls to assemble \(M\); ③ ② plus a linear solve, i.e. forward dynamics; ④ explicit \(M\), \(\partial M/\partial\mathbf q\), \(C\), \(\mathbf g\) and then the products, for inverse dynamics. ④ grows like \(n^4\) (building \(M\) alone is \(n^3\)), ① like \(n\). The longer the chain, the wider the gap.

    FIG 6操作数 vs 关节数Operation count vs number of joints
    每个点是该关节数下在这一页的代码里实际数出的乘加次数,链沿用三种连杆循环。横纵轴都取对数时,\(n^k\) 是斜率为 \(k\) 的直线。切换成线性坐标,红线几乎立刻冲出图外。竖线是当前的 \(n\);读数里的斜率是 \(n=20\to40\) 之间测得的局部斜率。 Each dot is the number of multiply-adds actually tallied by this page's code for that number of joints, cycling through the three link types. On log-log axes \(n^k\) is a straight line of slope \(k\). Switch to linear axes and the red curve leaves the plot almost immediately. The vertical line is the current \(n\); the slopes in the readout are measured between \(n=20\) and \(n=40\).
    • 把 \(n\) 拉到 30(人形机器人的量级)。显式拉格朗日比 RNEA 贵多少倍?Pull \(n\) up to 30 (a humanoid's order of magnitude). How many times costlier is the explicit Lagrangian than RNEA?
    真实系统里In real systems

    软件库:Pinocchio(rnea、crba、aba)、RBDL、KDL(ChainIdSolver_RNE)、Drake(MultibodyPlant::CalcInverseDynamics)、MuJoCo(mj_inverse 内部用 RNE)。它们的核心就是本节的算法,只是用更精细的空间代数和树结构实现。正动力学:Walker–Orin 的做法是 \(O(n^3)\)(要解线性方程);Featherstone 的关节体算法 (ABA) 用"关节体惯量"把链从末端向基座逐级吸收,正动力学也是 \(O(n)\),这是仿真大型机器人的标准算法;组合刚体算法 (CRBA) 则是求 \(M\) 的常用方法。控制:计算力矩控制和逆动力学前馈每个周期调用一次 RNEA(Franka 等机器人的库提供质量矩阵、科氏力、重力项);参数辨识:RNEA 对惯性参数是线性的,\(\boldsymbol\tau=Y(\mathbf q,\dot{\mathbf q},\ddot{\mathbf q})\boldsymbol\pi\),用激励轨迹的数据做最小二乘(Atkeson–An–Hollerbach,1986);真实机器人的质量、质心位置、惯量从来不会准确知道,还有转子惯量、齿轮摩擦和线缆的影响(9.4 节),所以模型算出的 \(\boldsymbol\tau\) 总有偏差,这也是反馈和自适应存在的理由。

    Software: Pinocchio (rnea, crba, aba), RBDL, KDL (ChainIdSolver_RNE), Drake (MultibodyPlant::CalcInverseDynamics) and MuJoCo (mj_inverse uses RNE internally). Their core is this lesson's algorithm, implemented with finer spatial algebra and tree structures. Forward dynamics: Walker–Orin is \(O(n^3)\) (it solves a linear system); Featherstone's articulated-body algorithm (ABA) absorbs the chain from tip to base through "articulated-body inertias" and makes forward dynamics \(O(n)\) as well, the standard for simulating large robots; the composite-rigid-body algorithm (CRBA) is the usual way to get \(M\). Control: computed-torque control and inverse-dynamics feed-forward call RNEA once per cycle (libraries for robots such as the Franka provide the mass matrix, Coriolis and gravity terms). Parameter identification: RNEA is linear in the inertial parameters, \(\boldsymbol\tau=Y(\mathbf q,\dot{\mathbf q},\ddot{\mathbf q})\boldsymbol\pi\), so exciting trajectories give a least-squares problem (Atkeson–An–Hollerbach, 1986). A real robot's masses, centre-of-mass positions and inertias are never exactly known, and rotor inertia, gear friction and cables add more (Lesson 9.4), so the model's \(\boldsymbol\tau\) is always somewhat off, which is why feedback and adaptation exist.

    7常见误区Common pitfalls

    误区 1:忘了每个量写在哪个坐标系里Pitfall 1: forgetting which frame every vector is written in

    平面版里所有向量都在世界系,所以可以直接相加。三维 RNEA 的每个量(\(\mathcal V_i\)、\(\dot{\mathcal V}_i\)、\(\mathcal F_i\))都在各自连杆的坐标系里,相加之前必须用 \(\mathrm{Ad}\) 换到同一个系。手爪力 \(\mathcal F_{n+1}\) 在手爪系里,而传感器读数常常在基座系或腕部传感器系,直接塞进去会得到错的力矩。症状:静止时 \(\tau\) 对,运动起来就错;或者只在某些姿态下错。

    In the planar version all vectors live in the world frame, so they add directly. In 3D RNEA every quantity (\(\mathcal V_i\), \(\dot{\mathcal V}_i\), \(\mathcal F_i\)) is written in its own link frame and must be brought to a common frame with \(\mathrm{Ad}\) before adding. The tip wrench \(\mathcal F_{n+1}\) is in the tool frame, whereas a sensor reading usually comes in the base or wrist-sensor frame; feeding it in unconverted gives the wrong torques. Symptom: \(\tau\) is right at rest but wrong in motion, or wrong only in some postures.

    误区 2:重力符号错了,或者算了两遍Pitfall 2: the wrong sign of gravity, or counting it twice

    重力技巧是令基座加速度 \(\dot{\mathcal V}_0=(\mathbf 0,-\mathbf g)\),\(\mathbf g\) 是重力加速度向量(指向下),所以 \(\dot{\mathcal V}_0\) 指向上。符号取反,机器人就像在天花板上受力。另一个常见错误是:已经用了基座加速度技巧,又在每根连杆上加了一次 \(m_i\mathbf g\),重力项变成两倍。把 \(\mathbf q\) 全部置零、\(\dot{\mathbf q}=\ddot{\mathbf q}=0\),水平杆的 \(\tau\) 应当是 \(+mgl/2\)(FIG 2),用它做自检。

    The gravity trick sets the base acceleration to \(\dot{\mathcal V}_0=(\mathbf 0,-\mathbf g)\) with \(\mathbf g\) the gravitational acceleration vector (pointing down), so \(\dot{\mathcal V}_0\) points up. Flip the sign and the robot feels gravity as if it hung from the ceiling. The other common error is to use the base-acceleration trick and then also add \(m_i\mathbf g\) on every link, doubling gravity. A built-in self-test: a horizontal rod at rest (\(\dot{\mathbf q}=\ddot{\mathbf q}=0\)) must give \(\tau=+mgl/2\) (FIG 2).

    误区 3:质心惯量和关节惯量混用Pitfall 3: mixing the centre-of-mass and joint-axis inertias

    CAD 软件给出的惯量常常是绕零件原点或绕关节轴的,而 RNEA 的 \(\mathcal G_i\) 要的是绕质心、写在质心坐标系里的惯量。平行轴定理:\(I_{\text{关节}}=I_c+md^2\)。均匀杆绕端点是 \(ml^2/3\),绕质心是 \(ml^2/12\),相差 4 倍。用错的后果是偏大的惯量:参数看上去合理,但模型预测的力矩系统性偏高,机器人的响应也与仿真对不上。

    CAD tools often report inertia about the part origin or the joint axis, whereas RNEA's \(\mathcal G_i\) wants the inertia about the centre of mass, written in the centre-of-mass frame. Parallel-axis theorem: \(I_{\text{joint}}=I_c+md^2\). A uniform rod has \(ml^2/3\) about its end and \(ml^2/12\) about its centre, a factor of 4 apart. Using the wrong one leaves the inertia too large: the parameters look plausible, but the model's torques are systematically high and the robot does not match the simulation.

    误区 4:把固定基座的 RNEA 用在浮动基座上Pitfall 4: applying a fixed-base RNEA to a floating base

    本节假设基座固定:\(\dot{\mathcal V}_0\) 已知(0 或重力技巧),基座的反力是算出来的"副产品"。四足或人形机器人的躯干是浮动的,有 6 个额外的自由度(9.2 节),躯干的加速度本身是未知量:要么把 6 个自由度加入广义坐标,用 \(M\ddot{\mathbf q}\) 的 \(n+6\) 维形式,要么给定躯干的加速度,从躯干的 6 个方程里解出接触力。直接对 \(n\) 个关节算 RNEA,只会得到"如果躯干被钉住"时的关节力矩。

    This lesson assumes a fixed base: \(\dot{\mathcal V}_0\) is known (zero, or the gravity trick) and the base reaction is a by-product. The trunk of a quadruped or humanoid is floating and has 6 extra degrees of freedom (Lesson 9.2); its acceleration is itself unknown. Either add the 6 coordinates and use the \((n+6)\)-dimensional \(M\ddot{\mathbf q}\) form, or prescribe the trunk acceleration and solve the contact forces from the trunk's six equations. Running RNEA over the \(n\) joints alone gives the joint torques "as if the trunk were nailed down".

    误区 5:模型的 \(\tau\) 不是电机该出的力矩Pitfall 5: the model's \(\tau\) is not what the motor should output

    RNEA 给的是关节轴上需要的力矩,在刚体、理想关节、参数准确的前提下。真实的电机还要克服转子惯量(乘以减速比的平方)、齿轮和轴承的摩擦、线缆的拉力,传动还有弹性。把 RNEA 直接作为电流指令的前馈,通常会留下百分之几到几十的力矩误差,所以必须有反馈(Part IV),并常常辨识摩擦和转子惯量。

    RNEA returns the torque needed at the joint axis, assuming rigid bodies, ideal joints and exact parameters. A real motor must also overcome rotor inertia (multiplied by the gear ratio squared), gear and bearing friction and cable forces, and the transmission can be compliant. Feeding RNEA directly forward as the current command typically leaves torque errors of several percent to tens of percent, so feedback (Part IV) is essential and friction and rotor inertia are often identified separately.

    8小练习Check yourself

    1. 一根均匀水平杆,质量 \(m\),长 \(l\),一端由电机关节托住并保持静止。重力加速度 \(g\)。电机需要的力矩是?1. A uniform horizontal rod of mass \(m\) and length \(l\) is held at rest by a motor at one end. Gravity is \(g\). What torque must the motor supply?
    静止时 \(\omega=\alpha=0\),用重力技巧 \(\mathbf a_c=(0,g)\),\(\mathbf f=m(0,g)\),\(\mu=\mathbf r_c\times\mathbf f=(l/2)\cdot mg\)。直观上是重心(在杆中点)的重量乘以杠杆臂 \(l/2\)。\(mgl/3\) 来自把端点惯量 \(ml^2/3\) 错用到静力学上。At rest \(\omega=\alpha=0\); with the gravity trick \(\mathbf a_c=(0,g)\), \(\mathbf f=m(0,g)\) and \(\mu=\mathbf r_c\times\mathbf f=(l/2)\cdot mg\). Intuitively: the weight (acting at the midpoint) times the lever arm \(l/2\). \(mgl/3\) comes from misapplying the end-point inertia \(ml^2/3\) to a statics problem.
    2. 太空中(无重力),同样的均匀杆绕一端的关节以恒定角速度 \(\omega\) 旋转。关节电机需要的力矩是?2. In space (no gravity), the same uniform rod spins at constant angular velocity \(\omega\) about the joint at one end. What torque must the joint motor supply?
    \(\alpha=0\),质心加速度只有向心项 \(-\omega^2\mathbf r_c\),所以关节要提供沿杆方向的力 \(\mathbf f=-m\omega^2\mathbf r_c\),大小 \(m\omega^2l/2\),这是力,不是力矩。力矩 \(\mu=I\alpha+\mathbf r_c\times\mathbf f=0+0\),因为 \(\mathbf f\) 与 \(\mathbf r_c\) 平行。单根杆绕固定端恒速旋转不需要力矩;多关节链里速度项才会产生力矩(在 FIG 3 里关掉重力、令 \(\ddot\theta=0\) 就能看到)。\(\alpha=0\) and the centre-of-mass acceleration is only the centripetal term \(-\omega^2\mathbf r_c\), so the joint must supply a force \(\mathbf f=-m\omega^2\mathbf r_c\) along the rod, of magnitude \(m\omega^2l/2\), but no torque: \(\mu=I\alpha+\mathbf r_c\times\mathbf f=0+0\), because \(\mathbf f\) is parallel to \(\mathbf r_c\). A single rod spinning at constant rate about a fixed end needs no torque; in a multi-joint chain velocity terms do produce torques (switch gravity off and set \(\ddot\theta=0\) in FIG 3 to see it).
    3. 一个 6 自由度机械臂,在关掉重力的情况下,要用 RNEA 拼出完整的 \(6\times6\) 质量矩阵 \(M(\mathbf q)\),最少要调用几次 RNEA?3. For a 6-DoF arm with gravity switched off, how many RNEA calls are needed at least to assemble the full \(6\times6\) mass matrix \(M(\mathbf q)\)?
    每次调用令 \(\dot{\mathbf q}=0\)、\(\ddot{\mathbf q}=\mathbf e_j\),得到 \(M\) 的一整列。需要 6 列,所以 6 次。开着重力时,每次要减去 \(\mathrm{RNEA}(\mathbf q,0,0)\),共 7 次。每次是 \(O(n)\),总共 \(O(n^2)\)。利用 \(M\) 的对称性可以少算,CRBA 就是这样把 \(O(n^2)\) 做得更紧。Each call with \(\dot{\mathbf q}=0\) and \(\ddot{\mathbf q}=\mathbf e_j\) returns one full column of \(M\); six columns need 6 calls. With gravity on you subtract \(\mathrm{RNEA}(\mathbf q,0,0)\), which makes 7. Each call is \(O(n)\), so \(O(n^2)\) in total. Exploiting the symmetry of \(M\) saves work; the CRBA does exactly that to make \(O(n^2)\) tighter.
    4. 世界系 \(z\) 向上,重力加速度向量是 \(\mathbf g=(0,0,-9.81)\)。用"基座加速度"技巧时,三维 RNEA 的初始值 \(\dot{\mathcal V}_0\) 是?(twist 角部分在前)4. World \(z\) points up and the gravitational acceleration vector is \(\mathbf g=(0,0,-9.81)\). With the base-acceleration trick, what is the initial value of the 3D RNEA, \(\dot{\mathcal V}_0\)? (twist: angular part first)
    \(\dot{\mathcal V}_0=(\mathbf 0,-\mathbf g)=(0,0,0,\,0,0,+9.81)\):线加速度部分(后三个分量)向上。选项 B 把重力放进了角加速度部分,选项 A 的符号反了。\(\dot{\mathcal V}_0=(\mathbf 0,-\mathbf g)=(0,0,0,\,0,0,+9.81)\): the linear-acceleration part (last three entries) points up. Option B puts gravity into the angular part; option A has the wrong sign.
    5. 做正动力学时,先调用 \(\mathrm{RNEA}(\mathbf q,\dot{\mathbf q},0)\),它得到的是什么?5. For forward dynamics you first call \(\mathrm{RNEA}(\mathbf q,\dot{\mathbf q},0)\). What does it return?
    \(\boldsymbol\tau=M\ddot{\mathbf q}+\mathbf b\),令 \(\ddot{\mathbf q}=0\) 就只剩 \(\mathbf b=C\dot{\mathbf q}+\mathbf g\)。若再令 \(\dot{\mathbf q}=0\),才只剩下 \(\mathbf g\)(选项 C)。然后解 \(M\ddot{\mathbf q}=\boldsymbol\tau-\mathbf b\) 得到加速度。\(\boldsymbol\tau=M\ddot{\mathbf q}+\mathbf b\); setting \(\ddot{\mathbf q}=0\) leaves \(\mathbf b=C\dot{\mathbf q}+\mathbf g\). Only with \(\dot{\mathbf q}=0\) as well do you get \(\mathbf g\) alone (option C). Then solve \(M\ddot{\mathbf q}=\boldsymbol\tau-\mathbf b\) for the acceleration.

    9延伸阅读Further reading

    • J. Y. S. Luh, M. W. Walker & R. P. C. Paul, On-Line Computational Scheme for Mechanical Manipulators, J. Dynamic Systems, Measurement, and Control 102(2), 1980 — 递推牛顿-欧拉算法的原始论文The original recursive Newton–Euler paper
    • M. W. Walker & D. E. Orin, Efficient Dynamic Computer Simulation of Robotic Mechanisms, J. Dynamic Systems, Measurement, and Control 104(3), 1982 — 用 RNEA 逐列拼出质量矩阵并求正动力学Assembling the mass matrix from RNEA calls and solving forward dynamics
    • R. Featherstone, Rigid Body Dynamics Algorithms, Springer, 2008 — 空间向量代数,RNEA、CRBA、ABA 的权威讲解Spatial vector algebra and the definitive treatment of RNEA, CRBA and ABA
    • K. Lynch & F. Park, Modern Robotics, Ch. 8, Sec. 8.3 — 本节空间版本的出处:Newton–Euler 逆动力学The source of this lesson's spatial form: Newton–Euler inverse dynamics
    • B. Siciliano, L. Sciavicco, L. Villani & G. Oriolo, Robotics: Modelling, Planning and Control, Ch. 7 — 动力学:拉格朗日与牛顿-欧拉两种形式及动力学参数辨识Dynamics: the Lagrange and Newton–Euler formulations, and dynamic parameter identification
    • C. G. Atkeson, C. H. An & J. M. Hollerbach, Estimation of Inertial Parameters of Manipulator Loads and Links, Int. J. Robotics Research 5(3), 1986 — 惯性参数辨识:动力学对参数线性Inertial parameter identification: dynamics is linear in the parameters