Part I · Foundations · Chapter 02
available

Linear algebra for mechanics

Vectors describe motion and force. Matrices translate between coordinate frames, encode inertia, and reveal which motions a robot can—or cannot—produce.

Level
Beginner
Hands-on
90–120 minutes
Before you start
Chapter 1, vectors, sine and cosine

By the end, you can…

  • Distinguish points, directions, velocities, and forces under a transform.
  • Use cross-product matrices and quadratic forms in mechanics.
  • Interpret inertia eigenvectors as principal axes.
  • Derive and numerically verify a two-link Jacobian.
  • Recognize singular and sparse mechanical systems.
  • Predict LavenderSim named-site velocity from body telemetry.

A vector needs a meaning and a frame

The array [1, 0, 0] is not yet a physical statement. Is it a point, a direction, a velocity, or a force? Is it expressed in the robot body frame or the world frame? Correct arithmetic begins by answering both questions.

The dot product measures alignment:

ab=abcosθa\cdot b=\lVert a\rVert\lVert b\rVert\cos\theta

The cross product produces a vector perpendicular to two inputs. Mechanics uses it for torque and point velocity:

τ=r×f,vpoint=vbody+ω×r\tau=r\times f,\qquad v_{\mathrm{point}}=v_{\mathrm{body}}+\omega\times r

It is often useful to write the cross product as matrix multiplication:

[r]×=[0rzryrz0rxryrx0],[r]×f=r×f[r]_{\times}=\begin{bmatrix}0&-r_z&r_y\\r_z&0&-r_x\\-r_y&r_x&0\end{bmatrix},\qquad [r]_{\times}f=r\times f
cross product matrix
def skew(vector):
    x, y, z = vector
    return np.array([
        [0, -z,  y],
        [z,  0, -x],
        [-y, x,  0],
    ], dtype=float)

Points translate; free vectors only rotate

A rigid transform contains a rotation RR and translation tt. A local point includes both:

pW=RWBpB+tWBp_W=R_{WB}p_B+t_{WB}

A direction, angular velocity, or force has no location, so translation does not apply:

fW=RWBfBf_W=R_{WB}f_B

A valid rotation satisfies RTR=IR^\mathsf{T}R=I and detR=1\det R=1. Its inverse is therefore its transpose. The inverse rigid transform is:

RBW=RWBT,tBW=RWBTtWBR_{BW}=R_{WB}^{\mathsf T},\qquad t_{BW}=-R_{WB}^{\mathsf T}t_{WB}
Common bug: adding a frame translation to a force or direction. Translation changes where a point is, not which way a free vector points.

Linear systems and quadratic forms

Simulation repeatedly solves equations that can be organized as:

Ax=bAx=b

AA may encode inertia, constraint coupling, or a local approximation to nonlinear dynamics. We normally solve the system with a factorization instead of explicitly forming A1A^{-1}. Explicit inversion does more work, hides exploitable structure, and often magnifies numerical error.

A quadratic form maps a direction to a scalar:

E(x)=12xTAxE(x)=\tfrac{1}{2}x^\mathsf{T}Ax

When symmetric AA is positive definite, xTAx>0x^\mathsf{T}Ax>0 for every nonzero xx. Mass and inertia matrices should have this property: every nonzero velocity stores positive kinetic energy.

Experiment 1: find the principal axes

Experiment 01verified

Rotate and diagonalize an inertia tensor

If a box is rotated in the world, did its physical resistance to rotation change—or only its coordinates?

A uniform box aligned with its body axes has diagonal inertia:

IB=m12diag(h2+d2,  w2+d2,  w2+h2)I_B=\frac{m}{12}\operatorname{diag}(h^2+d^2,\;w^2+d^2,\;w^2+h^2)

Expressed in world coordinates, the same tensor becomes:

IW=RWBIBRWBTI_W=R_{WB}I_BR_{WB}^{\mathsf T}

The eigenvectors of IWI_W point along the rotated principal axes. The eigenvalues are the principal moments and remain unchanged by rotation.

Rotated box with three colored principal inertia axes
Diagonalizing the world-frame tensor recovers three orthogonal physical axes. Their directions rotate with the body; their moments remain 0.057, 0.122, and 0.148 kg·m².
det R = 1proper rotation
3 positive λpositive-definite inertia
I = VΛVᵀeigen reconstruction
Expected result
The command exits successfully and reproduces the numerical or visual relationship described in this card.
Failure modes
Non-finite values, a reversed trend, a failed assertion, or a materially different plot means the assumptions, seed, timestep, build, or backend should be inspected before continuing.

Experiment 2: differentiate a two-link arm

For link lengths l1,l2l_1,l_2 and joint angles q1,q2q_1,q_2, the planar tip is:

p(q)=[l1cosq1+l2cos(q1+q2)l1sinq1+l2sin(q1+q2)]p(q)=\begin{bmatrix}l_1\cos q_1+l_2\cos(q_1+q_2)\\l_1\sin q_1+l_2\sin(q_1+q_2)\end{bmatrix}

The Jacobian contains the derivative of every output coordinate with respect to every input coordinate:

