Kimech
Kimech is a small Python library for modeling and solving the kinematics of planar rigid-body mechanisms.
Public documentation: https://jorgedelossantos.github.io/kimech/
It provides declarative rigid-body models with revolute and prismatic joints, robust one-DOF position/velocity/acceleration solving, structural topology introspection, structured numerical diagnostics, driver-coordinate sensitivity analysis, and schematic plotting and animation.
Kimech supports position, velocity, and acceleration analysis for one-DOF planar R/P mechanisms driven by one KinematicDriver. The current 0.6.x driver/time design is recorded in docs/study-0.6.0-kinematic-driver.md; earlier design baselines remain available in the docs/ directory. docs/api.md documents the implemented public API.
Installation
Install Kimech from PyPI:
pip install kimech
For plotting, animation, and GIF support:
pip install "kimech[viz]"
For local development, clone the repository and use an editable install:
pip install -e ".[dev,viz,docs]"
pytest
Quick start
The following builds a four-bar linkage and solves a differential kinematic sweep through the generic API:
import numpy as np
from kimech import KinematicDriver, Mechanism, solve
mechanism = Mechanism("four_bar")
ground = mechanism.ground
ground_a = ground.add_point("A", (0.0, 0.0))
ground_d = ground.add_point("D", (0.30, 0.0))
crank = mechanism.add_link("crank")
crank_a = crank.add_point("A", (0.0, 0.0))
crank_b = crank.add_point("B", (0.08, 0.0))
coupler = mechanism.add_link("coupler")
coupler_b = coupler.add_point("B", (0.0, 0.0))
coupler_c = coupler.add_point("C", (0.22, 0.0))
point_p = coupler.add_point("P", (0.10, 0.05))
rocker = mechanism.add_link("rocker")
rocker_c = rocker.add_point("C", (0.0, 0.0))
rocker_d = rocker.add_point("D", (0.18, 0.0))
input_joint = mechanism.revolute(ground_a, crank_a, name="input")
mechanism.revolute(crank_b, coupler_b)
mechanism.revolute(coupler_c, rocker_c)
mechanism.revolute(rocker_d, ground_d)
initial_guess = {
crank: (0.0, 0.0, 0.8),
coupler: (0.05, 0.06, 0.2),
rocker: (0.30, 0.0, 2.2),
}
input_positions = np.linspace(0.8, 1.3, 60)
driver = KinematicDriver(
input_joint,
position=input_positions,
velocity=1.5,
acceleration=0.0,
)
solution = solve(
mechanism,
driver=driver,
initial_guess=initial_guess,
)
positions = solution.point_positions(point_p)
velocities = solution.point_velocities(point_p)
accelerations = solution.point_accelerations(point_p)
KinematicDriver packages the prescribed natural coordinate of a revolute or prismatic joint together with optional physical velocity and acceleration data. position may be a scalar or a one-dimensional sequence; scalar differential values are broadcast across sweeps. solve() always returns a KinematicSolution, so a scalar driver position produces a solution of length one and solution[0] returns its Configuration.
Position-only solving remains valid by constructing the driver with position only. An optional time= array may associate each requested sample with a physical instant; it does not control continuation or trigger numerical differentiation. Position sweeps use predictor-corrector continuation with warm-start fallback and bounded adaptive subdivision when recovery is needed. Solutions also expose structured numerical diagnostics through solution.diagnostics.
For example:
diagnostics = solution.diagnostics
condition = diagnostics.condition_numbers
sigma_min = diagnostics.min_singular_values
strategies = diagnostics.strategies
subdivisions = diagnostics.subdivision_counts
residuals = diagnostics.residual_norms
These diagnostics describe the selected driven solve formulation. A configuration may therefore be regular for one chosen driver coordinate and singular for another.
Topology can be inspected independently of solved geometry:
topology = mechanism.topology()
print(topology.cycle_rank)
print(topology.connected_components)
Driver-coordinate sensitivity is an explicit downstream analysis:
from kimech import driver_sensitivity
sensitivity = driver_sensitivity(solution)
dq_du = sensitivity.coordinate_derivatives
point_dp_du = sensitivity.point_position_derivatives(point_p)
Sensitivity is with respect to the prescribed driver coordinate; it is not a time derivative.
Visualization
Visualization remains presentation-only. When solution.time is available it records physical sample times, while animation fps still controls playback only:
import matplotlib.pyplot as plt
from kimech.visualization import animate, plot_topology
animation = animate(solution, fps=30)
# Structural connectivity, independent of physical geometry
fig, ax = plot_topology(mechanism)
# Optional progressive trace for one or more mechanism points
animation = animate(solution, fps=30, trace_points=[point_p])
plt.show()
Examples
The example set separates motion/geometry from kinematic analysis and validation:
examples/
├── four_bar.py
├── four_bar_analysis.py
├── slider_crank.py
├── slider_crank_analysis.py
└── slider_crank_analysis_comparison.py
examples/four_bar.pyandexamples/slider_crank.pyfocus on position solving and animation.examples/four_bar_analysis.pyplots rocker angle, angular velocity, angular acceleration, and coupler-point speed/acceleration magnitude versus the prescribed crank angle.examples/slider_crank_analysis.pyplots slider displacement, velocity, and acceleration versus crank angle and demonstrates reconstruction of the same state with the prismatic coordinate prescribed instead.examples/slider_crank_analysis_comparison.pycompares Kimech's slider displacement, velocity, and acceleration with the independent closed-form slider-crank solution and reports the maximum absolute errors.
See CHANGELOG.md for release changes and intentional breaking renames.
Metadata
Release files for kimech 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| kimech-0.6.1.tar.gz | 70.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kimech-0.6.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 113.3 kB
Release files / kimech-0.6.1.tar.gz
| Download URL | kimech-0.6.1.tar.gz |
|---|---|
| Size | 70.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
371f842b38843b4e328cab2b4f34984673b1d6791e125d66e54a63f6476c622e
|
|
BLAKE2b-256 checksum How to use checksums |
d7b8af33fe2a2b7077601f46b4c6ebdd85a71ba4e924728bc77d3b595efe3397
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency logRelease files / kimech-0.6.1-py3-none-any.whl
| Download URL | kimech-0.6.1-py3-none-any.whl |
|---|---|
| Size | 42.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f1b3ffb15883f840f3125a611b7eed87a6603a00386d3f701a618ebd1860f171
|
|
BLAKE2b-256 checksum How to use checksums |
75a6ea7bc24bd0e8f2eda006663943dfdb581cfdc4e4bb21d05c8903f61f5a82
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 2, 2026.
Transparency log