test: U-Form-Faelle, Formkriterium laengs und Reihenanordnung der Linienzug-Tests

Drei neue Modus-2-Testfaelle aus echten Laeufen, ein Kriterium, das eine
heute eingebaute Fehlgeometrie gefunden haette, und ein aufgeraeumtes
Layout der Testketten.

1. Drei U-Form-Faelle (tests/testdata/linienzug_modus2_uform_*.json),
   aufgezeichnet mit lib/vf_journal_export.py. Gefaltete Laeufe: der Pfad
   wechselt ueber zwei 90-Grad-Vario-Kurven dreimal die Fahrtrichtung, die
   Kletterstrecke liegt in einem ANDEREN Schenkel als der Lauf-Eingang -
   genau der am 2026-10-29 korrigierte Fall. Variiert werden GF-Verteilung
   (alles am Einlauf vs. 1/2+1/2) und Winkel; beides ist noetig, weil die
   Verteilung entscheidet, ob ueberhaupt GF im fremden Schenkel steht, und
   der Restfehler der alten Bilanz mit L_GF skalierte.
   c:TEST_LINIENZUG_MODUS2 ist dafuer tabellengesteuert - ein weiterer Fall
   ist jetzt eine Zeile in *tlz-m2-faelle*.

2. RUECKNAHME des Schluss-Solves (vfl-zsolve-schluss-ziel, heute frueh
   eingebaut). Er loeste den letzten Fueller gegen Richtung UND Laenge und
   traf den Zielpunkt dadurch in X und Y exakt - um den Preis, dass er die
   letzte Gerade um 6.15 Grad verdrehte (hz-plan -90 -> -96.15), in der
   Zeichnung als schiefer Schenkel sichtbar. Das widerspricht der
   Entscheidung vom 2026-10-26: quer MUSS 0 sein, LAENGS DARF ABWEICHEN -
   der Hauptstrang bleibt gerade, der seitliche Versatz des ES-Elements ist
   dessen Bauform. Die Messwerte von heute (0.56 / 0.7 mm quer) stammen
   nicht von dieser Aenderung, sondern von der Laengenbilanz des gefalteten
   Laufs (35ebee1) - der Zweig blieb dort ungenutzt. Die Begruendung steht
   jetzt an der Aufrufstelle, damit niemand den Solve erneut baut.

3. laengs wird geprueft - als FORM-, nicht als Genauigkeitskriterium
   (erwartung_laengs_mm, Toleranz 5 mm). Der Wert ist die Ausladung des
   ES-Elements und je Fall eine Konstante (104.68 bei ES_Element_30,
   637.58 bei ES_Element_90). Punkt 2 war am Querwert NICHT erkennbar - die
   Verdrehung macht ihn gerade null, der Test meldete OK, gefunden wurde sie
   mit dem Auge. Ein verdrehter Hauptstrang zielt auf den Endpunkt und
   drueckt laengs auf ~0; daran faellt er auf. Gegengeprueft: mit kuenstlich
   auf 0.01 mm gesetzter Toleranz kippen alle fuenf Faelle auf ABWEICHUNG.

4. Alle sieben Ketten des Menueeintrags entstehen als Reihe auf Y=0, 20 m
   Abstand, statt verstreut. Die Modus-1-Skripte brauchen dafuer nur ihren
   EINEN point_abs (alles Weitere ist point_rel mit dL/hz); bei Modus 2
   mussten PT-Eintraege UND die Pfadkoordinaten in SEGS (Felder 6..9)
   mitwandern, sonst zeigt der Pfad woanders hin als Start und Ziel.
   Reine Translation - Laengen, Winkel und die geprueften Abweichungen sind
   davon unabhaengig; Z blieb stehen, weil die Starthoehe ein Eingabewert
   des Solvers ist. Geprueft: erstes Segment beginnt exakt am Startpunkt,
   letztes endet exakt am Zielpunkt, Messwerte unveraendert.

5. Die drei letzten Verweise auf doc/VarioFoerderer_Linienzug_Prinzipien.md
   (bewusst unversioniert) tragen ihre Begruendung jetzt selbst: Entkopplung
   Neigung/XY, warum es genau EINEN Kletterer je Lauf gibt, und warum ein
   VF-Sub-Segment auf der 3-Grad-Basis beginnen und enden muss.