J(q)=pq=[l1sinq1l2sin(q1+q2)l2sin(q1+q2)l1cosq1+l2cos(q1+q2)l2cos(q1+q2)]J(q)=\frac{\partial p}{\partial q}=\begin{bmatrix}-l_1\sin q_1-l_2\sin(q_1+q_2)&-l_2\sin(q_1+q_2)\\l_1\cos q_1+l_2\cos(q_1+q_2)&l_2\cos(q_1+q_2)\end{bmatrix}

It maps joint velocity to instantaneous Cartesian tip velocity:

p˙=J(q)q˙\dot p=J(q)\dot q
Experiment 02verified

Check the analytic Jacobian numerically

How do we catch a missing sign or an incorrect joint-angle sum before using the Jacobian in a controller?

Central differences perturb one coordinate in both directions:

J:,ip(q+εei)p(qεei)2εJ_{:,i}\approx\frac{p(q+\varepsilon e_i)-p(q-\varepsilon e_i)}{2\varepsilon}

At q=[0.55,0.8]q=[0.55,-0.8], the analytic and finite-difference matrices agree with Frobenius error below 8e-11. This is a reusable verification pattern for kinematics, sensors, and reward gradients.

python
analytic = two_link_jacobian(q)
numeric = finite_difference_jacobian(two_link_tip, q)

assert np.allclose(analytic, numeric, atol=2e-10)
Expected result
The command exits successfully and reproduces the numerical or visual relationship described in this card.
Failure modes
Non-finite values, a reversed trend, a failed assertion, or a materially different plot means the assumptions, seed, timestep, build, or backend should be inspected before continuing.

Experiment 3: lose a motion direction

A singular value measures how strongly a matrix maps a particular input direction. The condition number is the ratio between the largest and smallest singular values:

κ(J)=σmaxσmin\kappa(J)=\frac{\sigma_{\max}}{\sigma_{\min}}

When the arm is straight, both Jacobian columns point along the same Cartesian direction. Rank falls from two to one, σmin=0\sigma_{\min}=0, and the condition number is infinite.

Jacobian condition number rising near straight two-link arm configurations
The arm is singular at elbow angles 0 and ±π. Near those poses, tiny Cartesian requests can demand very large joint velocities.
A singularity is geometric, not a solver crash. The robot has genuinely lost an instantaneous motion direction. Damping or a pseudoinverse can control the numerical consequences but cannot invent the missing degree of freedom.

Structure matters as systems grow

In a serial chain, joint 1 affects every downstream link. Joint 16 affects only link 16. Most relationships in a large multibody model are local, leaving predictable zeros in Jacobians and mass-matrix factorizations.

Block lower triangular sparsity pattern for a sixteen-link serial chain Jacobian
Lavender cells are potentially nonzero. Storing or multiplying the dark region wastes work. Recursive rigid-body algorithms exploit this dependency structure without constructing one giant dense expression.

Experiment 4: predict a named site's velocity

Experiment 04verified

Reconstruct native site telemetry

Does LavenderSim's reported site velocity match the rigid-body point-velocity equation?

LavenderSim stores each body's world position, quaternion, linear velocity, and angular velocity. A named site supplies a body-local offset. After rotating that offset into the world as rr, its velocity is:

vsite=vbody+ω×r=[I[r]×][vbodyωbody]v_{site}=v_{body}+\omega\times r=\begin{bmatrix}I&-[r]_{\times}\end{bmatrix}\begin{bmatrix}v_{body}\\\omega_{body}\end{bmatrix}
python
body = sim.body_state()[0]
site = sim.site_data()["tool.tip"]

offset_world = site[:3] - body[:3]
twist = np.r_[body[7:10], body[10:13]]
J_site = np.c_[np.eye(3), -skew(offset_world)]

predicted = J_site @ twist
measured = site[7:10]

Across twelve rotating states, the maximum prediction error is below 1.4e-8 m/s, consistent with float32 telemetry roundoff.

Implemented by LavenderSim: site_data() rotates the local offset and evaluates the same cross product. This comparison verifies actual package behavior; it is not a separate browser approximation.
Expected result
The command exits successfully and reproduces the numerical or visual relationship described in this card.
Failure modes
Non-finite values, a reversed trend, a failed assertion, or a materially different plot means the assumptions, seed, timestep, build, or backend should be inspected before continuing.

Paw-check: make the matrices answer

  1. Change the box dimensions so two principal moments become equal. What happens to the uniqueness of the corresponding eigenvectors?
  2. Choose a joint velocity and use Jq˙J\dot q to predict the two-link tip direction. Confirm it with a tiny finite step.
  3. Find all elbow angles where the two-link Jacobian determinant is zero.
  4. Move tool.tip to the body center. Which three columns of its point Jacobian stop contributing?
  5. Count the nonzero blocks for a 100-link serial chain without allocating the full matrix.
What should I be able to say now?

Transforms act differently on points and free vectors. Symmetric positive-definite matrices encode positive mechanical energy. Eigenvectors reveal principal directions, while Jacobians convert coordinate rates and expose singularities. Mechanical matrices are usually structured and sparse, which later enables recursive algorithms and efficient constraint solves.