walker

Inheritance for Linkages

Hypergraph-native Walker for simulating and optimizing walking linkages.

A Walker stores a mechanism as a HypergraphLinkage (topology) plus Dimensions (geometry). It delegates kinematic simulation to pylinkage’s Mechanism class via to_mechanism(), naturally supporting multi-DOF mechanisms through multiple DRIVER nodes with independent angular velocities.

class leggedsnake.walker.Walker(topology: HypergraphLinkage, dimensions: Dimensions, name: str = '', motor_rates: dict[str, float] | float = -4.0, foot_edge_ids: list[str] | None = None)

Bases: object

A walking mechanism represented as a hypergraph.

The Walker holds a HypergraphLinkage (topology) and Dimensions (geometry). It supports multi-DOF mechanisms: each DRIVER node can have an independent angular velocity stored in Dimensions.driver_angles.

Kinematic simulation is delegated to pylinkage’s Mechanism class via to_mechanism(). Physics simulation is handled by converting to a DynamicLinkage (see physics_engine.World.add_linkage).

Variables:
  • topology (HypergraphLinkage) – The mechanism topology (nodes, edges, hyperedges).

  • dimensions (Dimensions) – Geometric data (node positions, edge distances, driver angles).

  • name (str) – Human-readable name.

  • motor_rates (dict[str, float] | float) – Motor angular velocities for dynamic (physics) simulation. Single float applies to all drivers. Dict maps driver node IDs to individual rates. Default -4.0 rad/s (clockwise).

__init__(topology: HypergraphLinkage, dimensions: Dimensions, name: str = '', motor_rates: dict[str, float] | float = -4.0, foot_edge_ids: list[str] | None = None) None
_apply_input_velocities(mechanism: Mechanism, omega: float | dict[str, float] | None, alpha: float | dict[str, float] | None) None

Seed each driver’s angular velocity and acceleration.

pylinkage treats a driver with no explicit input as stationary, so this has to run before every derivative sweep or the whole mechanism reports zero velocity. The default rate is the driver’s own angular_velocity — the same value _step_once advances the crank by, so positions and derivatives cannot disagree.

_foot_edge_ids: list[str] | None
_invalidate_cache() None

Invalidate cached Mechanism after topology/dimension changes.

_mechanism: Mechanism | None
property _solve_order: list[Any]

Expose the underlying mechanism’s solve order.

pylinkage 0.9’s linkage_to_solver_data (invoked from Ensemble and every optimizer that wraps it) reads linkage._solve_order. Delegating to the cached Mechanism keeps joint identities in sync with self.joints so id(joint) lookups resolve correctly.

_sync_dimensions_from_mechanism(mechanism: Mechanism) None

Sync Dimensions edge distances from Mechanism link state.

Update the edge distance in Dimensions for a given Mechanism link.

add_legs(legs: int | Sequence[float] = 1) None

Add phase-offset copies of all non-ground mechanism parts.

Each copy shares the same ground nodes but has its driver(s) phase-offset from the template. Cloned drivers remain DRIVER nodes with offset initial_angle, so each leg is independently driven at the same angular velocity.

Parameters:

legs (int or sequence of float) –

When int (default behaviour), add that many legs with phase offsets evenly spaced at tau * k / (n + 1) for k in 1..n — the classic rotating-stack gait.

When a sequence of floats, each entry is the phase offset (radians, taken modulo tau) of one new leg. This enables discovery of trot, pace, canter, bound, and other gait patterns when phase offsets are evolved by an optimizer.

add_opposite_leg(axis_x: float = 0.0) None

Create an antisymmetric (mirrored) copy of the mechanism.

The opposite leg has X-coordinates reflected across axis_x and driver initial angles offset by pi for phase opposition.

Parameters:

axis_x (float) – X-coordinate of the vertical mirror axis. Default 0.0.

dimensions: Dimensions
property dof: int

Mobility of the underlying hypergraph via Grübler’s formula.

