Boden-Luft-Abwehr

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen
Abbildung 3: Raketenwerfer mit Webcam

Autor: Adam Fankhauser

Betreuer: Prof. Schneider

Einleitung

Dieses Projekt wurde im Kurs Digitale Signal und Bildverarbeitung im Sommersemester 2016 als Bestandeil der Übungen durchgeführt und ist in diesem Artikel dokumentiert. Ebenso wurde zur Präsentation ein Video erstellt.

Aufgabenstellung

Aufgabe in diesem Projekt war die Weiterführung des Projekts Lego Mindstorms Rocket Launcher aus dem Fachpraktikum Elektrotechnik (WS 14/15). Der mechanisch fertiggestellte Rocket Launcher sollte per Webcam ein Objekt, beispielsweise einen roten Ballon, erkennen, sich auf das Objekt ausrichten und eine Rakete gezielt darauf abfeuern. Die Steuerung sollte über Matlab erfolgen.

Vorbereitung

Grundlage der Steuerung war die Vorarbeit der Gruppe, die den Rocket Launcher mechanisch aufgebaut hat. Diese hat ihre Arbeit ausreichend dukumentiert und ein Simulink-Modell hinterlassen, welches die Steuerung über die Tasten des EV3-Moduls ermöglicht. Mit Hinblick auf die Erweiterung des Programms um die Steuerung und Regelung des Rocket Launchers sollte das Simulink Modell nicht weiter genutzt werden, sondern die Funktionen in Matlab Code umgesetzt werden.

Für die Einbindung der Webcam und des Lego EV3-Moduls wurde Matlab mit den Support Packages USB Webcams und LEGO MINDSTORMS ausgerüstet.

Durchführung

Die Durchführung wurde in mehrere Abschnitte unterteilt. Zuerst wurde mit Beispielbildern die Bildverarbeitung entwickelt, dann wurde die Webcam in Matlab eingebunden, danach wurden die Lego Motoren des Raketenwerfers über Matlab angesteuert und eine Regelung entworfen, welche den Raketenwerfer auf das erkannte Objekt ausrichtet um zuletzt eine Schussfunktion zu implementieren.

Bildverarbeitung

Abbildung 2: RGB-Bild mit Histogramm

Um ein rotes Objekt zu erkennen wurde der Ansatz gewählt, nur die rote Matrix aus dem RGB Bild der Webcam zu nehmen, und dort anhand eines Schwellwertes zu entscheiden, welche Pixel zum Objekt gehören. Leider hat der RGB Farbraum keine befriedigenden Ergebnisse erbracht. Auf Abbildung 2 ist deutlich zu erkennen, wie sich im Original das rote Objekt vom blauen Hintergrund abhebt, doch im Grauwertbild mit den Rotwerten und im Histogramm ist zu erkennen, dass die Farbe Rot nicht besonders aus den anderen Farben heraussticht.

Abbildung 3: YCBCR-Bild mit Histogramm

Daher wurde das Bild in einen anderen Farbraum transformiert. Angeboten hat sich hier der YCBCR Farbraum, da in diesem die Farbe Rot deutlicher herauszufiltern ist. Hier ist sowohl im Teil CR (Chroma Rot) des Farbraums als auch im Histogramm zu sehen, dass die Farbe Rot deutlich hervorsticht (Abbildung 3). So konnte ein klarer Schwellwert vom Farbwert 160 festgelegt werden. Voraussetzung für die Funktionalität mit diesem Schwellwert ist natürlich, dass die zu erkennende Farbe rötlich ist, ähnlich wie auf dem Beispielbild, und auch die Beleuchtungsverhältnisse stimmen, mehr dazu im Abschnitt Webcam.

Abbildung 4: Bild mit extrahiertem Objekt

Da in einem Bild mehrere Objekte rot sein können muss natürlich festgelegt werden, welches Objekt herauszufiltern ist. Hierzu wurde das größte Objekt im Bild gesucht und extrahiert (Abbildung 4).

Als letzten Schritt der Bildverarbeitung musste die Position des extrahierten Objektes im Gesamtbild bestimmt werden. Hierzu wurde eine Funktion implementiert, die das bearbeitete Bild mit dem extrahierten Objekt übergeben bekommt. Die Funktion berechnet nun den geometrischen Schwerpunkt des Objektes. Ausserdem berechnet die Funktion weitere Merkmale, wie Umfang und Fläche des Objektes, die später als Kriterien zum Abschuss der Raketen genutzt werden können.

Webcam

Die Webcam wurde in Matlab mithilfe des Support Package eingebunden und getestet. Hierbei wurde festgestellt, dass die Grundeinstellungen der Webcam mit automatischem Weißabgleich etc. ausreichend für die Anwendung bei unterschiedlichen und wechselnden Lichtverhältnissen sind. Daher wurden hier keine weiteren Einstellungen vorgenommen. Des Weiteren wurde festgestellt, dass der Algorithmus der Bildverarbeitung anfällig für dunkle Lichtsituationen ist. Bei zu geringer Beleuchtung sticht die Farbe Rot nicht mehr ausreichend hervor und wird unzureichend erkannt. Auszugleichen ist dies mit der Anpassung des Schwellwertes, ab welchem Wert ein Objekt als "rot genug" erkannt wird. Ein Herabsetzen des Schwellwertes hat aber zur Folge, dass zu viele Objekte als "rot" erkannt werden. Daher wurde entschieden, den Schwellwert an eine ausreichende Beleuchtungssituation anzupassen und diese vorauszusetzen.

Regelung

Um den Raketenwerfer nun auf den Schwerpunkt des erkannten Objektes auszurichten, wurde entschieden, dass die Webcam oberhalb des Raktenwerfers anzubringen sei, sodass diese alle Bewegungen mitfährt und ständig in Schussrichtung ausgerichtet ist. Provisorisch wurde diese Fixierung durch Klebeband vorgenommen. Mit dieser Kameraposition konnte nun die Ansteuerung der Motoren über einen einfach P-Regler vorgenommen werden. Der Sollwert für die Ausrichtung ist natürlich der Bildmittelpunkt, der Istwert der Ausrichtung ist der Schwerpunkt des erkannten Objektes. Die resultierenden Regelabweichungen in horizontale und vertikale Richtung, multiplizeirt mit dem Kp-Wert wurde den Motoren als Geschwindigkeit übergeben. So konnte der Raketenwerfer sich bei laufendem Programm auf den Mittelpunkt des Objektes ausrichten.

Schussfunktion

Als letztes wurde nun noch eine Schussfunktion implementiert. Durch die Vorarbeit der letzten Gruppe ist es möglich, die Schussfunktion über einen Motorausgang des EV3-Moduls anzusteuern. Die Kriterien für den Abschuss der Raketen waren zum einen, ob ein Abschuss gewünscht ist. Dies wurde umgesetzt über eine Abfrage der "Down" Taste des EV3-Moduls. Bei einmaligem Drücken der Taste ist der Raketenwerfer in Schussbereitschaft versetzt, bei nochmaligem drücken der Taste wird die Schussbereitschaft zurückgesetzt. Ist der Raketenverfer in Schussbereitschaft versetzt, sind weitere Voraussetzungen für einen Abschuss zum einen die Größe des erkannten Objektes und die momentane Regelabweichung zum dessen Schwerpunkt. Dies bewirkt, dass ein Abschuss nur dann ausgelöst wird, wenn das Objekt groß genug zum Treffen, bzw. nah genug am Raketenwerfer ist und dieser auch auf das Objekt ausgerichtet ist.

Quellcode

%____________________________________________________________%
%
%
%  Programmbeschreibung: Steuerung eines Raketenwerfers zur Boden-Luft
%  Abwehr mithilfe von einem Lego EV3-Modul und einer Webcam
%
%  Autor: Adam Fankhauser
%  Datum: 18.06.2016
%
%  Hochschule Hamm Lippstadt
%  Studiengang Mechatronik
%  Sommersemester 2016
%  Digitale Signal- und Bildverarbeitung 
%
%____________________________________________________________%

%%
clear all
close all

%% Identifying Available Webcams
camList = webcamlist;
% Connect to the webcam.
cam = webcam(1);

%%  Lego EV3-Modul initialisieren
mylego = legoev3('usb');                           % Set up MATLAB and EV3 communication
clearLCD(mylego);
writeStatusLight(mylego,'green')

% Motoren initialisueren
mymotorAbschuss = motor(mylego, 'B');              % Set up motor
mymotorxy = motor(mylego, 'C');
mymotorz = motor(mylego, 'D');

Kp = 0.1; % Kp-Wert zur Regelung der Motoren

%% Variablen
MinFlaeche = 3000;
AbschussSpeed = 100;
Schussbereitschaft = 0;
Button = 1;
Wechselcounter = 0;

%%
while(1)
    %% Bildverarbeitung
    OrgImage = snapshot(cam);
    [height, width, kernel] = size(OrgImage);
    
    %Transformation in YCBCR Farbraum
    imageYCBCR=rgb2ycbcr(OrgImage);
    imageCR=imageYCBCR(:,:,3);   % Chroma Rot
    imageCR(imageCR<160)=0;   % alles unter 240 wird zu schwarz
    
    %Bild Binarisieren und kleine Löcher füllen
    BinaryImage = im2bw(imageCR);
    BinaryImageHoles = imfill(BinaryImage, 'holes');
    
    %Größtes Objekt extrahieren
    [labeledImage, numObjects] = bwlabel(BinaryImageHoles);
    stats = regionprops(labeledImage,'Area');
    allAreas = [stats.Area];
    [~, indexOfLargest] = max(allAreas);
    largestObject = ismember(labeledImage, indexOfLargest)>0;
    [height, width] = size(largestObject);


    %% Algorithmen für Merkmalsextraktion
    %Berechnen von Umfang, Fläche und Schwerpunkt in Pixeleinheiten
    [Umfang, Flaeche, Schwerpunkt, EntfernungPunkte] = Merkmalsberechnung_3(largestObject);

    %Schwerpunkt relativ zum Bildmittelpunkt setzen
    if (Schwerpunkt ~= 0)
        Schwerpunkt = [Schwerpunkt(1)-(width/2) Schwerpunkt(2)-(height/2)];
    else
        Schwerpunkt = [0 0];
    end
    
    %% Schussbereitschaft einstellen
    if(Schussbereitschaft == 0 && readButton(mylego,'down') == 1 && Button == 0)
        Schussbereitschaft = 1;
        Button = 1;
        writeStatusLight(mylego,'red');
    end
    if(Schussbereitschaft == 1 && readButton(mylego,'down') == 1 && Button == 0)
        Schussbereitschaft = 0;
        Button = 1;
        writeStatusLight(mylego,'green');
    end
    if(readButton(mylego,'down') == 0 && Button == 1)
        Button = 0;
    end
    
    %% Abschuss?
    if(Schussbereitschaft == 1 && Schwerpunkt(1) < 20 && Schwerpunkt(2) < 40 && Flaeche > MinFlaeche)
        if(Wechselcounter == 1)     %die Ansteuerung des Abschussmechanismus funktioniert nicht 
           AbschussSpeed = 100;     %wenn konstant 100% Motorengeschwindigkeeit übersendet wird
           Wechselcounter = 0;
        else
           AbschussSpeed = 99;
           Wechselcounter = 1;
        end
    else
        AbschussSpeed = 0;
    end
    
    %% Motoren ansprechen
    mymotorxy.Speed = Kp*Schwerpunkt(1);
    start(mymotorxy)
    mymotorz.Speed = Kp*Schwerpunkt(2);
    start(mymotorz)
    mymotorAbschuss.Speed = AbschussSpeed;
    start(mymotorAbschuss)
    
    %% Plotten
%     figure(1);
%     subplot(2,2,1);
%     imshow(OrgImage);
%     title('Originales Bild');
% 
%     subplot(2,2,2);
%     imshow(BinaryImage);
%     title('Grauwert Bild');
% 
%     subplot(2,2,3);
%     imshow(BinaryImageHoles);
%     title('Grauwert Bild ohne Löcher');
% 
%     subplot(2,2,4);
%     imshow(largestObject);
%     title('Größtes Objekt');

  %%  Programmmabbruch durch ESC Taste
  val = double(get(figure(1),'CurrentCharacter'));
  if(val == 27)
      break;
  end
end
%%Motoren stoppen
stop(mymotorAbschuss);                             % Stop motor 
stop(mymotorxy);
stop(mymotorz);
writeStatusLight(mylego,'green');

%% Clean up
% Once the connection is no longer needed, clear the associated variable.
% clear all
% close all


Ergebnis und Ausblick

Das Ergbnis dieses Projektes ist ein funktionierender Raketenwerfer, der die "Boden-Luft-Abwehr" beherrscht. Er ist in der Lage, sich ein in seinem Sichtfeld befindliches, rotes Objekt auszuwählen, sich auf dieses auszurichten und auf Wunsch (Tastendruck) all seine Munition drauf abzufeuern.


Natürlich gibt es noch eine ganze Menge Dinge, die zu optimieren sind:

Zum Einen ist durch die Bildverarbeitung das Matlab Programm recht langsam, was bewirkt, dass der Raketenwerfer immer ein wenig hinter einem sich bewegenden Objekt "hinterher hinkt". Um sich schnell bewegende Objekte sicher treffen zu können müsste die Durchlaufzeit der Algotithmen optimiert werden.

Ausserdem wäre es geraten, den P-Regler durch einen PI- oder einen PID-Regler zu ersetzen, da der P-Regler bekanntermaßen eine bleibende Regelabweichung hat und es für die Zielvorrichtung nicht immer möglich ist, sich exakt auf den Schwerpunkt des Objektes auszurichten. Andererseits könnte die Regelung der Motoren auch über die Motorposition geschehen. Hierdurch könnte eine genauere Ausrichtung erreicht werden.

Um den die Hardware des Raketenwerfers zu schützen sollte ebenfalls ein Überdrehungsschutz implementiert werden. So kann verhindert werden, dass die Motorverabelung und die USB-Kabel zum PC nicht verdreht werden und Schaden anrichten können.

Siehe auch

https://svn.hshl.de/svn/GET_Fachpraktikum_MTR/trunk/Projekte/33_Rocket_Launcher/

Weblinks

http://de.mathworks.com/help/supportpkg/usbwebcams/index.html?s_cid=doc_ftr

http://de.mathworks.com/help/supportpkg/legomindstormsev3io/index.html?s_cid=doc_ftr

https://www.youtube.com/watch?v=s5FSHQblAaE





→ zurück zum Hauptartikel: DSB SoSe2016