[FIX] GF aus Kreisel-Hoehen endeten bei steiler Neigung vor der Kette des unteren Kreisels (Showroom ~144 mm bei 43 Grad, Hoehe stimmte): mubea:gf-bauen zog die FLACH gemessene ES-Laenge ein-dx ab, geneigt ist das ES horizontal deutlich kuerzer. Neu dematic_arvato:gf-geometrie (Winkel UND Staustreckenlaenge, ES-Laenge und -Abfall bei der Einlaufneigung per dematic_arvato:es-mass gemessen und iteriert) + dematic_arvato:gf-bauen-exakt (gefaellestrecke-einfuegen mit dieser Staustreckenlaenge); ersetzt dematic_arvato:gf-winkel. Doku in CLAUDE.md und test_showroom_ils.lsp nachgezogen

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 15:49:18 +02:00
parent 4edf294dd2
commit f23a6fd0c2
3 changed files with 98 additions and 49 deletions
+95 -47
View File
@@ -36,7 +36,8 @@
;; "modus": 1 -> Gefaellestrecke ueber mubea:gf-bauen
;; (start_mm + deltaL_mm, kein Endpunkt). Mit
;; hoehe_ende_mm (Hoehe des Kreisels am Ende)
;; rechnet dematic_arvato:gf-winkel den Winkel,
;; rechnet dematic_arvato:gf-geometrie Winkel
;; und Staustreckenlaenge (gf-bauen-exakt),
;; sonst gilt winkel_grad.
;; "typ": "gerade" -> waagrechter Foerderer aus der Scanner-Vorlage -
;; kein Bau-Pfad, wird gemeldet und uebersprungen
@@ -97,59 +98,99 @@
(vsp-set (vsp-set rec "status" "uebersprungen") "fehler_text"
"kein Bau-Pfad fuer typ gerade"))
;; Gefaellewinkel aus Start- und Endhoehe - derselbe Loeser wie Modus 3
;; (gf-winkel-berechnen, Gefaellestrecke.lsp) mit den AS/ES-Massen der
;; aktuellen 2D/3D-Bibliothek. Die Kette ist eine einzige Gerade plus der
;; eine Separator vor dem ES (extra-sep 1); ihre Laenge ohne AS/ES/Separator
;; ist deltaL - aus-dx - ein-dx - 300, damit ergibt der Loeser als
;; Gesamtlaenge wieder genau deltaL (deltaL reicht von AS- bis ES-Ursprung).
;; VORZEICHEN: vf-set-as-masse (vf_core) misst dz als KS_AUS.z - KS_EIN.z
;; (bei AS/ES negativ), gf-winkel-berechnen erwartet die Konvention von
;; gf-init-bibliothek (KS_EIN.z - KS_AUS.z, positiv) und zieht den Wert ab.
;; Mit der VF-Konvention wurde der feste AS/ES-Abfall addiert statt
;; abgezogen - real gebaut: 3.79 statt ~2.49 Grad, GF endete 258 mm unter
;; dem Kreisel (HOEHE_BIS 1568 statt 1826). Darum hier der Betrag.
;; ES-Element bei Einlaufneigung w (Grad, bergab) in Fahrtrichtung hz
;; vermessen: horizontale Laenge entlang hz und Abfall von KS_EIN bis KS_AUS.
;; Wie gf-messe-dz-block (Gefaellestrecke.lsp), liefert aber zusaetzlich die
;; Laenge - beide aendern sich mit der Neigung (90-Grad-ES flach ~436 mm
;; lang, bei 43 Grad nur noch ~292 mm).
;; Rueckgabe: (dx dz), dz positiv = nach unten.
(defun dematic_arvato:es-mass (blockname hz w / rad-h rad-v frame-aus ent-vor ent-nach p)
(setq rad-h (* hz (/ pi 180.0))
rad-v (* w (/ pi 180.0)))
(setq ent-vor (entlast))
(setq frame-aus
(insert-block-ks-to-ks blockname
(make-frame-from-dir '(0 0 0)
(list (* (cos rad-h) (cos rad-v)) (* (sin rad-h) (cos rad-v))
(- (sin rad-v))))))
(setq ent-nach (entlast))
(if (and ent-nach (not (eq ent-nach ent-vor))) (entdel ent-nach))
(setq p (car frame-aus))
(list (+ (* (car p) (cos rad-h)) (* (cadr p) (sin rad-h)))
(- 0.0 (caddr p))))
;; Winkel UND Staustreckenlaenge einer GF (Modus 1) aus Start- und Endhoehe,
;; so dass der ES-Auslauf genau auf Hoehe UND Kette des unteren Kreisels
;; liegt. deltaL reicht von AS-KS_EIN bis ES-KS_AUS (horizontal).
;;
;; NICHT gf-winkel-berechnen: dessen asin(dH / L) behandelt die Laenge als
;; SCHRAEGE Laenge (richtig fuer Modus 3). Modus 1 haelt aber die
;; HORIZONTALE Laenge deltaL fest und streckt die Staustrecke um 1/cos(w)
;; (mubea:gf-bauen) - der Abfall der Schraege (Staustrecke + Separator) ist
;; dann genau (deltaL - aus-dx - ein-dx) * tan(w). Bei 2-3 Grad (Dematic)
;; ist das gleich, bei steilen GF nicht: Showroom_ILS_3_0 faellt 1860 mm auf
;; 2405 mm (~37 Grad), asin ergab ~50 Grad und die GF endete weit unter dem
;; unteren Kreisel. Der Abfall des ES haengt von der Einlaufneigung ab - er
;; wird wie in Modus 3 (gf-messe-dz-block) beim aktuellen Winkel gemessen
;; und iteriert; das AS liegt flach, sein Abfall ist fest (aus-dz).
(defun dematic_arvato:gf-winkel (deltaL hz as-seite es-seite as-winkel es-winkel
z-start z-ende / L dz-as dz-es winkel vorher
iter rad-h rad-v)
;; H = deltaL - aus-dx - es_dx(w) horizontale Laenge der Schraege
;; tan(w) = (dH - aus-dz - es_dz(w)) / H Schraege = Staustrecke + Separator
;; L_stau = H / cos(w) - 300
;;
;; es_dx/es_dz werden beim aktuellen Winkel gemessen (dematic_arvato:es-mass)
;; und iteriert; das AS liegt flach, aus-dx/aus-dz sind fest.
;;
;; Warum nicht mubea:gf-bauen / gf-winkel-berechnen:
;; - gf-winkel-berechnen rechnet asin(dH / L), also mit SCHRAEGER Laenge
;; (Modus 3); Modus 1 haelt aber die horizontale Laenge fest. Bei 2-3 Grad
;; (Dematic) gleich, bei den steilen Showroom-GF (1860 mm auf 2405 mm)
;; ~50 statt ~43 Grad - die GF endete weit unter dem Kreisel.
;; - mubea:gf-bauen zieht die FLACH gemessene ES-Laenge ein-dx ab. Bei 43
;; Grad ist das ES horizontal ~144 mm kuerzer, die GF hoerte so 144 mm
;; vor der Kette des unteren Kreisels auf (Hoehe stimmte).
;; VORZEICHEN: vf-set-as-masse misst aus-dz als KS_AUS.z - KS_EIN.z
;; (negativ) - darum der Betrag (Dematic: sonst HOEHE_BIS 1568 statt 1826).
;; Rueckgabe: (winkel L_stau)
(defun dematic_arvato:gf-geometrie (deltaL hz as-seite es-seite as-winkel es-winkel
z-start z-ende / es-block dH es H winkel vorher
iter dx-as dz-as)
(mubea:ensure-gf-init)
(vf-set-as-masse as-winkel as-seite)
(vf-set-es-masse es-winkel es-seite)
(setq L (- deltaL (float aus-dx) (float ein-dx))
dz-as (abs (float aus-dz))
dz-es (abs (float ein-dz))
rad-h (* hz (/ pi 180.0))
vorher -999.0
iter 0)
(setq winkel (* (atan (- z-start z-ende dz-as dz-es) L) (/ 180.0 pi)))
(while (and (< iter 6) (> (abs (- winkel vorher)) 0.001))
(setq es-block (strcat "ES_Element_" es-winkel "_" es-seite)
dx-as (float aus-dx)
dz-as (abs (float aus-dz))
dH (- z-start z-ende)
es (list (float ein-dx) (abs (float ein-dz)))
vorher -999.0
iter 0)
(setq H (- deltaL dx-as (car es))
winkel (* (atan (- dH dz-as (cadr es)) H) (/ 180.0 pi)))
(while (and (< iter 8) (> (abs (- winkel vorher)) 0.0005))
(setq vorher winkel
rad-v (* winkel (/ pi 180.0)))
(setq dz-es (gf-messe-dz-block (strcat "ES_Element_" es-winkel "_" es-seite)
(list (* (cos rad-h) (cos rad-v)) (* (sin rad-h) (cos rad-v))
(- (sin rad-v)))))
(setq winkel (* (atan (- z-start z-ende dz-as dz-es) L) (/ 180.0 pi))
es (dematic_arvato:es-mass es-block hz winkel)
H (- deltaL dx-as (car es))
winkel (* (atan (- dH dz-as (cadr es)) H) (/ 180.0 pi))
iter (1+ iter)))
(vf-set-as-masse "90" as-seite)
(vf-set-es-masse "90" es-seite)
winkel)
(list winkel (- (/ H (cos (* winkel (/ pi 180.0)))) 300.0)))
;; GF mit vorgegebener Staustreckenlaenge einfuegen (wie mubea:gf-bauen, aber
;; L_stau kommt aus dematic_arvato:gf-geometrie statt aus der flachen
;; ES-Laenge).
(defun dematic_arvato:gf-bauen-exakt (tid start-mm deltaL hz as-seite es-seite
as-winkel es-winkel winkel L_stau / ent)
(mubea:ensure-gf-init)
;; Element-Masse der Variante wie in mubea:gf-bauen, danach zurueck auf 90
(vf-set-as-masse as-winkel as-seite)
(vf-set-es-masse es-winkel es-seite)
(princ (strcat "\n [GF] " tid " -> Start=(" (rtos (car start-mm) 2 0)
"," (rtos (cadr start-mm) 2 0) "," (rtos (caddr start-mm) 2 0)
") hz=" (rtos hz 2 0) " deltaL=" (rtos deltaL 2 0)
" winkel=" (rtos winkel 2 3) " L_stau=" (rtos L_stau 2 1)))
(setq ent (car (gefaellestrecke-einfuegen
L_stau winkel start-mm as-seite es-seite hz
deltaL as-winkel es-winkel "0" "Schoenenberger Geruest")))
(vf-set-as-masse "90" as-seite)
(vf-set-es-masse "90" es-seite)
ent)
;; Gefaellestrecke (Modus 1) bauen - Felder wie mubea:build-gf, ohne dessen
;; anzahl/delta-Vervielfaeltigung (jede GF steht einzeln in der Datei).
;; Mit "hoehe_ende_mm" (Hoehe des Kreisels am Ende) wird der Winkel daraus
;; gerechnet, sonst gilt "winkel_grad" (Default 3.0).
(defun dematic_arvato:bau-gf (obj / tid start deltaL hz winkel z-ende
(defun dematic_arvato:bau-gf (obj / tid start deltaL hz winkel z-ende geo
as-seite es-seite as-winkel es-winkel rec)
(setq tid (ssg-val obj "test_id")
start (ssg-val obj "start_mm")
@@ -177,12 +218,15 @@
(vsp-set (vsp-set rec "status" "spec-fehler") "fehler_text"
"hoehe_ende_mm >= start_mm.z - kein Gefaelle"))
(T
;; Mit Endhoehe: Winkel + Staustreckenlaenge exakt (gf-geometrie),
;; sonst fester Winkel ueber mubea:gf-bauen.
(setq geo (if (numberp z-ende)
(dematic_arvato:gf-geometrie (float deltaL) (float hz)
as-seite es-seite as-winkel es-winkel
(float (caddr start)) (float z-ende))))
(setq winkel
(cond
((numberp z-ende)
(dematic_arvato:gf-winkel (float deltaL) (float hz) as-seite es-seite
as-winkel es-winkel
(float (caddr start)) (float z-ende)))
(geo (car geo))
((numberp winkel) (float winkel))
(T 3.0)))
;; Winkel und Soll-Endhoehe als Meldung (das Record-Schema aus vf_spec
@@ -195,8 +239,12 @@
"")))))
(setq rec
(dematic_arvato:rec-block rec
(mubea:gf-bauen tid (mapcar 'float start) (float deltaL) (float hz)
as-seite es-seite as-winkel es-winkel winkel)
(if geo
(dematic_arvato:gf-bauen-exakt tid (mapcar 'float start) (float deltaL)
(float hz) as-seite es-seite as-winkel
es-winkel winkel (cadr geo))
(mubea:gf-bauen tid (mapcar 'float start) (float deltaL) (float hz)
as-seite es-seite as-winkel es-winkel winkel))
"gefaellestrecke-einfuegen lieferte keinen GF-Block"))
;; Ist-Endhoehe gegen den Kreisel am Ende pruefen
(dematic_arvato:gf-endhoehe-pruefen rec z-ende))))
+2 -1
View File
@@ -27,7 +27,8 @@
;; angenaehert (Radmitten = Mittelpunkte der PIN-Kreise).
;; - Weichen (WB-*/WM-*/WL-*/WR-*) werden bewusst NICHT nachgebaut.
;; - Die GF sind steil (1860 bzw. 1495 mm Abfall auf 2405 mm) - den Winkel
;; rechnet dematic_arvato:gf-winkel aus hoehe_ende_mm, und
;; und die Staustreckenlaenge rechnet dematic_arvato:gf-geometrie aus
;; hoehe_ende_mm (ES-Masse bei der Neigung gemessen), und
;; dematic_arvato:gf-endhoehe-pruefen meldet "warnung", wenn eine GF
;; den unteren Kreisel um mehr als 5 mm verfehlt.
;;