Varioförderer Masse geändert

This commit is contained in:
2026-07-27 22:16:36 +02:00
parent e974e63c40
commit cee2a81b55
3 changed files with 58 additions and 43 deletions
+50 -35
View File
@@ -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)))
)
+6 -6
View File
@@ -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"]}'
# ============================================================
+2 -2
View File
@@ -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",