Geprueft: TEST_UNIT 897/897 (die 7 Tests der entfernten Funktion sind mit
ihr gegangen), TEST_LINIENZUG_MODUS2 5 von 5 OK, voller Menueablauf baut
sieben Ketten an den vorgesehenen Stellen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-29 14:28:57 +01:00
parent 11e334d0a2
commit b709f89404
12 changed files with 585 additions and 185 deletions
-49
View File
@@ -3036,54 +3036,6 @@
)
;; --- Schlussstueck: Richtung UND Laenge aus der IST-Lage ---------------------
;; vfl-zsolve-schluss-ziel loest den letzten Fueller gegen den Zielpunkt, mit der
;; Richtung als zweiter Unbekannter. Mit es-block = nil braucht die Funktion
;; weder Zeichnung noch Blockdatei - der Querversatz P ist dann 0 und uebrig
;; bleibt die reine Geometrie.
;; Bewusst NICHT gegen eine nachgerechnete Konstante C geprueft (das waere die
;; Formel ein zweites Mal hingeschrieben), sondern gegen Eigenschaften, die
;; unabhaengig von C gelten: der Winkel zeigt exakt zum Ziel, und eine
;; Zielverschiebung bzw. ein groesseres GF2 schlaegt 1:1 auf die Laenge durch.
(defun tu-tests-vfl-schluss ( / _rad3 _p0 _a _b _c _d)
(princ "\n[vf_linienzug Schlussstueck]")
(setq _rad3 (/ (* 3.0 pi) 180.0)
_p0 '(0.0 0.0 0.0))
;; Der Winkel zeigt ohne ES-Element exakt zum Zielpunkt (P = 0).
(tu-eqf "vfl-zsolve-schluss-ziel/winkel-ost"
0.0 (cadr (vfl-zsolve-schluss-ziel _p0 '(10000.0 0.0 0.0) 0.0 nil 0.0 _rad3)))
(tu-eqf "vfl-zsolve-schluss-ziel/winkel-nord"
90.0 (cadr (vfl-zsolve-schluss-ziel _p0 '(0.0 10000.0 0.0) 0.0 nil 0.0 _rad3)))
;; 3/4/5-Dreieck: die Richtung folgt dem Ziel, NICHT dem uebergebenen seg-hz.
;; Genau das ist der Kern der Aenderung - darum wird hier ein voellig anderer
;; Planwinkel (-137) hineingegeben.
(tu-eqf "vfl-zsolve-schluss-ziel/winkel-folgt-ziel-nicht-plan"
(/ (* 180.0 (atan 4000.0 3000.0)) pi)
(cadr (vfl-zsolve-schluss-ziel _p0 '(3000.0 4000.0 0.0) -137.0 nil 0.0 _rad3)))
;; Laenge: 1000 mm weiter entferntes Ziel -> 1000 mm mehr Fueller.
(setq _a (car (vfl-zsolve-schluss-ziel _p0 '(10000.0 0.0 0.0) 0.0 nil 0.0 _rad3))
_b (car (vfl-zsolve-schluss-ziel _p0 '(11000.0 0.0 0.0) 0.0 nil 0.0 _rad3)))
(tu-eqf "vfl-zsolve-schluss-ziel/laenge-folgt-ziel" 1000.0 (- _b _a))
;; GF2 steht im Schwanz und liegt unter 3 Grad: 1000 mm GF2 verbrauchen
;; 1000*cos(3) in der Laengsrichtung, der Fueller wird genau darum kuerzer.
(setq _c (car (vfl-zsolve-schluss-ziel _p0 '(10000.0 0.0 0.0) 0.0 nil 1000.0 _rad3)))
(tu-eqf "vfl-zsolve-schluss-ziel/gf2-verkuerzt-fueller"
(* 1000.0 (cos _rad3)) (- _a _c))
;; Die Loesung ist richtungsunabhaengig: dasselbe Ziel, um 90 Grad gedreht,
;; ergibt dieselbe Fuellerlaenge.
(setq _d (car (vfl-zsolve-schluss-ziel _p0 '(0.0 10000.0 0.0) 0.0 nil 0.0 _rad3)))
(tu-eqf "vfl-zsolve-schluss-ziel/laenge-drehinvariant" _a _d)
;; Kein loesbarer Fall: Ziel liegt auf dem Startpunkt -> nil (Aufrufer faellt
;; dann auf den bisherigen Weg zurueck, statt etwas zu raten).
(tu-nil "vfl-zsolve-schluss-ziel/ziel-auf-startpunkt"
(vfl-zsolve-schluss-ziel _p0 '(0.0 0.0 0.0) 0.0 nil 0.0 _rad3))
)
(defun c:TEST_UNIT ( / out-dir report)
(tu-reset)
@@ -3097,7 +3049,6 @@
"tu-tests-export" "tu-tests-hoehen" "tu-tests-gf" "tu-tests-omni" "tu-tests-kreisel" "tu-tests-kreisel-bp"
"tu-tests-sepliste" "tu-tests-json" "tu-tests-geruest"
"tu-tests-sepscan" "tu-tests-vfl-segs" "tu-tests-vfl-abbruch"
"tu-tests-vfl-schluss"
"tu-tests-werkzeuge" "tu-tests-kf" "tu-tests-hoehen-fam")
(tu-run-block fn))