Pinocchio
Pinocchio is a library for efficiently computing the dynamics (and derivatives) of a robot model, or of any articulated rigid-body model. It is primarily written in C++ with comprehensive Python bindings, leveraging Eigen for linear algebra and FCL for collision detection. It provides state-of-the-art rigid body algorithms and their analytical derivatives. The current version is 3.9.0, with frequent minor and patch releases.
Warnings
- breaking Migrating from Pinocchio 2.x to 3.x involves significant API changes. Many deprecated functions from version 2.x have been removed, and several functions/headers have been renamed or moved. The library's internal structure was also split into multiple CMake targets.
- gotcha Python version compatibility can be sensitive, particularly with Python 3.10 and newer versions or specific environments (e.g., Conda, Arch Linux). Users may encounter `ImportError` or unexpected crashes if `pinocchio` binaries are linked against an incompatible `Boost.Python` version (e.g., built for Python 3.8 trying to run on 3.10). Pinocchio 3.9.0 explicitly states Python 3.10 as the minimal supported version.
- gotcha Visualization tools (like Meshcat, Gepetto Viewer, Panda3D Viewer, RViz) are not part of the core `pin` (pinocchio) package and must be installed separately. The examples and tutorials often assume one of these viewers is available, leading to errors if they are not installed or configured.
- gotcha In older Pinocchio versions, C++ assertion failures (e.g., due to incorrect input vector sizes for model or data) could lead to a hard crash of the Python interpreter, rather than raising a Python exception. This behavior was tied to how the C++ library was compiled (assertions enabled, `NDEBUG` undefined).
Install
-
pip install pin -
conda install pinocchio -c conda-forge
Imports
- pinocchio
import pinocchio
Quickstart
import pinocchio as pin
import numpy as np
# Create a simple 6-DOF kinematic chain (built-in sample model)
model = pin.buildSampleModelManipulator()
data = model.createData()
# Get model information
print(f"Model name: {model.name}")
print(f"Number of joints: {model.nq}")
# Sample a random configuration
q = pin.randomConfiguration(model)
print(f"Random configuration (q): {q.T}")
# Perform forward kinematics
pin.forwardKinematics(model, data, q)
# Update all the placements for the joints and frames
pin.updateFramePlacements(model, data)
# Print the position of the end-effector frame
EE_frame_idx = model.getFrameId("joint6") # Assuming 'joint6' is the end-effector
if EE_frame_idx < model.nframes:
print(f"End-effector (joint6) position: {data.oMf[EE_frame_idx].translation.T}")
else:
print("End-effector frame 'joint6' not found in model.")
# Example for loading a URDF (requires 'example-robot-data' and a URDF file)
# from example_robot_data import loadUR
# robot = loadUR(robot_name='ur5')
# model_urdf = robot.model
# data_urdf = model_urdf.createData()
# q_urdf = pin.randomConfiguration(model_urdf)
# print(f"URDF model name: {model_urdf.name}, random config: {q_urdf.T}")