pylinkage.components package

Submodules

pylinkage.components.ground module

Ground component - fixed point on the frame.

A ground point is a stationary reference point in a planar mechanism. It does not move during simulation.

class pylinkage.components.ground.Ground(x: float, y: float, name: str | None = None)

Bases: Component

A fixed point on the frame (ground link).

Ground components define the stationary reference points of a mechanism. They don’t move during simulation and serve as anchors for other kinematic elements like actuators and dyads.

Example

>>> O1 = Ground(0.0, 0.0, name="O1")
>>> O2 = Ground(2.0, 0.0, name="O2")
>>> O1.position
(0.0, 0.0)
get_constraints() tuple[()]

Return empty tuple - ground has no constraints to optimize.

reload(dt: float = 1) None

No-op - ground doesn’t move.

set_constraints(*args: float | None) None

No-op - ground has no constraints.

pylinkage.components.point_tracker module

PointTracker - sensor component for tracking positions on links.

A PointTracker observes a position at fixed distance/angle from two anchors. Unlike FixedDyad, it is semantically a sensor that doesn’t affect kinematics and has no optimizable constraints.

class pylinkage.components.point_tracker.PointTracker(anchor1: Component | _AnchorProxy, anchor2: Component | _AnchorProxy, distance: float, angle: float, name: str | None = None)

Bases: ConnectedComponent

A sensor component for tracking positions on a link.

PointTracker computes its position at a fixed distance and angle from anchor1, with the angle measured relative to the line from anchor1 to anchor2. This is functionally identical to FixedDyad but is semantically a “sensor” that observes without contributing constraints to optimization.

Use PointTracker when you want to: - Track a coupler point on a link - Observe a position on a mechanism for analysis - Add tracer points without affecting optimization

Use FixedDyad when: - The distance/angle are parameters to optimize - The point is part of the mechanism structure

Variables:
  • anchor1 (Component | _AnchorProxy) – First anchor (origin for polar coordinates).

  • anchor2 (Component | _AnchorProxy) – Second anchor (defines reference direction).

  • distance (float) – Distance from anchor1 to this tracker.

  • angle (float) – Angle offset from anchor1->anchor2 direction (radians).

Example

>>> O1 = Ground(0.0, 0.0, name="O1")
>>> crank = Crank(anchor=O1, radius=1.0)
>>> O2 = Ground(2.0, 0.0, name="O2")
>>> # Track a point at 45 degrees from crank->O2 line
>>> tracker = PointTracker(
...     anchor1=crank.output,
...     anchor2=O2,
...     distance=0.5,
...     angle=math.pi/4,
...     name="tracer_point"
... )
anchor1: Component | _AnchorProxy
anchor2: Component | _AnchorProxy
property anchors: tuple[Component, Component]

Return the two parent anchors.

angle: float
distance: float
get_constraints() tuple[()]

Return empty tuple - PointTracker has no optimizable constraints.

PointTracker is a sensor/observer; its distance and angle are fixed and should not be included in optimization bounds.

Returns:

Empty tuple.

reload(dt: float = 1) None

Recompute position using polar projection.

The position is always deterministic - no ambiguity.

Parameters:

dt – Time step (unused for PointTracker, required for interface).

set_constraints(*args: float | None) None

No-op - PointTracker has no optimizable constraints.

Parameters:

*args – Ignored.

Module contents

Components - base classes and fixed frame elements.

This module provides the foundational classes for building kinematic mechanisms:

Classes:

Component: Abstract base class for all kinematic elements ConnectedComponent: Base for elements with parent connections Ground: Fixed point on the frame (ground link) PointTracker: Sensor for tracking positions on links _AnchorProxy: Proxy for output position access (internal)

The Component class serves as the base for all user-facing kinematic building blocks including: - Ground points (this module) - Actuators (see pylinkage.actuators) - Assur dyads (see pylinkage.dyads)

class pylinkage.components.Component(x: float | None, y: float | None, name: str | None = None)

Bases: ABC

Base class for all kinematic building blocks.

A component represents a kinematic element in a planar linkage mechanism. Each component has a position (x, y) and can compute its constraints.

Variables:
  • x (float | None) – Horizontal position coordinate.

  • y (float | None) – Vertical position coordinate.

  • name (str) – Human-readable identifier.

  • velocity – Linear velocity (vx, vy) in units/s. None if not computed.

  • acceleration – Linear acceleration (ax, ay) in units/s². None if not computed.

