Skip to main content

zero-franky

Use franky from a non-realtime machine through a ZeroMQ protocol.

flowchart LR
    subgraph Client["client process"]
        App["user code"]
        LocalFranky["local franky construction objects"]
        Proxy["zero-franky Robot proxy"]
    end

    subgraph Server["robot host process"]
        Rpc["ZeroMQ RPC server"]
        Builder["motion/policy builders"]
        Session["tracker session policy loop"]
        Handle["franky reference handle"]
        RemoteFranky["real franky Robot"]
        Pub["ZeroMQ state publisher"]
    end

    Robot["Franka robot"]

    App --> LocalFranky
    LocalFranky --> Proxy
    App --> Proxy
    Proxy -- "RPC: msgpack motion payloads" --> Rpc
    Proxy -- "RPC: import ref or cloudpickle policy" --> Rpc
    Rpc --> Builder
    Builder --> RemoteFranky
    Builder --> Session
    Session -- "local update loop" --> Handle
    Handle --> RemoteFranky
    RemoteFranky <--> Robot
    RemoteFranky --> Pub
    Pub -- "SUB: robot.state" --> App

Usage

from zero_franky import setup_zero_franky
from zero_franky import Robot
from franky import Affine, CartesianMotion, ReferenceType

setup_zero_franky("server-ip", 18812)

robot = Robot("192.168.100.1")
motion = CartesianMotion(Affine([0.2, 0.0, 0.0]), ReferenceType.Relative)
robot.move(motion, asynchronous=True)
robot.join_motion()

Robot is a proxy, and real local franky objects like Affine, CartesianMotion, and JointMotion are encoded into plain msgpack payloads. The server reconstructs corresponding real franky objects next to the robot.

Server

On the robot host:

zero-franky server

By default this binds RPC on tcp://0.0.0.0:18812, state PUB on tcp://0.0.0.0:18813, and tracker updates on tcp://0.0.0.0:18814.

Common overrides:

zero-franky server --host 192.168.1.20 --port 18812
zero-franky server --port 19000 --no-pub

Robotiq gripper

Robotiq 2F-85 support is optional. Install both control-machine extras only on hosts that physically run the robot and gripper services:

pip install 'zero-franky[server,robotiq]'

The base installation contains the network client and does not import or require pyrobotiqgripper.

Run the robot server together with the gripper server with --robotiq:

zero-franky server --robotiq --com-port auto

Or run the gripper service on its own (e.g. on a different host, or the robot server is already running separately):

zero-franky gripper serve --com-port auto

The gripper subcommand also provides diagnostic client commands:

zero-franky gripper status --host control-machine
zero-franky gripper open --host control-machine

The equivalent Python entry point is:

from zero_franky.zmq_server import ZmqRobotServer

ZmqRobotServer(
    bind="tcp://0.0.0.0:18812",
    pub_bind="tcp://0.0.0.0:18813",
    tracker_bind="tcp://0.0.0.0:18814",
).serve_forever()

Implemented protocol

  • robot.create
  • robot.recover_from_errors
  • robot.move
  • robot.join_motion
  • robot.poll_motion
  • robot.stop
  • robot.get_last_teleop_state
  • robot.start_joint_tracker
  • robot.start_cartesian_tracker
  • tracker.status
  • tracker.stop
  • tracker.set_joint_reference
  • tracker.set_cartesian_reference
  • tracker.set_joint_gains
  • tracker.set_joint_cartesian_gains
  • tracker.set_cartesian_gains
  • tracker.set_nullspace_gains

Supported motion payloads cover position, velocity, waypoint, stop, and fixed impedance motions.

Telemetry

When the server has a pub_bind, RobotManager registers a motion callback and publishes snapshots on robot.state.

setup_zero_franky("server-ip", 18812)
subscriber = robot.state_subscriber()
topic, state = subscriber.recv()

Tracker Sessions

Tracker sessions are for JointImpedanceTrackingMotion and CartesianImpedanceTrackingMotion. They keep the impedance motion and reference handle on the robot host. By default, client code sets references through the returned proxy:

