Skip to main content

Dynamics essentials

Intermediate40 minBefore this:Forward and inverse kinematics · Newton’s laws · NumPy

A robot arm holds a 2 kg weight straight out. Nobody is moving it, yet the shoulder motor is working hard and getting warm. Now the arm swings fast and the elbow motor suddenly struggles even though the weight has not changed. Kinematics cannot explain either fact. Dynamics can: it connects the torques your motors produce to the motion you get, and it tells you which motor to buy.

You will be able to

  • Explain what rigid-body dynamics adds to kinematics and state Newton-Euler and Lagrange approaches in words.
  • Read the manipulator equation M(q)q¨+C(q,q˙)q˙+g(q)=τM(q)\ddot q + C(q,\dot q)\dot q + g(q) = \tau term by term.
  • Compute the mass matrix, Coriolis and gravity terms for a 2-link arm in NumPy.
  • Use forward and inverse dynamics, and check a motion against joint torque limits.

Why dynamics?​

Dynamicsthe study of how forces and torques cause motion, taking mass and inertia into account answers two practical questions.

  • Inverse dynamics: given the motion I want (positions, velocities, accelerations), which joint torques do I need? Used for control, for sizing motors, and for checking a plan is feasible.
  • Forward dynamics: given the torques I apply, how will the robot move? Used by every physics simulator, including the ones in the simulation module.

Both come from one equation. Before we meet it, build the intuition for the forces that appear.

Newton-Euler intuition​

Newton's law for a body is F=maF = ma. Its rotating twin, Euler's law, is τ=Iα\tau = I\alpha (torque equals rotational inertia times angular acceleration). The moment of inertiathe rotational analogue of mass: how hard it is to change an object’s spinning speed about a given axis II depends on both the mass and how far from the axis it sits. A long arm is much harder to spin than the same mass held close to the shoulder.

The Newton-Euler method applies these two laws link by link. A forward pass starts at the base and works outward, computing each link's velocity and acceleration. A backward pass starts at the hand and works inward, computing the force and torque each joint must supply to produce that motion and carry the links beyond it. It is efficient, running in time proportional to the number of joints, and it is what most real-time dynamics libraries use.

The Lagrange method reaches the same equations from energy. Write down the kinetic energy KK and potential energy UU, form L=K−UL = K - U, and apply a derivative recipe. It gives neat symbolic equations for small arms, which is why we use it by hand here.

The manipulator equation​

For any serial arm the result has the same shape:

M(q) q¨+C(q,q˙) q˙+g(q)=τM(q)\,\ddot q + C(q,\dot q)\,\dot q + g(q) = \tau

Each term has a meaning you can feel.

  • M(q) q¨M(q)\,\ddot q: inertia. MM is the mass matrixa symmetric, positive-definite matrix describing the arm’s effective inertia as seen at each joint, which depends on the arm’s posture. It changes with posture: an extended arm has more inertia about the shoulder than a folded one.
  • C(q,q˙) q˙C(q,\dot q)\,\dot q: velocity-dependent forces. Centrifugal forces (a spinning link wants to fly outward) and Coriolis forces (swinging one joint pushes on another). They grow with the square of speed.
  • g(q)g(q): gravity. The torque needed just to hold the arm still. It depends on posture but not on speed.
  • τ\tau: the joint torques your motors supply. (Real arms also have joint friction, which we leave out for clarity.)

Take a planar arm moving in a vertical plane, with link masses m1m_1, m2m_2, lengths l1l_1, l2l_2, centres of mass at distances lc1l_{c1}, lc2l_{c2} from each joint, and inertias I1I_1, I2I_2 about those centres. Joint angles are measured from the horizontal. Using the Lagrange method, the pieces are

M(q)=[m11m12m12m22]M(q) = \begin{bmatrix} m_{11} & m_{12} \\ m_{12} & m_{22} \end{bmatrix}

with

m11=m1lc12+m2(l12+lc22+2l1lc2cos⁡q2)+I1+I2m12=m2(lc22+l1lc2cos⁡q2)+I2m22=m2lc22+I2\begin{aligned} m_{11} &= m_1 l_{c1}^2 + m_2\bigl(l_1^2 + l_{c2}^2 + 2 l_1 l_{c2}\cos q_2\bigr) + I_1 + I_2 \\ m_{12} &= m_2\bigl(l_{c2}^2 + l_1 l_{c2}\cos q_2\bigr) + I_2 \\ m_{22} &= m_2 l_{c2}^2 + I_2 \end{aligned}

and, defining h=−m2l1lc2sin⁡q2h = -m_2 l_1 l_{c2}\sin q_2,

