Browse by type
franky is a high-level control library for Franka robots, offering Python and C++ support. By providing a high-level control interface, franky eliminates the need for strict real-time programming at 1 kHz, making control from non-real-time environments, such as Python programs, feasible. Instead of relying on low-level control commands, franky expects high-level position or velocity targets and uses Ruckig to plan time-optimal trajectories in real-time.
Although Python does not provide real-time guarantees, franky strives to maintain as much real-time control as possible. Motions can be preempted at any moment, prompting franky to re-plan trajectories on the fly. To handle unforeseen situations—such as unexpected contact with the environment — franky includes a reaction system that allows for updating motion commands dynamically. Furthermore, most non-real-time functionality of libfranka, such as Gripper control is made directly available in Python.
Check out the tutorial and the examples for an introduction. The full documentation can be found at https://timschneider42.github.io/franky/.
Control your Franka robot directly from Python in just a few lines!
No more endless hours setting up ROS, juggling packages, or untangling dependencies. Just pip install — no ROS at all.
Four control modes: Cartesian position, Cartesian velocity, Joint position, Joint velocity franky uses Ruckig to generate smooth, time-optimal trajectories while respecting velocity, acceleration, and jerk limits.
Real-time control from Python and C++ Need to change the target while the robot’s moving? No problem. franky replans trajectories on the fly so that you can preempt motions anytime.
Reactive behavior Robots don’t always go according to plan. franky lets you define reactions to unexpected events—like contact with the environment — so you can change course in real-time.
Motion and reaction callbacks Want to monitor what’s happening under the hood? Add callbacks to your motions and reactions. They won’t block the control thread and are super handy for debugging or logging.
Things are moving too fast? Tune the robot's dynamics to your needs Adjust max velocity, acceleration, and jerk to match your setup or task. Fine control for smooth, safe operation.
Full Python access to the libfranka API Want to tweak impedance, read the robot state, set force thresholds, or mess with the Jacobian? Go for it. If libfranka supports it, chances are franky does, too.
Real-time kernel already installed and real-time permissions granted? Just install franky via
pip install franky-control
Otherwise, follow the setup instructions first.
Now we are already ready to go! Unlock the brakes in the web interface, activate FCI, and start coding:
from franky import *
robot = Robot("10.90.90.1") # Replace this with your robot's IP
# Let's start slow (this lets the robot use a maximum of 5% of its velocity, acceleration, and jerk limits)
robot.relative_dynamics_factor = 0.05
# Move the robot 20cm along the relative X-axis of its end-effector
motion = CartesianMotion(Affine([0.2, 0.0, 0.0]), ReferenceType.Relative)
robot.move(motion)
If you are seeing server version mismatch errors, such as
franky.IncompatibleVersionException: libfranka: Incompatible library version (server version: 5, library version: 9)
then your Franka robot is either not on the most recent firmware version, or you are using the older Franka Panda model. In any case, it's no big deal; just check here which libfranka version you need and follow our instructions to install the appropriate franky wheels.
To install franky, you have to follow three steps:
In order for Franky to function properly, it requires the underlying OS to use a real-time kernel.
Otherwise, you might see communication_constrains_violation errors.
To check whether your system is currently using a real-time kernel, type uname -a.
You should see something like this:
$ uname -a
Linux [PCNAME] 5.15.0-1056-realtime #63-Ubuntu SMP PREEMPT_RT ...
If it does not say PREEMPT_RT, you are not currently running a real-time kernel.
There are multiple ways of installing a real-time kernel. You can build it from source or, if you are using Ubuntu, it can be enabled through Ubuntu Pro.
First, create a group realtime and add your user (or whoever is running franky) to this group:
sudo addgroup realtime
sudo usermod -a -G realtime $(whoami)
Afterward, add the following limits to the real-time group in /etc/security/limits.conf:
@realtime soft rtprio 99
@realtime soft priority 99
@realtime soft memlock 102400
@realtime hard rtprio 99
@realtime hard priority 99
@realtime hard memlock 102400
Log out and log in again to let the changes take effect.
To verify that the changes were applied, check if your user is in the realtime group:
$ groups
... realtime
If real-time is not listed in your groups, try rebooting.
To start using franky with Python and libfranka 0.18.0, just install it via
pip install franky-control
We also provide wheels for libfranka versions 0.7.1, 0.8.0, 0.9.2, 0.12.1, 0.13.3, 0.14.2, 0.17.0, and 0.18.0. They can be installed via
VERSION=0-9-2
wget https://github.com/TimSchneider42/franky/releases/latest/download/libfranka_${VERSION}_wheels.zip
unzip libfranka_${VERSION}_wheels.zip
pip install numpy
pip install --no-index --find-links=./dist franky-control
To use franky within Docker we provide a Dockerfile and accompanying docker-compose file.
git clone --recurse-submodules https://github.com/timschneider42/franky.git
cd franky/
docker compose build franky-run
To use another version of libfranka than the default (0.18.0), add a build argument:
docker compose build franky-run --build-arg LIBFRANKA_VERSION=0.9.2
To run the container:
docker compose run franky-run bash
The container requires access to the host machine's network and elevated user rights to allow the Docker user to set RT capabilities of the processes run from within it.
Yes. However, you need to set IGNORE_PREEMPT_RT_PRESENCE=1 during the installation and all subsequent updates of the CUDA drivers on the real-time kernel.
First, make sure that you have rebooted your system after installing the real-time kernel.
Then, add IGNORE_PREEMPT_RT_PRESENCE=1 to /etc/environment, call export IGNORE_PREEMPT_RT_PRESENCE=1 to also set it in the current session, and follow the instructions of Nvidia to install CUDA on your system.
If you are on Ubuntu, you can also use this script to install CUDA on your real-time system:
# Download the script
wget https://raw.githubusercontent.com/timschneider42/franky/master/tools/install_cuda_realtime.bash
# Inspect the script to ensure it does what you expect
# Make it executable
chmod +x install_cuda_realtime.bash
# Execute the script
./install_cuda_realtime.bash
Alternatively, if you are a cowboy and do not care about security, you can also use this one-liner to directly call the script without checking it:
bash <(wget -qO- https://raw.githubusercontent.com/timschneider42/franky/master/tools/install_cuda_realtime.bash)
No problem! There are two projects which let you run franky remotely via RPC with minimal effort: franky-remote and net_franky.
Please note that I’m not involved in the development of these projects, so I cannot take any liability for its use. If you decide to use it, please ensure that you credit the developers of these projects for their work.
franky is based on libfranka, Eigen for transformation calculations and pybind11 for the Python bindings. As the Franka is sensitive to acceleration discontinuities, it requires jerk-constrained motion generation, for which franky uses the Ruckig community version for Online Trajectory Generation (OTG).
After installing the dependencies (the exact versions can be found here), you can build and install franky via
git clone --recurse-submodules git@github.com:timschneider42/franky.git
cd franky
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
make install
To use franky, you can also include it as a subproject in your parent CMake via add_subdirectory(franky) and then
target_link_libraries(<target> franky).
If you need only the Python module, you can install franky via
pip install .
Make sure that the built library _franky.cpython-3**-****-linux-gnu.so is in the Python path, e.g. by adjusting
PYTHONPATH accordingly.
For building franky and its wheels, we provide another Docker container that can also be launched using docker-compose:
docker compose build franky-build
docker compose run --rm franky-build run-tests # To run the tests
docker compose run --rm franky-build build-wheels # To build wheels for all supported python versions
franky comes with both a C++ and Python API that differ only regarding real-time capability.
We will introduce both languages next to each other.
In your C++ project, just include include <franky.hpp> and link the library.
For Python, just import franky.
As a first example, only four lines of code are needed for simple robotic motions.
#include <franky.hpp>
using namespace franky;
// Connect to the robot with the FCI IP address
Robot robot("10.90.90.1");
// Reduce velocity and acceleration of the robot
robot.setRelativeDynamicsFactor(0.05);
// Move the end-effector 20cm in positive x-direction
auto motion = std::make_shared<CartesianMotion>(RobotPose(Affine({0.2, 0.0, 0.0}), 0.0), ReferenceType::Relative);
// Finally move the robot
robot.move(motion);
The corresponding program in Python is
from franky import Affine, CartesianMotion, Robot, ReferenceType
robot = Robot("10.90.90.1")
robot.relative_dynamics_factor = 0.05
motion = CartesianMotion(Affine([0.2, 0.0, 0.0]), ReferenceType.Relative)
robot.move(motion)
Before executing any code, make sure that you have enabled the Franka Control Interface (FCI) in the Franka UI web interface.
Furthermore, we will introduce methods for geometric calculations, for moving the robot according to different motion types, how to implement real-time reactions and changing waypoints in real time, as well as controlling the gripper.
franky.Affine is a python wrapper for Eigen::Affine3d.
It is used for Cartesian poses, frames and transformation.
franky adds its own constructor, which takes a position and a quaternion as inputs:
import math
from scipy.spatial.transform import Rotation
from franky import Affine
z_translation = Affine([0.0, 0.0, 0.5])
quat = Rotation.from_euler("xyz", [0, 0, math.pi / 2]).as_quat()
z_rotation = Affine([0.0, 0.0, 0.0], quat)
combined_transformation = z_translation * z_rotation
In all cases, distances are in [m] and rotations in [rad].
franky exposes most of the libfanka API for Python. Moreover, we added methods to adapt the dynamic limits of the robot for all motions.
```python from franky import *
robot = Robot("10.90.90.1")
robot.recover_from_
$ claude mcp add franky \
-- python -m otcore.mcp_server <graph>