OSE Stopplinienerkennung

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen

Autoren: Florian Brinkmann & Suryaa Kalamani Ramamoorthy
Betreuer: Prof. Schneider

→ zurück zum Hauptartikel: OSE Softwareumgebung
→ zurück zum Hauptartikel: OSE - Objekt - und Spurerkennung
→ zurück zum Hauptartikel: Praktikum SDE

Motivation

Abbildung 1: Anforderung an das Verhalten an einer Stopp-Kreuzung

Gemäß der in Abbildung 1 dargestellten REQ10.2340 aus dem Lastenheft soll das autonome Fahrzeug an einer Stopp-Kreuzung anhalten. Dementsprechend muss die Stopplinie mittels Kamera detektiert werden. Dabei gilt es zu unterschieden, ob es sich um eine 40 mm breite Stopplinie oder eine schmalere Linie handelt, an der nicht gehalten werden muss. Zusätzlich enthält das Requirement den Hinweis, dass die Kreuzung rechtwinklig ist, sodass auch die Stopplinie in einem rechten Winkel zur Fahrbahnmarkierung liegt. [1]

Im Wintersemester 2022/23 hat sich das Team OSE (Stopplinienerkennung) damit beschäftigt die Stopplinienerkennung in die aktuelle Software zu implementieren. Dabei wurde zunächst der Lösungsansatz mittels Hough-Transformation von Kevin Hustedt und Moritz Oberg verfolgt. Jedoch wurde hierbei festgestellt, dass die genutzte Hough-Transformation mit der eingesetzten OpenCV 3.0.0-Version zu Speicherzugriffsverletzungen führt. Aus diesem Grund wurde der im folgenden vorgestellte Ansatz verfolgt.

Die Entwicklung der Stopplinienerkennung erfolgt einfachheitshalber mit dem Entwicklungsumgebung MATLAB®. Um trotzdem den Programmcode für das C-Projekt in Visual Studio bereitstellen zu können, soll aus dem MATLAB®-Code mit Hilfe der in MATLAB® integrierten App "MATLAB Coder" automatsiert C++-Code generiert werden. Daher befindet sich der MATLAB®-Code im Softwareordner OSE_Stopplinienerkennung und der generierte Programmcode im Projektverzeichnis des Visual Studio Projekts im Ordner MATLAB_Coder_Stopplinienerkennung. Die weitere Entwicklung am Visual Studio Projekt erfolgte im Branch 2022_10_05_OSE_Stopplinienerkennung. Mit der Revision 8360 wurden alle Änderungen vom Branch auf den Trunk übertragen.

Ansatz

Die Stopplinienerkennung kann in zwei Teile gegliedert werden. Zunächst geht es erst einmal um die Detektion einer Stopplinie auf der Fahrbahn. In einem zweiten Schritt muss dann für eine detektierte Stopplinie der Abstand zwischen dieser Stopplinie und dem Fahrzeug ermittelt werden. Im folgenden werden die Ansätze für die beiden Teilaufgaben vorgestellt.

Stopplinienerkennung

Abbildung 2: Mathematisches Prinzip der Stopplinienerkennung
Abbildung 3: Ablauf der Stopplinienerkennung

Der neue Ansatz basiert prinzipiell auf einer Zählung der weißen Pixel in jeder Bildzeile. Da allerdings in Kurven die Stopplinie nicht in einer einzelnen, sondern in mehreren Bildzeilen dargestellt wird, musste eine Möglichkeit gesucht werden, um auch schräge Stopplinien detektieren zu können. Dieses Problem kann gelöst werden, indem die Ergebnisse der zuvor erfolgten Spurerkennung eingesetzt werden. Aus den Koeffizienten der Fahrbahnmarkierung wird für jede Bildzeile der Richtungsvektor der Fahrbahnmarkierung bestimmt. Da eine Stopplinie senkrecht zur Fahrbahnmarkierung ist, kann der Richtungsvektor der Fahrbahnmarkierung um 90° gedreht werden, um den Richtungsvektor der Stopplinie zu berechnen. Mit Hilfe des Stopplinien-Richtungsvektors wird ein Punkt auf der potentiellen Stopplinie bestimmt (siehe Abbildung 2). Dieser wird wiederum dazu genutzt, um die Koeffizienten einer Geraden zu bestimmen, auf der die potentielle Stopplinie liegt. Ausgehend von einem Punkt auf der Fahrbahnmarkierung werden mit Hilfe der Geradengleichung Koordinaten von einzelnen Pixeln bestimmt, auf denen die potentielle Stopplinie liegt. Anschließend werden die Pixelwerte der bestimmten Koordinaten ausgelesen und bei einem weißen Pixel eine Zählvariable erhöht. Erreicht diese Zählvariable einen Schwellwert, ist eine Stopplinie erkannt worden. Dieses Vorgehen ist auch in dem nebenstehenden PAP (Abbildung 3) dargestellt.

