LinkMotion is a comprehensive robotics library that provides tools for robot modeling, joint control, collision detection, visualization, and URDF import/export functionality.
Project description
LinkMotion
A comprehensive Python library for robotics applications, providing tools for robot modeling, joint control, collision detection, visualization, and URDF import/export functionality.
Features
๐ค Robot Modeling
- Flexible Robot Construction: Build complex robot models from primitive shapes (box, sphere, cylinder, cone, capsule, mesh)
- Joint System: Support for revolute, prismatic, and fixed joints with configurable constraints
- Hierarchical Structure: Tree-based robot structure with parent-child relationships
- Custom Robots: Advanced robot construction utilities and custom modeling tools
๐ Transform System
- Spatial Transformations: Comprehensive 3D transformation calculations
- Coordinate Frames: Hierarchical coordinate frame management
- Transform Manager: Advanced transform hierarchy handling and operations
๐ฏ Robot Movement
- Joint Control: Precise control of robot joint positions and states
- State Management: Real-time management of robot configuration
- Transform Updates: Automatic update of link transformations based on joint movements
๐ฅ Collision Detection
- Real-time Collision Checking: Fast collision detection using FCL (Flexible Collision Library)
- Safety Verification: Comprehensive collision checking for robot configurations
- Collision Manager: High-level collision detection interface
๐ Workspace Analysis
- Reachability Analysis: Calculate robot workspace and reachable areas, which is called
rangein this project - Range Calculations: Joint and workspace limit analysis
- Multi-axis Analysis: 2D and 3D workspace visualization
๐จ 3D Visualization
- Interactive Visualization: 3D robot visualization using K3D
- Motion Animation: Real-time motion visualization and animation
- Collision Visualization: Visual collision detection and safety checking
๐ URDF Support
- URDF Import: Parse and import URDF (Unified Robot Description Format) files
- URDF Export: Generate URDF files from robot models
- Mesh Support: Handle complex mesh geometries in URDF files
โ๏ธ Advanced Modeling
- Sweep Operations: Complex geometry generation through sweep operations
- Geometry Modification: Advanced geometry removal and modification tools
Installation
Prerequisites
- Python 3.12 or higher
Basic Installation
pip install linkmotion
With Jupyter Support
For interactive notebooks and visualization:
pip install linkmotion[jup]
Dependencies
Core Dependencies:
joblib- Parallel computing utilitiesmanifold3d- 3D geometry processingpython-fcl- Collision detection libraryscipy- Scientific computingshapely- Geometric operationstrimesh- 3D mesh processing
Optional Dependencies (with --extra jup):
jupyter- Interactive notebooksk3d- 3D visualization in Jupyterplotly- Interactive plotting
Quick Start
Basic Robot Construction
import numpy as np
from scipy.spatial.transform import Rotation as R
from linkmotion import Robot, Link, Joint, JointType, Transform
humanoid = Robot()
body = Link.from_box("body", extents=np.array((3, 2, 10)))
t = Transform(rotate=R.from_rotvec(90.0 * np.array((0, 1, 0)), degrees=True), translate=np.array((4, 0, 3)))
right_arm = Link.from_cylinder("right_arm", radius=0.5, height=5, default_transform=t)
t = Transform(rotate=R.from_rotvec(90.0 * np.array((0, 1, 0)), degrees=True), translate=np.array((-4, 0, 3)))
left_arm = Link.from_cylinder("left_arm", radius=0.5, height=5, default_transform=t)
t = Transform(rotate=R.from_rotvec(180.0 * np.array((0, 1, 0)), degrees=True), translate=np.array((1, 0, -8)))
right_leg = Link.from_cone("right_leg", radius=0.5, height=6, default_transform=t)
t = Transform(rotate=R.from_rotvec(180.0 * np.array((0, 1, 0)), degrees=True), translate=np.array((-1, 0, -8)))
left_leg = Link.from_cone("left_leg", radius=0.5, height=6, default_transform=t)
t = Transform(translate=np.array((0, 0, -5)))
head = Link.from_sphere("head", 3, center=np.array((0, 0, 8)))
left_leg_joint = Joint(
"left_leg_joint",
JointType.REVOLUTE,
child_link_name="left_leg",
parent_link_name="body",
center=np.array((-1, 0, -5)),
direction=np.array((1, 0, 0)),
min_=-np.pi / 2.0,
max_=np.pi / 4.0,
)
t = Transform(translate=np.array((0, -5, 0)))
wall = Link.from_box("wall", extents=np.array((20, 1, 20)), default_transform=t, color=np.array((0.0, 0.8, 0.8, 0.2)))
humanoid.add_link(body)
humanoid.add_link(right_arm)
humanoid.add_link(left_arm)
humanoid.add_link(right_leg)
humanoid.add_link(left_leg)
humanoid.add_link(head)
humanoid.add_joint(left_leg_joint)
humanoid.add_link(wall)
Robot Appearance
Transform Operations
from linkmotion import MoveManager
mm = MoveManager(humanoid)
mm.move(joint_name="left_leg_joint", value=-np.pi / 6.0)
Robot Appearance
Collision Detection
from linkmotion import CollisionManager
cm = CollisionManager(mm)
cm.distance({"wall"}, {"body", "left_leg", "right_leg"})
Robot Appearance
URDF Import/Export
robot = Robot.from_urdf_file("../../models/toy_model/toy_model.urdf")
Robot Appearance
Range Calculations
import numpy as np
from scipy.spatial.transform import Rotation as R
from linkmotion import Robot, Link, Joint, JointType, Transform
robot = Robot()
base_link = Link.from_sphere(
name="base_link", radius=0.1, center=np.array([0, 0, 0])
)
arm_link = Link.from_cylinder(
name="arm_link",
radius=0.1,
height=1.0,
default_transform=Transform(translate=np.array([0, 0, 0.5])),
)
hand_link = Link.from_box(
name="hand_link",
extents=np.array([0.1, 0.1, 0.1]),
default_transform=Transform(translate=np.array([0, 0, 1.0])),
color=np.array([0, 1, 0, 1]),
)
finger_link = Link.from_box(
name="finger_link",
extents=np.array([0.05, 0.05, 0.1]),
default_transform=Transform(translate=np.array([0, 0, 1.1])),
color=np.array([1, 0, 0, 1]),
)
obstacle_link = Link.from_box(
name="obstacle_link",
extents=np.array([10, 10, 0.1]),
default_transform=Transform(translate=np.array([0, 0, 1.5])),
)
revolute_joint = Joint(
name="revolute_joint",
type=JointType.REVOLUTE,
parent_link_name="base_link",
child_link_name="arm_link",
direction=np.array([1, 0, 0]),
center=np.array([0, 0, 0.0]),
min_=-np.pi / 2,
max_=np.pi / 2,
)
prismatic_joint = Joint(
name="prismatic_joint",
type=JointType.PRISMATIC,
parent_link_name="arm_link",
child_link_name="hand_link",
direction=np.array([0, 1, 0]),
center=np.array([0, 0, 1.0]),
min_=-10,
max_=10,
)
prismatic_joint2 = Joint(
name="prismatic_joint2",
type=JointType.PRISMATIC,
parent_link_name="hand_link",
child_link_name="finger_link",
direction=np.array([0, 0, 1]),
center=np.array([0, 0, 1.1]),
min_=-10,
max_=10,
)
robot.add_link(base_link)
robot.add_link(arm_link)
robot.add_link(hand_link)
robot.add_link(finger_link)
robot.add_link(obstacle_link)
robot.add_joint(revolute_joint)
robot.add_joint(prismatic_joint)
robot.add_joint(prismatic_joint2)
Robot Appearance
from linkmotion.range.range import RangeCalculator
calculator = RangeCalculator(
robot, {"hand_link", "finger_link"}, {"obstacle_link"}
)
calculator.add_axis("revolute_joint", np.linspace(-np.pi / 2, np.pi / 2, 100))
calculator.add_axis("prismatic_joint", np.linspace(-3, 3, 200))
calculator.execute()
Range Appearance
- 1 means collided
- 0 means collision-free
Examples
The examples/ directory contains comprehensive examples organized by functionality:
Interactive Notebooks
Explore the library through interactive Jupyter notebooks:
Visualization Notebooks
notebooks/visual/01.base.ipynb- Basic visualization conceptsnotebooks/visual/02.mesh.ipynb- Mesh visualizationnotebooks/visual/03.robot.ipynb- Robot visualizationnotebooks/visual/04.move.ipynb- Motion visualizationnotebooks/visual/05.collision.ipynb- Collision visualizationnotebooks/visual/06.range_2axes.ipynb- 2D workspace analysisnotebooks/visual/07.range_3axes.ipynb- 3D workspace analysis
URDF Notebooks
notebooks/urdf/01.import_export.ipynb- URDF import/export demonstration
Future Works
- More URDF compatibility such as dae
- Inverse Kinematics
- Path planning using OMPL
Development
Code Quality
# Format code
uv run ruff format
# Check code quality
uv run ruff check
# Auto-fix issues
uv run ruff check --fix
Testing
# Run all tests
uv run pytest
# Run specific test file
uv run pytest tests/test_robot/test_robot.py
# Run with coverage
uv run pytest --cov
# Verbose output
uv run pytest -v
Development Scripts
# Format, lint, and test in sequence
./scripts/format_lint_test.sh
# Run all examples
./scripts/run_all_examples.sh
Project Structure
linkmotion/
โโโ src/linkmotion/ # Main source code
โ โโโ robot/ # Robot modeling and manipulation
โ โโโ transform/ # Spatial transformations
โ โโโ move/ # Robot joint control and movement
โ โโโ collision/ # Collision detection
โ โโโ range/ # Workspace analysis
โ โโโ modeling/ # Advanced geometric modeling
โ โโโ urdf/ # URDF import/export
โ โโโ visual/ # 3D visualization
โ โโโ typing/ # Type definitions
โ โโโ const/ # Constants and configuration
โโโ tests/ # Comprehensive test suite
โโโ examples/ # Usage examples by functionality
โโโ notebooks/ # Interactive Jupyter notebooks
โโโ models/ # Sample robot models and meshes
โโโ docs/ # Auto-generated documentation
โโโ scripts/ # Development automation scripts
API Reference
API Reference is available.
Core Classes
Robot- Main robot class for building and manipulating robot modelsLink- Robot link with geometric shapes and propertiesJoint- Robot joint with motion constraints and typesTransform- 3D transformation operations and calculationsMoveManager- Robot joint control and state management interfaceCollisionManager- Collision detection and safety checking
Shape Classes
Box,Sphere,Cylinder,Cone,Capsule- Primitive shapesMesh- Complex mesh geometryConvex- Convex hull shapes
Contributing
- Fork the repository
- Create a feature branch
- Make your changes following the coding guidelines in
CLAUDE.md - Run tests and quality checks
- Submit a pull request
Coding Standards
- Follow Google-style docstrings
- Use type hints for all functions
- Implement
__repr__for custom classes - Use logging instead of print statements
- Follow PEP 8 style guide (enforced by Ruff)
License
MIT License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file linkmotion-0.2.1.tar.gz.
File metadata
- Download URL: linkmotion-0.2.1.tar.gz
- Upload date:
- Size: 1.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6dff9e86976cccf25ce659ef931a108842341d8b77d3a33f92ae293d912d32d
|
|
| MD5 |
73e9b82c26788f3c81ae5bcfdec141ea
|
|
| BLAKE2b-256 |
61fb336faf5ab1a1cda4f2744aefc7703ac2fa4230d7594c15d721f5d0306e2b
|
Provenance
The following attestation bundles were made for linkmotion-0.2.1.tar.gz:
Publisher:
cd.yml on hshrg-kw/linkmotion
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
linkmotion-0.2.1.tar.gz -
Subject digest:
a6dff9e86976cccf25ce659ef931a108842341d8b77d3a33f92ae293d912d32d - Sigstore transparency entry: 728810462
- Sigstore integration time:
-
Permalink:
hshrg-kw/linkmotion@efb617718a32ff31e8e51fff71cd35801ea7da94 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/hshrg-kw
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@efb617718a32ff31e8e51fff71cd35801ea7da94 -
Trigger Event:
push
-
Statement type:
File details
Details for the file linkmotion-0.2.1-py3-none-any.whl.
File metadata
- Download URL: linkmotion-0.2.1-py3-none-any.whl
- Upload date:
- Size: 85.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
405237f9ae5c754118d28beee0d5419c1bba399859c359b2ca9e82cc80f885fd
|
|
| MD5 |
ff44de912869f3e71dcb6bd0e3e9c706
|
|
| BLAKE2b-256 |
e1709a49087f4242997c018bb00956b5e3fa7a43da26de0d11ab9d3350bc1522
|
Provenance
The following attestation bundles were made for linkmotion-0.2.1-py3-none-any.whl:
Publisher:
cd.yml on hshrg-kw/linkmotion
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
linkmotion-0.2.1-py3-none-any.whl -
Subject digest:
405237f9ae5c754118d28beee0d5419c1bba399859c359b2ca9e82cc80f885fd - Sigstore transparency entry: 728810463
- Sigstore integration time:
-
Permalink:
hshrg-kw/linkmotion@efb617718a32ff31e8e51fff71cd35801ea7da94 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/hshrg-kw
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@efb617718a32ff31e8e51fff71cd35801ea7da94 -
Trigger Event:
push
-
Statement type: