Skip to main content

Simulate and optimize planar leg mechanisms using PSO and GA

Project description

leggedsnake

PyPI version fury.io Downloads License: MIT

LeggedSnake is a Python toolkit for designing, simulating, and optimizing planar walking linkages. It layers a pymunk physics engine and multi-objective optimizers on top of pylinkage's kinematic model, so you can go from a mechanism sketch to an evolved walker in a few lines of code.

Strider optimized over 10 generations

One Strider mechanism optimized over 10 generations of a genetic algorithm, rendered walking on flat ground with 4 phase-offset legs (2 per side, mirrored).

Installation

From PyPI:

pip install leggedsnake

From source with uv:

git clone https://github.com/hugofara/leggedsnake
cd leggedsnake
uv sync

Quick start

A walker in five lines — the canonical Theo Jansen "Strandbeest" built from the Holy Numbers, mirrored left/right and cloned into four phase-offset pairs for stance stability, rendered in a live pyglet window:

import leggedsnake as ls

walker = ls.Walker.from_jansen(scale=0.1)
walker.add_opposite_leg()            # mirror for left/right pair
walker.add_legs(3)                   # 4 legs per side → 8-leg Strandbeest
ls.video(walker, duration=10)        # live simulation

Theo Jansen Strandbeest walking

Fewer legs pitch 10–20° and can tip over; four legs per side keeps at least two feet in stance at every crank angle, which is why real Strandbeests have many legs.

Other classical mechanisms ship as one-line factories too: Walker.from_strider, Walker.from_klann, Walker.from_chebyshev, Walker.from_watt, and Walker.from_catalog (pylinkage's topology catalog).

To build a custom mechanism, declare its topology (nodes + edges) and dimensions separately:

from math import tau
import leggedsnake as ls
from leggedsnake import (
    HypergraphLinkage, Node, Edge, NodeRole,
    Dimensions, DriverAngle, Walker,
)

hg = HypergraphLinkage(name="MyWalker")
for node_id, role in [
    ("frame", NodeRole.GROUND), ("frame2", NodeRole.GROUND),
    ("crank", NodeRole.DRIVER),
    ("upper", NodeRole.DRIVEN), ("foot", NodeRole.DRIVEN),
]:
    hg.add_node(Node(node_id, role=role))
for edge in [
    ("frame_crank", "frame", "crank"), ("frame2_upper", "frame2", "upper"),
    ("crank_upper", "crank", "upper"),
    ("crank_foot", "crank", "foot"), ("upper_foot", "upper", "foot"),
]:
    hg.add_edge(Edge(*edge))

dims = Dimensions(
    node_positions={
        "frame": (0, 0), "frame2": (2, 0),
        "crank": (1, 0), "upper": (1, 2), "foot": (1, 3),
    },
    edge_distances={
        "frame_crank": 1.0, "frame2_upper": 2.24,
        "crank_upper": 2.0, "crank_foot": 3.16, "upper_foot": 1.0,
    },
    driver_angles={"crank": DriverAngle(angular_velocity=-tau / 12)},
)

walker = Walker(hg, dims, name="My Walker")
walker.add_opposite_leg(axis_x=1.0)  # mirror for left/right pair
walker.add_legs(1)                   # add a phase-offset copy
ls.video(walker)

What you can do with it

Capability Entry points
Build mechanisms Walker, HypergraphLinkage, Walker.from_strider/jansen/klann/chebyshev/watt/catalog
Kinematic fitness leggedsnake.utility.stride, leggedsnake.utility.step
Physics simulation World, video, all_linkages_video, video_debug
Dynamic fitness DistanceFitness, EfficiencyFitness, StrideFitness, StabilityFitness, CompositeFitness
Single-objective GA GeneticOptimization, genetic_algorithm_optimization
Multi-objective (NSGA) nsga_walking_optimization, NsgaWalkingConfig
Topology co-design topology_walking_optimization, optimize_walking_mechanism
Gait & stability analyze_gait, StabilityTimeSeries, compute_tip_over_margin
Export to_urdf (ROS), save_walker (JSON), save_walker_svg
Plotting plot_pareto_front, plot_gait_diagram, plot_foot_trajectories, plot_optimization_dashboard

Documentation

  • Concepts guide — orientation to the three core ideas: topology + dimensions = walker, the DynamicFitness protocol, and the optimizer landscape from fast-kinematic to dynamic-multi-objective.
  • paramsWorldConfig migration guide — for code written against the legacy global params dict.
  • Full API reference — modules grouped by capability (Mechanism, Physics, Evaluation, Optimization, I/O & Plotting).

Tutorials and deeper examples

Start with the numbered notebooks — they walk through the full pipeline end to end:

  1. examples/01_walkers_gallery.ipynb — build and inspect the classical linkages.
  2. examples/02_physics_and_fitness.ipynb — physics simulation and fitness evaluation.
  3. examples/03_genetic_optimization.ipynb — evolve a walker with the genetic algorithm.
  4. examples/04_multi_objective_and_gait.ipynb — NSGA Pareto fronts plus gait / stability analysis.
  5. examples/05_topology_co_optimization.ipynb — topology + dimensions co-optimization, plus the Phase 8.3 evolve_offsets chromosome that co-evolves gait pattern alongside structure and geometry.
  6. examples/06_export_and_share.ipynb — JSON serialization, URDF export for ROS / Gazebo, SVG snapshots, and interactive plotly visualization.

The examples/tools/ directory holds maintenance scripts, not tutorials: verify_mechanisms.py renders foot-trajectory plots for every classical builder (Walker.from_jansen / from_klann / from_chebyshev) as a smoke test, and generate_readme_gifs.py regenerates the two animated GIFs above deterministically via matplotlib PillowWriter (headless).

Tips for faster experiments

  • Visualize early and often. Every optimizer will hand you a linkage with a better score; only the animation tells you whether it walks the way you wanted.
  • Don't start from a hand-tuned optimum. A random starting population is more robust against collapsing into a nearby suboptimum.
  • Exploit symmetry. A Strider half-leg has the same kinematic stride as the full mechanism and evaluates an order of magnitude faster. Use kinematic PSO on the reduced problem, then hand off the winner to a dynamic GA on the full mechanism. Kinematic half Strider
  • Checkpoint long runs. GeneticOptimization(..., startnstop="run.json") resumes automatically on the next launch.
  • Wrap optimization scripts in if __name__ == "__main__": — the GA and NSGA optimizers spawn worker processes.

Contributing

Contributions, feature requests, and "look at this weird walker" submissions are all welcome. See CONTRIBUTING.md for the developer workflow, or drop by the GitHub discussions. A star or a link to your favourite walker also helps.

Quick links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

leggedsnake-0.5.0.tar.gz (171.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

leggedsnake-0.5.0-py3-none-any.whl (123.4 kB view details)

Uploaded Python 3

File details

Details for the file leggedsnake-0.5.0.tar.gz.

File metadata

  • Download URL: leggedsnake-0.5.0.tar.gz
  • Upload date:
  • Size: 171.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for leggedsnake-0.5.0.tar.gz
Algorithm Hash digest
SHA256 dad349eaedb53e0a4e866fd82579afbaf1c605d1b982728c04eb5c4b1ad817a4
MD5 61aabb5cedd68ef98f1f547abba5f642
BLAKE2b-256 0115ad3667711141f5abf8cbf967db9f3fe2b6e5a2159cd2753ef6cae74fc7c0

See more details on using hashes here.

File details

Details for the file leggedsnake-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: leggedsnake-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 123.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for leggedsnake-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2795acb96e850a0df855e7b0764cc42f8f9f9688d747d2cde8cf14f440d73c3e
MD5 e0c099572624edab47f21431628c75c2
BLAKE2b-256 16498dcf25d27fce2a0e64303f3e94409201a24700d9823fcf91737cf4cf7987

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page