Skip to main content

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.

Download files

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

Source Distribution

franky_sim-1.0.2.tar.gz (25.9 MB view details)

Uploaded Source

Built Distribution

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

franky_sim-1.0.2-py3-none-any.whl (19.3 MB view details)

Uploaded Python 3

File details

Details for the file franky_sim-1.0.2.tar.gz.

File metadata

  • Download URL: franky_sim-1.0.2.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

Hashes for franky_sim-1.0.2.tar.gz
Algorithm Hash digest
SHA256 cf42ffc5dcfdb37dc030ac63aaafdba6078454e781de9914775e4df822ebd0ff
MD5 2636c40758b97a4f70fa549672997959
BLAKE2b-256 bfed737cc2ddda8e9dda5eb202aefb61bdad0e00306a5a3b06d26ca9e10a12d2

See more details on using hashes here.

Provenance

The following attestation bundles were made for franky_sim-1.0.2.tar.gz:

Publisher: publish.yml on TimSchneider42/franky-sim

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

File details

Details for the file franky_sim-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: franky_sim-1.0.2-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

Hashes for franky_sim-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 dcc08aa9c7d24eab3c1c99e03743b8cb699280b78806b07ed2fa9218bbbd078a
MD5 d6c9e170e975460816e9175907c7d805
BLAKE2b-256 0f174b72c962f5cb302017fe88ec43a4af3276655fc3d8c60ab7194af024b829

See more details on using hashes here.

Provenance

The following attestation bundles were made for franky_sim-1.0.2-py3-none-any.whl:

Publisher: publish.yml on TimSchneider42/franky-sim

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

Release history Release notifications | RSS feed

1.0.4

2 files

1.0.3

2 files

This release

1.0.2 This release

2 files

1.0.1

2 files

1.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page