pylinkage package
Subpackages
- pylinkage.actuators package
- pylinkage.assur package
- Submodules
- pylinkage.assur.analysis module
MobilityResultMobilityResult.degree_of_freedomMobilityResult.is_determinateMobilityResult.is_overconstrainedMobilityResult.is_underconstrainedMobilityResult.is_valid_mechanismMobilityResult.mobility_statusMobilityResult.num_1dof_jointsMobilityResult.num_2dof_jointsMobilityResult.num_driver_jointsMobilityResult.num_ground_jointsMobilityResult.num_jointsMobilityResult.num_linksMobilityResult.warnings
StructuralAnalysis
- pylinkage.assur.assur_mechanism module
AssurMechanismAssurMechanism.analyze()AssurMechanism.assur_groupsAssurMechanism.decompositionAssurMechanism.degree_of_freedomAssurMechanism.from_graph()AssurMechanism.from_mechanism()AssurMechanism.get_joint_positions()AssurMechanism.graphAssurMechanism.is_valid()AssurMechanism.mechanismAssurMechanism.num_assur_groupsAssurMechanism.num_driver_nodesAssurMechanism.num_ground_nodesAssurMechanism.reset()AssurMechanism.step()AssurMechanism.validate()
- pylinkage.assur.decomposition module
- pylinkage.assur.graph module
EdgeLinkageGraphLinkageGraph.add_edge()LinkageGraph.add_node()LinkageGraph.copy()LinkageGraph.degree()LinkageGraph.driven_nodes()LinkageGraph.driver_nodes()LinkageGraph.edgesLinkageGraph.get_edge_between()LinkageGraph.get_edges_for_node()LinkageGraph.ground_nodes()LinkageGraph.nameLinkageGraph.neighbors()LinkageGraph.nodesLinkageGraph.remove_edge()LinkageGraph.remove_node()
Node
- pylinkage.assur.groups module
- pylinkage.assur.hypergraph_conversion module
- pylinkage.assur.mechanism_conversion module
- pylinkage.assur.serialization module
- pylinkage.assur.signature module
- Module contents
- pylinkage.bridge package
- pylinkage.cam package
- Submodules
- pylinkage.cam.motion_laws module
- pylinkage.cam.profiles module
CamProfileFunctionProfileFunctionProfile.base_radiusFunctionProfile.dwell_high_endFunctionProfile.evaluate()FunctionProfile.evaluate_derivative()FunctionProfile.fall_endFunctionProfile.get_constraints()FunctionProfile.motion_lawFunctionProfile.nameFunctionProfile.rise_endFunctionProfile.rise_startFunctionProfile.set_constraints()FunctionProfile.to_numba_data()FunctionProfile.total_lift
PointArrayProfile
- Module contents
- pylinkage.components package
- pylinkage.dyads package
- Submodules
- pylinkage.dyads.factory module
- pylinkage.dyads.fixed module
- pylinkage.dyads.oscillating_cam module
OscillatingCamFollowerOscillatingCamFollower.anchorsOscillatingCamFollower.angular_displacementOscillatingCamFollower.arm_angleOscillatingCamFollower.arm_lengthOscillatingCamFollower.cam_angleOscillatingCamFollower.cam_driverOscillatingCamFollower.get_constraints()OscillatingCamFollower.initial_angleOscillatingCamFollower.outputOscillatingCamFollower.pivot_anchorOscillatingCamFollower.profileOscillatingCamFollower.reload()OscillatingCamFollower.roller_radiusOscillatingCamFollower.set_constraints()
- pylinkage.dyads.pp module
- pylinkage.dyads.rrp module
- pylinkage.dyads.rrr module
- pylinkage.dyads.translating_cam module
TranslatingCamFollowerTranslatingCamFollower.anchorsTranslatingCamFollower.cam_angleTranslatingCamFollower.cam_driverTranslatingCamFollower.displacementTranslatingCamFollower.get_constraints()TranslatingCamFollower.guideTranslatingCamFollower.guide_angleTranslatingCamFollower.outputTranslatingCamFollower.profileTranslatingCamFollower.reload()TranslatingCamFollower.roller_radiusTranslatingCamFollower.set_constraints()
- Module contents
- pylinkage.geometry package
- pylinkage.hypergraph package
- Submodules
- pylinkage.hypergraph.core module
- pylinkage.hypergraph.graph module
HypergraphLinkageHypergraphLinkage.add_edge()HypergraphLinkage.add_hyperedge()HypergraphLinkage.add_node()HypergraphLinkage.all_neighbors()HypergraphLinkage.copy()HypergraphLinkage.degree()HypergraphLinkage.driven_nodes()HypergraphLinkage.driver_nodes()HypergraphLinkage.edgesHypergraphLinkage.get_edge_between()HypergraphLinkage.get_edges_for_node()HypergraphLinkage.get_hyperedges_for_node()HypergraphLinkage.ground_nodes()HypergraphLinkage.hyperdegree()HypergraphLinkage.hyperedge_neighbors()HypergraphLinkage.hyperedgesHypergraphLinkage.nameHypergraphLinkage.neighbors()HypergraphLinkage.nodesHypergraphLinkage.remove_edge()HypergraphLinkage.remove_hyperedge()HypergraphLinkage.remove_node()HypergraphLinkage.to_simple_graph()
- pylinkage.hypergraph.hierarchy module
- pylinkage.hypergraph.mechanism_conversion module
- pylinkage.hypergraph.serialization module
component_instance_from_dict()component_instance_to_dict()connection_from_dict()connection_to_dict()edge_from_dict()edge_to_dict()graph_from_dict()graph_from_json()graph_to_dict()graph_to_json()hierarchical_from_dict()hierarchical_from_json()hierarchical_to_dict()hierarchical_to_json()hyperedge_from_dict()hyperedge_to_dict()node_from_dict()node_to_dict()
- pylinkage.hypergraph.sim_conversion module
- Module contents
- pylinkage.linkage package
- Submodules
- pylinkage.linkage.analysis module
- pylinkage.linkage.sensitivity module
SensitivityAnalysisSensitivityAnalysis.baseline_path_metricSensitivityAnalysis.baseline_transmissionSensitivityAnalysis.constraint_namesSensitivityAnalysis.most_sensitiveSensitivityAnalysis.perturbation_deltaSensitivityAnalysis.perturbed_path_metricsSensitivityAnalysis.perturbed_transmissionSensitivityAnalysis.sensitivitiesSensitivityAnalysis.sensitivity_rankingSensitivityAnalysis.to_dataframe()
ToleranceAnalysisanalyze_sensitivity()analyze_tolerance()
- pylinkage.linkage.transmission module
StrokeAnalysisTransmissionAngleAnalysisTransmissionAngleAnalysis.acceptable_rangeTransmissionAngleAnalysis.anglesTransmissionAngleAnalysis.is_acceptableTransmissionAngleAnalysis.max_angleTransmissionAngleAnalysis.max_angle_stepTransmissionAngleAnalysis.max_deviationTransmissionAngleAnalysis.mean_angleTransmissionAngleAnalysis.min_angleTransmissionAngleAnalysis.min_angle_stepTransmissionAngleAnalysis.min_deviationTransmissionAngleAnalysis.plot()TransmissionAngleAnalysis.worst_angle()
analyze_stroke()analyze_transmission()compute_slide_position()compute_transmission_angle()stroke_at_position()transmission_angle_at_position()
- Module contents
- pylinkage.mechanism package
- Submodules
- pylinkage.mechanism.builder module
ConnectionMechanismBuilderMechanismBuilder.add_arc_driver_link()MechanismBuilder.add_driver_link()MechanismBuilder.add_ground_link()MechanismBuilder.add_link()MechanismBuilder.add_point_tracker()MechanismBuilder.add_quaternary_link()MechanismBuilder.add_slide_axis()MechanismBuilder.add_ternary_link()MechanismBuilder.build()MechanismBuilder.connect()MechanismBuilder.connect_prismatic()MechanismBuilder.nameMechanismBuilder.set_branch()
PendingLinkPendingTrackerPortPrismaticConnectionSlideAxis
- pylinkage.mechanism.factories module
- pylinkage.mechanism.joint module
- pylinkage.mechanism.link module
- pylinkage.mechanism.mechanism module
MechanismMechanism.analyze_sensitivity()Mechanism.analyze_stroke()Mechanism.analyze_tolerance()Mechanism.analyze_transmission()Mechanism.compile()Mechanism.get_accelerations()Mechanism.get_constraints()Mechanism.get_coords()Mechanism.get_joint()Mechanism.get_joint_positions()Mechanism.get_link()Mechanism.get_rotation_period()Mechanism.get_velocities()Mechanism.groundMechanism.indeterminacy()Mechanism.jointsMechanism.linksMechanism.nameMechanism.rebuild()Mechanism.reset()Mechanism.set_completely()Mechanism.set_constraints()Mechanism.set_coords()Mechanism.set_input_velocity()Mechanism.set_joint_positions()Mechanism.simulation()Mechanism.step()Mechanism.step_fast()Mechanism.step_fast_with_kinematics()Mechanism.step_with_derivatives()Mechanism.stroke_position()Mechanism.transmission_angle()
- pylinkage.mechanism.serialization module
- Module contents
- pylinkage.optimization package
- Subpackages
- Submodules
- pylinkage.optimization.async_optimization module
- pylinkage.optimization.co_optimization_types module
CoOptSolutionCoOptimizationConfigCoOptimizationConfig.algorithmCoOptimizationConfig.crossover_probCoOptimizationConfig.dimension_bounds_factorCoOptimizationConfig.dimension_mutation_sigmaCoOptimizationConfig.max_linksCoOptimizationConfig.n_generationsCoOptimizationConfig.pop_sizeCoOptimizationConfig.seedCoOptimizationConfig.topology_mutation_rateCoOptimizationConfig.verbose
CoOptimizationResultMixedChromosome
- pylinkage.optimization.grid_search module
- pylinkage.optimization.mixed_variable module
- pylinkage.optimization.multi_objective module
- pylinkage.optimization.operators module
- pylinkage.optimization.particle_swarm module
- pylinkage.optimization.scipy_optimize module
- pylinkage.optimization.topology_neighborhood module
- pylinkage.optimization.utils module
- pylinkage.optimization.warm_start module
- Module contents
- pylinkage.population package
- pylinkage.simulation package
- Submodules
- pylinkage.simulation.linkage module
LinkageLinkage.analyze_sensitivity()Linkage.analyze_stroke()Linkage.analyze_tolerance()Linkage.analyze_transmission()Linkage.compile()Linkage.componentsLinkage.dyadsLinkage.get_accelerations()Linkage.get_constraints()Linkage.get_coords()Linkage.get_rotation_period()Linkage.get_velocities()Linkage.indeterminacy()Linkage.nameLinkage.rebuild()Linkage.set_completely()Linkage.set_constraints()Linkage.set_coords()Linkage.set_input_velocity()Linkage.simulation()Linkage.step()Linkage.step_fast()Linkage.step_fast_with_kinematics()Linkage.step_with_derivatives()Linkage.stroke_position()Linkage.to_hypergraph()Linkage.transmission_angle()
- Module contents
- pylinkage.solver package
- Submodules
- pylinkage.solver.acceleration module
- pylinkage.solver.groups module
- pylinkage.solver.joints module
- pylinkage.solver.simulation module
- pylinkage.solver.solve module
- pylinkage.solver.types module
SolverDataSolverData.accelerationsSolverData.alpha_valuesSolverData.constraint_countsSolverData.constraint_offsetsSolverData.constraintsSolverData.copy()SolverData.crank_indicesSolverData.joint_typesSolverData.n_constraintsSolverData.n_jointsSolverData.omega_valuesSolverData.parent_indicesSolverData.positionsSolverData.solve_orderSolverData.velocities
- pylinkage.solver.velocity module
- Module contents
- pylinkage.symbolic package
- Submodules
- pylinkage.symbolic.conversion module
- pylinkage.symbolic.geometry module
- pylinkage.symbolic.joints module
- pylinkage.symbolic.linkage module
SymbolicLinkageSymbolicLinkage.coupler_curve()SymbolicLinkage.get_constraint_equations()SymbolicLinkage.get_joint()SymbolicLinkage.get_trajectory_expressions()SymbolicLinkage.jacobian()SymbolicLinkage.jacobian_theta()SymbolicLinkage.jointsSymbolicLinkage.nameSymbolicLinkage.parametersSymbolicLinkage.simplify()SymbolicLinkage.substitute()SymbolicLinkage.theta
- pylinkage.symbolic.optimization module
- pylinkage.symbolic.solver module
- Module contents
- pylinkage.synthesis package
- Submodules
- pylinkage.synthesis.burmester module
- pylinkage.synthesis.conversion module
- pylinkage.synthesis.core module
- pylinkage.synthesis.function_generation module
- pylinkage.synthesis.generalized module
- pylinkage.synthesis.motion_generation module
- pylinkage.synthesis.multi_topology module
- pylinkage.synthesis.path_generation module
- pylinkage.synthesis.ranking module
- pylinkage.synthesis.six_bar module
- pylinkage.synthesis.topology_types module
- pylinkage.synthesis.utils module
- Module contents
- pylinkage.topology package
- Subpackages
- Submodules
- pylinkage.topology.analysis module
- pylinkage.topology.catalog module
CatalogEntryTopologyCatalogTopologyCatalog.all_graphs()TopologyCatalog.by_family()TopologyCatalog.by_num_links()TopologyCatalog.compatible_topologies()TopologyCatalog.entriesTopologyCatalog.from_json()TopologyCatalog.get()TopologyCatalog.load_builtin()TopologyCatalog.to_json()TopologyCatalog.topology_by_index()TopologyCatalog.topology_index()
generate_catalog()load_catalog()
- pylinkage.topology.enumeration module
- pylinkage.topology.isomorphism module
- Module contents
- pylinkage.visualizer package
- Submodules
- pylinkage.visualizer.animated module
- pylinkage.visualizer.core module
- pylinkage.visualizer.drawsvg_viz module
- pylinkage.visualizer.dxf_export module
- pylinkage.visualizer.kinematics module
- pylinkage.visualizer.plotly_viz module
- pylinkage.visualizer.pso_plots module
- pylinkage.visualizer.static module
- pylinkage.visualizer.step_export module
- pylinkage.visualizer.symbols module
- Module contents
Submodules
pylinkage.dimensions module
Dimensional data for linkage mechanisms.
This module provides the Dimensions class which holds all geometric data (positions, distances, angles) separate from topology. This separation allows pure topological analysis without geometric constraints.
The Dimensions class is shared by both the hypergraph and assur modules.
- class pylinkage.dimensions.Dimensions(node_positions: dict[str, tuple[float, float]] = <factory>, driver_angles: dict[str, ~pylinkage.dimensions.DriverAngle] = <factory>, edge_distances: dict[str, float] = <factory>, hyperedge_constraints: dict[str, dict[tuple[str, str], float]] = <factory>, name: str = '')
Bases:
objectGeometric data for a linkage topology.
Holds all dimensional information separate from the topological structure. This allows the same topology to be instantiated with different dimensions.
- Variables:
node_positions (dict[str, tuple[float, float]]) – Mapping from node ID to (x, y) coordinates.
driver_angles (dict[str, pylinkage.dimensions.DriverAngle]) – Mapping from driver node ID to angular parameters.
edge_distances (dict[str, float]) – Mapping from edge ID to link length.
hyperedge_constraints (dict[str, dict[tuple[str, str], float]]) – Mapping from hyperedge ID to pairwise distance constraints. Each value is a dict mapping (node1, node2) pairs to distances.
name (str) – Optional name for this dimension set.
Example
>>> dims = Dimensions( ... node_positions={"A": (0.0, 0.0), "B": (1.0, 0.0)}, ... driver_angles={"B": DriverAngle(0.1, 0.0)}, ... edge_distances={"AB": 1.0}, ... )
- copy() Dimensions
Create a deep copy of this Dimensions object.
- Returns:
A new Dimensions object with copied data.
- driver_angles: dict[str, DriverAngle]
- edge_distances: dict[str, float]
- classmethod from_dict(data: dict[str, Any]) Dimensions
Build a
Dimensionsfrom a dict produced byto_dict().Accepts both the canonical
[node1, node2, distance]triples emitted byto_dict()and the legacy{"('a', 'b')": distance}stringified-tuple form.
- get_driver_angle(node_id: str) DriverAngle | None
Get the driver angle parameters for a node.
- Parameters:
node_id – The node identifier.
- Returns:
The DriverAngle, or None if not defined.
- get_edge_distance(edge_id: str) float | None
Get the distance constraint for an edge.
- Parameters:
edge_id – The edge identifier.
- Returns:
The distance, or None if not defined.
- get_hyperedge_distance(hyperedge_id: str, node1: str, node2: str) float | None
Get a pairwise distance constraint from a hyperedge.
- Parameters:
hyperedge_id – The hyperedge identifier.
node1 – First node in the pair.
node2 – Second node in the pair.
- Returns:
The distance, or None if not defined.
- get_node_position(node_id: str) tuple[float, float] | None
Get the position of a node.
- Parameters:
node_id – The node identifier.
- Returns:
The (x, y) position, or None if not defined.
- hyperedge_constraints: dict[str, dict[tuple[str, str], float]]
- name: str = ''
- node_positions: dict[str, tuple[float, float]]
- to_dict() dict[str, Any]
Return a JSON-safe dict representation.
Hyperedge constraint keys are tuples of node IDs; to stay within JSON’s string-only key model they are serialised as
[node1, node2]lists rather than stringified tuples. The companionfrom_dict()accepts both that canonical shape and the legacy"('a', 'b')"stringified form for back-compat.
- validate_against(node_ids: Iterable[str], edge_ids: Iterable[str], hyperedge_ids: Iterable[str] | None = None) list[str]
Validate that dimensions are compatible with a topology.
Checks that all referenced node/edge IDs exist in the provided topology ID sets.
- Parameters:
node_ids – Valid node IDs from the topology.
edge_ids – Valid edge IDs from the topology.
hyperedge_ids – Valid hyperedge IDs from the topology (optional).
- Returns:
List of error messages. Empty list means validation passed.
Example
>>> dims = Dimensions(node_positions={"A": (0, 0), "X": (1, 1)}) >>> errors = dims.validate_against(["A", "B"], ["AB"]) >>> "X" in errors[0] # "X" is not a valid node True
- class pylinkage.dimensions.DriverAngle(angular_velocity: float, initial_angle: float = 0.0)
Bases:
objectAngular parameters for a driver joint.
- Variables:
angular_velocity (float) – Rotation angle per simulation step (radians).
initial_angle (float) – Starting angle of the driver (radians).
- angular_velocity: float
- classmethod from_dict(data: dict[str, Any]) DriverAngle
Build a
DriverAnglefrom a dict produced byto_dict().
- initial_angle: float = 0.0
- to_dict() dict[str, float]
Return a JSON-safe dict representation.
pylinkage.exceptions module
The exceptions module is a simple quick way to access the built-in exceptions.
Created on Wed Jun 16, 15:20:06 2021.
@author: HugoFara
- exception pylinkage.exceptions.NotCompletelyDefinedError(joint: Any, message: str = 'The joint is not completely defined!')
Bases:
ExceptionThe linkage definition is incomplete.
- exception pylinkage.exceptions.OptimizationError(message: str = 'Optimization failed')
Bases:
ExceptionShould be raised when the optimization process fails.
- exception pylinkage.exceptions.UnbuildableError(joint: Any, message: str = 'Unable to solve constraints')
Bases:
ExceptionShould be raised when the constraints cannot be solved.
Module contents
PyLinkage is a module to create, optimize and visualize linkages.
Please see the documentation at https://hugofara.github.io/pylinkage/. A copy of the documentation should have been distributed on your system in the docs/ folder.
Created on Thu Jun 10 21:30:52 2021
@author: HugoFara
- class pylinkage.ArcCrank(anchor: Ground, radius: float, angular_velocity: float = 0.017453292519943295, arc_start: float = 0.0, arc_end: float = 3.141592653589793, initial_angle: float | None = None, name: str | None = None)
Bases:
ConnectedComponentA motor-driven oscillating rotary input (arc crank).
An arc crank oscillates around a ground anchor between two angle limits at constant angular velocity, producing an output point that traces an arc. Direction reverses (“bounces”) when reaching angle limits, similar to LinearActuator behavior at stroke limits.
- Variables:
anchor (Ground) – The ground point this arc crank rotates around.
radius (float) – Distance from anchor to output.
angular_velocity (float) – Rotation rate magnitude in radians per step.
arc_start (float) – Minimum angle limit in radians.
arc_end (float) – Maximum angle limit in radians.
initial_angle (float) – Starting angle in radians (must be between arc_start and arc_end).
Example
>>> O1 = Ground(0.0, 0.0, name="O1") >>> arc_crank = ArcCrank( ... anchor=O1, ... radius=1.0, ... angular_velocity=0.1, ... arc_start=0.0, ... arc_end=math.pi/2, ... ) >>> arc_crank.position (1.0, 0.0)
- anchor: Ground
- property anchors: tuple[Ground]
Return the parent dyads (just the ground anchor).
- property angle: float
Return current angle.
- angular_velocity: float
- arc_end: float
- arc_start: float
- get_constraints() tuple[float, float, float]
Return optimizable constraints.
- Returns:
Tuple containing (radius, arc_start, arc_end).
- initial_angle: float
- property output: _AnchorProxy
Return the output joint (end of the arc crank).
This proxy can be used as an anchor for other dyads.
- Returns:
An anchor proxy representing the arc crank output.
- radius: float
- reload(dt: float = 1) None
Advance the arc crank by one step.
Rotates the arc crank position by angular_velocity * dt radians, reversing direction when hitting angle limits.
- Parameters:
dt – Time step multiplier.
- Raises:
ValueError – If anchor position is undefined.
- set_constraints(radius: float | None = None, arc_start: float | None = None, arc_end: float | None = None, *args: float | None) None
Set the constraints.
- Parameters:
radius – New radius value.
arc_start – New arc_start value.
arc_end – New arc_end value.
*args – Ignored (for interface compatibility).
- pylinkage.ComponentId
alias of
str
- class pylinkage.Crank(anchor: Ground, radius: float, angular_velocity: float = 0.017453292519943295, initial_angle: float = 0.0, name: str | None = None)
Bases:
ConnectedComponentA motor-driven rotary input (crank).
A crank rotates around a ground anchor at constant angular velocity, producing an output point that traces a circle. This is the primary input driver for most linkage mechanisms.
- Variables:
anchor (Ground) – The ground point this crank rotates around.
radius (float) – Distance from anchor to output.
angular_velocity (float) – Rotation rate in radians per step.
initial_angle (float) – Starting angle in radians.
Example
>>> O1 = Ground(0.0, 0.0, name="O1") >>> crank = Crank(anchor=O1, radius=1.0) >>> crank.position (1.0, 0.0) >>> crank.output.position # Same as crank.position (1.0, 0.0)
- anchor: Ground
- property anchors: tuple[Ground]
Return the parent dyads (just the ground anchor).
- angular_velocity: float
- get_constraints() tuple[float]
Return the radius (optimizable constraint).
- Returns:
Tuple containing the crank radius.
- initial_angle: float
- property output: _AnchorProxy
Return the output joint (end of the crank).
This proxy can be used as an anchor for other dyads.
- Returns:
An anchor proxy representing the crank output.
- radius: float
- reload(dt: float = 1) None
Advance the crank by one step.
Rotates the crank position by angular_velocity * dt radians.
- Parameters:
dt – Time step multiplier.
- Raises:
ValueError – If anchor position is undefined.
- set_constraints(distance: float | None = None, *args: float | None) None
Set the radius constraint.
- Parameters:
distance – New radius value.
*args – Ignored (for interface compatibility).
- pylinkage.EdgeId
alias of
str
- class pylinkage.FixedDyad(anchor1: Component | _AnchorProxy, anchor2: Component | _AnchorProxy, distance: float, angle: float, name: str | None = None)
Bases:
BinaryDyadFixed Dyad - deterministic polar projection.
Positions a joint at a fixed distance and angle from anchor1, with the angle measured relative to the line from anchor1 to anchor2.
Unlike RRRDyad which has two possible solutions, FixedDyad always has exactly one deterministic solution.
- Variables:
anchor1 – First anchor (origin for polar coordinates).
anchor2 – Second anchor (defines reference direction).
distance (float) – Distance from anchor1 to this joint.
angle (float) – Angle offset from anchor1->anchor2 direction (radians).
Example
>>> O1 = Ground(0.0, 0.0, name="O1") >>> O2 = Ground(2.0, 0.0, name="O2") >>> crank = Crank(anchor=O1, radius=1.0) >>> # Create a point at 90 degrees from crank->O2 line >>> fixed = FixedDyad( ... anchor1=crank.output, ... anchor2=O2, ... distance=1.0, ... angle=math.pi/2, ... name="coupler_point" ... )
- angle: float
- distance: float
- get_constraints() tuple[float, float]
Return the distance and angle constraints.
- Returns:
Tuple of (distance, angle).
- reload(dt: float = 1) None
Recompute position using polar projection.
The position is always deterministic - no ambiguity.
- Parameters:
dt – Time step (unused for Fixed, but required for interface).
- set_constraints(distance: float | None = None, angle: float | None = None, *args: float | None) None
Set the distance and angle constraints.
- Parameters:
distance – New distance from anchor1.
angle – New angle offset (radians).
*args – Ignored (for interface compatibility).
- class pylinkage.Ground(x: float, y: float, name: str | None = None)
Bases:
ComponentA 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.HyperedgeId
alias of
str
- class pylinkage.JointType(value)
Bases:
IntEnumKinematic joint type.
This enum classifies joints by their allowed degrees of freedom. Values are explicit integers for serialization stability.
- Variables:
REVOLUTE – Pin joint allowing rotation (R). 1 DOF rotation.
PRISMATIC – Slider joint allowing translation (P). 1 DOF translation.
GROUND – Fixed revolute joint on frame. Special case for mechanism module.
TRACKER – Observer joint (T). 0 DOF, just tracks a position.
- GROUND = 3
- PRISMATIC = 2
- REVOLUTE = 1
- TRACKER = 4
- class pylinkage.LinearActuator(anchor: Ground, angle: float, stroke: float, speed: float = 0.1, initial_extension: float = 0.0, name: str | None = None)
Bases:
ConnectedComponentA motor-driven linear input (linear actuator).
A linear actuator moves along a line from its anchor at constant speed, producing an output point that oscillates between 0 and the stroke limit. This provides linear reciprocating motion.
- Variables:
anchor (Ground) – The ground point this actuator extends from.
angle (float) – Direction angle in radians (from +x axis).
stroke (float) – Maximum extension distance.
speed (float) – Linear speed magnitude (units per step).
initial_extension (float) – Starting extension from anchor.
Example
>>> O1 = Ground(0.0, 0.0, name="O1") >>> actuator = LinearActuator(anchor=O1, angle=0.0, stroke=2.0, speed=0.1) >>> actuator.position (0.0, 0.0) >>> actuator.reload() >>> actuator.position # Moved 0.1 units along x-axis (0.1, 0.0)
- anchor: Ground
- property anchors: tuple[Ground]
Return the parent dyads (just the ground anchor).
- angle: float
- property extension: float
Return current extension from anchor.
- get_constraints() tuple[float, float]
Return the stroke and speed (optimizable constraints).
- Returns:
Tuple containing (stroke, speed).
- initial_extension: float
- property output: _AnchorProxy
Return the output joint (end of the actuator).
This proxy can be used as an anchor for other dyads.
- Returns:
An anchor proxy representing the actuator output.
- reload(dt: float = 1) None
Advance the actuator by one step.
Moves the actuator position by speed * dt, reversing direction when hitting stroke limits.
- Parameters:
dt – Time step multiplier.
- Raises:
ValueError – If anchor position is undefined.
- set_constraints(stroke: float | None = None, speed: float | None = None, *args: float | None) None
Set the constraints.
- Parameters:
stroke – New stroke value (must be positive).
speed – New speed value.
*args – Ignored (for interface compatibility).
- speed: float
- stroke: float
- class pylinkage.Linkage(components: Iterable[Component], order: Iterable[Component] | None = None, name: str | None = None)
Bases:
objectA planar linkage mechanism built from components.
The Linkage class orchestrates a collection of components (Ground points, actuators, and dyads) to simulate a planar mechanism. It handles solve order computation, stepping, and constraint management.
Example
>>> from pylinkage.components import Ground >>> from pylinkage.actuators import Crank >>> from pylinkage.dyads import RRRDyad >>> from pylinkage.simulation import Linkage >>> >>> O1 = Ground(0.0, 0.0, name="O1") >>> O2 = Ground(2.0, 0.0, name="O2") >>> crank = Crank(anchor=O1, radius=1.0, angular_velocity=0.1) >>> rocker = RRRDyad(crank.output, O2, distance1=2.0, distance2=1.5) >>> linkage = Linkage([O1, O2, crank, rocker], name="Four-Bar") >>> for positions in linkage.step(): ... print(positions)
- analyze_sensitivity(output_joint: object | int | None = None, delta: float = 0.01, include_transmission: bool = True, iterations: int | None = None) SensitivityAnalysis
Compute sensitivity of an output path to constraint perturbations.
See
pylinkage.linkage.analyze_sensitivity().
- analyze_stroke(prismatic_joint: object | None = None, iterations: int | None = None) StrokeAnalysis
Analyze stroke/slide position over a full motion cycle.
See
pylinkage.linkage.analyze_stroke().
- analyze_tolerance(tolerances: dict[str, float], output_joint: object | int | None = None, iterations: int | None = None, n_samples: int = 1000, seed: int | None = None) ToleranceAnalysis
Monte-Carlo tolerance analysis over the output path.
See
pylinkage.linkage.analyze_tolerance().
- analyze_transmission(iterations: int | None = None, acceptable_range: tuple[float, float] = (40.0, 140.0)) TransmissionAngleAnalysis
Analyze transmission angle over a full motion cycle.
See
pylinkage.linkage.analyze_transmission()for details.
- compile() None
Pre-compile the numba solver state for
step_fast().Cached on
self._solver_dataand reused until invalidated by a call tocompile()again.
- components: tuple[Component, ...]
- property dyads: tuple[Component, ...]
Return components (backwards compatibility alias).
- get_accelerations() list[tuple[float, float] | None]
Return accelerations for all components.
- Returns:
List of (ax, ay) tuples, one per component. Returns None for components whose acceleration has not been computed.
- get_constraints() list[float]
Return all geometric constraints as a flat list.
- Returns:
Flat list of all constraint values, used by optimizers.
- get_coords() list[tuple[float | None, float | None]]
Return positions of all components.
- Returns:
List of (x, y) positions.
- get_rotation_period() int
Return number of steps for one full cycle.
Computes the LCM of all actuator periods (cranks, arc cranks, and linear actuators). For cranks, period is 2*pi / angular_velocity. For arc cranks, period is 2 * (arc_end - arc_start) / angular_velocity. For linear actuators, period is 2 * stroke / velocity.
- Returns:
Number of iterations with dt=1.
- get_velocities() list[tuple[float, float] | None]
Return velocities for all components.
- Returns:
List of (vx, vy) tuples, one per component. Returns None for components whose velocity has not been computed.
- indeterminacy() int
Mobility (DOF) of the linkage — planar Gruebler-Kutzbach.
DOF = 3·(n − 1) − 2·R − Pwhere each non-ground component contributes its share of bodies and kinematic pairs:Groundanchors are points on the frame (no new body, no new pair on their own);Crank/LinearActuatoradd 1 body + 1 R/P pair;binary dyads (
RRRDyad,FixedDyad) add 2 bodies + 3 R-pairs;RRPDyadadds 2 bodies + 2 R-pairs + 1 P-pair.
A standard Grashof four-bar (Crank + RRRDyad) returns
1.
- name: str
- rebuild(positions: list[tuple[float, float]] | None = None) None
Rebuild the linkage, optionally setting initial positions.
- Parameters:
positions – Initial positions for each component. If None, uses current positions.
- set_completely(constraints: list[float], positions: list[tuple[float, float]]) None
Apply both constraints and initial positions in one call.
- Parameters:
constraints – Flat list (as accepted by
set_constraints()).positions – Per-component
(x, y)positions (as accepted byset_coords()).
- set_constraints(values: list[float]) None
Set constraints from a flat list.
Used to apply optimization results. Invalidates any cached SolverData so the next
step_fast()recompiles.- Parameters:
values – Flat list of constraint values.
- set_coords(coords: list[tuple[float, float]]) None
Set positions for all components.
- Parameters:
coords – List of (x, y) positions.
- set_input_velocity(actuator: Crank, omega: float, alpha: float = 0.0) None
Set angular velocity and acceleration for a crank actuator.
This is used for kinematics computation (velocity/acceleration analysis). The omega value will be used to compute linear velocities at each joint.
- Parameters:
actuator – The crank actuator to set velocity for.
omega – Angular velocity in rad/s (physical units for analysis).
alpha – Angular acceleration in rad/s² (default 0).
- Raises:
ValueError – If the actuator is not part of this linkage.
Example
>>> linkage.set_input_velocity(crank, omega=10.0) # 10 rad/s >>> for pos, vel, acc in linkage.step_with_derivatives(): ... print(f"Position: {pos}, Velocity: {vel}")
- simulation(iterations: int | None = None, dt: float = 1.0) _SimulationContext
Return a context manager that simulates this linkage.
The context restores the initial joint positions on exit, so repeated invocations return to the same starting state.
- step(iterations: int | None = None, dt: float = 1) Generator[tuple[tuple[float | None, float | None], ...], None, None]
Simulate the linkage.
Yields positions for all components at each step.
- Parameters:
iterations – Number of steps. If None, uses get_rotation_period().
dt – Time step multiplier for actuators (cranks and linear actuators).
- Yields:
Tuple of (x, y) positions for each component.
- step_fast(iterations: int | None = None, dt: float = 1) ndarray[tuple[Any, ...], dtype[float64]]
Run the simulation through the numba-compiled solver.
Significantly faster than
step()for large iteration counts because it avoids per-step Python dispatch.- Parameters:
iterations – Number of steps. Defaults to
get_rotation_period().dt – Time step multiplier (default 1.0).
- Returns:
Trajectory array of shape
(iterations, n_components, 2). Unbuildable configurations appear as NaN — check withnp.isnan(trajectory).any().
- step_fast_with_kinematics(iterations: int | None = None, dt: float = 1.0) tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]]
Run the numba-compiled simulation, returning velocities and accelerations.
Per-crank
omega/alphainputs must be set viaset_input_velocity()(cranks without an explicit input default to zero).- Parameters:
iterations – Number of steps. Defaults to
get_rotation_period().dt – Time step multiplier (default 1.0).
- Returns:
(positions, velocities, accelerations)— each a numpy array of shape(iterations, n_components, 2).
- step_with_derivatives(iterations: int | None = None, dt: float = 1) Generator[tuple[tuple[tuple[float | None, float | None], ...], tuple[tuple[float, float] | None, ...], tuple[tuple[float, float] | None, ...]], None, None]
Simulate the linkage with velocity and acceleration computation.
Yields positions, velocities, and accelerations for all components at each step. Requires that omega (and optionally alpha) is set on crank actuators via set_input_velocity().
- Parameters:
iterations – Number of steps. If None, uses get_rotation_period().
dt – Time step multiplier for actuators (cranks and linear actuators).
- Yields:
Tuple of (positions, velocities, accelerations) where –
positions: Tuple of (x, y) for each component
velocities: Tuple of (vx, vy) or None for each component
accelerations: Tuple of (ax, ay) or None for each component
Example
>>> linkage.set_input_velocity(crank, omega=10.0) >>> for pos, vel, acc in linkage.step_with_derivatives(): ... print(f"Crank velocity: {vel[2]}")
- stroke_position() float
Slide position of a prismatic joint at the current pose.
See
pylinkage.linkage.stroke_at_position().
- to_hypergraph() tuple[HypergraphLinkage, Dimensions]
Return a hypergraph view of this linkage.
Delegates to
pylinkage.hypergraph.from_sim_linkage(). The return is a tuple(HypergraphLinkage, Dimensions).
- transmission_angle() float
Transmission angle at the current pose, in degrees.
See
pylinkage.linkage.transmission_angle_at_position().
- pylinkage.NodeId
alias of
str
- class pylinkage.NodeRole(value)
Bases:
IntEnumRole of a node/joint in the mechanism.
Classifies joints by their kinematic role in the linkage structure.
- Variables:
GROUND – Fixed frame point that does not move.
DRIVER – Input/motor joint that provides motion (actuated).
DRIVEN – Position computed from constraints (passive, part of Assur groups).
- DRIVEN = 2
- DRIVER = 1
- GROUND = 0
- exception pylinkage.NotCompletelyDefinedError(joint: Any, message: str = 'The joint is not completely defined!')
Bases:
ExceptionThe linkage definition is incomplete.
- exception pylinkage.OptimizationError(message: str = 'Optimization failed')
Bases:
ExceptionShould be raised when the optimization process fails.
- class pylinkage.PPDyad(line1_anchor1: Component | _AnchorProxy, line1_anchor2: Component | _AnchorProxy, line2_anchor1: Component | _AnchorProxy, line2_anchor2: Component | _AnchorProxy, x: float | None = None, y: float | None = None, name: str | None = None)
Bases:
ConnectedComponentPP Dyad - line-line intersection.
Positions a joint at the intersection of two lines: - Line 1: defined by line1_anchor1 and line1_anchor2 - Line 2: defined by line2_anchor1 and line2_anchor2
This dyad has no distance constraints - its position is fully determined by the four line-defining anchor points.
- Variables:
line1_anchor1 (Component | _AnchorProxy) – First point defining line 1.
line1_anchor2 (Component | _AnchorProxy) – Second point defining line 1.
line2_anchor1 (Component | _AnchorProxy) – First point defining line 2.
line2_anchor2 (Component | _AnchorProxy) – Second point defining line 2.
Example
>>> A = Ground(0.0, 0.0, name="A") >>> B = Ground(2.0, 0.0, name="B") >>> C = Ground(0.0, 1.0, name="C") >>> D = Ground(2.0, 2.0, name="D") >>> joint = PPDyad( ... line1_anchor1=A, ... line1_anchor2=B, ... line2_anchor1=C, ... line2_anchor2=D, ... name="intersection" ... )
- property anchors: tuple[Component, Component, Component, Component]
Return the parent dyads (four line anchors).
- get_constraints() tuple[()]
Return the constraints (none for PP dyad).
PP dyads have no distance constraints - position is fully determined by the four anchor points.
- Returns:
Empty tuple (no constraints).
- line1_anchor1: Component | _AnchorProxy
- line1_anchor2: Component | _AnchorProxy
- line2_anchor1: Component | _AnchorProxy
- line2_anchor2: Component | _AnchorProxy
- reload(dt: float = 1) None
Recompute position using line-line intersection.
- Parameters:
dt – Time step (unused for PP, but required for interface).
- Raises:
UnbuildableError – If lines are parallel (no intersection).
- set_constraints(*args: float | None) None
Set constraints (no-op for PP dyad).
PP dyads have no constraints to set.
- Parameters:
*args – Ignored (for interface compatibility).
- class pylinkage.PointTracker(anchor1: Component | _AnchorProxy, anchor2: Component | _AnchorProxy, distance: float, angle: float, name: str | None = None)
Bases:
ConnectedComponentA 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.
- pylinkage.PortId
alias of
str
- class pylinkage.RRPDyad(revolute_anchor: Component | _AnchorProxy, line_anchor1: Component | _AnchorProxy, line_anchor2: Component | _AnchorProxy, distance: float, x: float | None = None, y: float | None = None, name: str | None = None)
Bases:
ConnectedComponentRRP Dyad - circle-line intersection (slider mechanism).
Positions a joint at the intersection of: - A circle centered at the revolute anchor - A line defined by two line anchor points
The joint slides along the line while maintaining a fixed distance from the revolute anchor.
When two solutions exist, the nearest to current position is chosen (hysteresis for continuity during simulation).
- Variables:
revolute_anchor (Component | _AnchorProxy) – Joint connected by revolute pair.
line_anchor1 (Component | _AnchorProxy) – First joint defining the sliding line.
line_anchor2 (Component | _AnchorProxy) – Second joint defining the sliding line.
distance (float) – Distance from revolute_anchor to this joint.
Example
>>> O1 = Ground(0.0, 0.0, name="O1") >>> L1 = Ground(0.0, 1.0, name="L1") >>> L2 = Ground(2.0, 1.0, name="L2") >>> crank = Crank(anchor=O1, radius=1.0) >>> slider = RRPDyad( ... revolute_anchor=crank.output, ... line_anchor1=L1, ... line_anchor2=L2, ... distance=1.5, ... name="slider" ... )
- property anchors: tuple[Component, Component, Component]
Return the parent dyads (revolute anchor, line anchors).
- distance: float
- get_constraints() tuple[float]
Return the distance constraint.
- Returns:
Tuple containing the distance to revolute anchor.
- line_anchor1: Component | _AnchorProxy
- line_anchor2: Component | _AnchorProxy
- reload(dt: float = 1) None
Recompute position using circle-line intersection.
- Parameters:
dt – Time step (unused for RRP, but required for interface).
- Raises:
UnbuildableError – If circle doesn’t intersect line.
- revolute_anchor: Component | _AnchorProxy
- set_constraints(distance: float | None = None, *args: float | None) None
Set the distance constraint.
- Parameters:
distance – New distance to revolute anchor.
*args – Ignored (for interface compatibility).
- class pylinkage.RRRDyad(anchor1: Component | _AnchorProxy, anchor2: Component | _AnchorProxy, distance1: float, distance2: float, x: float | None = None, y: float | None = None, name: str | None = None)
Bases:
BinaryDyadRRR Dyad - circle-circle intersection.
Positions a joint at the intersection of two circles centered at the anchor points. This is the most common Assur group.
When two solutions exist, the nearest to current position is chosen (hysteresis for continuity during simulation).
- Variables:
anchor1 – First connection point.
anchor2 – Second connection point.
distance1 (float) – Distance from anchor1 to this joint.
distance2 (float) – Distance from anchor2 to this joint.
Example
>>> O1 = Ground(0.0, 0.0, name="O1") >>> O2 = Ground(2.0, 0.0, name="O2") >>> crank = Crank(anchor=O1, radius=1.0) >>> rocker = RRRDyad( ... anchor1=crank.output, ... anchor2=O2, ... distance1=2.0, ... distance2=1.5, ... name="rocker" ... )
- distance1: float
- distance2: float
- get_constraints() tuple[float, float]
Return the two distance constraints.
- Returns:
Tuple of (distance1, distance2).
- reload(dt: float = 1) None
Recompute position using circle-circle intersection.
- Parameters:
dt – Time step (unused for RRR, but required for interface).
- Raises:
UnbuildableError – If the circles don’t intersect.
- set_constraints(distance1: float | None = None, distance2: float | None = None, *args: float | None) None
Set the distance constraints.
- Parameters:
distance1 – New distance to anchor1.
distance2 – New distance to anchor2.
*args – Ignored (for interface compatibility).
- class pylinkage.Simulation(linkage: Any, iterations: int | None = None, dt: float = 1.0)
Bases:
objectContext-managed wrapper around a linkage’s
step()generator.Works with any container that exposes
get_coords(),set_coords(positions), andstep(iterations=..., dt=...).Example
>>> with linkage.simulation(iterations=100) as sim: ... for step, coords in sim: ... print(step, coords)
- property iterations: int
Number of iterations for this simulation.
- property linkage: Any
The linkage being simulated.
- exception pylinkage.UnbuildableError(joint: Any, message: str = 'Unable to solve constraints')
Bases:
ExceptionShould be raised when the constraints cannot be solved.
- exception pylinkage.UnderconstrainedError(linkage: Linkage | str, message: str = 'The linkage is under-constrained!')
Bases:
ExceptionThe linkage is under-constrained and multiple solutions may exist.
- pylinkage.bounding_box(locus: Iterable[tuple[float, float]]) tuple[float, float, float, float]
Compute the bounding box of a locus.
- Parameters:
locus – A list of points or any iterable with the same structure.
- Returns:
Bounding box as (y_min, x_max, y_max, x_min).
- pylinkage.circle_intersect(x1: float, y1: float, r1: float, x2: float, y2: float, r2: float, tol: float = 0.0) tuple[int, float, float, float, float]
Get the intersections of two circles.
Transcription of a Matt Woodhead program, method provided by Paul Bourke, 1997. http://paulbourke.net/geometry/circlesphere/.
- Parameters:
x1 – X coordinate of first circle center.
y1 – Y coordinate of first circle center.
r1 – Radius of first circle.
x2 – X coordinate of second circle center.
y2 – Y coordinate of second circle center.
r2 – Radius of second circle.
tol – Distance under which two points are considered equal.
- Returns:
n=0: No intersection (other values undefined)
n=1: One intersection at (x1, y1)
n=2: Two intersections at (x1, y1) and (x2, y2)
n=3: Same circle (x1, y1, x2 are center and radius)
- Return type:
Tuple of (n_intersections, x1, y1, x2, y2) where
- pylinkage.cyl_to_cart(radius: float, theta: float, ori_x: float = 0.0, ori_y: float = 0.0) tuple[float, float]
Convert polar coordinates into cartesian.
- Parameters:
radius – Distance from origin.
theta – Angle starting from abscissa axis.
ori_x – Origin X coordinate (Default value = 0.0).
ori_y – Origin Y coordinate (Default value = 0.0).
- Returns:
Cartesian coordinates (x, y).
- pylinkage.extract_trajectories(loci: Sequence[Sequence[tuple[float, float] | tuple[Any, Any]]], linkage: Any | None = None) dict[Any, tuple[ndarray, ndarray]]
Extract the (x, y) path of every joint from simulation loci.
Frames where a given joint’s position is
None(unbuildable configuration) are skipped per joint — each joint’s arrays only contain frames where that joint was successfully solved.- Parameters:
loci – Sequence of frames as produced by
Linkage.step()orMechanism.step(). Each frame is a sequence of(x, y)tuples, one per joint/component in the linkage’s iteration order.linkage – Optional
LinkageorMechanism. If provided, the returned dict is keyed by joint name; otherwise it is keyed by integer index.
- Returns:
Mapping
{joint_name_or_index: (xs, ys)}. Each(xs, ys)pair is a tuple ofnumpy.ndarraywith matching length. Empty arrays indicate a joint was never buildable.
- pylinkage.extract_trajectory(loci: Sequence[Sequence[tuple[float, float] | tuple[Any, Any]]], joint: int | str | Any = -1, linkage: Any | None = None) tuple[ndarray, ndarray]
Extract the (x, y) path of a single joint from simulation loci.
Frames where the joint position is
None(unbuildable configuration) are silently skipped.- Parameters:
loci – Sequence of frames as produced by
Linkage.step()orMechanism.step(). Each frame is a sequence of(x, y)tuples, one per joint/component in the linkage’s iteration order.joint – Which joint’s trajectory to extract. Can be:
frame (- an integer index into each)
name (- a joint/component)
instance (- a joint/component)
linkage – The
LinkageorMechanismthe loci come from. Required whenjointis a name or instance.
- Returns:
Pair
(xs, ys)ofnumpy.ndarraywith the same length. Empty arrays if every frame is unbuildable.
- pylinkage.intersection(obj_1: tuple[float, float] | tuple[float, float, float], obj_2: tuple[float, float] | tuple[float, float, float], tol: float = 0.0) tuple[float, float] | tuple[tuple[float, float], ...] | tuple[float, float, float] | None
Intersection of two arbitrary objects.
The input objects should be points or circles.
- Parameters:
obj_1 – First point or circle (as tuple).
obj_2 – Second point or circle (as tuple).
tol – Absolute tolerance to use if provided.
- Returns:
The intersection found, if any.
- pylinkage.kinematic_default_test(func: Callable[[...], float], error_penalty: float) Callable[[Linkage, Iterable[float], JointPositions | None], float]
Standard run for any linkage before a complete fitness evaluation.
This decorator makes a kinematic simulation, before passing the loci to the decorated function.
- Parameters:
func – Fitness function to be decorated.
error_penalty – Penalty value for unbuildable linkage. Common values include float(‘inf’) and 0.
- pylinkage.norm(x: float, y: float) float
Return the norm of a 2-dimensional vector.
- Parameters:
x – X component.
y – Y component.
- Returns:
Vector magnitude.
- pylinkage.sqr_dist(x1: float, y1: float, x2: float, y2: float) float
Square of the distance between two points.
Faster than dist when only comparing distances.
- Parameters:
x1 – X coordinate of first point.
y1 – Y coordinate of first point.
x2 – X coordinate of second point.
y2 – Y coordinate of second point.
- Returns:
Squared distance.