Abstandsberechnung

Neben der Erkennung der Stopplinie ist es für den späteren Einsatz der Software notwendig, auch den Abstand zwischen dem Fahrzeug und der Stopplinie zu bestimmen. Da die Stopplinie in einem ausgeschnittenen ROI der Vogelperspektive gesucht wird, muss die Lage des ROI im Fahrzeugkoordinaten bekannt sein. Die Ergebnisse der Bestimmung der Lage des ROI sind im Abschnitt Transformation im Artikel OSE Softwareumgebung hinterlegt. Wie die nebenstehende Abbildung 4 zeigt, basiert der Ansatz zur Bestimmung des Abstands zur Stopplinie auf zwei Teilen:

Abbildung 4: Abstandberechnung zwischen Stopplinie und Fahrzeug
  1. Der Abstand zwischen Stopplinie und unterem Rand des ROI wird durch Bestimmung der Bogenlänge des Spurpolynoms ermittelt. Die berechnete Bogenlänge in Pixel muss noch in mm umgerechnet werden. Hierzu wird der oben beschriebene Umrechnungsfaktor in Längsrichtung verwendet.
  2. Der Abstand zwischen dem unteren Rand des ROI und Fahrzeug wird als konstant angenommen, sodass hierfür die Lage des ROI im Fahrzeug-KOS eingesetzt wird.

Damit ergibt sich für die Abstandsberechnung folgende Formel:

Die Bogenlänge des Spurpolynoms kann auf 2 Arten berechnet werden:

  1. Das Spurpolynom kann in kleine Abschnitte unterteilt werden, für die dann jeweils die euklidische Distanz berechnet wird [2]:
  2. Mit Hilfe der Integralrechnung kann die Formel aus 1. zu umgestellt werden [2], wobei als Grenzen des Integrals die y-Bildkoordinate der Stopplinie und der untere Rand des ROI eingesetzt werden.

Die Berechnung der Bogenlänge wurde im MATLAB-Code für beide Verfahren implementiert (berechneStopplinienAbstand.m (Revision 8137)). Da das erste Verfahren weniger Rechenzeit in Anspruch nimmt, ist dieses in der Funktion berechneStopplinienAbstand.m umgesetzt worden. Detaillierte Ergebnisse des Vergleichs sind in der Meilensteinpräsentation zu finden.

Umsetzung des Ansatzes mit MATLAB®

In einem ersten Schritt wurde der Ansatz der Stopplinienerkennung in dem MATLAB-Skript stopplinienerkennung.m (Revision 7857) für einige Situationen erfolgreich validiert. Auf Anregung bei der Meilensteinpräsentation soll der Ansatz für die gesamte Strecke validiert werden, bevor der Ansatz endgültig in C-Code umgesetzt wird.

Ab dem Revisionsstand 8088 befinden sich alle notwendigen MATLAB-Dateien für die Stopplinienerkennung im Software-Ordner OSE_Stopplinienerkennung

Zur Validierung sind folgende Vorbereitungsschritte notwendig:

  • Das transformierte Video muss aus Visual Studio heraus abgespeichert werden. Da Probleme mit den openCV-Funktionen cv::imwrite und write auftraten, wurde die Funktion saveImageData (Revision 7967) realisiert, die für jedes Frame alle Pixelwerte in je eine txt-Datei schreibt. Anschließend wurden die txt-Dateien mit dem MATLAB-Skript txt2mat.m (Revision 8088) in mat-Dateien umgewandelt. Diese wurden im Ordner Videoframes (Revision 8088) abgelegt.
  • Damit die Spurerkennung nicht mit MATLAB realisiert werden muss, wurden neben dem transformierten Video auch die zugehörigen Spurparameter in einer csv-Datei gesichert. Die zugehörige Funktion saveSpurparameter wurde mit der Revision 7927 ergänzt. Die spurparameter.csv-Datei (Revision 8088) besteht aus vier Spalten: In der ersten Spalte befindet sich die Nummer des Frames. Die weiteren drei Spalten beinhalten die Koeffizienten des Spurpolynoms (a, b und c).
  • Um die Stopplinienerkennung zu validieren, wurde das Framework testStopplinienerkennung.m erstellt, dass die Videoframes und die Spurparameter einliest und mit diesen Werten dann die Funktion stopplinienerkennung.m aufruft.

Umsetzung der Stopplinienerkennung in Visual Studio

Die Umsetzung der Stopplinienerkennung in C++-Code besteht aus zwei Schritten. Zunächst wird mit Hilfe von MATLAB Coder der gewünschte C++-Code generiert, der dann wiederum im zweiten Schritt in den Code des vorhandenen Visual Studio Projekts eingebunden werden muss. Die beiden Schritte werden nachfolgend dokumentiert.

