Skip to main content

Python bindings for libfranka with real-time control

Project description

libfrankapy

CI PyPI version Python 3.8+ License

libfrankapy is a Python binding project for the libfranka C++ library, designed to provide high-level Python interfaces for Franka robotic arms while maintaining the performance advantages of low-level C++ real-time control.

✨ Features

  • 🚀 Real-time Performance Guarantee: C++ control loop maintains 1kHz real-time performance, Python does not participate in real-time loops
  • 🐍 Python Friendly: Provides intuitive Python API with complete type hints
  • Efficient Communication: Uses shared memory and atomic operations for Python-C++ data exchange
  • 🛡️ Safety Control: Complete safety limits, error handling, and emergency stop functionality
  • 🎯 Multiple Control Modes: Supports joint space, Cartesian space, and trajectory control
  • 📊 Real-time Monitoring: Complete robot state feedback and monitoring functionality
  • 🏗️ Modular Design: Clear code structure and interface separation

📚 Documentation

  • 📖 Online Documentation: https://han-xudong.github.io/libfrankapy/
  • 🔧 API Reference: Complete API documentation with examples
  • 🚀 Quick Start Guide: Step-by-step tutorials for getting started
  • 🏗️ Architecture Guide: Detailed system architecture and design principles
  • 🛠️ Development Guide: Contributing guidelines and development setup

🏗️ Architecture Design

libfrankapy adopts a hybrid architecture of C++ real-time environment + Python high-level interface:

graph TD
    A[Python Application Layer] --> B[libfrankapy Python API]
    B --> C[Pybind11 Binding Layer]
    C --> D[C++ Control Manager]
    D --> E[Shared Memory Communication]
    D --> F[Real-time Control Thread]
    F --> G[LibFranka C++ Library]
    G --> H[Franka Robotic Arm Hardware]

    style A fill:#e1f5fe
    style B fill:#f3e5f5
    style C fill:#fff3e0
    style D fill:#e8f5e8
    style F fill:#ffebee
    style G fill:#f1f8e9
    style H fill:#fce4ec

📋 System Requirements

Hardware Requirements

  • Franka Robotics robotic arm (with FCI functionality)
  • Computer with PREEMPT_RT real-time kernel

Software Requirements

  • Operating System: Ubuntu 22.04+ with PREEMPT_RT real-time kernel
  • Python: 3.8+
  • C++ Compiler: GCC 7+ or Clang 6+
  • CMake: 3.16+
  • Dependencies:
    • libfranka 0.15+
    • Eigen3
    • Poco
    • fmt
    • pinocchio
    • pybind11 2.10+

🚀 Installation

1. Install System Dependencies

# Update package manager
sudo apt-get update

# Install basic build tools
sudo apt-get install -y build-essential cmake git

# Install libfranka dependencies
sudo apt-get install -y libpoco-dev libeigen3-dev libfmt-dev

# Install pinocchio (required for libfranka 0.14.0+)
sudo apt-get install -y lsb-release curl
sudo mkdir -p /etc/apt/keyrings
curl -fsSL http://robotpkg.openrobots.org/packages/debian/robotpkg.asc | sudo tee /etc/apt/keyrings/robotpkg.asc
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/robotpkg.asc] http://robotpkg.openrobots.org/packages/debian/pub $(lsb_release -cs) robotpkg" | sudo tee /etc/apt/sources.list.d/robotpkg.list
sudo apt-get update
sudo apt-get install -y robotpkg-pinocchio

2. Install libfranka

# Clone libfranka repository
git clone --recurse-submodules https://github.com/frankarobotics/libfranka.git
cd libfranka

# Checkout specific version (recommended 0.15.0)
git checkout 0.15.0
git submodule update

# Build and install
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/opt/openrobots/lib/cmake -DBUILD_TESTS=OFF ..
make -j$(nproc)

# Create and install Debian package (recommended)
cpack -G DEB
sudo dpkg -i libfranka*.deb

3. Install libfrankapy

Install from Source (Recommended)

# Clone repository
git clone https://github.com/han-xudong/libfrankapy.git
cd libfrankapy

# Create virtual environment (recommended)
python -m venv venv
source venv/bin/activate

# Install Python dependencies
pip install -r requirements.txt

# Build and install
pip install -e .

Install from PyPI

pip install libfrankapy

🎯 Quick Start

Basic Control Example

import libfrankapy as fp
import numpy as np

# Connect to robot
robot = fp.FrankaRobot("192.168.1.100")  # Replace with your robot IP
robot.connect()
robot.start_control()

try:
    # Get current state
    state = robot.get_robot_state()
    print(f"Current joint positions: {state.joint_state.positions}")
    print(f"Current end-effector pose: {state.cartesian_pose.position}")

    # Joint space motion
    target_joints = [0.0, -0.785, 0.0, -2.356, 0.0, 1.571, 0.785]
    robot.move_to_joint(target_joints, speed_factor=0.1)

    # Cartesian space motion
    target_pose = [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 1.0]  # [x, y, z, qx, qy, qz, qw]
    robot.move_to_pose(target_pose, speed_factor=0.1)

finally:
    # Disconnect
    robot.disconnect()

Trajectory Control Example

import libfrankapy as fp

# Create trajectory
trajectory = fp.Trajectory()
trajectory.add_waypoint([0.0, -0.785, 0.0, -2.356, 0.0, 1.571, 0.785], duration=2.0)
trajectory.add_waypoint([0.2, -0.785, 0.0, -2.356, 0.0, 1.571, 0.785], duration=2.0)
trajectory.add_waypoint([0.0, -0.785, 0.0, -2.356, 0.0, 1.571, 0.785], duration=2.0)

# Execute trajectory
robot = fp.FrankaRobot("192.168.1.100")
robot.connect()
robot.start_control()

