- lib/dxf_scan_components.py: erkennt ILS-/Omniflo-Komponenten in fremden
Projektzeichnungen und schreibt sie im Testdaten-JSON-Schema aus
- lib/dxf_abbild.py: getreue Abbildung der Bauteile einer Fremdzeichnung
(Attribute, Weltkoordinaten, Unterkomponenten) ohne Interpretation
- tests/test_hundm05.{lsp,py}, testdata/hundm05.json, conftest-Fixtures und
alltests.json-Eintrag fuer den Kreisel-Abschnitt aus ST500592_05.dxf
- menu: TEST_HUNDM05 im Testmenue, Connection_Insert/Edit in SSG_LIB.cui
- Doku: hartkodierte Pfade durch (getenv "DXFMAKRO") ersetzt
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
28 KiB
JSON-Schema fuer tests/testdata/*.json
Diese Datei leitet aus den Produktions-Routinen in Lisp/ (nicht aus den
Test-Hilfsfunktionen in tests/*.lsp) ab, welche Angaben pro Element-Typ
noetig sind, um das jeweilige Bauteil programmgesteuert (per JSON) zu
erzeugen. Fuer jeden Typ wird die tatsaechlich aufgerufene LISP-Funktion samt
Parameterliste referenziert.
Jede Objekt-Sektion enthaelt ein vollstaendiges JSON-Beispiel: es listet
alle Werte auf, die man setzen muss, damit die dahinterliegende
Produktionsfunktion mit saemtlichen Parametern aufgerufen werden kann — so,
als gaebe es keine tests/test_*.lsp-Wrapper. Wo Koordinaten (x/y/z) als
Eingang noetig sind, stehen sie explizit im Beispiel. Optionale Felder sind
mit ihrem Default annotiert; laesst man sie weg, greift der Default.
Wichtige Unterscheidung, die sich beim Durcharbeiten herauskristallisiert hat:
- Scriptbar = es existiert eine Produktions-Funktion, die alle noetigen
Werte als normale Parameter entgegennimmt (kein
getpoint/getstringnoetig). Diese Funktionen sind 1:1 aus JSON aufrufbar. - Nicht scriptbar = die Produktions-Funktion fragt Punkte/Optionen
interaktiv ab (
getpoint,getstring,ssgetauf bereits gezeichnete Geometrie). Es gibt inLisp/keinen parametrischen Einstiegspunkt; ein JSON-Testfall kann diese Faelle nur ueber einen eigens geschriebenen Wrapper (wie estests/*.lsptut) nicht-interaktiv nachbilden.
Einheiten durchgaengig: mm fuer Laengen/Koordinaten, Grad fuer Winkel
(intern wird oft in Radiant gerechnet, die LISP-API-Grenze ist aber immer
Grad). Richtung hz/hz_grad: 0=Ost(+X), 90=Nord(+Y), 180=West(-X),
270=Sued(-Y).
0. Uebersicht — alle skriptbaren Objekte
| # | Objekt | Produktionsfunktion (Bau) | Scriptbar? | Koordinaten-Eingang | Sektion |
|---|---|---|---|---|---|
| 1.1 | Kreisel Insert | kreisel-insert-script (pt abstand rotation typ hoehe) |
ja | 1 Punkt x,y,z |
#11 |
| 1.2 | Kreisel Connect | kreisel-connect-script (ptStart ptEnd typ hoehe) |
ja | 2 Punkte start_*/end_* |
#12 |
| 2.1 | Gefaellestrecke Modus 1 | gf-modus12-abschluss → gefaellestrecke-einfuegen |
ja | 1 Punkt start_mm |
#21 |
| 2.2 | Gefaellestrecke Modus 2 | gf-modus12-abschluss (deltaL/hz aus 2 Punkten) |
ja | 3 Punkte (linie_*, start_mm) |
#22 |
| 2.3 | Gefaellestrecke Modus 3 | gf-linienzug-modus () |
nein | vorgezeichnete LINE/ARC-Auswahl | #23 |
| 3.1 | VarioFoerderer Standard | variofoerderer-einfuegen (…) |
ja | 1 Punkt startpunkt |
#31 |
| 3.2 | VarioFoerderer Etage | etage-foerderanlage-einfuegen (…) |
ja | 1 Punkt startpunkt |
#32 |
| 3.3 | VarioFoerderer Linienzug | vf-linienzug-modus () |
nein | interaktiver Assistent | #33 |
| 3.4 | Vario_Kette_Merge | vfl-kette-verfolgen (Re-Packaging) |
n/a | 1 Entity-Pick | #34 |
| 4.1 | Omniflo Bogen/Weiche | omni:insert-dxf (sivasnr hoehe drehung) + _.INSERT |
Kern ja, Befehl nein | 1 Punkt x,y,z (nur via Wrapper) |
#41 |
| 4.2 | Omniflo Aluprofil-Gerade | omni:make-gerade (blockname pt pt2 …) |
Kern ja | 2 Punkte pt/pt2 |
#42 |
| 4.3 | Omniflo TEF/Zubehoer | omni:insert-dxf (fester Sivasnr) |
Position ja, Punkt interaktiv | 1 Punkt (nur via Wrapper) | #43 |
| 4.4 | Omniflo TV_/APBW_ | — (DUMMY) | nein | — | #44 |
| 5 | Separator/Scanner/Sensor | ils-insert-sensor (fname) + _.INSERT |
nein (Schleife) | 1 Punkt x,y,z (nur via Wrapper) |
#5 |
| 6 | Waagrechte Foerderstrecke (gerade) |
insert-hz-scaled-block-by-ks (blockname startpunkt laenge hz vert) |
ja | 1 Punkt startpunkt (+ endpunkt als Doku) |
#6 |
Legende Scriptbar-Spalte:
- ja — direkt per JSON aufrufbar.
- Kern ja, Befehl nein — die Bau-Funktion nimmt alle Werte an, aber der
ausgelieferte
c:…-Befehl fragt den Einfuegepunkt per Maus (pause) ab; ein JSON-Treiber muss den_.INSERTselbst nachbauen. - nein — nur interaktiv; JSON beschreibt hoechstens die gewuenschte Geometrie, nicht einen Funktions-Parametersatz.
1. Kreisel — Lisp/KreiselInsert.lsp
Scriptbar. Zwei Varianten.
1.1 Kreisel Insert (freier Punkt)
Produktionsfunktion: kreisel-insert-script (pt abstand rotation typ hoehe)
| Feld | Typ | Pflicht | Bedeutung | Default |
|---|---|---|---|---|
x, y |
real (mm) | ja | Einfuegepunkt (Welt-XY), zusammen pt |
- |
z |
real (mm) | nein | Z von pt; wird verwendet, wenn hoehe fehlt |
- |
hoehe |
real (mm) | nein | Ueberschreibt Z; sonst pts Z |
*kreisel-default-hoehe* (config kreisel.default_hoehe, 2000.0) |
abstand |
real (mm) | nein | Abstand zwischen AN-/SP-Kreiselhaelfte (Kreisel-Baulaenge) | *kreisel-default-laenge* (config kreisel.default_laenge, 2300.0) |
rotation |
real (Grad) | nein | freie Rotation, kein Rasterzwang | 0.0 |
typ |
string | nein | "STANDARD" oder "PIN" (einzige Optionen aus kreisel-ask-typ) |
"STANDARD" |
Konstanten (Config [kreisel]): durchmesser (800.0mm, fuer Connect-Abstandsberechnung), default_laenge, default_hoehe.
Vollstaendiges JSON (alle Parameter gesetzt):
{
"id": "K1",
"function": "insert",
"x": 500,
"y": 500,
"z": 2500,
"hoehe": 2500,
"abstand": 2300,
"rotation": 0.0,
"typ": "STANDARD"
}
id und expect_*-Felder (expect_block_prefix, expect_hoehe,
expect_kreiselart) sind keine Produktionsparameter — reine
Test-Erwartungswerte fuer die Ergebnispruefung, nicht von
kreisel-insert-script konsumiert.
1.2 Kreisel Connect (Start-/Endpunkt)
Produktionsfunktion: kreisel-connect-script (ptStart ptEnd typ hoehe)
| Feld | Typ | Pflicht | Bedeutung | Default |
|---|---|---|---|---|
start_x,start_y,start_z |
real (mm) | ja | aeusserster Punkt AN-Seite (Antriebsstation) | - |
end_x,end_y,end_z |
real (mm) | ja | aeusserster Punkt SP-Seite (Spannstation) | - |
typ |
string | nein | "STANDARD"/"PIN" |
"STANDARD" |
hoehe |
real (mm) | nein | Einfuegehoehe | Z von ptStart, sonst *kreisel-default-hoehe* |
abstand/rotation werden intern aus den beiden Punkten berechnet
(abstand = distanz - *kreisel-durchmesser*; Rotation aus dem Winkel der
Verbindungslinie) — bei Connect KEIN Eingabefeld.
Vollstaendiges JSON (alle Parameter gesetzt):
{
"id": "K2",
"function": "connect",
"start_x": 0,
"start_y": 0,
"start_z": 2000,
"end_x": 5000,
"end_y": 0,
"end_z": 2000,
"typ": "STANDARD",
"hoehe": 2000
}
2. Gefaellestrecke — Lisp/Gefaellestrecke.lsp
Drei Modi, siehe Kopfkommentar der Datei. Modus 1+2 teilen sich denselben
Abschluss (gf-modus12-abschluss) und sind beide scriptbar. Modus 3
(Linienzug) ist in Produktion nicht scriptbar.
Gemeinsame Bau-Funktion (von allen Modi letztlich aufgerufen):
gefaellestrecke-einfuegen (L_stau winkel startpunkt as-seite es-seite hz deltaL-total as-winkel es-winkel geruest-einzelmodul geruest-typ)
Wichtig: deltaL (horizontale Laenge) ist der Eingang, nicht die
Hoehendifferenz. Bei festem winkel legen Laenge und Hoehendifferenz
sich gegenseitig fest (L_stau = (deltaL - aus-dx - ein-dx - sep-x) / cos(rad),
sep-x = separator_breite * cos(rad), config gefaelle.separator_breite
Default 300.0). Es gibt keinen Parameter fuer eine gewuenschte
Ziel-Hoehendifferenz — die ergibt sich aus L_stau/winkel.
2.1 Gefaellestrecke Modus 1 — Manuelle Werteingabe
Eingangsfunktion (nach DCL-Dialog gefaellestrecke.dcl): gf-modus12-abschluss (deltaL winkel hz-winkel as-seite es-seite startpunkt as-winkel es-winkel dialog-bestaetigt geruest-einzelmodul geruest-typ)
| Feld | Typ | Pflicht | Bedeutung | Default |
|---|---|---|---|---|
deltaL_mm |
real (mm) | ja | horizontale Gesamtlaenge (AS+Staustrecke+Separator+ES) | config gefaelle.default_delta_l 5000.0 |
winkel_grad |
real (Grad) | nein | Gefaelle-Neigungswinkel | config gefaelle.default_winkel 3.0 |
hz_grad |
real (Grad) | nein | Fahrtrichtung (0/90/180/270 ueblich, frei waehlbar) | 0.0 |
start_mm |
[x,y,z] (mm) | ja | Startpunkt; Z = Einfuegehoehe | - |
as_seite |
string | nein | "links"/"rechts" (AUS-Element-Seite) |
"links" |
es_seite |
string | nein | "links"/"rechts" (EIN-Element-Seite) |
"links" |
as_winkel |
string | nein | "90"/"30" (AUS-Element-Variante) |
"90" |
es_winkel |
string | nein | "90"/"30" (EIN-Element-Variante) |
"90" |
geruest_einzelmodul |
string "0"/"1" | nein | Geruest je Einzelmodul | "1" |
geruest_typ |
string | nein | einer aus *ssg-geruest-optionen* (s.u.) |
"Schoenenberger Geruest" (Index 2) |
*ssg-geruest-optionen* (aus ssg_core.lsp): "IPE-Geruest abgestuft",
"Obergeruest oben", "Schoenenberger Geruest", "nur Doppelrohrtraeger".
Interner Parameter dialog-bestaetigt ist immer T (kein Datenfeld).
Vollstaendiges JSON (alle Parameter gesetzt):
{
"test_id": "GF_M1",
"modus": 1,
"deltaL_mm": 10000,
"winkel_grad": 3.0,
"hz_grad": 0.0,
"start_mm": [0, 0, 5000],
"as_seite": "links",
"es_seite": "links",
"as_winkel": "90",
"es_winkel": "90",
"geruest_einzelmodul": "1",
"geruest_typ": "Schoenenberger Geruest"
}
Hinweis: In gefaellestrecke_tests.json stehen deltaL_mm/winkel_grad/
z_start_mm als gemeinsamer Kopf-Eintrag (ein Objekt ohne test_id), weil
alle Modus-1-Faelle dieselbe Laenge teilen. Produktionsseitig ist deltaL
aber pro Aufruf ein normaler, nicht geteilter Parameter — daher hier
vollstaendig im Einzelfall aufgefuehrt.
2.2 Gefaellestrecke Modus 2 — 3D-Linie als Richtungsreferenz
Gleiche Ziel-Funktion (gf-modus12-abschluss), aber deltaL/hz-winkel
werden nicht direkt angegeben, sondern aus zwei Linienpunkten berechnet:
deltaX = ende.x - start.x ; deltaY = ende.y - start.y
deltaL = hypot(deltaX, deltaY)
hz-winkel = angle(deltaX, deltaY) [Grad, 0=Ost]
In Produktion werden diese zwei Punkte interaktiv per get-line-start-end-points
(Linie in der Zeichnung anklicken) bestimmt — fuer einen JSON-Treiber
genuegen aber zwei beliebige Punkte, da die Berechnung rein geometrisch ist.
| Feld | Typ | Pflicht | Bedeutung | Default |
|---|---|---|---|---|
linie_start_mm |
[x,y,z] | ja | erster Linienpunkt (nur X/Y verwendet) | - |
linie_ende_mm |
[x,y,z] | ja | zweiter Linienpunkt (nur X/Y verwendet) | - |
start_mm |
[x,y,z] | ja | Einfuegepunkt der Kette (unabhaengig von der Linie) | - |
winkel_grad |
real (Grad) | nein | Neigungswinkel | 3.0 |
as_seite,es_seite |
string | nein | "links"/"rechts" |
"links" |
as_winkel,es_winkel |
string | nein | "90"/"30" |
"90" |
Geruestoptionen sind in Modus 2 (reine Konsoleneingabe) nicht abfragbar,
bleiben auf Default (geruest_einzelmodul="0", geruest_typ="Schoenenberger Geruest").
Vollstaendiges JSON:
{
"test_id": "GF_M2",
"modus": 2,
"winkel_grad": 3.0,
"linie_start_mm": [0, 0, 0],
"linie_ende_mm": [10000, 0, 0],
"start_mm": [0, 0, 5000],
"as_seite": "links",
"es_seite": "links",
"as_winkel": "90",
"es_winkel": "90"
}
2.3 Gefaellestrecke Modus 3 — Linienzug — nicht scriptbar
Eingangsfunktion: gf-linienzug-modus () — keine Parameter.
Ablauf in Produktion:
(ssget '((0 . "LINE,ARC")))— der Nutzer muss die Leitlinie (Kette aus bereits in der Zeichnung vorhandenen LINE-/ARC-Entities) vorher zeichnen und dann per Maus auswaehlen. Es gibt keine Funktion, die eine Leitlinie aus Koordinaten/Bogen-Parametern (start_mm/ende_mm/bogen) direkt als Argument entgegennimmt.getpointfuer Startpunkt (Kettenanfang, Z = obere Anschlusshoehe) und Endpunkt-Referenz (Z = untere Anschlusshoehe);deltaHwird aus der Differenz der beiden Z-Werte gebildet.getstring-Abfragen fuer AS-/ES-Winkel ("90"/"30") und -Seite ("links"/"rechts") — inhaltlich identisch zu Modus 1/2.- Interne Analyse der selektierten Kette (
gf-sortiere-objekte,gf-analysiere-kette) leitet Ein-/Ausgangsrichtung sowie Segment-Laengenkorrekturen ab.
JSON beschreibt hier nur die gewuenschte Leitlinien-Geometrie, nicht
direkte Funktionsparameter. Um Modus 3 aus JSON zu treiben, muss man zuerst
die LINE/ARC-Geometrie per entmake erzeugen und dann eine eigene
(nicht-interaktive) Nachbildung von gf-linienzug-modus schreiben — genau
das tut tests/test_gefaellestrecke.lsp.
JSON (Intent-Beschreibung, kein Parametersatz):
{
"test_id": "M3_Bogen",
"modus": 3,
"start_mm": [30000, -50000, 2000],
"ende_mm": [38500, -43500, 1800],
"bogen": {"winkel_grad": 90, "radius_mm": 500, "seite": "links"},
"as_seite": "links",
"es_seite": "links",
"as_winkel": "90",
"es_winkel": "90"
}
3. VarioFoerderer — Lisp/vf_core.lsp + vf_standard.lsp/vf_etage.lsp/vf_linienzug.lsp
Dispatcher c:VarioFoerderer waehlt einen registrierten Anlagetyp
("standard", "etage", "linienzug"). Registry-Vertrag fuer scriptbare
Typen:
berechne-fn (deltaL deltaH richtung seite) -> (best-winkel best-L_GF best-L_VF ergebnis-liste)
einfuege-fn (deltaL deltaH richtung best-winkel L_GF1 L_GF2 L_VF startpunkt seite hz) -> endpunkt
Der Wrapper vf-block-erstellen fasst danach zentral alles zu einem
VF_n-Block zusammen (kein JSON-Feld dafuer noetig — laeuft automatisch).
best-winkel, L_GF1, L_GF2, L_VF stammen normalerweise aus dem Solver
(berechne-fn). Fuer einen scriptbaren Aufruf gibt man daher die
Eingangsgroessen (deltaL, deltaH, richtung, seite, optional
winkel, gf_verteilung) sowie startpunkt+hz an; der Solver liefert die
inneren Laengen/Winkel. Zwingt man winkel, wird dieser Kandidat statt der
Auto-Wahl verwendet.
3.1 VarioFoerderer Standard — scriptbar
- Winkel-/Laengen-Solver:
berechne-standard (deltaL deltaH richtung seite)→ wrapptberechne-alle-winkel (deltaL deltaH richtung feste-hz). Kandidatenwinkel (configvario.bogen_winkel, Default):3 6 9 12 15 18 21 27 33 39 45 51Grad — nur diese Werte sind moeglich, kein freier Winkel. - Bau-Funktion:
variofoerderer-einfuegen (deltaL deltaH richtung best-winkel L_GF1 L_GF2 L_VF startpunkt seite hz)
| Feld | Typ | Pflicht | Bedeutung | Default |
|---|---|---|---|---|
deltaL |
real (mm) | ja | horizontale Gesamtlaenge | - |
deltaH |
real (mm) | ja | Ziel-Hoehendifferenz (hier IST deltaH ein direkter Eingang, anders als bei Gefaellestrecke!) | - |
richtung |
string | ja | "Auf" oder "Ab" |
- |
winkel |
int | nein | einer der 12 Kandidatenwinkel; ohne Angabe waehlt der Solver den kleinsten gueltigen | (Solver) |
gf_verteilung |
string | nein | "gleichmaessig"/"vorne"/"hinten" (Modus 0/1/2); bestimmt L_GF1/L_GF2 |
"gleichmaessig" |
startpunkt |
[x,y,z] (mm) | ja | Einfuegepunkt | - |
seite |
string | nein | "links"/"rechts" (AS/ES-Element-Seite) |
"rechts" (Dialog) |
hz |
real (Grad) | nein | Fahrtrichtung | 0.0 |
motorseite |
string | nein | "links"/"rechts" — nur Dialog/Anzeige, kein Geometrie-Parameter von variofoerderer-einfuegen |
"links" |
Verteilungsmodi ausfuehrlich (in Produktion per Dialog): 0=gleichmaessig
(beide L_GF/2), 1=alles vorne (Rest hinten), 2=alles hinten (Rest
vorne), 3=manuell (L_GF1 frei, L_GF2=Rest).
Vollstaendiges JSON (alle Parameter gesetzt):
{
"test_id": "VF_Auf_2000",
"typ": "standard",
"richtung": "Auf",
"deltaL": 7000,
"deltaH": 2000,
"winkel": 27,
"gf_verteilung": "gleichmaessig",
"startpunkt": [0, 0, 0],
"seite": "rechts",
"hz": 0.0,
"motorseite": "links"
}
Minimal genuegt (Solver fuellt den Rest): richtung, deltaL, deltaH (+
startpunkt, falls nicht am Ursprung).
3.2 VarioFoerderer Etage — scriptbar
- Solver:
berechne-etage (deltaL deltaH richtung seite)→berechne-winkel-etage (deltaL deltaH richtung). Gleiche 12 Kandidatenwinkel wie Standard. - Bau-Funktion:
etage-foerderanlage-einfuegen (deltaL deltaH richtung best-winkel L_GF1 L_GF2 L_VF startpunkt seite hz)— identische Signatur wie Standard (Registry-Vertrag), Unterschied liegt im internen Aufbau (30-Grad-AS/ES-Elemente statt 90, AS/ES direkt uebereinander, zusaetzlicher fixer "Gefaellebogen" je nachseitegegenueber dem AS-Element).
Felder: identisch zu 3.1 (deltaL, deltaH, richtung, winkel,
gf_verteilung, startpunkt, seite, hz). Nur typ unterscheidet sich.
Vollstaendiges JSON:
{
"test_id": "VF_Etage_Auf_2000",
"typ": "etage",
"richtung": "Auf",
"deltaL": 7000,
"deltaH": 2000,
"winkel": 27,
"gf_verteilung": "gleichmaessig",
"startpunkt": [0, 0, 0],
"seite": "rechts",
"hz": 0.0,
"motorseite": "links"
}
3.3 VarioFoerderer Linienzug — nicht scriptbar
Eingangsfunktion vf-linienzug-modus () — keine Parameter, rein
interaktiver Mehrschritt-Assistent (Kettenaufbau aus GF-Boegen,
Vario-Kurven, VF-Einheiten, Horizontal-Stuecken). Jeder Schritt fragt per
getpoint/getstring/getint/getreal einzeln ab. Es existiert keine
einzelne Produktionsfunktion, die eine ganze Kette aus einer Liste von
Segment-Beschreibungen entgegennimmt.
linienzug_tests.json bildet die Prompt-Sequenz als Frage-Antwort-Protokoll
ab (typ: point_abs/point_rel/real/string/int, jeweils mit
wert/dL+hz und einem kommentar, der beschreibt, WELCHE Frage die
Antwort beantwortet) — das ist die einzige Moeglichkeit, den interaktiven
Ablauf nicht-interaktiv nachzubilden, kein direkter Parametersatz einer
Bau-Funktion. Prompt-Reihenfolge (Kurzfassung, Details in vf_linienzug.lsp):
- Startpunkt (
point_abs), Hoehe Z (real) - AS-Element setzen? Ja/Nein, wenn ja: Winkel 90/30, Seite links/rechts
- Schleife "naechstes Element": GF-Bogen | Neue Linie (GF) | Neue Linie
(Ab/Auf VF) | Horizontal-VF | Kettenende — jeweils eigene Unter-Prompts
(Endpunkt
point_relmitdL+hz, Ziel-Hoehe oder Neigungswinkel, Separator vor/nach, GF-Verteilung, Vario-Kurve Winkel/Seite/Variante, ...) - Kettenende: ES-Winkel (90/30) + ES-Seite (links/rechts)
JSON (Prompt-Protokoll, Auszug):
[
{ "typ": "point_abs", "wert": [0, 0, 5000], "kommentar": "Startpunkt + Hoehe Z" },
{ "typ": "string", "wert": "90", "kommentar": "AS-Element Winkel 90/30" },
{ "typ": "string", "wert": "links", "kommentar": "AS-Element Seite" },
{ "typ": "point_rel", "dL": 8000, "hz": 0.0, "kommentar": "Endpunkt naechstes Linien-Segment" },
{ "typ": "string", "wert": "90", "kommentar": "ES-Element Winkel" },
{ "typ": "string", "wert": "links", "kommentar": "ES-Element Seite" }
]
3.4 Vario_Kette_Merge — kein Neubau
c:Vario_Kette_Merge: benoetigt nur einen Start-Entity-Pick (entsel),
sucht danach selbst alle KS_EIN/KS_AUS-kompatiblen Nachbarbloecke in der
ganzen Zeichnung ab (vfl-kette-verfolgen, Toleranzen 2mm/100mm) und fasst
sie zu einem neuen VF_n zusammen. Kein JSON-Parametersatz noetig/moeglich —
reine Nachbearbeitung bereits vorhandener Geometrie.
4. Omniflo — Lisp/OmniModulInsert.lsp
4.1 Omniflo Boegen/Weichen
Kern-Funktion: omni:insert-dxf (sivasnr-str hoehe drehung)
| Feld | Typ | Pflicht | Bedeutung | Default |
|---|---|---|---|---|
sivasnr |
string | ja | Komponenten-ID; ist gleichzeitig der Dateiname <sivasnr>.dxf unter %DXFM_OMNIFLO% |
- |
hoehe |
string/real (mm) | nein | absolute Z-Koordinate + HOEHE-Attribut |
config omniflo.default_hoehe bzw. hart "2000" |
drehung |
real (Grad) | nein | feste Rotation | in c:OMNI_* interaktiv per Maus |
x, y, z |
real (mm) | (Wrapper) | Einfuegepunkt — kein Parameter von omni:insert-dxf; muss ueber einen eigenen _.INSERT-Aufruf gesetzt werden |
- |
Wichtig: Alle echten c:OMNI_APB_*/c:OMNI_W*_*-Befehle rufen
omni:insert-dxf ohne X/Y auf — der Einfuegepunkt kommt in _.INSERT
immer per pause (Mausklick). Es gibt in Produktion keinen Aufrufpfad,
der X/Y programmatisch uebergibt; omni:insert-dxf selbst akzeptiert keinen
Punkt-Parameter. Die Felder x/y/z beschreiben also nur, wo das Element
stehen soll — ein JSON-Treiber muss den _.INSERT selbst nachbauen (wie
mubea:build-separator in tests/test_mubea.lsp).
Sivasnr-Herkunft: data/json/omniflo_boegen.json und
data/json/omniflo_weichen.json (dienen der Dialog-Filterung/Anzeige, nicht
der Namensaufloesung — die ist sivasnr == dateiname).
Vollstaendiges JSON (alle fachlich noetigen Werte inkl. Position):
{
"id": "821104025",
"type": "bogen",
"sivasnr": "821104025",
"x": 219.4,
"y": 223.06,
"z": 2000,
"hoehe": 2000,
"drehung": 0.0
}
description/row sind reine Dokumentations-/Gruppierungsfelder, keine
Produktionsparameter.
4.2 Omniflo Aluprofil-Gerade (AP60/AP110/APG110)
Kern-Funktion: omni:make-gerade (blockname pt pt2 srcAttribs textHeight textGap textEnt)
| Feld | Typ | Pflicht | Bedeutung | Default |
|---|---|---|---|---|
blockname |
string | ja | "AP60" / "AP110" / "APG110" |
- |
pt |
[x,y,z] | ja | Startpunkt (absolute Weltkoordinaten) | - |
pt2 |
[x,y,z] | ja | Endpunkt; Laenge/Rotation aus Differenz pt→pt2 berechnet |
- |
textHeight |
real | nein | Textgroesse | config omniflo.text_height (100.0) |
textGap |
real | nein | Textabstand | config omniflo.text_gap (20.0) |
srcAttribs wird aus der Vorlagen-DWG gelesen (omni:read-src-attribs blockname);
textEnt ist ein vorhandener Text-Entity zum Aktualisieren (bei Neuaufbau
nil). Beide sind keine JSON-Datenfelder. Der oeffentliche Befehl
omni:insert-block (blockname laengemax) fragt pt/pt2 interaktiv per
getpoint ab — omni:make-gerade selbst ist mit festen Punkten aufrufbar.
Vollstaendiges JSON:
{
"type": "gerade",
"blockname": "AP110",
"pt": [2000.0, 0.0, 2000.0],
"pt2": [3000.0, 0.0, 2000.0],
"textHeight": 100.0,
"textGap": 20.0
}
(In omniflo_strecke_tests.json wird die Gerade als profil/x/y/
x_ende/y_ende/hoehe beschrieben — dieselben Punkte, nur andere
Feldnamen fuer den Reihen-Layout-Test.)
4.3 Omniflo TEF/Zubehoer
Stopper, Scanner, Buerstenbremse, Umlenk-/Antriebsstationen:
c:OMNI_STOPPER/c:OMNI_SCANNER/... rufen omni:insert-dxf mit
hartcodiertem sivasnr-str (z.B. "827062022") und hoehe=nil, drehung=nil auf — Punkt weiterhin interaktiv. Kein Nutzer-JSON-Feld fuer
sivasnr noetig (fest im Code); Position/Hoehe/Rotation waeren
grundsaetzlich scriptbar (wie 4.1), aber nicht ueber die vorhandenen
c:OMNI_*-Befehle. JSON identisch strukturiert wie 4.1 (mit sivasnr fest
je Zubehoer-Typ).
4.4 Omniflo TV_* / APBW_*
Transferwagen-Verbinder (c:OMNI_TV_*) und Boegen fuer Weichen
(c:OMNI_APBW_*): nicht implementiert — reine [DUMMY]-Platzhalter ohne
Bau-Logik, kein Parametersatz.
c:OMNI_UPDATE_ATTRIBS (in Lisp/export.lsp) aktualisiert HOEHE/DREHUNG
aller Omniflo-Elemente aus der Zeichnung — kein Bau-/Einfuege-Befehl, daher
kein JSON-Parametersatz.
5. Separator/Scanner/Sensor — Lisp/SSG_LIB_Commands.lsp
Funktion: ils-insert-sensor (fname)
| Feld | Typ | Pflicht | Bedeutung | Default |
|---|---|---|---|---|
block / fname |
string | ja | Blockdateiname ohne Erweiterung, z.B. "Separator_SP", "Scanner", "S-LP" — aufgeloest ueber ssg-ils-block-datei (2D/3D-Suffix + Fallback) |
- |
x, y, z |
real (mm) | (Wrapper) | Einfuegepunkt — kein Parameter von ils-insert-sensor |
- |
rotation |
real (Grad) | (Wrapper) | Rotation — kein Parameter (kommt per pause) |
- |
Nicht scriptbar: die Funktion fragt Einfuegepunkte in einer Schleife per
getpoint ab (_.INSERT pfad pt "" "" pause — auch die Rotation kommt per
Maus/pause), bis der Nutzer mit ENTER/ESC abbricht. Es gibt keinen
Parameter fuer Punkt, Anzahl oder Rotation. Ein JSON-Treiber muss den
_.INSERT-Aufruf direkt selbst nachbilden (Blockdatei-Pfad ueber
ssg-ils-block-datei bzw. ssg-ils-block-laden, dann
_.INSERT pfad pt "" "" rot mit festem rot statt pause) — der Ansatz von
mubea:build-separator in tests/test_mubea.lsp. Fachlich noetig sind nur
Blockname + Punkt + Rotation.
Vollstaendiges JSON (wie in mubea.jsons Separator-Eintraegen):
{
"function": "insert",
"block": "S-LP",
"x": 10310,
"y": -14158,
"z": 1467,
"rotation": 270
}
6. Waagrechte Foerderstrecke (gerade)
Produktionsfunktion:
insert-hz-scaled-block-by-ks (blockname startpunkt laenge hz-winkel vert-winkel)
(Lisp/vf_etage.lsp) — dieselbe Primitive, mit der der Etage-Foerderer seine
waagrechten Abschnitte baut. Skaliert Staustrecke_SP_1000_mm auf laenge
(Massstab = laenge / 1000) und richtet sie ueber KS_EIN/KS_AUS am
startpunkt aus.
Dieser Typ entstand beim Nachbau von results/ST500592_05.dxf: ein
Antriebs-/Umlenkstation-Paar ohne Hoehendifferenz ist fachlich kein
VarioFoerderer. Dessen Solver (berechne-standard →
berechne-alle-winkel) muss einen Bogenwinkel aus der Kandidatenliste
3…51 Grad waehlen, was bei deltaH ≈ 0 nicht aufgeht — der Eintrag waere
unbaubar. lib/dxf_scan_components.py trennt solche Paare darum ueber
GERADE_MAX_DELTA_H (10 mm) ab und gibt sie als gerade aus.
| Feld | Typ | Pflicht | Bedeutung | Default |
|---|---|---|---|---|
test_id |
string | ja | Kennung, Praefix GERADE_ (steuert den Dispatcher) |
- |
typ |
string | nein | "gerade" (Dokumentation, nicht ausgewertet) |
- |
laenge |
real (mm) | ja | horizontale Laenge; Massstab der Staustrecke | - |
hz |
real (Grad) | nein | Fahrtrichtung in der XY-Ebene | 0.0 |
startpunkt |
[x,y,z] (mm) | ja | Anfangspunkt (KS_EIN wird hierhin gelegt) |
- |
endpunkt |
[x,y,z] (mm) | nein | Endpunkt — reine Dokumentation/Herkunft, kein Parameter; die Geometrie folgt aus startpunkt + laenge + hz |
- |
vert-winkel wird vom Treiber fest auf 0 gesetzt (waagrecht). Die Funktion
gibt den Ausgangspunkt zurueck, nicht die Entity — ein Treiber holt den
Block ueber (entlast). Bei fehlender Blockdatei ruft sie (exit) auf und
wuerde einen Testlauf abbrechen, darum vorher mit ssg-ils-block-laden
pruefen (so macht es hundm05:build-gerade in tests/test_hundm05.lsp).
Vollstaendiges JSON (wie in hundm05.json):
{
"test_id": "GERADE_HundM05_08",
"typ": "gerade",
"laenge": 3305.26,
"hz": 143.35,
"startpunkt": [223150.89, 152953.65, 0.0],
"endpunkt": [220499.01, 154926.53, 0.0]
}
7. Zusammenfassung: scriptbar vs. nicht scriptbar
| Element | Produktionsfunktion | Scriptbar? |
|---|---|---|
| Kreisel Insert | kreisel-insert-script |
ja |
| Kreisel Connect | kreisel-connect-script |
ja |
| Gefaellestrecke Modus 1 | gf-modus12-abschluss → gefaellestrecke-einfuegen |
ja |
| Gefaellestrecke Modus 2 | gf-modus12-abschluss (deltaL/hz aus 2 Punkten) |
ja |
| Gefaellestrecke Modus 3 | gf-linienzug-modus |
nein (erfordert vorgezeichnete LINE/ARC-Auswahl) |
| VarioFoerderer Standard | variofoerderer-einfuegen |
ja |
| VarioFoerderer Etage | etage-foerderanlage-einfuegen |
ja |
| VarioFoerderer Linienzug | vf-linienzug-modus |
nein (mehrstufiger interaktiver Assistent) |
| Vario_Kette_Merge | vfl-kette-verfolgen |
n/a (Re-Packaging, kein Parametersatz) |
| Omniflo Bogen/Weiche | omni:insert-dxf (Kern) |
Kern ja, Produktionsbefehle nein (X/Y immer Maus) |
| Omniflo Aluprofil-Gerade | omni:make-gerade (Kern) |
Kern ja, Befehl omni:insert-block fragt Punkte interaktiv |
| Omniflo TEF/Zubehoer | omni:insert-dxf (fester Sivasnr) |
Position/Hoehe/Rotation ja, Punkt-Eingabe interaktiv |
| Omniflo TV_/APBW_ | - | nein (nicht implementiert, DUMMY) |
| Separator/Scanner | ils-insert-sensor |
nein (Schleife mit getpoint/pause) |