Docker für Roboter

Linux Devices in Docker

Für Roboter benötigt man meist sehr spezielle Umgebungen mit einer Vielzahl von Abhängigkeiten. Diese müssen zudem häufig in ganz bestimmten Versionen vorligen, um zusammen zu funktionieren.

Da macht es Sinn all diese Abhängigkeiten in einem Docker Container zusammenzufassen. Aber Roboter bestehen auch aus etlichen externen Komponenten. Wie spricht man diese jetzt aus dem Docker Container an?

Zuerst mal gar nicht, da die Verbindung zu den 'Devices' des Hostcomputers nicht automatisch verfügbar sind. Dieser Durchgriff auf angeschlossen Hardware muss extra konfiguriert werden. Dazu gibt es mehrere Möglichkeiten.

Weg1: --priviliged

Mit der Option -- priviliged hat der Docker Container vollständigen Root Zugriff auf alle Devices, aber auch auf alles andere.

Ist auf einem Raspberry Pi der nur einer Aufgabe dient vielleicht akzebtabel, auf einem Entwicklungsrechner auf dem viele unterschiedliche Anwendungen laufen, will man das lieber nicht so. Insbesondere wenn man die Container nicht vollständig selbst erzeugt hat.

Diese Option ist also eher was für den Fall das es anders überhaupt nicht funktioniert. Besser zuerst eine der anderen Optionen verwenden.

Weg2: --device

Mit der Oprion --device wird ein bestimmtes Device des Linux Hosts in den Docker Container gemapped.

z.B.: --device /dev/tty/USB0

Problem ist nur, dass ein USB-Device bereits beim Start des Containers angeschlossen sein muss. Wird ein Device wöhrend der Container läuft, getrennt und erneut verbunden, so ist es nicht zwingend wieder der gleicher Devicename. Also ist ein Ardunino an /dev/ttyUSB0 angeschlossen und wird getrennt, dann ist er bein erneuten Verbinden u.U. als /dev/ttyUSB1 vorhanden.

Damit ist der Arduino aber im Container nicht mehr erreichbar. Wiederholt man das Trennen und Wiederverbinden, so kann es sein das wieder /dev/ttyUSB0 verwendet wird, aber sicher ist das nicht.

Hier muss man ausprobieren ob diese Option mit dem Gerät gut funktioniert. Wenn neiin bleibt noch Weg3.

Weg3: Device Verzeichnis und cgroups

Mit dieser Methode ist man deutlich flexibler als mit Weg2. Gleichzeitig kann man mit dieser Methode die Berechtigungen deutlich einschränken. 1. das Deviceverzeichnis mappen -v /dev/tty:/dev/tty 2. Deviceklasse herausfinden = major device mit lsusb uind/oder ls -la /dev/... 3. mit cgroup() Zugriff auf alle minor Devices zulassen, wenn die Minor number sich beim Wiederverbinden ändert. 4. wenn nötig und möglich weiter Einschränken indem mann statt * die entsprechene minor number angibt also z.B.: 13:75

Syntax:

--device-cgroup-rule='c 13:* rmw' c=character device, 13: device major for input devices, * all minor devices rmw=read,make node,write

Man muss mit -v immer ganze Verzeichnisse mappen, es funktioniert nicht für einzelne Devices.

Solche Verzeichnisse könnten sein: - /dev/bus/usb - alle USB Devices - /dev/input - Input Devices (auch alle USB Input Devices aber eben nich nur) - /dev/dri - Zugriff auf die Grafikkarte (braucht iginition im ROS Container) - /dev/v4L - Camera Devices - /dev - hier gibt es alle ttys