Returns 1 for a well-formed single-input walking mechanism, 0 for a rigid structure, negative for overconstrained, >1 for under-constrained (needs more inputs).

Delegates to pylinkage.topology.compute_dof() on self.topology. Intended for fast pre-flight screening of candidates during optimization — reject DOF != 1 without paying the cost of building the mechanism and stepping it.

property foot_edge_ids: list[str] | None

Explicit foot-edge override, or None for auto-detection.

classmethod from_catalog(entry: CatalogEntry, dimensions: Dimensions, motor_rates: dict[str, float] | float = -4.0) Walker

Create a Walker from a topology catalog entry.

The catalog provides topology only (nodes, edges, roles). Dimensions (positions, distances, driver angles) must be supplied.

Parameters:
  • entry (CatalogEntry) – A topology from pylinkage.topology.load_catalog().

  • dimensions (Dimensions) – Geometric data for the topology’s nodes and edges.

  • motor_rates (float | dict[str, float]) – Motor angular velocities for dynamic simulation.

classmethod from_chebyshev(crank: float = 0.75, coupler: float = 3.75, rocker: float = 3.75, ground_length: float = 3.0, foot_ratio: float = 1.0, initial_crank_angle: float = 0.0, angular_velocity: float = -0.1308996938995747, motor_rates: float | dict[str, float] = -4.0, name: str = 'chebyshev') Walker

Build a Walker for Chebyshev’s Lambda linkage (1878).

A 4-bar crank-rocker whose coupler point traces an approximate straight line — the basis of Chebyshev’s “plantigrade machine”. The foot P rides rigidly on the coupler at distance foot_ratio * coupler from A (foot_ratio=1.0 puts P at B).

Parameters:
  • crank (float) – Link lengths. Defaults reproduce the working ratio used in the Chebyshev example.

  • coupler (float) – Link lengths. Defaults reproduce the working ratio used in the Chebyshev example.

  • rocker (float) – Link lengths. Defaults reproduce the working ratio used in the Chebyshev example.

  • ground_length (float) – Distance between ground pivots O1 and O2 (both on y=0).

  • foot_ratio (float) – Position of the foot along the A→B coupler, as a fraction of coupler (0.5 is the midpoint straight-line tracing point, 1.0 extends it to B).

  • initial_crank_angle (float) – Starting crank angle (radians).

  • angular_velocity (float) – Kinematic crank step (rad per step() iteration).

  • motor_rates (float | dict[str, float]) – Motor angular velocity (rad/s) for physics simulation.

  • name (str) – Name for the linkage.

Raises:

ValueError – If the coupler and rocker cannot meet at the chosen angle.

classmethod from_ghassaei(scale: float = 1.0, initial_crank_angle: float = 0.0, angular_velocity: float = -0.1308996938995747, motor_rates: float | dict[str, float] = -4.0, name: str = 'ghassaei') Walker

Build Amanda Ghassaei’s 5-dyad leg (Boim/Walkin8r, thesis Fig. 5.4.4).

8 nodes (A, B grounds; C crank tip; D, F off (C, B); H unnamed intermediate off (D, B); E real lower-left joint off (H, B); G foot off (E, F)), 11 bars, 5 RRR dyads. Classical Ghassaei dimensions are applied exactly: crank=26, ground=53, 56/77 inner/outer bars, 75 closing bars. H-E (not given on the figure) defaults to 130 to reproduce the Wikibooks reference foot-locus aspect (~0.243). Initial crank angle is 0.085 rad off vertical.

classmethod from_hierarchy(hierarchy: HierarchicalLinkage, dimensions: Dimensions, motor_rates: dict[str, float] | float = -4.0) Walker

Create a Walker from a hierarchical linkage composition.

Flattens the hierarchy (merging shared ports) into a single HypergraphLinkage suitable for simulation.