C(q,q˙)=[hq˙2h(q˙1+q˙2)−hq˙10],g(q)=[(m1lc1+m2l1) gcos⁡q1+m2lc2 gcos⁡(q1+q2)m2lc2 gcos⁡(q1+q2)]C(q,\dot q) = \begin{bmatrix} h\dot q_2 & h(\dot q_1 + \dot q_2) \\ -h\dot q_1 & 0 \end{bmatrix}, \qquad g(q) = \begin{bmatrix} (m_1 l_{c1} + m_2 l_1)\,g\cos q_1 + m_2 l_{c2}\,g\cos(q_1+q_2) \\ m_2 l_{c2}\,g\cos(q_1+q_2) \end{bmatrix}

Three observations. MM is symmetric. Its off-diagonal term couples the joints: accelerating joint 2 needs torque at joint 1. And gg is largest when the arm is horizontal (cos⁡0=1\cos 0 = 1) and zero when it points straight up or down.

dynamics.py
import numpy as np

m1, m2 = 2.0, 1.5 # link masses (kg)
l1, l2 = 0.4, 0.3 # link lengths (m)
lc1, lc2 = l1 / 2, l2 / 2 # centre of mass at the middle of each rod
I1 = m1 * l1**2 / 12 # thin-rod inertia about the centre
I2 = m2 * l2**2 / 12
G = 9.81


def mass_matrix(q):
c2 = np.cos(q[1])
m11 = m1 * lc1**2 + m2 * (l1**2 + lc2**2 + 2 * l1 * lc2 * c2) + I1 + I2
m12 = m2 * (lc2**2 + l1 * lc2 * c2) + I2
m22 = m2 * lc2**2 + I2
return np.array([[m11, m12], [m12, m22]])


def coriolis(q, qd):
h = -m2 * l1 * lc2 * np.sin(q[1])
return np.array([[h * qd[1], h * (qd[0] + qd[1])],
[-h * qd[0], 0.0]])


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


def inverse_dynamics(q, qd, qdd):
"""Torques needed to produce acceleration qdd at state (q, qd)."""
return mass_matrix(q) @ qdd + coriolis(q, qd) @ qd + gravity(q)


def forward_dynamics(q, qd, tau):
"""Acceleration produced by torques tau at state (q, qd)."""
return np.linalg.solve(mass_matrix(q), tau - coriolis(q, qd) @ qd - gravity(q))


if __name__ == "__main__":
q = np.array([0.5, 0.8])
qd = np.array([1.0, -0.5])
qdd = np.array([2.0, 1.0])

tau = inverse_dynamics(q, qd, qdd)
print("torques needed:", np.round(tau, 3), "N·m")
print("forward dynamics recovers qdd:", np.allclose(forward_dynamics(q, qd, tau), qdd))

print("holding torque, arm horizontal:", np.round(gravity(np.array([0.0, 0.0])), 3), "N·m")
print("mass matrix eigenvalues (all > 0):", np.round(np.linalg.eigvalsh(mass_matrix(q)), 4))

The round trip, inverse then forward dynamics, returning the same acceleration is a useful self-test for any dynamics code you write or import.

Gravity compensation and computed torque​

Because you now have g(q)g(q) and M(q)M(q), you can cancel the arm's own dynamics. Suppose a simple controller asks for a desired acceleration aa (computed from position error, as in the next lesson). The computed-torque command is

τ=M(q) a+C(q,q˙) q˙+g(q)\tau = M(q)\,a + C(q,\dot q)\,\dot q + g(q)

Plugging it into the manipulator equation gives q¨=a\ddot q = a: the nonlinear arm now behaves like a pile of simple, independent joints that obey whatever aa you ask for. This is called feedback linearisation. It depends on a good model: wrong masses mean imperfect cancellation, which is one reason real controllers keep feedback on top.

Forces at the hand​

Often you care about a force on the hand: pressing a sponge on a table, pushing a door. The Jacobian from the last lesson converts a hand force FF into the joint torques that produce it:

τ=J(q)TF\tau = J(q)^{\mathsf T} F

This is the same Jacobian, transposed. It also explains a useful fact about singularities: in the direction the arm cannot move, a hand force needs almost no joint torque, because the stiff straight links carry the load. A stretched arm can brace hard, but it cannot move or sense gently in that direction. The relationship is also the basis of the impedance control you will meet at the end of this module.

Torque limits and what they mean​

Every motor and gearbox has a peak torque (short bursts) and a continuous torque (what it can supply indefinitely without overheating). Dynamics lets you check a motion against them before you run it.

  • If the holding torque g(q)g(q) alone exceeds the continuous rating, the joint will overheat even when "standing still".
  • Fast motions raise Cq˙C\dot q and Mq¨M\ddot q. Doubling the speed of a swing roughly quadruples the Coriolis torque.
  • A payload adds to the mass of the last link. Many arms specify torque-limited payload versus reach curves: carrying more at a longer reach demands more shoulder torque.

