Einen Stream transformieren (experimentell)

Der Stream ist experimentell (ab v2.1.0). Seine Knoten und Einstellungen können sich noch ändern. Nutzen Sie ihn zur Evaluierung, und prüfen Sie ihn mit Ihrem Aufbau, bevor Sie sich darauf verlassen.

Die Funktion transform rechnet die Punkte um, die Ihr Programm schreibt, ein Request nach dem anderen. Ein Stream funktioniert umgekehrt. Das Modul abonniert einen Data-Layer-Knoten, seine Quelle, und transformiert jedes Update davon, sobald es eintrifft. Die Quelle wird in zwei Teilen benannt: dem Ordner, in dem sie liegt (address), und dem Knoten in diesem Ordner (das node des Schritts). Das Modul veröffentlicht das Ergebnis auf <module name>/control/subscribe/output/stream/points, mit der Lineage des Updates - woher seine Punkte stammen - und auf <module name>/control/subscribe/output/stream/plain-points als einfaches Array, und Ihr Programm abonniert einen davon.

Ein Stream kann seine Punkte auf zwei Arten lesen. Der Schritt in der Liste onEntry des Abschnitts stream des Moduls gibt an, welche:

  • plain (kein Schritt oder ein plain-Schritt): Der Knoten enthält die Punkte selbst, als ein Array von Zahlen: x0,y0,x1,y1,…​ oder x0,y0,z0,x1,y1,z1,…​. Ein SPS-Array ist eine typische Quelle.

  • remap (ein remap-Schritt): Der Knoten enthält das Ergebnis einer anderen Anwendung als FlatBuffer - standardmäßig das Bild-Stream-Ergebnis von LumiScan AI Object Matching. Der Schritt benennt die Liste der Elemente darin und die Felder, die das x und y jedes Elements enthalten.

In beiden Fällen veröffentlicht das Modul ein Tripel pro Punkt, x,y,z, in der Reihenfolge der Quelle (siehe Die Punkte). Ein Plain-Stream kann die Punkte eines anderen Moduls lesen, sodass sich Module verketten lassen (siehe Module verketten).

Ein Modul hat eine Quelle, die mit der einen Lookup-Tabelle des Moduls transformiert wird. Um zwei Quellen zu transformieren, verwenden Sie zwei Module - auch für zwei Quellen im Bild derselben Kamera, die sich dann dieselbe Lookup-Tabellendatei teilen.

Ein Remap-Stream transformiert jedes Ergebnis seiner Quelle, unabhängig davon, von welcher Kamera es stammt: Ein Filter liest Felder der Elemente, nicht die Lineage des Ergebnisses. Um die Ergebnisse mehrerer Kameras mit der eigenen Tabelle jeder Kamera zu transformieren, geben Sie jeder Kamera ein eigenes AI-Object-Matching-Modul und jedem davon ein Calibration-Modul.

Einen Stream konfigurieren

Jedes Modul hat die Stream-Knoten, und jedes Modul kann streamen. Der Abschnitt stream seiner Modul-Konfigurationsdatei benennt die Quelle und enthält den Stream-Modus. Seine Liste onEntry enthält die Schritte, die jedes Update der Quelle lesen. Ein Modul, dessen Datei keinen Abschnitt stream hat, streamt plain, und control/subscribe/execute legt den Abschnitt an, wenn es die Quelle speichert.

Der Abschnitt stream hat in jeder LumiScan-Anwendung, die einen Stream abonniert, dieselben allgemeinen Schlüssel. Nur die Schritte unterscheiden sich:

"stream": {
    "enable": true,
    "address": "hdvisionsystems/lumiscan-ai-object-matching/example/control/subscribe/output/stream",
    "queueSize": 64,
    "keepLatestOutput": false,
    "onEntry": [
        { "kind": "remap", "node": "result", "array": "instances",
          "x": "oriented_bounding_box.center_x", "y": "oriented_bounding_box.center_y" }
    ]
}
Schlüssel Erforderlich Bedeutung

enable

Nein

Stream-Modus: true lässt den Stream ab dem Start der Anwendung laufen, ohne dass jemand control/subscribe/execute aufruft. Benötigt eine address. Weggelassen oder false: Der Stream ist aus, bis control/subscribe/execute ihn einschaltet.

address

Mit enable

Der Ordner des Knotens, der abonniert werden soll; das node des Schritts benennt den Knoten darin. Sie wird genau so verwendet, wie sie geschrieben ist: Die Groß-/Kleinschreibung bleibt erhalten, was ein SPS-Symbol benötigt. Für einen Plain-Stream muss der Knoten ein float32- oder float64-Array enthalten, für einen Remap-Stream einen FlatBuffer des schema des Schritts. Weggelassen oder leer, um zur Laufzeit zu abonnieren. Eine Adresse, die mit dem Knoten des Schritts endet - der Knoten selbst, nicht sein Ordner - wird mit dem noch einmal angehängten Knoten abonniert, was fehlschlägt: Das Protokoll warnt und nennt den Ordner, der zu schreiben ist.

tag

Nein

Das Tag auf den Punkten, die das Modul veröffentlicht: Der Schritt des Moduls in ihrer Lineage trägt es, sodass ein nachfolgender Client sieht, welches Modul sie transformiert hat. Weggelassen oder leer: der Modulname. Siehe Die Lineage der Punkte.

queueSize

Nein

Wie viele Updates auf die Transformation warten dürfen: 1 bis 4096, standardmäßig 64. Siehe Die Warteschlange.

keepLatestOutput

Nein

true schreibt die Punkte jedes Updates zusätzlich in die normale Ausgabe des Moduls. Siehe Die neueste Ausgabe behalten. Standardmäßig false.

onEntry

Nein

Die Schritte, die auf jedes Update bei seinem Eintreffen angewendet werden, der Reihe nach, jeder ein Objekt mit einem kind: ein plain- oder ein remap-Schritt. Derzeit wird ein Schritt verarbeitet; eine Liste mit mehreren ist fehlerhaft. Weggelassen oder leer: ein Plain-Stream mit 2 Zahlen pro Punkt.

onExit

Nein

Reserviert für Schritte, die auf die Punkte angewendet werden, bevor sie veröffentlicht werden. Wird noch nicht gelesen: Das Modul protokolliert eine Warnung, und die Schritte werden nicht angewendet.

  • Das Hinzufügen, Ändern oder Entfernen des Abschnitts stream wird mit einem reset des Moduls wirksam. Ein Neustart der Anwendung ist nicht nötig.

  • Ein Reset, der ändert, wie die Quelle gelesen wird - ein Schritt von onEntry -, startet den Stream im nächsten Zyklus des Moduls neu, etwa 100 ms später. Ein Reset, der nur enable, address, tag, queueSize oder keepLatestOutput ändert, startet nichts neu: Der laufende Stream folgt.

  • Der Abschnitt enthält auch den Stream-Modus und die Quelle, wie sie zur Laufzeit gesetzt wurden: control/subscribe/execute und control/unsubscribe/execute speichern sie darin. Siehe In der Modul-Konfigurationsdatei gespeichert.

  • Ein fehlerhafter Abschnitt stream ist eine fehlerhafte Moduldatei: Das Modul meldet Status -2 (invalidSetting) und transformiert nichts, bis er korrigiert und das Modul zurückgesetzt ist. Fehlerhaft sind zum Beispiel Stream-Modus ohne Quelle (enable auf true gesetzt und keine address), ein Schritt mit einem anderen kind und ein Schlüssel eines Schritts - kind, node, components, schema, rootType, array, x, y oder filters -, der oben im Abschnitt statt in onEntry steht. Das Protokoll nennt den Schlüssel.

Ein älterer Schlüssel subscriptions, der mehrere Quellen nach Tag benannte, wird nicht mehr gelesen: Das Modul protokolliert eine entsprechende Warnung. Übertragen Sie seine eine Quelle nach address - ihren Ordner - und in das node des Schritts.

Um zu sehen, was eine Quelle enthalten darf, lesen Sie hdvisionsystems/lumiscan-calibration/system/meta/subscription-schema: siehe Was eine Quelle enthalten darf.

Plain: Arrays von Punkten

"stream": {
    "enable": true,
    "address": "plc/app/Application/sym/GVL_Vision",
    "onEntry": [
        { "kind": "plain", "node": "aPixelPoints", "components": 3 }
    ]
}

Ein Stream ohne Schritt - kein onEntry oder ein leeres - ist plain, mit 2 Zahlen pro Punkt, und liest den Knoten points: die Punkte eines anderen Calibration-Moduls (siehe Module verketten). Ein plain-Schritt ist für einen anderen Knoten nötig, etwa ein SPS-Array, oder für 3 Zahlen pro Punkt.

Schlüssel des Schritts Erforderlich Bedeutung

kind

Ja

"plain"

node

Nein

Der Knoten des Ordners, der das Array enthält, zum Beispiel ein SPS-Symbol, aPixelPoints. Standardmäßig points.

components

Nein

Die Zahlen pro Punkt: 2 für x,y (der Standard), 3 für x,y,z. Die Lookup-Tabelle bildet ein Pixel ab, ein z wird daher ignoriert. Ein Array, dessen Länge keine ganze Anzahl von Punkten ergibt, wird nicht transformiert und in statistics/failed-updates gezählt.

Remap: Punkte aus dem Ergebnis einer anderen Anwendung

"stream": {
    "address": "hdvisionsystems/lumiscan-ai-object-matching/<module name>/control/subscribe/output/stream",
    "onEntry": [
        {
            "kind": "remap",
            "node": "result",
            "array": "instances",
            "x": "oriented_bounding_box.center_x",
            "y": "oriented_bounding_box.center_y",
            "filters": [
                { "field": "class_index", "anyOf": [0, 2] },
                { "field": "score", "min": 0.5 }
            ]
        }
    ]
}

Dieses Beispiel transformiert den Mittelpunkt jeder Box, die AI Object Matching in seinem Bild-Stream findet, für die Klassen 0 und 2 mit einem Score von mindestens 0.5. Es liest den Knoten result des Stream-Ordners des AI-Moduls, einen FlatBuffer des Standardschemas stream_detections.

Ein Stream-Ergebnis wie dieses enthält zwei Dinge: seine lineage und das Ergebnis selbst - dasselbe Ergebnis, das die Anwendung in ihre normale Ausgabe schreibt. Der Schritt liest innerhalb des Ergebnisses, array ist also der Pfad wie in der normalen Ausgabe: instances, die Liste der Funde von AI Object Matching. Die Punkte, die das Modul veröffentlicht, tragen die Lineage des AI-Ergebnisses - das Kamerabild, auf dem es inferiert wurde - mit dem eigenen Schritt des Moduls ergänzt.

Das Beispielmodul, das die Anwendung mitbringt, example, hat einen solchen Schritt ohne Filter. Es liest das Beispielmodul von AI Object Matching, ebenfalls example, von seinem Start an. Siehe Modul-Konfigurationsdatei.

Schlüssel des Schritts Erforderlich Bedeutung

kind

Ja

"remap"

node

Nein

Der Knoten des Ordners, der den FlatBuffer enthält. Standardmäßig result: das Stream-Ergebnis einer LumiScan-Anwendung in ihrem Ordner control/subscribe/output/stream.

schema

Nein

Welchen FlatBuffer der Knoten enthält; standardmäßig stream_detections, das Stream-Ergebnis von AI Object Matching. Entweder der Name eines Schemas, das die Anwendung mitbringt, oder der Pfad einer kompilierten Schemadatei (.bfbs), relativ zur Modul-Konfigurationsdatei. Die mitgelieferten Schemata, jeweils mit ihrem array:

* die Stream-Ergebnisse (Knoten result): stream_detections (AI Object Matching, instances), stream_template_matches (Template Finder, matches), stream_object_matches (Object Finder, matches), stream_areas (Area Detector, blobs), stream_codes (die Code Reader, results), stream_texts (Text Reader, words); * die normalen Ausgaben: object_detection (output/result von AI Object Matching, instances), template_match_result, object_find_result, area_detect_result, code_detect_result und text_read_result, mit denselben Listen; * die Punkte eines anderen Calibration-Moduls: stream_points (Knoten points, array points, x und y mit den Namen x und y).

rootType

Nein

Die Tabelle an der Wurzel des Buffers, mit ihrem Namespace, zum Beispiel hdv.object_detection2d.Result. Weglassen, um den eigenen Root-Typ des Schemas zu verwenden.

array

Nein

Der Pfad zur Liste, deren Elemente die Punkte sind, zum Beispiel instances. In einem Stream-Ergebnis beginnt er innerhalb des Ergebnisses, wie in der normalen Ausgabe. Weggelassen: keine Liste - das Ergebnis selbst ist das eine Element, und jedes Update liefert einen Punkt, oder keinen, wenn ein Filter es ablehnt. Siehe Ein Punkt pro Update.

x, y

Ja

Der Pfad innerhalb eines Elements zu seinem x und seinem y, zum Beispiel oriented_bounding_box.center_x.

filters

Nein

Nur die Elemente, die jeden Filter passieren, werden zu Punkten. Jeder Filter hat ein field (ein Pfad innerhalb eines Elements zu einer Zahl) und mindestens eines von anyOf (eine Liste von Werten, von denen das Feld einem gleichen muss), min und max (einschließende Grenzen). Ein Integer-Feld wird als Integer verglichen.

