fix: Laengenbilanz des gefalteten Modus-2-Laufs (U-Form)
Gefaltete VF-Laeufe wurden zu kurz gebaut, weil der Solver Posten dem falschen Schenkel zurechnete. Vier Aenderungen, alle nach demselben Leitsatz: die letzten freien Groessen folgen der GEMESSENEN Ist-Lage, nicht einer vorab verteilten Gesamtplanung. 1. vfl-zsolve-schluss-ziel (neu): endet der Lauf auf einem flachen Fueller, werden RICHTUNG und LAENGE gemeinsam gegen den Zielpunkt geloest statt nur die Laenge. Geschlossene Loesung ueber A = sqrt(|D|^2 - P^2), hz = Winkel(D) - atan2(P, A); C und P sind von hz unabhaengig, daher ohne Iteration. Bisher uebernahm der Solve die Richtung aus dem gezeichneten Pfad - ein Querversatz der realen Eck-Bauteile war damit prinzipiell unerreichbar, weil eine Laenge die Kette nur entlang ihrer Achse verschiebt. 2. Eingangs-Hardware bei gefaltetem Lauf: Umlenkstation + Separator stehen auf dem Eingangs-Schenkel und verbrauchen die Kletterspanne nicht; ihr Laengenanteil wird der Spanne wieder zugeschlagen. feste-vf bleibt unveraendert - sein sin3-Hoehenanteil ist real. 3. kletter-ende-fp: endet der Lauf auf einem KLETTERER, gibt es keinen Schluss-Fueller, der Motorstation + Separator + ES abzieht - sie standen in keinem Budget. Nur bei flacher Zone, Pfadende und vorhandenem ES, sonst sind sie bereits anderweitig verbucht. 4. Nachrechner wieder aktiv (8 statt 4 Runden): GF1 steht im Budget, aber im Eingangs-Schenkel. Die Kollision mit filler-A-len, wegen der er abgeschaltet war, ist entfallen. 3 und 4 wirken NUR gemeinsam - die Betraege heben sich teilweise auf, eine einzeln eingebaute Korrektur verschiebt den Fehler bloss in die andere Richtung (GF1 1636.9 - (Motor+Sep+ES) 1235.1 = 401.8 mm). Gemessen am selben Pfad: 9 Grad 0.56 mm, 12 Grad 0.7 mm quer (vorher 1424 bzw. 934 mm), dZ 0.1 mm. Beide Modus-2-Regressionsketten weiter OK; TEST_UNIT 904/904 mit 7 neuen file-freien Tests. doc/todo.md: Punkt "Modus-2-Solver: achsenweise Laengen-Bilanz" ist damit erledigt. Die Detaildatei bleibt liegen, weil vier Kommentare in vf_linienzug.lsp auf ihren Pfad verweisen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+373
-29
@@ -5341,6 +5341,78 @@
|
||||
;; nil heisst fuer den Aufrufer: ABBRECHEN. Ein Rueckfall auf eine geratene
|
||||
;; Anfangsvariante waere genau der lautlose Fehlaufbau, den die Wertumstellung
|
||||
;; verhindern soll - lieber ein harter Abbruch mit Fundstelle.
|
||||
;; --- Schenkel eines VF-Laufs (reiner Kern, in test_unit getestet) ---
|
||||
;; Ein "Schenkel" ist ein zusammenhaengender Abschnitt des VF-Laufs mit EINER
|
||||
;; Fahrtrichtung. Eine Vario-Kurve im Lauf beendet den einen und beginnt den
|
||||
;; naechsten - eine U-Form (hoch, quer, runter) hat also drei Schenkel.
|
||||
;;
|
||||
;; Wozu: Der Solver bilanziert die Laengen SKALAR ueber den ganzen Lauf. Das
|
||||
;; stimmt nur, solange alle festen Teile auf derselben Achse liegen. Bei einem
|
||||
;; gefalteten Lauf sitzen Umlenkstation/Separator/GF1 im EINGANGS-Schenkel,
|
||||
;; die Kletterstrecke aber oft in einem anderen - der Solver zieht sie
|
||||
;; trotzdem von deren Spanne ab, und die Kette endet weit daneben
|
||||
;; (dokumentiert: dY = +2645 mm, doc/todo/modus2-achsenweise-bilanz.md).
|
||||
;;
|
||||
;; Rueckgabe: Liste der Fahrtrichtungen (hz) je Schenkel, in Bau-Reihenfolge.
|
||||
;; Laenge 1 = gerader Lauf (der Fall, fuer den der Solver gebaut ist).
|
||||
;; Gezaehlt wird ueber die RICHTUNG der Geraden, nicht ueber die Zahl der
|
||||
;; Kurven: zwei entgegengesetzte 90-Grad-Kurven ergeben drei Schenkel, zwei
|
||||
;; gleichsinnige ebenso - entscheidend ist, ob sich die Richtung aendert.
|
||||
(defun vfl-m2-schenkel (plan vf-start vf-ende / i seg out letzt hz)
|
||||
(setq i vf-start out '() letzt nil)
|
||||
(while (<= i vf-ende)
|
||||
(setq seg (nth i plan))
|
||||
(if (= (car seg) "Linie")
|
||||
(progn
|
||||
(setq hz (ks-winkel-normalisieren (float (cadr seg))))
|
||||
(if (or (null letzt) (> (abs (- hz letzt)) 1.0))
|
||||
(setq out (cons hz out)))
|
||||
(setq letzt hz)))
|
||||
(setq i (1+ i)))
|
||||
(reverse out))
|
||||
|
||||
;; T, wenn der Lauf gefaltet ist (mehr als eine Fahrtrichtung).
|
||||
(defun vfl-m2-gefaltet-p (plan vf-start vf-ende)
|
||||
(> (length (vfl-m2-schenkel plan vf-start vf-ende)) 1))
|
||||
|
||||
;; Nummer des Schenkels, in dem ein Segment liegt (0-basiert, ab vf-start
|
||||
;; gezaehlt). Fuer Bogen-Segmente der Schenkel, der VOR ihnen endet.
|
||||
;; Damit laesst sich fragen: liegt der Kletterer im selben Schenkel wie der
|
||||
;; Lauf-Eingang? Nur wenn NICHT, ist die skalare Bilanz falsch.
|
||||
(defun vfl-m2-schenkel-index (plan vf-start seg-idx / i seg k letzt hz)
|
||||
(setq i vf-start k 0 letzt nil)
|
||||
(while (<= i seg-idx)
|
||||
(setq seg (nth i plan))
|
||||
(if (= (car seg) "Linie")
|
||||
(progn
|
||||
(setq hz (ks-winkel-normalisieren (float (cadr seg))))
|
||||
(if (and letzt (> (abs (- hz letzt)) 1.0)) (setq k (1+ k)))
|
||||
(setq letzt hz)))
|
||||
(setq i (1+ i)))
|
||||
k)
|
||||
|
||||
;; --- Eingangs-Hardware auf einem FUELLER-Segment (reiner Kern, getestet) ---
|
||||
;; GF1 + Separator + Umlenkstation + Uebergangsbogen werden am Lauf-EINGANG
|
||||
;; gebaut, stehen also auf dem Segment vf-start. Ist dieses Segment zugleich
|
||||
;; der Kletterer, sind sie ueber feste-vf bereits im Solver beruecksichtigt -
|
||||
;; dann darf hier NICHTS abgezogen werden (sonst doppelt).
|
||||
;; Ist vf-start dagegen ein FUELLER (der Kletterer liegt hinter einer Kurve),
|
||||
;; kennt den Platzbedarf niemand: der Fueller bekam bisher die volle
|
||||
;; Restlaenge des Segments, als staende dort nichts. Realer Fall 2026-10-27:
|
||||
;; Planlaenge 5855 mm, tatsaechlich belegt 10668 mm, Kette 8005 mm daneben.
|
||||
;; Rueckgabe: der abzuziehende Grundriss-Anteil (0.0, wenn nicht zutreffend).
|
||||
;; gf-total = die vom Solver gewaehlte GF1-Laenge (Schraeglaenge bei 3 Grad).
|
||||
(defun vfl-m2-eingang-fp (idx vf-start climbers gf-total rad3 / m)
|
||||
(if (or (/= idx vf-start) (member vf-start climbers))
|
||||
0.0
|
||||
(progn
|
||||
(setq m (get-bogen-mass bogen-auf (fix *vfk-gefaelle-winkel*)))
|
||||
(+ (* (+ (if gf-total (float gf-total) 0.0)
|
||||
*vfk-separator-laenge*
|
||||
*vfk-stations-laenge*)
|
||||
(cos rad3))
|
||||
(if m (car m) 0.0)))))
|
||||
|
||||
;; Allgemeiner Normalisierer fuer selbstbeschreibende Antwortwerte.
|
||||
;; werte = heutige Werte in Optionsreihenfolge, alt = Alist Alt-Ziffer -> Wert
|
||||
;; (nur fuer Bestandsketten). Rueckgabe nil = UNBEKANNT; der Aufrufer bricht
|
||||
@@ -11171,6 +11243,43 @@
|
||||
;; ES-Eigen-dz. Spiegelt den tatsaechlichen Bau (Trimmung der letzten Geraden um
|
||||
;; 300+ein-fp, GF-Bogen bei Neigung). Eintritts-Neigung = 3 Grad (die Bruecke
|
||||
;; endet mit GF2 auf 3 Grad). So wird die Junction-Hoehe exakt statt geschaetzt.
|
||||
;; Stiller Nachrechner: L_GF/L_VF beim BEREITS GEWAEHLTEN Winkel mit einer
|
||||
;; korrigierten Spanne neu aufteilen - ohne Dialog, ohne neue Winkelfrage.
|
||||
;; Gebraucht bei gefaltetem Lauf: dort liegt ein Teil der Gefaellestrecke
|
||||
;; (GF1) auf dem Eingangs-Schenkel und verbraucht die Spanne des Kletterers
|
||||
;; nicht. Das weiss man erst, wenn Winkel UND GF-Verteilung beantwortet sind -
|
||||
;; also nach der Winkelwahl. Deshalb hier nachrechnen statt die Frage
|
||||
;; vorzuziehen: so bleibt die Fragenfolge (und damit jedes gespeicherte
|
||||
;; Journal) unveraendert.
|
||||
;; aus-dx/ein-dx werden wie in vfl-zsolve-winkel-waehlen temporaer genullt -
|
||||
;; dieselbe Begruendung, siehe dort.
|
||||
;; Rueckgabe: (L_GF L_VF) oder nil, wenn der Winkel bei dieser Spanne nicht
|
||||
;; mehr aufgeht (dann bleibt der Aufrufer beim bisherigen Ergebnis).
|
||||
(defun vfl-zsolve-nachrechnen (span dH-signiert feste winkel /
|
||||
o-adx o-adz o-eix o-eiz richtung res tr)
|
||||
(setq richtung (if (< dH-signiert 0) "Auf" "Ab"))
|
||||
(setq o-adx aus-dx o-adz aus-dz o-eix ein-dx o-eiz ein-dz)
|
||||
(setq aus-dx 0.0 aus-dz 0.0 ein-dx 0.0 ein-dz 0.0)
|
||||
(setq res (berechne-alle-winkel span (abs dH-signiert) richtung feste nil))
|
||||
(setq aus-dx o-adx aus-dz o-adz ein-dx o-eix ein-dz o-eiz)
|
||||
(setq tr nil)
|
||||
(foreach e (nth 3 res)
|
||||
(if (and (null tr) (= (car e) winkel) (cadddr e)
|
||||
(numberp (cadr e)) (numberp (caddr e))
|
||||
(> (cadr e) 0) (> (caddr e) 0))
|
||||
(setq tr (list (cadr e) (caddr e)))))
|
||||
tr)
|
||||
|
||||
;; Anteil der Gefaellestrecke, der NICHT auf dem Kletterer-Schenkel liegt.
|
||||
;; Reiner Kern (getestet). br-gf-mode: 1 = alles am Einlauf, 2 = halb/halb,
|
||||
;; 3 = alles am Auslauf. Liegt der Eingang auf dem Kletterer selbst, ist
|
||||
;; nichts fremd - dann 0.
|
||||
(defun vfl-m2-gf-fremdanteil (gf-total br-gf-mode eingang-ist-kletterer)
|
||||
(cond (eingang-ist-kletterer 0.0)
|
||||
((= br-gf-mode 1) (float gf-total))
|
||||
((= br-gf-mode 2) (/ (float gf-total) 2.0))
|
||||
(t 0.0)))
|
||||
|
||||
(defun vfl-zsolve-rueckanker (plan start-idx n last-idx ein-fp / i seg drop inc w dL rad)
|
||||
(setq drop 0.0 inc *vfk-gefaelle-winkel* i start-idx)
|
||||
(while (< i n)
|
||||
@@ -11481,6 +11590,60 @@
|
||||
(- (/ (- ep-na (* perp-es np-na)) dp-na) cc)
|
||||
100.0))))
|
||||
|
||||
;; --- Schlussstueck: RICHTUNG und LAENGE gemeinsam aus der IST-Lage loesen ---
|
||||
;; Nutzer-Vorgabe 2026-10-29: "nach der zweiten VF-Kurve den passenden Winkel
|
||||
;; neu aus dem KS_AUS der Kurve und dem Zielpunkt rechnen".
|
||||
;;
|
||||
;; Warum das noetig ist: vfl-zsolve-es-fueller loest NUR die Laenge und
|
||||
;; uebernimmt die Richtung unveraendert aus dem gezeichneten Pfad. Eine Laenge
|
||||
;; verschiebt die Kette aber ausschliesslich ENTLANG ihrer Achse. Steht der
|
||||
;; reale Kurvenausgang seitlich NEBEN der gezeichneten Geraden - und das tut er,
|
||||
;; sobald die echten Eck-Bauteile nicht in die gezeichnete Ecke passen -, dann
|
||||
;; laeuft die gebaute Achse PARALLEL zur Zielachse, und kein Fuellerwert der
|
||||
;; Welt holt den Querversatz noch ein (realer Befund 2026-10-29: waagerechte
|
||||
;; Kette, zwei 90-Grad-Vario-Kurven mit nur 269.9 mm gezeichnetem Zwischenstueck
|
||||
;; -> 637.6 mm quer, 1424.4 mm laengs daneben).
|
||||
;;
|
||||
;; Gibt man die Richtung mit frei, stehen zwei Unbekannte (fill, hz) zwei
|
||||
;; Gleichungen (X und Y des Zielpunkts) gegenueber - geschlossen loesbar, ohne
|
||||
;; Iteration. Der Schwanz (Fueller + ab_3 + Motor + GF2 + Separator + ES) ist
|
||||
;; starr; im Rahmen von hz hat sein Endpunkt die festen Komponenten
|
||||
;; (fill + C) laengs und P quer.
|
||||
;; Beide sind von hz UNABHAENGIG: vfl-zsolve-es-vektor dreht den ES-Vektor und
|
||||
;; den Bezugsrahmen um denselben Winkel. Also ist D = Ziel - pt genau der um hz
|
||||
;; gedrehte Vektor (fill + C, P), woraus folgt:
|
||||
;; A = sqrt(|D|^2 - P^2) (Laengskomponente, Pythagoras)
|
||||
;; fill = A - C
|
||||
;; hz = Winkel(D) - atan2(P, A)
|
||||
;; Damit wird der Zielpunkt in X UND Y exakt getroffen, nicht nur die ES-Achse.
|
||||
;;
|
||||
;; Das Schlussstueck weicht danach bewusst von der gezeichneten Richtung ab -
|
||||
;; genau im Sinn des Leitsatzes bei vfl-eck-korrekturen: massgeblich ist die
|
||||
;; reale Bauteilkette, der gezeichnete Pfad ist nur Hinweis.
|
||||
;;
|
||||
;; es-block = ES-Blockname oder nil (dann ohne ES-Element, P = 0).
|
||||
;; Rueckgabe: (fill hz-grad) oder nil, wenn der Zielpunkt naeher liegt als der
|
||||
;; Querversatz - dann gibt es keine Loesung und der Aufrufer faellt auf den
|
||||
;; bisherigen Weg (Richtung aus dem Plan) zurueck.
|
||||
(defun vfl-zsolve-schluss-ziel (pt endp seg-hz es-block gf2 rad3 /
|
||||
vek cc pp p0 p1 dd aa)
|
||||
(setq vek (if es-block (vfl-zsolve-es-vektor es-block seg-hz) nil))
|
||||
(if vek
|
||||
(setq cc (+ 196.0 (* (+ *vfk-feste-horizontal-kettenende* gf2) (cos rad3)) (car vek))
|
||||
pp (cadr vek))
|
||||
(setq cc (* (+ *vfk-stations-laenge* gf2) (cos rad3))
|
||||
pp 0.0))
|
||||
(setq p0 (list (car pt) (cadr pt))
|
||||
p1 (list (car endp) (cadr endp)))
|
||||
(setq dd (distance p0 p1))
|
||||
(if (<= dd (+ (abs pp) 1.0))
|
||||
nil
|
||||
(progn
|
||||
(setq aa (sqrt (- (* dd dd) (* pp pp))))
|
||||
(list (- aa cc)
|
||||
(- (/ (* 180.0 (angle p0 p1)) pi)
|
||||
(/ (* 180.0 (atan pp aa)) pi))))))
|
||||
|
||||
(defun vf-linienzug-modus2 ( / ss k obj-liste startpunkt start-hoehe as-seite
|
||||
endpunkt end-hoehe es-seite kette segmente segmente9 n i seg
|
||||
seg-ent
|
||||
@@ -11503,10 +11666,13 @@
|
||||
longest-idx climbers nonclimber-len
|
||||
nonclimber-cnt nkurve kurve-chords run-span
|
||||
hor-koerper-len hor-pairs flat-p flat-zone-erste fill-len wahl3
|
||||
schluss
|
||||
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 as-along-fix m-ueb
|
||||
abschluss-fp m-ab3 es-vek-back ein-fp-mess
|
||||
span-solver nachrechnen-k gf-fremd res-neu
|
||||
kletter-ende-fp kl-es-vek
|
||||
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
|
||||
@@ -11821,6 +11987,7 @@
|
||||
(vfl-meldung (ssg-textf "vfl-m3-vf-lauf-alert" (list (itoa vf-count))))
|
||||
(exit)))
|
||||
|
||||
|
||||
;; --- Bau-Grenzen der VF-Einheit (Nutzer-Regel 2026-10-22) ---
|
||||
;; Zwischen Umlenkstation und Motorstation: hoechstens 2 Vario-Kurven (also
|
||||
;; maximal drei VF-Geraden) und hoechstens *vfk-vf-laenge-max* (25 m).
|
||||
@@ -12203,6 +12370,17 @@
|
||||
(if (or (< longest-idx 0) (> (caddr seg) (caddr (nth longest-idx plan))))
|
||||
(setq longest-idx i)))
|
||||
(setq i (1+ i)))
|
||||
|
||||
;; An dieser Stelle stand ein Hinweis, dass ein gefalteter Lauf mit dem
|
||||
;; Kletterer in einem FREMDEN Schenkel noch skalar ueber EINE Achse
|
||||
;; bilanziert wird (davor zeitweise sogar eine Abweisung bzw. eine
|
||||
;; Warn-Messagebox). Beides ist seit 2026-10-29 gegenstandslos: die
|
||||
;; Eingangs-Hardware wird der Kletterspanne wieder zugeschlagen, die
|
||||
;; Abschluss-Hardware auf einem Kletter-Laufende abgezogen (kletter-ende-fp)
|
||||
;; und der GF1-Fremdanteil vom Nachrechner aufgeloest. Gemessen an demselben
|
||||
;; Pfad: 0.56 mm (9 Grad) und 0.7 mm (12 Grad) quer. Eine stehengebliebene
|
||||
;; Meldung waere hier nicht nur ueberfluessig, sondern falsch.
|
||||
|
||||
(setq climbers '() climber-span 0.0 nonclimber-len 0.0 nonclimber-cnt 0
|
||||
nkurve 0 kurve-chords 0.0 i vf-start)
|
||||
(while (<= i vf-ende)
|
||||
@@ -12371,10 +12549,88 @@
|
||||
;; 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
|
||||
(if (member vf-start climbers) as-along-fix 0.0))
|
||||
dH-adj feste-vf))
|
||||
;; Eingangs-Hardware (Umlenkstation + Separator) steht auf dem Segment
|
||||
;; vf-start. Liegt der Kletterer in einem ANDEREN Schenkel, verbraucht sie
|
||||
;; dessen Spanne nicht - der Solver zieht sie aber ueber feste-vf trotzdem
|
||||
;; ab (als feste*cos3, vf_standard.lsp:241). Dann bleibt am Ende Platz
|
||||
;; ungenutzt und die Kette endet zu frueh (gemessen 2026-10-27: 1424 mm).
|
||||
;; Kompensiert wird NUR der Laengenanteil: feste-vf traegt ueber
|
||||
;; feste*sin3 auch Hoehe bei, und die ist real - die Teile senken die Kette
|
||||
;; ab, egal auf welchem Segment sie stehen. Darum wird feste-vf selbst NICHT
|
||||
;; veraendert, sondern der uebergebenen Spanne der Laengenanteil wieder
|
||||
;; zugeschlagen. (Dieselbe Trennung wie bei es-along-fix; sie zu uebersehen
|
||||
;; hat am 2026-10-26 einen 43-mm-Hoehenfehler erzeugt.)
|
||||
;; Liegt der Kletterer im Eingangs-Schenkel - der gerade Normalfall und
|
||||
;; beide Regressionsketten -, ist der Zuschlag 0 und nichts aendert sich.
|
||||
;; GEFALTETER LAUF: die Eingangs-Hardware (Umlenkstation + Separator, als
|
||||
;; entry-fixed) steht auf dem Segment vf-start. Ist DAS zugleich der
|
||||
;; Kletterer (gerader Normalfall, beide Regressionsketten), verbraucht sie
|
||||
;; dessen Spanne - der Abzug ueber feste-vf stimmt. Liegt der Kletterer aber
|
||||
;; in einem ANDEREN Schenkel, verbraucht sie die Kletterspanne NICHT, und der
|
||||
;; Solver verplant Platz, den es dort gar nicht zu verplanen gibt: am Ende
|
||||
;; bleibt genau dieser Betrag ungenutzt und die Kette endet zu frueh.
|
||||
;; Zugeschlagen wird NUR der Laengenanteil (entry-fixed*cos3). feste-vf selbst
|
||||
;; bleibt unveraendert, weil es ueber feste*sin3 auch Hoehe beitraegt - und die
|
||||
;; ist real: die Teile senken die Kette ab, egal auf welchem Schenkel sie
|
||||
;; stehen. (Dieselbe Trennung wie bei es-along-fix; sie zu uebersehen hat am
|
||||
;; 2026-10-26 einen 43-mm-Hoehenfehler erzeugt.)
|
||||
;;
|
||||
;; Diese Korrektur war am 2026-10-28 schon einmal da und wurde zurueckgenommen,
|
||||
;; weil sie mit filler-A-len kollidierte: Fueller-A belegte im Kletter-Segment
|
||||
;; den Platz, den das halbe GF1 dort frei laesst - obwohl GF1 bei gefaltetem
|
||||
;; Lauf im Eingangs-Schenkel steht. Dieser Blocker ist entfallen, seit
|
||||
;; filler-A-len bei gefaltetem Lauf 0 ist (siehe dort), die Korrektur kann
|
||||
;; also zurueck.
|
||||
;;
|
||||
;; Den GF1-Anteil kann dieser Solve noch nicht beruecksichtigen: gf-total ist
|
||||
;; sein ERGEBNIS (Henne-Ei). Dafuer gibt es den Nachrechner weiter unten.
|
||||
;;
|
||||
;; --- Abschluss-Hardware, wenn der KLETTERER das Laufende ist --------------
|
||||
;; Endet der Lauf auf einem FUELLER, loest vfl-zsolve-es-fueller dessen Laenge
|
||||
;; gegen den Zielpunkt und zieht Motorstation + Separator + ES dabei selbst ab
|
||||
;; (Konstante cc dort). Endet er auf einem KLETTERER, gibt es diesen Fueller
|
||||
;; nicht - die drei Teile werden auf dem Kletter-Segment gebaut, stehen aber
|
||||
;; in KEINEM Budget: feste-vf traegt bei vorhandener flacher Zone nur
|
||||
;; entry-fixed (Umlenk+Sep am Eingang), und abschluss-fp wird ausschliesslich
|
||||
;; in fill-len verrechnet, also nur bei Fueller-Segmenten.
|
||||
;; Abgezogen wird deshalb genau dasselbe wie in cc, ABER OHNE den ab_3-Bogen
|
||||
;; (196 mm): der steckt bei einem Kletterer am Laufende bereits in
|
||||
;; uebergang-fp (Zweig "flache Zone GEHT VORAUS"), und doppelt gezaehlt
|
||||
;; verkuerzte er die Kette erneut.
|
||||
;;
|
||||
;; Die drei Bedingungen sind KEINE Vorsichtsmassnahme, sondern genau die
|
||||
;; Faelle, in denen sonst doppelt gebucht wird:
|
||||
;; - hor-pairs > 0: OHNE flache Zone traegt feste-vf die Motorstation bereits
|
||||
;; selbst (siehe dortiger Zweig), und es-along-fix den ES-Anteil.
|
||||
;; - vf-ende = n-1: endet der Pfad nicht mit dem VF-Lauf, baut der Back-Lauf
|
||||
;; Separator + ES und reserviert sie ueber ein-fp-mess selbst.
|
||||
;; - es-vorhanden: ohne ES-Element gibt es weder Separator noch ES-Ausladung.
|
||||
;; Realer Regressionsbefund 2026-10-29 (Variante B, tests/testdata/
|
||||
;; linienzug_modus2_gfbogen.json): dort ist vf-start = vf-ende = 0, der VF-Lauf
|
||||
;; besteht aus EINEM Segment und die Segmente 2..5 sind Back-Lauf. Ohne diese
|
||||
;; Bedingungen schlug der Abzug mit 800*cos3 = 798.9 mm zu, Segment 1 wurde um
|
||||
;; genau diesen Betrag kuerzer, und weil es bei hz=0 liegt, erschien der
|
||||
;; Fehler als reine X-Verschiebung von -799.1 mm.
|
||||
(setq kletter-ende-fp 0.0)
|
||||
(if (and (member vf-ende climbers) (not m2-offenes-ende)
|
||||
(> hor-pairs 0) (= vf-ende (1- n)) es-vorhanden)
|
||||
(progn
|
||||
(setq kl-es-vek
|
||||
(vfl-zsolve-es-vektor
|
||||
(strcat "ES_Element_" (vfl-es-winkel) "_" es-seite)
|
||||
(cadr (nth vf-ende plan))))
|
||||
(setq kletter-ende-fp
|
||||
(+ (* *vfk-feste-horizontal-kettenende* (cos rad3v))
|
||||
(if kl-es-vek (car kl-es-vek) 0.0)))
|
||||
(princ (ssg-textf "vfl-m2-kletter-ende-fussabdruck"
|
||||
(list (rtos kletter-ende-fp 2 1) (itoa (1+ vf-ende)))))))
|
||||
;; span-solver = dieselbe Spanne, die der Nachrechner weiter unten wieder
|
||||
;; aufgreift (dort kommt der GF-Fremdanteil hinzu).
|
||||
(setq span-solver
|
||||
(+ (- climber-span es-along-fix uebergang-fp kletter-ende-fp
|
||||
(if (member vf-start climbers) as-along-fix 0.0))
|
||||
(if (member vf-start climbers) 0.0 (* entry-fixed (cos rad3v)))))
|
||||
(setq wahl3 (vfl-zsolve-winkel-waehlen span-solver dH-adj feste-vf))
|
||||
(if (null wahl3)
|
||||
(progn
|
||||
;; Stufe 2: KEIN Tabellenwinkel passt (der/die Kletterer sind bei JEDER
|
||||
@@ -12418,11 +12674,81 @@
|
||||
(setq br-gf-mode
|
||||
(if (= (vfl-menu (ssg-text "prompt-wahl-1-2")
|
||||
(list "Alles am Einlauf (GF1)" "1/2 GF1 + 1/2 GF2") 1
|
||||
"vfl-m3-gf-verteilung") "2") 2 1))
|
||||
(if (= br-gf-mode 2)
|
||||
(setq br-gf1 (/ gf-total 2.0) br-gf2-exp (/ gf-total 2.0)
|
||||
filler-A-len (* (/ gf-total 2.0) (cos rad3v)))
|
||||
(setq br-gf1 gf-total br-gf2-exp 0.0 filler-A-len 0.0))))
|
||||
"vfl-m3-gf-verteilung") "2") 2 1))))
|
||||
;; --- Stiller Nachrechner bei gefaltetem Lauf ---
|
||||
;; Jetzt sind Winkel UND Verteilung bekannt - erst damit steht fest, wie viel
|
||||
;; Gefaellestrecke auf dem EINGANGS-Schenkel landet und die Spanne des
|
||||
;; Kletterers gar nicht verbraucht. Der Solver hat sie bisher mitgerechnet,
|
||||
;; weshalb am Kettenende Platz ungenutzt blieb (gemessen 2026-10-27:
|
||||
;; 1424 mm). Hier wird bei UNVERAENDERTEM Winkel neu aufgeteilt.
|
||||
;; Die Schleife iteriert, weil der fremde Anteil selbst von gf-total
|
||||
;; abhaengt - ohne Dialog, daher unbemerkt. Sie konvergiert schnell (die
|
||||
;; Korrektur wird mit jedem Durchgang kleiner) und bricht nach 4 Runden
|
||||
;; oder bei weniger als 1 mm Aenderung ab.
|
||||
;; Liegt der Eingang auf dem Kletterer (gerader Normalfall, beide
|
||||
;; Regressionsketten), ist der Fremdanteil 0 und die Schleife laeuft nicht.
|
||||
;;
|
||||
;; Am 2026-10-28 war der Nachrechner abgeschaltet, weil er mit filler-A-len
|
||||
;; kollidierte: jener Fueller belegte im Kletter-Segment den Platz, den das
|
||||
;; halbe GF1 dort frei laesst - obwohl GF1 bei gefaltetem Lauf im Eingangs-
|
||||
;; Schenkel steht, wurde er zusaetzlich gebaut (gemessen: Fueller -369 mm,
|
||||
;; geklemmt auf 100). Seit filler-A-len bei gefaltetem Lauf 0 ist, entfaellt
|
||||
;; die Kollision und der Nachrechner darf wieder laufen.
|
||||
;;
|
||||
;; Er ist die zweite Haelfte der Korrektur und wirkt NUR zusammen mit
|
||||
;; kletter-ende-fp: GF1 steht im Budget, aber nicht auf dem Kletterer
|
||||
;; (zu viel verplant), Motor+Separator+ES stehen auf dem Kletterer, aber in
|
||||
;; keinem Budget (zu wenig verplant). Die beiden Betraege heben sich
|
||||
;; TEILWEISE auf - wer nur einen von beiden einbaut, verschiebt den Fehler
|
||||
;; bloss in die andere Richtung. Gemessen 2026-10-29 am 9-Grad-U-Form-Lauf:
|
||||
;; GF1 1636.9 - (Motor+Sep+ES) 1235.1 = 401.8 mm, exakt die damalige
|
||||
;; Restabweichung von 401.7 mm.
|
||||
;;
|
||||
;; 8 statt 4 Runden: die Korrektur schrumpft je Runde auf etwa ein Drittel
|
||||
;; (gemessen 3278 -> 4372 -> 4737 -> 4859 -> 4899), nach 4 Runden blieben
|
||||
;; rund 20 mm stehen. 8 Runden kosten nur Arithmetik und bringen den Rest
|
||||
;; unter die 1-mm-Abbruchschwelle.
|
||||
(setq nachrechnen-k 0)
|
||||
(while (< nachrechnen-k 8)
|
||||
(setq gf-fremd (vfl-m2-gf-fremdanteil gf-total br-gf-mode
|
||||
(and (member vf-start climbers) t)))
|
||||
(if (< gf-fremd 1.0)
|
||||
(setq nachrechnen-k 8)
|
||||
(progn
|
||||
(setq res-neu (vfl-zsolve-nachrechnen
|
||||
(+ span-solver (* gf-fremd (cos rad3v)))
|
||||
dH-adj feste-vf br-winkel))
|
||||
(cond
|
||||
((null res-neu)
|
||||
;; Winkel geht bei korrigierter Spanne nicht mehr auf - beim
|
||||
;; bisherigen Ergebnis bleiben und das sagen, statt still etwas
|
||||
;; anderes zu bauen.
|
||||
(vfl-meldung (ssg-textf "vfl-m2-nachrechnen-fehl" (list (itoa br-winkel))))
|
||||
(setq nachrechnen-k 8))
|
||||
((< (abs (- (car res-neu) gf-total)) 1.0)
|
||||
(setq nachrechnen-k 8))
|
||||
(t
|
||||
(princ (ssg-textf "vfl-m2-nachrechnen"
|
||||
(list (rtos gf-total 2 0) (rtos (car res-neu) 2 0)
|
||||
(rtos (cadr res-neu) 2 0))))
|
||||
(setq gf-total (car res-neu) br-lvf (cadr res-neu))
|
||||
(setq nachrechnen-k (1+ nachrechnen-k)))))))
|
||||
;; GF-Aufteilung jetzt aus dem (ggf. nachgerechneten) gf-total bilden.
|
||||
(if (/= br-gf-mode 3)
|
||||
(if (= br-gf-mode 2)
|
||||
(setq br-gf1 (/ gf-total 2.0) br-gf2-exp (/ gf-total 2.0)
|
||||
;; Fueller-A fuellt den Platz, den das halbierte GF1 auf DERSELBEN
|
||||
;; Achse frei laesst - er gehoert zur Annahme "GF1 und GF2 liegen
|
||||
;; auf einer Geraden". Bei gefaltetem Lauf stimmt das nicht: GF1
|
||||
;; steht im Eingangs-Schenkel, GF2 im Kletterer-Schenkel. Fueller-A
|
||||
;; wuerde dann auf dem Eingangs-Segment zusaetzlich zu GF1 gebaut,
|
||||
;; und insgesamt entstuenden 1.5 x gf-total Gefaellestrecke bei
|
||||
;; einem Budget von gf-total - die Kette endet zu frueh
|
||||
;; (gemessen 2026-10-27: 1424 mm).
|
||||
filler-A-len (if (member vf-start climbers)
|
||||
(* (/ gf-total 2.0) (cos rad3v))
|
||||
0.0))
|
||||
(setq br-gf1 gf-total br-gf2-exp 0.0 filler-A-len 0.0)))
|
||||
(setq filler-a-done nil)
|
||||
(princ (ssg-textf "vfl-m3-vario-ergebnis"
|
||||
(list (itoa br-winkel)
|
||||
@@ -12491,30 +12817,48 @@
|
||||
;; Separator + ES kuemmert sich der Back-Lauf selbst (siehe dort die
|
||||
;; last-line-Reservierung).
|
||||
(if (and (= i vf-ende) (= vf-ende (1- n)))
|
||||
;; letzter Fueller, MIT ES-Element (unveraendert): Laenge so, dass der
|
||||
;; ENDPUNKT auf der ES-KS_AUS-ACHSE liegt (Spiegel der AS-Regel). Der
|
||||
;; Schwanz (Fueller + ab_3 + Motor + GF2 + Separator + ES) verschiebt
|
||||
;; sich starr entlang seg-hz mit dem Fueller; KS_AUS = pt + (fill + C)*
|
||||
;; dp + perp-es*np, Achse u_a = seg-hz + ES-Turn. Aus (Endpunkt -
|
||||
;; KS_AUS)*n_a = 0 folgt fill (n_a senkrecht zu u_a). OHNE ES-Element
|
||||
;; (Nutzerwunsch): keine Achsen-Korrektur noetig, da nach Motor+GF2
|
||||
;; nichts mehr gebaut wird - Fueller zielt direkt auf den Endpunkt.
|
||||
(setq fill-len
|
||||
(if es-vorhanden
|
||||
(vfl-zsolve-es-fueller pt endpunkt seg-hz
|
||||
(strcat "ES_Element_" (vfl-es-winkel) "_" es-seite)
|
||||
br-gf2-exp rad3v)
|
||||
(- (+ (* (- (car endpunkt) (car pt)) (cos (* seg-hz (/ pi 180.0))))
|
||||
(* (- (cadr endpunkt) (cadr pt)) (sin (* seg-hz (/ pi 180.0)))))
|
||||
(* (+ *vfk-stations-laenge* br-gf2-exp) (cos rad3v)))
|
||||
)
|
||||
)
|
||||
;; Letztes Segment UND Pfadende: RICHTUNG und LAENGE des Schlussstuecks
|
||||
;; gemeinsam aus der IST-Lage loesen (vfl-zsolve-schluss-ziel), statt
|
||||
;; die Richtung aus dem gezeichneten Pfad zu uebernehmen und nur die
|
||||
;; Laenge zu loesen. Damit wird der Zielpunkt in X UND Y getroffen;
|
||||
;; ein Querversatz, den die realen Eck-Bauteile vorher aufgebaut haben,
|
||||
;; wird hier eingefangen statt bis ans Kettenende mitgeschleppt.
|
||||
;; Scheitert der Solve (Ziel liegt naeher als der ES-Querversatz),
|
||||
;; bleibt es beim bisherigen Weg: Richtung aus dem Plan, Laenge so, dass
|
||||
;; der Endpunkt auf der ES-KS_AUS-Achse liegt (Spiegel der AS-Regel) -
|
||||
;; bzw. ohne ES-Element direkt auf den Endpunkt.
|
||||
(progn
|
||||
(setq schluss (vfl-zsolve-schluss-ziel pt endpunkt seg-hz
|
||||
(if es-vorhanden
|
||||
(strcat "ES_Element_" (vfl-es-winkel) "_" es-seite))
|
||||
br-gf2-exp rad3v))
|
||||
(if schluss
|
||||
(progn
|
||||
(dbgmsg (strcat "SCHLUSS-SOLVE hz-plan=" (rtos seg-hz 2 3)
|
||||
" hz-neu=" (rtos (cadr schluss) 2 3)
|
||||
" fill=" (rtos (car schluss) 2 1)))
|
||||
(setq fill-len (car schluss)
|
||||
seg-hz (cadr schluss)))
|
||||
(setq fill-len
|
||||
(if es-vorhanden
|
||||
(vfl-zsolve-es-fueller pt endpunkt seg-hz
|
||||
(strcat "ES_Element_" (vfl-es-winkel) "_" es-seite)
|
||||
br-gf2-exp rad3v)
|
||||
(- (+ (* (- (car endpunkt) (car pt)) (cos (* seg-hz (/ pi 180.0))))
|
||||
(* (- (cadr endpunkt) (cadr pt)) (sin (* seg-hz (/ pi 180.0)))))
|
||||
(* (+ *vfk-stations-laenge* br-gf2-exp) (cos rad3v)))))))
|
||||
;; 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.
|
||||
;; das AS am Laufanfang, Abschlussbogen + Motorstation am Laufende,
|
||||
;; und die Eingangs-Hardware, falls sie auf einem FUELLER steht.
|
||||
(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))))
|
||||
(if (= i vf-ende) abschluss-fp 0.0)
|
||||
;; br-gf1 (das TATSAECHLICH gebaute GF1), nicht
|
||||
;; gf-total: bei Verteilung 1/2+1/2 steht nur die
|
||||
;; Haelfte auf diesem Segment, seit Fueller-A dort
|
||||
;; nicht mehr entsteht (siehe filler-A-len oben).
|
||||
(vfl-m2-eingang-fp i vf-start climbers br-gf1 rad3v))))
|
||||
;; 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
|
||||
|
||||
-11
@@ -11,17 +11,6 @@ Stand: 2026-10-26. Wird woechentlich (freitags) mit der Doku geprueft, siehe
|
||||
|
||||
## 1. VarioFoerderer / Linienzug
|
||||
|
||||
- **Modus-2-Solver: achsenweise Laengen-Bilanz.** Gefaltete VF-Laeufe (U-Form)
|
||||
werden falsch gebaut (erste GF zu lang, Kletterstrecke zu kurz, Motor/ES
|
||||
falsch), weil der Solver die festen Fussabdruecke skalar von EINER Spanne
|
||||
abzieht. **Teilweise erledigt 2026-10-26** (ce4ad0f): AS-Element,
|
||||
Abschlussbogen+Motorstation und die Eck-Differenzen werden seitdem dem
|
||||
Segment zugeschlagen, auf dem sie physisch stehen (`vfl-eck-extra` je
|
||||
Segmentindex, `as-along-fix` auf `vf-start`, `abschluss-fp` auf `vf-ende`) -
|
||||
das ist die achsenweise Idee fuer diese Posten. SKALAR bleiben `feste-vf`
|
||||
(Umlenkstation + Separator) und `gf-total` (GF1), und genau die verursachen
|
||||
den U-Form-Fehler. Als Zwischenloesung zumindest gefaltete Laeufe mit
|
||||
Meldung abweisen. -> `doc/todo/modus2-achsenweise-bilanz.md`
|
||||
- **VF-Linienzug ohne GUI/Konsole, Stufe 2** (Funktionstrennung): eigener,
|
||||
separat abzuarbeitender Auftrag mit Schritt-Tabelle. Schritte 5c, 6, 8, 9,
|
||||
10 offen (u.a. `vfl-spec-ausfuehren`). Schritt 11 war zurueckgestellt, bis
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
# TODO: Modus-2-Solver auf achsenweise Laengen-Bilanz umstellen
|
||||
# Modus-2-Solver: achsenweise Laengen-Bilanz
|
||||
|
||||
Status: **Vorschlag / noch nicht umgesetzt** (2026-09-18). Mit dem Entwickler zu
|
||||
besprechen, bevor der Solver angefasst wird. Reiner Plan - kein Code geaendert.
|
||||
Status: **ERLEDIGT 2026-10-29.** Gefaltete Laeufe (U-Form) werden gebaut; am
|
||||
selben Pfad gemessen 0.56 mm (9 Grad) und 0.7 mm (12 Grad) quer, beide
|
||||
Regressionsketten weiter OK. Der Abschnitt "Stand 2026-10-29" und der "Nachtrag
|
||||
2026-10-29" am Ende beschreiben Loesung und Herleitung.
|
||||
|
||||
**Pruefung 2026-10-26:** weiterhin OFFEN - der Solver bilanziert noch skalar
|
||||
(`climber-span`, `hor-pairs` 0/1), auch die Zwischenloesung (gefaltete Laeufe
|
||||
abweisen) ist nicht eingebaut. Die Zeilennummern unten sind veraltet: Phase B
|
||||
von `vf-linienzug-modus2` liegt inzwischen bei ca. `vf_linienzug.lsp:11880-12100`
|
||||
(per Suche nach `climber-span` finden).
|
||||
Die Datei bleibt BEWUSST liegen, obwohl der Auftrag abgeschlossen ist: vier
|
||||
Kommentare in `Lisp/vf_linienzug.lsp` verweisen auf diesen Pfad (Suche nach
|
||||
`modus2-achsenweise-bilanz`). Sie dokumentiert damit nicht mehr einen Plan,
|
||||
sondern WARUM der Solver so bilanziert, wie er es tut - einschliesslich der
|
||||
fehlgeschlagenen Versuche, damit sie niemand ein zweites Mal unternimmt.
|
||||
|
||||
Alles unterhalb dieser Zeile ist der urspruengliche Plan von 2026-09-18 und
|
||||
seine Zwischenstaende. Die dort genannten Zeilennummern sind veraltet; Phase B
|
||||
von `vf-linienzug-modus2` findet man per Suche nach `climber-span`. Die damals
|
||||
vorgeschlagene Zwischenloesung (gefaltete Laeufe mit Meldung abweisen) wurde
|
||||
NICHT umgesetzt und ist gegenstandslos - solche Laeufe funktionieren jetzt.
|
||||
|
||||
## Kurzfassung
|
||||
|
||||
@@ -166,3 +174,220 @@ namentlich (`AS-Fussabdruck ... von Segment N abgezogen`,
|
||||
`Abschluss-Fussabdruck ...`, `Eck-Korrektur ... auf Segment N`). Eine
|
||||
FEHLENDE Zeile ist das Warnsignal - so wurde ein 2,4-mm-Rest gefunden. Fuer
|
||||
die U-Form-Diagnose sind diese Zeilen der schnellste Einstieg.
|
||||
|
||||
---
|
||||
|
||||
## Stand 2026-10-28: Fueller-Seite geloest, Solver-Seite offen
|
||||
|
||||
### Geloest und gemessen
|
||||
|
||||
`vfl-m2-eingang-fp`: GF1 + Separator + Umlenkstation + Uebergangsbogen stehen
|
||||
auf dem Segment `vf-start`. Ist dieses Segment ein FUELLER (der Kletterer
|
||||
liegt hinter einer Kurve), bekam der Fueller bisher die volle Restlaenge, als
|
||||
staende dort nichts. Jetzt werden sie abgezogen.
|
||||
|
||||
Ist das Eingangs-Segment selbst der Kletterer - der gerade Normalfall -, gibt
|
||||
die Funktion hart 0.0 zurueck; der funktionierende Fall kann sich also nicht
|
||||
aendern. Gemessen am U-Form-Testfall: **Querabweichung 8005 -> 1424 mm**,
|
||||
Segment 1 danach auf 0,2 mm genau belegt.
|
||||
|
||||
### Noch offen: der Solver rechnet GF und Stationen gegen die falsche Achse
|
||||
|
||||
Rest 1424 mm. Segment 5 (Kletterer) legt 6475,5 mm zurueck, verfuegbar waeren
|
||||
7899,8 - der Solver reserviert dort Platz fuer Umlenkstation, Separator und
|
||||
den GF1-Anteil, die auf Segment 1 stehen.
|
||||
|
||||
### Fehlgeschlagene Versuche (nicht wiederholen)
|
||||
|
||||
Drei Anlaeufe am 2026-10-27/28, jeder an einer anderen Kopplung gescheitert:
|
||||
|
||||
1. **`feste-vf` kleiner uebergeben.** Geht nicht: `feste-hz` fliesst in
|
||||
`vf-winkel-AB` (vf_standard.lsp:241/245) sowohl als `feste*cos3` in die
|
||||
LAENGE als auch als `feste*sin3` in die HOEHE. Die Hoehe ist real - die
|
||||
Teile senken die Kette ab, egal auf welchem Schenkel sie stehen. Nur der
|
||||
Laengenanteil darf verschoben werden.
|
||||
2. **Spanne vorab korrigieren und iterieren.** Geht nicht direkt:
|
||||
`vfl-zsolve-winkel-waehlen` enthaelt die WINKELFRAGE an den Nutzer - eine
|
||||
Iteration wuerde mehrfach fragen. Und die Korrektur ist pro Winkel
|
||||
verschieden, weil jeder Winkel ein anderes `L_GF` ergibt.
|
||||
3. **Stiller Nachrechner nach der GF-Verteilungsfrage** (Code vorhanden, per
|
||||
`(setq nachrechnen-k 4)` deaktiviert). Technisch sauber: kein Dialog,
|
||||
Fragenfolge und Journal unveraendert, Konvergenz in 4 Runden
|
||||
(3278 -> 4372 -> 4737 -> 4859 -> 4899 mm). ABER er kollidiert mit
|
||||
**`filler-A-len`**: dieser Fueller belegt im Kletter-Segment genau den
|
||||
Platz, den das halbe GF1 dort frei laesst. Nimmt man GF1 aus der
|
||||
Kletterer-Spanne heraus, wird Fueller-A trotzdem gebaut - zusaetzlich zum
|
||||
echten GF1 auf demselben Segment. Gemessen: Fueller nach der
|
||||
Umlenkstation -369 mm (auf 100 geklemmt), Kette 746 mm daneben.
|
||||
Kleinerer Endfehler, aber entartete Geometrie - deshalb zurueckgenommen.
|
||||
|
||||
### Daraus fuer den naechsten Anlauf
|
||||
|
||||
Der Nachrechner ist vermutlich der richtige Weg, aber **`filler-A-len` muss
|
||||
mitbehandelt werden**: er gehoert zur Annahme "GF1 liegt im Kletter-Segment"
|
||||
und darf bei gefaltetem Lauf nicht mehr entstehen. Wer das angeht, sollte
|
||||
beide Mechanismen zusammen betrachten, nicht nacheinander.
|
||||
|
||||
Testfall vorhanden: U-Form 5855 / 270 / 7806 mm (Kletterer hinter zwei
|
||||
90-Grad-Kurven), Soll-Querabweichung ~0, Stand heute 1424 mm. Die beiden
|
||||
geraden Referenzketten in `c:TEST_LINIENZUG_MODUS2` schuetzen den Normalfall.
|
||||
|
||||
---
|
||||
|
||||
## Stand 2026-10-29: Eingangs-Segment exakt, Kletterer-Segment offen
|
||||
|
||||
### Zusaetzlich geloest (gegenueber dem Stand vom 2026-10-28)
|
||||
|
||||
**Fueller-A entfaellt bei gefaltetem Lauf**, und `vfl-m2-eingang-fp` zieht
|
||||
seitdem `br-gf1` ab statt `gf-total`. Beides gehoert zusammen:
|
||||
|
||||
`filler-A-len` fuellt den Platz, den ein halbiertes GF1 auf DERSELBEN Achse
|
||||
frei laesst - er gehoert zur Annahme "GF1 und GF2 liegen auf einer Geraden".
|
||||
Bei gefaltetem Lauf wurde er auf dem Eingangs-Segment ZUSAETZLICH zu GF1
|
||||
gebaut; zusammen mit GF2 im Kletterer-Schenkel entstanden damit 1.5 x
|
||||
gf-total Gefaellestrecke bei einem Budget von gf-total.
|
||||
|
||||
Ergebnis, am U-Form-Testfall nachgerechnet (9 Grad, Verteilung 1/2+1/2):
|
||||
|
||||
```
|
||||
Segment 1: AS 425,8 + GF1 1370,3 + Sep 299,6 + Umlenk 499,3
|
||||
+ Bogen 199,9 + Fueller 3153,7 = 5948,6 mm
|
||||
Budget: 5855 + 93,8 (Eck-Korrektur) = 5948,8 mm
|
||||
```
|
||||
|
||||
Das Eingangs-Segment ist damit **auf 0,2 mm exakt belegt**, und im Protokoll
|
||||
steht nur noch EIN Fueller statt zwei.
|
||||
|
||||
### Was offen bleibt
|
||||
|
||||
Das KLETTERER-Segment. Gemessen im selben Lauf: Segment 5 belegt 6965,8 mm,
|
||||
verfuegbar waeren 7899,8 - es fehlen **934 mm**, exakt die Endabweichung.
|
||||
|
||||
Der Solver bekommt als Spanne 7704,16 mm und verplant darin u.a. GF1
|
||||
(1370,3) sowie Umlenkstation + Separator (798,9) - Teile, die auf Segment 1
|
||||
stehen. Umgekehrt enthaelt seine Spanne NICHT den Abschluss-Fussabdruck
|
||||
(ab_3 + Motorstation, 695 mm), weil dieser nur von FUELLER-Segmenten
|
||||
abgezogen wird (`fill-len`) und das Kletterer-Segment keines ist.
|
||||
|
||||
**Der Restfehler skaliert mit `L_GF`** und damit mit dem gewaehlten Winkel -
|
||||
unabhaengig bestaetigt durch zwei Laeufe auf demselben Pfad:
|
||||
|
||||
| Winkel | L_GF | Querabweichung |
|
||||
|---|---|---|
|
||||
| 6 Grad | 1093 | 90 mm |
|
||||
| 9 Grad | 2744 | 934 mm |
|
||||
|
||||
Praktische Folge: Mit flachem Winkel ist der gefaltete Lauf heute brauchbar,
|
||||
mit steilem nicht.
|
||||
|
||||
### Hinweis zur Methodik fuer den naechsten Anlauf
|
||||
|
||||
Zwei Laeufe sind nur vergleichbar, wenn **Winkel UND GF-Verteilung gleich**
|
||||
sind. Mehrere Messreihen dieser Sitzung waren nicht deutbar, weil sich
|
||||
zwischendurch der Winkel geaendert hatte und der Restfehler mit `L_GF`
|
||||
skaliert. Vor einer Aenderung also eine feste Kombination festlegen
|
||||
(Vorschlag: 12 Grad, Verteilung 1/2+1/2) und nur die vergleichen.
|
||||
|
||||
---
|
||||
|
||||
## Nachtrag 2026-10-29: Loesungsansatz vom Nutzer
|
||||
|
||||
Der Abschnitt darueber beschreibt den Stand VOR dem folgenden Umbau; er bleibt
|
||||
als Herleitung stehen.
|
||||
|
||||
Nutzer-Vorgabe: *"nach der zweiten VF-Kurve den passenden Winkel neu aus dem
|
||||
KS_AUS der Kurve und dem Zielpunkt rechnen"* und *"da GF2 feststeht, steht auch
|
||||
die fuer Auf/Ab verbleibende Laenge fest - passender Winkel plus eine
|
||||
ausgleichende GF"*.
|
||||
|
||||
Das ist die Umkehrung der bisherigen Logik und trifft den Kern: bisher wurde
|
||||
ALLES vorab global verplant und der aufgelaufene Fehler landete am Kettenende.
|
||||
Richtig ist, die letzten freien Groessen aus der GEMESSENEN Ist-Lage zu
|
||||
bestimmen. Je nachdem, was das letzte Segment ist, sind das verschiedene
|
||||
Groessen:
|
||||
|
||||
| Letztes Segment | feste Groesse | freie Groessen |
|
||||
|---|---|---|
|
||||
| flacher Fueller | - | Richtung + Fuellerlaenge |
|
||||
| Auf/Ab-Koerper (U-Form) | Laenge (aus dem Pfad) | Winkel (diskret) + GF-Ausgleich |
|
||||
|
||||
### Umgesetzt
|
||||
|
||||
**1. Flacher Fueller als Schlussstueck** - neue Funktion
|
||||
`vfl-zsolve-schluss-ziel`. Bisher loeste `vfl-zsolve-es-fueller` nur die LAENGE
|
||||
und uebernahm die Richtung aus dem gezeichneten Pfad. Eine Laenge verschiebt die
|
||||
Kette aber nur ENTLANG ihrer Achse - steht der reale Kurvenausgang seitlich
|
||||
NEBEN der gezeichneten Geraden, laeuft die gebaute Achse parallel zur Zielachse
|
||||
und der Querversatz ist unerreichbar. Gibt man die Richtung mit frei, stehen
|
||||
zwei Unbekannte zwei Gleichungen (X und Y) gegenueber, geschlossen loesbar:
|
||||
|
||||
```
|
||||
D = Ziel - KS_AUS(letzte Kurve)
|
||||
A = sqrt(|D|^2 - P^2) ; P = Querversatz des ES-Fussabdrucks
|
||||
fill = A - C
|
||||
hz = Winkel(D) - atan2(P, A)
|
||||
```
|
||||
|
||||
`C` und `P` sind von `hz` unabhaengig, weil `vfl-zsolve-es-vektor` Vektor und
|
||||
Bezugsrahmen um denselben Winkel dreht - deshalb ist keine Iteration noetig.
|
||||
Scheitert der Solve (Ziel naeher als `P`), bleibt der bisherige Weg. Unit-Tests:
|
||||
`tu-tests-vfl-schluss` (file-frei ueber `es-block = nil`).
|
||||
|
||||
**2. Eingangs-Hardware bei gefaltetem Lauf** - der am 2026-10-28 zurueck-
|
||||
genommene Spannen-Zuschlag ist wieder da. Begruendung fuer die Ruecknahme war
|
||||
die Kollision mit `filler-A-len`; dieser Blocker ist entfallen, seit Fueller-A
|
||||
bei gefaltetem Lauf gar nicht mehr entsteht. Zugeschlagen wird weiterhin NUR
|
||||
der Laengenanteil (`entry-fixed * cos3`), nie `feste-vf` selbst - dessen
|
||||
`sin3`-Hoehenanteil ist real.
|
||||
|
||||
**3. Abschluss-Hardware auf dem Kletterer** (`kletter-ende-fp`) - endet der Lauf
|
||||
auf einem FUELLER, zieht `vfl-zsolve-es-fueller` Motorstation + Separator + ES
|
||||
beim Loesen der Fuellerlaenge selbst ab. Endet er auf einem KLETTERER, gibt es
|
||||
diesen Fueller nicht: die drei Teile werden dort gebaut, standen aber in keinem
|
||||
Budget. Abgezogen wird dasselbe wie in dessen Konstante `cc`, OHNE den
|
||||
ab_3-Bogen (der steckt in diesem Fall schon in `uebergang-fp`).
|
||||
|
||||
**4. GF1-Fremdanteil** (Nachrechner wieder aktiv, 8 statt 4 Runden) - `gf-total`
|
||||
ist ein ERGEBNIS des Winkel-Solves, sein auf dem Eingangs-Schenkel stehender
|
||||
Teil laesst sich dort noch nicht abziehen (Henne-Ei). Der Nachrechner loest bei
|
||||
UNVERAENDERTEM Winkel neu und konvergiert mit Faktor ~1/3.
|
||||
|
||||
### Der entscheidende Punkt: 3 und 4 wirken nur GEMEINSAM
|
||||
|
||||
| Posten | im Budget des Solvers | steht real auf dem Kletterer |
|
||||
|---|---|---|
|
||||
| GF1 | ja | nein - liegt im Eingangs-Schenkel |
|
||||
| Motor + Separator + ES | nein | ja |
|
||||
|
||||
Die beiden Betraege heben sich TEILWEISE auf. Wer nur einen davon korrigiert,
|
||||
verschiebt den Fehler bloss in die andere Richtung - genau das war der
|
||||
746-mm-Befund vom 2026-10-28, der damals wie eine Verschlechterung aussah.
|
||||
Gemessen am 9-Grad-Lauf: GF1 1636.9 - (Motor+Sep+ES) 1235.1 = 401.8 mm, exakt
|
||||
die damalige Restabweichung von 401.7 mm.
|
||||
|
||||
### Messergebnis
|
||||
|
||||
| Lauf | vorher | nachher |
|
||||
|---|---|---|
|
||||
| U-Form 9 Grad | 1424 -> 934 mm | **0.56 mm** |
|
||||
| U-Form 12 Grad | - | **0.7 mm** |
|
||||
| Variante A (Vario-Kurve) | OK | OK |
|
||||
| Variante B (GF-Bogen) | OK | OK |
|
||||
|
||||
Zwei verschiedene Winkel auf demselben Pfad - der Restfehler skaliert also
|
||||
nicht mehr mit `L_GF`, die Bilanz selbst stimmt.
|
||||
|
||||
### Regression auf dem Weg dorthin (Lehrstueck)
|
||||
|
||||
`kletter-ende-fp` schlug zunaechst auch in Variante B zu und verkuerzte deren
|
||||
Segment 1 um 798.9 mm. Dort ist `vf-start = vf-ende = 0`: der VF-Lauf besteht
|
||||
aus EINEM Segment, die Segmente 2..5 sind Back-Lauf. Damit ist der Kletterer
|
||||
zugleich Laufende, der Abzug griff - obwohl ohne flache Zone die Motorstation
|
||||
bereits in `feste-vf` steckt und Separator + ES vom Back-Lauf reserviert werden.
|
||||
Die drei Bedingungen am `if` (`hor-pairs > 0`, `vf-ende = n-1`, `es-vorhanden`)
|
||||
sind deshalb keine Vorsichtsmassnahme, sondern benennen genau die Faelle, in
|
||||
denen sonst doppelt gebucht wird.
|
||||
|
||||
Auffindbar war die Ursache nur, weil Segment 1 von Variante B bei `hz=0` liegt:
|
||||
eine Verkuerzung dieses Segments uebersetzt sich 1:1 in `dX`, und `IST - SOLL =
|
||||
(-799.11 | -104.68)` aus `logs/vfl_modus2.dbg` zeigte die reine X-Verschiebung.
|
||||
|
||||
+5
-2
@@ -265,6 +265,7 @@
|
||||
"vfl-m2-segwert-unbekannt": "Segment %1 nicht lesbar: Kette %2 enthaelt einen unbekannten Klassifizierungswert. Aufbau abgebrochen - ein geratener Segmenttyp wuerde die Kette falsch neu bauen.",
|
||||
"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-kletter-ende-fussabdruck": "\n Kletter-Ende: %1 mm von Segment %2 abgezogen (Motorstation + Separator + ES stehen auf dem Kletterer, nicht auf einem Fueller).",
|
||||
"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.",
|
||||
@@ -728,8 +729,8 @@
|
||||
"plq-nichts-zu-loeschen": "\n[DELETE_PLANQUADRATE] Kein Planquadrat-Raster in der Zeichnung vorhanden.",
|
||||
"exp-check-ids": "\n[%1] Pruefe und vergebe IDs...",
|
||||
"exp-hoehencheck-frage": "\nVor dem Export den Hoehen-Check (Montagehoehe/Buehnen) ausfuehren?",
|
||||
"exp-hoehencheck-fehlt": "\nHinweis: HOEHEN_CHECK nicht verfuegbar - Export laeuft ohne Hoehen-Check.",
|
||||
"exp-bereinigen": "\nBereinige Zeichnung (PURGE: unbenutzte Bloecke, Layer, Linientypen) ...",
|
||||
"exp-hoehencheck-fehlt": "\nHinweis: HOEHEN_CHECK nicht verfuegbar - Export laeuft ohne Hoehen-Check.",
|
||||
"exp-hoehen-aktualisiert": "\nHoehen-Attribute von %1 verschobenen Bloecken aus der Z-Koordinate neu gesetzt.",
|
||||
"exp-sep-proxy-fehler": "\n[EXPORT] WARNUNG: Kopie von '%1' aus Block '%2' fehlgeschlagen (%3) - dieses Element fehlt im Export.",
|
||||
"exp-sep-zuordnung": "\n[%1] verpackte Separator-Kopie(n): ZUORDNUNG aus der ID des Wrapper-Blocks gesetzt.",
|
||||
@@ -1236,6 +1237,8 @@
|
||||
"kf-edit-waehlen": "\nKettenfoerderer (KF_n) zum Bearbeiten waehlen: ",
|
||||
"kf-edit-kein-kf": "Der gewaehlte Block ist kein Kettenfoerderer (KF_n).",
|
||||
"kf-edit-fertig": "\n>>> %1 neu aufgebaut als %2.",
|
||||
"cmd-kettenfoerderer-bearbeiten": "\n>>> Kettenfoerderer %1 wird bearbeitet ..."
|
||||
"cmd-kettenfoerderer-bearbeiten": "\n>>> Kettenfoerderer %1 wird bearbeitet ...",
|
||||
"vfl-m2-nachrechnen": "\n Gefalteter Lauf: Laengen bei gleichem Winkel neu aufgeteilt - GF %1 -> %2 mm, Kletterstrecke %3 mm (GF1 liegt im Eingangs-Schenkel und verbraucht die Kletterer-Spanne nicht).",
|
||||
"vfl-m2-nachrechnen-fehl": "Der gewaehlte Winkel %1 Grad geht mit der korrigierten Laengenbilanz nicht mehr auf. Die Kette wird mit der urspruenglichen Aufteilung gebaut und kann daher am Ende zu frueh enden - bitte den Ist/Soll-Vergleich pruefen oder einen anderen Winkel waehlen."
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -265,6 +265,7 @@
|
||||
"vfl-m2-segwert-unbekannt": "Segment %1 cannot be read: chain %2 contains an unknown classification value. Build aborted - guessing a segment type would rebuild the chain incorrectly.",
|
||||
"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-kletter-ende-fussabdruck": "\n Climbing end: %1 mm deducted from segment %2 (motor station + separator + ES sit on the climber, not on a filler).",
|
||||
"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.",
|
||||
@@ -728,8 +729,8 @@
|
||||
"plq-nichts-zu-loeschen": "\n[DELETE_PLANQUADRATE] No Planquadrat grid found in the drawing.",
|
||||
"exp-check-ids": "\n[%1] Checking and assigning IDs...",
|
||||
"exp-hoehencheck-frage": "\nRun the height check (mounting height/platforms) before the export?",
|
||||
"exp-hoehencheck-fehlt": "\nNote: HOEHEN_CHECK not available - export runs without height check.",
|
||||
"exp-bereinigen": "\nPurging drawing (unused blocks, layers, linetypes) ...",
|
||||
"exp-hoehencheck-fehlt": "\nNote: HOEHEN_CHECK not available - export runs without height check.",
|
||||
"exp-hoehen-aktualisiert": "\nHeight attributes of %1 moved blocks reset from their Z coordinate.",
|
||||
"exp-sep-proxy-fehler": "\n[EXPORT] WARNING: copying '%1' out of block '%2' failed (%3) - this element is missing from the export.",
|
||||
"exp-sep-zuordnung": "\n[%1] packed separator copy/copies: ZUORDNUNG set from the wrapper block ID.",
|
||||
@@ -1236,6 +1237,8 @@
|
||||
"kf-edit-waehlen": "\nSelect chain conveyor (KF_n) to edit: ",
|
||||
"kf-edit-kein-kf": "The selected block is not a chain conveyor (KF_n).",
|
||||
"kf-edit-fertig": "\n>>> %1 rebuilt as %2.",
|
||||
"cmd-kettenfoerderer-bearbeiten": "\n>>> Editing chain conveyor %1 ..."
|
||||
"cmd-kettenfoerderer-bearbeiten": "\n>>> Editing chain conveyor %1 ...",
|
||||
"vfl-m2-nachrechnen": "\n Folded run: lengths redistributed at the same angle - GF %1 -> %2 mm, climbing section %3 mm (GF1 sits in the entry leg and does not consume the climber span).",
|
||||
"vfl-m2-nachrechnen-fehl": "The chosen angle of %1 degrees no longer works with the corrected length balance. The chain is built with the original distribution and may therefore end too early - please check the actual/target comparison or pick a different angle."
|
||||
}
|
||||
}
|
||||
|
||||
+130
-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 _ez)
|
||||
(defun tu-tests-vfl-parallel ( / _b30 _b60 _b90 _kand _l _plan _plan3 _g _p _w _ez _plan2)
|
||||
(princ "\n[vf_linienzug Parallel zum Kreisel]")
|
||||
|
||||
;; --- Bogenwahl: der Bogen muss den AS-Schwenk GENAU aufheben ---
|
||||
@@ -610,6 +610,85 @@
|
||||
(tu-nil "vfl-wert-norm/kein-string"
|
||||
(vfl-wert-norm 1 *vfl-m2-linie-werte* *vfl-m2-linie-alt*))
|
||||
|
||||
;; --- Gefalteter VF-Lauf erkennen (Schenkel = Fahrtrichtungen) ---
|
||||
;; Der Modus-2-Solver bilanziert skalar ueber EINE Achse. Liegt der Lauf
|
||||
;; gefaltet (U-Form), sitzen die festen Teile in einem anderen Schenkel als
|
||||
;; die Kletterstrecke und die Kette wird sichtbar falsch gebaut. Bis die
|
||||
;; Bilanz achsenweise rechnet, wird so ein Lauf abgewiesen - diese
|
||||
;; Erkennung entscheidet darueber.
|
||||
;; Plan-Eintraege: Linie = ("Linie" hz laenge typ ...), Bogen = ("Bogen" hz ...)
|
||||
(setq _plan2 (list (list "Linie" 0.0 9700.0 "VF" nil)
|
||||
(list "Bogen" 0.0 707.1 90 "rechts" "Vario-Kurve" "aussen")
|
||||
(list "Linie" -90.0 4296.0 "VF" nil)))
|
||||
(tu-eq "vfl-m2-schenkel/u-form-zwei-richtungen" 2
|
||||
(length (vfl-m2-schenkel _plan2 0 2)))
|
||||
(tu-true "vfl-m2-gefaltet/u-form" (vfl-m2-gefaltet-p _plan2 0 2))
|
||||
;; Gerader Lauf: eine Richtung, auch ueber mehrere Geraden hinweg.
|
||||
(setq _plan2 (list (list "Linie" 0.0 9700.0 "VF" nil)
|
||||
(list "Linie" 0.0 2000.0 "VF" nil)))
|
||||
(tu-eq "vfl-m2-schenkel/gerade-eine-richtung" 1
|
||||
(length (vfl-m2-schenkel _plan2 0 1)))
|
||||
(tu-nil "vfl-m2-gefaltet/gerade" (vfl-m2-gefaltet-p _plan2 0 1))
|
||||
;; Zurueck auf dieselbe Richtung zaehlt als NEUER Schenkel - die Kette ist
|
||||
;; dann seitlich versetzt, die Laengen liegen nicht mehr auf einer Linie.
|
||||
(setq _plan2 (list (list "Linie" 0.0 3000.0 "VF" nil)
|
||||
(list "Bogen" 0.0 707.1 90 "rechts" "Vario-Kurve" "aussen")
|
||||
(list "Linie" -90.0 1000.0 "VF" nil)
|
||||
(list "Bogen" -90.0 707.1 90 "links" "Vario-Kurve" "aussen")
|
||||
(list "Linie" 0.0 3000.0 "VF" nil)))
|
||||
(tu-eq "vfl-m2-schenkel/u-form-drei" 3
|
||||
(length (vfl-m2-schenkel _plan2 0 4)))
|
||||
;; Winkel werden normalisiert: 270 und -90 sind dieselbe Richtung.
|
||||
(setq _plan2 (list (list "Linie" -90.0 1000.0 "VF" nil)
|
||||
(list "Linie" 270.0 1000.0 "VF" nil)))
|
||||
(tu-eq "vfl-m2-schenkel/270-gleich-minus90" 1
|
||||
(length (vfl-m2-schenkel _plan2 0 1)))
|
||||
|
||||
;; --- Eingangs-Hardware auf einem Fueller-Segment ---
|
||||
;; Steht der Lauf-Eingang (GF1 + Separator + Umlenkstation + Bogen) auf
|
||||
;; einem FUELLER, muss dessen Laenge abgezogen werden - sonst bekommt der
|
||||
;; Fueller die volle Restlaenge, als staende dort nichts (real 2026-10-27:
|
||||
;; 5855 mm Plan, 10668 mm belegt, Kette 8005 mm daneben).
|
||||
;; Ist das Eingangs-Segment selbst der Kletterer, steckt dieselbe Laenge
|
||||
;; schon in feste-vf - dann MUSS der Abzug 0 sein, sonst doppelt.
|
||||
(tu-eqf "vfl-m2-eingang-fp/kletterer-kein-abzug" 0.0
|
||||
(vfl-m2-eingang-fp 0 0 '(0) 3726.34 (* 3.0 (/ pi 180.0))))
|
||||
;; Anderes Segment als der Eingang: ebenfalls nichts.
|
||||
(tu-eqf "vfl-m2-eingang-fp/fremdes-segment" 0.0
|
||||
(vfl-m2-eingang-fp 2 0 '(2) 3726.34 (* 3.0 (/ pi 180.0))))
|
||||
;; Eingang ist Fueller (Kletterer liegt woanders): GF1 + 300 + 500,
|
||||
;; projiziert auf 3 Grad, plus der Uebergangsbogen aus der Tabelle.
|
||||
;; Die DIFFERENZ zweier Aufrufe prueft den GF-Anteil exakt und kommt ohne
|
||||
;; die Bogen-Tabelle aus - die ist im file-freien Unit-Test leer
|
||||
;; (init-bibliothek laeuft hier nicht), der Bogenanteil faellt also weg.
|
||||
;; Eine absolute Schranke waere dadurch umgebungsabhaengig gewesen.
|
||||
(tu-eqf "vfl-m2-eingang-fp/gf-anteil-exakt"
|
||||
(* 3726.34 (cos (* 3.0 (/ pi 180.0))))
|
||||
(- (vfl-m2-eingang-fp 0 0 '(2) 3726.34 (* 3.0 (/ pi 180.0)))
|
||||
(vfl-m2-eingang-fp 0 0 '(2) 0.0 (* 3.0 (/ pi 180.0)))))
|
||||
;; Separator + Umlenkstation sind IMMER dabei, auch ohne GF und ohne Tabelle.
|
||||
(setq _l (vfl-m2-eingang-fp 0 0 '(2) 0.0 (* 3.0 (/ pi 180.0))))
|
||||
(tu-true "vfl-m2-eingang-fp/stationen-immer-dabei"
|
||||
(>= _l (* (+ *vfk-separator-laenge* *vfk-stations-laenge*)
|
||||
(cos (* 3.0 (/ pi 180.0))))))
|
||||
|
||||
;; --- Fremdanteil der Gefaellestrecke (fuer den stillen Nachrechner) ---
|
||||
;; Wieviel der vom Solver berechneten GF liegt NICHT auf dem Schenkel des
|
||||
;; Kletterers? Nur das darf dessen Spanne wieder zugeschlagen werden.
|
||||
;; Liegt der Eingang auf dem Kletterer selbst (gerader Normalfall), ist
|
||||
;; nichts fremd - dann MUSS 0 herauskommen, sonst wuerde der funktionierende
|
||||
;; Fall veraendert.
|
||||
(tu-eqf "vfl-m2-gf-fremd/eingang-ist-kletterer" 0.0
|
||||
(vfl-m2-gf-fremdanteil 3726.34 1 T))
|
||||
(tu-eqf "vfl-m2-gf-fremd/alles-einlauf" 3726.34
|
||||
(vfl-m2-gf-fremdanteil 3726.34 1 nil))
|
||||
(tu-eqf "vfl-m2-gf-fremd/halb-halb" 1863.17
|
||||
(vfl-m2-gf-fremdanteil 3726.34 2 nil))
|
||||
;; Alles am Auslauf (Modus 3, erzwungen bei offenem Anfang): die GF liegt
|
||||
;; dann beim Kletterer, nichts ist fremd.
|
||||
(tu-eqf "vfl-m2-gf-fremd/alles-auslauf" 0.0
|
||||
(vfl-m2-gf-fremdanteil 3726.34 3 nil))
|
||||
|
||||
;; --- 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
|
||||
@@ -2957,6 +3036,55 @@
|
||||
)
|
||||
|
||||
|
||||
;; --- Schlussstueck: Richtung UND Laenge aus der IST-Lage ---------------------
|
||||
;; vfl-zsolve-schluss-ziel loest den letzten Fueller gegen den Zielpunkt, mit der
|
||||
;; Richtung als zweiter Unbekannter. Mit es-block = nil braucht die Funktion
|
||||
;; weder Zeichnung noch Blockdatei - der Querversatz P ist dann 0 und uebrig
|
||||
;; bleibt die reine Geometrie.
|
||||
;; Bewusst NICHT gegen eine nachgerechnete Konstante C geprueft (das waere die
|
||||
;; Formel ein zweites Mal hingeschrieben), sondern gegen Eigenschaften, die
|
||||
;; unabhaengig von C gelten: der Winkel zeigt exakt zum Ziel, und eine
|
||||
;; Zielverschiebung bzw. ein groesseres GF2 schlaegt 1:1 auf die Laenge durch.
|
||||
(defun tu-tests-vfl-schluss ( / _rad3 _p0 _a _b _c _d)
|
||||
(princ "\n[vf_linienzug Schlussstueck]")
|
||||
(setq _rad3 (/ (* 3.0 pi) 180.0)
|
||||
_p0 '(0.0 0.0 0.0))
|
||||
|
||||
;; Der Winkel zeigt ohne ES-Element exakt zum Zielpunkt (P = 0).
|
||||
(tu-eqf "vfl-zsolve-schluss-ziel/winkel-ost"
|
||||
0.0 (cadr (vfl-zsolve-schluss-ziel _p0 '(10000.0 0.0 0.0) 0.0 nil 0.0 _rad3)))
|
||||
(tu-eqf "vfl-zsolve-schluss-ziel/winkel-nord"
|
||||
90.0 (cadr (vfl-zsolve-schluss-ziel _p0 '(0.0 10000.0 0.0) 0.0 nil 0.0 _rad3)))
|
||||
;; 3/4/5-Dreieck: die Richtung folgt dem Ziel, NICHT dem uebergebenen seg-hz.
|
||||
;; Genau das ist der Kern der Aenderung - darum wird hier ein voellig anderer
|
||||
;; Planwinkel (-137) hineingegeben.
|
||||
(tu-eqf "vfl-zsolve-schluss-ziel/winkel-folgt-ziel-nicht-plan"
|
||||
(/ (* 180.0 (atan 4000.0 3000.0)) pi)
|
||||
(cadr (vfl-zsolve-schluss-ziel _p0 '(3000.0 4000.0 0.0) -137.0 nil 0.0 _rad3)))
|
||||
|
||||
;; Laenge: 1000 mm weiter entferntes Ziel -> 1000 mm mehr Fueller.
|
||||
(setq _a (car (vfl-zsolve-schluss-ziel _p0 '(10000.0 0.0 0.0) 0.0 nil 0.0 _rad3))
|
||||
_b (car (vfl-zsolve-schluss-ziel _p0 '(11000.0 0.0 0.0) 0.0 nil 0.0 _rad3)))
|
||||
(tu-eqf "vfl-zsolve-schluss-ziel/laenge-folgt-ziel" 1000.0 (- _b _a))
|
||||
|
||||
;; GF2 steht im Schwanz und liegt unter 3 Grad: 1000 mm GF2 verbrauchen
|
||||
;; 1000*cos(3) in der Laengsrichtung, der Fueller wird genau darum kuerzer.
|
||||
(setq _c (car (vfl-zsolve-schluss-ziel _p0 '(10000.0 0.0 0.0) 0.0 nil 1000.0 _rad3)))
|
||||
(tu-eqf "vfl-zsolve-schluss-ziel/gf2-verkuerzt-fueller"
|
||||
(* 1000.0 (cos _rad3)) (- _a _c))
|
||||
|
||||
;; Die Loesung ist richtungsunabhaengig: dasselbe Ziel, um 90 Grad gedreht,
|
||||
;; ergibt dieselbe Fuellerlaenge.
|
||||
(setq _d (car (vfl-zsolve-schluss-ziel _p0 '(0.0 10000.0 0.0) 0.0 nil 0.0 _rad3)))
|
||||
(tu-eqf "vfl-zsolve-schluss-ziel/laenge-drehinvariant" _a _d)
|
||||
|
||||
;; Kein loesbarer Fall: Ziel liegt auf dem Startpunkt -> nil (Aufrufer faellt
|
||||
;; dann auf den bisherigen Weg zurueck, statt etwas zu raten).
|
||||
(tu-nil "vfl-zsolve-schluss-ziel/ziel-auf-startpunkt"
|
||||
(vfl-zsolve-schluss-ziel _p0 '(0.0 0.0 0.0) 0.0 nil 0.0 _rad3))
|
||||
)
|
||||
|
||||
|
||||
(defun c:TEST_UNIT ( / out-dir report)
|
||||
(tu-reset)
|
||||
(princ "\n================================================================")
|
||||
@@ -2969,6 +3097,7 @@
|
||||
"tu-tests-export" "tu-tests-hoehen" "tu-tests-gf" "tu-tests-omni" "tu-tests-kreisel" "tu-tests-kreisel-bp"
|
||||
"tu-tests-sepliste" "tu-tests-json" "tu-tests-geruest"
|
||||
"tu-tests-sepscan" "tu-tests-vfl-segs" "tu-tests-vfl-abbruch"
|
||||
"tu-tests-vfl-schluss"
|
||||
"tu-tests-werkzeuge" "tu-tests-kf" "tu-tests-hoehen-fam")
|
||||
(tu-run-block fn))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user