with robot.start_joint_impedance_session(stiffness=[10.0] * 7, damping=[6.0] * 7) as session:
    session.set_joint_reference(q, velocity=dq)
    session.set_joint_gains(stiffness=[20.0] * 7, damping=[8.0] * 7)

The proxy stops the tracker when the context block exits.

A session can also run a Python policy loop beside the reference handle. This avoids trying to servo over ZeroMQ while still letting client code define the policy.

There are two policy transports:

  • import: send module + qualname; the server imports the policy. Use this for stable policies installed on the robot host.
  • cloudpickle: serialize the function and send it over RPC. Use this for exploratory work on a trusted control network.

The built-in hold policies are importable:

from zero_franky.tracker_policies import hold_current_joint

with robot.start_joint_impedance_session(
    hold_current_joint,
    stiffness=[10.0] * 7,
    damping=[6.0] * 7,
) as session:
    status = session.status()

Or it can be shipped with cloudpickle for exploratory work:

import math


def wiggle_joints(context):
    q = list(context.robot.current_joint_positions)
    amplitude = 0.03
    frequency = 0.25
    phase_offsets = [index * math.pi / 7.0 for index in range(7)]

    def step(context):
        omega = 2.0 * math.pi * frequency
        position = [
            q_i + amplitude * math.sin(omega * context.elapsed + phase)
            for q_i, phase in zip(q, phase_offsets)
        ]
        velocity = [
            amplitude * omega * math.cos(omega * context.elapsed + phase)
            for phase in phase_offsets
        ]
        return {"position": position, "velocity": velocity}

    return step

with robot.start_joint_impedance_session(
    wiggle_joints,
    policy_transport="cloudpickle",
    stiffness=[10.0] * 7,
) as session:
    status = session.status()

cloudpickle policy transport executes client-provided Python on the robot host. Use it only on a trusted control network.

Cartesian sessions use the same policy shape and return an Affine target:

from zero_franky.tracker_policies import hold_current_cartesian

with robot.start_cartesian_impedance_session(
    hold_current_cartesian,
    translational_stiffness=250.0,
    rotational_stiffness=25.0,
) as session:
    session.set_cartesian_gains(translational_stiffness=300.0, rotational_stiffness=30.0)
    status = session.status()

The policy function receives a context with franky, robot, elapsed, iterations, and stop(). A factory may return a step function, or the policy may act directly as the step function. Joint steps return {"position": q, "velocity": dq, "torque_feedforward": tau}. Cartesian steps return {"target": affine, "target_twist": twist}.

Metadata

Release files for zero-franky 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zero-franky 0.1.3
File Size Uploaded Provenance Actions
zero_franky-0.1.3.tar.gz 26.2 kB With provenance Details for zero_franky-0.1.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for zero-franky 0.1.3
File Interpreter ABI Platform Actions
zero_franky-0.1.3-py3-none-any.whl Python 3 none any Details for zero_franky-0.1.3-py3-none-any.whl

Total release size: 55.0 kB

Release files / zero_franky-0.1.3.tar.gz

Download URL zero_franky-0.1.3.tar.gz
Size 26.2 kB
Tags Source
SHA-256 checksum
How to use checksums
ccd80d401544c6d83719c878f12dcaf980957b300b529bd1416388ff2cf62241
BLAKE2b-256 checksum
How to use checksums
a8883548668e6fe4b84ca004bd9479ee3bf6e419d11288259a17647b55bc4087
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 16, 2026.

Transparency log

Release files / zero_franky-0.1.3-py3-none-any.whl

Download URL zero_franky-0.1.3-py3-none-any.whl
Size 28.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a6df5ef5224bbd98e34d4cd992122f1633a73398709d90490129d5428f4c0728
BLAKE2b-256 checksum
How to use checksums
1385feac971e64bb9361f994f83eb87f64f2307882c08345dfc17fd8a11181ea
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 16, 2026.

Transparency log

Security for zero-franky 0.1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for zero_franky-0.1.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 16, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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