Parameters:
  • hierarchy (HierarchicalLinkage) – Composed mechanism with component instances and connections.

  • dimensions (Dimensions) – Geometric data for the flattened topology’s nodes and edges.

  • motor_rates (float | dict[str, float]) – Motor angular velocities for dynamic simulation.

classmethod from_jansen(scale: float = 1.0, initial_crank_angle: float = 0.0, angular_velocity: float = -0.1308996938995747, motor_rates: float | dict[str, float] = -4.0, name: str = 'jansen', lengths: dict[str, float] | None = None) Walker

Build a Walker for Theo Jansen’s 8-bar “Strandbeest” leg.

Uses Jansen’s canonical “Holy Numbers” (link lengths he discovered through decades of optimization), scaled by scale. The single foot G traces a stable walking locus for a full crank rotation.

Parameters:
  • scale (float) – Multiplier applied to every link length. Default 1.0 yields the raw Holy Numbers (~65 length units at widest); drop to ~0.04 for physics-friendly metric dimensions.

  • initial_crank_angle (float) – Starting crank angle (radians).

  • angular_velocity (float) – Kinematic crank step (rad per step() iteration). Default traces 48 samples per revolution.

  • motor_rates (float | dict[str, float]) – Motor angular velocity (rad/s) for physics simulation.

  • name (str) – Name for the linkage.

  • lengths (dict[str, float] | None) – Per-parameter overrides of the 13 length parameters (keys "a", "b", …, "m" — see leggedsnake._classical.JANSEN_HOLY_NUMBERS for the canonical values). Partial dicts are allowed. Use this to optimize link lengths directly rather than round-tripping through set_constraints, which on hypergraph walkers can’t propagate through rigid triangles.

classmethod from_klann(scale: float = 3.0, initial_crank_angle: float = 0.0, angular_velocity: float = 0.1308996938995747, motor_rates: float | dict[str, float] = 4.0, name: str = 'klann') Walker

Build a Walker for Joe Klann’s 6-bar walking linkage.

Uses the dimensions of US Patent 6,260,862, scaled by scale. The mechanism is a Stephenson-III topology with two rigid triangles: the ternary coupler (A-elbow-knee) rotates with the crank, while the ternary leg (hip-knee-foot) carries the foot.

Parameters:
  • scale (float) – Multiplier applied to every length and offset. Default 3.0 matches the canonical example visualization; patent values themselves are dimensionless ratios around 1.0.

  • initial_crank_angle (float) – Starting crank angle (radians).

  • angular_velocity (float) – Kinematic crank step (rad per step() iteration). Positive by default since the Klann mechanism walks forward under counter-clockwise rotation.

  • motor_rates (float | dict[str, float]) – Motor angular velocity (rad/s) for physics simulation.

  • name (str) – Name for the linkage.

classmethod from_stephenson(crank: float, coupler: float, rocker: float, link4: float, link5: float, link6: float, ground_length: float, ground_pivot_a: tuple[float, float] = (0.0, 0.0), initial_crank_angle: float = 0.0, motor_rates: float | dict[str, float] = -4.0, name: str = 'stephenson') Walker

Build a Walker from a Stephenson six-bar specification.

Wraps pylinkage.synthesis.stephenson_from_lengths() and feeds its result through pylinkage’s to_hypergraph bridge.

Stephenson differs from Watt in where the second loop attaches: on a Stephenson the second chain branches from the coupler joint C and ground D (so the two ternary links are separated); on a Watt the second chain branches from B and C (ternary links adjacent). See pylinkage.synthesis.stephenson_from_lengths() for the kinematic chain.

Raises:

ValueError – If pylinkage cannot assemble the mechanism at the given link lengths / initial angle.

classmethod from_strider(crank: float = 1.0, triangle: float = 2.0, femur: float = 1.8, rocker_l: float = 2.6, rocker_s: float = 1.4, tibia: float = 2.5, foot: float = 1.8, angular_velocity: float = -0.6283185307179586, motor_rates: float | dict[str, float] = -4.0, name: str = 'strider') Walker