A planner that ignores torque limits can produce a path that is geometrically perfect and physically impossible. Time-optimal trajectory methods, such as time-optimal path parameterisation, bake these limits into the speed profile for exactly this reason.

Warning

Never run a new, fast motion on a real arm without first checking it against the torque and speed limits, either in simulation or with a slow trial. A joint that saturates in the middle of a fast move can make the arm deviate from the planned path suddenly.

Hands-on lab​

You will size the motors for a motion.

  1. Save dynamics.py and run it. Confirm the round trip prints True.
  2. Write a function tau_for_trajectory that takes joint paths q(t)q(t) sampled at 100 Hz for 2 seconds, going from q=(0,0)q = (0, 0) to q=(1.2,0.8)q = (1.2, 0.8) with a smooth cubic profile q(t)=q0+(qf−q0)(3s2−2s3)q(t) = q_0 + (q_f - q_0)(3s^2 - 2s^3) where s=t/2s = t/2. Compute q˙\dot q and q¨\ddot q analytically or with np.gradient.
  3. For each sample, call inverse_dynamics, and print the peak absolute torque on each joint.
  4. Add a 1 kg payload by increasing m2 by 1.0 and re-running. How much did the peak shoulder torque rise?
  5. Pretend the shoulder motor's peak rating is 20 N·m. Does your motion respect it? If not, lengthen the motion time and re-check.

You know it worked when the shoulder peak torque rises noticeably with the payload and drops when you slow the motion down.

Exercises​

Holding torqueBeginner

A uniform rod of mass 2 kg and length 0.5 m is held horizontally by a motor at one end. What static torque is needed?

Show solutionHide solution

The weight acts at the centre, 0.25 m from the joint, so τ=mg l/2=2×9.81×0.25≈4.9\tau = m g\, l/2 = 2 \times 9.81 \times 0.25 \approx 4.9 N·m. If the rod points straight up, the torque falls to zero (ignoring friction), because the weight line passes through the joint.

Which term dominates?Intermediate

Using dynamics.py, evaluate the three torque contributions separately at q=(0.5,0.8)q = (0.5, 0.8) for q˙=(0.2,0.1)\dot q = (0.2, 0.1), q¨=(0.5,0.5)\ddot q = (0.5, 0.5), then again with q˙=(3,2)\dot q = (3, 2). Describe how the shares change.

Show solutionHide solution

Compute mass_matrix(q) @ qdd, coriolis(q, qd) @ qd and gravity(q) separately. At slow speed gravity dominates and the Coriolis term is tiny. At the faster speed the velocities are 15 to 20 times larger, and because the Coriolis term grows with velocity squared it becomes a couple of hundred times larger, while gravity stays unchanged. The lesson: gravity matters at rest and slow speed, velocity terms matter during fast motion.

Why is M symmetric and positive definite?Advanced

Give a physical reason that every eigenvalue of M(q)M(q) must be positive.

Show solutionHide solution

The kinetic energy of the arm is K=12q˙TM(q) q˙K = \tfrac{1}{2}\dot q^{\mathsf T} M(q)\,\dot q. Any real motion of a body with mass has strictly positive kinetic energy, so q˙TMq˙>0\dot q^{\mathsf T}M\dot q > 0 for every nonzero q˙\dot q. That is the definition of positive definite. It also guarantees MM is invertible, which is why forward dynamics can always solve for q¨\ddot q.

Check your understanding​

1In M(q) q̈ + C(q, q̇) q̇ + g(q) = τ, which term holds the arm still against gravity?
2What is inverse dynamics?
3Why does the mass matrix depend on the arm’s posture?
4A good reason to add g(q) to a controller’s output is to…
0 of 4 answered

Takeaways

  • Dynamics links joint torques to motion; kinematics alone cannot say what a motor must supply.
  • The manipulator equation has inertia, velocity-dependent, and gravity terms plus the applied torque.
  • Inverse dynamics gives torques for a desired motion; forward dynamics gives motion from torques and powers simulators.
  • Gravity is usually the largest torque for slow motions; velocity terms grow with speed squared.
  • The mass matrix is symmetric and positive definite, and depends on posture.
  • Check planned motions against continuous and peak torque limits before running them on hardware.

Stuck? Ask Rivet, the course assistant, bottom-right.

Go deeper​

Next: Control and PID

Finished the lab and the quiz?

Mark it done to track your progress through the course.