Franky
0.2.0
A High-Level Motion API for Franka
|
Franky is a high-level motion library (both C++ and Python) for the Franka Emika robot. It adds a Python wrapper around libfranka, while replacing necessary real-time programming with higher-level motion commands. As franky focuses on making real-time trajectory generation easy, it allows the robot to react to unforeseen events.
Franky is a fork of frankx, though both codebase and functionality differ substantially from frankx by now. In particular, franky provides the following new features/improvements:
setCollisionBehavior
, setJoinImpedance
, and setCartesianImpedance
).Affine
changed. Affine
does not handle elbow positions anymore. Instead, a new class RobotPose
stores both the end-effector pose and optionally the elbow position.MotionData
class does not exist anymore. Instead, reactions and other settings moved to Motion
.Measure
class allows for arithmetic operations.To install franky, you have to follow three steps:
In order for franky to function properly, it requires the underlying OS to use a realtime 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:
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:
Afterward, add the following limits to the real-time group in /etc/security/limits.conf:
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:
If realtime is not listed in your groups, try rebooting.
To start using franky with Python and libfranka 0.12.1, just install it via
We also provide wheels for libfranka versions 0.7.1, 0.8.0, 0.9.2, 0.10.0, 0.11.0, 0.12.1, 0.13.3. They can be installed via
Franky is based on libfranka, Eigen for transformation calculations and pybind11 for the Python bindings. Franky uses the Ruckig Community Version for Online Trajectory Generation (OTG). As the Franka is quite sensitive to acceleration discontinuities, it requires constrained jerk for all motions. After installing the dependencies (the exact versions can be found below), you can build and install franky via
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> libfranky)
. If you need only the Python module, you can install franky via
Make sure that the built library can be found from Python by adapting your Python Path.
To use franky within Docker we have supplied a Dockerfile which you currently need to build yourself:
To use another version of libfranka than the default (v.0.7.0) simply change the build argument. Then, to run the container simply:
The container requires access to the host machines network and elevated user rights to allow the docker user to set RT capabilities of the processes run from within it.
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/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.
The corresponding program in Python is
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:
In all cases, distances are in [m] and rotations in [rad].
We wrapped most of the libfanka API (including the RobotState or ErrorMessage) for Python. Moreover, we added methods to adapt the dynamics of the robot for all motions. The rel
name denotes that this a factor of the maximum constraints of the robot.
The robot state can be retrieved by calling the following methods:
state
: Return an object of the franky.RobotState
class which contains most of the same attributes, under the same name, as the libfranka franka::RobotState definition.current_pose
: Return a 3D Affine transformation object of the measured end effector pose in base frame (alias for franka::RobotState::O_T_EE).current_joint_positions
: Return a sequence of the manipulator arm's 7-joint positions (alias for franka::RobotState::q).Franky defines a number of different motion types. In python, you can use them as follows:
Every motion and waypoint type allows to adapt the dynamics (velocity, acceleration and jerk) by setting the respective velocity_rel
, acceleration_rel
, and jerk_rel
parameters.
The real robot can be moved by applying a motion to the robot using move
:
By adding reactions to the motion data, the robot can react to unforeseen events. In the Python API, you can define conditions by using a comparison between a robot's value and a given threshold. If the threshold is exceeded, the reaction fires.
Possible values to measure are
Measure.FORCE_X,
Measure.FORCE_Y,
Measure.FORCE_Z
: Force in X, Y and Z directionMeasure.REL_TIME
: Time in seconds since the current motion startedMeasure.ABS_TIME
: Time in seconds since the initial motion startedThe difference between Measure.REL_TIME
and Measure.ABS_TIME
is that Measure.REL_TIME
is reset to zero whenever a new motion starts (either by calling Robot.move
or as a result of a triggered Reaction
). Measure.ABS_TIME
, on the other hand, is only reset to zero when a motion terminates regularly without being interrupted and the robot stops moving. Hence, Measure.ABS_TIME
measures the total time in which the robot has moved without interruption.
Measure
values support all classical arithmetic operations, like addition, subtraction, multiplication, division, and exponentiation (both as base and exponent).
With arithmetic comparisons, conditions can be generated.
Conditions support negation, conjunction (and), and disjunction (or):
To check whether a reaction has fired, a callback can be attached:
Note that these callbacks are not executed in the control thread since they would otherwise block it. Instead, they are put in a queue and executed by another thread. While this scheme ensures that the control thread can always run, it cannot prevent that the queue grows indefinitely when the callbacks take more time to execute than it takes for new callbacks to be queued. Hence, callbacks might be executed significantly after their respective reaction has fired if they are triggered in rapid succession or take a long time to execute.
In C++ you can additionally use lambdas to define more complex behaviours:
By setting the asynchronous
parameter of Robot.move
to True
, the function does not block until the motion finishes. Instead, it returns immediately and, thus, allows the main thread to set new motions asynchronously.
By calling Robot.join_motion
the main thread can be synchronized with the motion thread, as it will block until the robot finishes its motion.
Note that when exceptions occur during the asynchronous execution of a motion, they will not be thrown immediately. Instead, the control thread stores the exception and terminates. The next time Robot.join_motion
or Robot.move
are called, they will throw the stored exception in the main thread. Hence, after an asynchronous motion has finished, make sure to call Robot.join_motion
to ensure being notified of any exceptions that occurred during the motion.
In the franky::Gripper
class, the default gripper force and gripper speed can be set. Then, additionally to the libfranka commands, the following helper methods can be used:
The Python API is straight-forward for the Gripper class.
An auto-generated documentation can be found at https://timschneider42.github.io/franky/. Moreover, there are multiple examples for both C++ and Python in the examples directory.
Franky is written in C++17 and Python3.7. It is currently tested against following versions
For non-commercial applications, this software is licensed under the LGPL v3.0. If you want to use franky within commercial applications or under a different license, please contact us for individual agreements.