Build a Walker for the Strider mechanism (Vagle, DIY Walkers).

The Strider is a symmetric 11-node mechanism producing two feet per crank. Its kinematic chain: ground pair (A, Y) → rigidly attached frame points (B, B_p) → knees (D, E) driven off crank C → ankles (F, G) rigid on the C-E / C-D rockers → feet (H, I).

Parameters:
  • crank (float) – Link lengths. Defaults reproduce the canonical Strider geometry documented in the gallery notebook (examples/01_walkers_gallery.ipynb).

  • triangle (float) – Link lengths. Defaults reproduce the canonical Strider geometry documented in the gallery notebook (examples/01_walkers_gallery.ipynb).

  • femur (float) – Link lengths. Defaults reproduce the canonical Strider geometry documented in the gallery notebook (examples/01_walkers_gallery.ipynb).

  • rocker_l (float) – Link lengths. Defaults reproduce the canonical Strider geometry documented in the gallery notebook (examples/01_walkers_gallery.ipynb).

  • rocker_s (float) – Link lengths. Defaults reproduce the canonical Strider geometry documented in the gallery notebook (examples/01_walkers_gallery.ipynb).

  • tibia (float) – Link lengths. Defaults reproduce the canonical Strider geometry documented in the gallery notebook (examples/01_walkers_gallery.ipynb).

  • foot (float) – Link lengths. Defaults reproduce the canonical Strider geometry documented in the gallery notebook (examples/01_walkers_gallery.ipynb).

  • angular_velocity (float) – Kinematic crank step (rad per step() iteration). Default traces 10 samples per revolution (matches the example).

  • motor_rates (float | dict[str, float]) – Motor angular velocity (rad/s) for physics simulation.

  • name (str) – Name for the linkage.

classmethod from_synthesis(solution: Any, index: int = 0, motor_rates: float | dict[str, float] = -4.0, name: str = '', iterations: int = 360) Walker

Build a Walker from any pylinkage.synthesis output.

Dimensional synthesis (Burmester path/motion/function generation, topology-aware N-bar synthesis) answers “which mechanism traces this foot path?”. This factory is the hand-off from that answer to a physics-ready walker, collapsing the solution -> SimLinkage -> Walker chain into one call.

Every solution container pylinkage emits is accepted:

Input

Produced by

SynthesisResult

path_generation, function_generation, motion_generation_3_poses, six_bar_path_generation, path_generation_with_timing

list[TopologySolution]

multi_topology_synthesize

list[NBarSolution]

generalized_synthesis

FourBarSolution

SynthesisResult.raw_solutions

Ensemble

SynthesisResult.ensemble

Linkage (SimLinkage)

solution_to_linkage, and co_optimize

Containers are indexed with index; scalars ignore it. Synthesis routines return candidates best-first, so the default index=0 picks the top-ranked solution.

Parameters:
  • solution (Any) – A synthesis result, a single solution, an Ensemble, a SimLinkage, or a sequence of any of those.

  • index (int) – Which candidate to convert when solution is a container. Negative indices count from the end.

  • motor_rates (float | dict[str, float]) – Motor angular velocities (rad/s) for physics simulation.

  • name (str) – Name for the resulting Walker. Empty keeps the name pylinkage gave the solution.

  • iterations (int) – Simulation steps per rotation, forwarded to pylinkage when a raw solution still has to be converted to a linkage. Ignored for inputs that already carry a linkage.

Returns:

Hypergraph-native walker ready for add_legs() and World.add_linkage().

Return type:

Walker

Raises:
  • TypeError – If solution is not a recognised synthesis output.

  • ValueError – If solution is an empty container.

  • IndexError – If index is out of range for solution.

  • NotImplementedError – Propagated from to_hypergraph when the solution contains a component type pylinkage cannot convert.

Examples