Ein Pfad ist eine Liste von Feldnamen, verbunden mit ., so wie das Schema sie benennt. Jeder Schritt außer dem letzten muss zu einer Struktur führen, der letzte zu einer Zahl. Das Modul prüft jeden Pfad beim Start des Streams gegen das Schema. Passt einer nicht, startet der Stream nicht, und das Protokoll sagt, welcher Schritt falsch ist. Zwei Fehler werden mit der Korrektur genannt:

  • ein array, das mit dem eigenen Feld des Stream-Ergebnisses beginnt, result.instances: Das Ergebnis wird bereits gelesen, schreiben Sie "array": "instances";

  • kein array, während x oder y nur in den Elementen einer Liste des Ergebnisses zu finden ist: Benennen Sie die Liste, zum Beispiel "array": "instances".

Ein Punkt pro Update

Ein Ergebnis, das keine Liste ist - eine Pose, eine Position -, liefert einen Punkt pro Update. Lassen Sie array weg, und benennen Sie die Felder innerhalb des Ergebnisses:

{ "kind": "remap", "schema": "my_result.bfbs", "node": "result", "x": "pose.x", "y": "pose.y" }

Die Filter gelten für dieses eine Element: Ein Update, das sie nicht passiert, wird ohne Punkte veröffentlicht.

Gut zu wissen:

  • Ein Feld, das das Element nicht setzt, wird als sein Standardwert im Schema gelesen, wie bei jedem FlatBuffer-Reader.

  • Fehlt eine Struktur auf einem Pfad in einem Element, wird der Punkt als NaN,NaN,NaN veröffentlicht, und ein Filter auf diesem Pfad lehnt das Element ab.

  • Ein Update, das kein gültiger Buffer des angegebenen Typs ist, wird nicht transformiert. Es wird in statistics/failed-updates gezählt, und das erste wird in das Protokoll geschrieben.

Adressen

Alle folgenden Adressen beginnen mit hdvisionsystems/lumiscan-calibration/<module name>/. Jedes Modul hat sie. Der Stream folgt dem Aufbau einer Execute-Methode: control/subscribe besitzt seine Eingaben und Ausgaben.

Tabelle 1. Methoden
Adresse Bedeutung

control/subscribe/execute

Prüft alle control/subscribe/input/…​ gemeinsam, speichert sie in der Modul-Konfigurationsdatei und wendet sie dann an: Der Stream folgt im nächsten Zyklus des Moduls, ohne Neustart. Siehe Zur Laufzeit abonnieren.

control/unsubscribe/execute

Entfernt die Quelle, die control/unsubscribe/input/address nennt, was auch den Stream-Modus beendet, und speichert das.

Tabelle 2. Eingaben
Adresse Typ Beim Start Bedeutung

control/subscribe/input/enable

bool

stream.enable oder false

true lässt den Stream laufen; false stoppt ihn.

control/subscribe/input/address

string

stream.address oder leer

Der Ordner des Knotens, der abonniert werden soll, genau wie geschrieben. Das node des Schritts benennt den Knoten darin.

control/subscribe/input/tag

string

stream.tag oder leer

Das Tag auf den Punkten, die das Modul veröffentlicht, in ihrer Lineage. Leer: der Modulname.

control/subscribe/input/queue-size

uint32

stream.queueSize oder 64

Wie viele Updates auf die Transformation warten dürfen, 1 bis 4096. Siehe Die Warteschlange.

control/subscribe/input/keep-latest-output

bool

stream.keepLatestOutput oder false

true schreibt die Punkte jedes Updates zusätzlich in die normale Ausgabe. Siehe Die neueste Ausgabe behalten.

control/unsubscribe/input/address

string

leer

Die Quelle, die control/unsubscribe/execute entfernt: die Adresse auf setting/stream/address.

Das Schreiben einer Eingabe ändert für sich allein nichts: Nur control/subscribe/execute wendet die Eingaben an. Sie beginnen mit dem, was das Modul anwendet, und ein Reset setzt sie wieder auf die Werte der Datei, sodass ein Client eine Eingabe ändern und die Methode aufrufen kann.

Tabelle 3. Ausgaben
Adresse Typ Bedeutung

control/subscribe/output/stream/active

bool

true, solange der Stream läuft.

control/subscribe/output/stream/points

flatbuffers (stream_points)

Die Punkte jedes Updates, transformiert, mit ihrer Lineage. Abonnieren Sie ihn, um jedes zu erhalten. Ein Lesen liefert das neueste. Siehe Die Punkte.

control/subscribe/output/stream/plain-points

float32-Array

Dieselben Punkte als einfaches Array, x0,y0,z0,x1,y1,z1,…​, ohne die Lineage: für einen Client, der keinen FlatBuffer lesen kann, etwa eine SPS.

control/subscribe/output/stream/statistics/…​

uint64

Zähler des aktuellen oder letzten Streams, siehe Die Statistik lesen.

