Objekterkennung mit LiDAR-Sensor: Unterschied zwischen den Versionen
Zeile 8: | Zeile 8: | ||
Der Begriff LiDAR setz sich aus „Light Detection And Ranging“ zusammen. Dabei nutzt der LiDAR einen rotierenden Laser, über den die Entfernungen gemessen werden. | Der Begriff LiDAR setz sich aus „Light Detection And Ranging“ zusammen. Dabei nutzt der LiDAR einen rotierenden Laser, über den die Entfernungen gemessen werden. | ||
In Abbildung 1 ist eine beispielhafte Visualisierung des Sensorbilds zu erkennen. | In Abbildung 1 ist eine beispielhafte Visualisierung des Sensorbilds zu erkennen. | ||
[[Datei:UrgBenriVisualisierungssoftware.png| | [[Datei:UrgBenriVisualisierungssoftware.png|600px|thumb|left|Abbildung 1: UrgBenri Visualisierungssoftware]] | ||
Gut zu erkennen sind hier die jeweiligen Distanzen, die bei einem Umlauf gemessen wurden. Der hier verwendete Sensor hat einen Messbereich von 240°. In diesem Umkreis kann so die Lage von etwaigen Hindernissen bestimmt werden. | Gut zu erkennen sind hier die jeweiligen Distanzen, die bei einem Umlauf gemessen wurden. Der hier verwendete Sensor hat einen Messbereich von 240°. In diesem Umkreis kann so die Lage von etwaigen Hindernissen bestimmt werden. | ||
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> | |||
==Laden der Messdaten== | ==Laden der Messdaten== | ||
Zeile 40: | Zeile 40: | ||
%% MALTAB initisalisieren | %% MALTAB initisalisieren | ||
clear all; close all; clc | clear all; close all; clc | ||
%% Dateipfad temporär hinzufügen | %% Dateipfad temporär hinzufügen | ||
dateiPfad = ['C:\Users\svenp\Documents\SVN\HSHL\MTR_SDE_Praktikum\trunk\'... | dateiPfad = ['C:\Users\svenp\Documents\SVN\HSHL\MTR_SDE_Praktikum\trunk\'... | ||
'Workshops\10 - Objekterkennung mit LiDAR - Schneider\Daten']; | 'Workshops\10 - Objekterkennung mit LiDAR - Schneider\Daten']; | ||
addpath(dateiPfad); | addpath(dateiPfad); | ||
dateiName = 'Lidar.ubh'; % Eingangsdatei | dateiName = 'Lidar.ubh'; % Eingangsdatei | ||
nSamples = 682; % Anzahl der Messwerte | nSamples = 682; % Anzahl der Messwerte | ||
%% Datei öffnen | %% Datei öffnen | ||
fileID= fopen(dateiName); | fileID= fopen(dateiName); | ||
Zeile 54: | Zeile 51: | ||
error("Datei ist nicht vorhanden"); | error("Datei ist nicht vorhanden"); | ||
end | end | ||
daten={}; | daten={}; | ||
%% Winkel berechnen | %% Winkel berechnen | ||
Aufloesung = (120--120)/(nSamples-1);% Winkelauflösung | Aufloesung = (120--120)/(nSamples-1);% Winkelauflösung | ||
aWinkel= -120:Aufloesung:120 ; % [-a:Aufloesung:a]; | aWinkel= -120:Aufloesung:120 ; % [-a:Aufloesung:a]; | ||
%% Einmalige Winkelberechnung | %% Einmalige Winkelberechnung | ||
acosdw = cosd(aWinkel); % Array mit nSamples Einträgen | acosdw = cosd(aWinkel); % Array mit nSamples Einträgen | ||
asindw = sind(aWinkel); % Array mit nSamples Einträgen | asindw = sind(aWinkel); % Array mit nSamples Einträgen | ||
%% Schleife solange die Datei nicht abgearbeitet wurde | %% Schleife solange die Datei nicht abgearbeitet wurde | ||
% Zeile aus Datei lesen | % Zeile aus Datei lesen | ||
Zeile 74: | Zeile 67: | ||
timestamp = cellfun(@str2num,timestamp); | timestamp = cellfun(@str2num,timestamp); | ||
Zeit = (timestamp(1,:)-timestamp(1,1))./1000; %[s] | Zeit = (timestamp(1,:)-timestamp(1,1))./1000; %[s] | ||
%Log Time | %Log Time | ||
logTime = daten(34:6:end); | logTime = daten(34:6:end); | ||
%%Schrägentfernungen | %%Schrägentfernungen | ||
range = daten(36:6:end); | range = daten(36:6:end); | ||
range= str2num(char(range)); | range= str2num(char(range)); | ||
RangeScan= reshape(range,[682,336])'; | RangeScan= reshape(range,[682,336])'; | ||
% KOS-Trafo Polar- zu kartesische Koordinaten | % KOS-Trafo Polar- zu kartesische Koordinaten | ||
xMesswerte=asindw.*RangeScan./1000; | xMesswerte=asindw.*RangeScan./1000; | ||
yMesswerte=acosdw.*RangeScan./1000; | yMesswerte=acosdw.*RangeScan./1000; | ||
%% Daten speichern | %% Daten speichern | ||
stSaveFileName = 'Messdaten.mat'; | stSaveFileName = 'Messdaten.mat'; | ||
Zeile 98: | Zeile 82: | ||
fclose(fileID); | fclose(fileID); | ||
% .uhb Datei schließen | % .uhb Datei schließen | ||
== Darstellung der Messdaten == | == Darstellung der Messdaten == | ||
Über das Skript startDarstellungDerMessdaten.m können die Messdaten dargestellt werden. | |||
Über das Skript startDarstellungDerMessdaten.m können die Messdaten dargestellt werden. In Abbildung 2 sind diese Beispielhaft dargestellt. | |||
[[Datei:DarstellunMessdatenLiDAR.png|600px|thumb|left|Abbildung 2: Darstellung der Messdaten]] | |||
== Zyklisches Laden der Messdaten == | |||
Über die Funktion LadeMessdaten.m werden die Messdaten für ein Frame geladen: | Über die Funktion LadeMessdaten.m werden die Messdaten für ein Frame geladen: | ||
Version vom 12. Juli 2021, 15:55 Uhr
Autor: SDE Team 2021/2022
Betreuer: Ulrich Schneider
Auswertung der Messdaten
LiDAR Daten
Der Begriff LiDAR setz sich aus „Light Detection And Ranging“ zusammen. Dabei nutzt der LiDAR einen rotierenden Laser, über den die Entfernungen gemessen werden. In Abbildung 1 ist eine beispielhafte Visualisierung des Sensorbilds zu erkennen.
Gut zu erkennen sind hier die jeweiligen Distanzen, die bei einem Umlauf gemessen wurden. Der hier verwendete Sensor hat einen Messbereich von 240°. In diesem Umkreis kann so die Lage von etwaigen Hindernissen bestimmt werden.
Laden der Messdaten
Mit dem Code der Datei startUBH2MAT.m werden die Messdaten geladen und in einer .mat-Datei gespeichert.
%**************************************************************** % Modul : startUBH2MAT.m * % * % Datum : 24. Juni 2021 * % * % Funktion : Messdaten der Dateien LiDAR.ubh laden und * % verarbeiten * % * % * % * % * % Implementation : MATLAB R2020a * % * % Author : SDE-Team 20/21 * % * % Bemerkung : - * % * % * % Letzte Änderung : 29. Juni 2021 * % * %****************************************************************
%% MALTAB initisalisieren clear all; close all; clc %% Dateipfad temporär hinzufügen dateiPfad = ['C:\Users\svenp\Documents\SVN\HSHL\MTR_SDE_Praktikum\trunk\'... 'Workshops\10 - Objekterkennung mit LiDAR - Schneider\Daten']; addpath(dateiPfad); dateiName = 'Lidar.ubh'; % Eingangsdatei nSamples = 682; % Anzahl der Messwerte %% Datei öffnen fileID= fopen(dateiName); if fileID == -1 error("Datei ist nicht vorhanden"); end daten={}; %% Winkel berechnen Aufloesung = (120--120)/(nSamples-1);% Winkelauflösung aWinkel= -120:Aufloesung:120 ; % [-a:Aufloesung:a]; %% Einmalige Winkelberechnung acosdw = cosd(aWinkel); % Array mit nSamples Einträgen asindw = sind(aWinkel); % Array mit nSamples Einträgen %% Schleife solange die Datei nicht abgearbeitet wurde % Zeile aus Datei lesen while ~feof(fileID) daten=[daten {fgetl(fileID)}]; end % Zeitstempel in s auslesen timestamp = daten(32:6:end); %[ms] timestamp = cellfun(@str2num,timestamp); Zeit = (timestamp(1,:)-timestamp(1,1))./1000; %[s] %Log Time logTime = daten(34:6:end); %%Schrägentfernungen range = daten(36:6:end); range= str2num(char(range)); RangeScan= reshape(range,[682,336])'; % KOS-Trafo Polar- zu kartesische Koordinaten xMesswerte=asindw.*RangeScan./1000; yMesswerte=acosdw.*RangeScan./1000; %% Daten speichern stSaveFileName = 'Messdaten.mat'; save(stSaveFileName, "Zeit","RangeScan","xMesswerte","yMesswerte"); disp([stSaveFileName,' wurde gespeichert...']) fclose(fileID); % .uhb Datei schließen
Darstellung der Messdaten
Über das Skript startDarstellungDerMessdaten.m können die Messdaten dargestellt werden. In Abbildung 2 sind diese Beispielhaft dargestellt.
Zyklisches Laden der Messdaten
Über die Funktion LadeMessdaten.m werden die Messdaten für ein Frame geladen:
function [z,dt,aRangeScan] = LadeMessdaten(i) % LADEMESSDATEIN läd die Messdaten für ein Frame Messwerte = load("Messdaten.mat"); dt = Messwerte.Zeit(i); z = [Messwerte.xMesswerte(i,:); Messwerte.yMesswerte(i,:)]; aRangeScan = Messwerte.RangeScan; end
Mit dem Skript testeLadeMessdaten.m lässt sich die Funktion testen:
%% MALTAB initisalisieren clear all; close all; clc %% Figure vorbereiten % ROI festlegen xROI = [-5; 5]; yROI = [0; 5]; fRange = 5.5; % m figure('units','normalized','outerposition',[0 0 1 1]); h = plot(0,0,'b.'); %hold on set(gca,'XDir','reverse'); line([-fRange fRange], [0 0]) line([0 0], [-fRange fRange]) xlabel('y in m'); ylabel('x in m'); ylim manual xlim manual hAxis = gca; hAxis.XLimMode = 'manual'; hAxis.YLimMode = 'manual'; xlim(xROI) ylim(yROI) %% Messdaten darstellen nStart = 1; % Startframe; nEnde = 336; % Anzahl der Frames for nFrame=nStart:nEnde % Zyklusschleife über alle Messzyklen %% Messwerte [z, dt, aRangeScan] = LadeMessdaten(nFrame); X = z(1,:); Y = z(2,:); set(h, "XData",X ); set(h, "YData", Y); refreshdata title(["Frame: ",num2str(nFrame)]); pause(0.01); end
Spezifikationsübersicht des URG-04LX
Name des Produkts | Laser Entfernungsmesser |
---|---|
Lichtquelle | Halbleiter Laserdiode (Wellenlänge 785 nm) |
Versorgungsspannung | 5VDC |
Maximale Reichweite | 0,002 m bis 5,6 m |
Messbereich | 0,006 m bis 4 m |
Messauflösung | 0,001 m |
Genauigkeit (20mm - 1000mm) | ± 0,03 m |
Genauigkeit (1000mm - 4000mm) | ± 3 % |
Horizontaler Scanwinkel | 240° |
Winkelauflösung | 0,36° |
Anzahl Scanschritte | 683 |
Scangeschwindigkeit | 100 ms/scan |
Schnittstelle | RS-232 (seriell) |
Bewertung der Messwerte
Abstand der Messwerte
Segmentierung
Als weitere Aufgabe, die typisch für die Auswertung von LiDAR Messdaten ist, ist die Segmentierung. Dabei werden unterschiedliche Algorithmen verwendet. Wir haben uns im Praktikum mit dem sogenannten Succesive Edge Following beschäftigt.
Dabei konnten wir auf eine fertige Funktion zurückgreifen, die aus den RangeScan Messwerten Segmentierungen bildet und diese in einem Struct mit vielen weiteren Daten ablegt.
Das Struct, das der SuccesiveEdgeFollowing Algorithmus zurückgibt besteht aus der Objekt ID, sowie den linken, den nächsten und den rechten Punkt des Segments. Zusätzlich werden diese Punkt in Polar- und Kartesischen Koordinaten angegeben.
Mithilfe des im Folgenden drárgestellten Code, konnte das Objekt aus der Funktion gelesen werden und es werden die 3 Puknt aus der Funktion miteinander verbunden. Dies dient im wesentlichen zur Datenreduktion, da dann anstatt zahlreicher Punkt des LiDARs nur noch 3 Punkt pro Segent ausgewertet werden müssen.
segment=SucessiveEdgeFollowing(RangeScan(1,:)); plot(xMesswerte(1,:), yMesswerte(1,:),'r.'); hold on for i=1: length(segment) x=[segment(i).LeftCartesian(1) segment(i).NearbyCartesian(1) segment(i).RightCartesian(1)]; y=[segment(i).LeftCartesian(2) segment(i).NearbyCartesian(2) segment(i).RightCartesian(2)]; plot(y,x, '-'); set(gca, 'XDir', 'reverse'); end