franky.JointImpedanceTracker

class franky.JointImpedanceTracker(robot: Robot, *, stiffness: ndarray | None = None, damping: ndarray | None = None, cartesian_stiffness: ndarray | None = None, cartesian_damping: ndarray | None = None, constant_torque_offset: ndarray | None = None, compensate_coriolis: bool = True, friction: FrictionCompensationParams | None = None, max_delta_tau: float = 1.0, lower_joint_limits: ndarray | None = None, upper_joint_limits: ndarray | None = None, joint_limit_activation_distance: float = 0.1, joint_limit_stiffness: float = 4.0, joint_limit_damping: float = 1.0, joint_limit_max_torque: float = 5.0, gains_time_constant: float = 0.1, period: float | None = None)

Bases: object

A long-lived session for streaming joint impedance tracking commands.

Passing cartesian_stiffness (a 6-vector [x, y, z, rx, ry, rz] in the base frame at the end-effector) enables hybrid Cartesian gain shaping: the controller adds J^T diag(cartesian_stiffness) J on top of the joint-space stiffness each cycle (and likewise for cartesian_damping, defaulting to critical damping when omitted). The hybrid path is fixed for the lifetime of the motion.

Example:

with JointImpedanceTracker(robot, stiffness=[6.0]*7, period=0.01) as tracker:
    while tracker.tick():
        tracker.set_target(q_desired)
__init__(robot: Robot, *, stiffness: ndarray | None = None, damping: ndarray | None = None, cartesian_stiffness: ndarray | None = None, cartesian_damping: ndarray | None = None, constant_torque_offset: ndarray | None = None, compensate_coriolis: bool = True, friction: FrictionCompensationParams | None = None, max_delta_tau: float = 1.0, lower_joint_limits: ndarray | None = None, upper_joint_limits: ndarray | None = None, joint_limit_activation_distance: float = 0.1, joint_limit_stiffness: float = 4.0, joint_limit_damping: float = 1.0, joint_limit_max_torque: float = 5.0, gains_time_constant: float = 0.1, period: float | None = None)
set_gains(*, stiffness: ndarray | None = None, damping: ndarray | None = None) None

Update joint impedance gains (smoothed in the RT loop).

stiffness/damping are orthogonal 7-vectors. damping is all-or-nothing: passing it pins it, CRITICAL unpins it. Omitting damping means critical: a stiffness change re-criticals unless damping is passed too.

set_target(q: ndarray, dq: ndarray | None = None, tau_ff: ndarray | None = None) None

Update the joint target position, optional velocity, and optional feedforward torque.

stop(stop_motion: TorqueStopMotion | None = None) None

Gracefully stop the tracking controller and wait for the arm to come to rest.

Enqueues a TorqueStopMotion that ramps the last commanded torque into a damping-only law, brings the arm to rest, and finishes cleanly (no preemption exception). Pass stop_motion to override the ramp/damping behaviour; otherwise sensible defaults are used.

If the controller is no longer in control (e.g. it already faulted), this just joins the motion to surface any stored exception.

tick() float | None

Sleep to maintain the requested period and return the measured timestep.

Returns the wall-clock seconds elapsed since the previous tick, or None once the controller is no longer in control, so a loop can pace itself and pick up a timestep to integrate with in one step:

while dt := tracker.tick():
    tracker.set_target(integrate(dt))

The returned timestep is always non-zero positive.

On the first call, returns immediately (no sleep) and reports period: the nominal length of the cycle about to run, since there is no previous tick to measure against and construction or caller setup time is not the loop’s to report. With no period configured, the first call reports a negligible non-zero timestep. On subsequent calls, sleeps the remaining time until the next tick boundary so that loop body time is compensated for; a body that overran its period shows up as a timestep larger than period.

If no period was set, just measures and returns without sleeping.

property current_joint_state

The current joint state as a JointState (shorthand for robot.current_joint_state).

property dt: float

The timestep most recently returned by tick() (0.0 before the first tick).

property elapsed_time: float

Seconds since the tracker was created.

property is_running: bool

Whether the tracking controller is still active.

property motion: JointImpedanceTrackingMotion

The underlying tracking motion instance.

property period: float | None

The configured loop period in seconds, or None if the tracker is unpaced.

property state

The current robot state from this control session.

property tick_count: int

Number of ticks that have run, i.e. returned a timestep rather than None.