Inhaltsverzeichnis:
- Schritt 1: Sammeln Sie Ihre Materialien
- Schritt 2: Laden Sie die Roomba Toolboxes für MATLAB herunter
- Schritt 3: Verbinden Sie sich mit Ihrem Roomba
- Schritt 4: Wählen Sie, wie Sie Ihren Roomba steuern möchten
- Schritt 5: Fahren Sie Ihren Roomba
Video: Verwandeln Sie Ihren Roomba in einen Mars Rover - Gunook
2024 Autor: John Day | [email protected]. Zuletzt bearbeitet: 2024-01-30 07:15
Schritt 1: Sammeln Sie Ihre Materialien
Um dieses Projekt abzuschließen, müssen Sie die folgenden Materialien sammeln:
1 Roomba-Roboter
1 Raspberry Pi-Kit
1 Videokamera
Zugang zu MATLAB
Schritt 2: Laden Sie die Roomba Toolboxes für MATLAB herunter
Führen Sie den folgenden Code aus, um die erforderlichen Toolboxen zu installieren, um dieses Projekt abzuschließen.
Funktion roombaInstall
clc;
% Liste der zu installierenden Dateien
files = {'roomba.m', 'roombaSim.m', 'roombaSimGUI.m', 'roombaSimGUI.fig'};
% Speicherort, von dem aus installiert werden soll
options = weboptions('Zertifikatsdateiname', ''); % sagen ihm, dass es die Zertifikatsanforderungen ignorieren soll
server = 'https://ef.engr.utk.edu/ef230/projects/roomba-f2016/install/';
dlgTitle = 'Roomba-Installation/-Aktualisierung';
% Anzeigezweck und Bestätigung erhalten
Aufforderung = {
'Dieses Programm lädt diese EF 230 Roomba-Dateien herunter:'
''
strjoin(Dateien, ' ')
''
'in diesen Ordner:'
''
CD
''
'Wollen Sie fortfahren? '
};
Signalton;
yn = questdlg(Aufforderung, …
dlgTitel, …
'Ja', 'Nein', 'Ja');
if ~strcmp(yn, 'Ja'), return; Ende
% Liste der vorhandenen Dateien abrufen
vorhandene_Dateien = Dateien (cellfun (@exist, Dateien) > 0);
if ~isempty(vorhandene_Dateien)
% stellen Sie sicher, dass es wirklich in Ordnung ist, sie zu ersetzen
prompt = {'Sie ersetzen diese Datei(en): '
''
strjoin(vorhandene_Dateien, ' ')
''
'OK zu ersetzen?'
};
Signalton;
yn = questdlg(Aufforderung, …
dlgTitel, …
'Ja', 'Nein', 'Ja');
if ~strcmp(yn, 'Ja'), return; Ende
Ende
% laden Sie die Dateien herunter
cnt = 0;
für i=1:Länge(Dateien)
f=Dateien{i};
disp(['Herunterladen' f]);
Versuchen
URL = [Server f];
websave(f, URL, Optionen); % hinzugefügte Optionen, um Sicherheitsfehler zu vermeiden
cnt = cnt + 1;
fangen
disp(['Fehler beim Herunterladen' f]);
dummy = [f '.html'];
if exist(dummy, 'file')==2
löschen (Dummy)
Ende
Ende
Ende
if cnt == Länge (Dateien)
msg = 'Installation erfolgreich';
waitfor(msgbox(msg, dlgTitle));
anders
msg = 'Installationsfehler - siehe Befehlsfenster für Details';
waitfor(errordlg(msg, dlgTitle));
Ende
Ende %roombaInstall
Schritt 3: Verbinden Sie sich mit Ihrem Roomba
Jetzt ist es an der Zeit, sich über WLAN mit Ihrem Roomba zu verbinden. Drücken Sie mit 2 Fingern gleichzeitig die Dock- und Spot-Tasten, um Ihren Roomba einzuschalten oder zurückzusetzen. Führen Sie als Nächstes den Code r=roomba (# Ihres Roomba) im Befehlsfenster von MATLAB aus, um eine Verbindung zu Ihrem Roboter herzustellen. Sobald Sie diesen Befehl ausgeführt haben, sollte Ihr Roomba einsatzbereit sein.
Schritt 4: Wählen Sie, wie Sie Ihren Roomba steuern möchten
Es gibt zwei Möglichkeiten, wie Sie Ihren Roomba steuern können: autonom oder mit einem Smartphone als Controller.
Wenn Sie den Roomba autonom fahren möchten, müssen Sie die drei integrierten Sensoren verwenden: Klippensensoren, Stoßsensoren und Lichtsensoren.
Um ein Smartphone zu verwenden, müssen Sie zuerst Ihr Smartphone mit Ihrem Computer verbinden, indem Sie die folgenden Schritte ausführen.
HINWEIS: Ihr Computer und Ihr Smartphone müssen sich im selben WLAN-Netzwerk befinden, um eine ordnungsgemäße Verbindung herzustellen!
1. Laden Sie die MATLAB-App aus dem App Store auf Ihr Gerät herunter.
2. Geben Sie "connector on" in Ihr Befehlsfenster ein und legen Sie ein Passwort fest, das in beide Geräte eingegeben werden muss.
3. Danach gibt Ihnen MATLAB die IP-Adresse Ihres Computers. Sie müssen die Einstellungsseite in der MATLAB-App auf Ihrem Smartphone aufrufen und einen Computer mit der angegebenen IP-Adresse und dem zuvor eingegebenen Passwort hinzufügen.
4. Geben Sie im Befehlsfenster Ihres Computers den Code m=mobiledev ein und dies sollte Ihr Smartphone als Controller für Ihren Roomba initialisieren.
5. Ihr Computer und Ihr Smartphone sollten jetzt einsatzbereit sein.
Schritt 5: Fahren Sie Ihren Roomba
Da Sie nun über alle notwendigen Werkzeuge zum Erstellen Ihres Mars Rover verfügen, können Sie Ihren eigenen Code erstellen. Sowohl für das autonome Fahren als auch für das Smartphone-gesteuerte Fahren haben wir unten einen Beispielcode angehängt.
Autonomes Fahren
Funktion Explore_modified(r)
%input-Argumente: 1 roomba-Objekt, r
%Ausgabeargumente: keine
%Bezeichnung:
%function verwendet eine unendliche while-Schleife, um autonomes Arbeiten zu ermöglichen
%Erkundung der Umgebung des Bots.
%
%funciton gibt dem Roomba auch Anweisungen, was in
%in den folgenden Situationen: Rad(er) verliert(en) Bodenkontakt, und
%object wird vor oder zu beiden Seiten des Bots erkannt und a
%sudden drop wird vor oder zu beiden Seiten des Bots erkannt.
%
%typische Anweisungen beinhalten Bewegungsbefehle zur Maximierung
%Erkundung oder Vermeidung einer erkannten Gefahr und Befehle zur Kommunikation
%Informationen zu den Entdeckungen der Bots (Bilder), Position (Grafik), %and State (gestrandete Warnung) mit dem Benutzer über Matlab und/oder E-Mail. Mehrere
%sound-Befehle werden zum Vergnügen hinzugefügt.
% E-Mail-Funktionen einrichten
mail = '[email protected]';
Passwort = 'EF230Roomba';
setpref('Internet', 'SMTP_Server', 'smtp.gmail.com');
setpref('Internet', 'E_Mail', Mail);
setpref('Internet', 'SMTP_Benutzername', mail);
setpref('Internet', 'SMTP_Password', Passwort);
props = java.lang. System.getProperties;
props.setProperty('mail.smtp.starttls.enable', 'true');
props.setProperty('mail.smtp.auth', 'true');
props.setProperty('mail.smtp.socketFactory.class', 'javax.net.ssl. SSLSocketFactory');
props.setProperty('mail.smtp.socketFactory.port', '465');
% r=Roomba(19)
r.beep('G2^^, G2^^, G2^^, G2^^, A2^^, A2^^, G1^^, E1^^, C2^^, C2^^, C1^^, C1 ^^, D1^^, C1^^, D2^^, E4^^, G2^^, G2^^, G2^^, G2^^, A2^^, A2^^, G1^^, E1^^, C2^^, C2^^, C2^^, E1^^, E1^^, E1^^, D1^^, C4^^');
v =.1;
reflekt_datum=2700; %set Klippensensoren Referenzwert
lightBumper_datum = 200; %set light Stoßfängersensoren Referenzwert
pos=[0, 0]; %variable für Positionsspeicherung mit Datum initialisiert
Winkel = 0; %eingestellter Referenzwinkel
Netzwinkel=0; % Netto-Winkelverschiebung
i=2; %iterator zum Hinzufügen von Zeilen zur Positionsspeichervariablen
dist = 0;
r.setDriveVelocity(v, v); %start roomba vorwärts
während wahr
Cliff = r.getCliffSensors;
Bump = r.getBumpers;
Licht = r.getLightBumpers;
RandWinkel = Randi([20, 60], 1); %erzeugt 1 zufälligen Winkel zwischen 20 und 60 Grad. Wird verwendet, um zu verhindern, dass der Bot in einer Schleife stecken bleibt
%Was tun, wenn ein oder mehrere Räder den Bodenkontakt verlieren:
% Bewegung stoppen, eine Warn-E-Mail mit Umgebungsbild senden, %und fragen Sie den Benutzer, ob er fortfahren oder auf Hilfe warten soll
if Bump.rightWheelDrop == 1 || Bump.leftWheelDrop == 1
r.stop
dist = r.getDistance;
pos(i, 1)= pos(i-1, 1) + dist * sind(Netzwinkel); %x-Koordinate holen
pos(i, 2)= pos(i-1, 2) + dist * cosd(netangle); % Y-Koordinate abrufen
i=i+1;
r.beep('F#1^^, C1^^, F#1^^, C1^^, F#1^^, C1^^, F#1^^, C1^^, F#1^^, C1^^, F#1^^, C1^^, F#1^^, C1^^, F#1^^, C1^^')
img = r.getImage;
imwrite(img, 'stuck.png');
%--------------------------
imfile='stuck.png';
position=savepos(pos);
%---------------------------
sendmail(mail, 'HILFE!', 'Ich bin auf einer Klippe gestrandet!', {imfile, position})
list = {'Weiter', 'Stop'};
idx = menu('Was soll ich tun?', Liste);
wenn idx == 2
brechen
Ende
%Was ist zu tun, wenn ein Objekt vor dem Bot erkannt wird:
%stop, zurückgehen, Foto machen, Benutzer auf Entdeckung aufmerksam machen
%per E-Mail, um 90 Grad drehen und weiter erkunden
elseif Light.leftCenter > lightBumper_datum || Light.rightCenter > lightBumper_datum || Stoßfront == 1
r.stop;
dist = r.getDistance;
pos(i, 1)= pos(i-1, 1) + dist * sind(Netzwinkel); %x-Koordinate holen
pos(i, 2)= pos(i-1, 2) + dist * cosd(netangle); % Y-Koordinate abrufen
i=i+1;
r.moveDistance(-.125);
dist = r.getDistance;
pos(i, 1)= pos(i-1, 1) + dist * sind(Netzwinkel); %x-Koordinate holen
pos(i, 2)= pos(i-1, 2) + dist * cosd(netangle); % Y-Koordinate abrufen
i=i+1;
r.beep('A1^, A1^, A4^, A2^, G2^, G2^, G4^, Bb2^, Bb2^, Bb3.5^, G1^, A8^')
img = r.getImage;
imwrite(img, 'FrontBump.png')
%--------------------------
imfile='FrontBump.png';
position=savepos(pos);
%---------------------------
sendmail(mail, 'Alert!', 'Ich habe etwas gefunden!', {imfile, position})
Winkel = 90;
Netzwinkel=Netzwinkel+Winkel;
r.turnAngle (Winkel);
r.setDriveVelocity(v, v);
%Was ist zu tun, wenn links vom Bot ein Objekt erkannt wird:
%stopp, zum Objekt drehen, zurückfahren, Foto machen, warnen
%Entdeckungsnutzer per E-Mail, 90 Grad drehen und weiter erkunden
elseif Light.leftFront > lightBumper_datum || Licht.links > LichtBumper_datum || Bump.links == 1
r.stop;
dist = r.getDistance;
pos(i, 1)= pos(i-1, 1) + dist * sind(Netzwinkel); %x-Koordinate holen
pos(i, 2)= pos(i-1, 2) + dist * cosd(netangle); % Y-Koordinate abrufen
i=i+1;
Winkel = 30;
Netzwinkel=Netzwinkel+Winkel;
r.turnAngle (Winkel);
r.moveDistance(-.125);
dist = r.getDistance;
pos(i, 1)= pos(i-1, 1) + dist * sind(Netzwinkel); %x-Koordinate holen
pos(i, 2)= pos(i-1, 2) + dist * cosd(netangle); % Y-Koordinate abrufen
i=i+1;
r. Piep('A4^, A4^, G1^, E1^, C3.5^, C2^^, C1^, C1^, C2^, D2^, D2^, E8^')
img = r.getImage;
imwrite(img, 'LeftBump.png')
%--------------------------
imfile='LeftBump.png';
position=savepos(pos);
%---------------------------
sendmail(mail, 'Alert!', 'Ich habe etwas gefunden!', {imfile, position})
Winkel = -90;
Netzwinkel=Netzwinkel+Winkel;
r.turnAngle (Winkel);
r.setDriveVelocity(v, v);
%Was ist zu tun, wenn rechts vom Bot ein Objekt erkannt wird:
%stopp, zum Objekt drehen, zurückfahren, Foto machen, warnen
%Entdeckungsnutzer per E-Mail, 90 Grad drehen und weiter erkunden
elseif Light.rightFront > lightBumper_datum || Licht.rechts > LichtBumper_datum || Stoß.rechts == 1
r.stop;
dist = r.getDistance;
pos(i, 1)= pos(i-1, 1) + dist * sind(Netzwinkel); %x-Koordinate holen
pos(i, 2)= pos(i-1, 2) + dist * cosd(netangle); % Y-Koordinate abrufen
i=i+1;
Winkel = -30;
Netzwinkel=Netzwinkel+Winkel;
r.turnAngle (Winkel);
r.moveDistance(-.125);
dist = r.getDistance;
pos(i, 1)= pos(i-1, 1) + dist * sind(Netzwinkel); %x-Koordinate holen
pos(i, 2)= pos(i-1, 2) + dist * cosd(netangle); % Y-Koordinate abrufen
i=i+1;
Pause (1,5);
r. Piep('C1^, C1^, C2^, D2^, D2^, C8^')
img = r.getImage;
imwrite(img, 'RightBump.png')
%--------------------------
imfile='RightBump.png';
position=savepos(pos);
%---------------------------
sendmail(mail, 'Alert!', 'Ich habe etwas gefunden!', {imfile, position});
Winkel = 90;
Netzwinkel=Netzwinkel+Winkel;
r.turnAngle (Winkel);
r.setDriveVelocity(v, v);
%Was ist zu tun, wenn links vom Bot eine Klippe erkannt wird:
%stop, rückwärts gehen, rechts abbiegen, weiter erkunden
elseif Cliff.left < reflect_datum || Cliff.leftFront < reflect_datum
r.stop;
dist = r.getDistance;
pos(i, 1)= pos(i-1, 1) + dist * sind(Netzwinkel); %x-Koordinate holen
pos(i, 2)= pos(i-1, 2) + dist * cosd(netangle); % Y-Koordinate abrufen
i=i+1;
r.moveDistance(-.125);
dist = r.getDistance;
pos(i, 1)= pos(i-1, 1) + dist * sind(Netzwinkel); %x-Koordinate holen
pos(i, 2)= pos(i-1, 2) + dist * cosd(netangle); % Y-Koordinate abrufen
i=i+1;
angle=-RandWinkel;
Netzwinkel=Netzwinkel+Winkel;
r.turnAngle (Winkel);
r.setDriveVelocity(v, v);
%Was ist zu tun, wenn rechts vom Bot eine Klippe erkannt wird:
%stop, rückwärts bewegen, links abbiegen, weiter erkunden
elseif Cliff.right < reflect_datum || Cliff.rightFront < reflect_datum
r.stop;
dist = r.getDistance;
pos(i, 1)= dist * sind(Winkel); %x-Koordinate holen
pos(i, 2)= dist * cosd(Winkel); % Y-Koordinate abrufen
i=i+1;
r.moveDistance(-.125);
Winkel = RandWinkel;
Netzwinkel=Netzwinkel+Winkel;
r.turnAngle (Winkel);
r.setDriveVelocity(v, v);
Ende
Ende
Smartphone-Controller
Optionen = {'Autonom', 'Manuelle Steuerung'}
Prompt = menu('Wie möchten Sie den Rover steuern?', Optionen)
m = mobiledev
r = roomba(19)
wenn Aufforderung == 1
Forscher)
anders
während wahr
Pause(.5)
PhoneData=m. Orientierung;
Azi=Telefondaten(1);
Tonhöhe = Telefondaten (2);
Seite=Telefondaten(3);
wenn Seite>130 || Seite<-130 %Wenn das Telefon mit der Vorderseite nach unten gedreht wird, stoppen Sie den Roomba und verlassen Sie die Schleife
r.stop
r.beep('C, C, C, C')
brechen
elseif Seite>25 && Seite<40 %Wenn das Telefon zwischen 25 und 40 Grad seitwärts gedreht wird, biegen Sie um 5 Grad nach links ab
r. Drehwinkel(-5);
elseif Side>40 %wenn das Telefon seit über 40 Grad gedreht wird, biegen Sie nach links um 45 Grad
r. Drehwinkel(-45)
elseif Side-40 %Wenn das Telefon zwischen -25 und -40 Grad seitwärts gedreht wird, drehe 5 Grad nach rechts
r. Drehwinkel(5);
elseif Side<-40 % wenn das Telefon weniger als -40 Grad seitwärts gedreht wird, biege um 45 Grad nach links ab
r. Drehwinkel(45)
Ende
%Wenn das Telefon in der Nähe des Scheitels gehalten wird, nehmen Sie ein Bild auf und zeichnen Sie es
wenn Tonhöhe<-60 && Bild<=9
r.piep
img=r.getImage;
Nebenhandlung(3, 3, Bild)
imshow(img)
Ende
% vorwärts und rückwärts bewegen basierend auf der vorderen und hinteren Ausrichtung
if Pitch>15 && Pitch<35 %if Pitch zwischen 15 und 35 Grad bewegen Sie sich eine kurze Strecke vorwärts
% holen Sie sich leichte Stoßfängerdaten, bevor Sie sich bewegen
litBump=r.getLightBumpers;
wenn litBump.leftFront>500 || litBump.leftCenter>500 || litBump.rightCenter>500 || litBump.rightFront>500 % wenn sich etwas vor dem Roomba befindet und trifft, wenn er sich vorwärts bewegt, machen Sie Geräusche und zeigen Sie eine Meldung an
r.beep('C^^, F#^, C^^, F#^')
sonst %bewegen
r.moveDistance(.03);
%Bumper-Daten nach dem Umzug abrufen
Bump=r.getBumpers;
wenn Bump.right==1 || Stoß.links==1 || Stoßfront==1
r.beep('A, C, E')
r.moveDistance(-.01)
Ende
% Daten des Klippensensors abrufen
Cliff=r.getCliffSensors;
wenn Klippe.links>1500 || Klippe.linksvorne>1500 || Klippe.rechtsvorne>1500 || Cliff.right>1500 % Wenn etwas den Klippensensor auslöst, behandle es als Lava und gehe zurück
r.beep('C^^, C, C^^, C, C^^, C, C^^, C, C^^, C, C^^, C')
r.moveDistance(-.031)
Ende
Ende
elseif Steigung>35 %wenn Steigung größer 35 Grad weiter vorwärts bewegen
% holen Sie sich leichte Stoßfängerdaten, bevor Sie sich bewegen
litBump=r.getLightBumpers;
wenn litBump.leftFront>15 || litBump.leftCenter>15 || litBump.rightCenter>15 || litBump.rightFront>15 % wenn sich etwas vor dem Roomba befindet und trifft, wenn er sich vorwärts bewegt, machen Sie Geräusche und zeigen Sie eine Meldung an
r.beep('C^^, F#^, C^^, F#^')
sonst %bewegen
r.moveDistance(.3)
%Bumper-Daten nach dem Umzug abrufen
Bump=r.getBumpers;
wenn Bump.right==1 || Stoß.links==1 || Bump.front==1 %Wenn du etwas triffst, mache ein Geräusch, zeige eine Nachricht an und gehe zurück
r.beep('A, C, E')
r.moveDistance(-.01)
Ende
% erhalten Klippensensordaten nach dem Bewegen
Cliff=r.getCliffSensors;
wenn Klippe.links>1500 || Klippe.linksvorne>1500 || Klippe.rechtsvorne>1500 || Cliff.right>1500 % Wenn etwas den Klippensensor auslöst, behandle es als Lava und gehe zurück
r.beep('C^^, C, C^^, C, C^^, C, C^^, C, C^^, C, C^^, C')
r.moveDistance(-.31)
Ende
Ende
elseif Pitch-35 %if Pitch zwischen -15 und -35 Grad kurze Distanz zurückbewegen
r.moveDistance(-.03);
% erhalten Klippensensordaten nach dem Bewegen
Cliff=r.getCliffSensors;
wenn Klippe.links>1500 || Klippe.linksvorne>1500 || Klippe.rechtsvorne>1500 || Cliff.right>1500 % Wenn etwas den Klippensensor auslöst, behandle es als Lava und gehe zurück
r.beep('C^^, C, C^^, C, C^^, C, C^^, C, C^^, C, C^^, C')
r.moveDistance(.04)
Ende
elseif Pitch-60 %if Pitch zwischen -35 und -60 Grad bewegen Sie sich länger zurück
r.moveDistance(-.3)
% erhalten Klippensensordaten nach dem Bewegen
Cliff=r.getCliffSensors;
wenn Klippe.links>1500 || Klippe.linksvorne>1500 || Klippe.rechtsvorne>1500 || Cliff.right>1500 % Wenn etwas den Klippensensor auslöst, behandle es als Lava und gehe zurück
r.beep('C^^, C, C^^, C, C^^, C, C^^, C, C^^, C, C^^, C')
r.moveDistance(.31)
Ende
Ende
Ende
Ende
Empfohlen:
So verwandeln Sie Ihren Raspberry Pi in ein Remote Access Gateway – wikiHow
So verwandeln Sie Ihren Raspberry Pi in ein Remote Access Gateway: Hey Leute! Angesichts der jüngsten Ereignisse hat unser Team von remote.it hart daran gearbeitet, Ideen zu sammeln, um die Arbeit aus der Ferne schmerzfrei und zugänglich zu machen. Wir haben das remote.itPi SD Card Image entwickelt, eine SD-Karte, die Sie in eine neue
So erstellen Sie einen Tiefpassfilter für einen Subwoofer mit dem NE5532-IC - DIY (ELECTROINDIA): 4 Schritte
So erstellen Sie einen Tiefpassfilter für einen Subwoofer mit dem NE5532-IC | DIY (ELECTROINDIA): In diesem Projekt zeige ich Ihnen, wie Sie einen Tiefpassfilter für Subwoofer herstellen können. Los geht's
So erhalten Sie Musik von fast jeder (Haha) Website (solange Sie sie hören können, können Sie sie bekommen Okay, wenn sie in Flash eingebettet ist, können Sie es möglicherweise nicht) BEARBEITET!!!!! Hinzugefügte Informationen: 4 Schritte
So erhalten Sie Musik von fast jeder (Haha) Website (solange Sie sie hören können, können Sie sie bekommen … Okay, wenn sie in Flash eingebettet ist, können Sie es möglicherweise nicht) BEARBEITET!!!!! Zusätzliche Informationen: Wenn Sie jemals auf eine Website gehen und ein Lied abspielen, das Sie mögen und es wollen, dann ist hier das anweisbare für Sie, nicht meine Schuld, wenn Sie etwas durcheinander bringen (nur so wird es passieren, wenn Sie ohne Grund anfangen, Dinge zu löschen) ) Ich konnte Musik für
Verwandeln Sie Ihren alten CRT-Computermonitor in ein Aquarium! ! !: 11 Schritte (mit Bildern)
Verwandeln Sie Ihren alten CRT-Computermonitor in ein Aquarium! ! !: Sprechen Sie über einen großartigen Bildschirmschoner! Diesen Build wollte ich schon seit einiger Zeit machen. Fast jedes Mal, wenn ich am Mülltag einen alten CRT-Computermonitor am Straßenrand sehe, denke ich mir … das würde sicher ein cool aussehendes Aquarium abgeben. So
"Verwandeln Sie Ihren toten PC in ein Aquarium": 11 Schritte (mit Bildern)
"Verwandeln Sie Ihren toten PC in ein Aquarium": Was tun mit einem toten veralteten PC??? Verwandeln Sie es in ein Aquarium! Ich hatte einen alten, veralteten, toten PC herumliegen und sah, dass ich ihn für nichts benutzte, und beschloss, ihn in ein Aquarium zu verwandeln. Ich wollte schon lange immer irgendwie