Skip to article

Configure gravity compensation

Checked 2026-11-01

Result: use a model matching your arm and understand what happens when control ends. You need verified calibration and a controller file.

Check the model match

The host computes effort from measured positions and sends it to the servos. Firmware contains no arm geometry. Positive effort follows increasing encoder counts; the model must account for the physical joint direction.

Two models describe upright arms with empty grippers:

File in host/arm-control/models/ Arm
arm-upright-empty.json SO-102
so101-upright-empty.json SO-101

Both define coupled terms for M2–M4 and explicit zero effort for M1, M5 and M6. The supplied six-motor arm setup uses IDs 1–6 with a profile for every motor. Their calibration binds specific encoder offsets, unit resolution and reversal flags; preflight compares those values with the motors before starting control.

An arm name or a reference reading of 2048 is insufficient. Do not copy another arm’s offsets into your motors or change only encoderCalibration to pass the check. Different calibration, mounting, geometry or payload requires an adapted or fitted model and hardware validation.

Connect a validated model

For tools/poses/controller.local.json, add this field to the existing JSON object; the line is not a complete configuration:

"gravityModel": "../../host/arm-control/models/arm-upright-empty.json"

That path selects the SO-102 model. The SO-101 file is so101-upright-empty.json; its status explicitly requires validation on the intended arm and motion path. Use a relative path for your own model and preserve commas between JSON fields.

Each profile’s gravitySlewEffortPerS limits how quickly gravity effort changes; effortLimit caps total motor output. Without gravityModel, the tools run without a model and clear retained gravity when reusing a session. A nonzero slew setting alone does not enable compensation.

Check before moving

Run normal preview with your recording:

macOS / Linux
npm run replay -- tools/poses/controller.local.json POSES.json
Windows PowerShell
npm.cmd run replay -- tools/poses/controller.local.json POSES.json

A calibration mismatch, missing input or excessive computed effort requires investigation. Results above model or motor limits are rejected rather than silently clipped. Do not raise a limit merely to suppress the error without reviewing the load.

With --run, the controller calculates, sends and confirms gravity before the first motion target. On a supported mechanism, verify direction and behavior at several poses and loads. One successful pose does not validate the entire workspace.

During control and after exit

Feedback and gravity share one reader, with updates approximately every 50 ms. Host freshness and deadline checks do not make the host a real-time system.

Normal completion leaves the final compensation in the servo. It no longer adapts to pose or payload changes. Missing messages also do not clear gravity: firmware approaches the last request at the configured slew rate and keeps it. Torque-off clears it. See finishing the first movement.

Creating a model

Every controlled motor needs an explicit model, including zero-compensation entries. Every input used by coupled terms must be controlled and measured. Terms use coefficient × sin(angle) or coefficient × cos(angle), where angle = offsetRad + sum(counts[id] × weights[id]). Angles are radians and coefficients are PWM effort units. Constant terms have no weights.

Log-based fitting and independent validation belong to the tuning process. Fitted coefficients are not measured physical torque and do not automatically constitute a validated model.


Documentation home · Source revision: a995f77. Extension 9.0.