From cee2a81b5538bff45c3b5d96f6127115cafe11f0 Mon Sep 17 00:00:00 2001 From: Michael Stangl Date: Mon, 27 Jul 2026 22:16:36 +0200 Subject: [PATCH] =?UTF-8?q?Variof=C3=B6rderer=20Masse=20ge=C3=A4ndert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_mubea.lsp | 85 +++++++++++++++++++++++---------------- tests/test_mubea.py | 12 +++--- tests/testdata/mubea.json | 4 +- 3 files changed, 58 insertions(+), 43 deletions(-) diff --git a/tests/test_mubea.lsp b/tests/test_mubea.lsp index 05d098c..aa9691b 100644 --- a/tests/test_mubea.lsp +++ b/tests/test_mubea.lsp @@ -100,55 +100,70 @@ ) -;; --- Vario (VF_*): deltaL/L_VF fuer winkel+deltaH loesen, dann bauen --- -(defun mubea:build-vario (e / tid richtung deltaH winkel gf1 gf2 gf-ziel seite hz - startpunkt dlA dlB it1 it2 lgfA lgfB steig dL item L_VF - hoehe-bis lastEnt ent) - (setq tid (ssg-val e "test_id") - richtung (ssg-val e "richtung") - deltaH (float (ssg-val e "deltaH")) - winkel (fix (ssg-val e "winkel")) - gf1 (float (ssg-val e "L_GF1")) - gf2 (float (ssg-val e "L_GF2")) - seite (ssg-val e "seite") - hz (ssg-val e "hz") +;; --- Vario (VF_*): L_GF/L_VF fuer gegebenes deltaL+deltaH+winkel loesen, dann bauen --- +;; deltaL ist (wie bei der Gefaellestrecke) die horizontale PROJIZIERTE +;; Gesamtlaenge des VF (Vorlauf L_GF1 + Foerderer L_VF + Nachlauf L_GF2 + +;; Boegen/AS-ES-Elemente), analog foerderer_tests.json/object_data.md 3.1 - +;; KEIN abgeleiteter Wert. "winkel" erzwingt einen bestimmten Bogenwinkel aus +;; der Kandidatenliste von berechne-alle-winkel (wie foerderer:winkel- +;; erzwingen in test_foerderer.lsp), statt den automatisch kleinsten +;; gueltigen Winkel zu nehmen. L_GF1 aus JSON ist der Vorlauf-Zielwert; +;; L_GF2 (Nachlauf) ist der Rest (L_GF_gesamt - L_GF1). +(defun mubea:build-vario (e / tid richtung deltaH deltaL winkel-soll gf1-ziel seite hz + startpunkt ergebnis winkel-treffer best-winkel L_GF L_VF + gf1 gf2 hoehe-bis lastEnt ent) + (setq tid (ssg-val e "test_id") + richtung (ssg-val e "richtung") + deltaL (float (ssg-val e "deltaL")) + deltaH (float (ssg-val e "deltaH")) + winkel-soll(ssg-val e "winkel") + gf1-ziel (float (ssg-val e "L_GF1")) + seite (ssg-val e "seite") + hz (ssg-val e "hz") startpunkt (list (float (ssg-val e "x")) (float (ssg-val e "y")) (float (ssg-val e "z")))) (if (or (null seite) (= seite "")) (setq seite "links")) (if (null hz) (setq hz 0.0) (setq hz (float hz))) - (setq gf-ziel (+ gf1 gf2)) - (princ (strcat "\n [VARIO] " tid " -> Winkel=" (itoa winkel) - " deltaH=" (rtos deltaH 2 0) " L_GF1=" (rtos gf1 2 0) - " L_GF2=" (rtos gf2 2 0))) + (princ (strcat "\n [VARIO] " tid " -> deltaL=" (rtos deltaL 2 0) + " deltaH=" (rtos deltaH 2 0) + " Winkel(soll)=" (if winkel-soll (itoa (fix winkel-soll)) "auto") + " L_GF1-Ziel=" (rtos gf1-ziel 2 0))) - ;; L_GF ist linear in deltaL -> deltaL aus zwei Stuetzstellen interpolieren, - ;; sodass L_GF gesamt = gf-ziel am gewaehlten Winkel. - (setq dlA 5000.0 dlB 10000.0) - (setq it1 (car (vl-remove-if-not '(lambda (a) (= (car a) winkel)) - (cadddr (berechne-alle-winkel dlA deltaH richtung nil))))) - (setq it2 (car (vl-remove-if-not '(lambda (a) (= (car a) winkel)) - (cadddr (berechne-alle-winkel dlB deltaH richtung nil))))) - (if (and it1 it2 (numberp (cadr it1)) (numberp (cadr it2)) - (/= (cadr it1) (cadr it2))) + (setq ergebnis (berechne-alle-winkel deltaL deltaH richtung nil)) + (setq best-winkel (car ergebnis) L_GF (cadr ergebnis) L_VF (caddr ergebnis)) + (if (numberp winkel-soll) (progn - (setq lgfA (cadr it1) lgfB (cadr it2)) - (setq steig (/ (- lgfB lgfA) (- dlB dlA))) - (setq dL (+ dlA (/ (- gf-ziel lgfA) steig))) - (setq item (car (vl-remove-if-not '(lambda (a) (= (car a) winkel)) - (cadddr (berechne-alle-winkel dL deltaH richtung nil))))) - (setq L_VF (caddr item)) - (princ (strcat " -> deltaL=" (rtos dL 2 1) " L_VF=" (rtos L_VF 2 1))) + (setq winkel-treffer + (car (vl-remove-if-not '(lambda (a) (= (car a) (fix winkel-soll))) + (cadddr ergebnis)))) + (if (and winkel-treffer (cadddr winkel-treffer) + (numberp (cadr winkel-treffer)) (numberp (caddr winkel-treffer)) + (> (cadr winkel-treffer) 0) (> (caddr winkel-treffer) 0)) + (setq best-winkel (car winkel-treffer) + L_GF (cadr winkel-treffer) + L_VF (caddr winkel-treffer)) + (setq best-winkel nil L_GF nil L_VF nil)))) + + (if (and best-winkel L_GF L_VF (> L_GF 0) (> L_VF 0)) + (progn + (setq gf1 (min gf1-ziel L_GF)) + (setq gf2 (max 0.0 (- L_GF gf1))) + (princ (strcat " -> Winkel=" (itoa best-winkel) " L_GF=" (rtos L_GF 2 1) + " L_VF=" (rtos L_VF 2 1) " L_GF1=" (rtos gf1 2 1) + " L_GF2=" (rtos gf2 2 1))) (setq hoehe-bis (if (= richtung "Auf") deltaH (- deltaH))) (setq lastEnt (vf-lastent-ohne-attribute)) - (variofoerderer-einfuegen dL deltaH richtung winkel gf1 gf2 L_VF startpunkt seite hz) + (variofoerderer-einfuegen deltaL deltaH richtung best-winkel gf1 gf2 L_VF startpunkt seite hz) (setq ent (vf-block-erstellen "standard" seite 1 0 0 hoehe-bis - deltaH dL L_VF gf1 gf2 richtung winkel + deltaH deltaL L_VF gf1 gf2 richtung best-winkel startpunkt lastEnt hz "0" "Schoenenberger Geruest")) (if (or (null ent) (/= (type ent) 'ENAME)) (setq ent (mubea:last-insert-prefix "VF_"))) (mubea:ent-json tid "vario" ent)) (progn - (princ (strcat "\n FEHLER: Winkel " (itoa winkel) " nicht loesbar (kein gueltiges L_GF).")) + (princ (strcat "\n FEHLER: deltaL=" (rtos deltaL 2 0) + " bei Winkel " (if winkel-soll (rtos winkel-soll 2 0) "auto") + " nicht loesbar (kein gueltiges L_GF/L_VF).")) (mubea:result-json tid "vario" "failed" nil nil nil nil))) ) diff --git a/tests/test_mubea.py b/tests/test_mubea.py index e6758a6..4161caa 100644 --- a/tests/test_mubea.py +++ b/tests/test_mubea.py @@ -93,7 +93,8 @@ class TestMubeaResults: f'{t["id"]}: Block "{r["block_name"]}" ohne Praefix "{prefix}"' def test_vario_winkel_und_split(self, mubea_testdata, mubea_results): - """Vario: VF_WINKEL entspricht Vorgabe, L_GF-Split = 500/4230 (Meter).""" + """Vario: VF_WINKEL entspricht Vorgabe, L_GF-Vorlauf entspricht L_GF1-Ziel, + Vorlauf+Nachlauf (L_GF_m) ergeben zusammen die aus deltaL geloeste Gesamtlaenge.""" by_id = {r["test_id"]: r for r in mubea_results} for t in mubea_testdata: if not _is_vario(t): @@ -106,15 +107,14 @@ class TestMubeaResults: if "winkel" in t: assert attrs.get("VF_WINKEL") == str(t["winkel"]), \ f'{t["test_id"]}: VF_WINKEL ist={attrs.get("VF_WINKEL")}, erwartet={t["winkel"]}' - # L_GF_m = "vorne,hinten" in Metern -> 500mm/4230mm = "0.500,4.230" - if "L_GF1" in t and "L_GF2" in t and "L_GF_m" in attrs: + # L_GF_m = "vorne,hinten" in Metern; L_GF1 (Vorlauf-Ziel) muss exakt + # getroffen werden, L_GF2 (Nachlauf) ist der aus deltaL geloeste Rest. + if "L_GF1" in t and "L_GF_m" in attrs: teile = attrs["L_GF_m"].split(",") assert len(teile) == 2, f'{t["test_id"]}: L_GF_m Format "{attrs["L_GF_m"]}"' - v, h = float(teile[0]) * 1000.0, float(teile[1]) * 1000.0 + v = float(teile[0]) * 1000.0 assert abs(v - t["L_GF1"]) < 1.0, \ f'{t["test_id"]}: L_GF1 vorn ist={v}, erwartet={t["L_GF1"]}' - assert abs(h - t["L_GF2"]) < 1.0, \ - f'{t["test_id"]}: L_GF2 hinten ist={h}, erwartet={t["L_GF2"]}' # ============================================================ diff --git a/tests/testdata/mubea.json b/tests/testdata/mubea.json index b5f5a59..5b228b0 100644 --- a/tests/testdata/mubea.json +++ b/tests/testdata/mubea.json @@ -84,17 +84,17 @@ { "test_id": "VF_Schnitt_C", "richtung": "Auf", + "deltaL": 9110, "deltaH": 553, "winkel": 21, "gf_verteilung": "manuell", "L_GF1": 500, - "L_GF2": 8610, "seite": "rechts", "hz": 0.0, "x": 410, "y": 13137, "z": 1475, - "comment": "Foerdererwinkel 21 (naechster verfuegbarer Bogenwinkel); Gefaellestrecke vorn L_GF1=500 unveraendert, hinten L_GF2=8610 (gesamt L_GF=9110, angeglichen an deltaL_mm der GF_Mubea-Gefaellestrecken); deltaL und L_VF werden beim Bauen fuer winkel=21 und deltaH=553 geloest (L_GF ist linear in deltaL)" + "comment": "deltaL=9110 wie die Gefaellestrecken (GF_Mubea deltaL_mm) - deltaL ist die GESAMTLAENGE des VF (Vorlauf L_GF1 + Foerderer L_VF + Nachlauf L_GF2), analog foerderer_tests.json/object_data.md 3.1; winkel=21 wird erzwungen (naechster verfuegbarer Bogenwinkel); L_GF (gesamt) und L_VF werden von berechne-alle-winkel aus deltaL/deltaH/winkel geloest, L_GF1=500 (Vorlauf-Ziel) fix, L_GF2 = L_GF_gesamt - L_GF1 (Nachlauf, Rest)" }, { "test_id": "GF_Mubea",