Video4Linux, UDP und Java GUI

In diesem Lab erstellen wir eine Embedded Systems Applikation basierend auf Buildroot um Kamerainput via UDP/IP via Netzwerk an einen Client zu senden.

Ziele

  • Erstellen eines Custom Buildroot Images
  • UVC Treiber für Kamera Laden
  • WiFi / Ethernet einrichten
  • Python Applikation, welche Image via UDP an client sendet.
  • TCP Server für Steuerung des Servos
  • Clientseitige Java Applikation, welche das Kamerabild darstellt und GUI zur Kontrolle des Servos zur Verfügung stellt

Buildroot aufsetzen

Als erstes kompilieren wir ein Buildroot Image und deployen es anschliessend auf die SD-Karte.

Folgende Features werden benötigt.

  • Wireguard Tools
  • Python mit Python pip
  • WiFi + Firmware
  • V4L2 Tools (v4l2-ctl)
    • JPEG Support aktivieren (libjpeg)

Buildroot neu Deployen

Falls Sie wiederholt neue Packages Buildroot hinzufügen, können Sie beim Deployen selektiv nur die neu kompilierten Files auf das RFS kopieren:

# zuerst ins buildroot source dir wechseln

cd output/target
# idealerweise alle files löschen, die konfiguriert wurden
rm etc/network/interfaces
rm etc/wpa_supplicant.conf
tar -cvf ../rootfs.tar -N "1 hour ago" *

Sie können nun die nur eben erstellten Files auf die SD-Karte kopieren:

cd ..
# erstelltes archiv
ls -al rootfs.tar

# sicherstellen, dass die SD gemountet ist

lsblk

# über dem rfs der SD entpacken

sudo tar -xvf rootfs.tar -C /media/${USER}/rootfs

WiFi mit fhnw-public

Für das fhnw-public können Sie folgende /etc/wpa_supplicant.conf Config verwenden:

# /etc/wpa_supplicant

update_config=1
country=CH

network={
    ssid="fhnw-public"
    key_mgmt=NONE
    proto=RSN
    scan_ssid=1
}

Um ins Internet via fhnw-public zu gelangen, können Sie folgendes Python Script auf dem Target verwenden.

#!/usr/bin/python3

from getpass import getpass
from urllib.parse import urlencode
import requests


email = input("Email: ")
password = getpass('Password: ')

payload = {
    'intercepted_url': 'https://google.ch',
    'check': 'on',
    'username': email,
    'password': password
}

res = requests.post(url='https://mpp.ict.fhnw.ch/login',
                    headers={
                        'authority': 'authority: mpp.ict.fhnw.ch',
                        'content-type': 'application/x-www-form-urlencoded',
                        'origin': 'https://mpp.ict.fhnw.ch'
                    },
                    data=urlencode(payload), verify=False)


print(res)

Hierbei loggen Sie sich via username unt passwort über den Webserver ein.

Video4Linux

  • uvc Kameratreiber laden

Studieren Sie v4l2-ctl anhand dieses Tutorials: http://trac.gateworks.com/wiki/linux/v4l2

  • Welche Formate werden von der USB Kamera Unterstützt?

Python Applikation schreiben, welche Bilder ausliest

  • Python pip verwenden um v4l2py zu installieren
    • Studieren Sie die Library und Dokumentation

Python Serial Applikation um Servo zu steuern

  • Python pyserial installieren um den Servo via Terminal zu kontrollieren

USB CDC Treiber laden

Um den Servomotor als USB-Serial Device zu sehen wird der cdc-acm Treiber benötigt. Laden Sie diesen bei Bedarf mit modprobe nach.

Python Applikation erweiter, dass UDP Packets mit MJPEG an Host geschickt werden

Erweitern Sie die Applikation so, dass die gelesenen Frames an einen (als Arguement definierten) Host via UDP sendet.

  • Python socket für UDP studieren.

Java Application

Erstellen Sie ein Java GUI, welches die Frames darstellt und Controls für die Steuerung des Servos enthält.

Java GUI Boilerplate

Sie können als Basis folgende Boilerplate verwenden: https://gitlab.fhnw.ch/oop/gui-boilerplate

Python mit TCP Socket erweitern

Erweitern Sie die Python App mit einem TCP Server Socket, der Control Commands für den Serve erhält.

Java TCP

Erweitern Sie die Java App mit einem TCP Client, welcher beim Starten versucht den Server zu empfangen. Beim Press des entsprechenden Buttons, soll sich der Servo nun auch bewegen.

Wunscherweiterungen

  • UDP Stream mit Keepalive
    • UDP erst beginnnen, wenn ein Client den Stream anfordern möchte
    • ... sobald einmal angefordert gibt es bei UDP keine Möglichkeit zu bemerken, ob sich der Client verabschiedet hat. Ein Keepalive würde hier das Problem lösen.