diff --git a/Lisp/vf_spec.lsp b/Lisp/vf_spec.lsp index 437e89a..3e1f5c7 100644 --- a/Lisp/vf_spec.lsp +++ b/Lisp/vf_spec.lsp @@ -65,10 +65,21 @@ (setq *vsp-tab-ende2* '(("ja-mit-es" . "1") ("nein" . "2"))) ;; Glied -> Menue-Code. Der Code haengt am Frame: die ERSTE Sektion laeuft -;; ohne Frame und bekommt 4 Optionen (kein GF-Bogen - es gibt noch keine -;; Richtung, an die er anschliessen koennte), jede spaetere 5. -(setq *vsp-menu-start* '(("Linie-GF" . "1") ("Linie-VF" . "2") - ("Horizontal-VF" . "3") ("Linie" . "4"))) +;; ohne Frame (Kettenanfang) und bekommt 6 Optionen - GF-Bogen UND Vario-Kurve +;; sind seit der "Fortsetzung einer bestehenden Teilkette"-Erweiterung +;; (vf_linienzug.lsp, vfl-naechstes-element-header-Zweig ohne frame) AUCH am +;; Kettenanfang waehlbar (Referenzrichtung kommt dann aus einem KS_AUS am +;; Startpunkt statt aus einem Frame) - NICHT mehr nur 4 Optionen wie fruecher. +;; Jede spaetere Sektion (Frame existiert bereits) hat weiterhin 5 Optionen +;; (GF-Bogen ist dort IMMER Option 1, kein Vario-Kurve-Sonderfall noetig - eine +;; Vario-Kurve wird dort ueber die VF-Einheit selbst erreicht). Beide Tabellen +;; MUESSEN exakt zur Options-Reihenfolge in vf-linienzug-modus passen (siehe +;; dortiger Kommentar "Kettenanfang: 6 Optionen statt 4") - ein Regressions-Fund +;; 2026-09-12 (TEST_HUNDM05 baute "GF-Bogen" statt "Linie-GF" als erstes Glied, +;; weil diese Tabelle noch die alte 4-Optionen-Zuordnung hatte). +(setq *vsp-menu-start* '(("GF-Bogen" . "1") ("Vario-Kurve" . "2") + ("Linie-GF" . "3") ("Linie-VF" . "4") + ("Horizontal-VF" . "5") ("Linie" . "6"))) (setq *vsp-menu-weiter* '(("GF-Bogen" . "1") ("Linie-GF" . "2") ("Linie-VF" . "3") ("Horizontal-VF" . "4") ("Linie" . "5"))) @@ -88,6 +99,10 @@ ;; darum in vsp-bau-aus-spec und nicht einmal aussen: der Abbruch-Handler in ;; vf-linienzug-modus setzt *ssg-ils-dim* zurueck. (if (not (boundp '*vsp-dim-override*)) (setq *vsp-dim-override* nil)) +;; Ausgabe-Flag von vsp-sektion (siehe dort): T, wenn eine "Linie-GF"-Sektion +;; mit ende="ja-mit-es" die NAECHSTE Sektion (das ES-Glied) bereits inline +;; mitverarbeitet hat - vsp-journal ueberspringt sie dann beim Weiterzaehlen. +(if (not (boundp '*vsp-es-verbraucht*)) (setq *vsp-es-verbraucht* nil)) ;; Fehler sammeln (aeltester zuerst) statt beim ersten abzubrechen: eine ;; handgeschriebene Spec hat selten genau einen Tippfehler. @@ -234,7 +249,13 @@ (vsp-wert-str (ssg-val kopf "as_winkel") "as_winkel") (vsp-code-raus *vsp-tab-seite* (ssg-val kopf "as_seite") "as_seite")))) -(defun vsp-sektion (sek subs erster / label tab code art modus smodus) +;; naechste: Felder der NAECHSTEN Top-Level-Sektion (oder nil) - wird nur fuer +;; "Linie-GF" gebraucht (siehe dort). *vsp-es-verbraucht* (Ausgabe-Flag, vom +;; Aufrufer vsp-journal gelesen): T, wenn diese Sektion die naechste (das +;; ES-Glied) bereits mitverarbeitet hat - der Aufrufer muss sie dann beim +;; Weiterzaehlen ueberspringen. +(defun vsp-sektion (sek subs erster naechste / label tab code art modus smodus ende-wert) + (setq *vsp-es-verbraucht* nil) (setq label (ssg-val sek "glied")) (setq *vsp-wo* (strcat "Sektion " (if label label "(ohne glied)"))) (cond @@ -277,6 +298,31 @@ (setq modus (ssg-val sek "laenge_modus")) (if (null modus) (setq modus "endpunkt")) (vsp-code-raus *vsp-tab-gf-laenge-modus* modus "laenge_modus") + ;; NEU (2026-09-12): "Ist das Kettenende?" wird im Bau-Ablauf jetzt + ;; SOFORT nach der Laenge-Modus-Wahl gefragt (vor Separator/ + ;; Gefaelle) - vorher lief die Frage erst nach dem Bau. Bei + ;; "ja-mit-es" fragt vf-linienzug-modus DIREKT im Anschluss auch + ;; ES-Winkel/-Seite (damit deren Fussabdruck schon in die + ;; Laengenberechnung eingeht) - die Spec beschreibt das ES-Element + ;; aber weiterhin als EIGENE, nachfolgende Sektion (glied="ES", + ;; siehe dort) fuer bessere Lesbarkeit. vsp-journal muss die beiden + ;; Tokengruppen daher HIER zusammenziehen: "ende" + (bei ja-mit-es) + ;; die Winkel/Seite-Tokens der naechsten Sektion, vorgezogen. Die + ;; eigentliche ES-Sektion wird dadurch bereits vollstaendig + ;; verbraucht - vsp-journal ueberspringt sie danach (siehe + ;; *vsp-es-verbraucht*), sonst kaemen ihre Tokens ein zweites Mal. + (setq ende-wert (ssg-val sek "ende")) + (vsp-code-raus *vsp-tab-ende3* ende-wert "ende") + (if (= ende-wert "ja-mit-es") + (cond + ((null naechste) + (vsp-fehler "ende=\"ja-mit-es\", aber keine folgende ES-Sektion vorhanden")) + ((/= (ssg-val naechste "glied") "ES") + (vsp-fehler "ende=\"ja-mit-es\" erwartet eine direkt folgende Sektion mit glied=\"ES\"")) + (T + (vsp-wert-str (ssg-val naechste "winkel") "winkel (ES, vorgezogen)") + (vsp-code-raus *vsp-tab-seite* (ssg-val naechste "seite") "seite (ES, vorgezogen)") + (setq *vsp-es-verbraucht* T)))) (cond ((= modus "steigend") (setq smodus (ssg-val sek "steigend_modus")) @@ -304,7 +350,7 @@ (vsp-zahl "REAL" (ssg-val sek "hoehe") "hoehe") (vsp-zahl "REAL" (ssg-val sek "winkel") "winkel"))) ) - (vsp-code-raus *vsp-tab-ende3* (ssg-val sek "ende") "ende")) + ) ((= label "Linie-VF") (vsp-linie sek) @@ -424,17 +470,24 @@ ;; Spec -> Vorwaerts-Journal. Rueckgabe: Journal, oder nil wenn die Spec ;; Fehler hat (dann stehen sie in *vsp-fehler*). -(defun vsp-journal (spec / sektionen i) +;; Index-basierte Schleife (statt foreach) - noetig, damit "Linie-GF" bei +;; ende="ja-mit-es" die naechste Sektion (das ES-Glied) vorziehen UND danach +;; ueberspringen kann (siehe vsp-sektion/*vsp-es-verbraucht*). +(defun vsp-journal (spec / sektionen n i s naechste) (setq *vsp-fehler* nil *vsp-tok* nil *vsp-erster-dl* T *vsp-wo* "Spec") (cond ((null (vsp-kopf spec)) (vsp-fehler "Kopf-Objekt fehlt") nil) (T (vsp-praeambel (vsp-kopf spec)) - (setq sektionen (vsp-sektionen spec) i 0) + (setq sektionen (vsp-sektionen spec)) + (setq n (length sektionen)) (if (null sektionen) (vsp-fehler "Spec hat keine Sektionen")) - (foreach s sektionen - (setq i (1+ i)) - (vsp-sektion (vsp-sek-felder s) (vsp-sek-subs s) (= i 1))) + (setq i 0) + (while (< i n) + (setq s (nth i sektionen)) + (setq naechste (if (< (1+ i) n) (vsp-sek-felder (nth (1+ i) sektionen)) nil)) + (vsp-sektion (vsp-sek-felder s) (vsp-sek-subs s) (= i 0) naechste) + (setq i (+ i (if *vsp-es-verbraucht* 2 1)))) (if *vsp-fehler* nil (reverse *vsp-tok*))))) ;; Nur pruefen, nichts bauen: liefert die Fehlerliste (nil = Spec in diff --git a/Lisp/vf_standard.lsp b/Lisp/vf_standard.lsp index b903ed0..80f8aec 100644 --- a/Lisp/vf_standard.lsp +++ b/Lisp/vf_standard.lsp @@ -217,12 +217,22 @@ ;; feste-hz: horizontales Budget der festen Elemente (Umlenk+Motor+Separatoren). ;; nil => Standardwert FESTE_HORIZONTAL (1600, Standard-VF mit 2 Separatoren). ;; Der Linienzug uebergibt 1300 (nur 1 Separator am Einlauf, siehe vf_linienzug). -(defun berechne-alle-winkel (deltaL deltaH richtung feste-hz / +;; schon-flach: T => der Frame kommt FLACH (0 Grad) an, statt schon auf der +;; 3-Grad-Basis zu stehen - der Aufrufer wird VOR dem eigentlichen VF-Koerper +;; noch einen Uebergangsbogen (flach->3 Grad, IMMER "ab", siehe vfl-nach- +;; 3grad) einfuegen, dessen Fussabdruck (entry-dx/entry-dz) hier - genau wie +;; aus-dx/aus-dz beim AS-Element - VORAB vom verfuegbaren Budget abgezogen +;; werden muss. Ohne das wurde diese Strecke stillschweigend verbraucht und +;; die Kette verfehlte den Zielpunkt (real beobachtet: schon-flach-Faelle im +;; Linienzug-Kettenende, bis dahin nur bei Stufe 2/berechne-horizontale-mitte +;; beruecksichtigt). Default nil (unveraendertes Verhalten fuer alle +;; Aufrufer, die immer von der 3-Grad-Basis starten). +(defun berechne-alle-winkel (deltaL deltaH richtung feste-hz schon-flach / winkel-list ergebnis-liste A B cos3 sin3 bogen-x1 bogen-z1 bogen-x2 bogen-z2 abs-dz-AUS abs-dz-EIN L_GF L_VF cosα sinα winkel-eff cosEff sinEff rad5 rad7 - winkel mass1 mass2 gueltig + winkel mass1 mass2 gueltig entry-mass entry-dx entry-dz best-winkel best-L_GF best-L_VF) (if (or (not *lib-initialized*) (null aus-dz) (null ein-dz)) @@ -233,6 +243,11 @@ ) (if (null feste-hz) (setq feste-hz FESTE_HORIZONTAL)) + (setq entry-dx 0.0 entry-dz 0.0) + (if schon-flach + (progn + (setq entry-mass (get-bogen-mass bogen-ab (fix *vfk-gefaelle-winkel*))) + (setq entry-dx (car entry-mass) entry-dz (caddr entry-mass)))) (setq abs-dz-AUS (abs aus-dz) abs-dz-EIN (abs ein-dz)) (setq winkel-list (ssg-cfg-or "vario" "bogen_winkel" '(3 6 9 12 15 18 21 27 33 39 45 51))) @@ -270,15 +285,15 @@ (setq cosα (cos (* winkel (/ pi 180.0))) sinα (sin (* winkel (/ pi 180.0)))) (setq A (- deltaL aus-dx ein-dx bogen-x1 bogen-x2 - (* feste-hz cos3))) + (* feste-hz cos3) entry-dx)) (setq winkel-eff (if (= richtung "Auf") (- winkel *vfk-gefaelle-winkel*) (+ winkel *vfk-gefaelle-winkel*))) (setq cosEff (cos (* winkel-eff (/ pi 180.0))) sinEff (sin (* winkel-eff (/ pi 180.0)))) (if (= richtung "Auf") - (setq B (+ deltaH abs-dz-AUS abs-dz-EIN + (setq B (+ deltaH abs-dz-AUS abs-dz-EIN (abs entry-dz) (- bogen-z1) (- bogen-z2) (* feste-hz sin3))) - (setq B (+ (- deltaH abs-dz-AUS abs-dz-EIN + (setq B (+ (- deltaH abs-dz-AUS abs-dz-EIN (abs entry-dz) (* feste-hz sin3)) bogen-z1 bogen-z2)) ) @@ -395,7 +410,7 @@ (setq FESTE_HORIZONTAL (ssg-cfg-or "vario" "feste_horizontal" 1600)) (setq staustrecke-basis (ssg-cfg-or "vario" "staustrecke_basis" 1000)) (init-bibliothek) - (berechne-alle-winkel deltaL deltaH richtung nil) + (berechne-alle-winkel deltaL deltaH richtung nil nil) ) ;; ============================================================ diff --git a/lib/vf_spec_export.py b/lib/vf_spec_export.py index 8a7d4ad..d970106 100644 --- a/lib/vf_spec_export.py +++ b/lib/vf_spec_export.py @@ -71,6 +71,28 @@ ENDE2 = {"1": "ja-mit-es", "2": "nein"} # haengt am Frame: die ERSTE Sektion laeuft ohne Frame und bekommt 4 Optionen # (kein GF-Bogen - es gibt noch keine Richtung, an die er anschliessen # koennte), jede spaetere 5. Siehe vf-linienzug-modus. +# +# WICHTIG (2026-09-12): vf-linienzug-modus wurde SPAETER um "GF-Bogen"/ +# "Vario-Kurve" auch am Kettenanfang erweitert (6 statt 4 Optionen dort, +# "Fortsetzung einer bestehenden Teilkette" - Referenzrichtung kommt dann aus +# einem KS_AUS am Startpunkt). Lisp/vf_spec.lsp's *vsp-menu-start* wurde +# entsprechend auf die NEUE 6er-Zuordnung umgestellt, WEIL vsp-journal seine +# Tokens durch den AKTUELLEN (lebenden) vf-linienzug-modus REPLAYT - der +# Code muss dort zur JETZT gueltigen Menue-Reihenfolge passen. +# +# Diese Python-Tabelle bleibt bewusst auf der ALTEN 4er-Zuordnung: sie +# decodiert tests/testdata/hm_recformat.json - eine EINGEFRORENE Aufzeichnung +# einer echten Kundenzeichnung, die zu einem Zeitpunkt VOR dieser Erweiterung +# entstand (ihr roher Code fuer "Linie-GF" am Kettenanfang ist "1", nicht +# "3"). Wuerde diese Tabelle auf die neue Zuordnung umgestellt, koennte +# SpecReader die vorhandene Aufzeichnung nicht mehr korrekt lesen (siehe +# Testfall test_verlustfrei in tests/test_vf_spec.py). Die Tokenfolgen von +# LISP (vsp-journal, GEGEN den lebenden Bau-Ablauf) und Python (hier, GEGEN +# die eingefrorene Aufzeichnung) sind fuer "Linie-GF" am Kettenanfang darum +# ab dieser Erweiterung bewusst NICHT mehr identisch - eine unvermeidbare +# Folge davon, dass sich die Menue-Struktur nach der Aufzeichnung geaendert +# hat. Wird hm_recformat.json je aus einer NEUEN Aufzeichnung (mit dem +# aktuellen 6-Optionen-Ablauf) neu erzeugt, muesste diese Tabelle mitziehen. MENU_START = {"Linie-GF": "1", "Linie-VF": "2", "Horizontal-VF": "3", "Linie": "4"} MENU_WEITER = {"GF-Bogen": "1", "Linie-GF": "2", "Linie-VF": "3", diff --git a/menu/SSG_LIB.cui b/menu/SSG_LIB.cui index 58b2b9f..e728c14 100644 --- a/menu/SSG_LIB.cui +++ b/menu/SSG_LIB.cui @@ -20,715 +20,715 @@ - + Einfuegen ^C^C(ssg-ensure "KreiselInsert") KreiselInsert - + Verbinden ^C^C(ssg-ensure "KreiselInsert") KreiselConnect - + Bearbeiten ^C^C(ssg-ensure "KreiselInsert") KreiselEdit - + Eckrad ^C^C(ssg-ensure "KreiselInsert") ILS_Eckrad - + BTMT-Beladung ^C^C(ssg-ensure "SSG_LIB_Commands") ILS_BTMT_Beladung - + BTMT-Entladung ^C^C(ssg-ensure "SSG_LIB_Commands") ILS_BTMT_Entladung - + Scanner einfuegen ^C^C(ssg-ensure "SSG_LIB_Commands") ILS_SCANNER_INSERT - + Separator einfuegen ^C^C(ssg-ensure "SSG_LIB_Commands") ILS_SEPARATOR_INSERT - + Werte manuell ^C^C(ssg-ensure "VarioFoerderer") StandardVarioFoerderer - + aus 3D-Linie ^C^C(ssg-ensure "VarioFoerderer") StandardVarioFoerderer3D - + Werte manuell ^C^C(ssg-ensure "VarioFoerderer") EtageVarioFoerderer - + aus 3D-Linie ^C^C(ssg-ensure "VarioFoerderer") EtageVarioFoerderer3D - + 3D-Linienzug ^C^C(ssg-ensure "VarioFoerderer") LinienzugVarioFoerderer - + Vario_Kette_Merge ^C^C(ssg-ensure "VarioFoerderer") Vario_Kette_Merge - + VarioFoerderer nachruesten (Marker) ^C^C(ssg-ensure "VarioFoerderer") VARIOFOERDERER_NACHRUESTEN - + einfach ^C^C(ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_EINFACH - + aus 3D-Linie ^C^C(ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_3DLINIE - + aus Linienzug (LINE + ARC) ^C^C(ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_LINIENZUG - + 90 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_630_90 - + 67.5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_550_675 - + 45 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_630_45 - + 22.5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_550_225 - + 180 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB_650_180 - + 90 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APB60_90 - + AP 60 ^C^C(ssg-ensure "OmniModulInsert") OMNI_AP60 - + AP 110 ^C^C(ssg-ensure "OmniModulInsert") OMNI_AP110 - + APG 110 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APG110 - + Einfach 90 700/700 links M ^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Einfach - + Doppel 90 700/700 M ^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Doppel - + Dreiwege 90 700/700 M ^C^C(ssg-ensure "OmniModulInsert") OMNI_W90_Dreiwege - + Einfach 45 350/700 links M ^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Einfach - + Doppel 45 350/700 M ^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Doppel - + Dreiwege 45 350/700 M ^C^C(ssg-ensure "OmniModulInsert") OMNI_W45_Dreiwege - + Einfach Parallel 200/750 links M ^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Einfach - + Doppel Parallel 200/750 M ^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Doppel - + Dreiwege Parallel 200/750 M ^C^C(ssg-ensure "OmniModulInsert") OMNI_WP_Dreiwege - + Einfach 22.5 links M ^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Einfach - + Doppel 22.5 M ^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Doppel - + Dreiwege 22.5 M ^C^C(ssg-ensure "OmniModulInsert") OMNI_WK_Dreiwege - + Delta 1400/700 M ^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Delta_1400 - + Delta 1600/800 M ^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Delta_1600 - + Star 1400/1400 M ^C^C(ssg-ensure "OmniModulInsert") OMNI_WKomb_Star - + TEF Antriebst. rechts ^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_AntriebR - + TEF Umlenkspannst. rechts ^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_UmlenkR - + TEF Antriebst. links ^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_AntriebL - + TEF Umlenkspannst. links ^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_UmlenkL - + TEF Gerade auf Linie ^C^C(ssg-ensure "TEFInsert") TEF_FOERDERER_LINIE - + TEF Gerade ^C^C(ssg-ensure "OmniModulInsert") OMNI_TEF_Gerade - + Stopper AP ^C^C(ssg-ensure "OmniModulInsert") OMNI_STOPPER - + Scanner ^C^C(ssg-ensure "OmniModulInsert") OMNI_SCANNER - + Bürstenbremse ^C^C(ssg-ensure "OmniModulInsert") OMNI_BUERSTENBREMSE - + KettenFoerderer ^C^C(ssg-ensure "OmniModulInsert") OMNI_KettenFoerderer - + TV W-W kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_W - + TV W-AP110 kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110 - + TV W-AP60 oben kpl. ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP60 - + TV W-AP110-W kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP110_W - + TV W-AP oben kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_W_AP - + TV 80 ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_80 - + TV 50 ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_50 - + Endplatte Al-Profil AP schraubbar ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_ENDPLATTE - + Anschlag AP-Ende fuer Spulenzug ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_ANSCHLAG - + TV-A fuer AP110/AP60 kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_AP60 - + TV-A fuer AP60/ST ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP60_ST - + TV-A fuer AP110/ST kpl ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_A_AP110_ST - + TV-SW II fuer SW-SW ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_II_SW_SW - + TV-SW III fuer SW-AP110-SW ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_III_AP110_SW - + TV-SW III fuer SW-AP110 ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_III_AP110 - + TV-SW IV fuer Anschluss SW-AP60 ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_AP60 - + TV-SW IV fuer SW-ST ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_SW_IV_ST - + Muffe ^C^C(ssg-ensure "OmniModulInsert") OMNI_TV_MUFFE - + APB 110 R400/45 140 nur fuer Delta ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R400_45_140 - + APB 110 R550/45 194 nur fuer Delta ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_45_194 - + APBW 110 R550/22,5 360x248,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_360 - + APBW 110 R550/22,5 410x298,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_410A - + APBW 110 R550/22,5 410x78,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_410B - + APBW 110 R550/22,5 410x98,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_225_410C - + APBW 110 R550/67,5 360x598,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_360 - + APBW 110 R400/67,5 260x398,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R400_675_260 - + APBW 110 R550/45 77x160 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_45_77 - + APBW 110 R550/67,5 125x83,5 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_125 - + APBW 110 R750/90 200x290 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R750_90_200 - + APBW 110 R650/90 300x190 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R650_90_300 - + APBW 110 R550/67,5 208x347 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_208 - + APBW 110 R550/67,5 58x497 ^C^C(ssg-ensure "OmniModulInsert") OMNI_APBW_R550_675_58 - + Element bearbeiten ^C^C(ssg-ensure "OmniModulInsert") OMNI_EDIT - + Marker einfuegen ^C^C(ssg-ensure "Tro_Edit") TRO_INSERT - + Marker bearbeiten ^C^C(ssg-ensure "Tro_Edit") TRO_EDIT - + Bearbeiten (Auto) ^C^C(ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT - + Verbindung einfuegen ^C^C(ssg-ensure "Connection_Edit") CONNECTION_INSERT - + Verbindung bearbeiten ^C^C(ssg-ensure "Connection_Edit") CONNECTION_EDIT - + Eingang ^C^C(ssg-ensure "SSG_LIB_Commands") ILS_EINGANG_INSERT - + Ausgang ^C^C(ssg-ensure "SSG_LIB_Commands") ILS_AUSGANG_INSERT - + SPS Schliessen ^C^C - + Export Sivas ^C^C(ssg-ensure "export") EXPORTSIVAS - + Export CSV ^C^C(ssg-ensure "export") EXPORTCSV - + Umschalten 2D und 3D ^C^C(ssg-ensure "SSG_LIB_Commands") SSG_DIM_SWITCH - + Alle Bloecke auf 2D ^C^C(ssg-ensure "SSG_LIB_Commands") SSG_DIM_ALL_2D - + Alle Bloecke auf 3D ^C^C(ssg-ensure "SSG_LIB_Commands") SSG_DIM_ALL_3D - + Sprache ^C^C(ssg-ensure "SSG_LIB_Commands") SSG_SPRACHE - + Planquadrate an/aus ^C^C(ssg-ensure "DrawPlanquadrate") PLANQUADRATE_TOGGLE - + alle Tests ausfuehren und exportieren ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp")) SSG_RUN_ALL_TESTS_EXPORT - + Tests ausfuehren und stehen lassen ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_run_all.lsp")) SSG_RUN_ALL_TESTS_OFFEN - + Export CSV/Sivas ALL ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_export_all.lsp")) TEST_EXPORT_ALL - + Kreisel ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_kreisel.lsp")) TEST_KREISEL - + Foerderer ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_foerderer.lsp")) TEST_FOERDERER - + Foerderer-Linienzug - ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_linienzug.lsp")) TEST_LINIENZUG + ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_linienzug.lsp")) TEST_LINIENZUG TEST_LINIENZUG_STUFE2 - + Omniflo ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo.lsp")) TEST_OMNIFLO - + Omniflo Strecke ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo_strecke.lsp")) TEST_OMNIFLO_STRECKE - + Gefaellestrecke ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_gefaellestrecke.lsp")) TEST_GEFAELLESTRECKE - + Mubea Gesamtmodell ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_mubea.lsp")) TEST_MUBEA - + HundM05 Kreisel-Abschnitt ^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_hundm05.lsp")) TEST_HUNDM05 - + KS 2D/3D pruefen (CSV) ^C^C(load (strcat (getenv "DXFMAKRO") "/Lisp/ks_pruefung.lsp")) KS_PRUEFEN - + Kreisel bearbeiten (ssg-ensure "KreiselInsert") KreiselEdit - + Omniflo Element bearbeiten (ssg-ensure "OmniModulInsert") OMNI_EDIT - + Gefaellestrecke bearbeiten (ssg-ensure "Gefaellestrecke") GEFAELLESTRECKE_EDIT - + VarioFoerderer bearbeiten (ssg-ensure "VarioFoerderer") VARIOFOERDERER_EDIT - + TRO-Marker bearbeiten (ssg-ensure "Tro_Edit") TRO_EDIT - + Verbindung bearbeiten (ssg-ensure "Connection_Edit") CONNECTION_EDIT - + SSG Bearbeiten (Auto) (ssg-ensure "SSG_LIB_Commands") SSG_BLOCKEDIT @@ -740,846 +740,846 @@ - + POP1 SSG_LIB - - - - - + + + + + + + + + ILS + + + - - ILS - - - - - - + Kreisel-Module Einfuegen - + Verbinden - + Bearbeiten - + Eckrad - + - + Zusatzmodul BTMT-Beladung - + BTMT-Entladung - + Scanner einfuegen - + Separator einfuegen - + - + Foerderer - - + + 3D-Linienzug - + Vario_Kette_Merge - + VarioFoerderer nachruesten (Marker) - + - + Standard Werte manuell - - - - - - aus 3D-Linie - - - - - - - Etage - - Werte manuell - - - - - - aus 3D-Linie - - - - - - - Gefaellestrecke - - einfach - - - - - - aus 3D-Linie - - - - - - aus Linienzug (LINE + ARC) - - - - - - - Omniflo - - - - - - - - - - - - ~KettenFoerderer - - - - - - - - Element bearbeiten - - - - - - - Boegen APB110 - - 90 - 67.5 + aus 3D-Linie + + + Etage - 45 - - - - - - 22.5 + Werte manuell - 180 + aus 3D-Linie - - Boegen APB60 + + Gefaellestrecke - 90 - - - - - - - Aluprofil Gerade - - AP 60 - - - - - - AP 110 - - - - - - APG 110 - - - - - - - Weiche 90 Grad - - Einfach 90 700/700 links M + einfach - Doppel 90 700/700 M + aus 3D-Linie - Dreiwege 90 700/700 M + aus Linienzug (LINE + ARC) - - Weiche 45 Grad + + Omniflo + + + + + + + + + + - Einfach 45 350/700 links M + ~KettenFoerderer - + + + - Doppel 45 350/700 M + Element bearbeiten - + + + + Boegen APB110 - Dreiwege 45 350/700 M + 90 - - - Weichen Parallel - Einfach Parallel 200/750 links M + 67.5 - Doppel Parallel 200/750 M + 45 - Dreiwege Parallel 200/750 M + 22.5 - - - Weichenkoerper - Einfach 22.5 links M + 180 + + + Boegen APB60 - Doppel 22.5 M - - - - - - Dreiwege 22.5 M + 90 - - Weichenkombinationen + + Aluprofil Gerade - Delta 1400/700 M - - - - - - Delta 1600/800 M + AP 60 - Star 1400/1400 M + AP 110 + + APG 110 + + + + - + + Weiche 90 Grad + + Einfach 90 700/700 links M + + + + + + Doppel 90 700/700 M + + + + + + Dreiwege 90 700/700 M + + + + + + + Weiche 45 Grad + + Einfach 45 350/700 links M + + + + + + Doppel 45 350/700 M + + + + + + Dreiwege 45 350/700 M + + + + + + + Weichen Parallel + + Einfach Parallel 200/750 links M + + + + + + Doppel Parallel 200/750 M + + + + + + Dreiwege Parallel 200/750 M + + + + + + + Weichenkoerper + + Einfach 22.5 links M + + + + + + Doppel 22.5 M + + + + + + Dreiwege 22.5 M + + + + + + + Weichenkombinationen + + Delta 1400/700 M + + + + + + Delta 1600/800 M + + + + + + Star 1400/1400 M + + + + + + TEF Elemente TEF Antriebst. rechts - + TEF Umlenkspannst. rechts - + TEF Antriebst. links - + TEF Umlenkspannst. links - + TEF Gerade auf Linie - + TEF Gerade - - - - - - - Anbaugruppen - - Stopper AP - - - - - - Scanner - - - - - - Bürstenbremse - - - - - - - Verbinder - - ~TV W-W kpl - - - - - - ~TV W-AP110 kpl - - - - - - ~TV W-AP60 oben kpl. - - - - - - ~TV W-AP110-W kpl - - - - - - ~TV W-AP oben kpl - - - - - - ~TV 80 - - - - - - ~TV 50 - - - - - - ~Endplatte Al-Profil AP schraubbar - - - - - - ~Anschlag AP-Ende fuer Spulenzug - - - - - - ~TV-A fuer AP110/AP60 kpl - - - - - - ~TV-A fuer AP60/ST - - - - - - ~TV-A fuer AP110/ST kpl - - - - - - ~TV-SW II fuer SW-SW - - - - - - ~TV-SW III fuer SW-AP110-SW - - - - - - ~TV-SW III fuer SW-AP110 - - - - - - ~TV-SW IV fuer Anschluss SW-AP60 - - - - - - ~TV-SW IV fuer SW-ST - - - - - - ~Muffe - - - - - - - Boegen fuer Weichen - - ~APB 110 R400/45 140 nur fuer Delta - - - - - - ~APB 110 R550/45 194 nur fuer Delta + + + Anbaugruppen - ~APBW 110 R550/22,5 360x248,5 - - - - - - ~APBW 110 R550/22,5 410x298,5 + Stopper AP - ~APBW 110 R550/22,5 410x78,5 + Scanner - ~APBW 110 R550/22,5 410x98,5 + Bürstenbremse + + + Verbinder - ~APBW 110 R550/67,5 360x598,5 - - - - - - ~APBW 110 R400/67,5 260x398,5 - - - - - - ~APBW 110 R550/45 77x160 + ~TV W-W kpl - ~APBW 110 R550/67,5 125x83,5 + ~TV W-AP110 kpl - ~APBW 110 R750/90 200x290 + ~TV W-AP60 oben kpl. - ~APBW 110 R650/90 300x190 + ~TV W-AP110-W kpl - ~APBW 110 R550/67,5 208x347 + ~TV W-AP oben kpl - ~APBW 110 R550/67,5 58x497 + ~TV 80 - - - SPS - - - SPS Schliessen + ~TV 50 - + - - - TRO - Marker einfuegen + ~Endplatte Al-Profil AP schraubbar - Marker bearbeiten + ~Anschlag AP-Ende fuer Spulenzug - Bearbeiten (Auto) + ~TV-A fuer AP110/AP60 kpl - - - Connections - Verbindung einfuegen + ~TV-A fuer AP60/ST - Verbindung bearbeiten + ~TV-A fuer AP110/ST kpl - Eingang + ~TV-SW II fuer SW-SW - Ausgang + ~TV-SW III fuer SW-AP110-SW - Bearbeiten (Auto) + ~TV-SW III fuer SW-AP110 - + - - - Export - Export Sivas + ~TV-SW IV fuer Anschluss SW-AP60 - Export CSV + ~TV-SW IV fuer SW-ST - - - Konfiguration - Umschalten 2D und 3D + ~Muffe + + + Boegen fuer Weichen - Alle Bloecke auf 2D - - - - - - Alle Bloecke auf 3D + ~APB 110 R400/45 140 nur fuer Delta - Sprache + ~APB 110 R550/45 194 nur fuer Delta - Planquadrate an/aus + ~APBW 110 R550/22,5 360x248,5 - Konfiguration Schliessen - - - - - - - Tests - - alle Tests ausfuehren und exportieren + ~APBW 110 R550/22,5 410x298,5 - Tests ausfuehren und stehen lassen + ~APBW 110 R550/22,5 410x78,5 - Export CSV/Sivas ALL + ~APBW 110 R550/22,5 410x98,5 + + ~APBW 110 R550/67,5 360x598,5 + + + + + + ~APBW 110 R400/67,5 260x398,5 + + + + + + ~APBW 110 R550/45 77x160 + + + + + + ~APBW 110 R550/67,5 125x83,5 + + + + + + ~APBW 110 R750/90 200x290 + + + + + + ~APBW 110 R650/90 300x190 + + + + + + ~APBW 110 R550/67,5 208x347 + + + + + + ~APBW 110 R550/67,5 58x497 + + + + + + + SPS + + + + Eingang + + + + + + Ausgang + + + + + + SPS Schliessen + + + + + + + TRO + + Marker einfuegen + + + + + + Marker bearbeiten + + + + + + Bearbeiten (Auto) + + + + + + + Connections + + Verbindung einfuegen + + + + + + Verbindung bearbeiten + + + + + + Bearbeiten (Auto) + + + + + + + Export + + Export Sivas + + + + + + Export CSV + + + + + + + Konfiguration + + Umschalten 2D und 3D + + + + + + Alle Bloecke auf 2D + + + + + + Alle Bloecke auf 3D + + + + + + Sprache + + + + + + Planquadrate an/aus + + + + + + Konfiguration Schliessen + + + + + + + Tests + + alle Tests ausfuehren und exportieren + + + + + + Tests ausfuehren und stehen lassen + + + + + + Export CSV/Sivas ALL + + + + Kreisel - + Foerderer - + Foerderer-Linienzug - + Omniflo - + Omniflo Strecke - + Gefaellestrecke - + Mubea Gesamtmodell - + HundM05 Kreisel-Abschnitt - + KS 2D/3D pruefen (CSV) - + - + POP501 SSG_LIB Edit Context Kreisel bearbeiten - + Omniflo Element bearbeiten - + Gefaellestrecke bearbeiten - + VarioFoerderer bearbeiten - + TRO-Marker bearbeiten - + Verbindung bearbeiten - + SSG Bearbeiten (Auto) - + diff --git a/menu/SSG_LIB.mnu b/menu/SSG_LIB.mnu index bb2688e..7294389 100644 --- a/menu/SSG_LIB.mnu +++ b/menu/SSG_LIB.mnu @@ -139,7 +139,7 @@ [--] [Kreisel]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_kreisel.lsp")) TEST_KREISEL [Foerderer]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_foerderer.lsp")) TEST_FOERDERER -[Foerderer-Linienzug]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_linienzug.lsp")) TEST_LINIENZUG +[Foerderer-Linienzug]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_linienzug.lsp")) TEST_LINIENZUG TEST_LINIENZUG_STUFE2 [Omniflo]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo.lsp")) TEST_OMNIFLO [Omniflo Strecke]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_omniflo_strecke.lsp")) TEST_OMNIFLO_STRECKE [Gefaellestrecke]^C^C(load (strcat (getenv "DXFMAKRO") "/tests/test_gefaellestrecke.lsp")) TEST_GEFAELLESTRECKE diff --git a/tests/test_foerderer.lsp b/tests/test_foerderer.lsp index fbc89ad..298493b 100644 --- a/tests/test_foerderer.lsp +++ b/tests/test_foerderer.lsp @@ -217,7 +217,7 @@ results-list)) ) (progn - (setq ergebnis (berechne-alle-winkel deltaL deltaH richtung nil)) + (setq ergebnis (berechne-alle-winkel deltaL deltaH richtung nil nil)) (setq best-winkel (car ergebnis)) (setq L_GF (cadr ergebnis)) (setq L_VF (caddr ergebnis)) @@ -286,7 +286,7 @@ ;; geometrisch moeglich (analog Schritt 5b in c:VarioFoerderer). (if (= richtung "Ab") (progn - (setq horizontal-info (berechne-horizontale-mitte deltaL deltaH "Ab")) + (setq horizontal-info (berechne-horizontale-mitte deltaL deltaH "Ab" nil)) (if (and horizontal-info (caddr horizontal-info)) (progn (setq anz-gebaut (1+ anz-gebaut)) diff --git a/tests/test_mubea.lsp b/tests/test_mubea.lsp index 3a49229..613336c 100644 --- a/tests/test_mubea.lsp +++ b/tests/test_mubea.lsp @@ -159,7 +159,7 @@ (setq ergebnis (if (= typ "etage") (berechne-etage deltaL deltaH richtung seite) - (berechne-alle-winkel deltaL deltaH richtung nil))) + (berechne-alle-winkel deltaL deltaH richtung nil nil))) (setq best-winkel (car ergebnis) L_GF (cadr ergebnis) L_VF (caddr ergebnis)) (if (numberp winkel-soll) (progn diff --git a/tests/testdata/linienzug_tests.json b/tests/testdata/linienzug_tests.json index 67c4d73..11878de 100644 --- a/tests/testdata/linienzug_tests.json +++ b/tests/testdata/linienzug_tests.json @@ -1,198 +1,172 @@ [ { - "beschreibung": "Standard-Linienzug (Modus 1): Start Z4500 AS rechts -> Neue Linie Ab Z1800 45deg (GF am Einlauf) -> Horizontal 900 mit Separator VOR+NACH -> Vario-Kurve 90 links aussen -> Horizontal 250 -> Vario-Kurve 90 links aussen -> Kettenende (Option 3) Z4500 45deg ES rechts", - "erwartung_dx_mm": 0, - "erwartung_dy_mm": 637, + "beschreibung": "VF-Linienzug Modus 1 (2026-09-12, nach ES-Nein/schon-flach-Solver-Fix + AS-Auto-Erkennung + Kettenende/ES-Vorfrage + immer-pruefen Uebergangsbogen): Start Z2154 AS 90 links -> Neue VF mit horizontalem Anfang (GF1 am Einlauf, voller Eingang) -> Horizontal-VF-Fortsetzung (Vario-Kurve 90 rechts innen, hz 90->0 -> Horizontaler Foerderer 457mm -> Vario-Kurve 90 rechts innen, hz 0->-90) -> Kettenende ueber 'Ist der Endpunkt der Foerderer?'-Option 3 mit ES 90 links. Stufe 1 (Winkeltabelle) liefert mehrere gueltige Kandidaten (12/15/18/21/27/33/39/45 Grad), Nutzer waehlt 18 Grad (Index 3 der gueltigen Liste). Ersetzt die alte, laengst nicht mehr zum aktuellen Menue passende Datei (Kettenanfang-Menuewert 'Neue Linie: Ab/Auf VF' bei einer 5-Optionen-Zuordnung, die es so nicht mehr gibt) - direkt aus einem echten, erfolgreichen BricsCAD-Lauf uebernommen (XDATA-Journal aus logs/vfl_modus1.dbg, siehe Kommentare je Schritt), keine Handrechnung.", + "erwartung_dx_mm": 638, + "erwartung_dy_mm": 0, "erwartung_dz_mm": 0, - "erwartung_hinweis": "dY~637 = seitlicher Fussabdruck ES_Element_90 (Bauform, kein Baufehler)" + "erwartung_hinweis": "dX~638 = seitlicher Fussabdruck ES_Element_90 (Bauform, kein Baufehler) - Fahrtrichtung liegt hier auf der Y-Achse (hz=-90), daher zeigt sich der Versatz in X statt wie im urspruenglichen Test in Y." }, { "typ": "point_abs", - "wert": [0, 0, 0], + "wert": [-1289.407125, 95.871332, 2154], "kommentar": "getpoint Startpunkt der Kette" }, { "typ": "real", - "wert": 4500.0, + "wert": 2154.0, "kommentar": "getreal Hoehe (Z) Startpunkt" }, { "typ": "string", "wert": "1", - "kommentar": "getstring AS-Element setzen? (Ja) - neue Frage aus 3e23003, fehlte bisher in den Testdaten" + "kommentar": "getstring AS-Element setzen? (Ja)" + }, + { + "typ": "string", + "wert": "90", + "kommentar": "getstring AS-Element Winkel (90 Grad - echter Winkelwert, kein Index)" }, { "typ": "string", "wert": "1", - "kommentar": "getstring AS-Element Winkel (90 Grad)" + "kommentar": "getstring AS-Seite (links)" }, { "typ": "string", - "wert": "2", - "kommentar": "getstring AS-Seite (rechts)" - }, - { - "typ": "string", - "wert": "2", - "kommentar": "getstring Naechstes Element (2 = Neue Linie: Ab/Auf VF - Gefaelle hier 26 Grad > GF-Maximalwinkel, daher NICHT Option 1/GF)" + "wert": "5", + "kommentar": "getstring Naechstes Element (Kettenanfang, 6 Optionen): 5 = Neue VF mit horizontalem Anfang" }, { "typ": "point_rel", - "dL": 5500, - "hz": 0, - "kommentar": "getpoint Endpunkt Linie (frei, +X, dL=5500)" + "dL": 5854.769733, + "hz": 90, + "kommentar": "getpoint Endpunkt der Linie (frei, hz=90 - Kettenanfang, keine Richtungsvorgabe)" }, { "typ": "real", "wert": 1800.0, - "kommentar": "getreal Hoehe (Z) Linienendpunkt" + "kommentar": "getreal Ziel-Hoehe fuer den horizontalen VF-Anfang" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Zusaetzlichen Separator VOR dem horizontalen Stueck? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Zusaetzlichen Separator NACH dem horizontalen Stueck? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Ist der Endpunkt der Foerderer? (Nein - im Ziel-Modus VOR dem Bau gefragt, vor-antwort wird von der Fortsetzungsschleife uebernommen)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Naechstes Element im VarioFoerderer (2 = Vario-Kurve)" }, { "typ": "int", - "wert": 1, - "kommentar": "getint Winkelwahl (45 Grad)" + "wert": 90, + "kommentar": "getint Vario-Kurve Winkel (90 Grad, echter Wert)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring GF-Verteilung (alles am Einlauf)" + "kommentar": "getstring Vario-Kurve Seite (rechts)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Ist Endpunkt? (Nein)" + "kommentar": "getstring Vario-Kurve Variante (innen)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Ist der Endpunkt der Foerderer? (Nein)" }, { "typ": "string", "wert": "1", - "kommentar": "getstring Naechstes im VF (Horizontal)" + "kommentar": "getstring Naechstes Element im VarioFoerderer (1 = Horizontaler Foerderer)" }, { "typ": "point_rel", - "dL": 900, + "dL": 457.481366, "hz": 0, - "kommentar": "getpoint Horizontal-Endpunkt (dL=900, hz=0)" - }, - { - "typ": "string", - "wert": "1", - "kommentar": "getstring Separator VOR? (Ja)" - }, - { - "typ": "string", - "wert": "1", - "kommentar": "getstring Separator NACH? (Ja)" + "kommentar": "getpoint Horizontal-Endpunkt (dL=457.48, hz=0 - Richtung durch die erste Vario-Kurve auf 0 Grad gedreht)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Ist Endpunkt? (Nein)" + "kommentar": "getstring Zusaetzlichen Separator VOR? (Nein)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Naechstes (Vario-Kurve)" + "kommentar": "getstring Zusaetzlichen Separator NACH? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Ist der Endpunkt der Foerderer? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Naechstes Element im VarioFoerderer (2 = Vario-Kurve)" }, { "typ": "int", - "wert": 1, - "kommentar": "getint Kurve-Winkel (90)" - }, - { - "typ": "string", - "wert": "1", - "kommentar": "getstring Kurve-Seite (links)" - }, - { - "typ": "string", - "wert": "1", - "kommentar": "getstring Kurve-Variante (aussen)" + "wert": 90, + "kommentar": "getint Vario-Kurve Winkel (90 Grad)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Ist Endpunkt? (Nein)" - }, - { - "typ": "string", - "wert": "1", - "kommentar": "getstring Naechstes (Horizontal)" - }, - { - "typ": "point_rel", - "dL": 250, - "hz": 90, - "kommentar": "getpoint Horizontal-Endpunkt (dL=250, hz=90)" + "kommentar": "getstring Vario-Kurve Seite (rechts)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Separator VOR? (Nein)" - }, - { - "typ": "string", - "wert": "2", - "kommentar": "getstring Separator NACH? (Nein)" - }, - { - "typ": "string", - "wert": "2", - "kommentar": "getstring Ist Endpunkt? (Nein)" - }, - { - "typ": "string", - "wert": "2", - "kommentar": "getstring Naechstes (Vario-Kurve)" - }, - { - "typ": "int", - "wert": 1, - "kommentar": "getint Kurve-Winkel (90)" - }, - { - "typ": "string", - "wert": "1", - "kommentar": "getstring Kurve-Seite (links)" - }, - { - "typ": "string", - "wert": "1", - "kommentar": "getstring Kurve-Variante (aussen)" + "kommentar": "getstring Vario-Kurve Variante (innen)" }, { "typ": "string", "wert": "3", - "kommentar": "getstring Ist Endpunkt? (Option 3 - Kettenende)" + "kommentar": "getstring Ist der Endpunkt der Foerderer? (3 = Ja, Motorstation setzen + Kettenende definieren)" }, { "typ": "string", "wert": "1", - "kommentar": "getstring ES-Element setzen? (Ja) - neue Frage aus 3e23003, fehlte bisher in den Testdaten" + "kommentar": "getstring ES-Element setzen? (Ja)" + }, + { + "typ": "string", + "wert": "90", + "kommentar": "getstring ES-Element Winkel (90 Grad - echter Winkelwert)" + }, + { + "typ": "string", + "wert": "1", + "kommentar": "getstring ES-Seite (links)" }, { "typ": "point_rel", - "dL": 6215, - "hz": 180, - "kommentar": "getpoint Option-3-Endpunkt (dL=6215, hz=180)" + "dL": 5854.769733, + "hz": -90, + "kommentar": "getpoint Endpunkt entlang Fahrtrichtung (Kettenende-Modus, hz=-90 - unveraendert nach der zweiten Vario-Kurve, 90 Grad rechts)" }, { "typ": "real", - "wert": 4500.0, - "kommentar": "getreal Hoehe (Z) Kettenende (ES)" + "wert": 2154.0, + "kommentar": "getreal Ziel-Hoehe Kettenende (ES). Ab hier laeuft vfl-body-zerlegung AUTOMATISCH: Stufe 1 (Winkeltabelle) liefert 8 gueltige Kandidaten (12/15/18/21/27/33/39/45 Grad)" }, { "typ": "int", - "wert": 2, - "kommentar": "getint Option-3-Winkelwahl (45 Grad)" - }, - { - "typ": "string", - "wert": "1", - "kommentar": "getstring ES-Element Winkel (90 Grad)" - }, - { - "typ": "string", - "wert": "2", - "kommentar": "getstring ES-Seite (rechts)" + "wert": 3, + "kommentar": "getint Winkel-Wahl: Index 3 unter den GUELTIGEN Kandidaten (= 18 Grad, siehe vfl-waehle-winkel - Index in die gefilterte Liste, kein Winkelwert)" } ] diff --git a/tests/testdata/linienzug_tests_stufe2.json b/tests/testdata/linienzug_tests_stufe2.json index 8e2d56d..fca6e62 100644 --- a/tests/testdata/linienzug_tests_stufe2.json +++ b/tests/testdata/linienzug_tests_stufe2.json @@ -1,15 +1,15 @@ [ { - "beschreibung": "Stufe-2-Fallback-Regressionstest (Kettenende): Start Z2154 AS 90 Grad links -> Horizontal-VF (2x Vario-Kurve 90 rechts innen) -> Linie-GF 3 Grad (Sep vor+nach) -> Horizontal-VF (Vario-Kurve 30 rechts innen -> Auf 27 Grad -> Vario-Kurve 30 links aussen) -> Kettenende ueber 'Ist der Endpunkt der Foerderer?'-Option 3 mit ES 90 Grad links; GF2 (86mm) liegt unter der Mindestlaenge (400mm), Stufe 1 (Winkeltabelle) scheitert komplett (alle Kandidaten negative Laenge) -> Stufe 2 (vfl-winkel-stufe-entscheidung) liefert typ=VF winkel=0 (horizontales VF + GF-Ausgleich). Reproduziert den in dieser Session gefixten Bug (Stufe-2-Fallback griff im Kettenende-Zweig 'Ab, steiler als 3 Grad' bisher nicht, wenn Stufe 1 scheiterte) - erster erfolgreicher Stufe-2-Bau der Session, live in BricsCAD verifiziert.", + "beschreibung": "VF-Linienzug Modus 1 (2026-09-12, nach ES-Nein/schon-flach-Solver-Fix + AS-Auto-Erkennung + Kettenende/ES-Vorfrage bei Linie-GF): Start Z2154 AS 90 links -> Horizontal-VF (2x Vario-Kurve 90 rechts innen, hz 90->0->-90) -> Linie-GF 3 Grad Winkel direkt, Separator VOR+NACH (Kettenende-Frage jetzt VOR der Gefaelle-Berechnung, hier 'Nein weiterbauen') -> Horizontal-VF (Vario-Kurve 30 rechts innen, hz -90->-120 -> Auf-Tabelle Index 8 = 27 Grad -> Vario-Kurve 30 links aussen, hz -120->-90) -> Kettenende ueber 'Ist der Endpunkt der Foerderer?'-Option 3 mit ES 90 links. Stufe 1 (Winkeltabelle) scheitert am Kettenende komplett (alle 12 Kandidaten negative Laenge), Stufe 2 (horizontales VF + GF2=319mm, unter Mindestlaenge 400mm, Nutzer bestaetigt 'exakt bauen') greift - deckt denselben Stufe-2-Fallback-Pfad ab wie der urspruengliche Testfall. Direkt aus einem echten, erfolgreichen BricsCAD-Lauf uebernommen (XDATA-Journal aus logs/vfl_modus1.dbg, siehe Kommentare je Schritt) - keine Handrechnung.", "erwartung_dx_mm": 638, "erwartung_dy_mm": 0, "erwartung_dz_mm": 0, - "erwartung_hinweis": "dX~638 = seitlicher Fussabdruck ES_Element_90 quer zur letzten Fahrtrichtung (Bauform des 90-Grad-ES-Elements, kein Baufehler). Kernzweck des Testfalls: Stufe-2-Fallback beim Kettenende (typ=VF winkel=0 im Kettenende-Abschluss, GF2=86mm unter Mindestlaenge -> 'trotzdem mit 86mm bauen?'=Ja)." + "erwartung_hinweis": "dX~638 = seitlicher Fussabdruck ES_Element_90 (Bauform, kein Baufehler) - Fahrtrichtung liegt hier auf der Y-Achse (hz=-90), daher zeigt sich der Versatz in X statt wie im Standardtest in Y." }, { "typ": "point_abs", - "wert": [24377.817458, -10300, 2067], - "kommentar": "getpoint Startpunkt der Kette (Rohwert aus dem realen BricsCAD-Testlauf)" + "wert": [21377.904954, -10300, 2067], + "kommentar": "getpoint Startpunkt der Kette" }, { "typ": "real", @@ -23,8 +23,8 @@ }, { "typ": "string", - "wert": "1", - "kommentar": "getstring AS-Element Winkel - Menu-Index 1=90 Grad/2=30 Grad (vf-frage-element-winkel mappt den rohen Index auf den Winkel-STRING '90'/'30'; im Debug-Journal erscheint bereits der gemappte Wert '90', die Konsolen-/Mock-Eingabe selbst bleibt der Index)" + "wert": "90", + "kommentar": "getstring AS-Element Winkel (90 Grad - echter Winkelwert, kein Index, siehe vf-frage-element-winkel)" }, { "typ": "string", @@ -34,33 +34,43 @@ { "typ": "string", "wert": "5", - "kommentar": "getstring Naechstes Element (Kettenanfang-Menue, 6 Optionen: 5 = Horizontal-VF)" + "kommentar": "getstring Naechstes Element (Kettenanfang, 6 Optionen): 5 = Neue VF mit horizontalem Anfang" }, { "typ": "point_rel", - "dL": 6082.461, + "dL": 5854.769733, "hz": 90, - "kommentar": "getpoint Endpunkt Horizontal-VF (freie Richtung am Kettenanfang, hz-vorgabe=nil - hz=90 ist die vom Code gesnappte Richtung, direkt aus dem Debug-Journal (REAL-Eintrag unmittelbar nach dem DL-Eintrag) uebernommen; dieser REAL-Eintrag ist ein reiner Journal-Nebeneffekt von vfl-in-abstand und KEIN eigener Eingabe-Schritt, siehe Lisp/vf_linienzug.lsp vfl-in-abstand" + "kommentar": "getpoint Endpunkt der Linie (frei, hz=90 - Kettenanfang, keine Richtungsvorgabe)" }, { "typ": "real", "wert": 1980.0, - "kommentar": "getreal Ziel-Hoehe Eingang GF1 (eingang-modus=voll/nil, vollstaendiger Neuaufbau des VF-Eingangs)" + "kommentar": "getreal Ziel-Hoehe fuer den horizontalen VF-Anfang" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Ist der Endpunkt der Foerderer? (Nein) - erste Frage innerhalb vfl-baue-horizontal-koerper (ziel-modus)" + "kommentar": "getstring Zusaetzlichen Separator VOR dem horizontalen Stueck? (Nein)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Naechstes im VarioFoerderer (Vario-Kurve)" + "kommentar": "getstring Zusaetzlichen Separator NACH dem horizontalen Stueck? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Ist der Endpunkt der Foerderer? (Nein - im Ziel-Modus VOR dem Bau gefragt, vor-antwort wird von der Fortsetzungsschleife uebernommen)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Naechstes Element im VarioFoerderer (2 = Vario-Kurve)" }, { "typ": "int", "wert": 90, - "kommentar": "getint Vario-Kurve Winkel (90 Grad, roher Winkelwert - KEIN Auswahl-Index, siehe vfl-menu-winkel)" + "kommentar": "getint Vario-Kurve Winkel (90 Grad, echter Wert - vfl-menu-winkel)" }, { "typ": "string", @@ -80,23 +90,33 @@ { "typ": "string", "wert": "1", - "kommentar": "getstring Naechstes im VarioFoerderer (Horizontaler Foerderer)" + "kommentar": "getstring Naechstes Element im VarioFoerderer (1 = Horizontaler Foerderer)" }, { "typ": "point_rel", - "dL": 1300, + "dL": 1340, "hz": 0, - "kommentar": "getpoint Horizontal-Endpunkt innerhalb der VF-Einheit. hz=0 ANNAHME (NICHT direkt im Debug-/Konsolen-Auszug als 'hz=' ausgewiesen, sondern aus der Turn-Arithmetik hergeleitet: Start-hz=90, davor bereits eine 90-Grad-rechts-Vario-Kurve (-90) -> 90-90=0; dieselbe Turn-Konvention [rechts=-Winkel/links=+Winkel] ist an ZWEI anderen Stellen dieses Testfalls unabhaengig durch explizite 'hz='-Werte im Konsolen-Auszug bestaetigt, siehe die Vario_Bogen_ab_3/ab_27-Eintraege). BITTE in BricsCAD live gegenpruefen (einzige nicht direkt beleg-bestaetigte hz-Rekonstruktion dieses Testfalls)." + "kommentar": "getpoint Horizontal-Endpunkt (dL=1340, hz=0 - Richtung durch die erste Vario-Kurve auf 0 Grad gedreht)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Ist der Endpunkt der Foerderer? (Nein) - innerhalb vfl-baue-horizontal-koerper (ziel-modus)" + "kommentar": "getstring Zusaetzlichen Separator VOR? (Nein)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Naechstes im VarioFoerderer (Vario-Kurve)" + "kommentar": "getstring Zusaetzlichen Separator NACH? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Ist der Endpunkt der Foerderer? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Naechstes Element im VarioFoerderer (2 = Vario-Kurve)" }, { "typ": "int", @@ -116,12 +136,12 @@ { "typ": "string", "wert": "1", - "kommentar": "getstring Ist der Endpunkt der Foerderer? (Ja, nur Motorstation) - schliesst die 1. Horizontal-VF-Einheit ab" + "kommentar": "getstring Ist der Endpunkt der Foerderer? (1 = Ja, nur Motorstation setzen - schliesst die Horizontal-VF-Einheit)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Ist das Kettenende (ES-Element)? (Nein, weiterbauen) - vfl-vf-einheit-abschluss" + "kommentar": "getstring Ist das das Kettenende (ES-Element)? (Nein - GF-Verteilung entfaellt hier, eingang-modus=voll aber gf-verteilung-fest)" }, { "typ": "string", @@ -131,64 +151,74 @@ { "typ": "string", "wert": "2", - "kommentar": "getstring Naechstes Element (Hauptmenue, 5 Optionen, Frame vorhanden: 2 = Neue Linie: GF)" + "kommentar": "getstring Naechstes Element (5 Optionen, Kette laeuft weiter): 2 = Neue Linie: GF (Gefaellestrecke)" }, { "typ": "string", "wert": "1", - "kommentar": "getstring Wie soll die Laenge dieser Gefaellestrecke bestimmt werden? (1 = Endpunkt waehlen)" + "kommentar": "getstring Wie soll die Laenge bestimmt werden? (1 = Endpunkt waehlen, Zweig A)" + }, + { + "typ": "string", + "wert": "3", + "kommentar": "getstring Ist das das Kettenende? (3 = Nein, weiterbauen - NEU: kommt seit dieser Session VOR der Gefaelle-/Laengenberechnung)" }, { "typ": "point_rel", - "dL": 978.394396, + "dL": 800, "hz": -90, - "kommentar": "getpoint Endpunkt Gefaellestrecke. hz=-90 DIREKT aus dem Debug-Journal bestaetigt (GEOMETRIE-Zeile 'vfl-insert-gf-segment (deltaL=379 hz=-90 winkel=3)')" + "kommentar": "getpoint Endpunkt der Gefaellestrecke (dL=800, hz=-90 - Richtung nach der zweiten Vario-Kurve)" }, { "typ": "string", "wert": "1", - "kommentar": "getstring Separator VOR dieser Gefaellestrecke einfuegen? (Ja)" + "kommentar": "getstring Separator VOR dieser Gefaellestrecke? (Ja)" }, { "typ": "string", "wert": "1", - "kommentar": "getstring Separator NACH dieser Gefaellestrecke einfuegen? (Ja)" + "kommentar": "getstring Separator NACH dieser Gefaellestrecke? (Ja)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Gefaelle festlegen (1 = Hoehe, 2 = Neigungswinkel eingeben - Reihenfolge im Code seit dieser Sitzung getauscht)" + "kommentar": "getstring Gefaelle festlegen (2 = Neigungswinkel eingeben)" }, { "typ": "real", "wert": 3.0, "kommentar": "getreal Neigungswinkel (3 Grad)" }, - { - "typ": "string", - "wert": "3", - "kommentar": "getstring Ist das Kettenende? (3 = Nein, weiterbauen - 3-Optionen-Menue: 1=Ja+ES, 2=Ja ohne ES, 3=Nein)" - }, { "typ": "string", "wert": "4", - "kommentar": "getstring Naechstes Element (5 Optionen: 4 = Neue VF mit horizontalem Anfang/Horizontal-VF)" + "kommentar": "getstring Naechstes Element (5 Optionen): 4 = Neue VF mit horizontalem Anfang" }, { "typ": "point_rel", - "dL": 888.101488, + "dL": 838.819967, "hz": -90, - "kommentar": "getpoint Endpunkt Horizontal-VF (2. Einheit). hz=-90 unveraendert gegenueber dem vorigen GF-Segment (keine Richtungsaenderung dazwischen); eingang-modus=separator (letztes Glied war der Separator NACH der Gefaellestrecke) -> KEINE Ziel-Hoehe-Frage fuer GF1 (im Unterschied zur 1. Horizontal-VF-Einheit)" + "kommentar": "getpoint Endpunkt der Linie (dL=838.82, hz=-90 - unveraendert nach der Gefaellestrecke)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Ist der Endpunkt der Foerderer? (Nein) - innerhalb vfl-baue-horizontal-koerper (ziel-modus)" + "kommentar": "getstring Zusaetzlichen Separator VOR? (Nein)" }, { "typ": "string", "wert": "2", - "kommentar": "getstring Naechstes im VarioFoerderer (Vario-Kurve)" + "kommentar": "getstring Zusaetzlichen Separator NACH? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Ist der Endpunkt der Foerderer? (Nein)" + }, + { + "typ": "string", + "wert": "2", + "kommentar": "getstring Naechstes Element im VarioFoerderer (2 = Vario-Kurve)" }, { "typ": "int", @@ -213,13 +243,13 @@ { "typ": "string", "wert": "3", - "kommentar": "getstring Naechstes im VarioFoerderer (Auf/Ab-Foerderer)" + "kommentar": "getstring Naechstes Element im VarioFoerderer (3 = Auf/Ab-Foerderer)" }, { "typ": "point_rel", - "dL": 1614.972606, + "dL": 1621.311164, "hz": -120, - "kommentar": "getpoint Endpunkt Auf/Ab-Foerderer. hz=-120 DIREKT bestaetigt (Konsolen-Auszug zeigt fuer den anschliessenden Vario_Bogen_ab_3_TEF_rechts explizit 'hz=-120 Grad' bei derselben Fahrtrichtung)" + "kommentar": "getpoint Endpunkt entlang Fahrtrichtung (dL=1621.31, hz=-120 - Richtung nach der dritten Vario-Kurve, 30 Grad rechts)" }, { "typ": "string", @@ -229,7 +259,7 @@ { "typ": "int", "wert": 8, - "kommentar": "getint Winkel-/Hoehen-Tabelle: Auswahl-Index (NICHT der Winkel selbst) unter den GUELTIGEN Kandidaten - gueltig sind hier 3/6/9/12/15/18/21/27 Grad (8 Werte), Index 8 = letzter gueltiger Kandidat = 27 Grad (siehe Konsolen-Auszug '5/11: Vario_Bogen_auf_27_TEF_rechts')" + "kommentar": "getint Winkel-Hoehen-Tabelle: Index 8 unter den GUELTIGEN Kandidaten (= 27 Grad, siehe vfl-waehle-winkel-hoehen-tabelle - Index, kein Winkelwert)" }, { "typ": "string", @@ -239,7 +269,7 @@ { "typ": "string", "wert": "2", - "kommentar": "getstring Naechstes im VarioFoerderer (Vario-Kurve)" + "kommentar": "getstring Naechstes Element im VarioFoerderer (2 = Vario-Kurve)" }, { "typ": "int", @@ -254,12 +284,12 @@ { "typ": "string", "wert": "1", - "kommentar": "getstring Vario-Kurve Variante (aussen) - Konsolen-Auszug bestaetigt 'Vario_Kurve_links_30_TEF_aussen'" + "kommentar": "getstring Vario-Kurve Variante (aussen)" }, { "typ": "string", "wert": "3", - "kommentar": "getstring Ist der Endpunkt der Foerderer? (3 = Ja, Motorstation setzen + Kettenende definieren) - startet den Stufe-1/Stufe-2-Kettenende-Zweig (vfl-body-abschluss/vfl-body-zerlegung)" + "kommentar": "getstring Ist der Endpunkt der Foerderer? (3 = Ja, Motorstation setzen + Kettenende definieren)" }, { "typ": "string", @@ -268,8 +298,8 @@ }, { "typ": "string", - "wert": "1", - "kommentar": "getstring ES-Element Winkel - Menu-Index 1=90 Grad/2=30 Grad (wie AS-Winkel oben, gleiches Mapping ueber vf-frage-element-winkel)" + "wert": "90", + "kommentar": "getstring ES-Element Winkel (90 Grad - echter Winkelwert)" }, { "typ": "string", @@ -278,18 +308,18 @@ }, { "typ": "point_rel", - "dL": 1802.808856, + "dL": 1797.304153, "hz": -90, - "kommentar": "getpoint Endpunkt Kettenende (vfl-body-abschluss). hz=-90 DIREKT bestaetigt: die im Debug-Log erreichte Position (25544.710135 -8783.275914 2270.287821) hat exakt dieselbe X- und Z-Koordinate wie die KS_AUS-Position der vorigen Vario-Kurve (25544.71 / 2270.29 lt. Konsolen-Auszug) - nur Y aendert sich, das ist ausschliesslich mit hz=-90 (reine Y-Richtung) vereinbar" + "kommentar": "getpoint Endpunkt entlang Fahrtrichtung (Kettenende-Modus, dL=1797.30, hz=-90 - unveraendert nach der vierten Vario-Kurve, 30 Grad links)" }, { "typ": "real", "wert": 2154.0, - "kommentar": "getreal Ziel-Hoehe Kettenende. Ab hier laeuft vfl-body-zerlegung AUTOMATISCH: Stufe 1 (Winkeltabelle 3/6/9/.../51 Grad) scheitert komplett (alle Kandidaten ergeben negative L_VF), Stufe 2 (vfl-winkel-stufe-entscheidung/berechne-horizontale-mitte) liefert typ=VF winkel=0 L_GF=86 L_VF=286 - KEINE weitere Eingabe fuer diese Entscheidung noetig" + "kommentar": "getreal Ziel-Hoehe Kettenende (ES). Ab hier laeuft vfl-body-zerlegung AUTOMATISCH: Stufe 1 (Winkeltabelle 3/6/.../51 Grad) scheitert komplett (alle 12 Kandidaten negative Laenge), Stufe 2 (horizontales VF + GF2) liefert typ=VF winkel=0 L_GF=319 L_VF=48" }, { "typ": "string", "wert": "1", - "kommentar": "getstring Berechnetes GF2=86mm liegt unter der ueblichen Mindestlaenge (400mm) - trotzdem mit den exakt berechneten 86mm bauen? (Ja) - schliesst die Kette ab (VF_n mit GF=1 VF=5)" + "kommentar": "getstring Berechnetes GF2 (319mm) liegt unter der Mindestlaenge (400mm) - Ja: mit den exakt berechneten 319mm bauen (Zielpunkt wird exakt getroffen)" } ]