def progress_callback(progress):
    print(f"Trajectory execution progress: {progress:.1%}")

robot.execute_trajectory(trajectory, callback=progress_callback)
robot.disconnect()

Real-time State Monitoring

import libfrankapy as fp
import time

robot = fp.FrankaRobot("192.168.1.100")
robot.connect()
robot.start_control()

try:
    for i in range(100):  # Monitor for 10 seconds
        state = robot.get_robot_state()

        print(f"Timestamp: {state.timestamp:.3f}")
        print(f"Joint positions: {[f'{q:.3f}' for q in state.joint_state.positions]}")
        print(f"End-effector position: {[f'{p:.3f}' for p in state.cartesian_pose.position]}")
        print(f"External forces: {[f'{f:.3f}' for f in state.external_wrench[:3]]}")
        print("-" * 50)

        time.sleep(0.1)

finally:
    robot.disconnect()

📚 API Documentation

Main Classes

FrankaRobot

Main robot control class.

class FrankaRobot:
    def __init__(self, robot_ip: str, realtime_config: Optional[RealtimeConfig] = None)
    def connect() -> bool
    def disconnect() -> None
    def is_connected() -> bool
    def start_control() -> None
    def stop_control() -> None
    def move_to_joint(self, joint_positions: List[float],
                      speed_factor: float = 0.1,
                      acceleration_factor: float = 0.1) -> bool
    def move_to_pose(self, target_pose: List[float],
                     speed_factor: float = 0.1) -> bool
    def execute_trajectory(self, trajectory: Trajectory,
                          callback: Optional[Callable] = None) -> bool
    def get_joint_state() -> JointState
    def get_cartesian_pose() -> CartesianPose
    def get_robot_state() -> RobotState
    def emergency_stop() -> None

Data Structures

@dataclass
class JointState:
    positions: List[float]  # 7 joint angles (rad)
    velocities: List[float] # 7 joint velocities (rad/s)
    efforts: List[float]    # 7 joint torques (Nm)
    timestamp: float

@dataclass
class CartesianPose:
    position: List[float]   # [x, y, z] (m)
    orientation: List[float] # [qx, qy, qz, qw] quaternion
    timestamp: float

@dataclass
class RobotState:
    joint_state: JointState
    cartesian_pose: CartesianPose
    external_wrench: List[float]  # [fx, fy, fz, tx, ty, tz]
    control_mode: int
    timestamp: float

🔧 Configuration

Real-time Configuration

config = fp.RealtimeConfig(
    control_frequency=1000,  # Hz
    filter_cutoff=100.0,     # Hz
    safety_limits=fp.SafetyLimits(
        max_joint_velocity=2.0,     # rad/s
        max_joint_acceleration=5.0, # rad/s²
        max_cartesian_velocity=1.0, # m/s
        max_cartesian_acceleration=3.0, # m/s²
        max_force=20.0,             # N
        max_torque=10.0             # Nm
    )
)

robot = fp.FrankaRobot("192.168.1.100", realtime_config=config)

🧪 Testing

# Run all tests
pytest

# Run specific tests
pytest tests/test_robot.py

# Run tests with coverage
pytest --cov=libfrankapy

📖 Examples

See the examples/ directory for more usage examples:

  • basic_control.py - Basic control example
  • trajectory_control.py - Trajectory control example
  • state_monitoring.py - Real-time state monitoring example

🤝 Contributing

We welcome community contributions! Please see CONTRIBUTING.md for details on how to participate in project development.

Development Environment Setup

# Clone repository
git clone https://github.com/han-xudong/libfrankapy.git
cd libfrankapy

# Create development environment
python3 -m venv venv
source venv/bin/activate

# Install development dependencies
pip install -e ".[dev]"

# Install pre-commit hooks
pre-commit install

📄 License

This project is licensed under the Apache License 2.0.

🙏 Acknowledgments

  • Franka Robotics for providing excellent robotic arm hardware and the libfranka library
  • pybind11 for providing excellent Python-C++ binding tools
  • All developers who have contributed to this project

📞 Support

🔗 Related Links


Note: When using this library to control robotic arms, please ensure you follow all safety protocols and test in a controlled environment.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

libfrankapy-0.1.0.tar.gz (124.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

libfrankapy-0.1.0-cp39-cp39-manylinux1_x86_64.whl (183.9 kB view details)

Uploaded CPython 3.9

File details

Details for the file libfrankapy-0.1.0.tar.gz.

File metadata

  • Download URL: libfrankapy-0.1.0.tar.gz
  • Upload date:
  • Size: 124.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for libfrankapy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a2a6ed7f677c698fc97ea3edaf3856b83e7c6f26ddbb59c08b9580713f6d85ec
MD5 aded44ba2e7fd055a74e7b4acbf377e1
BLAKE2b-256 bdee74f973df0affca5d1f277e812e6e69054aa431cf6b04b18711c25c56e218

See more details on using hashes here.

Provenance

The following attestation bundles were made for libfrankapy-0.1.0.tar.gz:

Publisher: release.yml on han-xudong/libfrankapy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file libfrankapy-0.1.0-cp39-cp39-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for libfrankapy-0.1.0-cp39-cp39-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 63fd5f21705b6d7767ff48efba2584e711fcaa08520ec53bdac6da050c626c4c
MD5 4caef2acd210ac22233315ad599f9339
BLAKE2b-256 7d849e9c12b3f8914251a2b1bf88779c1052f0a281fe32042100eed4bfa42f43

See more details on using hashes here.

Provenance

The following attestation bundles were made for libfrankapy-0.1.0-cp39-cp39-manylinux1_x86_64.whl:

Publisher: release.yml on han-xudong/libfrankapy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page