>>> from pylinkage.synthesis import path_generation
>>> result = path_generation(
...     precision_points=[(0, -3), (2, -3), (1, -1)],
...     max_solutions=10,
... )
>>> walker = Walker.from_synthesis(result)
>>> walker.add_legs(1)
classmethod from_trotbot(scale: float = 1.0, initial_crank_angle: float = 0.0, angular_velocity: float = -0.1308996938995747, motor_rates: float | dict[str, float] = -4.0, name: str = 'trotbot') Walker

Build a Walker for the TrotBot mechanism (Vagle, DIYwalkers).

Uses the bar lengths from Wade & Ben Vagle’s combined Python simulator published at https://www.diywalkers.com, scaled by scale. The mechanism has 10 joints, 15 binary edges, and three collinear rigid ternaries (j3-j2-j4, j5-j4-j6, j1-j2-j9) modelled as hyperedges. The foot is j7.

Parameters:
  • scale (float) – Multiplier applied to every link length and the frame offset.

  • initial_crank_angle (float) – Starting crank angle (radians).

  • angular_velocity (float) – Kinematic crank step (rad per step() iteration).

  • motor_rates (float | dict[str, float]) – Motor angular velocity (rad/s) for physics simulation.

  • name (str) – Name for the linkage.

Raises:

ValueError – If the mechanism cannot be assembled at the given crank angle.

classmethod from_watt(crank: float, coupler1: float, rocker1: float, link4: float, link5: float, rocker2: float, ground_length: float, ground_pivot_a: tuple[float, float] = (0.0, 0.0), initial_crank_angle: float = 0.0, motor_rates: float | dict[str, float] = -4.0, name: str = 'watt') Walker

Build a Walker from a Watt six-bar specification.

Wraps pylinkage.synthesis.watt_from_lengths() and feeds its result through pylinkage’s to_hypergraph bridge. A Watt six-bar has two four-bar loops sharing the crank output, yielding two coupled rocker trajectories that can serve as foot paths.

Parameters:
  • crank (float) – Link lengths. See pylinkage.synthesis.watt_from_lengths() for the kinematic chain diagram.

  • coupler1 (float) – Link lengths. See pylinkage.synthesis.watt_from_lengths() for the kinematic chain diagram.

  • rocker1 (float) – Link lengths. See pylinkage.synthesis.watt_from_lengths() for the kinematic chain diagram.

  • link4 (float) – Link lengths. See pylinkage.synthesis.watt_from_lengths() for the kinematic chain diagram.

  • link5 (float) – Link lengths. See pylinkage.synthesis.watt_from_lengths() for the kinematic chain diagram.

  • rocker2 (float) – Link lengths. See pylinkage.synthesis.watt_from_lengths() for the kinematic chain diagram.

  • ground_length (float) – Distance between ground pivots A and D.

  • ground_pivot_a ((float, float)) – World position of ground pivot A.

  • initial_crank_angle (float) – Starting crank angle (radians).

  • motor_rates (float | dict[str, float]) – Motor angular velocities applied to the resulting Walker.

  • name (str) – Name for the linkage.

Raises:

ValueError – If pylinkage cannot assemble the mechanism at the given link lengths / initial angle.

get_constraints() list[float]

Get optimizable constraints as a flat list of floats.

Returns edge distances from the Mechanism (link lengths), compatible with pylinkage optimizers that sniff linkage.get_constraints().

get_coords() list[tuple[float, float]]

Get current joint positions as a list of (x, y) tuples.

get_feet() list[str]

Return node IDs of foot joints.

Detection heuristic (in priority order):

  1. Terminal nodes (degree 1, non-ground, non-driver) — classic walking linkages like Theo Jansen or Klann.

  2. Outermost driven nodes — nodes that are DRIVEN and whose neighbours are all either GROUND, DRIVER, or already identified as feet. This catches coupler points (P) in synthesised four-bars where P connects to B and C but is the true foot.

