Repository navigation
Commit 13cef32
fix: Twist2.ad raised ValueError for every twist; add Twist2.Ad and SE2.Ad (#259)
## Problem
`Twist2.ad` raises `ValueError: argument must be a 1- or 3-vector` for
every twist, and always has. It is a copy of `Twist3.ad` that was never
adapted to 2D: it calls `skew()` on the scalar `w` and builds 6x6
blocks, where the 2D result is 3x3. Nothing in the repo calls it and no
test covered it.
It also differs from its 3D sibling in other ways:
- It is a `@property`, while `Twist3.ad` is a method and both docstrings
say `S.ad()`.
- Its docstring example calls `S.unit()`, and its see-also points at
`SE3.Ad`.
- `Twist2` has no `Ad()`, and neither does `SE2`. `tr2adjoint2` exists,
but only as a base function, so the `ad`/`Ad` pair that `Twist3` and
`SE3` have was half missing in 2D.
## Changes
- **`Twist2.ad()`** is now a method returning the 3x3 matrix of the Lie
bracket, `[[0, -ω, v_y], [ω, 0, -v_x], [0, 0, 0]]`. For a sequence it
returns a list, as `skewa()` does.
- **`Twist2.Ad()`** is new and mirrors `Twist3.Ad()`: the adjoint of the
equivalent SE(2) pose.
- **`SE2.Ad()`** is new and mirrors `SE3.Ad()`.
- **`tr2adjoint2` docstring:** its text named `tr2jac2` and said 6x6.
Now it names `tr2adjoint2` and gives 3x3 (1x1 for SO(2)).
## Verification
The new `tests/test_twist2_adjoint.py` checks against independent
oracles, not against the implementation:
- `ad(S) @ T` equals the commutator of the augmented skew matrices,
`vee([S, T])`.
- Antisymmetry: `[S, S] = 0` and `ad(S) T = -ad(T) S`.
- `expm(ad(S))` equals `Ad(exp(S))`.
- `SE2.Ad() @ S` equals `vee(T [S] T^-1)`.
- `Ad(T1 T2) = Ad(T1) Ad(T2)`, and `Ad` of the identity is `I`.
- Sequence handling.
All six fail on `master` and pass here. Full suite: 386 passed, 3
skipped. Black is clean. The branch merges cleanly with #225, #248,
#249, #258 and the integration hub #246.
## Not changed
- `tr2adjoint` and `tr2adjoint2` both have a `.. math:` directive with a
single colon (so it renders as a comment) and unbalanced braces in the
formula. I left those alone because the 3D function shares them and
fixing the math needs a check of the Sphinx macros.
- `Twist3.ad()` silently uses the first element of a sequence.
`Twist2.ad()` returns a list, so the two now differ for sequences. I'd
harmonize them separately.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>1 parent 9b83ba0 commit 13cef32
4 files changed
Lines changed: 151 additions & 16 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
796 | 796 | | |
797 | 797 | | |
798 | 798 | | |
799 | | - | |
800 | | - | |
801 | | - | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
802 | 802 | | |
803 | 803 | | |
804 | 804 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
609 | 609 | | |
610 | 610 | | |
611 | 611 | | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
612 | 638 | | |
613 | 639 | | |
614 | 640 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1641 | 1641 | | |
1642 | 1642 | | |
1643 | 1643 | | |
1644 | | - | |
1645 | 1644 | | |
1646 | | - | |
1647 | | - | |
| 1645 | + | |
| 1646 | + | |
| 1647 | + | |
| 1648 | + | |
| 1649 | + | |
| 1650 | + | |
| 1651 | + | |
| 1652 | + | |
1648 | 1653 | | |
1649 | | - | |
1650 | | - | |
| 1654 | + | |
| 1655 | + | |
| 1656 | + | |
| 1657 | + | |
| 1658 | + | |
| 1659 | + | |
| 1660 | + | |
| 1661 | + | |
| 1662 | + | |
| 1663 | + | |
1651 | 1664 | | |
1652 | 1665 | | |
1653 | 1666 | | |
| |||
1656 | 1669 | | |
1657 | 1670 | | |
1658 | 1671 | | |
1659 | | - | |
| 1672 | + | |
| 1673 | + | |
| 1674 | + | |
| 1675 | + | |
1660 | 1676 | | |
1661 | | - | |
| 1677 | + | |
1662 | 1678 | | |
1663 | | - | |
1664 | | - | |
1665 | | - | |
1666 | | - | |
1667 | | - | |
1668 | | - | |
| 1679 | + | |
| 1680 | + | |
| 1681 | + | |
| 1682 | + | |
| 1683 | + | |
| 1684 | + | |
| 1685 | + | |
| 1686 | + | |
| 1687 | + | |
| 1688 | + | |
| 1689 | + | |
| 1690 | + | |
| 1691 | + | |
| 1692 | + | |
| 1693 | + | |
| 1694 | + | |
| 1695 | + | |
| 1696 | + | |
| 1697 | + | |
| 1698 | + | |
| 1699 | + | |
| 1700 | + | |
| 1701 | + | |
| 1702 | + | |
| 1703 | + | |
| 1704 | + | |
| 1705 | + | |
| 1706 | + | |
| 1707 | + | |
| 1708 | + | |
| 1709 | + | |
| 1710 | + | |
| 1711 | + | |
1669 | 1712 | | |
1670 | 1713 | | |
1671 | 1714 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
0 commit comments