Skip to main content

LinkMotion

A comprehensive Python library for robotics applications, providing tools for robot modeling, joint control, collision detection, visualization, and URDF import/export functionality.

API Reference

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 range in 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 utilities
  • manifold3d - 3D geometry processing
  • python-fcl - Collision detection library
  • scipy - Scientific computing
  • shapely - Geometric operations
  • trimesh - 3D mesh processing

Optional Dependencies (with --extra jup):

  • jupyter - Interactive notebooks
  • k3d - 3D visualization in Jupyter
  • plotly - 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

OutputExample

Transform Operations

from linkmotion import MoveManager

mm = MoveManager(humanoid)
mm.move(joint_name="left_leg_joint", value=-np.pi / 6.0)

Robot Appearance

OutputExample

Collision Detection

from linkmotion import CollisionManager

cm = CollisionManager(mm)
cm.distance({"wall"}, {"body", "left_leg", "right_leg"})

Robot Appearance

OutputExample

URDF Import/Export

robot = Robot.from_urdf_file("../../models/toy_model/toy_model.urdf")

Robot Appearance

OutputExample

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

OutputExample

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

OutputExample

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 concepts
  • notebooks/visual/02.mesh.ipynb - Mesh visualization
  • notebooks/visual/03.robot.ipynb - Robot visualization
  • notebooks/visual/04.move.ipynb - Motion visualization
  • notebooks/visual/05.collision.ipynb - Collision visualization
  • notebooks/visual/06.range_2axes.ipynb - 2D workspace analysis
  • notebooks/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 models
  • Link - Robot link with geometric shapes and properties
  • Joint - Robot joint with motion constraints and types
  • Transform - 3D transformation operations and calculations
  • MoveManager - Robot joint control and state management interface
  • CollisionManager - Collision detection and safety checking

Shape Classes

  • Box, Sphere, Cylinder, Cone, Capsule - Primitive shapes
  • Mesh - Complex mesh geometry
  • Convex - Convex hull shapes

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes following the coding guidelines in CLAUDE.md
  4. Run tests and quality checks
  5. 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

Metadata

Release files for linkmotion 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for linkmotion 0.2.1
File Size Uploaded
linkmotion-0.2.1.tar.gz 1.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for linkmotion 0.2.1
File Interpreter ABI Platform
linkmotion-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 1.6 MB

Release files / linkmotion-0.2.1.tar.gz

Download URL linkmotion-0.2.1.tar.gz
Size 1.6 MB
Tags Source
SHA-256 checksum
How to use checksums
a6dff9e86976cccf25ce659ef931a108842341d8b77d3a33f92ae293d912d32d
BLAKE2b-256 checksum
How to use checksums
61fb336faf5ab1a1cda4f2744aefc7703ac2fa4230d7594c15d721f5d0306e2b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Nov 27, 2025.

Transparency log

Release files / linkmotion-0.2.1-py3-none-any.whl

Download URL linkmotion-0.2.1-py3-none-any.whl
Size 85.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
405237f9ae5c754118d28beee0d5419c1bba399859c359b2ca9e82cc80f885fd
BLAKE2b-256 checksum
How to use checksums
e1709a49087f4242997c018bb00956b5e3fa7a43da26de0d11ab9d3350bc1522
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Nov 27, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.20

2 release files

0.1.19

2 release files

0.1.18

2 release files

0.1.17

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page