Edge-first Inline-Inspektion: Wie man KI-Inferenz deterministisch an die SPS koppelt (ohne die Linie zu bremsen)
Das konkrete Problem
Visuelle Inline-Inspektion scheitert in der Produktion selten an der Modellgenauigkeit, sondern an Latenz und Jitter. Ein CNN, das im Labor 98% Defekte findet, nützt in der Linie wenig, wenn die SPS den Auswurf nach 80 ms erwartet, die Bildübertragung schwankt, die Inferenz manchmal 40 ms, manchmal 200 ms braucht und das Ergebnis dadurch zu spät oder unzuverlässig kommt. Die Folge: Stopps, Fehlwürfe, oder – schlimmer – Defekte, die passieren, weil der Fallback unsauber ist.
Dieser Artikel beschreibt, wie man KI-Inferenz deterministisch an die SPS (S7/Profinet, Codesys, Beckhoff, etc.) koppelt: Architektur, Datenpfade, Synchronisation, Fallback-Strategien. Alles Edge-first, ohne Cloud-Latenzen, DSGVO-konform, mit konkreten Implementierungsdetails aus realen Fertigungsumgebungen.
Warum deterministisch statt “schnell im Mittel”
Die Produktionslinie kennt keine 50th-Percentile. Tritt ein Bauteil unter Kamera X in T+35 ms in den Auswurfbereich ein, muss das System vorher ein valides Urteil liefern – jedes Mal. “Im Schnitt 25 ms” ist irrelevant, wenn das 99. Perzentil 120 ms ist. Entsprechend ist die Architektur auf Worst-Case und Jitter-Budgets zu optimieren, nicht auf Benchmark-Spitzenwerte.
Zielgröße: deterministische, zweistellige Millisekunden-Latenzen mit engem Jitter-Budget, vom Trigger bis zum Ergebnis-Bit in der SPS – und ein definierter sicheren Fallback, wenn das Budget überschritten wird.
Systemarchitektur: Trennung von Echtzeitpfad und Best-Effort
Bewährtes Muster ist eine klare Entkopplung:
- Echtzeitpfad (hard/firm real-time): Kamera-Trigger → Bildaufnahme → minimale Vorverarbeitung → Inferenz → Entscheidungsbits an SPS. Implementiert in C++ mit lockfreien Strukturen, ohne Heap-Allokation im Hot Path, mit Thread-Prioritäten (SCHED_FIFO), CPU-Pinning und deterministischer IO.
- Best-Effort-Pfad: Persistenz (Bildspeicher), Metriken, Dashboards, Batch-Auswertungen, Datasets, Training/Retuning, Model-Monitoring. Asynchron, darf nie den Echtzeitpfad blockieren.
Kommunikations- und Timing-Grundlagen
- Triggerung: Hardware-Trigger von der SPS zur Kamera oder zum Framegrabber (Bevorzugt), alternativ deterministische Software-Trigger aus einem Signal des Encoders/Geberrads, falls Zykluszeiten es erlauben.
- Zeitsynchronisation: PTP (IEEE 1588) zwischen SPS, Kamera/Framegrabber und Edge-Host. Ziel: konsistente Timestamps, um Auswurf-/Aktuatorfenster exakt zu timen.
- Handshake zur SPS: Ein definierter Zustandsautomat mit Bits für “Bild aufgenommen”, “Analyse läuft”, “Ergebnis gültig”, “Fail-Safe/Timeout”. Kein “wir schreiben einfach ein Ergebnisbit irgendwann”.
Referenz-Datenfluss (inline, Einzelkamera)
1) SPS setzt Trigger (Hardware-Strobe oder deterministisches Signal).
2) Kamera erfasst Bild und schreibt es per DMA zum Framegrabber/NIC.
3) Edge-Host nimmt Frame in einen Single-Producer-Single-Consumer (SPSC) Ringpuffer im Shared Memory auf (zero-copy oder ein kontrollierter Copy-Schritt).
4) Vorverarbeitung minimal (Crop/Normalize, ggf. Farbkanalwechsel); GPU/CPU-Entscheid abhängig vom Modell.
5) Inferenz via voroptimierter Engine (z. B. TensorRT/ONNX Runtime mit statisch gebauter Graph-Optimierung).
6) Postprocessing (Thresholding, Geometrie-Check, ROI-Mapping).
7) Ergebnis wird binär/bitcodiert an SPS zurückgegeben (z. B. “iO/n.iO”, “Klasse A/B/C”, “Unsicher”).
8) Asynchroner Pfad speichert selektiv Frames/Heatmaps/Logs für Nachvollziehbarkeit, nicht in-line-blockierend.
Kameraschnittstellen und Treiber-Entscheidungen
- GigE Vision: Flexibel, robust, PTP-fähig. Achten auf NIC/Interrupt-Affinität, Jumbo Frames, Receive-Side Scaling (deaktivieren, wenn es Jitter einführt), und deterministische Treiber-Einstellungen.
- USB3: Geringere Latenzpotenziale, aber empfindlicher für Host-Jitter und Kabel-/Stromthemen; nur mit geprüften Controllern einsetzen.
- CoaXPress/Camera Link: Sehr deterministisch, aber teurer und mit spezifischem Hardware-Stack; für hochauflösende, schnelle Linien eine gute Wahl.
Allgemeine Regel: Wählen Sie die simpelste, deterministisch kontrollierbare Kette. Eine vermeintlich “schnelle” Kamera nützt nichts, wenn der Host-Treiber jittert oder die NIC-IRQ überbucht ist.
Host-Tuning für deterministisches Verhalten
- CPU-Isolation: Dedizierte Cores für den Echtzeitpfad, nohz_full/isolcpus Kernel-Parameter oder cset Shielding. Keine Fremdprozesse/GC auf diesen Kernen.
- IRQ-Affinität: Kamera-/NIC-Interrupts an die Echtzeit-Cores pinnen. CPU-Steuerung: governor “performance”, fixe Frequenzen, Turbo/Boost ggf. deaktivieren, um Frequenzsprünge zu vermeiden.
- Speicher: Große Puffer vorallozieren, Pinned/Locked Memory für GPU-Transfers. Kein new/malloc im Hot Path. Lockfreie SPSC-Queues.
- Containerisierung: Wenn Container genutzt werden, beachten: CAP_SYS_NICE für RT-Prioritäten, cgroup-CPUSets hart zuweisen, keine Overcommitment. Timestamps via host PTP Namespace verfügbar machen.
- Kernel: PREEMPT_RT hilft, ist aber kein Muss, wenn der IO-Stack sauber getunt ist. Entscheidend ist Messbarkeit und Einhaltung des Worst-Case-Budgets.
Modelloptimierung für Latenz statt nur Genauigkeit
- Architekturwahl: Für Inline-Klassifikation/Segmentierung oft effizienter, eine spezialisierte, kleine Architektur mit gezieltem ROI-Crop zu nutzen, statt ein großes Generalisten-Netz. Split: schneller Segmentierer + regelbasierter Geometriecheck schlägt häufig ein großes All-in-one-Netz im Jitter.
- Quantisierung: INT8 kann Latenz und Konsistenz verbessern. Voraussetzung ist eine repräsentative Kalibrierung aus realer Linie (Verschmutzung, Beleuchtungsdrift, Bauteiltoleranzen). Kein Lab-only-Kalibrierdatensatz.
- Batchgröße: Immer Batch=1 im Echtzeitpfad. Mikro-Batching erzeugt Jitter und ist in Inline-Szenarien kontraproduktiv.
- Pre-/Postprocessing: Auf die gleiche Recheneinheit wie die Inferenz legen (GPU-Preprocessing, z. B. Farbkonvertierung/Resize via GPU), um PCIe-Jitter zu vermeiden.
- Standardisierung: Modell als festgebackenes Inferenz-Artifact (z. B. Engine/Plan-Datei). Keine On-the-fly-Kompilation bei Schichtwechsel.
Handshaking mit der SPS: Einfach, explizit, fehlertolerant
Minimaler Zustandsautomat (Beispiel, bitcodiert über Profinet/OPC UA/Shared Memory Gateway):
- TRIG_IN (SPS→Edge): Teil im Prüfbereich, Bild aufnehmen.
- CAP_ACK (Edge→SPS): Bild akquiriert.
- INFER_BUSY (Edge→SPS): Inferenz läuft.
- RES_VALID (Edge→SPS): Ergebnis liegt vor.
- RES_CODE[0..n] (Edge→SPS): Ergebnisbits (iO/n.iO/Klasse/Unsicher).
- TIMEOUT_FAILSAFE (Edge→SPS): Budget überschritten; in sichere Zustandslogik fallen (konservativer Auswurf, oder definierter Pass je nach Prozessgefahr).