Load Carrier Funktionalität¶
Einleitung¶
Die Load Carrier Funktionalität wird von einer internen Load Carrier Komponente bereitgestellt und kann nur über die Softwaremodule genutzt werden, die diese Funktionalität anbieten.
Die Load Carrier Funktionalität wird von den ItemPick und BoxPick Modulen und vom SilhouetteMatch Modul angeboten.
Load Carrier¶
Ein sogenannter Load Carrier ist ein Behälter mit vier Wänden, einem Boden und einem rechteckigen Rand, der Objekte enthalten kann.
Seine Geometrie ist durch die inneren und äußeren Abmessungen (inner_dimensions
und outer_dimensions
) definiert. Die maximalen outer_dimensions
betragen 2.0 m in allen Dimensionen.
Bemerkung
Die Innen- und Außenmaße eines Behälters sind typischerweise in den Angaben des jeweiligen Herstellers spezifiziert, und können im Produktblatt oder auf der Produktseite nachgeschlagen werden.
Der rc_visard erlaubt das Speichern von bis zu 50 verschiedenen Behältern, von denen jeder mit einer id
versehen ist. Die für eine spezifische Anwendung relevanten Behälter können mithilfe der rc_visard Web GUI oder der REST-API-Schnittstelle konfiguriert werden.
Bemerkung
Die konfigurierten Behälter sind persistent auf dem rc_visard gespeichert und auch nach Firmware-Updates und -Wiederherstellungen verfügbar.
Erkennung von Load Carriern¶
Der Erkennungsalgorithmus basiert auf der Erkennung des oberen, rechteckigen Randes (engl. rim) des Behälters. Für Standardbehälter wird dessen Stärke rim_thickness
aus der Differenz von inner_dimensions
und outer_dimensions
berechnet. Für Nicht-Standardbehälter kann dieser Wert alternativ vom Nutzer explizit gesetzt werden.
Das Referenzkoordinatensystem für Load Carrier ist so definiert, dass dessen Urprung im Zentrum des durch die Außenmaße definierten Quaders liegt. Dabei zeigt die z-Achse senkrecht aus dem Behälter hinaus. Bei der Erkennung wird auch ermittelt, ob der Load Carrier überfüllt (overfilled
) ist.
Um Mehrdeutigkeiten bei der Lageschätzung der Behältererkennung zu umgehen, kann eine grobe Vorgabe für die Pose pose
des Behälters spezifiziert werden. Wird keine angegeben, sucht der Algorithmus standardmäßig nach Behältern, die horizontal zum Gravitationsvektor stehen.
Füllstandserkennung¶
Die Load Carrier Funktionalität bietet den Service detect_filling_level
an, um den Füllstand eines erkannten Load Carriers zu berechnen.
Dazu wird der Load Carrier in eine konfigurierbare Anzahl von Zellen unterteilt, welche in einem 2D-Raster angeordnet sind. Die maximale Anzahl der Zellen beträgt 10x10. Für jede Zelle werden folgende Werte ermittelt:
level_in_percent
: Minimum, Maximum und Mittelwert des Füllstands vom Boden in Prozent. Diese Werte können größer als 100% sein, falls die Zelle überfüllt ist.level_free_in_meters
: Minimum, Maximum und Mittelwert in Metern des freien Teils der Zelle vom Rand des Load Carriers gemessen. Diese Werte können negativ sein, falls die Zelle überfüllt ist.cell_size
: Abmessungen der 2D-Zelle in Metern.cell_position
: Position des Mittelpunkts der Zelle in Metern (entweder im Koordinatensystemcamera
oderexternal
, siehe Hand-Auge-Kalibrierung). Die z-Koordinate liegt auf der Ebene des Load Carrier Randes.coverage
: Anteil der gültigen Pixel in dieser Zelle. Dieser Wert reicht von 0 bis 1 in Schritten von 0.1. Ein niedriger Wert besagt, dass die Zelle fehlende Daten beinhaltet (d.h. nur wenige Punkte konnten in der Zelle gemessen werden).
Diese Werte werden auch für den gesamten Load Carrier berechnet. Falls keine Zellunterteilung angegeben ist, wird nur der Gesamtfüllstand (overall_filling_level
) berechnet.
Wechselwirkung mit anderen Modulen¶
Die folgenden, intern auf dem rc_visard laufenden Module liefern Daten für die Load Carrier Funktionalität oder haben Einfluss auf die Datenverarbeitung.
Bemerkung
Jede Konfigurationsänderung dieser Module kann direkte Auswirkungen auf die Qualität oder das Leistungsverhalten der Load Carrier Funktionalität haben.
Stereokamera und Stereo-Matching¶
Folgende Daten werden von der Load Carrier Funktionalität verarbeitet:
- Die rektifizierten Bilder des Stereokamera-Moduls (
rc_stereocamera
); - Die Disparitäts-, Konfidenz- und Fehlerbilder des Stereo-Matching-Moduls (
rc_stereomatching
).
Für alle genutzten Bilder ist garantiert, dass diese nach dem Auslösen des Services aufgenommen wurden.
Schätzung der Gravitationsrichtung¶
Jedes Mal, wenn eine Behälter- oder Füllstandserkennung durchgeführt wird, wird die Gravitationsrichtung basierend auf den IMU-Daten des rc_visard geschätzt.
Bemerkung
Die Richtung des Gravitationsvektors wird durch Messungen der linearen Beschleunigung der IMU bestimmt. Für eine korrekte Schätzung des Gravitationsvektors muss der rc_visard stillstehen.
IOControl und Projektor-Kontrolle¶
Für den Anwendungsfall, dass der rc_visard zusammen mit einem externen Musterprojektor und dem Modul für IOControl und Projektor-Kontrolle (rc_iocontrol
) betrieben wird, wird empfohlen, den Projektor an GPIO Out 1 anzuschließen und den Aufnahmemodus des Stereokamera-Moduls auf SingleFrameOut1
zu setzen (siehe Stereomatching-Parameter, damit bei jedem Aufnahme-Trigger ein Bild mit und ohne Projektormuster aufgenommen wird.
Alternativ kann der verwendete digitale Ausgang in den Betriebsmodus ExposureAlternateActive
geschaltet werden (siehe Beschreibung der Laufzeitparameter).
In beiden Fällen sollte die Belichtungszeitregelung (exp_auto_mode
) auf AdaptiveOut1
gesetzt werden, um die Belichtung beider Bilder zu optimieren (siehe Stereokamera-Parameter.
Darüber hinaus sind keine weiteren Änderungen für diesen Anwendungsfall notwendig.
Hand-Auge-Kalibrierung¶
Falls die Kamera zu einem Roboter kalibriert wurde, kann die Load Carrier Komponente automatisch Posen im Roboterkoordinatensystem ausgeben. Für die Services kann das Koordinatensystem der berechneten Posen mit dem Argument pose_frame
spezifiziert werden.
Zwei verschiedene Werte für pose_frame
können gewählt werden:
- Kamera-Koordinatensystem (
camera
): Alle Posen sind im Kamera-Koordinatensystem angegeben und es ist kein zusätzliches Wissen über die Lage der Kamera in seiner Umgebung notwendig. Das bedeutet insbesondere, dass sich Load Carrier, welche in diesem Koordinatensystem angegeben sind, mit der Kamera bewegen. Es liegt daher in der Verantwortung des Anwenders, in solchen Fällen die entsprechenden Posen der Situation entsprechend zu aktualisieren (beispielsweise für den Anwendungsfall einer robotergeführten Kamera). - Benutzerdefiniertes externes Koordinatensystem (
external
): Alle Posen sind im sogenannten externen Koordinatensystem angegeben, welches vom Nutzer während der Hand-Auge-Kalibrierung gewählt wurde. In diesem Fall bezieht die Load Carrier Funktionalität alle notwendigen Informationen über die Kameramontage und die kalibrierte Hand-Auge-Transformation automatisch vom Modul Hand-Auge-Kalibrierung. Für den Fall einer robotergeführten Kamera ist vom Nutzer zusätzlich die jeweils aktuelle Roboterposerobot_pose
anzugeben.
Bemerkung
Wenn keine Hand-Auge-Kalibrierung durchgeführt wurde bzw. zur Verfügung steht, muss als Referenzkoordinatensystem pose_frame
immer camera
angegeben werden.
Zulässige Werte zur Angabe des Referenzkoordinatensystems sind camera
und external
. Andere Werte werden als ungültig zurückgewiesen.
Parameter¶
Die Load Carrier Funktionalität wird intern von mehreren anderen Softwaremodulen genutzt und ihre Parameter und Services werden von diesen Modulen zur Verfügung gestellt. Sie können auch in der Web GUI auf der Seite des jeweiligen Softwaremoduls (unter der Seite Module) genutzt werden. Der Benutzer kann die Parameter entweder dort oder über die REST-API-Schnittstelle ändern.
Übersicht über die Parameter¶
Diese Komponente bietet folgende Laufzeitparameter:
Name | Typ | Min. | Max. | Default | Beschreibung |
---|---|---|---|---|---|
load_carrier_crop_distance |
float64 | 0.0 | 0.05 | 0.005 | Sicherheitsspielraum um den das Load Carrier Innenmaß verringert wird, um eine Region of Interest für die Erkennung zu definieren |
load_carrier_model_tolerance |
float64 | 0.003 | 0.025 | 0.008 | Gibt an, wie weit die Abmessungen des Load Carriers von den Werten im Modell abweichen dürfen |
Beschreibung der Laufzeitparameter¶
Die Laufzeitparameter werden in der Web GUI zeilenweise im Abschnitt Parameter zur Load Carrier Detektion auf der Seite des Softwaremoduls, das die Load Carrier Funktionalität anbietet, dargestellt. Im folgenden wird der Name des Parameters in der Web GUI in Klammern hinter dem eigentlichen Parameternamen angegeben. Die Parameter sind in derselben Reihenfolge wie in der Web GUI aufgelistet:
load_carrier_model_tolerance
(Modelltoleranz)¶
Gibt an, wie weit die Abmessungen des Load Carriers von den Werten im Modell abweichen dürfen.
load_carrier_crop_distance
(Cropping)¶
setzt den Sicherheitsspielraum, um den das Load Carrier Innenmaß verringert wird, um eine Region of Interest für die Erkennung zu definieren.
Services¶
Die angebotenen Services der Load Carrier Komponente können mithilfe der REST-API-Schnittstelle oder der rc_visard Web GUI auf der Seite des Softwaremoduls, das diese Funktionalität anbietet, ausprobiert und getestet werden.
Zusätzlich zur eigentlichen Serviceantwort gibt jeder Service einen sogenannten return_code
bestehend aus einem Integer-Wert und einer optionalen Textnachricht zurück. Erfolgreiche Service-Anfragen werden mit einem Wert von 0
quittiert. Positive Werte bedeuten, dass die Service-Anfrage zwar erfolgreich bearbeitet wurde, aber zusätzliche Informationen zur Verfügung stehen. Negative Werte bedeuten, dass Fehler aufgetreten sind. Für den Fall, dass mehrere Rückgabewerte zutreffend wären, wird der kleinste zurückgegeben, und die entsprechenden Textnachrichten werden in return_code.message
akkumuliert.
Die folgende Tabelle führt die möglichen Rückgabe-Codes an:
Code | Beschreibung |
---|---|
0 | Erfolgreich |
-1 | Ungültige(s) Argument(e) |
-4 | Die maximal erlaubte Zeitspanne von 5.0 Sekunden für die interne Akquise der Bilddaten wurde überschritten. |
-10 | Das neue Element konnte nicht hinzugefügt werden, da die maximal speicherbare Anzahl an Load Carriern überschritten wurde. |
-302 | Es wurde mehr als ein Load Carrier an den detect_load_carriers oder detect_filling_level Service übergeben, aber nur einer wird unterstützt. |
10 | Die maximal speicherbare Anzahl an Load Carriern wurde erreicht. |
11 | Mit dem Aufruf von set_load_carrier wurde ein bereits existierendes Objekt mit derselben id überschrieben. |
100 | Die angefragten Load Carrier wurden in der Szene nicht gefunden. |
102 | Der erkannte Load Carrier ist leer. |
300 | Ein gültiges robot_pose -Argument wurde angegeben, ist aber nicht erforderlich. |
Alle Softwaremodule, die die Load Carrier Funktionalität anbieten, stellen folgende Services zur Verfügung.
set_load_carrier
¶
speichert einen Load Carrier auf dem rc_visard. Alle Load Carrier sind dauerhaft gespeichert, auch über Firmware-Updates und -Wiederherstellungen hinweg.
Die Definition der Request-Argumente mit jeweiligen Datentypen ist:
{ "args": { "load_carrier": { "id": "string", "inner_dimensions": { "x": "float64", "y": "float64", "z": "float64" }, "outer_dimensions": { "x": "float64", "y": "float64", "z": "float64" }, "pose": { "orientation": { "w": "float64", "x": "float64", "y": "float64", "z": "float64" }, "position": { "x": "float64", "y": "float64", "z": "float64" } }, "pose_frame": "string", "rim_thickness": { "x": "float64", "y": "float64" } } } }Die Definition des Typs
load_carrier
wird in Erkennung von Load Carriern beschrieben.Die Definition der Response mit jeweiligen Datentypen ist:
{ "name": "set_load_carrier", "response": { "return_code": { "message": "string", "value": "int16" } } }
get_load_carriers
¶
gibt die mit
load_carrier_ids
spezifizierten, gespeicherten Load Carrier zurück. Werden keineload_carrier_ids
angegeben, enthält die Serviceantwort alle gespeicherten Load Carrier.Die Definition der Request-Argumente mit jeweiligen Datentypen ist:
{ "args": { "load_carrier_ids": [ "string" ] } }Die Definition der Response mit jeweiligen Datentypen ist:
{ "name": "get_load_carriers", "response": { "load_carriers": [ { "id": "string", "inner_dimensions": { "x": "float64", "y": "float64", "z": "float64" }, "outer_dimensions": { "x": "float64", "y": "float64", "z": "float64" }, "pose": { "orientation": { "w": "float64", "x": "float64", "y": "float64", "z": "float64" }, "position": { "x": "float64", "y": "float64", "z": "float64" } }, "pose_frame": "string", "rim_thickness": { "x": "float64", "y": "float64" } } ], "return_code": { "message": "string", "value": "int16" } } }
delete_load_carriers
¶
löscht die mit
load_carrier_ids
spezifizierten, gespeicherten Load Carrier. Alle zu löschenden Load Carrier müssen explizit angegeben werden.Die Definition der Request-Argumente mit jeweiligen Datentypen ist:
{ "args": { "load_carrier_ids": [ "string" ] } }Die Definition der Response mit jeweiligen Datentypen ist:
{ "name": "delete_load_carriers", "response": { "return_code": { "message": "string", "value": "int16" } } }
detect_load_carriers
¶
löst die Erkennung von Load Carriern aus, wie in Erkennung von Load Carriern beschrieben.
Request:
Die Definition der Request-Argumente mit jeweiligen Datentypen ist:
{ "args": { "load_carrier_ids": [ "string" ], "pose_frame": "string", "region_of_interest_id": "string", "robot_pose": { "orientation": { "w": "float64", "x": "float64", "y": "float64", "z": "float64" }, "position": { "x": "float64", "y": "float64", "z": "float64" } } } }Obligatorische Serviceargumente:
pose_frame
: siehe Hand-Auge-Kalibrierung.
load_carrier_ids
: IDs der zu erkennenden Load Carrier.Möglicherweise benötigte Serviceargumente:
robot_pose
: siehe Hand-Auge-Kalibrierung.Optionale Serviceargumente:
region_of_interest_id
: Die ID der 3D Region of Interest, innerhalb welcher nach den Load Carriern gesucht wird.Warnung
In SilhouetteMatch gibt es anstelle des Feldes
region_of_interest_id
das Feldregion_of_interest_2d_id
, welches die ID der 2D Region of Interest enthält, innerhalb welcher nach den Load Carriern gesucht wird.Response:
Die Definition der Response mit jeweiligen Datentypen ist:
{ "name": "detect_load_carriers", "response": { "load_carriers": [ { "id": "string", "inner_dimensions": { "x": "float64", "y": "float64", "z": "float64" }, "outer_dimensions": { "x": "float64", "y": "float64", "z": "float64" }, "overfilled": "bool", "pose": { "orientation": { "w": "float64", "x": "float64", "y": "float64", "z": "float64" }, "position": { "x": "float64", "y": "float64", "z": "float64" } }, "pose_frame": "string", "rim_thickness": { "x": "float64", "y": "float64" } } ], "return_code": { "message": "string", "value": "int16" }, "timestamp": { "nsec": "int32", "sec": "int32" } } }
load_carriers
: Liste der erkannten Load Carrier (Behälter).
timestamp
: Zeitstempel des Bildes, auf dem die Erkennung durchgeführt wurde.
return_code
: enthält mögliche Warnungen oder Fehlercodes und Nachrichten.
detect_filling_level
¶
löst eine Behälter-Füllstandserkennung aus, wie in Füllstandserkennung beschrieben.
Request:
Die Definition der Request-Argumente mit jeweiligen Datentypen ist:
{ "args": { "filling_level_cell_count": { "x": "uint32", "y": "uint32" }, "load_carrier_ids": [ "string" ], "pose_frame": "string", "region_of_interest_id": "string", "robot_pose": { "orientation": { "w": "float64", "x": "float64", "y": "float64", "z": "float64" }, "position": { "x": "float64", "y": "float64", "z": "float64" } } } }Obligatorische Serviceargumente:
pose_frame
: siehe Hand-Auge-Kalibrierung.
load_carrier_ids
: IDs der zu erkennenden Load Carrier.Möglicherweise benötigte Serviceargumente:
robot_pose
: siehe Hand-Auge-Kalibrierung.Optionale Serviceargumente:
filling_level_cell_count
: Anzahl der Zellen im Füllstandsraster.
region_of_interest_id
: Die ID der 3D Region of Interest, innerhalb welcher nach den Load Carriern gesucht wird.Warnung
In SilhouetteMatch gibt es anstelle des Feldes
region_of_interest_id
das Feldregion_of_interest_2d_id
, welches die ID der 2D Region of Interest enthält, innerhalb welcher nach den Load Carriern gesucht wird.Response:
Die Definition der Response mit jeweiligen Datentypen ist:
{ "name": "detect_filling_level", "response": { "load_carriers": [ { "cells_filling_levels": [ { "cell_position": { "x": "float64", "y": "float64", "z": "float64" }, "cell_size": { "x": "float64", "y": "float64" }, "coverage": "float64", "level_free_in_meters": { "max": "float64", "mean": "float64", "min": "float64" }, "level_in_percent": { "max": "float64", "mean": "float64", "min": "float64" } } ], "filling_level_cell_count": { "x": "uint32", "y": "uint32" }, "id": "string", "inner_dimensions": { "x": "float64", "y": "float64", "z": "float64" }, "outer_dimensions": { "x": "float64", "y": "float64", "z": "float64" }, "overall_filling_level": { "cell_position": { "x": "float64", "y": "float64", "z": "float64" }, "cell_size": { "x": "float64", "y": "float64" }, "coverage": "float64", "level_free_in_meters": { "max": "float64", "mean": "float64", "min": "float64" }, "level_in_percent": { "max": "float64", "mean": "float64", "min": "float64" } }, "overfilled": "bool", "pose": { "orientation": { "w": "float64", "x": "float64", "y": "float64", "z": "float64" }, "position": { "x": "float64", "y": "float64", "z": "float64" } }, "pose_frame": "string", "rim_thickness": { "x": "float64", "y": "float64" } } ], "return_code": { "message": "string", "value": "int16" }, "timestamp": { "nsec": "int32", "sec": "int32" } } }
load_carriers
: Liste an erkannten Load Carriern und deren Füllstand.
timestamp
: Zeitstempel des Bildes, auf dem die Erkennung durchgeführt wurde.
return_code
: enthält mögliche Warnungen oder Fehlercodes und Nachrichten.