Tabelle 4. Einstellung
Adresse Typ Bedeutung

setting/stream/enable, setting/stream/address, setting/stream/tag, setting/stream/queue-size, setting/stream/keep-latest-output

wie die Eingaben

Was das Modul jetzt anwendet, wie im Abschnitt stream gespeichert.

setting/settings-hash

string

Der Hash dessen, womit die Punkte transformiert werden, als 16 Hexadezimalziffern. Siehe Der Einstellungs-Hash.

Sofern keep-latest-output nicht gesetzt ist, werden die Punkte des Streams nur auf control/subscribe/output/stream/points und control/subscribe/output/stream/plain-points veröffentlicht, und die normalen Ausgaben behalten das Ergebnis des letzten Transforms auf Anfrage.

Was eine Quelle enthalten darf

hdvisionsystems/lumiscan-calibration/system/meta/subscription-schema (string, schreibgeschützt, experimentell) beschreibt, was der Knoten, den ein Modul abonniert, enthalten darf, als JSON Schema (draft-04) der JSON-Form des Knotens. Es führt drei Arten auf, von denen jede passt (anyOf):

  • ein einfaches Array von Zahlen - ein plain-Schritt oder keiner;

  • ein stream_points - die Punkte eines anderen Calibration-Moduls, plain gelesen;

  • ein stream_detections - das Stream-Ergebnis von AI Object Matching, gelesen von einem remap-Schritt mit dem Standardschema.

Es ist für jedes Modul gleich und sagt daher nicht, welche Art ein Modul liest: Das sagt sein onEntry-Schritt. Die Beschreibungen darin stammen aus den FlatBuffer-Schemata. Ein Feld eines FlatBuffers wird so gezeigt, wie das JSON von flatc --strict-json es darstellt: ein Enum über seinen Namen, eine Struktur als Objekt.

Einen Stream ausführen

  1. Abonnieren Sie control/subscribe/output/stream/points oder control/subscribe/output/stream/plain-points für das einfache Array.

  2. Schreiben Sie true auf control/subscribe/input/enable - und die Adresse der Quelle, falls das Modul noch keine hat - und true auf control/subscribe/execute. Warten Sie, bis control/subscribe/output/stream/active true ist. Ab dann werden Updates der Quelle transformiert.

  3. Zum Stoppen schreiben Sie false auf control/subscribe/input/enable und true auf control/subscribe/execute.

Gut zu wissen:

  • Der Stream-Modus wird im Abschnitt stream gespeichert, bevor er wirkt: Nach einem Neustart der Anwendung streamt das Modul wieder, oder nicht, wie zuvor. Niemand muss die Methode erneut aufrufen.

  • Der Stream läuft nur, solange die Lizenz vorhanden ist.

  • Kann der Stream nicht starten, weil ein Remap-Pfad nicht zum Schema passt, bleibt control/subscribe/output/stream/active false, und der Grund wird in das Protokoll geschrieben. Es wird nicht erneut versucht, bis das Modul zurückgesetzt oder der Stream-Modus mit control/subscribe/execute aus- und wieder eingeschaltet wird.

  • Eine Quelle, die nicht abonniert werden kann, zum Beispiel ein Knoten, der noch nicht existiert, hindert den Stream nicht am Laufen: Es wird alle 5 Sekunden erneut versucht, und der erste Fehlschlag wird in das Protokoll geschrieben.

  • Das Transformieren auf Anfrage funktioniert weiter, während der Stream läuft: Der transform-Handshake und control/transform/execute werden wegen des Streams nie abgelehnt.

  • Ein reset ersetzt die Lookup-Tabelle sofort, auch für den laufenden Stream: Das nächste Update wird mit der neuen Tabelle transformiert. Schlägt der Reset fehl, hat das Modul keine Tabelle, und der Stream veröffentlicht NaN für jeden Punkt, bis ein Reset gelingt.

Die Warteschlange

Die Updates der Quelle warten in einer Warteschlange, in der Reihenfolge ihres Eintreffens, und werden nacheinander transformiert. Ein Update wird nur verworfen, wenn die Warteschlange voll ist - queueSize Updates, standardmäßig 64, warten bereits: Dann geht das älteste verloren und wird in statistics/skipped-updates gezählt.

Eine größere queueSize übersteht längere Lastspitzen, ohne ein Update zu verwerfen; aktualisiert die Quelle aber über längere Zeit schneller, als das Modul transformiert, sind die veröffentlichten Punkte älter: bis zu queueSize Updates im Rückstand. Eine kleinere hält die Punkte aktuell und verwirft mehr.

Eine geänderte Warteschlangengröße gilt sofort, ohne Neustart des Streams. Schrumpft sie unter die Zahl der bereits wartenden Updates, werden die ältesten davon verworfen und als übersprungen gezählt.

Zur Laufzeit abonnieren

Eine SPS oder ein anderer Client ändert die Quelle und den Stream-Modus, während die Anwendung läuft, mit oder ohne laufenden Stream:

  1. Schreiben Sie die Eingaben, die sich ändern, auf control/subscribe/input/…​ - für eine andere Quelle control/subscribe/input/address, ihren Ordner (der Knoten darin bleibt der des Schritts); zum Starten oder Stoppen control/subscribe/input/enable; für ein anderes Tag auf den Punkten control/subscribe/input/tag.

  2. Schreiben Sie true auf control/subscribe/execute.

Die Methode prüft alle Eingaben gemeinsam, speichert sie im Abschnitt stream und wendet sie dann an: setting/stream/…​ zeigt sie sofort, und ein laufender Stream folgt im nächsten Zyklus des Moduls. Eine andere Adresse ersetzt die Quelle - ein vorheriges Unsubscribe ist nicht nötig -, und die Updates, die die alte Quelle noch wartend hatte, werden verworfen und als übersprungen gezählt. Die Warteschlangengröße und keep-latest-output gelten, ohne erneut zu abonnieren, ebenso das Tag: Die ab dann veröffentlichten Punkte tragen es.

Um die Quelle zu entfernen, schreiben Sie ihre Adresse auf control/unsubscribe/input/address und true auf control/unsubscribe/execute. Das beendet auch den Stream-Modus und speichert enable als false ohne Adresse. Das Tag bleibt: Es markiert die Punkte des Moduls, nicht die Quelle. control/subscribe/input/…​ werden ebenfalls darauf gesetzt, sodass ein späteres control/subscribe/execute, das eine andere Eingabe ändert, die Quelle nicht zurückbringt. Ein / an einem der Enden einer Adresse spielt keine Rolle.

Die Methoden antworten wie folgt. Wo ein Ergebnis nur einen Namen hat, ist es der Name auf dem ctrlX Data Layer; LumiScan Keryx meldet dasselbe Ergebnis unter eigenem Namen, siehe Ergebnisse eines Methodenaufrufs.

Ergebnis Wann

DL_OK

Erledigt.

DL_INVALID_VALUE (ctrlX Data Layer), Rejected (LumiScan Keryx)

control/subscribe: enable ist true und die Adresse ist leer, oder die Warteschlangengröße liegt nicht zwischen 1 und 4096. control/unsubscribe: Die Adresse ist nicht die Quelle, oder es gibt keine Quelle. Nichts hat sich geändert.

DL_CREATION_FAILED

Die Änderung konnte nicht in der Modul-Konfigurationsdatei gespeichert werden: Die Datei konnte nicht gelesen oder geschrieben werden. Nichts hat sich geändert: Der Stream bleibt, wie er war. Die Antwort und das Protokoll nennen den Grund.

DL_RESOURCE_UNAVAILABLE

Die Einstellungen wurden auf system/settings bearbeitet, und die Anwendung wartet auf einen Neustart.

In der Modul-Konfigurationsdatei gespeichert

Stream-Modus und Quelle sind Einstellungen des Moduls, im Abschnitt stream seiner Konfigurationsdatei. control/subscribe/execute und control/unsubscribe/execute speichern enable, address, tag, queueSize und keepLatestOutput dort, bevor sie sie anwenden: Können sie nicht gespeichert werden, antwortet die Methode mit DL_CREATION_FAILED, und nichts ändert sich. Nach einem Neustart abonniert das Modul dieselbe Quelle und startet, wenn enable true ist, seinen Stream sofort.

Das Speichern ändert nur diese Werte: Der Rest der Datei bleibt, wie er war, einschließlich Kommentaren und der Schritte von onEntry. Eine Datei ohne Abschnitt stream erhält einen, mit diesen Werten und ohne Schritt: ein Plain-Stream.

Ein Reset liest die Datei erneut ein und setzt die Eingaben darauf: Eine Änderung, die Sie von Hand in der Datei vornehmen, wird mit dem nächsten Reset wirksam.

Die neueste Ausgabe behalten

Mit gesetztem keep-latest-output werden die Punkte jedes Updates zusätzlich in die normale Ausgabe des Moduls geschrieben, so wie ein Transform auf Anfrage sie schreibt: output/x-coordinate-array, output/y-coordinate-array und output/z-coordinate-array, output/timestamp und output/package-identifier, weitergezählt von den Transforms auf Anfrage. Ein Client, der die normale Ausgabe liest - zum Beispiel ein SPS-Programm, das für die Funktion transform geschrieben wurde -, sieht dort dann die neuesten Punkte des Streams. Ein Punkt, der nicht transformiert werden kann, ist auch dort NaN.

Es kostet eine Kopie der Punkte jedes Updates und ist deshalb standardmäßig aus. Die Punkte auf control/subscribe/output/stream/points werden zuerst veröffentlicht.

Die Punkte

control/subscribe/output/stream/points enthält eine FlatBuffers-Tabelle vom Typ stream_points, auf dem Data Layer registriert als types/hdvisionsystems/lumiscan-calibration/stream_points. Ihr kompiliertes Schema ist als bfbs/stream_points.bfbs installiert.

Feld Bedeutung

points

Je ein x, y, z (float32) pro Punkt des Updates, in dessen Reihenfolge.

invalid

Wie viele der Punkte nicht transformiert werden konnten.

lineage

Woher das Update stammt, siehe Die Lineage der Punkte.

control/subscribe/output/stream/plain-points veröffentlicht dieselben Punkte als x0,y0,z0,x1,y1,z1,…​, direkt nach control/subscribe/output/stream/points.

  • Der i-te Punkt ist der i-te Punkt des Updates. Ein Punkt, der nicht transformiert werden kann, wird an seiner Stelle als NaN veröffentlicht, sodass die Reihenfolge erhalten bleibt. Ein Punkt kann nicht transformiert werden, wenn er außerhalb der Lookup-Tabelle liegt oder wenn das Modul keine Tabelle hat.

  • Ein Update ohne Punkte wird ohne Punkte veröffentlicht.

  • z ist der Wert der Lookup-Tabelle. Ein z in einer Plain-Quelle mit components 3 wird ignoriert.

Ein Punkt außerhalb der Lookup-Tabelle wird nur vom Stream als NaN veröffentlicht. Auf Anfrage liefert die Funktion transform für einen solchen Punkt einen Wert vom Rand der Tabelle, ohne Fehler, wie schon immer. Halten Sie die Punkte, die Sie anfragen, innerhalb des Bildes, für das die Tabelle erstellt wurde.

Module verketten

control/subscribe/output/stream/points eines Moduls kann die Quelle eines Plain-Streams in einem anderen Modul sein. Das zweite Modul liest ihn als x,y,z-Punkte, unabhängig von seinem components, transformiert das x und y jedes Punkts und ignoriert das z. Seine Punkte tragen die Lineage des ersten Moduls mit seinem eigenen Schritt ergänzt. control/subscribe/output/stream/plain-points funktioniert ebenfalls als Quelle, mit components 3, aber seine Punkte beginnen eine eigene Lineage.

Die Lineage der Punkte

lineage.steps listet auf, woher die Punkte eines Updates stammen, Ursprung zuerst:

  • Eine Quelle, die eine Lineage trägt - control/subscribe/output/stream/result von AI Object Matching, control/subscribe/output/stream/points eines anderen Moduls -, gibt ihre Schritte weiter: zuerst der Schritt der Kamera (producer die Adresse der Kamera, tag das Tag des Cam-Driver-Moduls, run und sequence die Stelle des Bildes im Stream der Kamera), dann der des AI-Moduls, mit dem Tag des AI-Moduls.

  • Eine Quelle, die keine trägt - ein SPS-Array -, erhält einen für sie erzeugten Schritt, markiert als synthesized: Sein producer ist die Adresse des Knotens, Ordner und Knoten; er hat kein tag; seine sequence ist der eigene Zähler des Moduls seit dem Start des Streams. Auf LumiScan Keryx ist die sequence die Sequenznummer des Data Layers für das Update, wo es eine gibt, sonst der eigene Zähler des Moduls.

  • Der eigene Schritt des Moduls kommt zuletzt: producer ist die Adresse des Moduls, hdvisionsystems/lumiscan-calibration/<module name>; tag das Tag des Moduls (stream.tag) oder der Modulname, wenn es keines hat; run, wann der Stream des Moduls gestartet wurde; sequence die Nummer des Updates im Lauf; settings_hash, siehe Der Einstellungs-Hash; elapsed_us die Mikrosekunden vom Eintreffen des Updates bis zur Veröffentlichung der Punkte.

Das tag jedes Schritts sagt, welches Modul das Update dort verarbeitet hat - der eigene Name des Moduls oder das Tag, das es erhalten hat. Geben Sie zwei gleichnamigen Modulen in verschiedenen Anwendungen, oder einem Modul, dessen Name wenig aussagt, ein Tag, das sagt, was es in Ihrer Linie tut.

Eine Quelle, die geändert wird, während der Stream läuft, behält den Lauf des Moduls: Die Updates der neuen Quelle werden weitergezählt, und der producer ihres ersten Schritts benennt sie.

Der Einstellungs-Hash

setting/settings-hash und der settings_hash des Modulschritts identifizieren, womit die Punkte transformiert werden. Der Hash ändert sich, wenn sich eines davon ändert:

  • die Einstellungen der Modul-Konfigurationsdatei - außer dem name des Transforms; enable, address, dem node seines Schritts, tag, queueSize und keepLatestOutput des Streams, die die Updates schalten, auswählen, takten und markieren, statt ihre Punkte zu ändern; und seinem onExit, das noch nicht gelesen wird;

  • die Lookup-Tabelle (relativePathToTiff) nach ihrem Inhalt - eine neue Tabelle unter dem alten Dateinamen ist ein neuer Hash; und das schema eines Remap-Schritts nach seinem Inhalt - dasselbe Schema unter anderem Namen ist derselbe Hash;

  • die Version der Anwendung.

Ein Reset liest sie erneut ein. Wenn ein Hash zum ersten Mal auftritt, schreibt das Modul die Einstellungen, für die er steht, nach settings-history/<module name>-<hash>.json im Konfigurationsordner der Anwendung, sodass ein Hash, der in der Lineage der Punkte gefunden wird, später nachgeschlagen werden kann.

Die Punkte tragen nur den Hash. Ein anderer Hash sagt, dass sich etwas geändert hat, womit sie transformiert werden, nicht was. Um es herauszufinden, vergleichen Sie die beiden Dateien in settings-history, die die Hashes benennen, von Hand.

Die Statistik lesen

Die Zähler beginnen bei jedem Start des Streams bei null und werden etwa viermal pro Sekunde aktualisiert, solange er läuft. Alle Adressen beginnen mit control/subscribe/output/stream/statistics/.

Zähler Bedeutung

elapsed-ms

Millisekunden seit dem Start des Streams. Teilen Sie die anderen Zähler dadurch, um Raten zu erhalten.

received-updates

Updates der Quelle, die eingetroffen sind.

transformed-updates

Updates, die transformiert und auf control/subscribe/output/stream/points und control/subscribe/output/stream/plain-points veröffentlicht wurden.

skipped-updates

Updates, die unverarbeitet verworfen wurden, weil die Warteschlange voll war (queueSize, standardmäßig 64): Das Modul konnte mit der Quelle nicht Schritt halten. Das älteste wartende Update wird zuerst verworfen. Außerdem die Updates, die warteten, als die Quelle ersetzt wurde oder als die Warteschlangengröße unter ihre Zahl schrumpfte.

failed-updates

Updates, die nicht transformiert werden konnten: nicht der erwartete Typ oder die erwartete Länge, oder kein gültiger Buffer. Das erste wird in das Protokoll geschrieben.

lost-updates

Updates, die verworfen wurden, bevor sie eintrafen. Für eine Quelle, die eine Lineage trägt, ermittelt aus Lücken in der sequence des Schritts ihres Produzenten innerhalb eines Laufs. Auf LumiScan Keryx, für ein einfaches Array, aus Lücken in den Sequenznummern des Data Layers. Eine neue Quelle beginnt die Zählung neu.

points

Transformierte Punkte, alle Updates zusammen.

invalid-points

Davon die Punkte, die als NaN veröffentlicht wurden.

transform-us

Mikrosekunden, die alle Transformationen gedauert haben, summiert. Teilen Sie durch transformed-updates für den Mittelwert.

Was ein Stream empfängt

control/subscribe/output/stream/points veröffentlicht jedes Update an seine Abonnenten. Was der Stream selbst empfängt, hängt vom Quellknoten ab:

Data Layer Quelle, die jedes Update veröffentlicht (zum Beispiel control/subscribe/output/stream/result von AI Object Matching oder control/subscribe/output/stream/points eines anderen Moduls) Gewöhnlicher Knoten (zum Beispiel ein SPS-Array)

ctrlX Data Layer (ctrlX OS)

Jedes Update, in Reihenfolge.

Der Wert etwa alle 100 ms. Änderungen dazwischen werden nicht gesehen.

LumiScan Keryx (PC)

Jedes Update, in Reihenfolge.

Jede Änderung: Dieselben Werte erneut zu schreiben ist kein Update.

Auf dem ctrlX Data Layer wurde der Stream mit einer SPS-Quelle auf einem Gerät noch nicht gemessen.

Das Stream-Konzept aller LumiScan-Anwendungen ist unter Streams (experimentell) beschrieben.