Drop-in Franka robot simulator implementing the libfranka network protocol.
Project description
franky-sim
A high-fidelity simulation server for the Franka FR3 robot that implements the libfranka network protocol and serves as a drop-in replacement for real hardware.
franky-sim pairs with franky — a Python interface for Franka robots — to give you a full simulation stack with no code changes needed when moving to real hardware.
How it works
franky-sim starts a local TCP/UDP server that speaks the same network protocol as a real Franka robot. Any libfranka-compatible client connects to this server instead of the real robot IP. The server forwards commands to a physics simulator (MuJoCo by default, Genesis optionally) and streams back robot state at 1 kHz.
franky-sim supports all control modes available on the real robot, including joint position, joint velocity, Cartesian position, Cartesian velocity, and gripper control.
Installation
pip install franky-sim
To run the examples below, install with the franky option:
pip install franky-sim[franky]
To use the Genesis physics backend instead of MuJoCo:
pip install franky-sim[genesis]
Quick start
Command-line server
franky-sim # headless (no window)
franky-sim --render # with visualisation
franky-sim --simulator genesis # use Genesis backend
Connect your libfranka/franky client to the IP printed by the program (127.0.0.1 if the port is available).
Embedded server
from franky_sim import SimulationServer
from franky_sim.mujoco_simulator import MujocoSimulator
with MujocoSimulator(enable_visualization=True) as sim:
robot = sim.add_robot()
with SimulationServer(sim) as server:
server.run_async()
print(f"Server ready at {robot.hostname}")
# connect your client here ...
Control mode examples
Joint position control
Move the robot through a series of joint-space waypoints.
import franky
from franky_sim import SimulationServer
from franky_sim.mujoco_simulator import MujocoSimulator
with MujocoSimulator(enable_visualization=True) as sim:
robot_model = sim.add_robot()
with SimulationServer(sim) as server:
server.run_async()
robot = franky.Robot(robot_model.hostname, realtime_config=franky.RealtimeConfig.Ignore)
target = [-0.3, 0.1, 0.3, -1.4, 0.1, 1.8, 0.7]
robot.move(franky.JointWaypointMotion([franky.JointWaypoint(target)]))
print("Joint positions:", list(robot.current_joint_state.position))
Joint velocity control
Command joint velocities for a fixed duration.
import franky
from franky_sim import SimulationServer
from franky_sim.mujoco_simulator import MujocoSimulator
with MujocoSimulator(enable_visualization=True) as sim:
robot_model = sim.add_robot()
with SimulationServer(sim) as server:
server.run_async()
robot = franky.Robot(robot_model.hostname, realtime_config=franky.RealtimeConfig.Ignore)
robot.move(
franky.JointVelocityWaypointMotion([
franky.JointVelocityWaypoint(
[0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
hold_target_duration=franky.Duration(500),
)
])
)
print("Joint positions:", list(robot.current_joint_state.position))
Cartesian position control
Move the end-effector to a target pose in Cartesian space.
import franky
from franky_sim import SimulationServer
from franky_sim.mujoco_simulator import MujocoSimulator
with MujocoSimulator(enable_visualization=True) as sim:
robot_model = sim.add_robot()
with SimulationServer(sim) as server:
server.run_async()
robot = franky.Robot(robot_model.hostname, realtime_config=franky.RealtimeConfig.Ignore)
# Move 5 cm in the x direction (relative to current pose)
robot.move(franky.CartesianMotion(franky.Affine([0.1, 0.0, 0.0]), franky.ReferenceType.Relative))
print("End-effector pose:", robot.current_cartesian_state.pose.end_effector_pose)
Cartesian velocity control
Command end-effector velocity for a fixed duration.
import franky
from franky_sim import SimulationServer
from franky_sim.mujoco_simulator import MujocoSimulator
with MujocoSimulator(enable_visualization=True) as sim:
robot_model = sim.add_robot()
with SimulationServer(sim) as server:
server.run_async()
robot = franky.Robot(robot_model.hostname, realtime_config=franky.RealtimeConfig.Ignore)
# Move at 2 cm/s in the x direction for 500 ms
robot.move(
franky.CartesianVelocityWaypointMotion([
franky.CartesianVelocityWaypoint(
franky.Twist([0.1, 0.0, 0.0]),
hold_target_duration=franky.Duration(500),
)
])
)
print("End-effector pose:", robot.current_cartesian_state.pose.end_effector_pose)
Gripper control
Home, move, and grasp with the simulated gripper.
import franky
from franky_sim import SimulationServer
from franky_sim.mujoco_simulator import MujocoSimulator
with MujocoSimulator(enable_visualization=True) as sim:
robot_model = sim.add_robot()
with SimulationServer(sim) as server:
server.run_async()
gripper = franky.Gripper(robot_model.hostname)
# Home the gripper (opens to max width)
gripper.homing()
print(f"Width after homing: {gripper.width:.4f} m")
# Move to a specific width at a given speed
gripper.move(0.02, 0.05) # 2 cm, 5 cm/s
# Grasp at 2 cm with ±2 cm tolerance
success = gripper.grasp(0.02, 0.02, 10.0, epsilon_inner=0.02, epsilon_outer=0.02)
print(f"Grasp success: {success}, is_grasped: {gripper.is_grasped}")
More examples are available in the examples/ directory.
Limitations
franky-sim does not enforce safety limits on joint positions, velocities, or torques and generally does not produce control errors. Hence, it is not guaranteed that controllers that work in simulation will also work on real hardware.
Furthermore, franky-sim only supports Robot Server version 10 and Gripper Server version 3. No older versions are supported.
Credits
franky-sim was originally forked from libfranka-sim though it has been substantially altered.
Still, many thanks to Baris Yazici for the original work and for making it open source.
License
Apache License 2.0 — see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file franky_sim-1.0.1.tar.gz.
File metadata
- Download URL: franky_sim-1.0.1.tar.gz
- Upload date:
- Size: 25.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d85f647aabf8f564cb2625a3d994ab7f8202f98fe94f109161b5f380adf3aa53
|
|
| MD5 |
a0746632fe76958dee6641e337117980
|
|
| BLAKE2b-256 |
0f0042e1e8ac1e1ebfca91ce5b4c0f1a12f50fa574751dfc0a80576fbceaa092
|
Provenance
The following attestation bundles were made for franky_sim-1.0.1.tar.gz:
Publisher:
publish.yml on TimSchneider42/franky-sim
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
franky_sim-1.0.1.tar.gz -
Subject digest:
d85f647aabf8f564cb2625a3d994ab7f8202f98fe94f109161b5f380adf3aa53 - Sigstore transparency entry: 1968945581
- Sigstore integration time:
-
Permalink:
TimSchneider42/franky-sim@c24ae821a7843fc99dd5f94d1101f0382e07a5dd -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/TimSchneider42
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c24ae821a7843fc99dd5f94d1101f0382e07a5dd -
Trigger Event:
push
-
Statement type:
File details
Details for the file franky_sim-1.0.1-py3-none-any.whl.
File metadata
- Download URL: franky_sim-1.0.1-py3-none-any.whl
- Upload date:
- Size: 19.3 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
670f27ac384243c1d1375b21f65405e012b11c1393de7abfb778900064da9fb0
|
|
| MD5 |
9d71afd47a7f3d0b6cb41f0408e1184c
|
|
| BLAKE2b-256 |
6c9c39f89cff96fdbcfac009d5fad77286a2a4c2ae8bf32edc8178ba60995c8f
|
Provenance
The following attestation bundles were made for franky_sim-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on TimSchneider42/franky-sim
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
franky_sim-1.0.1-py3-none-any.whl -
Subject digest:
670f27ac384243c1d1375b21f65405e012b11c1393de7abfb778900064da9fb0 - Sigstore transparency entry: 1968945615
- Sigstore integration time:
-
Permalink:
TimSchneider42/franky-sim@c24ae821a7843fc99dd5f94d1101f0382e07a5dd -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/TimSchneider42
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c24ae821a7843fc99dd5f94d1101f0382e07a5dd -
Trigger Event:
push
-
Statement type: