Free shipping on every order. No tariffs or duties to pay at checkout or on delivery.

Impedance control (MIT mode) on robot joint modules

By Tolerance Labs engineering team · Updated

Many joint modules accept one command that sets a target position and velocity, a stiffness, a damping and a feed-forward torque. The joint then behaves like a spring and damper around the target. This guide covers choosing those numbers and switching them on safely.

The command

The joint computes its torque from five fields: τ = Kp·(q_des − q) + Kd·(q̇_des − q̇) + τ_ff. Here q is the measured joint angle, q̇ the measured velocity, q_des and q̇_des the targets, Kp the stiffness, Kd the damping and τ_ff a feed-forward torque. The result becomes a current command for the motor’s current loop. Setting some fields to zero gives familiar modes:

  • Position hold: Kp and Kd set, q̇_des = 0.
  • Velocity control: Kp = 0, Kd and q̇_des set.
  • Pure torque: Kp = Kd = 0, so the joint outputs τ_ff alone.
  • Damping only: Kp = 0, q̇_des = 0, Kd set. The joint resists motion but holds no position, which makes a useful safe state.

The name comes from the open-source motor controller of the MIT Cheetah robots. The joint evaluates the law locally, typically at several kHz or faster, while the host sends targets at 200 Hz to 1 kHz. CAN, CAN FD, EtherCAT or RS485 covers the bus side.

Units of Kp and Kd

At the output, Kp is in N·m/rad and Kd in N·m·s/rad. A Kp of 20 N·m/rad pulls back with 2 N·m at 0.1 rad (about 5.7°) of error. Before tuning, check:

  • Angle unit. A gain meant as N·m/rad but read as N·m per degree is 57.3 times stiffer than intended.
  • Motor side or output side. If the gains act on motor angle and motor torque, the output feels Kp × N², where N is the ratio. On a 9:1 joint, 1 N·m/rad at the motor feels like 81 N·m/rad at the output.
  • Torque clamp. Past the clamp, the output saturates and the joint stops acting like a spring.

Choosing gains from natural frequency and damping

Treat the joint and its link as a mass, spring and damper. With total inertia J about the joint axis, the closed loop has natural frequency ω_n = √(Kp ÷ J) and damping ratio ζ = Kd ÷ (2·√(Kp·J)). Turned around, Kp = J·ω_n² and Kd = 2·ζ·√(Kp·J).

J is the link inertia plus rotor inertia times N². A damping ratio of about 0.7 settles quickly with little overshoot; 1.0 gives none.

Worked example: a 9:1 joint swings a link that acts like 2 kg at 0.25 m. Rotor inertia is 5 × 10⁻⁵ kg·m². Target: 5 Hz natural frequency and ζ = 0.7.

  • Link inertia: 2 kg × 0.25² m² = 2 × 0.0625 = 0.125 kg·m².
  • Reflected rotor inertia: 5 × 10⁻⁵ × 81 ≈ 0.0041 kg·m².
  • Total J ≈ 0.129 kg·m².
  • ω_n = 2π × 5 ≈ 31.4 rad/s, so ω_n² ≈ 987.
  • Kp = 0.129 × 987 ≈ 127 N·m/rad.
  • Kd = 2 × 0.7 × √(127 × 0.129) = 1.4 × √16.4 ≈ 1.4 × 4.05 ≈ 5.7 N·m·s/rad.

Two checks follow. Gravity on this link is 2 × 9.81 × 0.25 ≈ 4.9 N·m when it is horizontal, which leaves a sag of 4.9 ÷ 127 ≈ 0.039 rad, about 2.2°. Send a gravity estimate in τ_ff instead of raising Kp. And a 0.1 rad error asks for 12.7 N·m; if that is near peak torque, the output saturates.

The same gains act very differently on another load. Take the link off and J falls to 0.0041 kg·m². Then ω_n = √(127 ÷ 0.0041) ≈ 176 rad/s, about 28 Hz, and ζ = 5.7 ÷ (2 × √(127 × 0.0041)) ≈ 5.7 ÷ 1.44 ≈ 4. Heavy damping on a light load is where sampling and velocity noise cause chatter, so test gains on a leg in the air as well as under load.

Update rate and latency

Every loop has delay: encoder sampling, velocity filtering and, if the loop runs on the host, the bus round trip. A delay T adds a phase lag of ω·T radians at frequency ω. A 2 ms delay at 31.4 rad/s adds about 0.063 rad (3.6°), which is harmless. At 176 rad/s it adds about 0.35 rad (20°), enough to make a lightly damped loop ring. A common rule is to run the loop at 10 to 20 times the highest natural frequency in Hz.

Damping has its own limit. In a simple sampled model, a damper on inertia J at sample period T goes unstable when Kd·T ÷ J exceeds 2. For the bare joint, a host loop at 1 kHz caps Kd at 2 × 0.0041 ÷ 0.001 ≈ 8.2 N·m·s/rad, and one extra sample of delay halves that to about 4.1, below the 5.7 tuned above. Inside the joint at 10 kHz the bound is ten times higher, which is why the joint, not the host, should run the impedance law.

What limits the gains

Velocity noise limits Kd. One count of a 14-bit output encoder is 2π ÷ 16,384 ≈ 0.00038 rad. Differenced at 10 kHz, one count reads as 3.8 rad/s, and at Kd = 5.7 that is a 22 N·m spike. A 14-bit motor encoder behind 9:1 is nine times finer at the output, which cuts the spike to about 2.4 N·m. Firmware filters velocity, and the filter adds delay, which tightens the limits above.

Compliance and backlash limit Kp. A loop closed on the motor encoder cannot see backlash and windup, so the output still moves by that much under load. A loop closed on an output encoder includes the gearbox, whose stiffness and the reflected inertia form a resonance the gains must stay below. See backlash and torsional stiffness.

Reflected inertia and friction set floors. Impedance control cannot make the joint feel lighter than its reflected inertia without a torque measurement in the loop, such as a series elastic element. On high-ratio joints, friction makes a soft Kp stick and then slip. Impedance mode works best on backdrivable joints.

Fixed-point command fields

To fit five fields into one 8-byte CAN frame, joints pack them as fixed-point integers. A common layout uses 16 bits for position and 12 bits each for velocity, Kp, Kd and torque, 64 bits in all. Each maps linearly: value = min + raw × (max − min) ÷ (2^bits − 1). Typical ranges, which differ by vendor and model:

FieldBitsExample rangeStep size
Position16−12.5 to +12.5 rad25 ÷ 65,535 ≈ 0.00038 rad
Velocity12−45 to +45 rad/s90 ÷ 4,095 ≈ 0.022 rad/s
Kp120 to 500 N·m/rad500 ÷ 4,095 ≈ 0.12 N·m/rad
Kd120 to 5 N·m·s/rad5 ÷ 4,095 ≈ 0.0012 N·m·s/rad
Torque12−18 to +18 N·m36 ÷ 4,095 ≈ 0.0088 N·m

In this layout the Kd of 5.7 from the example does not fit and would clamp at 5. A ±12.5 rad range covers about two output turns each way. If host and joint disagree on a range, every command is silently scaled, so read ranges from the joint’s own documentation, not another model’s example code.

Safe startup

A joint that wakes with a high Kp and a stale target jumps at full torque: a 1 rad error at 127 N·m/rad asks for 127 N·m. Use a fixed sequence:

  • Read the measured position and check that it is inside the expected range.
  • Enable with Kp = 0, Kd = 0 and τ_ff = 0, so the joint is limp.
  • Set q_des to the measured position and q̇_des to zero.
  • Raise Kd first. Damping cannot cause a jump.
  • Ramp Kp to its target over 0.5 to 2 s.
  • Move q_des along a smooth trajectory to the start pose. Never step it.
  • Set a torque clamp and a command timeout that falls back to damping or a brake.

On a gravity-loaded arm the limp step lets the link fall. Start from a supported pose, add gravity to τ_ff before ramping Kp, or hold the joint with a brake until the gains are up.

Checklist

  • Confirm the angle unit, motor or output side, and every field’s range.
  • Compute J loaded and unloaded.
  • Kp = J·ω_n² and Kd = 2·ζ·√(Kp·J).
  • Keep Kp times expected error below peak torque; carry gravity in τ_ff.
  • Loop rate 10 to 20 times the natural frequency; Kd·T ÷ J well below 2.
  • Enable limp, add damping, ramp stiffness, then move.

Compare quasi-direct-drive joint modules, which suit impedance control best, with other robot joint modules in Robot Parts, and check each datasheet for control modes and command ranges.

More guides

Not sure what fits? Tell us what you're building.

We procure every part of the robot. Send a sentence or a BOM and we come back with options and a landed quote.

Send a request