Skip to content

fix(panda): judge move_to_pose success by absolute tolerances - #64

Merged
JeanElsner merged 1 commit into
mainfrom
jean/fix/move-to-pose-success
Sep 30, 2026
Merged

JeanElsner merged 1 commit into
mainfrom
jean/fix/move-to-pose-success

Conversation

@JeanElsner

@JeanElsner JeanElsner commented Sep 30, 2026 •

Copy link
Copy Markdown
Owner

Stacked on #63, which is stacked on #61. Merge in that order; each retargets to main when its base merges.

Summary

move_to_pose returned False for most moves that finished as well as its controller can.

  • Position tolerance was relative. Eigen's isApprox made it 1% of the goal's distance from the robot base, about 5 mm at the start pose and more further out.
  • Orientation was compared as raw quaternion coefficients. That gives about 1.1° of tolerance, and q and −q, the same orientation, compared unequal.
  • The warning was misleading. It reported only the position error, although orientation usually decided the result: a move could say "finished 0.0043 m from the goal" with 4.3 mm inside the position tolerance.

Why the defaults are what they are. The Cartesian controller is an impedance controller without integral action. It settles wherever its spring balances friction. Measured on an FER at the default impedance (800 N/m, 40 Nm/rad), four 5 cm moves from the start pose ended up to 7.7 mm and 3.0° from the goal, which is about 3–5 N and 2 Nm of friction. Three of the four returned False. Tripling the impedance roughly halved the errors, which confirms the cause.

Changes

  • success_threshold for move_to_pose is now an absolute distance in metres, 0.02 by default.
  • New orientation_threshold, a rotation angle in radians, 0.1 (5.7°) by default. It's computed with Quaterniond::angularDistance, so the quaternions' sign no longer matters.
  • The warning reports both errors and both thresholds. The docstring explains the defaults and suggests tightening them together with a higher impedance.
  • Test hooks: _core._pose_error exposes the computation, and _core._MOVE_TO_POSE_*_THRESHOLD exposes the defaults, following the existing _JOINT_* constants.
  • move_to_joint_position is unchanged. Its relative tolerance works in practice, and changing it would change joint-move behaviour.

This is an API behaviour change. Anyone passing success_threshold to move_to_pose gets a metre value instead of a relative one. The value 0.01 now means 1 cm.

Test plan

  • New tests/test_pose_error.py checks:
    • the distance is absolute and independent of the distance from the base;
    • the angle matches known rotations;
    • q and −q compare equal, and unnormalised quaternions are accepted;
    • the defaults accept the errors measured on the FER.
  • Full suite passes: 83 tests on Python 3.13 with libfranka 0.9.2, and on 3.9 and 3.14 with 0.21.3.
  • CI across the libfranka matrix: all eight builds pass.
  • Hardware: notes/check_pose_path.py on the FER (protocol 5) with a libfranka 0.9.2 build of this branch, 2026-09-30. All 12 moves returned True with no warnings, at 800, 1600 and 2400 N/m. The same moves on the previous build returned False for 10 of 12. Worst at the default impedance: 7.6 mm and 2.99 deg. The motion repeated within 0.2 mm and 0.1 deg of the earlier run, so only the verdict changed.

The check used Eigen's relative isApprox on the position and on the raw
quaternion coefficients. The position tolerance was therefore 1% of the
goal's distance from the robot base, the orientation tolerance about 1.1
degrees and sensitive to the sign of the quaternion, and the warning only
reported the position, although the orientation usually decided it.

The Cartesian controller is an impedance controller without integral action,
so it settles short of the goal wherever friction balances its spring. On an
FER at the default impedance that was up to 7.7 mm and 3 degrees, and most
moves returned False. success_threshold is now an absolute distance, 2 cm by
default, and orientation_threshold a rotation angle, 0.1 rad by default,
computed with angularDistance so q and -q compare equal. The warning reports
both errors and both thresholds.

The error computation is exposed privately as _core._pose_error for tests.
@JeanElsner
JeanElsner force-pushed the jean/fix/speed-factor-validation branch from 4cb25a4 to 2e4a85b Compare September 30, 2026 16:58
@JeanElsner
JeanElsner force-pushed the jean/fix/move-to-pose-success branch from d7c4df7 to f0f5a95 Compare September 30, 2026 16:58
@JeanElsner
JeanElsner changed the base branch from jean/fix/speed-factor-validation to main September 30, 2026 17:12
@JeanElsner
JeanElsner merged commit c27b4f7 into main Sep 30, 2026
8 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant