4.4
Wrap and gauge symmetries
A revolute exponential is 2π-periodic, so shifting both limits by
2πk rewrites the same motion over the same anchor. The definition of
E uses the limits exactly as stored, so such a pair of encodings is
charged the shift. As an optional preprocessing step, wrap_revolute_limits
shifts a revolute joint's limits by the common 2πk that places the
midpoint ½(l⁻ + l⁺) in [−π, π), and
joint_to_endpoint_pair(joint, wrap_revolute=True) applies it before forming the pair.
Only revolute joints can be wrapped: a prismatic shift translates and a helical shift also
translates, so for them k = 0 is forced.
The wrap has a seam. Picking one representative per orbit is a choice of fundamental domain, and at its boundary (midpoint exactly ±π) the representative jumps. With the wrap on, E is invariant under the full-turn shift but is discontinuous there, which is the other reason it stays optional.
A prismatic twist is (0, a) and contains no origin at all, so moving the drawn origin is pure gauge and the metric returns zero. The prior origin score charges ‖o₁ − o₂‖ for it. For a revolute joint the origin matters through the moment, which is the physically right behavior: a hinge on a different line moves the door differently.