Lab Hardware CAD
Entwerfen Sie physische Forschungshardware als parametrische Python-Quelle, exportieren Sie STEP als das maßgebliche Artefakt, und überprüfen Sie das Ergebnis sowohl numerisch als auch visuell, bevor irgendetwas gefertigt wird.
Das Schwierige an Laborhardware ist fast nie die Geometrie. Es ist die Tatsache, dass das Bauteil mit Geräten zusammenpassen muss, deren Abmessungen durch einen veröffentlichten Standard oder eine Herstellerzeichnung festgelegt sind. Ein Halter, der 0,5 mm zu breit ist, passt nicht in das Plattenlesegerät; ein Kanal mit dem falschen Seitenverhältnis kollabiert beim Bonden; eine Halterung, deren Lochmuster 25,4 mm statt 25,0 mm beträgt, erreicht den optischen Tisch nicht. Dieser Skill existiert, um diese Zahlen korrekt zu halten und zu überprüfen.
Wann verwenden
Verwenden Sie diesen Skill für jede Anfrage zum Entwerfen, Modellieren oder Fertigen eines physischen Bauteils für ein Labor: Chip, Form, Montage, Adapter, Halter, Gestell, Bügel, Gehäuse, Vorrichtung, Befestigung, Arena oder Labyrinth. Verwenden Sie ihn auch, um eine vorhandene STEP-Datei zu inspizieren oder zu ändern.
Verwenden Sie ihn nicht für Finite-Elemente-Analysen, numerische Strömungsmechanik, Molekularstrukturen oder wissenschaftliches Plotten. Dies sind andere Skills.
Einrichtung
uv venv --python 3.12 .venv-labcad
uv pip install --python .venv-labcad/bin/python "build123d==0.11.1" "matplotlib>=3.8"
build123d 0.11.1 benötigt Python >=3.10,<3.15 und zieht den OpenCascade-Kernel über
cadquery-ocp-novtk nach sich. Das Wheel ist groß; installieren Sie es einmal pro Projekt und
verwenden Sie es wieder.
Alle gebündelten Skripte akzeptieren --help. check.py standards läuft ohne installiertes
build123d.
Modelldateien werden ausgeführt, nicht geparst. gen.py, check.py und snapshot.py
importieren ein *_model.py und rufen dessen build() auf, was beliebiges Python in der aktuellen
Umgebung ausführt. Das ist der parametrischen CAD inhärent – die Quelle ist das Design. Führen Sie
nur Modelldateien aus, die in dieser Sitzung erstellt oder vom Benutzer von einem vertrauenswürdigen
Ort bereitgestellt wurden. Wenn ein Modell aus dem Internet, von einer gemeinsamen Festplatte oder
von einem nicht vertrauenswürdigen Kollegen stammt, lesen Sie es, bevor Sie es ausführen, und geben
Sie an, dass Sie dies getan haben.
Erforderlicher Arbeitsablauf
Befolgen Sie diese Schritte in der angegebenen Reihenfolge. Die Schritte 5 und 6 sind nicht optional, und Schritt 6 wird nicht durch das Bestehen von Schritt 5 aufgehoben.
1. Einer Gerätefamilie zuordnen
Lesen Sie die Anfrage, klassifizieren Sie sie und laden Sie genau eine Familienreferenz. Laden Sie nicht alle vier – sie sind lang, und das Vermischen von Konventionen zwischen Familien ist eine häufige Fehlerquelle.
| Wenn das Bauteil … | Laden Sie |
|---|---|
| Ein Chip, eine Form, ein Kanalnetzwerk, eine Durchflusszelle, eine Dichtung oder etwas mit Fluidanschlüssen | references/mikrofluidik.md |
| Eine Montage, ein Pfosten, ein Breadboard-Adapter, ein Käfigsystem-Teil, ein Filter- oder Probenhalter in einem Strahlengang | references/optomechanik.md |
| Ein Adapter, Einsatz, Gestell oder Halter für Platten, Küvetten, Röhrchen, Objektträger oder Schalen | references/laborzubehoeradapter.md |
| Eine Arena, ein Labyrinth, ein Kopffixierungsteil, ein Auslauf, eine Leine oder ein extrusionsmontiertes Gehäuse für Tierarbeiten | references/verhaltensanlagen.md |
Wenn das Bauteil tatsächlich zwei Familien überspannt – ein mikrofluidischer Chip, der auf einen optischen Tisch geschraubt wird – laden Sie die Familie, die die kritische Schnittstelle besitzt, und lesen Sie dann nur den Schnittstellenabschnitt der zweiten. Geben Sie in Ihrer Antwort an, zu welcher Familie Sie weitergeleitet haben.
2. Schnittstellenabmessungen vor jeder Geometrie festlegen
Jedes Bauteil hat mindestens eine passende Schnittstelle. Bevor Sie Code schreiben, notieren Sie für jede Schnittstelle:
- die Quelle der Abmessung: ein veröffentlichter Standard, eine Herstellerzeichnung oder eine Benutzermessung;
- den Nennwert und die Toleranz;
- das Spiel oder den Übermaß, das/das Sie beabsichtigen, und warum.
Schlagen Sie die Nummer in assets/standards.json oder der Familienreferenz nach. Schreiben Sie
niemals eine Schnittstellenabmessung aus dem Gedächtnis auf. Wenn die Nummer nicht in der
Standardsdatei oder der Referenz enthalten ist, fragen Sie den Benutzer nach der Herstellerzeichnung
oder der Messung, anstatt zu raten. Eine geratene Schnittstellenabmessung ist der mit Abstand
teuerste Fehlermodus in diesem Skill.
Ein Merkmal, das ein standardisiertes Bauteil aufnehmen muss, wird gegen den Maximalstoffzustand dieses Bauteils dimensioniert – Nennmaß plus seine Plus-Toleranz – und erhält erst dann Spiel. Wird es stattdessen vom Nennmaß aus dimensioniert, passt es nur in die kleinere Hälfte der konformen Bauteile.
python scripts/check.py standards --list
python scripts/check.py standards --show slas-microplate-footprint
Die gebündelten Standard-IDs (exakte Zeichenfolgen; raten Sie keine Varianten):
slas-microplate-footprint, slas-microplate-height, slas-microplate-flange,
slas-well-positions-96, slas-well-positions-384, slas-well-positions-1536,
cuvette-standard-10mm, optical-breadboard-metric, optical-breadboard-imperial,
cage-system-30mm, sm1-lens-tube-thread.
Wenn das Bauteil mit nichts in dieser Liste zusammenpasst, ist das üblich und in Ordnung: Deklarieren Sie keine Schnittstellen, und benennen Sie jede Schnittstellenabmessung mit ihrer Quelle (Benutzerspezifikation, Herstellerzeichnung, Messung) im Bericht als ungeprüft. Deklarieren Sie niemals gegen einen nicht zugehörigen Standard, um die Lücke zu füllen – eine erfundene Deklaration ist schlimmer als ein ehrliches "niemand hat dies geprüft".
3. Wählen Sie den Prozess, bevor Sie die Geometrie wählen
Lesen Sie references/fertigungsgrenzen.md. Der Prozess bestimmt die minimale Wandstärke, minimale
Strukturgröße, erreichbare Toleranz und ob das Bauteil Autoklavieren oder Kontakt mit Ihrem
Lösungsmittel überlebt. FDM kann ±0,05 mm nicht halten; SLA-Harz ist im Allgemeinen nicht sicher
für Zellkontakt ohne Nachhärtung und Tests. Dokumentieren Sie den Prozess und das Material im
Docstring des Modells.
4. Erstellen Sie ein parametrisches Modell
Schreiben Sie <teil>_model.py. Die Quelle ist das maßgebliche Artefakt – bearbeiten Sie niemals
von Hand eine exportierte STEP-Datei und regenerieren Sie niemals aus einem Mesh.
Anforderungen:
- Jede Abmessung, die ein Benutzer ändern könnte, ist ein modulweiter benannter Konstanten mit
Einheiten im Namen:
bohr_d_mm,wand_t_mm,pfosten_h_mm. Keine nackten Zahlen im Rumpf außer 0, 1 und 2. - Stellen Sie
build() -> Partbereit.gen.pyruft es auf. - Gruppieren Sie Parameter in einen
INTERFACE-Block (durch einen Standard festgelegte Abmessungen, mit der Standard-ID kommentiert) und einenDESIGN-Block (Abmessungen, die Sie frei wählen können). - Leiten Sie jede berechnete Abmessung innerhalb einer Funktion ab, niemals auf Modulebene,
damit
--param-Überschreibungen sie tatsächlich erreichen. - Deklarieren Sie eine
interfaces()-Funktion, die die Abmessungen zurückgibt, in die das Bauteil passen muss, jeweils mit seiner Standard-ID und Absicht. Dies macht die Schnittstelle in Schritt 5 maschinell prüfbar.intentist"envelope", wenn das Merkmal jedes konforme Bauteil aufnehmen muss (eine Tasche, Bohrung oder Nut – einseitig geprüft am Maximalstoffzustand plus Ihrem Spiel) und"match", wenn dieses Bauteil selbst konform sein muss (symmetrischer Bereich).clearanceist das beabsichtigte Gesamtspiel in mm und muss nicht-negativ sein. Deklarieren Sie nur Abmessungen, die die Passmerkmale dieses Bauteils einschränken – eine Eigenschaft des passenden Geräts (ein Tischrand, eine typische Plattendicke) ist keine Ihrer Schnittstellen. Wenn kein gebündelter Standard zutrifft, geben Sie[]zurück. - Deklarieren Sie eine
checks()-Funktion von Go/No-Go-Lehren, gemessen am erstellten Volumen: einenclear-Bereich für alles, das hindurchpassen oder hineinpassen muss (Schraubenschäfte, Strahlkorridore, das passende Bauteil im Maximalstoffzustand, das in seine Tasche fällt), einenmaterial-Bereich für alles, das erhalten bleiben muss (eine Rippe, eine Kante, ein Schraubensitz), und einebbox_*-Grenze für jede Größenbeschränkung, die der Benutzer angegeben hat. Ordnen Sie jede geometrische Anforderung in der Anfrage einem Eintrag zu; diese fangen die Fehler, dieis_valid, der Begrenzungsrahmen und deklarierte Zahlen nicht sehen können.gen.pyführt sie bei jeder Generierung aus und bricht den Build bei einem Fehler ab. Schema und ausgearbeitete Beispiele:references/build123d-patterns.md. - Setzen Sie den Prozess, das Material und jede Schnittstellenquelle in das Docstring des Moduls.
"""SLAS-Mikroplattenträger für einen kundenspezifischen Staging-Einsatz.
Prozess: FDM, PETG, 0,2 mm Schicht. Toleranzbudget +/-0,3 mm.
Schnittstellen:
- Plattentasche: ANSI/SLAS 1-2004 (R2012) Grundfläche 127,76 x 85,48 mm, +/-0,25.
- Staging-Schrauben: benutzergemessen, 40,0 mm Mittenabstand (Zeichnung in docs/stage.pdf).
"""
from build123d import *
# --- INTERFACE (durch Standard festgelegt; nicht optimieren) ---
platte_l_mm = 127.76 # ANSI/SLAS 1-2004 Nennmaß
platte_b_mm = 85.48 # ANSI/SLAS 1-2004 Nennmaß
platte_tol_mm = 0.25 # ANSI/SLAS 1-2004; die Tasche ist auf dieses Nennmaß + toleriert
# --- DESIGN (frei) ---
taschenspiel_mm = 0.40 # pro Seite; FDM, siehe fertigungsgrenzen.md
wand_t_mm = 3.0
boden_t_mm = 2.5
koerper_h_mm = 12.0
def taschenmasse_mm() -> tuple[float, float]:
"""Tasche im Maximalstoffzustand der Platte plus Spiel pro Seite.
Eine vom Nennmaß aus dimensionierte Tasche klemmt auf etwa der Hälfte der konformen Platten.
"""
wachstum = platte_tol_mm + 2 * taschenspiel_mm
return platte_l_mm + wachstum, platte_b_mm + wachstum
def interfaces() -> list[dict]:
"""In was dieses Bauteil passen muss. `check.py interfaces` überprüft jeden Eintrag."""
t_l, t_b = taschenmasse_mm()
return [
{"feature": "Plattentaschenlänge", "standard": "slas-microplate-footprint",
"dimension": "footprint_length", "value": t_l,
"intent": "envelope", "clearance": 2 * taschenspiel_mm},
{"feature": "Plattentaschenbreite", "standard": "slas-microplate-footprint",
"dimension": "footprint_width", "value": t_b,
"intent": "envelope", "clearance": 2 * taschenspiel_mm},
]
def checks() -> list[dict]:
"""Lehren, gemessen am erstellten Volumen. Dimensioniert von den ZAHLEN DER ANFORDERUNG
(Platten-MMC, die Höhenbegrenzung des Benutzers), nicht von den Taschenparametern, damit ein
falscher Parameter die Lehre nicht verkleinern kann, um der falschen Geometrie zu entsprechen."""
tiefe = koerper_h_mm - boden_t_mm
return [
{"feature": "Platte bei MMC fällt in die Tasche",
"clear": {"box": (platte_l_mm + platte_tol_mm, platte_b_mm + platte_tol_mm, tiefe),
"at": [(0.0, 0.0, boden_t_mm + tiefe / 2)]}},
{"feature": "Unter 15 mm für das Staging", "bbox_z": {"max": 15.0}},
]
def build() -> Part:
t_l, t_b = taschenmasse_mm()
with BuildPart() as traeger:
Box(t_l + 2 * wand_t_mm, t_b + 2 * wand_t_mm, koerper_h_mm,
align=(Align.CENTER, Align.CENTER, Align.MIN))
with Locations((0, 0, boden_t_mm)):
Box(t_l, t_b, koerper_h_mm, mode=Mode.SUBTRACT,
align=(Align.CENTER, Align.CENTER, Align.MIN))
return traeger.part
Siehe references/build123d-patterns.md für die Entscheidung Builder vs. Algebra, den Vertrag von
interfaces(), Skizzieren, Selektoren, Verrundungen und Gewindeeinsatzbohrungen.
5. Generieren und Prüfungen ausführen
python scripts/gen.py traeger_model.py --outdir out/
python scripts/check.py facts out/traeger.step
python scripts/check.py interfaces out/traeger.manifest.json
python scripts/check.py geometry out/traeger.step --model traeger_model.py
gen.py wertet auch die checks()-Lehren des Modells gegen den gerade erstellten Volumenkörper aus,
druckt jedes BESTANDEN/FEHLGESCHLAGEN, zeichnet sie im Manifest auf und beendet sich bei einem
Fehler mit einem Exit-Code ungleich Null – so wird ein Bauteil, das seine eigene deklarierte
Geometrie verletzt, niemals stillschweigend zu einem Artefakt. check.py geometry führt dieselben
Lehren erneut gegen die exportierte STEP-Datei aus, die das maßgebliche Artefakt ist.
out/ ist eine temporäre Konvention, keine Anforderung. Wenn der Benutzer die Ausgabe an einem
bestimmten Ort angefordert hat, generieren Sie dort (--outdir .) oder kopieren Sie die STEP, das
Manifest und die DXF dorthin, bevor Sie fertig sind – ein Artefakt, das nur innerhalb von out/
existiert, wurde nicht ausgeliefert.
gen.py schreibt traeger.step (maßgeblich), traeger.stl (Mesh-Vorschau und Druck) und
traeger.manifest.json, das den Quell-Hash, aufgelöste Parameter, deklarierte Schnittstellen,
Bibliotheksversionen und gemessenen Begrenzungsrahmen, Volumen und Gültigkeit aufzeichnet. Das
Manifest ist der Herkunftsnachweis – bewahren Sie es mit dem Artefakt auf.
check.py facts meldet is_valid, Begrenzungsrahmen, Volumen, Oberfläche, Schwerpunkt und
Volumenkörperanzahl. Ein Bauteil, das is_valid: false meldet, hat eine defekte Geometrie;
korrigieren Sie die Quelle, bevor Sie fortfahren.
check.py interfaces wertet jeden vom Modell deklarierten Eintrag gegen die Standarddatenbank aus
und beendet sich bei einem Fehler mit einem Exit-Code ungleich Null. Seien Sie klar darüber, was
es überprüft und was nicht: es überprüft die deklarierten Zahlen – erfasst eine
Transkriptionsdimension, den falschen Standard und eine Dimensionierung vom Nennmaß statt vom MMC –
aber es misst nie die erstellte Geometrie, und ein Wert, der aus denselben Konstanten berechnet
wurde, gegen die er geprüft wird, besteht konstruktionsbedingt ohne Spielraum. Zitieren Sie es
nicht als Beleg dafür, dass die Geometrie korrekt ist; facts und der Schnappschuss sind die
Geometrieprüfungen. Eine leere Deklarationsliste besteht: Ein Bauteil, das mit nichts in der
gebündelten Datenbank zusammenpasst, hat nichts zu deklarieren, und seine Schnittstellenabmessungen
werden stattdessen im Bericht als ungeprüft benannt.
Verwenden Sie interfaces anstelle von check.py fit für alles Interne – eine Tasche, Bohrung
oder Nut erscheint nicht im äußeren Begrenzungsrahmen des Bauteils, den fit misst. Greifen Sie
nur dann zu fit, um eine Zahl von Hand zu überprüfen (--value footprint_length=128.81), oder
wenn der Umriss des Bauteils selbst die Schnittstelle ist, wie z. B. eine Dichtung, die auf eine
Plattengrundfläche zugeschnitten ist.
Überprüfen Sie bei Baugruppen, dass die Teile sich nicht gegenseitig stören:
python scripts/check.py clearance out/traeger.step out/deckel.step --min 0.3
6. Schnappschuss erstellen und tatsächlich ansehen
python scripts/snapshot.py out/traeger.step --out out/traeger.png
Dann lesen Sie das PNG. Dieser Schritt ist nach jeder Generierung und jeder Änderung
obligatorisch. Das Bestehen deterministischer Prüfungen ist kein Grund, ihn auszulassen: is_valid
und ein korrekter Begrenzungsrahmen sind beide vollständig vereinbar mit einer Tasche, die auf der
falschen Seite geschnitten wurde, einem Vorsprung, der außerhalb des Volumenkörpers platziert wurde,
oder einer Verrundung, die ein Merkmal verschlungen hat. Diese Fehler sind in einem Bild offensichtlich
und in den Zahlen unsichtbar.
Kennen Sie auch die Grenzen des Renderings. Ein Merkmal, das viel kleiner als der Rahmen ist – eine
0,3 mm Formkante an einem 40 mm Bauteil, eine Senkung auf einer Platte – kann aus den Ansichten
möglicherweise überhaupt nicht erkannt werden. Berichten Sie nicht, etwas zu sehen, das das Bild
nicht auflösen kann; das ist schlimmer, als nicht hinzusehen. Für solche Merkmale hat der Skill
Instrumente: check.py bores gibt jede zylindrische Fläche aus (Durchmesser, Achse, Position,
Spannweite, Richtung), sodass Sie abstimmen können,