The Physics of 2D Multibody Systems
Top-level map: Field Guide
Companion chapter: The Computational Machinery: 2D MBSD in Python — how each piece of the physics below is implemented in code.
A consolidated reference for the mechanical-dynamics theory underlying every simulation in this series: rigid-body mechanics, generalised coordinates, constraints, forces, energy, and the Lagrangian formulation that ties them all together.
Pure physics and maths, no code.
Intended as a clean refresher for a mechanical engineer who wants to understand what the simulator is computing before (or after) looking at how.
1. Rigid bodies in the plane
A rigid body in 2D is described by three coordinates:
is the position of a reference point on the body (usually an attachment point where a joint lives), and is the body’s angular orientation measured counter-clockwise from the world x-axis.
The body’s centre of mass sits at a body-fixed offset relative to that reference point. In world coordinates, the CG is at
where is the rotation matrix:
So is a model input per body; setting means the body’s reference point coincides with its CG.
A crank whose reference point is at the pivot but whose CG is half-way along its length has — exactly our slider-crank convention.
Velocities and accelerations follow by time differentiation.
In particular, the CG velocity couples translation and rotation:
where . When , any rotation contributes to CG motion, and the body’s linear and angular equations of motion become coupled.
2. Mass and inertia — the body mass matrix
For a single body with mass , central inertia , and CG offset , Newton–Euler equations expressed at the reference point (not the CG) give a mass matrix:
with by Steiner’s parallel-axis theorem. Two observations:
- The off-diagonal terms vanish only when (reference point = CG).
- For a system of bodies, the global mass matrix is block-diagonal, one per body. Size: .
The mass matrix is configuration-dependent (through ) but the structure is fixed; it only depends on the geometric constants , , per body.
3. Generalised coordinates
Stacking all body coordinates gives the system’s generalised coordinate vector:
Plus, for joint types that use extra algebraic parameters (the cam/leva constraint’s surface parameters, for instance), additional entries appended at the end.
- has entries total.
- (generalised velocities).
- (generalised accelerations).
A mechanism with no constraints would have independent degrees of freedom; reality imposes constraint equations that remove some of these.
4. Constraints
A holonomic constraint is an equation of the form that must hold at every time.
“Holonomic” means it depends only on positions (and possibly explicit time), not on velocities. All the joints in this series are holonomic.
Common 2D joint types and the number of equations each contributes:
| Joint | Geometric meaning | Equations |
|---|---|---|
| Revolute (pin) | Two body-fixed points coincide in world | 2 |
| Prismatic (slider) | Same angle + one point stays on a fixed line | 2 |
| Point-on-line | One body-fixed point stays on a line defined by another body | 1 |
| Cam/Leva | Two parameterised surfaces stay in tangent contact | 3 (+ 2 extra coords per joint) |
| Gear | (fixed transmission ratio) | 1 |
| User | Any scalar equation (driving motion, locks, …) | 1 or more |
Plus three equations pinning the ground body at .
Stacking all constraint equations gives the constraint vector . The system’s physical degrees of freedom are
For a slider-crank driven by a user constraint that prescribes the crank angle, — the mechanism’s motion is completely determined.
Without that user constraint, — the crank can spin freely.
Velocity and acceleration constraints
Differentiating once in time gives the velocity-level constraint:
where is the constraint Jacobian, a matrix of size . Differentiating a second time gives the acceleration-level constraint:
These are not independent of the original position-level — they are consequences of it. But they are what the solver actually uses.
5. Forces
Generalised forces have the same dimension as — one entry per coordinate.
5.1 Gravity
If is the uniform world gravity vector, the gravitational potential energy of body is
The generalised gravity force on is . In practice:
- Force on : — the usual weight.
- Torque on : — non-zero only when the body has an offset CG (), capturing gravity’s lever arm.
5.2 Springs and dampers
A linear spring-damper element connects point on body to point on body . Its instantaneous length is ; the force magnitude along that line is
Projecting this scalar force onto uses the spring Jacobian (derivative of with respect to the body coordinates). The rate of length change involves both translation and rotation of the attachment points.
5.3 Elastic (penalty) contact
Unilateral contact between two surfaces is modelled as a Hertzian penalty force that only acts when the surfaces interpenetrate:
where is the signed penetration depth (positive when interpenetrating) and is the penetration velocity. The normal force points along the surface normal; it always pushes (never pulls), which is the defining property of unilateral contact.
Optional Coulomb friction along the surface tangent is regularised using a smooth :
is the tangential relative velocity at the contact point; is a regularisation scale that replaces the discontinuous of exact Coulomb friction with a smooth S-curve, essential for ODE integrators.
5.4 Other force types
- Centrifugal / Coriolis pseudo-forces in a rotating reference frame.
- User-defined forces — any function returning a generalised force vector.
5.5 Total generalised force
The total applied force on the system is the sum of all contributions:
This is what appears on the right-hand side of the equations of motion.
6. The Lagrangian formulation
For an unconstrained system the Lagrangian is where
The Euler–Lagrange equations give the unconstrained equations of motion:
For a system with position-dependent mass matrix this would produce velocity-quadratic “Christoffel” terms, but because we work in reference coordinates and the mass matrix varies only through the rotation angles (and even then smoothly), for rigid-body dynamics in 2D the formulation simplifies to
For planar mechanisms with bodies whose the velocity-quadratic terms vanish entirely; for bodies with they appear as small correction terms that we absorb into the numerical formulation (the mass-matrix time derivative when assembling for the constraint right-hand side).
6.1 Adding constraints: the Lagrange-multiplier augmentation
To enforce , we augment the Lagrangian with a multiplier vector :
Stationarity with respect to gives
and stationarity with respect to recovers the constraint itself.
Physical meaning of the multipliers. The term is the constraint reaction force: the force the constraint applies to the system to keep satisfied. Each individual is the generalised force associated with constraint equation . For a revolute joint, the multiplier pair is the bearing reaction; for a user constraint that drives the crank angle, the multiplier is (minus) the required driving torque.
7. The equations of motion: an index-1 DAE
Putting everything together, the continuous-time equations of motion are a differential-algebraic system (DAE) of three coupled equations:
The second equation is algebraic — it has no time derivatives of — which is what makes this a DAE rather than an ODE. The “index” refers to how many times the algebraic equation must be differentiated to recover an ODE in all variables.
Index reduction. Differentiating twice gives the acceleration-level constraint . Combining with Newton’s law:
This is the saddle-point system that the simulator solves at every time step. It’s a single linear system in the unknowns and . Once solved, we have:
- — the generalised accelerations, ready to integrate (forward dynamics).
- — the Lagrange multipliers = constraint reaction forces (interesting in their own right, especially for inverse dynamics).
The name “saddle-point” comes from the associated optimisation interpretation: the solution is a minimum of the system’s kinetic energy functional in and a maximum of the Lagrangian in — a saddle point of the augmented functional. For us it’s just a linear solve.
8. Bilateral vs unilateral contact
A bilateral constraint (revolute, prismatic, cam/leva contact) enforces exactly at all times. The associated Lagrange multiplier can have any sign — positive or negative — and the constraint force can act in either direction.
A unilateral contact (penalty-based ground contact, tyre-on-road) does not produce a constraint equation. Instead it appears as a force in . The force only exists when the bodies interpenetrate; it always pushes them apart. No multiplier is required.
The trade-off:
- Bilateral constraints are exactly satisfied (up to numerical precision). Fast, clean, but require invertibility of the constraint Jacobian and may force spurious attractive contact if the real physics would have lost contact.
- Penalty unilateral contact is approximately satisfied via very stiff forces ( large). Robust, physical (contact can open and close naturally), but makes the ODE stiff and imposes small integration timesteps.
Our simulator supports both and uses each where appropriate: bilateral for joint connections that should never separate, penalty for wheel-on-ground and similar contact dynamics.
9. Energy
Three forms of energy live in the system:
Total mechanical energy is . For a system with only bilateral constraints, conservative forces, and no dampers, is conserved along the trajectory; this is the single most sensitive correctness test of a dynamic simulator.
Penalty contact and dampers dissipate energy — monotonically decreasing is the correctness test for those.
10. Forward vs inverse dynamics
The same saddle-point system supports two complementary questions:
- Forward dynamics: given and initial , find the trajectory . Integrate the block system forward in time — an initial-value DAE problem.
- Inverse dynamics: prescribe the motion (typically via user constraints that make ), and read off the Lagrange multipliers . No integration is needed — one linear solve per time step is enough. The multipliers directly report bearing reactions, driving torque, guide normal forces.
Both are just different projections of the same underlying saddle-point system — the difference is only whether you advance or whether are prescribed.
11. FAQ — common points of confusion
Three questions that regularly come up when an engineer first meets this framework. Each maps directly back to a section above, but the phrasing is closer to the way the question actually gets asked in practice.
Q1. Why doesn’t my simulated engine conserve energy?
Check Section 9. Energy conservation is a strict test, but only in the right conditions — you need (i) only bilateral constraints (joints, not penalty contacts), (ii) only conservative forces (gravity and springs, not dampers), and (iii) no driving torque doing work into the system. Common failure modes:
- You have a damper. Any term in a spring-damper, or the term in a penalty contact, dissipates energy on purpose. The monotonic decrease of is the correctness test in that case, not its constancy.
- You have penalty contact. Even with , the term
is conservative in theory (it’s a spring) but in practice the stiff
dynamics mean integration error dominates unless tolerances are very
tight. Tightening
rtol/atolis the fix. - You have drift. For long simulations of index-1 DAE formulations, constraint violations at the position level can accumulate even when the acceleration-level constraint is exactly enforced. Symptom: energy slowly grows or shrinks over many periods. Fixes are Baumgarte stabilisation (feedback correction), projection (re-solve periodically), or just tighter ODE tolerances.
- You have a driving user constraint. A user constraint like is an external input — its Lagrange multiplier is the driving torque, and is the power that the “motor” pumps into the system. Energy isn’t conserved; it grows at the rate the motor supplies work.
Q2. Why is the mass matrix block-diagonal?
Because we define one coordinate triplet per body (Section 3), and the kinetic energy of body A has no coordinate overlap with body B. Each body’s kinetic-energy contribution is , involving only its own three coordinates. When you stack those into the full Lagrangian, the resulting global has one block per body and zeros everywhere else.
The physical mechanical coupling between bodies comes through the constraint Jacobian , not through . That’s exactly why the saddle-point system couples and — to introduce the between-body interaction that the mass matrix alone cannot express.
In a formulation that uses different variables — e.g. relative joint coordinates for a tree-structured robot — the effective mass matrix is not block-diagonal, because the dependency chain propagates inertias through the joints. We chose the simpler representation (absolute body coordinates + constraints) specifically because the block-diagonal mass matrix is cheap to assemble and the constraint mechanics is well-studied.
Q3. Is the driving torque a “force” or a “constraint”?
This one trips everyone up. In our framework it’s a constraint, and the Lagrange multiplier associated with that constraint is the torque you have to apply:
- Inverse dynamics (the slider-crank chapters): we prescribe as a user constraint (). The mechanism’s saddle-point solve returns a Lagrange multiplier for that equation, and is the torque a motor would have to supply to produce the prescribed rotation. Given motion → find force.
- Forward dynamics (where you’d actually simulate a motor, not yet built in this project): the driving torque becomes an applied force, part of . You’d add and let the solver integrate forward — emerges from the dynamics rather than being prescribed.
These two formulations are duals of each other; the same mathematical object (the of a user constraint = the of an applied torque) plays opposite roles. Inverse asks “what torque realises this motion?”; forward asks “what motion does this torque produce?”. The saddle-point system handles both — it’s the interpretation that changes.
12. Summary — the state of physics in this series
Everything in the slider-crank, multi-cylinder, boxer, and rocking-couples chapters reduces to:
- Bodies with per rigid body.
- Constraints defined per joint.
- Forces summed into .
- The saddle-point system derived from Lagrangian mechanics:
Solve it. Integrate forward, or extract directly. Everything else — slider-crank secondary imbalance, boxer cancellation, rocking couples, vibration spectra — is a consequence.
See the companion chapter The Computational Machinery for how each piece of this physics is assembled in Python, which constraint types are pre-built, and which example scripts exercise which physical features.