Code-Generation mit MATLAB Coder

Die Umsetzung der Stopplinienerkennung in Visual Studio wurde mit Hilfe des MATLAB Coders realisiert. Die entsprechende Projektdatei befindet sich im SVN. Zunächst wird der Nutzer durch die GUI von MATLAB Coder geführt. Dabei werden folgende Schritte durchlaufen:

  1. Auswahl des Skriptes/der Funktion, für die Code generiert werden soll: stopplinienerkennung
  2. Definition der Übergabeparameter:
    1. img: double(1113 x 752) Achtung: Sollte die Größe des Bildes im Visual Studio Projekt verändert werden, muss der C-Code mit den aktualisierten Werten neu generiert werden!
    2. a: double(1 x 1)
    3. b: double(1 x 1)
    4. c: double(1 x 1)
  3. Suche nach Laufzeitproblemen (hier kann ein Check der Software durchgeführt werden)
  4. Code-Generation: Mit einem Klick auf "Generate" wird der C++-Code erzeugt, wobei hier noch einige Einstellungen getroffen werden können:
    1. Build type: Source Code
    2. Language: C++
    3. Interface style: Functions
    4. More Settings → Path →
      1. Working folder: Project folder
      2. Build folder: Specified folder
      3. Build folder name: Hier muss je nach lokalem Projektverzeichnis der vollständige lokale Dateipfad zum Ordner ...\OSE_Draufsicht_Spurpolynom_RS232\Bahnspurpolynom_verlinkt\MATLAB_Coder_Stopplinienerkennung (SVN-Link) eingefügt werden
  5. Abschluss: Hier kann das Code-Package als *.zip-Datei heruntergeladen werden, muss es aber nicht!

Anpassung des Visual Studio Projekts

Nachdem nun der C++-Code generiert und bereits im Ordner MATLAB_Coder_Stopplinienerkennung abgelegt wurde, kann nun die Einbindung in das VS-Projekt beginnen.

In einem ersten Schritt müssen die generierten Dateien mit dem Projekt verknüpft werden.

  • Die Header-Dateien können mit Hilfe zusätzlicher Include-Verzeichnisse eingebunden werden. Dies kann in Visual Studio im Projektmappen-Explorer unter OSE_Draufsicht_Spurpolynom_RS232 → Eigenschaften → Konfigurationseigenschaften → VC++-Verzeichnisse → Includeverzeichnisse → bearbeiten erfolgen. Hier muss nun eine neue Zeile mit dem Inhalt $(ProjectDir)MATLAB_Coder_Stopplinienerkennung eingefügt werden. Damit wird der Ordner mit den generierten Dateien inkludiert. $(ProjectDir) ermöglicht dabei, dass der Pfad unabhängig vom lokalen Verzeichnis ist. Wichtig ist allerdings, dass nach $(ProjectDir) kein / eingefügt wird, da dies automatisch ergänzt wird. Der erzeugte Dateipfad kann unten unter "Ausgewerteter Wert" kontrolliert werden.
  • Zwar befinden sich die *.cpp-Dateien auch in diesem Ordner, jedoch werden diese hierdurch nicht inkludiert. Hierzu muss im Projektmappen-Explorer in Visual Studio unter Quelldateien → Hinzufügen → Vorhandenes Element jede einzelne *.cpp-Datei hinzugefügt werden.

Zusätzlich müssen in der main.cpp-Datei einige Anpassungen vorgenommen werden.

  • Wie in dem von MATLAB Coder generiertem Beispiel müssen einige Header-Dateien inkludiert werden.
  • Die von MATLAB generierte Funktion nutzt nicht den Datentyp cv::Mat, sondern ein eindimensionales Array mit 836976 Elementen (). Daher müssen vor der Übergabe des aktuellen Frames die einzelnen Pixel in dem eindimensionalen Array imgSLE abgelegt werden. Die Ablage der einzelnen Pixel erfolgt dabei analog zu dem generierten Beispiel. Da Probleme mit der Größe des Heaps auftraten, wurde das Array dynamisch angelegt. Wichtig ist dabei, dass das Array im Anschluss wieder gelöscht wird.

Testkonzept

Für die OSE Softwareumgebung wurden verschiedene Testfälle sowohl für die Simulation als auch für Tests am Fahrzeug entwickelt. Die beiden Artikel und die verschiedenen Testfälle sind in der unten stehenden Tabelle 1 verlinkt. Bitte die Tabelle aktuell halten.

OSE: Test in der Simulation OSE: Test am Fahrzeug
Tabelle 1: Testfälle für die Stopplinienerkennung

Literatur



→ zurück zum Hauptartikel: OSE Softwareumgebung
→ zurück zum Hauptartikel: OSE - Objekt - und Spurerkennung
→ zurück zum Hauptartikel: Praktikum SDE