fix: Fussabdruecke aller Festbauteile im Segmentbudget (Modus 2)
Leitsatz, aus dem alle Einzelaenderungen folgen (neu als Abschnitt 0 in doc/VarioFoerderer_Linienzug_Prinzipien.md): die gezeichneten GERADEN besitzen den Pfad, ein gezeichneter Bogen ist Hilfsgeometrie und nennt nur Ort und Drehsinn. Jedes fest gebaute Teil zieht seine Laenge von dem Segment ab, auf dem es steht - und zwar in LAENGEN- UND HOEHENbilanz mit demselben, GEMESSENEN Wert. Behoben: - AS-Element: Fussabdruck wurde bei vf-start = 0 gar nicht abgezogen (die Trimmung lief nur im Front-Lauf, der dort leer ist). Jetzt gemessen aus dem gebauten KS_AUS - ein aus dem Block-dx gerechneter Wert lag 184 mm daneben. - Abschlussbogen + Motorstation: standen auf dem letzten Segment des VF-Laufs, fehlten aber im Budget (feste-vf traegt den Motor nur im Zweig OHNE flache Zone). - ES-Element: die letzte Gerade reservierte nur den Laengsanteil. Jetzt die Strecke, die auch den Querversatz aufhebt (vfl-es-achs-reserve) - Vorgabe: quer zur KS_AUS-Achse MUSS 0 sein, laengs darf abweichen, dZ MUSS 0 sein. - ES-Abzug griff auch, wenn ein Back-Lauf zwischen VF-Lauf und ES liegt, und verkuerzte dann das falsche Segment um die volle ES-Laenge (878 mm). Jetzt nur noch bei direktem Anschluss (vf-ende = n-1). - Eck-Bauteile: Vario-Kurve/Gefaellebogen ersetzen den gezeichneten Bogen mit eigenem Fussabdruck. Die Differenz der Tangentenabstaende geht als Zuschlag an beide angrenzenden Geraden (vfl-eck-korrekturen/-zerlegen), damit die Mittellinie beide beruehrt. Der gezeichnete Radius kuerzt sich dabei heraus. GF-Boegen werden geneigt eingebaut - ihr Grundriss- Fussabdruck wird mit vfl-projiziere-neigung projiziert. - Kletterlaenge wurde anteilig mit der Planlaenge im Zaehler und dem korrigierten climber-span im Nenner verteilt; die Anteile summierten sich dadurch auf weniger als 1. - Absturz bei fehlendem Uebergangsbogen: get-bogen-mass wurde zweimal fuer dieselbe Suche aufgerufen und sein nil ungeprueft an vfl-projiziere-neigung gereicht. Messreihe ueber die Sitzung (gleicher Pfad, Abweichung quer): 695.7 -> 270 -> 139.5 -> 98.5 -> 45.7 -> 2.4 -> 0.2 mm, dZ durchgehend 0. Beide Pfad-Varianten (Ecke als Vario-Kurve bzw. als GF-Bogen) landen auf demselben Wert - 0.2 mm ist die Messaufloesung, kein Restfehler. 21 neue file-freie Unit-Tests mit den echten Messwerten; TEST_UNIT 866/866. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+341
-30
@@ -11149,7 +11149,9 @@
|
||||
(setq seg (nth i plan))
|
||||
(cond
|
||||
((= (car seg) "Linie")
|
||||
(setq w (nth 4 seg) dL (caddr seg))
|
||||
;; Eck-Zuschlag wie im Bau (vfl-eck-extra) - sonst rechnet die Hoehe mit
|
||||
;; einer anderen Laenge als gebaut wird (vgl. dZ-Sprung 2026-10-26).
|
||||
(setq w (nth 4 seg) dL (+ (caddr seg) (vfl-eck-extra i)))
|
||||
(if (= i last-idx) (setq dL (- dL *vfk-separator-laenge* ein-fp)))
|
||||
(setq dL (max *vfk-restlaenge-min-clamp* dL))
|
||||
(setq rad (* (float w) (/ pi 180.0)))
|
||||
@@ -11267,6 +11269,159 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; --- Eck-Korrektur: Eck-Bauteil an die beiden GERADEN anlegen ---
|
||||
;; Leitsatz (Nutzer-Vorgabe 2026-10-26): der gezeichnete Bogen sagt nur, WO
|
||||
;; die Ecke liegt und WIE HERUM es geht. Sein Radius und seine Masse sind
|
||||
;; KEINE Vorgabe - massgeblich sind die beiden Geraden. Die MITTELLINIE des
|
||||
;; Eck-Bauteils (Vario-Kurve bzw. Gefaellebogen) muss die beiden Geraden
|
||||
;; beruehren: KS_EIN liegt auf der Geraden davor UND zeigt in deren Richtung,
|
||||
;; KS_AUS auf der Geraden danach und in deren Richtung. Dann laeuft die Kette
|
||||
;; knickfrei und ohne Seitenversatz durch die Ecke - egal, welchen Radius
|
||||
;; jemand gezeichnet hat.
|
||||
;; Weil zwei nicht-parallele Geradenrichtungen die Ebene aufspannen, ist die
|
||||
;; Bedingung durch zwei Laengenzuschlaege EXAKT erfuellbar; an einer Ecke
|
||||
;; bleibt also kein Querrest uebrig.
|
||||
;;
|
||||
;; Umgesetzt als Differenz der TANGENTENABSTAENDE zur Ecke. Die Planlaengen
|
||||
;; der Geraden sind bis zum GEZEICHNETEN Tangentenpunkt gemessen, das Bauteil
|
||||
;; setzt an seinem EIGENEN an - die Differenz bekommt jede der beiden Geraden
|
||||
;; als Budget-Zuschlag. Rechnerisch ist das die Zerlegung
|
||||
;; d = a*u_ein + b*u_aus, d = gezeichnete Sehne - Bauteil-Fussabdruck
|
||||
;; auf die Richtungen der beiden Geraden (eindeutig, solange die Ecke einen
|
||||
;; Schwenk hat). Der gezeichnete Radius kuerzt sich dabei vollstaendig heraus:
|
||||
;; mit R300 statt R500 aendern sich Planlaenge UND Sehne gemeinsam.
|
||||
;; Ohne diese Korrektur verschiebt die Differenz ALLES Nachfolgende und taucht
|
||||
;; erst am Kettenende auf (real 2026-10-26: 132.6 mm von 155 mm Gesamtfehler -
|
||||
;; Pfad R500 = Tangentenabstand 500, Vario-Kurve = 406.2).
|
||||
;;
|
||||
;; Grenze: beruehren kann das Bauteil nur beide Geraden, wenn sein Schwenk zum
|
||||
;; Eckwinkel passt (90-Grad-Kurve an 90-Grad-Ecke). Weichen sie voneinander
|
||||
;; ab, bleibt ein Rest, den keine Laengenaenderung aufheben kann.
|
||||
;;
|
||||
;; GEMESSEN, nicht gerechnet: die Sehne steht als (caddr seg) im Plan (aus der
|
||||
;; Zeichnung), der Bauteil-Fussabdruck kommt ueber vfl-zsolve-es-vektor aus der
|
||||
;; realen Blockgeometrie. Darum greift die Korrektur fuer jeden Eckwinkel und
|
||||
;; jeden gezeichneten Radius, ohne gepflegte Tabelle.
|
||||
;; Rueckgabe: Alist (segment-index . zuschlag-mm).
|
||||
(defun vfl-eck-korrekturen (plan n / korr i seg hz w seite blk vek
|
||||
sgn th s-along s-perp d-along d-perp a b j
|
||||
jp bm neig)
|
||||
(setq korr '() i 0)
|
||||
(while (< i n)
|
||||
(setq seg (nth i plan))
|
||||
(if (and (= (car seg) "Bogen") (nth 3 seg) (nth 4 seg))
|
||||
(progn
|
||||
(setq hz (cadr seg)
|
||||
w (float (nth 3 seg))
|
||||
seite (nth 4 seg)
|
||||
sgn (if (= seite "links") 1.0 -1.0)
|
||||
th (* sgn w (/ pi 180.0)))
|
||||
;; Sehne des GEZEICHNETEN Bogens im Fahrtrichtungs-System der
|
||||
;; einlaufenden Geraden - ihre Richtung ist der halbe Schwenk.
|
||||
(setq s-along (* (caddr seg) (cos (/ th 2.0)))
|
||||
s-perp (* (caddr seg) (sin (/ th 2.0))))
|
||||
;; Blocknamen NICHT selbst zusammensetzen - gf-bogen-blockname ist die
|
||||
;; eine Stelle, die das Namensschema der Gefaelleboegen kennt (Radius,
|
||||
;; Sonderfaelle). Ein handgebauter Name traf den Block nicht, die
|
||||
;; Messung kam leer zurueck und die Ecke blieb unkorrigiert - real
|
||||
;; 2026-10-26: 2.4 mm Rest, weil der 90-Grad-Gefaellebogen geneigt
|
||||
;; eingebaut nur 497.8 statt 500 mm Grundriss-Fussabdruck hat.
|
||||
(setq blk (if (= (nth 5 seg) "Vario-Kurve")
|
||||
(strcat "Vario_Kurve_" seite "_" (itoa (fix w)) "_TEF_"
|
||||
(if (nth 6 seg) (nth 6 seg) "aussen"))
|
||||
(gf-bogen-blockname (fix w) seite)))
|
||||
(setq vek (vfl-zsolve-es-vektor blk hz))
|
||||
;; GF-Boegen werden GENEIGT eingebaut (Gefaellewinkel der Strecke) -
|
||||
;; ihr GRUNDRISS-Fussabdruck ist dadurch kuerzer als flach gemessen.
|
||||
;; Real 2026-10-26: flach 500.0, bei 3 Grad 497.8; der Unterschied
|
||||
;; blieb als 2.4 mm am Kettenende stehen. Vario-Kurven werden
|
||||
;; waagerecht eingebaut und bleiben unberuehrt (dort war die Kette
|
||||
;; bereits auf 0.2 mm genau). Projiziert mit dem vorhandenen
|
||||
;; vfl-projiziere-neigung, Neigung = Gefaellewinkel der Geraden davor
|
||||
;; (sonst der Standardwert, mit dem auch hinter einer VF-Einheit
|
||||
;; gebaut wird).
|
||||
(if (and vek (/= (nth 5 seg) "Vario-Kurve"))
|
||||
(progn
|
||||
(setq jp (1- i))
|
||||
(while (and (>= jp 0) (/= (car (nth jp plan)) "Linie")) (setq jp (1- jp)))
|
||||
(setq neig (if (and (>= jp 0)
|
||||
(numberp (nth 4 (nth jp plan)))
|
||||
(> (nth 4 (nth jp plan)) 0))
|
||||
(float (nth 4 (nth jp plan)))
|
||||
(float *vfk-gefaelle-winkel*)))
|
||||
(setq bm (gf-bogen-masse (fix w) seite))
|
||||
(if bm
|
||||
(setq vek (list (car (vfl-projiziere-neigung (car vek) (cadr bm) neig))
|
||||
(cadr vek))))))
|
||||
(setq d-along (if vek (vfl-eck-zerlegen s-along s-perp
|
||||
(car vek) (cadr vek) th) nil))
|
||||
(if d-along
|
||||
(progn
|
||||
(setq a (car d-along) b (cadr d-along))
|
||||
;; a auf die Gerade DAVOR, b auf die Gerade DANACH
|
||||
(setq j (1- i))
|
||||
(while (and (>= j 0) (/= (car (nth j plan)) "Linie")) (setq j (1- j)))
|
||||
(if (>= j 0) (setq korr (cons (cons j a) korr)))
|
||||
(setq j (1+ i))
|
||||
(while (and (< j n) (/= (car (nth j plan)) "Linie")) (setq j (1+ j)))
|
||||
(if (< j n) (setq korr (cons (cons j b) korr)))))))
|
||||
(setq i (1+ i)))
|
||||
korr)
|
||||
|
||||
;; Laengs-Reservierung der letzten Geraden, damit der ES-KS_AUS auf der
|
||||
;; KS_AUS-ACHSE durch den Zielpunkt landet (reiner Kern, getestet).
|
||||
;; Nutzer-Vorgabe 2026-10-26: QUER zur KS_AUS-Achse MUSS 0 sein, LAENGS darf
|
||||
;; abweichen (das ist die Ausladung des Elements), dZ MUSS 0 sein.
|
||||
;; Ein reiner Laengs-Abzug (= along) stellt den Endpunkt zwar in Fahrtrichtung
|
||||
;; richtig, laesst aber den bauteileigenen Querversatz stehen - real 45.7 mm.
|
||||
;; Gesucht ist die Strecke entlang der Fahrtrichtung, die ihn AUFHEBT:
|
||||
;; KS_AUS = P + V_es, Bedingung (KS_AUS - Ziel) . n_a = 0
|
||||
;; -> Reserve = (V_es . n_a) / (dp . n_a)
|
||||
;; dp = Fahrtrichtung der letzten Geraden, n_a = Normale der KS_AUS-Achse
|
||||
;; (Achsrichtung = hz + es-turn). Die Gerade wird dadurch laenger als die
|
||||
;; Planlaenge - zulaessig, weil laengs abweichen darf; ihre Mittellinie bleibt
|
||||
;; dabei auf der gezeichneten Linie. Da derselbe Wert auch in den Rueckanker
|
||||
;; geht, bleibt dZ 0 (vgl. Leitsatz: eine Groesse, beide Bilanzen).
|
||||
;; Faellt die Achse mit der Fahrtrichtung zusammen (es-turn = 0), ist der
|
||||
;; Nenner 0 - dann gibt es keinen Querversatz und along ist richtig.
|
||||
;; along/perp: ES-Fussabdruck im Fahrtrichtungs-System (vfl-zsolve-es-vektor).
|
||||
(defun vfl-es-achs-reserve (along perp hz es-turn / rad ua dpx dpy nax nay vx vy nenner)
|
||||
(setq rad (/ pi 180.0))
|
||||
(setq ua (* (+ (float hz) (float es-turn)) rad))
|
||||
(setq nax (- (sin ua)) nay (cos ua))
|
||||
(setq dpx (cos (* (float hz) rad)) dpy (sin (* (float hz) rad)))
|
||||
;; V_es aus (along perp) ins Weltsystem: x^ = dp, y^ = senkrecht dazu
|
||||
(setq vx (- (* along dpx) (* perp dpy))
|
||||
vy (+ (* along dpy) (* perp dpx)))
|
||||
(setq nenner (+ (* dpx nax) (* dpy nay)))
|
||||
(if (< (abs nenner) 1e-6)
|
||||
along
|
||||
(/ (+ (* vx nax) (* vy nay)) nenner)))
|
||||
|
||||
;; Reiner Kern der Eck-Korrektur (in tests/test_unit.lsp geprueft):
|
||||
;; Differenz zwischen gezeichneter Sehne (s-*) und Bauteil-Fussabdruck (b-*),
|
||||
;; beide im Fahrtrichtungs-System der EINLAUFENDEN Geraden, zerlegt auf
|
||||
;; d = a*u_ein + b*u_aus mit u_ein = (1,0) und u_aus = (cos th, sin th).
|
||||
;; th = Schwenk der Ecke im Bogenmass (positiv = links). Rueckgabe (a b),
|
||||
;; nil bei th = 0 (keine Ecke - dann ist die Zerlegung nicht eindeutig).
|
||||
(defun vfl-eck-zerlegen (s-along s-perp b-along b-perp th / a b)
|
||||
(if (< (abs (sin th)) 1e-9)
|
||||
nil
|
||||
(progn
|
||||
(setq b (/ (- s-perp b-perp) (sin th)))
|
||||
(setq a (- (- s-along b-along) (* b (cos th))))
|
||||
(list a b))))
|
||||
|
||||
;; Summe der Eck-Zuschlaege fuer ein Segment (0.0, wenn keiner vorliegt).
|
||||
;; Globale Tabelle statt zusaetzlichem Parameter, damit die Signatur von
|
||||
;; vfl-zsolve-rueckanker unveraendert bleibt (AutoLISP verlangt exakte
|
||||
;; Argumentzahl - eine Erweiterung muesste jeden Aufrufer nachziehen).
|
||||
(defun vfl-eck-extra (idx / s)
|
||||
(setq s 0.0)
|
||||
(if (boundp '*vfl-eck-korr*)
|
||||
(foreach e *vfl-eck-korr* (if (= (car e) idx) (setq s (+ s (cdr e))))))
|
||||
s)
|
||||
|
||||
;; Letzte Fueller-Laenge so, dass der Endpunkt auf der ES-KS_AUS-Achse liegt.
|
||||
;; pt = Fueller-Start (flach 0 Grad), seg-hz = letzte Richtung, es-block = ES-Block,
|
||||
;; gf2 = erwartete GF2-Laenge, rad3 = 3 Grad (rad). Modell: der Schwanz (Fueller +
|
||||
@@ -11322,7 +11477,8 @@
|
||||
hor-koerper-len hor-pairs flat-p flat-zone-erste fill-len wahl3
|
||||
rad3v feste-vf dH-adj dir-x dir-y fill-D end-hz
|
||||
laengs-wert quer-wert soll-korrigiert
|
||||
es-vek-fix es-along-fix
|
||||
es-vek-fix es-along-fix as-along-fix m-ueb
|
||||
abschluss-fp m-ab3 es-vek-back ein-fp-mess
|
||||
gf-total br-gf-mode br-gf2-exp filler-A-len filler-a-done
|
||||
as-vorhanden es-vorhanden dbg-an dbg-old-error
|
||||
m2-lauf-antwort m2-offenes-ende es-frueh-abgelehnt
|
||||
@@ -11669,11 +11825,24 @@
|
||||
(if dz (setq z-junction (- z-junction dz)))
|
||||
(setq i (1- i)))
|
||||
|
||||
;; Eck-Zuschlaege EINMAL bestimmen (siehe vfl-eck-korrekturen) - sie gehen
|
||||
;; in JEDES Laengenbudget ein: Spannweite, Kletterer, Fueller, Rueckanker.
|
||||
;; Nur so koennen Laengen- und Hoehenbilanz nicht auseinanderlaufen.
|
||||
(setq *vfl-eck-korr* (vfl-eck-korrekturen plan n))
|
||||
;; Auch kleine Zuschlaege melden: bleibt eine Ecke unkorrigiert (Block nicht
|
||||
;; messbar), FEHLT die Zeile - und genau das ist die Information, die man
|
||||
;; beim Suchen eines Millimeter-Rests braucht.
|
||||
(foreach e *vfl-eck-korr*
|
||||
(if (> (abs (cdr e)) 0.05)
|
||||
(princ (ssg-textf "vfl-m2-eck-korrektur"
|
||||
(list (rtos (cdr e) 2 1) (itoa (1+ (car e))))))))
|
||||
|
||||
;; Bruecken-Spannweite = Summe der VF-Geraden-Planlaengen im Lauf.
|
||||
(setq span-bruecke 0.0 i vf-start)
|
||||
(while (<= i vf-ende)
|
||||
(setq seg (nth i plan))
|
||||
(if (= (car seg) "Linie") (setq span-bruecke (+ span-bruecke (caddr seg))))
|
||||
(if (= (car seg) "Linie")
|
||||
(setq span-bruecke (+ span-bruecke (caddr seg) (vfl-eck-extra i))))
|
||||
(setq i (1+ i)))
|
||||
|
||||
(setq dH-bruecke (- z-front z-junction))
|
||||
@@ -11828,6 +11997,33 @@
|
||||
(progn (if (< first-line 0) (setq first-line i)) (setq last-line i)))
|
||||
(setq i (1+ i)))
|
||||
|
||||
;; --- ES-Laengsanteil EINMAL messen, fuer LAENGE *und* HOEHE ---
|
||||
;; Der Endpunkt der letzten Geraden ist der KS_AUS des ES-Elements, nicht
|
||||
;; dessen Anfang - vom Budget dieses Segments gehen also Separator UND der
|
||||
;; ES-Laengsanteil ab. Entscheidend ist, dass BEIDE Bilanzen denselben Wert
|
||||
;; benutzen: das Laengenbudget im B4-Bau und das Hoehenbudget in
|
||||
;; vfl-zsolve-rueckanker. Liefen sie auseinander, stimmte die Laenge und die
|
||||
;; Hoehe kippte um Differenz*tan(Neigung) - real am 2026-10-26 gesehen:
|
||||
;; GF 820 mm kuerzer, dZ sprang von 0.1 auf 43 mm (= 820*sin(3 Grad)).
|
||||
;; GEMESSEN aus der realen Blockgeometrie statt aus dem Block-dx `ein` -
|
||||
;; letzteres kennt den Schwenk des 30-Grad-Elements nicht und lag ~520 mm
|
||||
;; daneben. `ein` bleibt nur Rueckfall, wenn der Block nicht lesbar ist.
|
||||
(setq es-vek-back
|
||||
(if (and es-vorhanden (>= last-line 0))
|
||||
(vfl-zsolve-es-vektor (strcat "ES_Element_" (vfl-es-winkel) "_" es-seite)
|
||||
(cadr (nth last-line plan)))
|
||||
nil))
|
||||
;; NICHT der reine Laengsanteil (car), sondern die Reserve, die zusaetzlich
|
||||
;; den Querversatz aufhebt - siehe vfl-es-achs-reserve.
|
||||
(setq ein-fp-mess
|
||||
(cond (es-vek-back
|
||||
(vfl-es-achs-reserve (car es-vek-back) (cadr es-vek-back)
|
||||
(cadr (nth last-line plan))
|
||||
(vf-element-plan-turn
|
||||
(strcat "ES_Element_" (vfl-es-winkel) "_" es-seite))))
|
||||
(es-vorhanden ein)
|
||||
(t 0.0)))
|
||||
|
||||
;; --- B1: FRONT-Lauf bauen (Segmente 0 .. vf-start-1) -> Front-Anker MESSEN ---
|
||||
(princ (ssg-text "vfl-m3-phase-b1"))
|
||||
(setq i 0)
|
||||
@@ -11893,10 +12089,30 @@
|
||||
(vfl-pfad-as-vf-einfuegen startpunkt hz as-seite)
|
||||
(make-frame-from-dir startpunkt (hz-winkel->xu hz 0.0)))))
|
||||
(setq z-front (caddr (car frame)))
|
||||
;; --- AS-Fussabdruck ins LAENGENbudget (GEMESSEN, nicht gerechnet) ---
|
||||
;; Das AS-Element steht SELBST auf dem ersten Segment des Laufs; sein
|
||||
;; Laengsanteil gehoert nicht mehr der Bruecke. Identische Formel wie die
|
||||
;; Trimmung der ersten Geraden im Front-Lauf oben (Projektion von
|
||||
;; KS_AUS - startpunkt auf die Fahrtrichtung) - dort laeuft sie nur, wenn
|
||||
;; dem VF-Lauf ueberhaupt Segmente vorausgehen; bei vf-start = 0 ist die
|
||||
;; Schleife leer und der Abzug fiel bisher komplett aus. Folge: der Solver
|
||||
;; verteilte die VOLLE Planlaenge HINTER dem AS, die Kette ueberschoss um
|
||||
;; den AS-Fussabdruck (realer Fall 2026-10-26).
|
||||
;; GEMESSEN statt aus der Blockgeometrie gerechnet: das Block-Mass stimmt
|
||||
;; nach dem Achs-Versatz des AS nicht mehr (ein gerechneter Wert lag
|
||||
;; 184 mm daneben und machte das erste Segment sichtbar zu kurz).
|
||||
;; Ohne AS-Element faellt der Wert von allein auf 0 - dann ist (car frame)
|
||||
;; gleich startpunkt -, eine Abfrage auf as-vorhanden braucht es nicht.
|
||||
(setq as-along-fix
|
||||
(+ (* (- (car (car frame)) (car startpunkt)) (cos (* hz (/ pi 180.0))))
|
||||
(* (- (cadr (car frame)) (cadr startpunkt)) (sin (* hz (/ pi 180.0))))))
|
||||
(if (> (abs as-along-fix) 0.01)
|
||||
(princ (ssg-textf "vfl-m2-as-fussabdruck"
|
||||
(list (rtos as-along-fix 2 1) (itoa (1+ vf-start))))))
|
||||
|
||||
;; --- B2: Back-Abstieg -> Junction; Kletterer + Horizontal-Mitte bestimmen ---
|
||||
(setq z-junction (+ (float end-hoehe)
|
||||
(vfl-zsolve-rueckanker plan (1+ vf-ende) n last-line ein)))
|
||||
(vfl-zsolve-rueckanker plan (1+ vf-ende) n last-line ein-fp-mess)))
|
||||
;; Offenes Ende (kein Motor/Separator/ES danach) ODER Motor+GF2 OHNE ES
|
||||
;; danach (Lauf-Abschluss "Motorstation", es-vorhanden nil - Motor selbst
|
||||
;; ist bereits ueber dH-adj/*vfk-bruecke-korrektur* separat eingerechnet,
|
||||
@@ -11947,8 +12163,10 @@
|
||||
;; NUR die laengste VF-Gerade klettert (siehe Regel oben) - jede
|
||||
;; weitere wird flacher Fueller.
|
||||
(if (= i longest-idx)
|
||||
(setq climbers (cons i climbers) climber-span (+ climber-span (caddr seg)))
|
||||
(setq nonclimber-len (+ nonclimber-len (caddr seg)) nonclimber-cnt (1+ nonclimber-cnt))))
|
||||
(setq climbers (cons i climbers)
|
||||
climber-span (+ climber-span (caddr seg) (vfl-eck-extra i)))
|
||||
(setq nonclimber-len (+ nonclimber-len (caddr seg) (vfl-eck-extra i))
|
||||
nonclimber-cnt (1+ nonclimber-cnt))))
|
||||
((= (car seg) "Bogen")
|
||||
(setq nkurve (1+ nkurve) kurve-chords (+ kurve-chords (caddr seg)))))
|
||||
(setq i (1+ i)))
|
||||
@@ -11988,6 +12206,27 @@
|
||||
(m2-kein-gf1-vorne *vfk-stations-laenge*)
|
||||
(t (+ *vfk-stations-laenge* *vfk-separator-laenge*))))
|
||||
(setq es-along-fix 0.0)
|
||||
;; --- Abschluss-Hardware der VF-Einheit ins LAENGENbudget ---
|
||||
;; Spiegelbild zum AS-Fussabdruck am anderen Ende des Laufs: MIT flacher
|
||||
;; Zone sitzt die Motorstation nicht im Kletterer, sondern auf dem LETZTEN
|
||||
;; Segment des Laufs - zusammen mit dem Abschlussbogen davor. Genau diese
|
||||
;; beiden fehlten im Budget: feste-vf traegt die Motorstation nur im Zweig
|
||||
;; OHNE flache Zone (siehe unten), und die Fuellerlaenge war schlicht die
|
||||
;; volle Planlaenge. Realer Fall 2026-10-26: Segment 3 (Plan 4296 mm) wurde
|
||||
;; 4990.55 mm lang = 4296 + 195.73 (Bogen ab_3) + 499.32 (Motorstation).
|
||||
;; Der Ueberschuss lief laengs zur ES-Achse und wurde darum von der Zeile
|
||||
;; "Soll (ES-korrigiert)" verdeckt - sichtbar war nur die Querabweichung.
|
||||
;; Nicht doppelt zu uebergang-fp: das sind die Uebergangsboegen AM
|
||||
;; KLETTERER, hier geht es um den Bogen VOR der Motorstation.
|
||||
(setq abschluss-fp 0.0)
|
||||
(if (and (> hor-pairs 0) (not m2-offenes-ende))
|
||||
(progn
|
||||
(setq m-ab3 (get-bogen-mass bogen-ab (fix *vfk-gefaelle-winkel*)))
|
||||
(setq abschluss-fp
|
||||
(+ (* *vfk-stations-laenge* (cos rad3v))
|
||||
(if m-ab3 (car m-ab3) 0.0)))
|
||||
(princ (ssg-textf "vfl-m2-abschluss-fussabdruck"
|
||||
(list (rtos abschluss-fp 2 1) (itoa (1+ vf-ende)))))))
|
||||
(if (> hor-pairs 0)
|
||||
(setq feste-vf entry-fixed
|
||||
dH-adj (- dH-bruecke (+ (* *vfk-stations-laenge* (sin rad3v)) *vfk-bruecke-korrektur*))) ; Motor + auf_3/ab_3
|
||||
@@ -12008,7 +12247,18 @@
|
||||
;; Test dieses Fixes (dZ=38.6mm, vorher exakt 0).
|
||||
(setq feste-vf (+ entry-fixed (if m2-offenes-ende 0.0 *vfk-stations-laenge*))
|
||||
dH-adj dH-bruecke)
|
||||
(if es-vorhanden
|
||||
;; NUR wenn das ES unmittelbar auf den VF-Lauf folgt, also der Lauf das
|
||||
;; Pfadende ist. Liegt ein Back-Lauf dazwischen (Segmente nach vf-ende),
|
||||
;; traegt dessen letzte Gerade den ES-Fussabdruck bereits selbst
|
||||
;; (ein-fp-mess im B4-Zweig) - ihn hier nochmal vom VF-Lauf abzuziehen,
|
||||
;; verkuerzt das FALSCHE Segment um die volle ES-Laenge.
|
||||
;; Realer Fall 2026-10-26: derselbe Pfad, aber Segment 2 als GF-Bogen
|
||||
;; statt Vario-Kurve gewaehlt -> keine flache Zone -> dieser Zweig
|
||||
;; griff, und Segment 1 wurde um 875.8 mm zu kurz (Abweichung 878.2 mm
|
||||
;; quer). Mit Vario-Kurve lief dieselbe Kette auf 0.2 mm genau.
|
||||
;; Der hz von vf-ende waere ausserdem die falsche Fahrtrichtung: das ES
|
||||
;; steht dann am Ende des Back-Laufs, nicht am Ende des VF-Laufs.
|
||||
(if (and es-vorhanden (= vf-ende (1- n)))
|
||||
(progn
|
||||
(setq es-vek-fix (vfl-zsolve-es-vektor
|
||||
(strcat "ES_Element_" (vfl-es-winkel) "_" es-seite)
|
||||
@@ -12033,20 +12283,49 @@
|
||||
;; Kletterer, wenn eine flache Zone vorausgeht.
|
||||
;; Nur die LAENGE wird korrigiert - die Hoehe dieser Boegen steckt bereits
|
||||
;; in *vfk-bruecke-korrektur* (siehe dH-adj oben).
|
||||
;; Die Masse werden EINMAL geholt und gegen nil geprueft. Beides war vorher
|
||||
;; nicht so: get-bogen-mass wurde fuer dieselbe Suche zweimal aufgerufen
|
||||
;; (car/caddr), meldete einen Fehlschlag also doppelt, und das nil ging
|
||||
;; ungeprueft an vfl-projiziere-neigung, wo (cos rad) den ganzen Lauf
|
||||
;; abbrach (realer Fall 2026-10-26: "Winkel 3 nicht in Bogen-Tabelle"
|
||||
;; zweimal, danach Call-Stack-Abbruch). bogen-auf/bogen-ab entstehen beim
|
||||
;; Init nur aus den BLOECKEN, die ladbar UND messbar sind (vf_standard.lsp)
|
||||
;; - fehlt eine DWG, fehlt der Eintrag. Das darf den Bau nicht toeten:
|
||||
;; ohne Mass bleibt der Uebergangsbogen mit 0 im Budget (die Kette wird um
|
||||
;; seine Laenge zu lang, entsteht aber und ist nachbesserbar) und der
|
||||
;; Nutzer bekommt gesagt, welcher Block fehlt.
|
||||
(setq uebergang-fp 0.0)
|
||||
(if (> n-climb 0)
|
||||
(progn
|
||||
(if (< (car climbers) vf-ende) ; flache Zone FOLGT -> flach-ein
|
||||
(setq uebergang-fp
|
||||
(+ uebergang-fp
|
||||
(car (vfl-projiziere-neigung (car (get-bogen-mass bogen-auf 3))
|
||||
(caddr (get-bogen-mass bogen-auf 3))
|
||||
(fix *vfk-gefaelle-winkel*))))))
|
||||
(progn
|
||||
(setq m-ueb (get-bogen-mass bogen-auf (fix *vfk-gefaelle-winkel*)))
|
||||
(if m-ueb
|
||||
(setq uebergang-fp
|
||||
(+ uebergang-fp
|
||||
(car (vfl-projiziere-neigung (car m-ueb) (caddr m-ueb)
|
||||
(fix *vfk-gefaelle-winkel*)))))
|
||||
(vfl-meldung (ssg-textf "vfl-m2-uebergang-bogen-fehlt"
|
||||
(list (strcat "Vario_Bogen_auf_"
|
||||
(itoa (fix *vfk-gefaelle-winkel*))
|
||||
"_TEF_rechts")))))))
|
||||
(if (> (car climbers) vf-start) ; flache Zone GEHT VORAUS -> flach-aus
|
||||
(setq uebergang-fp
|
||||
(+ uebergang-fp (car (get-bogen-mass bogen-ab 3)))))))
|
||||
(progn
|
||||
(setq m-ueb (get-bogen-mass bogen-ab (fix *vfk-gefaelle-winkel*)))
|
||||
(if m-ueb
|
||||
(setq uebergang-fp (+ uebergang-fp (car m-ueb)))
|
||||
(vfl-meldung (ssg-textf "vfl-m2-uebergang-bogen-fehlt"
|
||||
(list (strcat "Vario_Bogen_ab_"
|
||||
(itoa (fix *vfk-gefaelle-winkel*))
|
||||
"_TEF_rechts")))))))))
|
||||
;; as-along-fix nur abziehen, wenn das AS-Segment auch wirklich ein
|
||||
;; Kletterer ist - sitzt es auf einem Fueller-Segment, zieht es dort ab
|
||||
;; (siehe fill-len weiter unten). Sonst waere der Abzug doppelt bzw. am
|
||||
;; falschen Segment.
|
||||
(setq wahl3 (vfl-zsolve-winkel-waehlen
|
||||
(- climber-span es-along-fix uebergang-fp) dH-adj feste-vf))
|
||||
(- climber-span es-along-fix uebergang-fp
|
||||
(if (member vf-start climbers) as-along-fix 0.0))
|
||||
dH-adj feste-vf))
|
||||
(if (null wahl3)
|
||||
(progn
|
||||
;; Stufe 2: KEIN Tabellenwinkel passt (der/die Kletterer sind bei JEDER
|
||||
@@ -12126,7 +12405,15 @@
|
||||
;; --- Kletterer (geneigt, 3-Grad-Basis) ---
|
||||
((and (= (car seg) "Linie") (member i climbers))
|
||||
(if flat-p (progn (setq pt (vfl-zsolve-flach-aus pt seg-hz)) (setq flat-p nil)))
|
||||
(setq this-lvf (max *vfk-restlaenge-min-clamp* (* br-lvf (/ (caddr seg) climber-span))))
|
||||
;; Anteil dieses Kletterers an der Gesamt-Kletterlaenge. Zaehler UND
|
||||
;; Nenner muessen denselben Laengenbegriff benutzen: climber-span
|
||||
;; enthaelt die Eck-Zuschlaege (vfl-eck-extra), die Planlaenge allein
|
||||
;; nicht. Ohne den Zuschlag im Zaehler summieren sich die Anteile auf
|
||||
;; weniger als 1, der Kletterer wird zu kurz - bei EINEM Kletterer um
|
||||
;; genau den Zuschlag (real 2026-10-26: 55 mm zu kurz, davon 5.4 mm
|
||||
;; Hoehenfehler ueber sin(Steigwinkel)).
|
||||
(setq this-lvf (max *vfk-restlaenge-min-clamp*
|
||||
(* br-lvf (/ (+ (caddr seg) (vfl-eck-extra i)) climber-span))))
|
||||
(setq pt (vfs-vf-koerper pt br-richtn br-winkel this-lvf seg-hz))
|
||||
(vfl-acc-vf-seg br-richtn br-winkel this-lvf)
|
||||
(setq anzahl-vf (1+ anzahl-vf) letzt-koerper-hz seg-hz))
|
||||
@@ -12173,7 +12460,12 @@
|
||||
(* (+ *vfk-stations-laenge* br-gf2-exp) (cos rad3v)))
|
||||
)
|
||||
)
|
||||
(setq fill-len (caddr seg)))
|
||||
;; Gewoehnlicher Fueller: volle Planlaenge des Segments, abzueglich
|
||||
;; der fest gebauten Teile, die auf GENAU diesem Segment stehen -
|
||||
;; das AS am Laufanfang, Abschlussbogen + Motorstation am Laufende.
|
||||
(setq fill-len (- (+ (caddr seg) (vfl-eck-extra i))
|
||||
(if (= i vf-start) as-along-fix 0.0)
|
||||
(if (= i vf-ende) abschluss-fp 0.0))))
|
||||
;; Kritische Fueller-Position (direkt nach Umlenkstation ODER direkt vor
|
||||
;; Motorstation) zu kurz fuer den geforderten Wert - statt still zu
|
||||
;; klemmen, den Nutzer warnen (Zielhoehe/-position wird dann nicht exakt
|
||||
@@ -12245,12 +12537,28 @@
|
||||
(setq seg (nth i plan) typ (car seg) hz (cadr seg))
|
||||
(cond
|
||||
((= typ "Linie")
|
||||
(setq winkel (nth 4 seg) deltaL (caddr seg)
|
||||
(setq winkel (nth 4 seg) deltaL (+ (caddr seg) (vfl-eck-extra i))
|
||||
sep-vor-gf (nth 5 seg) sep-nach-gf (nth 6 seg))
|
||||
;; Footprint fuer Separator(300)+ES nur reservieren, wenn ES-Element
|
||||
;; gewuenscht ist (ein=0 sonst, siehe oben) - ohne ES entfaellt auch
|
||||
;; der abschliessende Separator.
|
||||
(if (= i last-line) (setq deltaL (- deltaL (if es-vorhanden *vfk-separator-laenge* 0.0) ein)))
|
||||
;; Letzte Gerade vor dem ES: ihr ENDPUNKT ist der KS_AUS des ES-Elements,
|
||||
;; nicht dessen Anfang (Nutzer-Vorgabe 2026-10-26). Vom Segmentbudget
|
||||
;; gehen darum Separator UND der echte ES-Laengsanteil ab.
|
||||
;; Der frueher benutzte Skalar `ein` (ein-dx) ist das Block-dx OHNE den
|
||||
;; Schwenk des 30-Grad-Elements und lag real weit daneben: Segment 5
|
||||
;; hatte 1466 mm Plan und wurde 2285 mm lang (GF 1411 statt ~591).
|
||||
;; vfl-zsolve-es-vektor misst along/quer aus der REALEN Blockgeometrie
|
||||
;; gegen die Fahrtrichtung dieses Segments - dieselbe Funktion, die der
|
||||
;; Zweig ohne flache Zone fuer es-along-fix schon benutzt. Nur wenn der
|
||||
;; Block nicht lesbar ist, bleibt `ein` als grobe Naeherung.
|
||||
;; ein-fp-mess ist derselbe Wert, mit dem vfl-zsolve-rueckanker die
|
||||
;; Hoehe gerechnet hat (einmal gemessen, siehe oben) - nur so koennen
|
||||
;; Laenge und Hoehe nicht auseinanderlaufen.
|
||||
(if (= i last-line)
|
||||
(setq deltaL (- deltaL
|
||||
(if es-vorhanden *vfk-separator-laenge* 0.0)
|
||||
ein-fp-mess)))
|
||||
;; Separator(en) VOR/NACH aus der Klassifizierung (Punkt 1, wie B1).
|
||||
(if sep-vor-gf (setq deltaL (- deltaL *vfk-separator-laenge*)))
|
||||
(if sep-nach-gf (setq deltaL (- deltaL *vfk-separator-laenge*)))
|
||||
@@ -12307,8 +12615,12 @@
|
||||
(list (rtos (- (car ist-ende) (car soll-ende)) 2 1)
|
||||
(rtos (- (cadr ist-ende) (cadr soll-ende)) 2 1)
|
||||
(rtos (- (caddr ist-ende) (caddr soll-ende)) 2 1))))
|
||||
;; Zerlegung bezogen auf die ES-KS_AUS-ACHSE: Quer (senkrecht zur Achse) soll
|
||||
;; ~0 sein (Endpunkt liegt auf der KS_AUS-Achse), Laengs = ES-Ausladung.
|
||||
;; Zerlegung bezogen auf die ES-KS_AUS-ACHSE (Nutzer-Vorgabe 2026-10-26):
|
||||
;; QUER (senkrecht zur Achse) MUSS 0 sein - der Endpunkt liegt auf der
|
||||
;; Achse, in dieser Richtung darf es keine Abweichung geben.
|
||||
;; LAENGS (auf der Achse) darf abweichen - das ist die Ausladung des
|
||||
;; ES-Elements.
|
||||
;; Ebenso MUSS dZ 0 sein.
|
||||
(setq end-hz (car (frame->hz-winkel frame))) ; KS_AUS-Achsrichtung
|
||||
(setq dir-x (cos (* end-hz (/ pi 180.0))) dir-y (sin (* end-hz (/ pi 180.0))))
|
||||
(setq laengs-wert (+ (* (- (car ist-ende) (car soll-ende)) dir-x)
|
||||
@@ -12317,15 +12629,14 @@
|
||||
(* (- (cadr ist-ende) (cadr soll-ende)) dir-x)))
|
||||
(princ (ssg-textf "vfl-m3-laengs-quer" (list (rtos laengs-wert 2 1) (rtos quer-wert 2 1))))
|
||||
(princ (ssg-text "vfl-m3-achse-hinweis"))
|
||||
;; Soll (ES-korrigiert): der gepickte Zielpunkt, verschoben um den bereits
|
||||
;; oben gemessenen Laengs-Wert entlang der KS_AUS-Achse - zeigt, dass die
|
||||
;; Abweichung oben keine Unsicherheit ist, sondern GENAU der ES-eigene
|
||||
;; Fussabdruck (90/30-Grad-Schwenk, siehe doc/VarioFoerderer_Linienzug_
|
||||
;; Prinzipien.md Abschnitt 6/14.11: "seitliche ES-Ausladung, kein Fehler").
|
||||
;; Bewusst aus dem bereits gemessenen Laengs-Wert abgeleitet statt ueber
|
||||
;; eine zweite, eigenstaendige vf-element-ks-info-Neuberechnung - das waere
|
||||
;; ein zweiter Rechenweg fuer dieselbe Information mit eigenem Bug-Risiko,
|
||||
;; hier reicht die Umkehrung der bereits validierten Laengs/Quer-Zerlegung.
|
||||
;; Der Querversatz ist KEIN Fehler, sondern die Geometrie des ES-Blocks:
|
||||
;; das Ausschleuselement wandert beim Schwenken zur Seite. Ihn als
|
||||
;; "Abweichung" stehen zu lassen hat real zu einer langen Fehlersuche
|
||||
;; gefuehrt - darum wird er benannt. Die frueheren Zeilen "Soll
|
||||
;; (ES-korrigiert)" sind damit entfallen: sie haben den gepickten Zielpunkt
|
||||
;; um den Laengs-Wert verschoben, damit dY per Konstruktion 0 wurde, und
|
||||
;; verdeckten so genau die Fehlerart, die wir hier jagen (ein zu langes
|
||||
;; Segment laengs der Achse sah dadurch fehlerfrei aus).
|
||||
(setq soll-korrigiert (list (+ (car soll-ende) (* laengs-wert dir-x))
|
||||
(+ (cadr soll-ende) (* laengs-wert dir-y))
|
||||
(caddr soll-ende)))
|
||||
|
||||
@@ -0,0 +1,822 @@
|
||||
# VarioFoerderer / Gefaellestrecke - Konstruktionsprinzipien (Linienzug)
|
||||
|
||||
Referenzdokument fuer den Anlagen-Typ "linienzug" (gemischte GF/VF-Kette).
|
||||
Fasst alle im Gespraech festgelegten Prinzipien und Definitionen zusammen.
|
||||
|
||||
> Hinweis: Dieses Dokument beschreibt das ZIEL-Verhalten. Der aktuelle
|
||||
> Umsetzungsstand und bekannte Abweichungen sind in Abschnitt 13 gesammelt.
|
||||
|
||||
---
|
||||
|
||||
## 0. Leitsatz: die Geraden besitzen den Pfad, Boegen sind Verbindungsstuecke
|
||||
|
||||
Festgelegt am 2026-10-26, gilt fuer alle Modi und fuer GF wie VF.
|
||||
|
||||
**Massgeblich sind die gezeichneten GERADEN.** Die Mittellinie jedes geraden
|
||||
Abschnitts liegt auf seiner Pfadlinie - das ist die Bedingung, an der sich
|
||||
alles ausrichtet.
|
||||
|
||||
**Ein gezeichneter Bogen ist dagegen nur Hilfsgeometrie.** Er sagt, WO die
|
||||
Ecke liegt und WIE HERUM es geht. Sein Radius und seine Masse sind KEINE
|
||||
Vorgabe; wer R300 oder R800 zeichnet, bekommt dieselbe Kette.
|
||||
|
||||
**Das Eck-Bauteil ist ein Verbindungsstueck und hat keinen eigenen
|
||||
Freiheitsgrad.** Seine Lage folgt aus den beiden Geraden, die es verbindet:
|
||||
seine Mittellinie beruehrt beide. `KS_EIN` liegt auf der Geraden davor und
|
||||
zeigt in deren Richtung, `KS_AUS` auf der Geraden danach und in deren
|
||||
Richtung. Damit laeuft die Kette knickfrei und ohne Seitenversatz durch die
|
||||
Ecke.
|
||||
|
||||
### Daraus folgt: jedes fest gebaute Teil zieht seine Laenge von dem Segment ab, auf dem es steht
|
||||
|
||||
Ein gerades Segment vergibt Laenge an alles, was darauf gebaut wird. Was
|
||||
dort ein festes Mass hat, gehoert nicht mehr dem frei rechenbaren Rest:
|
||||
|
||||
| Stelle | Vorgabe aus der Zeichnung | Mass kommt vom Bauteil |
|
||||
|---|---|---|
|
||||
| Kettenanfang | Startpunkt | AS-Element (Fussabdruck entlang des Segments) |
|
||||
| Ende des VF-Laufs | Segmentlaenge | Abschlussbogen + Motorstation |
|
||||
| letzte Gerade vor dem ES | Endpunkt | Separator + ES-Laengsanteil |
|
||||
| Ecke | NUR Ort und Drehsinn | Tangentenabstand des Eck-Bauteils |
|
||||
|
||||
**Die Masse werden GEMESSEN, nicht aus Block-Massen oder Radien gerechnet.**
|
||||
Gerechnete Werte lagen in der Praxis daneben: der AS-Fussabdruck um 184 mm
|
||||
(das Block-`dx` kennt den Achs-Versatz nicht), der ES-Laengsanteil um ~520 mm
|
||||
(das Block-`dx` kennt den Schwenk des 30-Grad-Elements nicht).
|
||||
|
||||
**Laengen- und Hoehenbilanz muessen denselben Wert benutzen.** Laufen sie
|
||||
auseinander, stimmt die Laenge und die Hoehe kippt um
|
||||
`Differenz * sin(Neigung)` - real aufgetreten: 820 mm Differenz ergaben
|
||||
43 mm Hoehenfehler. Darum wird jeder Fussabdruck EINMAL gemessen und an
|
||||
beide Bilanzen gegeben (Bau-Pfad und `vfl-zsolve-rueckanker`).
|
||||
|
||||
### Grenzen
|
||||
|
||||
- Ein Eck-Bauteil kann nur dann beide Geraden beruehren, wenn sein Schwenk
|
||||
zum Eckwinkel passt (90-Grad-Kurve an 90-Grad-Ecke). Weichen sie ab,
|
||||
bleibt ein Knick, den keine Laengenaenderung aufhebt.
|
||||
- Der **seitliche Versatz des ES-Elements** ist GEWOLLT und bleibt bestehen
|
||||
(Entscheidung aus Modus 1: der Hauptstrang bleibt gerade). Entweder liegt
|
||||
die letzte Gerade exakt auf der gezeichneten Linie und der ES-`KS_AUS`
|
||||
landet daneben, oder umgekehrt - beides zugleich geht nicht.
|
||||
|
||||
---
|
||||
|
||||
## 1. Grundkonzept "Kette"
|
||||
|
||||
- Eine Kette (Linienzug) ist eine durchgehende Foerderstrecke entlang eines
|
||||
beliebigen 3D-Pfades.
|
||||
- Eine Kette beginnt **immer** mit genau **einem** `AS_Element`
|
||||
(Kettenanfang) und endet **immer** mit genau **einem** `ES_Element`
|
||||
(Kettenende).
|
||||
- Pro Kette gibt es also **genau ein** AS_Element und **genau ein** ES_Element.
|
||||
- Die Mittelachse der gesamten Kette liegt exakt auf dem gewaehlten/gezeichneten
|
||||
Pfad (wie in der Gefaellestrecke, ueber KS_EIN/KS_AUS-Frame-Kettung).
|
||||
|
||||
### Eingabemodi (Konsolen-Nummerierung, intern GLEICHNAMIG - kein Tausch)
|
||||
1. **Modus 1 - Wert manuell eingeben** (`vf-linienzug-modus`): Startpunkt
|
||||
waehlen, dann Punkt-fuer-Punkt eine Linie in beliebige Richtung ziehen,
|
||||
Endhoehe abfragen usw. (interaktiv). Gegenstand der Abschnitte 1-13.
|
||||
2. **Modus 2 - Pfad + Ziel-Hoehe** (`vf-linienzug-modus2`): Ein bereits
|
||||
gezeichneter Pfad (LINE/ARC-Kette) wird ausgewaehlt, Start-/Endpunkt +
|
||||
Zielhoehe abgefragt; die Kette wird als Randwertproblem geloest (Ziel-Hoehe
|
||||
wird EXAKT getroffen). Siehe Abschnitt 14.
|
||||
3. **Modus 3 - Vorwaerts-Nachbau** (`vf-linienzug-modus3`): baut eine Kette
|
||||
Segment fuer Segment vorwaerts anhand ausgewaehlter 3D-Objekte; die
|
||||
Endhoehe ist nur ein Ergebnis, nicht vorgebbar (Anfangswertproblem).
|
||||
Legacy, wird schrittweise umgebaut - nicht Gegenstand dieses Dokuments.
|
||||
|
||||
---
|
||||
|
||||
## 2. Definition: reiner VarioFoerderer (VF)
|
||||
|
||||
- **Prinzipiell ist ein reiner VarioFoerderer die Gesamtheit aller Segmente
|
||||
zwischen einer Umlenkstation und einer Motorstation.**
|
||||
- Die **Umlenkstation** steht **einmal** am Anfang einer VF-Einheit, die
|
||||
**Motorstation** steht **einmal** am Ende einer VF-Einheit.
|
||||
- Alles dazwischen (geneigte Strecken, horizontale Strecken, Vario-Kurven,
|
||||
Vertikalboegen) gehoert zum reinen VarioFoerderer und kann eine
|
||||
Unter-Kette bilden.
|
||||
|
||||
### Warum GF1/GF2 und Separatoren dazugehoeren
|
||||
Was `variofoerderer-einfuegen` aktuell baut, ist eine Kombination MIT
|
||||
`AS_Element`, `ES_Element`, `GF1`, `GF2` und Separatoren. Grund:
|
||||
|
||||
- `AS_Element` hat zwischen KS_EIN und KS_AUS eine Neigung von ca. **3 Grad**.
|
||||
Deshalb ist eine **3-Grad-Gefaellestrecke `GF1`** noetig, um das AS_Element
|
||||
mit der Umlenkstation zu verbinden.
|
||||
- Ebenso ist eine **3-Grad-Gefaellestrecke `GF2`** noetig, um die Motorstation
|
||||
mit dem `ES_Element` zu verbinden.
|
||||
|
||||
### Standard-Aufbau (11 Schritte, Typ "standard")
|
||||
```
|
||||
1. AS_Element (Kettenanfang, ~3 Grad Neigung)
|
||||
2. GF1 Gefaellestrecke (3 Grad) -> verbindet AS mit Umlenkstation
|
||||
3. Separator (300 mm)
|
||||
4. Umlenkstation (500 mm, 3 Grad) <-- Beginn reiner VF
|
||||
5. Vertikalbogen 1
|
||||
6. L_VF variable Strecke
|
||||
7. Vertikalbogen 2
|
||||
8. Motorstation (500 mm, 3 Grad) <-- Ende reiner VF
|
||||
9. GF2 Gefaellestrecke (3 Grad) -> verbindet Motorstation mit ES
|
||||
10. Separator (300 mm)
|
||||
11. ES_Element (Kettenende)
|
||||
```
|
||||
Der "reine VF" sind hier die Schritte 5-7 (zwischen Umlenk- und Motorstation).
|
||||
|
||||
### Aufbau einer VF-Einheit im LINIENZUG (Abweichung vom Standard)
|
||||
Im Linienzug sitzt die Staustrecke bevorzugt am **Einlauf** und der Separator
|
||||
wird erst spaeter gesetzt:
|
||||
```
|
||||
[AS bzw. vorheriges Element]
|
||||
GF1 Gefaellestrecke (3 Grad) <- ganze oder halbe Staustrecke (Wahl)
|
||||
Separator (300 mm)
|
||||
Umlenkstation (500 mm, 3 Grad) <-- Beginn reiner VF
|
||||
[1..n Koerper-Sub-Segmente + Vario-Kurven] <-- reiner VF (mehrsegmentig)
|
||||
Motorstation (500 mm, 3 Grad) <-- Ende reiner VF
|
||||
[GF2 Gefaellestrecke (3 Grad)] <- nur falls "halbe am Ausgang"
|
||||
-> KEIN Separator direkt hinter der Motorstation/GF2
|
||||
```
|
||||
Der abschliessende Separator + das ES-Element kommen erst am **Kettenende**
|
||||
(bzw. optional ein Separator zwischen zwei Foerderern). Details: Abschnitt 5, 8,
|
||||
9 (GF-Verteilung) und 12 (Block-Attribute).
|
||||
|
||||
---
|
||||
|
||||
## 3. Segment-Entscheidung: GF oder VF
|
||||
|
||||
Fuer jedes gerade Linien-Segment wird anhand von Start-/Endhoehe entschieden.
|
||||
**Wichtig: Eine reine Gefaellestrecke ist NIE steiler als 3 Grad.** Deshalb ist
|
||||
die reine GF auf ~3 Grad beschraenkt, alles Steilere ist ein VarioFoerderer:
|
||||
|
||||
| Bedingung | Ergebnis |
|
||||
|---|---|
|
||||
| Endpunkt **hoeher** als Startpunkt | **immer VF** (eine Gefaellestrecke kann als reine Schwerkraftstrecke nicht steigen) - **Ausnahme:** "Neue Linie: GF" bietet dafuer einen eigenen, bewusst getrennten Sonderfall "Steigende GF" (siehe unten) |
|
||||
| Endpunkt **tiefer**, Neigung **~ 3 Grad** (Toleranzband) | **reine Gefaellestrecke (GF)** bei fest 3 Grad |
|
||||
| Endpunkt **tiefer**, Neigung **> 3 Grad** | **VF-ab** (angetrieben, erreicht die Steilheit ueber Vertikalboegen 3-51 Grad) |
|
||||
| Endpunkt **tiefer**, Neigung **< 3 Grad** | **VF** (zu flach fuer reine GF: Horizontale Mitte oder diskreter Winkel) |
|
||||
|
||||
Das Toleranzband um 3 Grad ist ueber `*vfl-gf-winkel-toleranz*` (Vorgabe 0.5 Grad)
|
||||
einstellbar.
|
||||
|
||||
### Sonderfall: Steigende GF (bis 3 Grad)
|
||||
|
||||
"Neue Linie: GF" hat eine dritte, eigenstaendige Laengen-Modus-Option
|
||||
("Steigende GF (Sonderfall, bis 3 Grad)", `gf-laenge-modus="3"`) NUR fuer
|
||||
diesen einen Ausnahmefall: eine reine Gefaellestrecke, die bis zu 3 Grad
|
||||
STEIGT statt faellt (Vorzeichenkonvention wie `frame->hz-winkel`: negativer
|
||||
Winkel = steigend). Bewusst getrennt von den normalen Zweigen A (Endpunkt
|
||||
waehlen) und B (Zielhoehe zuerst) - kein Separator wird dafuer gefragt
|
||||
(Separatoren gelten nur fuer die normale, fallende GF).
|
||||
|
||||
- Die Bibliothek kennt nur EINEN 3-Grad-Bogen gegenueber FLACH (0 Grad,
|
||||
`Vario_Bogen_auf_3`/`Vario_Bogen_ab_3`) - ein Wechsel zwischen der
|
||||
fallenden (+3) und der steigenden (-3) Basis braucht daher IMMER 1-2
|
||||
Boegen ueber 0 Grad als Zwischenhalt (`vfl-bogen-uebergang`, generischer
|
||||
Uebergangs-Helfer): 3 Grad Differenz = ein Bogen, 6 Grad Differenz (voll
|
||||
fallend -> voll steigend oder umgekehrt) = zwei Boegen.
|
||||
- `vfl-bogen-uebergang` wird sowohl VOR jeder normalen (fallenden) GF
|
||||
eingehaengt (falls der Vorgaenger noch steigend ist - No-Op, wenn schon
|
||||
passend) als auch VOR jeder Separator+ES-Element-Anhaengung ans
|
||||
Kettenende: **ES-Element-Hardware gibt es nur fuer die Anfahrt auf der
|
||||
Standard-Fallend-Basis** - kommt die Kette steigend an, wird zuerst
|
||||
automatisch zurueckgewandelt (siehe Abschnitt 6).
|
||||
|
||||
- **3 Grad** ist die kleinste im gesamten Projekt verfuegbare Neigung
|
||||
(`Vario_Bogen_auf_3` / `Vario_Bogen_ab_3`). Eine flachere GF gibt es nicht.
|
||||
|
||||
### Kurzsegment-Regel (deltaL < 1000 mm)
|
||||
- Ein VarioFoerderer braucht mindestens **1000 mm** deltaL, weil Umlenkstation
|
||||
(500 mm) + Motorstation (500 mm) diese Strecke bereits belegen. Unterhalb
|
||||
1000 mm ist kein VF baubar.
|
||||
- Ist deltaL < 1000 mm, wird das Segment **automatisch eine 3-Grad-geneigte
|
||||
Gefaellestrecke** (die kleinstmoegliche GF-Neigung).
|
||||
- Fuer solche Kurzsegmente wird die **Endpunkt-Hoehe NICHT abgefragt** - die
|
||||
Hoehe ergibt sich fest aus `deltaH = deltaL * tan(3 Grad)`.
|
||||
- Ein steigendes Kurzsegment ist nicht baubar (GF kann nicht steigen, VF kein
|
||||
Platz). Da fuer Kurzsegmente keine Hoehe abgefragt wird, entsteht dieser Fall
|
||||
im interaktiven Ablauf ohnehin nicht (immer fallend mit 3 Grad).
|
||||
- Beim VF-Fall (< 3 Grad Gefaelle) wird die Machbarkeit in dieser Reihenfolge
|
||||
geprueft:
|
||||
1. Horizontaler VarioFoerderer (`berechne-horizontale-mitte`),
|
||||
2. sonst diskreter Winkel 3-51 Grad (`berechne-alle-winkel`).
|
||||
- **Ein VarioFoerderer ist im Kern eine Kombination aus Foerderer und
|
||||
Gefaellestrecke** - deshalb greifen fuer die geneigten Anteile eines VF
|
||||
dieselben 3-Grad-Prinzipien.
|
||||
|
||||
---
|
||||
|
||||
## 4. Verfeinerter interaktiver Ablauf eines VF-Segments
|
||||
|
||||
Wird ein Linien-Segment als VF eingestuft, folgt diese Logik:
|
||||
|
||||
### 4.1 Frage: Ist der Endpunkt dieser Linie das Ende des Foerderers?
|
||||
|
||||
**JA (Foerderer-Ende):**
|
||||
- Es wird eine **Motorstation** gebaut (unabhaengig von Auf/Ab).
|
||||
- Der gewaehlte **Vertikalbogen** muss **denselben Winkel** wie der
|
||||
**vorherige Vertikalbogen** haben. Dadurch neigt sich der KS_AUS des
|
||||
Vertikalbogens um **3 Grad nach unten** - passend zur 3-Grad-Neigung der
|
||||
Motorstation.
|
||||
|
||||
**NEIN (kein Foerderer-Ende):**
|
||||
- Es wird **keine Motorstation** gebaut.
|
||||
- Stattdessen Frage: **Horizontalen Foerderer fortsetzen?**
|
||||
- Falls ja: eine weitere Linie **ohne Hoehendifferenz** zeichnen und einen
|
||||
**horizontalen VF-Abschnitt** bauen.
|
||||
- Nach dem horizontalen Foerderer folgt erneut eine 3-fache Auswahl
|
||||
(siehe 4.2).
|
||||
|
||||
### 4.2 Auswahl nach einem horizontalen Foerderer-Abschnitt
|
||||
|
||||
1. **Foerderer-Ende bauen**: einen **3-Grad-Bogen (auf oder ab)** einfuegen,
|
||||
sodass KS_AUS sich 3 Grad nach unten neigt, danach die **Motorstation**
|
||||
(die selbst 3 Grad geneigt ist).
|
||||
2. **Vario-Kurve einfuegen?** Falls ja: Winkel abfragen. Reihenfolge/Vorgabe:
|
||||
**90 / 60 / 30 Grad** (90 Grad auf Position 1 und als Standard, da am
|
||||
haeufigsten gebraucht).
|
||||
3. **Auf/Ab-Foerderer fortsetzen**: naechste Linie zeichnen, Endhoehe abfragen
|
||||
und pruefen, ob das das Foerderer-Ende ist (entscheidet, ob eine
|
||||
Motorstation gebaut wird - zurueck zu 4.1).
|
||||
|
||||
### 4.3 Rekursion
|
||||
Erreicht der Foerderer noch nicht das Ende, wird immer wieder gefragt, ob der
|
||||
horizontale Foerderer fortgesetzt werden soll (Schleife ueber 4.1 -> 4.2), bis
|
||||
schliesslich ein Foerderer-Ende (mit Motorstation) gesetzt wird.
|
||||
|
||||
### 4.4 Prompt "Ist der Endpunkt der Foerderer?" - drei Optionen
|
||||
|
||||
Der Prompt in der VF-Koerper-Schleife hat drei Optionen:
|
||||
1. **Ja (nur Motorstation setzen)** - VF-Einheit schliessen, Kette laeuft weiter
|
||||
(weiterer Foerderer/Motor moeglich, siehe Abschnitt 8).
|
||||
2. **Nein (weiterbauen)** - naechstes Koerper-Sub-Segment (zurueck zu 4.2).
|
||||
3. **Ja (Motorstation setzen, Kettenende definieren)** - siehe 4.5.
|
||||
|
||||
### 4.5 Option 3: Kettenende exakt am Zielpunkt definieren (ein Motor)
|
||||
|
||||
Deckt den Fall ab, dass **Start- und Endpunkt der Kette feststehen** und die
|
||||
Strecke - unter Nutzung von Horizontal-Stuecken/Vario-Kurven, aber mit **nur
|
||||
einem Motor** - genau am Ziel schliessen soll.
|
||||
|
||||
Ablauf (`vfl-body-abschluss` / `vfl-body-zerlegung`):
|
||||
1. Zielpunkt (XY, auf die Fahrtrichtung projiziert) + Zielhoehe (Z) abfragen.
|
||||
2. Der verbleibende **gerade** Lauf wird mit der bewaehrten Standard-Logik
|
||||
zerlegt (`berechne-alle-winkel` bzw. `berechne-horizontale-mitte`), aber mit
|
||||
**reduziertem Mid-Body-Budget**: der Einlauf (AS/GF1/Separator/Umlenk) ist
|
||||
schon gebaut, deshalb `aus-dx = aus-dz = 0` und festes Budget nur
|
||||
**Motor 500 + Auslauf-Separator 300 = 800 mm** (statt 1300).
|
||||
3. **GF2 variiert mit dem gewaehlten Winkel** (Winkeltabelle wie aussen, jede
|
||||
Zeile hat ihr eigenes L_GF) und sitzt **hinter dem Motor**. Die
|
||||
GF-Verteilungs-Frage (Abschnitt 9) wird fuer diesen GF2-Anteil ueberschrieben;
|
||||
Mindestwert `*vfl-gf-min-laenge*` (400 mm).
|
||||
4. **Hoehe** kommt aus gewinkeltem VF + GF2, die ueberschuessige **Laenge** aus
|
||||
einem horizontalen VF (flacher/langer Lauf).
|
||||
5. Abschluss automatisch: Motorstation -> GF2 -> Separator -> ES-Element.
|
||||
|
||||
Horizontale **Vario-Kurven** (XY-Richtungswechsel) bleiben **manuell** und werden
|
||||
von Option 3 nicht platziert - Option 3 baut nur den geraden Schluss.
|
||||
|
||||
**Ist-Ziel-Report:** Nach dem ES wird Soll (Zielpunkt) vs. Ist (ES-KS_AUS)
|
||||
ausgegeben (dX/dY/dZ). Ein `ES_Element_90` macht einen 90-Grad-Schwenk; sein
|
||||
KS_AUS liegt daher ~637 mm **seitlich** (dY) neben der Kettenachse. dX/dZ treffen
|
||||
das Ziel exakt - das dY ist der Fussabdruck des ES-Elements, **kein Fehler** (die
|
||||
Soll-Berechnung modelliert nur den geraden Lauf ohne den seitlichen ES-Versatz).
|
||||
|
||||
### 4.6 "Neue Linie BIS Kettenende" (Option 4/6): Startpunkt-Typ-Erkennung
|
||||
|
||||
Das Hauptmenue "Naechstes Element waehlen" bietet daneben eine EIGENE Option
|
||||
("Neue Linie BIS Kettenende (danach Separator + ES-Element)"), die IMMER mit
|
||||
Separator+ES-Element abschliesst, aber - anders als Option 3 oben - auch am
|
||||
echten Kettenanfang (allererster Klick der Session) aufgerufen werden kann.
|
||||
Damit sich die Bau-Logik dabei nicht blind auf die generische GF/VF-Automatik
|
||||
(Abschnitt 3) verlaesst, wird zuerst erkannt, ob der gewaehlte Startpunkt zu
|
||||
einer bestehenden VF- oder GF-Kette gehoert:
|
||||
|
||||
- **Laufende Fortsetzung** (ein Frame existiert schon in dieser Session):
|
||||
der Vorgaengertyp ist bereits bekannt (`letzter-typ`) - `"Vario-Kurve"`
|
||||
zaehlt zur VF-Familie, `"GF"`/`"Separator"` zur GF-Familie. `"VF"` (eine
|
||||
gerade FERTIG gebaute VF-Einheit) zaehlt bewusst NICHT zur VF-Familie fuer
|
||||
diesen Zweck - eine neue VF-Einheit direkt danach braucht trotzdem eine
|
||||
frische Umlenkstation (siehe unten).
|
||||
- **Echter Kettenanfang ohne AS-Element**: KS_AUS-Scan am gepickten Punkt
|
||||
(`vfl-ks-aus-hz-an-punkt`, dieselbe Erkennung wie in
|
||||
`vfl-eingang-modus-bestimmen`) - trifft der Punkt exakt auf das KS_AUS
|
||||
eines bestehenden Bausteins, wird dessen Typ uebernommen.
|
||||
|
||||
**VF-Familie erkannt** (kein eigener Umlenkstation-Bedarf, z.B. Fortsetzung
|
||||
einer Vario-Kurve): baut ueber `vfl-body-abschluss` + `vfl-vf-ausgang-bauen`
|
||||
- dieselben Bausteine wie Option 3 oben (800 mm Budget statt 1300, volle
|
||||
Stufe-1/2-Diagnose inkl. exakter Zielhoehe bleibt erhalten, da kein
|
||||
GF1-Stumpf noetig ist, dessen Wegfall die Loesung stoeren wuerde).
|
||||
|
||||
**GF-Familie erkannt** (Fortsetzung einer Gefaellestrecke): dieselbe
|
||||
Endpunkt-/Zielhoehe-Wahl wie "Neue Linie: GF" Zweig A/B (Abschnitt 3) statt
|
||||
der generischen Automatik - eine reine Gefaellestrecke kann nicht steigen.
|
||||
|
||||
**Nicht eindeutig zuordenbar** (z.B. frisch gesetztes AS-Element ohne
|
||||
erkennbaren Vorgaenger): unveraendert die generische Machbarkeits-Automatik
|
||||
(`vfl-segment-entscheidung`, Abschnitt 3).
|
||||
|
||||
---
|
||||
|
||||
## 5. Separator-Regeln
|
||||
|
||||
Ein Separator (300 mm) wird eingefuegt:
|
||||
- am **Ende jeder Gefaellestrecke (GF)**, und
|
||||
- **vor jedem Gefaellebogen**.
|
||||
|
||||
### Basis-Regel (keine Verdopplung)
|
||||
Da nach einer GF nur ein GF-Bogen oder eine neue Linie folgen darf, fallen die
|
||||
beiden obigen Regeln an einer direkten **GF -> Gefaellebogen**-Verbindung auf
|
||||
**dieselbe Nahtstelle**. Dort wird nur **EIN** Separator eingefuegt (nicht zwei
|
||||
- kein Separator "am GF-Ende" zusaetzlich zu einem Separator "vor dem Bogen").
|
||||
Ein Separator sitzt also genau einmal an der Grenze zwischen GF und
|
||||
Gefaellebogen.
|
||||
|
||||
### Separator im LINIENZUG (Platzierung)
|
||||
Damit zwischen einem AS und ES **mehrere Foerderer (Motoren)** liegen koennen,
|
||||
wurde der Separator vom VF-Ausgang geloest:
|
||||
- **Direkt hinter Motorstation/GF2: KEIN Separator** (`vfs-vf-exit` wird mit
|
||||
`mit-separator=nil` aufgerufen).
|
||||
- **Am Kettenende (Ja):** Separator (300 mm) + ES-Element werden zusammen
|
||||
gesetzt (`vfl-insert-es-element`).
|
||||
- **Bei "kein Kettenende" (Nein):** es wird gefragt, ob an dieser Stelle ein
|
||||
**zusaetzlicher Separator** eingefuegt werden soll (`vfl-insert-separator`);
|
||||
danach geht es mit dem naechsten Element weiter (neuer Foerderer moeglich).
|
||||
- Der Standard-/Etage-VF (nicht Linienzug) behaelt den Separator direkt hinter
|
||||
GF2 (`mit-separator=t`).
|
||||
|
||||
### Separator am horizontalen Stueck (0 Grad)
|
||||
Wird VOR/NACH einem horizontalen Stueck ein Separator gewuenscht, liegt er in der
|
||||
**horizontalen Ebene (0 Grad)** - also ZWISCHEN den beiden Vertikalboegen
|
||||
(`auf_3` ... `ab_3`), nicht auf der 3-Grad-Basis davor/danach. Umgesetzt in
|
||||
`vfl-sep-hz` (Einfuegung bei 0 Grad). Der optionale **Zwischen-Separator**
|
||||
zwischen zwei Foerderern sitzt dagegen auf der 3-Grad-Basis (`vfl-insert-separator`).
|
||||
|
||||
---
|
||||
|
||||
## 6. Vertikalbogen-Regeln
|
||||
|
||||
- Der Vertikalbogen am **Ende** eines VF (vor der Motorstation) hat **denselben
|
||||
Winkel** wie der Vertikalbogen am **Anfang** (nach der Umlenkstation).
|
||||
- Der abschliessende Vertikalbogen bringt die Strecke auf **3 Grad Neigung nach
|
||||
unten**, damit der Anschluss an die (3 Grad geneigte) Motorstation passt.
|
||||
|
||||
### Bogen-Blockname vs. Konsolen-Rotationsanzeige der Geraden (KEIN Fehler)
|
||||
Beim Bau (`vfs-vf-koerper`) zeigt die Konsole fuer einen S-Bogen mit
|
||||
Tabellenwinkel z.B. 18 Grad folgendes Muster:
|
||||
```
|
||||
5/11: Vario_Bogen_auf_18_TEF_rechts (3 Grad geneigt)
|
||||
6/11: Steigungsstrecke (-15 Grad, L=... mm)
|
||||
7/11: Vario_Bogen_ab_18_TEF_rechts (-15 Grad geneigt)
|
||||
```
|
||||
Die **Bogen-Bloecke** (`auf_18`/`ab_18`) tragen den ECHTEN, gewaehlten
|
||||
Tabellenwinkel im Namen - das ist der massgebliche Wert (auch fuer
|
||||
`Vario_Kette_Merge`s `VF_WINKEL`-Attribut, das ihn direkt aus dem Blocknamen
|
||||
liest). Die **Gerade dazwischen** wird dagegen mit `winkel-eff = best-winkel -
|
||||
3` inseriert (hier 18-3=15, negativ fuer "Auf") - NICHT mit dem vollen
|
||||
Tabellenwinkel. Grund: der Eintrittsbogen hat den Frame bereits von der
|
||||
3-Grad-Basis auf den vollen Winkel (18 Grad) gedreht; die Gerade wird relativ
|
||||
zu diesem BEREITS gedrehten Frame eingefuegt und muss deshalb nur noch die
|
||||
DIFFERENZ zur Basis nachdrehen. In Weltkoordinaten liegt die Gerade trotzdem
|
||||
exakt bei 18 Grad - die "-15" ist eine reine Bau-interne Rotationsangabe,
|
||||
kein zweiter, abweichender Winkel. Bestaetigt durch den Ist-Ziel-Report
|
||||
(dX/dZ exakt) - waeren beide Werte real unterschiedliche Winkel, koennte das
|
||||
Ergebnis nicht exakt stimmen.
|
||||
|
||||
### Flache Zone (horizontale Stuecke bleiben flach - Uebergang spaeter)
|
||||
Ein horizontales Stueck endet **NICHT** mehr automatisch mit `ab_3` auf der
|
||||
3-Grad-Basis, sondern bleibt **flach (0 Grad)**:
|
||||
- Der `auf_3`-Eintritt wird nur gesetzt, wenn der Frame noch **nicht** flach ist
|
||||
(sonst bleibt die laufende flache Zone erhalten).
|
||||
- Der `ab_3`-Uebergang zurueck auf 3 Grad kommt **erst dann**, wenn ein echtes
|
||||
3-Grad-Element folgt: Motorstation, Auf/Ab-Koerper oder Option-3-Abschluss
|
||||
(`vfl-nach-3grad`).
|
||||
- Die aktuelle Neigung wird direkt aus dem Frame gelesen (`vfl-frame-flach-p`,
|
||||
Schwelle 1,5 Grad).
|
||||
|
||||
Vorteil: aufeinanderfolgende horizontale Elemente (Strecken, Separatoren,
|
||||
Vario-Kurven) bleiben **durchgehend flach** - kein unnoetiges 3->0->3-Gezappel.
|
||||
Die VF-Einheit als Ganzes endet weiterhin auf 3-Grad-Basis (der Guard vor der
|
||||
Motorstation stellt das sicher), sodass die aeussere Kette unveraendert
|
||||
3-Grad-basiert bleibt.
|
||||
|
||||
### ES-Element/Umlenkstation brauchen die Standard-Fallend-Basis
|
||||
Separator+ES-Element (Kettenende) UND eine Umlenkstation (VF-Einheit-Start)
|
||||
gibt es hardwareseitig nur fuer die Anfahrt auf der Standard-Fallend-Basis
|
||||
(+3 Grad) - eine Anfahrt auf der steigenden Basis (-3 Grad, siehe Abschnitt 3
|
||||
"Steigende GF") ist physisch nicht vorgesehen. Vor beiden Anhaengepunkten wird
|
||||
deshalb `vfl-bogen-uebergang` (Ziel = die Standard-Fallend-Basis) eingehaengt
|
||||
- bei einer bereits fallenden Ankunft ist das ein No-Op, bei einer steigenden
|
||||
Ankunft werden automatisch die noetigen 1-2 Ausgleichsboegen eingefuegt.
|
||||
|
||||
### Motorstation-Seite
|
||||
- Jede Motorstation hat eine **Seite** (links/rechts). Aktuell existiert nur die
|
||||
**rechts**-DWG (`Vario_Motorstation_500mm`), daher wird derzeit immer "rechts"
|
||||
verwendet und im Attribut `MOTORSEITE` (kommagetrennt je Motorstation)
|
||||
festgehalten. Die "links"-Einzel-DWG wird spaeter ergaenzt.
|
||||
|
||||
---
|
||||
|
||||
## 7. 20-Meter-Regel (Motorstation)
|
||||
|
||||
- Ueberschreitet die **Gesamtlaenge der VF-Segmente nach einer Umlenkstation
|
||||
20 m**, erscheint der Hinweis:
|
||||
**"Foerderer laenger als 20 m - Motorstation einfuegen?"**
|
||||
|
||||
---
|
||||
|
||||
## 8. Uebergangsregeln zwischen Elementen
|
||||
|
||||
- Vario-Kurven werden **innerhalb** einer VF-Einheit behandelt (im
|
||||
Foerderer-Ende-Ablauf, Abschnitt 4), nicht auf Ketten-Ebene.
|
||||
- Nach einem **GF-Segment ODER einer abgeschlossenen VF-Einheit** (beide enden
|
||||
auf 3-Grad-Neigung) darf als naechstes ein **GF-Bogen** oder eine **neue
|
||||
Linie** folgen. Nur am Kettenanfang folgt direkt eine neue Linie.
|
||||
- Bei Boegen/Kurven ist **keine Hoehenabfrage** noetig (die Hoehe ergibt sich
|
||||
aus der Bogen-/Kurvengeometrie). Bei Linien wird die Endhoehe abgefragt (Aus-
|
||||
nahme: Kurzsegment < 1000 mm, siehe Abschnitt 3).
|
||||
|
||||
### Mehrere Foerderer (Motoren) je Kette
|
||||
Zwischen **einem** AS und **einem** ES koennen **mehrere VF-Einheiten** liegen
|
||||
(jede mit eigener Umlenk- und Motorstation). Nachdem eine VF-Einheit mit der
|
||||
Motorstation geschlossen ist und "kein Kettenende" gewaehlt wurde, kann die
|
||||
Kette (optional mit Zwischen-Separator) mit einem GF-Bogen oder einer neuen
|
||||
Linie weitergebaut werden - ist die neue Linie wieder ein VF, entsteht eine
|
||||
weitere VF-Einheit (weiterer Motor). Die Motorenzahl/-seiten stehen im Attribut
|
||||
`MOTORSEITE`.
|
||||
|
||||
### Fahrtrichtung folgt dem Vorgaengerelement
|
||||
Eine gerade Foerderstrecke kann die Fahrtrichtung nicht aendern - das geht nur
|
||||
ueber einen GF-Bogen bzw. eine Vario-Kurve. Beim Zeichnen einer neuen Linie
|
||||
wird der gewaehlte Punkt daher auf die aktuelle Fahrtrichtung **projiziert**
|
||||
(`vfl-neue-linie-messen`); nur das allererste Segment definiert die Richtung
|
||||
frei. Auch die Start-Z-Hoehe der Kette wird abgefragt.
|
||||
|
||||
---
|
||||
|
||||
## 9. GF-Verteilung (Staustrecke: Einlauf / Ausgang)
|
||||
|
||||
Pro VF-Einheit wird gefragt, wie die Staustrecke (L_GF) verteilt wird:
|
||||
- **1** - halbe Staustrecke als **GF2 am Ausgang**, halbe als **GF1 am Einlauf**.
|
||||
- **2** - **gesamte** Staustrecke am **Einlauf** (GF1), kein GF2.
|
||||
|
||||
- Mindest-Gesamt-Staustrecke (GF1+GF2) = `*vfl-gf-min-laenge*` (Vorgabe **400 mm**);
|
||||
faellt das berechnete L_GF darunter, wird angehoben.
|
||||
- Hinter GF2 folgt **nie** direkt ein Separator (siehe Abschnitt 5).
|
||||
|
||||
---
|
||||
|
||||
## 10. Laengenbudget & FESTE_HORIZONTAL
|
||||
|
||||
`berechne-alle-winkel` zieht das horizontale Budget der festen Elemente von
|
||||
deltaL ab (`FESTE_HORIZONTAL`):
|
||||
- **Standard-/Etage-VF:** `FESTE_HORIZONTAL = 1600` mm
|
||||
(Umlenk 500 + Motor 500 + **2** Separatoren 300).
|
||||
- **Linienzug:** `*vfl-feste-horizontal* = 1300` mm
|
||||
(Umlenk 500 + Motor 500 + **1** Separator am Einlauf 300; der Ausgangs-
|
||||
Separator entfaellt). Wird als optionaler 4. Parameter an
|
||||
`berechne-alle-winkel` uebergeben.
|
||||
|
||||
> Offen: Bei mehrsegmentigen VF-Einheiten rechnet `berechne-alle-winkel` je
|
||||
> Sub-Segment mit eigener Entry/Exit-Annahme - der reale Fussabdruck kann
|
||||
> abweichen (empirisch pruefen).
|
||||
|
||||
---
|
||||
|
||||
## 11. Bedienung
|
||||
|
||||
- Alle Ja/Nein- und Auswahl-Abfragen sind **zahlenbasiert** (1/2 bzw. 1/2/3),
|
||||
keine Buchstaben.
|
||||
- **Winkelauswahl:** Gibt es fuer einen VF mehrere gueltige Winkel, listet das
|
||||
System sie (mit L_GF/L_VF) und der Nutzer waehlt (`vfl-waehle-winkel`).
|
||||
- Beim Start wird die **Z-Hoehe des Kettenstartpunkts** abgefragt.
|
||||
- **Lueckenlose Nummerierung** im Prompt "Naechstes Element waehlen": der
|
||||
GF-Bogen ist nur mit vorhandenem Frame Option 1; ohne Frame ruecken die
|
||||
uebrigen Optionen auf 1/2/3 auf (keine Luecke wie frueher 2/3/4).
|
||||
- **Vario-Kurve-Winkel:** Reihenfolge 90 / 60 / 30 Grad, 90 Grad ist Standard.
|
||||
- **GF-Verteilungstext:** "1 - 1/2GF am Ausgang (GF2), 1/2GF am Einlauf (GF1)".
|
||||
|
||||
---
|
||||
|
||||
## 12. Block-Attribute (TYP = "Streckengruppe")
|
||||
|
||||
Der Linienzug erzeugt EINEN Block `VF_<Nr>` mit der vollen Attributstruktur
|
||||
(analog Standard/Etage-VF), aber mit **segmentweisen, kommagetrennten** Werten.
|
||||
Zwei parallele Segment-Achsen:
|
||||
- **VF-Sub-Segmente:** `L_VF_m` <-> `WINKEL` <-> `ANTRIEBFAHRTRICHTUNG`
|
||||
- **GF-Segmente:** `L_GF_m` <-> `GF_WINKEL`
|
||||
|
||||
| Attribut | Inhalt |
|
||||
|---|---|
|
||||
| `NUMMER` | fortlaufende VF-Nummer |
|
||||
| `ID` | aufsteigende, eindeutige ID (`ssg-id-generate`, wie Kreisel) |
|
||||
| `TYP` | `"Streckengruppe"` |
|
||||
| `MONTAGEHOEHE_m` | mittlere Hoehe (m) |
|
||||
| `HOEHE_VON` / `HOEHE_BIS` / `DELTA_H` | Start-/End-/Differenzhoehe (mm) |
|
||||
| `DELTA_L` | planare Gesamtdistanz Start->Ende (mm) |
|
||||
| `L_VF_m` | Laenge je VF-Sub-Segment (m), kommagetrennt |
|
||||
| `WINKEL` | Vertikalbogen-Winkel je VF-Sub-Segment (0 = horizontal), kommagetrennt |
|
||||
| `ANTRIEBFAHRTRICHTUNG` | `Auf`/`Ab`/`horizontal` je VF-Sub-Segment, kommagetrennt |
|
||||
| `L_GF_m` | Laenge je GF-Segment **inkl. GF1/GF2** (m), kommagetrennt |
|
||||
| `GF_WINKEL` | Neigung je GF-Segment (Grad), parallel zu `L_GF_m`, kommagetrennt |
|
||||
| `MOTORSEITE` | Seite je Motorstation (`rechts`/`links`), kommagetrennt |
|
||||
| `ANZAHL_SEGMENTE` / `ANZAHL_GF` / `ANZAHL_VF` | Segmentzaehler |
|
||||
| `SEITE` | AS-Seite (links/rechts) |
|
||||
| `GF_Bogen_L_90/60/30`, `GF_Bogen_R_90/60/30` | Anzahl GF-Boegen je Seite + Winkel (je eigenes Attribut) |
|
||||
| `VF_Bogen_A_90/60/30`, `VF_Bogen_I_90/60/30` | Anzahl Vario-Kurven je Variante (A=aussen/I=innen) + Winkel (je eigenes Attribut) |
|
||||
|
||||
Gefuellt werden diese Werte ueber Akkumulatoren (`vfl-acc-*`), die waehrend des
|
||||
Baus in Reihenfolge angehaengt bzw. hochgezaehlt werden.
|
||||
|
||||
---
|
||||
|
||||
## 13. Umsetzungsstand & bekannte Abweichungen
|
||||
|
||||
Stand `vf_linienzug.lsp` (Modus 1).
|
||||
|
||||
### Umgesetzt
|
||||
- **Kettenstruktur** (Abschnitt 1): AS am Anfang, ES am Ende, EIN Block je Kette.
|
||||
- **GF/VF-Entscheidung** (Abschnitt 3): `vfl-segment-entscheidung` - reine GF
|
||||
nur ~3 Grad, steiler VF-ab, flacher VF; Kurzsegment < 1000 mm -> 3-Grad-GF
|
||||
ohne Hoehenabfrage.
|
||||
- **VF-Einheit, mehrsegmentig** (Abschnitt 2/4): `vfl-vf-einheit` baut Entry
|
||||
(Umlenkstation) einmal, dann beliebig viele Koerper-Sub-Segmente +
|
||||
Vario-Kurven, dann Exit (Motorstation) einmal. Bausteine in `vf_standard.lsp`:
|
||||
`vfs-vf-entry` / `vfs-vf-koerper` / `vfs-vf-exit`.
|
||||
- **Mehrere Foerderer (Motoren) je Kette** (Abschnitt 8): nach einer VF-Einheit
|
||||
kann (optional mit Zwischen-Separator) weitergebaut werden.
|
||||
- **Foerderer-Ende-Abfrage + horizontale Fortsetzung + Vario-Kurve** (Abschn. 4).
|
||||
- **Vertikalbogen-Winkelgleichheit** (Abschnitt 6): jeder Koerper faengt/endet
|
||||
auf 3-Grad-Basis.
|
||||
- **20-m-Regel** (Abschnitt 7): `vfl-20m-check` gibt den Hinweis aus.
|
||||
- **GF-Verteilung waehlbar** (Abschnitt 9): ½ am Ausgang (GF2) oder alles am
|
||||
Einlauf; Mindest-GF `*vfl-gf-min-laenge*` = 400 mm.
|
||||
- **Separator-Platzierung** (Abschnitt 5): kein Separator hinter Motorstation/
|
||||
GF2; Separator + ES am Kettenende bzw. optionaler Zwischen-Separator.
|
||||
`vfs-vf-exit` mit `mit-separator=nil` (Linienzug) bzw. `t` (Standard-VF).
|
||||
- **FESTE_HORIZONTAL = 1300** im Linienzug (Abschnitt 10).
|
||||
- **Fahrtrichtung folgt dem Vorgaenger** (Projektion), Start-Z-Abfrage (Abschn. 8/11).
|
||||
- **Winkelauswahl** bei mehreren gueltigen Winkeln (Abschnitt 11).
|
||||
- **Zahlenbasierte Menues** (Abschnitt 11).
|
||||
- **ID-Vergabe** (`ssg-id-generate`) fuer Linienzug-, Standard-/Etage-VF- und
|
||||
Gefaellestrecke-Bloecke.
|
||||
- **Volle Block-Attribute** (Abschnitt 12): TYP="Streckengruppe", segmentweise
|
||||
L_VF_m/L_GF_m/GF_WINKEL/ANTRIEBFAHRTRICHTUNG/WINKEL, MOTORSEITE, GF_Bogen_*/
|
||||
VF_Bogen_*-Zaehler.
|
||||
- **Option 3 "Kettenende definieren"** (Abschnitt 4.5): Mid-Body-Zerlegung mit
|
||||
reduziertem Budget (800), GF2 variiert mit Winkel (min 400), gewinkeltes +
|
||||
horizontales VF, Auto-Abschluss (Motor->GF2->Separator->ES), Ist-Ziel-Report.
|
||||
- **Flache Zone** (Abschnitt 6): horizontales Stueck endet flach, `ab_3` erst vor
|
||||
einem 3-Grad-Element (`vfl-nach-3grad` / `vfl-frame-flach-p`).
|
||||
- **Horizontale Separatoren** (Abschnitt 5): Separator am horizontalen Stueck in
|
||||
der 0-Grad-Ebene (`vfl-sep-hz`).
|
||||
- **Menue-Nummerierung lueckenlos** + **Vario-Kurve 90/60/30** (Abschnitt 11).
|
||||
- **Regressionstest `TEST_LINIENZUG`** (in `tests/test_linienzug.lsp`, Skript aus
|
||||
`tests/testdata/linienzug_tests.json`): spielt eine reale Session per
|
||||
Eingabe-Mock ab (getpoint/getstring/getint/getreal), laesst den echten
|
||||
`vf-linienzug-modus` durchlaufen. Punkt-Abfragen laufen ueber den
|
||||
verhaltensneutralen Wrapper **`vfl-getpoint`** (feste 2-Arity), damit der Mock
|
||||
greift. Zusaetzlich `TEST_LINIENZUG_STUFE2` (`linienzug_tests_stufe2.json`,
|
||||
siehe `doc/vf_linienzug_modus1_anleitung.md`) fuer den Stufe-2-Fallback am
|
||||
Kettenende.
|
||||
- **Steigende GF (Sonderfall, bis 3 Grad)** (Abschnitt 3): eigener Zweig C in
|
||||
"Neue Linie: GF" (`gf-laenge-modus="3"`), `vfl-bogen-uebergang` als
|
||||
genereller Uebergangs-Helfer zwischen Basis-Neigungen (auch in Zweig A/B
|
||||
eingehaengt, falls der Vorgaenger steigend war).
|
||||
- **"Neue Linie BIS Kettenende" erkennt VF-/GF-Startpunkt** (Abschnitt 4.6):
|
||||
`vfl-ks-aus-hz-an-punkt`/`letzter-typ`-basierte Familien-Erkennung,
|
||||
VF-Familie baut ueber `vfl-body-abschluss` + `vfl-vf-ausgang-bauen` (wie
|
||||
Option 3), GF-Familie ueber dieselbe Endpunkt-/Zielhoehe-Wahl wie "Neue
|
||||
Linie: GF".
|
||||
- **Abbruch-Trigger vollstaendig** (`vfl-in-value`/`-value-p`): ein per
|
||||
Wizard-Dialog gesetztes Abbruch-Flag wird jetzt auch von den Funktionen mit
|
||||
eigener Replay-/Pending-Logik erkannt (`vfl-in-abstand`, `vfl-in-selection`)
|
||||
- vorher konnte ein Dialog-Abbruch dort auf einen rohen `getpoint` statt auf
|
||||
Terminierung zurueckfallen.
|
||||
|
||||
### Noch offen / zu pruefen (bitte in BricsCAD verifizieren)
|
||||
1. **Laengen-Budget** bei mehrsegmentigen VF-Einheiten (Abschnitt 10) -
|
||||
empirisch nachmessen.
|
||||
2. **20-m-Regel** nur Hinweis, noch keine automatische Zwischen-Motorstation.
|
||||
3. **Knick-Risiko** am Uebergang GF-Segment -> VF-Einheit (Entry startet immer
|
||||
bei 3 Grad).
|
||||
4. **AS-/ES-Fusspunkte** (`aus-dx` / `ein-dx`) werden nicht von der Segmentlaenge
|
||||
abgezogen (anders als in `gf-linienzug-modus`).
|
||||
5. **"Neue Linie BIS Kettenende" bei erkannter VF-Familie MIT Umlenkstation**
|
||||
(letzter-typ="VF", eine gerade fertig gebaute VF-Einheit, oder ein per
|
||||
KS_AUS erkannter reiner Umlenk-/Motor-/Bogen-Typ am Kettenanfang): faellt
|
||||
bewusst auf die generische Automatik zurueck (Abschnitt 4.6) - noch NICHT
|
||||
live in BricsCAD getestet.
|
||||
6. **Regressionstests noch nicht nachgezogen**: keiner der Tests
|
||||
(`test_linienzug.lsp`, `test_vf_spec.lsp`/`.py`) deckt bisher die neuen
|
||||
Punkte oben ab (Steigende GF, Kettenende-Familien-Erkennung,
|
||||
Abbruch-Trigger-Fix) - nur manuell in BricsCAD verifiziert.
|
||||
7. **Modus 3** (`vf-linienzug-modus3`, Vorwaerts-Nachbau, siehe Eingabemodi in
|
||||
Abschnitt 1): Grundgeruest gebaut (GF-Kette + VF-Laeufe per
|
||||
Run-State-Machine, AS-Querschub auf Pfad). Offen: Laengen-Reservierung am
|
||||
Kettenende (Exit-Fussabdruck ueberschiesst). Kann eine vorgegebene
|
||||
Endpunkt-Hoehe NICHT treffen - dafuer ist Modus 2 vorhanden (Abschnitt 14).
|
||||
8. **Option-3 Ist-Ziel-Report**: die Soll-Berechnung modelliert nur den geraden
|
||||
Lauf und beruecksichtigt den **seitlichen Versatz des ES_Element_90** nicht
|
||||
(dY ~ 637 mm ist erwartet, kein Fehler). dX/dZ treffen exakt. Zwei bekannte
|
||||
Naeherungen koennten dennoch kleine Restabweichungen erzeugen: der
|
||||
Eintrittsbogen wird mit 3-Grad-Basis gerechnet (Sonderfall: Start nach einer
|
||||
horizontalen Vario-Kurve), und GF2 wird bei < 400 mm auf das Minimum
|
||||
angehoben. Bei Bedarf empirisch nachjustieren.
|
||||
|
||||
### Geloest
|
||||
- **Vario-Kurve-Bloecke** (`data/ils/3D/Vario_Kurve_*`): fuehren ihre KS als
|
||||
`KSYS_EIN`/`KSYS_AUS` (statt `KS_EIN`/`KS_AUS`); `extract-ks-from-block-raw`
|
||||
normalisiert beide ueber `ks-normalize-name` - die Kurven docken korrekt an.
|
||||
- **Versatz Separator/ES** (Bild-Befund): Ursache war das erzwungene Z-Ziel von
|
||||
`insert-block-mixed-to-ks` (setzt ES-KS_AUS auf eine feste Hoehe - sinnvoll im
|
||||
Standalone-Gefaelle mit vorgegebener Endhoehe, aber falsch im frei auslaufenden
|
||||
Linienzug). Der Linienzug-ES wird jetzt rein per **KS-zu-KS**
|
||||
(`insert-block-ks-to-ks`) an den Separator angekettet - ES-KS_EIN folgt exakt
|
||||
dem Separator-Ausgang, kein Z-Ziel -> Versatz behoben (in BricsCAD gegenpruefen).
|
||||
- **Vario-Kurve war 3 Grad geneigt**: der uebergebene Frame trug die
|
||||
3-Grad-Basisneigung. Die Kurve wird jetzt auf einem abgeflachten Frame (0 Grad)
|
||||
eingefuegt (horizontaler Richtungswechsel).
|
||||
|
||||
---
|
||||
|
||||
## 14. Modus 2: Pfad + Ziel-Hoehe (Randwert-Solver)
|
||||
|
||||
> **Hinweis zur Nummerierung:** Dieser Solver ist im finalen Menue **Modus 2**
|
||||
> (Befehl waehlt intern `vf-linienzug-modus2`); Modus 3 ist der aeltere
|
||||
> Vorwaerts-Nachbau (`vf-linienzug-modus3`, siehe Eingabemodi in Abschnitt 1
|
||||
> und Abschnitt 13 Punkt 7).
|
||||
>
|
||||
> Die internen Helfer trugen bis 2026-10-22 die Praefixe `vfl3-`/`vfl2-` aus
|
||||
> einer frueheren Planungsphase - und zwar GENAU VERTAUSCHT zur endgueltigen
|
||||
> Menue-Zuordnung. Sie heissen jetzt nach ihrer ROLLE statt nach einer
|
||||
> Modus-Nummer:
|
||||
>
|
||||
> | Praefix | Rolle | genutzt von |
|
||||
> |---|---|---|
|
||||
> | `vfl-zsolve-*` (frueher `vfl3-*`) | rechnet die Hoehen (Z) durch | nur Modus 2 |
|
||||
> | `vfl-pfad-*` (frueher `vfl2-*`) | arbeitet auf dem gezeichneten Pfad (Eckwinkel, AS einfuegen, VF oeffnen/schliessen) | Modus 2 **und** Modus 3 |
|
||||
>
|
||||
> Eine Modus-Nummer war fuer die zweite Gruppe ohnehin nicht richtig
|
||||
> vergebbar, weil drei dieser Funktionen von beiden Modi benutzt werden.
|
||||
|
||||
Modus 3 (Vorwaerts-Nachbau) kann eine vorgegebene Endpunkt-Hoehe nicht treffen,
|
||||
weil er die Kette Segment fuer Segment vorwaerts baut - die Endhoehe ist nur ein
|
||||
Ergebnis (Anfangswertproblem / initial value problem). Modus 2 loest stattdessen
|
||||
ein Randwertproblem (boundary value problem): Start UND Ziel (je X,Y,Z) sind
|
||||
bekannt, die Zwischenhoehen werden gerechnet.
|
||||
|
||||
### 14.0 Grundprinzip (zwei getrennte Probleme)
|
||||
- XY = gezeichneter Pfad, reine KS-Kettung (wie Modus 3, mm-Drift akzeptiert).
|
||||
- Z = wird gerechnet, sodass das Kettenende die Ziel-Hoehe EXAKT trifft.
|
||||
Ablauf in zwei Phasen: erst planen (alle Hoehen durchrechnen), dann bauen.
|
||||
|
||||
### 14.1 Entkopplung Neigung <-> XY
|
||||
Die Neigung eines Teils aendert seine Hoehe (Z), aber nicht seinen
|
||||
XY-Fussabdruck: ein Staustrecken-Teil mit Planlaenge L belegt in der Draufsicht
|
||||
immer L (die 3D-Laenge waechst mit L/cos(w), die Projektion bleibt L). Deshalb
|
||||
lassen sich Z-Ziel und Pfadtreue unabhaengig loesen.
|
||||
|
||||
### 14.2 GF-Rollen
|
||||
- GF1/GF2 INNERHALB einer VF-Einheit: fest 3 Grad, Laenge variabel (Ausgleich).
|
||||
- Eigenstaendige GF-Laeufe: Neigung per Eingabe (wie Modus 3, Vorgabe 3 Grad).
|
||||
|
||||
### 14.3 VF-Bruecke = Standard-VF-Einheit
|
||||
Jede VF-Strecke im Pfad ist eine Standard-VF-Einheit ohne eigene AS/ES:
|
||||
GF1 + Separator + Umlenkstation + Vario-Koerper + Motorstation + GF2. Alle Teile
|
||||
liegen kolinear auf derselben Pfad-Geraden; variieren ihre Laengen, verschieben
|
||||
sich nur die inneren Grenzen, die Bruecken-Enden bleiben fix. Pro Bruecke ein
|
||||
2-Gleichungs-System:
|
||||
- Summe der Planlaengen = gezeichnete Spannweite (aus dem Pfad)
|
||||
- Summe der Hoehenaenderung = delta-H zwischen den Ankern
|
||||
Freie Variablen: Vario-Winkel (diskret) + GF1-Laenge + GF2-Laenge. Das loest der
|
||||
vorhandene Modus-1-Solver (berechne-alle-winkel / berechne-horizontale-mitte).
|
||||
|
||||
### 14.4 Anker rechnen (Zwei-Anker / shooting)
|
||||
- Front-Anker: Z von AS vorwaerts durch alle fuehrenden deterministischen Teile
|
||||
(GF-Geraden mit Eingabe-Winkel + GF-Boegen) bis zur ersten VF-Bruecke.
|
||||
- Rueck-Anker (Junction): Z_Ende RUECKWAERTS durch alle nachlaufenden
|
||||
deterministischen Teile - reine Rechnung, kein Rueckwaerts-Bauen.
|
||||
- delta-H_Bruecke = Z_Front - Z_Junction; Spannweite = Pfad-Planlaenge der
|
||||
VF-Strecke (minus Fussabdruck etwaiger Vario-Kurven darin).
|
||||
|
||||
### 14.5 Ecken in der Hoehen-Bilanz
|
||||
- GF-Bogen: Z-Drop aus der KS_EIN->KS_AUS-Z-Differenz des Blocks
|
||||
(Temp-Objekt + extract-ks-from-block, wie insert-block-mixed-to-ks).
|
||||
- Vario-Kurve: auf 0 Grad geflacht -> delta-Z ~ 0 (verifizieren).
|
||||
|
||||
### 14.6 Phasen
|
||||
Phase A (planen): Pfad waehlen; Start (X,Y,Z)+AS-Seite; Ende (X,Y,Z)+ES-Seite;
|
||||
sortieren/analysieren; Eck-Vorpruefung; Segmente klassifizieren (Ergebnis nur
|
||||
speichern); deterministische delta-Z; Anker rechnen; Bruecke loesen. Nicht
|
||||
loesbar -> Meldung + Abbruch.
|
||||
Phase B (bauen): vorwaerts, KS-Kettung; alle Bau-Primitive existieren bereits
|
||||
(vfl-pfad-as-gf-einfuegen, vfl-insert-gf-segment, vfl-insert-gf-bogen-block,
|
||||
vfl-pfad-vf-oeffnen / vfs-vf-koerper / vfl-pfad-vf-schliessen mit GELOESTEN Werten,
|
||||
vfl-insert-vario-kurve-block, vfl-insert-es-element, vfl-block-erstellen).
|
||||
|
||||
### 14.7 Machbarkeit (warum eine Bruecke "infeasibel" sein kann)
|
||||
Hoehen-Erhaltung (conservation of height): delta-H_gesamt = Z_Start - Z_Ende ist
|
||||
fest und wird aufgeteilt in Summe(deterministische GF+Boegen) + delta-H_Bruecke.
|
||||
Die deterministischen Anteile bestimmen die Benutzer-Winkel; der Rest muss die
|
||||
Bruecke ueber ihre feste Spannweite liefern.
|
||||
|
||||
WICHTIG - Vorzeichen ist nur Richtung, nicht Machbarkeit: Ein VF ist
|
||||
ANGETRIEBEN und kann STEIGEN und FALLEN (VF-Auf / VF-Ab). Eine reine GF kann nur
|
||||
fallen; steigen erzwingt daher immer VF (siehe Abschnitt 3).
|
||||
- delta-H_Bruecke > 0 -> Bruecke faellt -> VF-Ab.
|
||||
- delta-H_Bruecke < 0 -> Bruecke steigt -> VF-Auf (voellig gueltig, KEIN Fehler).
|
||||
|
||||
Infeasibel wird es nur ueber die MAGNITUDE: die noetige mittlere Neigung
|
||||
uebersteigt den Vario-Bereich (rund 3..51 Grad), oder die Spannweite fasst den
|
||||
Pflicht-Fussabdruck nicht (Separator 300 + Umlenk 500 + Motor 500 + min. GF1/GF2
|
||||
+ mind. 1 Vario-Koerper). Dann: saubere Meldung statt Fehlbau. Flachere GF-Winkel
|
||||
verschieben den Rest-delta-H der Bruecke.
|
||||
|
||||
### 14.8 Staffelung
|
||||
- M2a - EINE VF-Bruecke (GF ... VF ... GF): delta-H_Bruecke voll determiniert ->
|
||||
eindeutig loesbar. Erster Wurf (Fokus).
|
||||
- M2b - MEHRERE VF-Bruecken: die delta-H-Verteilung auf N Bruecken ist
|
||||
unterbestimmt; Regel: die fehlende Hoehe je Bruecke wird abgefragt. Spaeter.
|
||||
|
||||
### 14.9 Grenzen (bewusst)
|
||||
Z trifft die Ziel-Hoehe EXAKT (Solver). XY landet auf dem Pfad mit mm-Drift
|
||||
(reine KS-Kettung); der Endpunkt wird in XY nahe, nicht mathematisch exakt
|
||||
getroffen. Exakter XY-Endschluss = eigenes Inverse-Kinematik-Problem, das mit
|
||||
reiner KS-Kettung kollidiert - vorerst nicht Ziel.
|
||||
|
||||
### 14.10 Wiederverwendung
|
||||
Vorhanden: Pfad-Analyse (gf-sortiere-objekte / gf-analysiere-kette), Eck-Pruefung
|
||||
(vfl-pfad-eckwinkel-pruefen, geteilt mit Modus 3), Klassifizierung (aus Modus 3),
|
||||
alle Bau-Primitive, Bruecken-Solver (Modus 1). Neu (~mittel): delta-Z-Helfer
|
||||
(vfl-zsolve-gf-dz / vfl-zsolve-bogen-dz / vfl-zsolve-kurve-dz), Vorwaerts/Rueckwaerts-Z-
|
||||
Propagation, Endpunkt/ES-Setup, Zwei-Phasen-Orchestrierung
|
||||
(`vf-linienzug-modus2`).
|
||||
|
||||
### 14.11 Umsetzungsstand M2a (umgesetzt, in BricsCAD getestet)
|
||||
|
||||
**Ablauf (`vf-linienzug-modus2`):** Pfad waehlen; Start (X,Y,Z) + AS-Winkel(30/90)
|
||||
+ AS-Seite; Ende (X,Y,Z) + ES-Winkel + ES-Seite; sortieren/analysieren/Eck-Pruefung;
|
||||
Segmente klassifizieren; VF-Lauf finden; Phase B (bauen).
|
||||
|
||||
**Hoehe exakt (messen statt schaetzen):**
|
||||
- **Front-Anker** wird GEMESSEN: AS + Front-GF werden zuerst gebaut, dann die reale
|
||||
KS_AUS-Hoehe abgelesen (AS-Eigen-dz + Trimmung automatisch enthalten).
|
||||
- **Junction (Rueck-Anker)** exakt rueckwaerts vom Ziel gerechnet (`vfl-zsolve-rueckanker`:
|
||||
GF-Bogen bei Neigung, Separator, ES-dz).
|
||||
- **GF2** = kleine gemessene Feinkorrektur bis zur Junction -> **dZ = 0**.
|
||||
|
||||
**VF-Bruecke = Standard-Vario:** `berechne-alle-winkel` auf dem Kletter-Segment,
|
||||
GF-Verteilung feste-hz = 800/1300 + Hoehen-Anpassung fuer Motor/Uebergaenge. Bei
|
||||
mehreren gueltigen Winkeln waehlt der Nutzer (`vfl-waehle-winkel`).
|
||||
|
||||
**Vario-Kurve = mehrsegmentiger VF-Lauf (eine VF-Einheit):**
|
||||
- VF-Geraden + Vario-Kurven bilden EINEN Lauf (die Kurve unterbricht ihn nicht).
|
||||
- **Kletterer = GENAU EINE VF-Gerade: die laengste des Laufs.** Alle anderen
|
||||
werden **horizontal** (nur Anschluss). Verbindet also eine Vario-Kurve zwei
|
||||
VF-Geraden, wird die kuerzere flach gebaut und die laengere traegt die ganze
|
||||
Hoehe (Regel 2026-10-22).
|
||||
Grund: der Solver budgetiert EIN Kletterstueck mit EINEM Paar Vertikalboegen,
|
||||
der Bau setzt dieses Paar aber je Kletterer. Mit zwei Kletterern fehlten ein
|
||||
zweites Bogenpaar UND die Uebergaenge der zusaetzlichen flachen Zone im
|
||||
Laengenbudget - gemessen: erstes Segment 1355.9 mm zu lang, Kette insgesamt
|
||||
3185 mm zu lang, bei korrekter Hoehe (dZ -10.2 mm).
|
||||
Die frueher benutzte Schwelle `*vfl-min-climber-laenge*` (Vorgabe 3000) spielt
|
||||
fuer die Auswahl damit keine Rolle mehr.
|
||||
- **Flache Zone:** genau EIN `auf_3` rein, EIN `ab_3` raus; Kurve + horizontale
|
||||
Fueller sind bei 0 Grad DIREKT verbunden (keine Zwischen-Boegen).
|
||||
- **Horizontaler Fueller** gleicht die Restlaenge aus (dein „Laenge folgt").
|
||||
|
||||
**GF-Verteilung waehlbar:** 1 = alles am Einlauf (GF1); 2 = 1/2 GF1 + 1/2 GF2. Bei
|
||||
1/2/1/2 wird der im Kletter-Segment durch das halbe GF1 frei werdende Platz mit
|
||||
einem horizontalen Fueller-A in VF1 gefuellt; GF2 sitzt hinter dem Motor.
|
||||
|
||||
**AS/ES 30 oder 90 Grad waehlbar** (auch in Gefaellestrecke):
|
||||
- Abfrage `vf-frage-element-winkel` vor der Seite; Blockname
|
||||
`AS_Element_<30|90>_<seite>` / `ES_...`; Masse pro Wahl neu gesetzt
|
||||
(`vf-set-as-masse` / `vf-set-es-masse`) -> berechne/GF rechnen variantengerecht.
|
||||
- **AS-Schwenk GEMESSEN** (`vf-element-plan-turn`, KS_EIN.xu -> KS_AUS.xu), damit
|
||||
KS_AUS entlang hz zeigt - unabhaengig von der Bauform (30/90/gerade).
|
||||
|
||||
**AS/ES-Achs-Verankerung (Start-/Endpunkt liegen auf der KS-Achse):**
|
||||
- **AS:** Versatz ENTLANG der KS_EIN-Achse (statt senkrecht zum Pfad) -> KS_AUS
|
||||
auf dem Pfad UND Startpunkt auf der KS_EIN-Achse.
|
||||
- **erste GF-Trimmung:** echter AS-Fussabdruck entlang des Pfads aus dem realen
|
||||
KS_AUS (nicht Block-dx) -> GF-Bogen sitzt exakt auf der Ecke.
|
||||
- **ES:** letzte Fueller-Laenge so geloest (`vfl-zsolve-es-fueller` + `vf-element-ks-info`),
|
||||
dass der Endpunkt auf der ES-KS_AUS-Achse liegt (Spiegel der AS-Regel).
|
||||
|
||||
**Ergebnis (Test 30 und 90 Grad):** dZ = 0; Startpunkt auf AS-KS_EIN-Achse;
|
||||
Endpunkt auf ES-KS_AUS-Achse (Quer zur Achse ~0). Der Rest-Laengs-Wert ist die
|
||||
seitliche ES-Ausladung (Bauform), kein Fehler.
|
||||
|
||||
**Bekannte Rest-Abweichung (bewusst akzeptiert):** nach einem GF-Bogen driftet die
|
||||
Mittellinie ~einige mm vom gezeichneten Pfad (reine KS-Kettung: Folge-Teile haengen
|
||||
am Bogen-KS_AUS, nicht am gezeichneten Eckpunkt). Kein Re-Anchoring (Wunsch: Teile
|
||||
schliessen exakt aneinander).
|
||||
|
||||
### 14.12 Noch offen
|
||||
- **25-m-Regel** im Pfad-Modus (VF-Kette zu lang -> Motorstation als Einheitsende).
|
||||
- **M2b:** mehrere getrennte VF-Bruecken (delta-H-Verteilung abfragen).
|
||||
- Standard-VarioFoerderer (`vf_standard.lsp`) bleibt bei 90 Grad (bewusst).
|
||||
@@ -261,6 +261,10 @@
|
||||
"vfl-m3-lauf-anfang-opt-offen": "\n 3 - Ohne Umlenkstation (offener Anfang, spaeter fortsetzen/verschmelzen)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk": "\n 2 - Umlenkstation direkt (kein GF1/Separator)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk-gf1": "\n 1 - Umlenkstation mit GF1 + Separator",
|
||||
"vfl-m2-uebergang-bogen-fehlt": "Uebergangsbogen %1 fehlt in der Bogen-Tabelle - der Block ist nicht ladbar oder hat kein messbares KS. Der Lauf wird ohne seinen Laengenanteil gebaut und faellt dadurch um dessen Laenge zu lang aus.",
|
||||
"vfl-m2-eck-korrektur": "\n Eck-Korrektur %1 mm auf Segment %2 (gezeichneter Bogen gegen Fussabdruck des Eck-Bauteils).",
|
||||
"vfl-m2-abschluss-fussabdruck": "\n Abschluss-Fussabdruck %1 mm von Segment %2 abgezogen (Abschlussbogen + Motorstation stehen darauf).",
|
||||
"vfl-m2-as-fussabdruck": "\n AS-Fussabdruck %1 mm von Segment %2 abgezogen (das AS-Element steht selbst darauf).",
|
||||
"vfl-m2-anfang-wert-unbekannt": "Lauf-Anfang nicht lesbar: Kette %1 enthaelt den unbekannten Wert %2. Aufbau abgebrochen - eine geratene Anfangsvariante wuerde die Kette falsch neu bauen.",
|
||||
"vfl-m3-lauf-anfang-offen-hinweis": "\n Anfang bleibt bewusst offen - keine Umlenkstation/GF1/Separator gebaut, spaeter fortsetzen oder per Vario_Kette_Merge verbinden.",
|
||||
"vfl-m2-anfang-offen-gesperrt-zeile": "\n (nicht waehlbar - mit AS-Element braucht der Lauf eine Umlenkstation)",
|
||||
|
||||
@@ -261,6 +261,10 @@
|
||||
"vfl-m3-lauf-anfang-opt-offen": "\n 3 - No reversing station (open start, continue/merge later)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk": "\n 2 - Reversing station directly (no GF1/separator)",
|
||||
"vfl-m3-lauf-anfang-opt-umlenk-gf1": "\n 1 - Reversing station with GF1 + separator",
|
||||
"vfl-m2-uebergang-bogen-fehlt": "Transition bend %1 is missing from the bend table - the block cannot be loaded or has no measurable KS. The run is built without its length share and therefore comes out too long by that amount.",
|
||||
"vfl-m2-eck-korrektur": "\n Corner correction %1 mm on segment %2 (drawn arc versus footprint of the corner component).",
|
||||
"vfl-m2-abschluss-fussabdruck": "\n Closing footprint %1 mm deducted from segment %2 (closing bend + motor station sit on it).",
|
||||
"vfl-m2-as-fussabdruck": "\n AS footprint %1 mm deducted from segment %2 (the AS element sits on it).",
|
||||
"vfl-m2-anfang-wert-unbekannt": "Cannot read run start: chain %1 contains the unknown value %2. Build aborted - guessing a start variant would rebuild the chain incorrectly.",
|
||||
"vfl-m3-lauf-anfang-offen-hinweis": "\n Start deliberately left open - no reversing station/GF1/separator built; continue later or join with Vario_Kette_Merge.",
|
||||
"vfl-m2-anfang-offen-gesperrt-zeile": "\n (not selectable - with an AS element the run needs a reversing station)",
|
||||
|
||||
+60
-1
@@ -409,7 +409,7 @@
|
||||
;; vfl-par-gf-laenge - wie lang wird das GF-Stueck dazwischen?
|
||||
;; Die Plan-Turn-Werte unten sind die Vorzeichen-Konvention aus
|
||||
;; vf-element-plan-turn (KS_EIN -> KS_AUS in der XY-Ebene, links positiv).
|
||||
(defun tu-tests-vfl-parallel ( / _b30 _b60 _b90 _kand _l _plan _plan3 _g _p _w)
|
||||
(defun tu-tests-vfl-parallel ( / _b30 _b60 _b90 _kand _l _plan _plan3 _g _p _w _ez)
|
||||
(princ "\n[vf_linienzug Parallel zum Kreisel]")
|
||||
|
||||
;; --- Bogenwahl: der Bogen muss den AS-Schwenk GENAU aufheben ---
|
||||
@@ -516,6 +516,65 @@
|
||||
(tu-nil "vfl-m2-anfang/kein-string" (vfl-m2-anfang-norm 3))
|
||||
(tu-nil "vfl-m2-anfang/nil" (vfl-m2-anfang-norm nil))
|
||||
|
||||
;; --- Eck-Korrektur: gezeichneter Bogen gegen Eck-Bauteil ---
|
||||
;; Die Ecke des Pfads wird durch ein reales Bauteil ersetzt, dessen
|
||||
;; Fussabdruck abweichen darf. Die Differenz wird auf die Richtungen der
|
||||
;; beiden angrenzenden Geraden zerlegt. Werte aus dem echten Lauf vom
|
||||
;; 2026-10-26: 90-Grad-Ecke, Pfad R500 (Sehne 707.1 -> 500/-500), gebaute
|
||||
;; Vario-Kurve wirkt wie R406.2 -> je 93.78 mm auf beide Nachbargeraden.
|
||||
(setq _ez (vfl-eck-zerlegen 500.0 -500.0 406.22 -406.22 (- (/ pi 2.0))))
|
||||
(tu-eqf "vfl-eck-zerlegen/90-grad-davor" 93.78 (car _ez))
|
||||
(tu-eqf "vfl-eck-zerlegen/90-grad-danach" 93.78 (cadr _ez))
|
||||
;; 30-Grad-Ecke links, Gefaellebogen R500 trifft den Pfad fast exakt:
|
||||
;; nur 0.85 mm, und zwar ausschliesslich auf der Geraden DAVOR.
|
||||
(setq _ez (vfl-eck-zerlegen 250.0 66.99 249.15 66.99 (/ pi 6.0)))
|
||||
(tu-eqf "vfl-eck-zerlegen/30-grad-davor" 0.85 (car _ez))
|
||||
(tu-eqf "vfl-eck-zerlegen/30-grad-danach" 0.0 (cadr _ez))
|
||||
;; Deckungsgleiches Bauteil -> kein Zuschlag auf keiner Seite.
|
||||
(setq _ez (vfl-eck-zerlegen 500.0 -500.0 500.0 -500.0 (- (/ pi 2.0))))
|
||||
(tu-eqf "vfl-eck-zerlegen/gleich-davor" 0.0 (car _ez))
|
||||
(tu-eqf "vfl-eck-zerlegen/gleich-danach" 0.0 (cadr _ez))
|
||||
;; Ohne Schwenk ist die Zerlegung nicht eindeutig - nil statt Division durch 0.
|
||||
(tu-nil "vfl-eck-zerlegen/ohne-schwenk"
|
||||
(vfl-eck-zerlegen 100.0 0.0 90.0 0.0 0.0))
|
||||
;; GF-Boegen werden GENEIGT eingebaut: ihr Grundriss-Fussabdruck ist kuerzer
|
||||
;; als flach gemessen, und genau diese Differenz muss in die Eck-Korrektur.
|
||||
;; Werte aus dem echten Lauf 2026-10-26: Gefaellebogen_rechts_90_R500 flach
|
||||
;; dx=500 dz=-28.6, bei 3 Grad eingebaut 497.8 - die 2.2 mm blieben vorher
|
||||
;; als Rest am Kettenende stehen. Negatives dz muss dabei VERKUERZEN.
|
||||
(tu-eqf "vfl-projiziere-neigung/gf-bogen-3-grad"
|
||||
(- (* 500.0 (cos (* 3.0 (/ pi 180.0))))
|
||||
(* 28.6 (sin (* 3.0 (/ pi 180.0)))))
|
||||
(car (vfl-projiziere-neigung 500.0 -28.6 3.0)))
|
||||
(tu-true "vfl-projiziere-neigung/gf-bogen-kuerzer-als-flach"
|
||||
(< (car (vfl-projiziere-neigung 500.0 -28.6 3.0)) 500.0))
|
||||
;; Waagerecht eingebaut (Vario-Kurve) bleibt der Fussabdruck unveraendert.
|
||||
(tu-eqf "vfl-projiziere-neigung/waagerecht" 500.0
|
||||
(car (vfl-projiziere-neigung 500.0 -28.6 0.0)))
|
||||
|
||||
;; --- ES-Reservierung auf die KS_AUS-Achse ---
|
||||
;; Vorgabe: quer zur KS_AUS-Achse MUSS 0 sein, laengs darf abweichen.
|
||||
;; Der reine Laengsanteil reicht dafuer NICHT - er laesst den bauteileigenen
|
||||
;; Querversatz stehen. Werte aus dem echten Lauf 2026-10-26:
|
||||
;; ES_Element_30_rechts an einer Geraden mit hz=-60, Schwenk -30 Grad,
|
||||
;; Fussabdruck (laengs 575.84 | quer -52.54). Reserve 484.8 statt 575.8 -
|
||||
;; die Gerade wird also rund 91 mm laenger und hebt den Querversatz auf.
|
||||
(tu-eqf "vfl-es-achs-reserve/echt-30-grad" 484.838050570331
|
||||
(vfl-es-achs-reserve 575.84 -52.54 -60.0 -30.0))
|
||||
;; Ohne Querversatz bleibt es beim reinen Laengsanteil.
|
||||
(tu-eqf "vfl-es-achs-reserve/ohne-quer" 500.0
|
||||
(vfl-es-achs-reserve 500.0 0.0 -60.0 -30.0))
|
||||
;; Ohne Schwenk faellt die Achse mit der Fahrtrichtung zusammen - dann gibt
|
||||
;; es keinen aufhebbaren Querversatz und der Laengsanteil ist richtig
|
||||
;; (Nenner 0, Rueckfall statt Division durch null).
|
||||
(tu-eqf "vfl-es-achs-reserve/ohne-schwenk" 575.84
|
||||
(vfl-es-achs-reserve 575.84 -52.54 -60.0 0.0))
|
||||
;; Richtungsunabhaengig: dieselbe Geometrie um 90 Grad gedreht gibt
|
||||
;; denselben Wert - die Reserve haengt an den Winkeln zueinander, nicht
|
||||
;; an der Lage im Welt-KS.
|
||||
(tu-eqf "vfl-es-achs-reserve/gedreht" 484.838050570331
|
||||
(vfl-es-achs-reserve 575.84 -52.54 30.0 -30.0))
|
||||
|
||||
;; --- Rueckwaerts bauen: Punkt entgegen der Fahrtrichtung zuruecksetzen ---
|
||||
;; vfl-rueck-punkt ist der Rechenkern des Rueckwaerts-Baus: zu einem
|
||||
;; BEKANNTEN Endpunkt den Startpunkt eines Bausteins finden. Vorwaerts gilt
|
||||
|
||||
Reference in New Issue
Block a user