Class and method signatures for Molenspin 0.4.x. Generated from source docstrings; last updated 2026-05-08.
class Assembly(
name: str = "assembly",
gravity: float = 9.81,
default_module: float = 2.0,
backlash: float = 0.0,
frame_origin: tuple[float, float] = (0.0, 0.0),
)
Top-level container for a kinematic model.
def add_shaft(
omega_rpm: float | None = None,
omega_rad: float | None = None,
name: str = "",
) -> Shaft
Add a shaft. Specify angular velocity in RPM or rad/s (not both). If neither is given, the shaft is free and its velocity is determined by constraints.
def add_gear(
teeth: int,
driven_by: Shaft | None = None,
meshes_with: Gear | None = None,
module: float | None = None,
pressure_angle: float = 20.0,
helix_angle: float = 0.0,
name: str = "",
) -> Gear
def simulate(
duration: float,
dt: float = 1e-3,
integrator: str = "rk4",
rtol: float = 1e-6,
atol: float = 1e-9,
warm_start: bool = True,
record_contacts: bool = False,
) -> SimResult
class Shaft:
name: str
omega_rpm: float # current angular velocity in RPM
omega_rad: float # current angular velocity in rad/s
theta: float # current angular position in radians
class Gear:
teeth: int
module: float
shaft: Shaft # the shaft this gear sits on
pitch_radius: float # = module * teeth / 2 (mm)
name: str
class SimResult:
dt: float
n_steps: int
shafts: dict[str, ShaftHistory]
def print_summary(self) -> None: ...
def export_svg(self, path: str, fps: int = 30,
duration: float | None = None, **kwargs) -> None: ...
def export_json(self, path: str, indent: int = 0) -> None: ...
class ShaftHistory:
name: str
omega_history: np.ndarray # shape (n_steps,), rad/s
theta_history: np.ndarray # shape (n_steps,), radians
omega_rpm: float # final value
n_revolutions: float # total revolutions over simulation
class BevelPair:
def __init__(
self,
gear_a: Gear,
gear_b: Gear,
shaft_angle: float = 90.0,
): ...
class BeltDrive:
def __init__(
self,
sprocket_driver: Gear,
sprocket_driven: Gear,
slip: float = 0.0,
): ...
class Constraint:
"""Subclass this to add custom algebraic constraints."""
def residual(self, state: np.ndarray) -> float: ...
def jacobian(self, state: np.ndarray) -> np.ndarray: ...
Custom constraints are registered with asm.add_constraint(my_constraint). See the geometry engine post for an example of a fixed-pivot constraint used in the windmill model.
| Exception | Raised when |
|---|---|
ms.OverdeterminedError | The constraint graph has more equations than degrees of freedom. |
ms.UnderdeterminedError | At least one shaft has no constraints and is free-floating. |
ms.ConvergenceError | The Newton solver didn't converge within the maximum iterations. |
ms.TopologyError | A gear mesh creates a cycle in the assembly graph. |