dynamic_linkage

Interface to dynamic compatible joints

Dynamic linkage: pymunk physics wrapper for hypergraph-based linkages.

Provides DynamicLinkage which converts a HypergraphLinkage + Dimensions into pymunk rigid bodies and constraints for physics simulation.

class leggedsnake.dynamic_linkage.DynamicLinkage(topology: HypergraphLinkage, dimensions: Dimensions, space: Space, motor_rates: float | dict[str, float] | None = None, density: float = 1, load: float = 0, thickness: float = 0.1, name: str = '', foot_edge_ids: set[str] | None = None)

Bases: object

Physics simulation wrapper for a hypergraph linkage.

Converts a HypergraphLinkage + Dimensions into pymunk rigid bodies and constraints. Each edge becomes a rigid body, and nodes where multiple bodies meet get PivotJoint constraints.

Variables:
  • body (pm.Body) – The frame/chassis body (load).

  • rigidbodies (list[pm.Body]) – All physics bodies including the load body.

  • joints (tuple[NodeProxy, ...]) – Proxy objects for reading node positions from physics.

  • mass (float) – Total mass of all bodies.

  • space (pm.Space) – The pymunk simulation space.

  • physics_mapping (PhysicsMapping) – Mapping from hypergraph elements to pymunk objects.

__init__(topology: HypergraphLinkage, dimensions: Dimensions, space: Space, motor_rates: float | dict[str, float] | None = None, density: float = 1, load: float = 0, thickness: float = 0.1, name: str = '', foot_edge_ids: set[str] | None = None) None

Create a DynamicLinkage from a hypergraph.

Parameters:
  • topology (HypergraphLinkage) – The mechanism topology.

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

  • space (pm.Space) – Pymunk simulation space.

  • motor_rates (MotorRates | None) – Motor angular velocities. Single float for all drivers, or dict mapping driver node IDs to individual rates (multi-DOF).

  • density (float) – Density for body mass calculation.

  • load (float) – Mass of the load/chassis body.

  • thickness (float) – Radius of segment shapes.

  • name (str) – Human-readable name.

  • foot_edge_ids (set[str] | None) – Edge IDs whose segments should collide with the ground. All other edges (and the load body) will pass through the ground. None disables selective collision (all edges collide with the ground, legacy behaviour).

_build_load(position: Vec2d, load_mass: float, use_non_foot: bool = False) Body

Create the load/chassis body.

_dimensions: Dimensions
_hypergraph: HypergraphLinkage
_non_foot_filter: ShapeFilter | None
_thickness: float
body: Body
density: float
filter: ShapeFilter
get_all_positions() dict[str, tuple[float, float]]

Get current world positions of all nodes.

height: float
joints: tuple[NodeProxy, ...]
mass: float
mechanical_energy: float
name: str
physics_mapping: PhysicsMapping
rigidbodies: list[Body]
space: Space
leggedsnake.dynamic_linkage.GROUND_FILTER = (0, 4, 1)

Collision filter for ground / road segments.

Category bit 2 (0x4). Mask 0x1 means the ground only collides with foot edges (category 0x1), ignoring non-foot linkage parts (category 0x2). When no foot edges are specified (legacy mode) every linkage shape stays in pymunk’s default collision regime and this filter is unused.

class leggedsnake.dynamic_linkage.NodeProxy(node_id: str, role: NodeRole, mapping: PhysicsMapping, name: str | None = None)

Bases: object

Lightweight proxy for reading a node’s physics position.

Provides .x, .y, .coord(), .name, .role, and .reload() for compatibility with physics engine and visualizer code.

__init__(node_id: str, role: NodeRole, mapping: PhysicsMapping, name: str | None = None) None
_mapping
_node_id
_role
_x
_y
coord() tuple[float, float]
name
reload() None

Update cached coordinates from physics body positions.

property role: NodeRole
property x: float
property y: float
leggedsnake.dynamic_linkage.convert_to_dynamic_linkage(source: Walker, space: pm.Space, density: float = 1, load: float = 1, motor_rates: MotorRates | None = None) DynamicLinkage

Convert a Walker to a DynamicLinkage.

Parameters:
  • source (Walker) – The mechanism to convert.

  • space (pm.Space) – Pymunk simulation space.

  • density (float) – Density for body mass calculation.

  • load (float) – Mass of the load/chassis.

  • motor_rates (MotorRates | None) – Motor angular velocities. If None, uses source.motor_rates.