If auto-detection returns nothing, every DRIVEN node is considered a candidate (safe fallback that preserves the old “all edges collide” behaviour until the user specifies manually).

get_foot_edges() list[str]

Return edge IDs of edges that connect to foot nodes.

Foot edges are the only edges that should collide with the ground during physics simulation. By default, every edge with at least one foot endpoint (as returned by get_feet()) is considered a foot edge. Override or set foot_edge_ids to customise.

get_num_constraints(flat: bool = True) list[float]

Deprecated alias for get_constraints().

Deprecated since version 0.6.0: Use get_constraints(). Removed in 0.7.0.

get_rotation_period() int

Number of steps for one full rotation cycle.

property joints: list[Any]

Mechanism joints in solve order.

Surface pylinkage’s compatibility hook: pylinkage._compat.get_parts sniffs for .joints or .components to iterate over a linkage’s parts. Optimizers such as chain_optimizers / minimize_linkage / particle_swarm_optimization rely on it.

mirror_leg(axis_x: float = 0.0) None

Create an antisymmetric (mirrored) copy of the mechanism.

The opposite leg has X-coordinates reflected across axis_x and driver initial angles offset by pi for phase opposition.

Parameters:

axis_x (float) – X-coordinate of the vertical mirror axis. Default 0.0.

property mobility: MobilityInfo

Full MobilityInfo (DOF, link count, joint counts).

See dof for the scalar-only variant. Delegates to pylinkage.topology.compute_mobility().

motor_rates: dict[str, float] | float
name: str
set_constraints(values: list[float] | list[list[float]]) None

Set constraints from a list of floats.

Nested input (as returned by a param_expander such as param2dimensions) is flattened in order; flat input is used as-is. Updates the Mechanism, then syncs edge distances back to Dimensions.

set_coords(coords: list[tuple[float, float]] | list[tuple[float | None, float | None]]) None

Set joint positions.

set_num_constraints(constraints: list[float] | list[list[float]], flat: bool = True) None

Deprecated alias for set_constraints().

Accepts a flat list of floats or a nested list that will be flattened in order.

Deprecated since version 0.6.0: Use set_constraints(), which now flattens nested input itself. Removed in 0.7.0.

step(iterations: int | None = None, dt: float = 1.0, skip_unbuildable: bool = False) Generator[tuple[tuple[float, float] | tuple[float | None, float | None], ...], None, None]

Simulate one full rotation of the mechanism.

Delegates to Mechanism.step(). Each driver advances independently.

Parameters:
  • iterations (int | None) – Number of simulation steps. If None, uses one full rotation period.

  • dt (float) – Time step multiplier.

  • skip_unbuildable (bool) – If True, yield (None, None) tuples for iterations where the mechanism cannot be assembled, instead of raising UnbuildableError. Drivers keep advancing so the trajectory resumes on the buildable side of dead zones. Mirrors pylinkage.linkage.Linkage.step’s parameter of the same name.

Yields:

tuple of (x, y) coordinate tuples – Joint positions at each step.

step_with_derivatives(iterations: int | None = None, dt: float = 1.0, skip_unbuildable: bool = False, omega: float | dict[str, float] | None = None, alpha: float | dict[str, float] | None = None) Generator[tuple[tuple[tuple[float, float] | tuple[float | None, float | None], ...], tuple[tuple[float, float] | tuple[None, None], ...], tuple[tuple[float, float] | tuple[None, None], ...]], None, None]

Simulate one rotation, yielding per-frame positions, velocities, accelerations.

Velocities and accelerations are solved analytically by pylinkage (solver.velocity / solver.acceleration) rather than differenced from the position stream, so they are exact at every frame — including the first and last, where a finite-difference estimate has to degrade to a one-sided stencil.

Rates default to each driver’s own angular_velocity, which is expressed in radians per simulation step. One step spans dt time units and advances the crank by angular_velocity * dt radians, so the derivatives come out per unit time and are independent of dt. Pass omega / alpha to drive the mechanism at physical rates instead.

