test: add console test reproducing planar drag quaternion flip (#338) #39

Merged
forbes merged 1 commits from test/planar-drag-console-test into main 2026-02-27 15:30:58 +00:00
Owner

Adds tests/console_test_planar_drag.py — a live FreeCAD console test that reproduces the quaternion branch-jump failure from create#338.

What this test does

Runs 5 test suites in the FreeCAD Python console against a live (broken) instance:

  1. Validator function correctness — verifies our Python replica of C++ validateNewPlacements() matches the real behavior (uses acos(w) not acos(|w|))
  2. Realistic drag with non-identity geometry — Cylindrical + Planar constraints with diagonal axis, non-trivial marker quaternions, and 15°/step axial perturbation. Reliably triggers the bug: 10/40 steps rejected.
  3. Negated initial quaternion — tests w<0 starting placement to catch hemisphere mismatch on first solve
  4. Live assembly introspection — reads the open document's actual part placements and joint data
  5. Direct hemisphere flip — alternates ±q drag inputs to probe solver output stability

Key findings

  • The failure is not simple hemisphere negation (q vs -q)
  • The solver finds geometrically valid but quaternion-distinct solutions when Cylindrical + Planar constraints have multiple satisfying orientations
  • _enforce_quat_continuity only catches sign flips, not these deeper branch jumps
  • The C++ validator uses acos(w) not acos(|w|), so opposite-hemisphere quaternions appear as ~360° rotation

Test 2 failure pattern (reproducible)

Steps 1-15 (15°-225°):  ACCEPT — solver stays on same quaternion branch
Step 16 (240°):         REJECT — solver jumps to different branch (104.6°)
Steps 17-22:            REJECT — cascading (stale baseline)
Step 23 (345°):         ACCEPT — solver returns to original branch
Steps 37-40 (555-600°): same pattern repeats (periodic)

Refs: kindred/create#338, kindred/create#339

Adds `tests/console_test_planar_drag.py` — a live FreeCAD console test that reproduces the quaternion branch-jump failure from create#338. ## What this test does Runs 5 test suites in the FreeCAD Python console against a live (broken) instance: 1. **Validator function correctness** — verifies our Python replica of C++ `validateNewPlacements()` matches the real behavior (uses `acos(w)` not `acos(|w|)`) 2. **Realistic drag with non-identity geometry** — Cylindrical + Planar constraints with diagonal axis, non-trivial marker quaternions, and 15°/step axial perturbation. **Reliably triggers the bug: 10/40 steps rejected.** 3. **Negated initial quaternion** — tests w<0 starting placement to catch hemisphere mismatch on first solve 4. **Live assembly introspection** — reads the open document's actual part placements and joint data 5. **Direct hemisphere flip** — alternates ±q drag inputs to probe solver output stability ## Key findings - The failure is **not simple hemisphere negation** (q vs -q) - The solver finds geometrically valid but **quaternion-distinct** solutions when Cylindrical + Planar constraints have multiple satisfying orientations - `_enforce_quat_continuity` only catches sign flips, not these deeper branch jumps - The C++ validator uses `acos(w)` not `acos(|w|)`, so opposite-hemisphere quaternions appear as ~360° rotation ## Test 2 failure pattern (reproducible) ``` Steps 1-15 (15°-225°): ACCEPT — solver stays on same quaternion branch Step 16 (240°): REJECT — solver jumps to different branch (104.6°) Steps 17-22: REJECT — cascading (stale baseline) Step 23 (345°): ACCEPT — solver returns to original branch Steps 37-40 (555-600°): same pattern repeats (periodic) ``` Refs: kindred/create#338, kindred/create#339
forbes added 1 commit 2026-02-27 15:30:50 +00:00
Adds console_test_planar_drag.py — a live FreeCAD console test that
reproduces the quaternion branch-jump failure from #338.

Test 2 (realistic geometry) reliably triggers the bug: 10/40 drag
steps rejected by the C++ validateNewPlacements() simulator when
the solver converges to an equivalent but distinct quaternion branch
around 240-330 deg axial rotation.

Key findings from the test:
- The failure is NOT simple hemisphere negation (q vs -q)
- The solver finds geometrically valid but quaternion-distinct
  solutions when Cylindrical + Planar constraints have multiple
  satisfying orientations
- _enforce_quat_continuity only catches sign flips, not these
  deeper branch jumps
- The C++ validator uses acos(w) not acos(|w|), so opposite-
  hemisphere quaternions show as ~360 deg rotation
forbes merged commit 54fec18afb into main 2026-02-27 15:30:58 +00:00
forbes deleted branch test/planar-drag-console-test 2026-02-27 15:31:02 +00:00
Sign in to join this conversation.