Skip to content

fix: honour flip in DHLink.A() when the joint ET is not last (#563) - #619

Open
youdie006 wants to merge 1 commit into
petercorke:mainfrom
youdie006:fix/563-dhlink-flip-honor-nonlast
Open

fix: honour flip in DHLink.A() when the joint ET is not last (#563)#619
youdie006 wants to merge 1 commit into
petercorke:mainfrom
youdie006:fix/563-dhlink-flip-honor-nonlast

Conversation

@youdie006

Copy link
Copy Markdown

Fixes #563.

Problem

DHLink.A() decided whether to negate the joint variable by checking self.ets[-1].isflip. For a link with a nonzero a, d or alpha, _to_ets() places the joint ET (Rz(flip=flip)) before the constant ETs (tz(d) / tx(a) / Rx(alpha)), so self.ets[-1] is a constant ET whose isflip is always False. As a result flip=True was silently ignored for such links and q was not negated, so DHRobot.fkine disagreed with the link's own ETS.

import roboticstoolbox as rp, math
L = rp.RevoluteDH(a=1.0, flip=True)
L.A(0.5).A[1, 0]        # returned +0.47943 (== +sin(0.5)), wrong
L.ets.eval([0.5])[1, 0] # -0.47943 (== sin(-0.5)), correct

A control link with a = 0 (where the joint ET is last) already behaved correctly, which pinpoints the cause.

Fix

Check self.isflip (the joint ET's flip, via Link.isflip -> self.v.isflip) instead of the last ET. When the joint ET is last (a = d = alpha = 0) the two are equal, so previously-correct links are unaffected. One line in DHLink.A().

Testing

  • Added test_flip_with_nonzero_a in tests/test_DHRobot.py: asserts RevoluteDH(a=1.0, flip=True).A(q).A equals the link's own ets.eval([q]) and that A[1, 0] == sin(-q).
  • Verified red -> green: the new test fails on the current code (+0.479 vs desired -0.479) and passes with the fix. Isolated the change against the full tests/test_DHRobot.py: baseline had 2 failures (this new test + the pre-existing test_payload drift), and after the one-line fix only test_payload remains -- exactly this test flips fail -> pass, no other test changes. Sanity-checked that a=0 flip stays correct and non-flip links are unchanged.

Thanks to @yucchengyi for the report and the precise root-cause diagnosis.


This change was prepared with AI assistance and reviewed by me before submission.

DHLink.A() decided whether to negate the joint variable by checking
self.ets[-1].isflip. For a link with a nonzero a, d or alpha, _to_ets() places
the joint ET before the constant ETs, so self.ets[-1] is a constant ET whose
isflip is always False. As a result flip=True was silently ignored for such
links and q was not negated, so DHRobot.fkine disagreed with the link's own
ETS. For example RevoluteDH(a=1.0, flip=True).A(0.5).A[1, 0] returned +sin(0.5)
instead of -sin(0.5).

Check self.isflip (the joint ET's flip, via Link.isflip -> self.v.isflip)
instead of the last ET. When the joint ET is last (a = d = alpha = 0) the two
are equal, so previously-correct links are unaffected.

Fixes petercorke#563.
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.

Possible bug: DHLink.A() checks self.ets[-1].isflip instead of the joint ET

1 participant