Pylinkage
Pylinkage lets you design planar linkage mechanisms by specifying the motion you need. Tell it where you want a coupler point to go, and it finds mechanism dimensions automatically using classical synthesis theory (Burmester, Freudenstein) and metaheuristic optimization (PSO, differential evolution). You can then simulate, analyze, visualize, and export to DXF or STEP for fabrication.
from pylinkage.synthesis import path_generation
from pylinkage.visualizer import plot_kinematic_linkage
# "I need a coupler that passes through these four points"
result = path_generation([(0, 0), (1, 1), (2, 1), (3, 0)])
plot_kinematic_linkage(result.solutions[0])

Installation
pip install pylinkage # Core only: define, simulate, and build linkages
pip install pylinkage[full] # Everything: all optional backends included
Install only what you need:
Extra |
What it adds |
|---|---|
|
JIT-compiled solvers (1.5-2.5M steps/sec) |
|
Differential evolution optimizer, synthesis solvers |
|
SymPy-based closed-form expressions and gradient optimization |
|
Matplotlib visualization and animation |
|
Interactive HTML visualization |
|
Publication-quality SVG export via drawsvg |
Extras can be combined: pip install pylinkage[viz,scipy,numba]
For development:
git clone https://github.com/HugoFara/pylinkage.git
cd pylinkage
uv sync # or pip install -e ".[full,dev]"
Quick Start
Define and Visualize a Four-Bar Linkage
Using the component-based API (recommended). Visualization requires pip install pylinkage[viz].
from pylinkage.components import Ground
from pylinkage.actuators import Crank
from pylinkage.dyads import RRRDyad
from pylinkage.simulation import Linkage
from pylinkage.visualizer import plot_kinematic_linkage
# Define ground pivots
O1 = Ground(0, 0, name="O1")
O2 = Ground(3, 0, name="O2")
# Create crank (motor-driven input)
crank = Crank(anchor=O1, radius=1.0, angular_velocity=0.31, name="crank")
# Create rocker via RRR dyad (circle-circle intersection)
rocker = RRRDyad(
anchor1=crank.output,
anchor2=O2,
distance1=3.0,
distance2=1.0,
name="rocker"
)
my_linkage = Linkage([O1, O2, crank, rocker], name="Four-Bar")
plot_kinematic_linkage(my_linkage)

Alternative: Links-First Builder
For a more mechanical engineering-oriented approach, use MechanismBuilder to define links with their lengths first, then connect them:
from pylinkage.mechanism import MechanismBuilder
# Define links by their lengths, then connect with joints
mechanism = (
MechanismBuilder("four-bar")
.add_ground_link("ground", ports={"O1": (0, 0), "O2": (4, 0)})
.add_driver_link("crank", length=1.0, motor_port="O1", omega=0.1)
.add_link("coupler", length=3.5)
.add_link("rocker", length=3.0)
.connect("crank.tip", "coupler.0")
.connect("coupler.1", "rocker.0")
.connect("rocker.1", "ground.O2")
.build()
)
# Joint positions are computed automatically from link lengths
for positions in mechanism.step():
print(positions)
Optimize with PSO
PSO is built-in (no extra needed).
import pylinkage as pl
@pl.kinematic_minimization
def fitness(loci, **_):
tip_locus = tuple(x[-1] for x in loci)
return pl.bounding_box(tip_locus)[0] # Minimize min_y
bounds = pl.generate_bounds(my_linkage.get_num_constraints())
ensemble = pl.particle_swarm_optimization(
eval_func=fitness, linkage=my_linkage, bounds=bounds, order_relation=min
)
best = ensemble.top(1)[0]
my_linkage.set_num_constraints(best.dimensions)

Symbolic Analysis
Requires pip install pylinkage[symbolic]. Get closed-form trajectory expressions:
from pylinkage.symbolic import fourbar_symbolic, compute_trajectory_numeric
import numpy as np
linkage = fourbar_symbolic(ground_length=4, crank_length=1, coupler_length=3, rocker_length=3)
params = {"L1": 1.0, "L2": 3.0, "L3": 3.0}
trajectories = compute_trajectory_numeric(linkage, params, np.linspace(0, 2*np.pi, 100))

Tutorials
The docs/notebooks/ directory contains hands-on tutorials that walk through each major feature:
# |
Notebook |
What you’ll learn |
|---|---|---|
01 |
Design a mechanism that traces a straight line from scratch |
|
02 |
Use PSO to shape a four-bar coupler path |
|
03 |
Monte Carlo analysis for manufacturing variation |
|
04 |
Design cam profiles with motion laws |
|
05 |
Closed-form trajectory expressions with SymPy |
|
06 |
Match input/output angle relationships (Freudenstein) |
|
07 |
Guide a rigid body through specified poses (Burmester) |
|
08 |
Compute joint velocities and accelerations |
|
09 |
Evaluate mechanism quality and mobility |
|
10 |
Link-first definition with |
|
11 |
Pareto-optimal design with NSGA-II and scipy |
|
12 |
Side-by-side comparison of path, function, and motion synthesis |
|
13 |
Batch simulation, ranking, and filtering of mechanism families |
|
14 |
Enumerate and synthesize across all valid topologies |
|
15 |
Compose mechanisms hierarchically from reusable hypergraph components |
What Else Can It Do?
Pylinkage also supports velocity and acceleration analysis, cam-follower mechanisms with configurable motion laws, transmission angle evaluation, Monte Carlo tolerance analysis for manufacturing, multi-objective optimization (NSGA-II/III via pymoo), and export to DXF and STEP for CNC and CAD workflows. See the tutorials for details.
Architecture
Level 0: Geometry → Pure math primitives (numba-accelerated when installed)
Level 1: Solver → Assur group solvers (numba-accelerated when installed)
Level 2: Components → Ground, Crank, RRRDyad, LinearActuator, cam-followers
Level 3: Simulation → Linkage orchestration, step(), step_fast()
Level 4: Applications → Optimization, Synthesis, Symbolic, Visualization
Performance: With the numba extra, step_fast() achieves 1.5-2.5M steps/sec (4-7x faster than step()). Without numba, the same code runs in pure Python/NumPy.
Full module reference
Module |
Purpose |
Extras needed |
|---|---|---|
|
Base components: |
— |
|
Motor drivers: |
— |
|
Assur groups: |
— |
|
|
— |
|
Low-level Links+Joints model and |
— |
|
High-performance numba-compiled simulation backend |
|
|
PSO, differential evolution, grid search |
|
|
Classical synthesis: function/path/motion generation |
|
|
SymPy-based symbolic computation and gradient optimization |
|
|
Matplotlib, Plotly, SVG, DXF, and STEP export |
|
|
Assur group decomposition and graph representation |
— |
|
Hierarchical component-based linkage definition |
— |
Requirements
Python >= 3.10
Core: numpy, tqdm
Optional (via extras): numba, scipy, sympy, matplotlib, plotly, drawsvg
Contributing
Contributions welcome! Please see CONTRIBUTING.md and respect the CODE_OF_CONDUCT.md.