Note

A joint can still come back (None, None) on an otherwise buildable frame — prismatic joints, and genuine dead centres where the mechanism is at a toggle. Those are honest reports of an indeterminate derivative, and they propagate: a joint solved from an undefined anchor is undefined too, rather than being solved against an anchor assumed stationary. Requires pylinkage >= 1.1.0; on 1.0.0, joints collinear with their anchors (from_chebyshev’s foot, several of from_trotbot’s) report no derivative, and the joints downstream of those report wrong ones.

Parameters:
  • iterations (int | None) – Number of simulation steps. If None, one full rotation period.

  • dt (float) – Time step multiplier, as in step().

  • skip_unbuildable (bool) – If True, frames where the mechanism cannot be assembled yield (None, None) for every joint in all three tuples instead of raising UnbuildableError. Drivers keep advancing, so the stream resumes on the far side of a dead zone and its length always equals iterations.

  • omega (float | dict[str, float] | None) – Driver angular velocity to differentiate against. A float applies to every driver, a dict maps driver node id → rate. None uses each driver’s own angular_velocity.

  • alpha (float | dict[str, float] | None) – Driver angular acceleration, same shape as omega. Defaults to 0 — a constant-speed crank. This is the only way to express a driver that is spinning up or down; without it accelerations describe centripetal terms alone.

Yields:

(positions, velocities, accelerations) – Each is a tuple of per-joint (x, y) (or (None, None) where undefined). The stream’s length equals iterations.

to_mechanism() Mechanism

Convert to a pylinkage Mechanism for kinematic simulation.

The result is cached and invalidated when topology or dimensions change.

topology: HypergraphLinkage
leggedsnake.walker._derivative_pairs(values: Sequence[tuple[float, float] | None]) tuple[tuple[float, float] | tuple[None, None], ...]

Normalise pylinkage’s per-joint Coord | None to (x, y) pairs.

Upstream reports an undefined derivative as a bare None, which would make callers special-case those entries before unpacking. Every frame this module yields unpacks as two values.

leggedsnake.walker._driver_rate(spec: float | dict[str, float] | None, node_id: str | None, default: float) float

Resolve a per-driver rate from a scalar, a per-node dict, or None.

leggedsnake.walker._pick_solution(candidates: Any, index: int, origin: str) Any

Index into a synthesis container, reporting its size on failure.

leggedsnake.walker._sim_linkage_from_ensemble(ensemble: Any, index: int) Any

Materialise one Ensemble member as a standalone SimLinkage.

An Ensemble stores a single shared linkage plus one row of constraints and initial positions per member, so a member only becomes an independent mechanism once those are applied to a private copy.

leggedsnake.walker._sim_linkage_from_synthesis(solution: Any, index: int = 0, name: str = '', iterations: int = 360) Any

Resolve any pylinkage synthesis output down to a single SimLinkage.

See Walker.from_synthesis() for the accepted input types.

leggedsnake.walker._walker_from_sim_linkage(sim_linkage: object, motor_rates: float | dict[str, float] = -4.0) Walker

Convert a pylinkage SimLinkage to a Walker.

Thin wrapper over pylinkage’s native pylinkage.simulation.Linkage.to_hypergraph() bridge (available since pylinkage 1.0.0), which handles every component type upstream emits and raises NotImplementedError for any it does not.

Parameters:
  • sim_linkage (pylinkage.simulation.Linkage) – A SimLinkage, as produced by pylinkage.synthesis or pylinkage.optimization.co_optimize.

  • motor_rates (float | dict[str, float]) – Forwarded to the resulting Walker.

Returns:

Hypergraph-native walker wrapping the converted topology and dimensions.

Return type:

Walker

Raises:
  • TypeError – If sim_linkage is not a SimLinkage.

  • NotImplementedError – Propagated from to_hypergraph when the linkage contains a component type pylinkage cannot yet convert.