property acceleration: tuple[float, float] | None

Return linear acceleration (ax, ay) in units/s².

Returns None if acceleration has not been computed.

coord() tuple[float | None, float | None]

Return cartesian coordinates (alias for position).

abstractmethod get_constraints() tuple[float | None, ...]

Return constraint values for optimization.

Returns:

Tuple of constraint values (distances, angles, etc.).

name: str
property position: tuple[float | None, float | None]

Return current (x, y) position.

abstractmethod reload(dt: float = 1) None

Recompute position based on parent positions.

Parameters:

dt – Time step or fraction of movement.

abstractmethod set_constraints(*args: float | None) None

Set constraint values from optimization.

Parameters:

*args – Constraint values to apply.

set_coord(x: float | None, y: float | None) None

Set cartesian coordinates.

Parameters:
  • x – Horizontal position coordinate.

  • y – Vertical position coordinate.

property velocity: tuple[float, float] | None

Return linear velocity (vx, vy) in units/s.

Returns None if velocity has not been computed.

x: float | None
y: float | None
class pylinkage.components.ConnectedComponent(x: float | None, y: float | None, name: str | None = None)

Bases: Component

Base class for components that connect to parent elements.

Connected components have one or more anchor points that they reference for position computation.

abstract property anchors: tuple[Component, ...]

Return the parent components this connects to.

Returns:

Tuple of parent Component objects.

class pylinkage.components.Ground(x: float, y: float, name: str | None = None)

Bases: Component

A fixed point on the frame (ground link).

Ground components define the stationary reference points of a mechanism. They don’t move during simulation and serve as anchors for other kinematic elements like actuators and dyads.

Example

>>> O1 = Ground(0.0, 0.0, name="O1")
>>> O2 = Ground(2.0, 0.0, name="O2")
>>> O1.position
(0.0, 0.0)
get_constraints() tuple[()]

Return empty tuple - ground has no constraints to optimize.

reload(dt: float = 1) None

No-op - ground doesn’t move.

set_constraints(*args: float | None) None

No-op - ground has no constraints.

class pylinkage.components.PointTracker(anchor1: Component | _AnchorProxy, anchor2: Component | _AnchorProxy, distance: float, angle: float, name: str | None = None)

Bases: ConnectedComponent

A sensor component for tracking positions on a link.

PointTracker computes its position at a fixed distance and angle from anchor1, with the angle measured relative to the line from anchor1 to anchor2. This is functionally identical to FixedDyad but is semantically a “sensor” that observes without contributing constraints to optimization.

Use PointTracker when you want to: - Track a coupler point on a link - Observe a position on a mechanism for analysis - Add tracer points without affecting optimization

Use FixedDyad when: - The distance/angle are parameters to optimize - The point is part of the mechanism structure

Variables:
  • anchor1 (Component | _AnchorProxy) – First anchor (origin for polar coordinates).

  • anchor2 (Component | _AnchorProxy) – Second anchor (defines reference direction).

  • distance (float) – Distance from anchor1 to this tracker.

  • angle (float) – Angle offset from anchor1->anchor2 direction (radians).

Example

>>> O1 = Ground(0.0, 0.0, name="O1")
>>> crank = Crank(anchor=O1, radius=1.0)
>>> O2 = Ground(2.0, 0.0, name="O2")
>>> # Track a point at 45 degrees from crank->O2 line
>>> tracker = PointTracker(
...     anchor1=crank.output,
...     anchor2=O2,
...     distance=0.5,
...     angle=math.pi/4,
...     name="tracer_point"
... )
anchor1: Component | _AnchorProxy
anchor2: Component | _AnchorProxy
property anchors: tuple[Component, Component]

Return the two parent anchors.

angle: float
distance: float
get_constraints() tuple[()]

Return empty tuple - PointTracker has no optimizable constraints.

PointTracker is a sensor/observer; its distance and angle are fixed and should not be included in optimization bounds.

Returns:

Empty tuple.

reload(dt: float = 1) None

Recompute position using polar projection.

The position is always deterministic - no ambiguity.

Parameters:

dt – Time step (unused for PointTracker, required for interface).

set_constraints(*args: float | None) None

No-op - PointTracker has no optimizable constraints.

Parameters:

*args – Ignored.