Skip to main content

Troubleshooting & FAQ

Real gotchas pulled from this workspace's own incident write-ups — not a generic checklist.

A joint silently stops moving mid-trajectory, no error​

Symptom: every other joint keeps going, only one stalls. No status flag, no current draw, nothing in the logs.

Cause: the servo's own EEPROM MIN/MAX_ANGLE_LIMIT is stricter than what the calibration file or planner believes. Software layers above the servo (calibration, planner YAML, URDF) are all beliefs about where the mechanism stops — only the EEPROM register and the physical hard stop are real, and nothing compares them by default. One real incident: a TCP plan asked wrist_flex to move 0.41 rad past its actual EEPROM cap.

Fix: execute.py reads every servo's live EEPROM limits and checks the manifest's waypoints against them before streaming anything — it now refuses the run and names the joint and overshoot. If you hit this during development, soarm-widen-limit walks a limit outward (toward the URDF's own bound, never further) in small steps while watching current, and records the result so future connects catch a mismatch immediately. See soarm_tamp/docs/joint-limits-architecture.md for the full layer map.

The arm sits at an arbitrary pose — never assume zero before enabling torque​

The SO-101 doesn't return to a known pose when powered off. Before enabling torque on a freshly connected arm, park it at a measured pose (or use a dashboard's Home button, which moves to a known folded-flat pose via the arm's own calibration) rather than assuming it's near zero.

IMU yaw drifts even after calibration​

The gyro bias calibration at boot only removes a constant bias — see IMU Setup § Gyro bias calibration. If the device was moved during the ~2.5 s calibration window, the bias estimate is wrong and drift will be visible; power-cycle and keep it still. Beyond that, m5teleop's ESKF corrects yaw at rest via ZARU — sustained rotation can still drift, since there's no magnetometer fusion in the current pipeline. See Tuning Guide § Known limitations.

Teleop arm oscillates, is sluggish, or won't track after zero-reset​

These all have specific config knobs — see the full symptom → fix table in Teleoperation → Tuning Guide.

Servo bus / hardware issues​

  • Baud rate mismatch — confirm controller and servos agree; some adapters top out below 1 Mbps.
  • Mixed firmware revisions — update all servos to the same version before chaining them.
  • Power polarity — double-check barrel jack wiring (5.5/2.1 mm vs. 5.5/2.5 mm) before powering up.
  • A joint moves the wrong direction — direction signs are per-joint and must be verified against the physical robot: command +0.1 rad on each joint and confirm it moves the expected way (soarm_sdk.conversions.SOARM100_DIRECTION_SIGNS).

See Specifications → Hardware for the full hardware reference.

TAMP execution: arm drove into the table / joints fell out of sync​

A HPP-certified collision-free plan is not automatically a plan the servos can track — streaming waypoints at a fixed rate without waiting for arrival lets joints desynchronize from the checked path. This is a real documented incident with the full root-cause and fix — see TAMP planning & execution, step by step § 6 and soarm_tamp/docs/execution-tuning.md for the complete account, including why "settle slowly" makes the last-centimeter error worse, not better.

Calibrate before a first real run​

Before running m5teleop or soarm_tamp against real hardware for the first time: calibrate the arm (see Quick Start → Calibration), and confirm which serial port is the servo bus vs. the IMU (ls /dev/cu.usbserial-* with only one plugged in at a time is the reliable way to tell them apart).