Skip to content

IK.py unconditionally wraps q to +-pi, breaking prismatic joints #639

Description

@petercorke

Background

Two independent reports (#406, #457) hit the same bug: IK.py's numerical solvers (ikine_LM and friends) unconditionally wrap the entire solved q vector to [-pi, pi] after convergence -- including prismatic joints, where the value is a translation distance, not an angle, and any revolute joint with a range wider than 180 degrees.

Confirmed still live (2026-08-25)

src/roboticstoolbox/robot/IK.py:317:

# Wrap q to be within +- 180 deg
# If your robot has larger than 180 deg range on a joint
# this line should be modified in incorporate the extra range
q = (q + np.pi) % (2 * np.pi) - np.pi

Applied unconditionally to every element of q, with no check for joint type. Reproduced #457's exact repro directly on current main: a 6-DOF robot with 3 prismatic + 3 revolute joints, q_in = [4, 0, 0, 0, pi/3, 0] comes back as q_out = [-2.28, 0, -0, 0, 1.05, -0] after the wrap -- 4 (a valid prismatic value, well within its qlim=[-10,10]) gets wrapped into [-pi,pi] as if it were an angle, and the resulting fkine(q_out) translation is wrong by the same amount.

#406's own report already identifies the fix location and confirms commenting out the wrap line resolves their case (though a real fix should be joint-type-aware, not just remove wrapping entirely -- revolute joints with a >180 deg physical range still need some handling, per the comment's own caveat).

Next steps

Make the wrap conditional on joint type -- only wrap elements corresponding to revolute joints (and ideally only those without an explicit wider qlim), leave prismatic joints untouched. ets/ets.structure (or equivalent per-joint type info) should already be available at this point in IK.py.

Originally reported: #406, #457.

Metadata

Metadata

Assignees

No one assigned

    Labels

    tech-debtKnown technical debt / deferred cleanup, not a live bug

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions