Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

projektesose21:insektpublic:start

Einführung


Ziel dieses Projekts war es, das Verhalten eines Insekts in einem Roboter zu implementieren, sodass er selbstständig auf äußere Reize entsprechend reagieren kann. Inspiriert haben wir uns von dem bereits bestehenden Projekt der Firma Plum Geek (http://www.plumgeek.com/ringo.html). Die Firma baute Ringo mit dem Ziel, die Programmierung von Mikrokontrollern Anfängern näher zu bringen.
Der Roboter kann sich in der Umgebung selbständig zurechtfinden und auf äußere Reize entsprechend des Verhaltensmusters eines Insektes reagieren. Dem sehr hellen Licht einer Lichtquelle folgt der Insektroboter und markierte Linien auf dem Tisch fährt der Insektroboter ab. Zusätzlich weicht er den Kanten und Objekten nicht nur aus, sondern zeigt eine weitere Reaktion in Form von Tönen.
Da sich einige Funktionen des Roboters gegenseitig stören wurde dieser in zwei Modi eingeteilt: dem Tischmodus und Bodenmodus. Eine Ausführung dazu findet sich im nächsten Kapitel unter dem Punkt Aufgaben.
Der Fokus des ganzen Projektes liegt hierbei darauf, das Insekt möglichst klein, schnell und agil zu bauen, was im Großen und Ganzen gut gelungen ist.

Umsetzung

Baugruppen:

Entfernungssenoren
- 3x Infrarotsensoren
- 2x Ultraschallsensoren
Lichtsensoren
- 3x Phototransistoren
- 2x Farbsensoren
Sensoren zur Orientierung
- 1x Gyroskop

Abb.01: Frontaufnahme

Abb.02: Foto von der Rückseite

Aufgaben:

Um Kanten und Objekten ausweichen zu können, werden Entfernungssensoren genutzt. Dabei wurden Ultraschallsensoren zur Kantenerkennung und Infrarotsensoren zur Objekterkennung genutzt. Gründe für diese Wahl von Sensoren werden im nächsten Kapitel besprochen. Um die Position einer Lichtquelle zu erfassen und ihr zu folgen wurden konventionelle Phototransistoren eingebaut. Dagegen werden zum Erkennen und Folgen einer Linie Farbsensoren genutzt. Für die Tonreaktion wird ein einfacher Piezolautsprecher verwendet.

Nach Implementation aller Funktionen war zu beobachten, dass diese sich gegenseitig beeinträchtigen. Folgt der Insektroboter beispielsweise gerade einer Linie und erkennt einen hellen Lichtfleck auf dem Tisch, dreht dieser sich von der Linie weg und zum Lichtfleck hin. Das Resultat ist ein unsauberes und unvollständiges Abfahren der Linie. Aus diesem Grund haben wir uns entschieden, die Funktionen des Roboter in zwei Modi einzuteilen, dem Tischmodus und Bodenmodus. Für den Tischmodus werden die Kantenerkennung und Linienerkennung aktiviert und für den Bodenmodus die Objekt- und Lichterkennung. Ein Wechsel zwischen den Modi erfolgt über einen am digitalen Pin 1 angeschlossenen Schalter.


Fortbewegung

Die Fortbewegung des Roboters haben wir über zwei Gleichstrommotoren mit befestigten Rädern realisiert. Da die Drehung dieser, im Gegensatz zu Steppermotoren nicht präzise über den Arduino steuerbar ist und wir aus Größengründen auf einen Motortreiber verzichtet haben, wird zusätzlich eine Schaltung zur Motoransteuerung benötigt. Entscheidend ist dabei zum einen die Regelung der Drehzahl und damit der Geschwindigkeit des Roboters. Zum anderen ist es für Drehungen des Roboters wichtig, dass die Drehrichtung beider Motoren jeweils unabhängig voneinander umgeschaltet werden kann.

Steuerung der Drehzahl

Die Drehzahl des Motors ist von der anliegenden Spannung abhängig, welche sich mit Hilfe von Pulsweitenmodulation(pwm) und einem Transistor gut über den Arduino regeln lässt. Dafür muss der Transistor so in den Stromkreis des Motors eingebaut werden, dass die Spannungsversorgung unterbrochen wird, wenn der Transistor sperrt. Die Basis des Transistors muss an einen pwm-fähigen Pin des Arduino angeschlossen werden (beim Nano digitale Pins 3, 5, 6, 9, 10 und 11). Mit analogWrite(pin, value) kann auf den Pin eine pwm geschaltet werden. Dabei wird der Pin in einer bestimmten Frequenz abwechselnd auf HIGH und LOW geschaltet, sodass die Spannungsversorgung in kurzer Zeit regelmäßig unterbrochen wird. Dadurch, dass die Spannung somit nur einen Teil der Zeit anliegt, entspricht sie im Durchschnitt auch nur einem Teil der Spannung der eigentlichen Spannungsversorgung. Durch das zeitliche Verhältnis der HIGH- und LOW-Phasen, welches durch den value-Parameter in analogWrite(pin, value) bestimmt werden kann, lässt sich die Spannung beliebig regeln und in unserem Fall damit die Drehzahl der Motoren.

//beide Motoren auf maximaler Drehzahl
   analogWrite(motor1, 255);
   analogWrite(motor2, 255);
Steuerung der Drehrichtung

Um die Drehrichtung eines Motors steuern zu können, muss die Polung über den Arduino gewechselt werden können. Dies haben wir mit einer H-Brücke realisiert:

Abb.03: Schaltplan H-Brücke

Die Basis des auf dem Schaltplan ganz rechten Transistors wird hierbei an einen pwm-fähigen Pin des Arduinos angeschlossen, über den die Drehzahl des Motors gesteuert werden kann.
Die Basis des ganz linken Transistors wird an einen normalen digitalen Pin angeschlossen. Hierüber kann die Drehrichtung bestimmt werden, da je nachdem ob der Transistor sperrt oder nicht, die Basen der Transistoren im inneren der Schaltung mit ground oder 12V einer externen Spannungsquelle verbunden werden. Durch unterschiedliches Sperrverhalten von npn- und pnp-Transistoren wird der Stromkreis über den Motor jeweils in eine andere Richtung geschlossen. Somit dreht sich der Motor in die eine Richtung, wenn der Pin zur Richtungssteuerung auf HIGH ist und in die entgegengesetzte Richtung, wenn dieser auf LOW ist. Zu beachten ist dabei, dass wenn der Richtung-Pin auf HIGH ist, der Wert für die pwm invertiert werden muss. Das heißt 0 bedeutet dann maximale Drehzahl und 255 minimale Drehzahl.

Pro Motor haben wir eine separate H-Brücke verwendet, um beide unabhängig voneinander ansteuern zu können.

Präzisierung des Drehwinkels

Ein weiteres Problem, welches wir mit den Gleichstrommotoren hatten ist, dass man sie nicht wie Steppermotoren um ein definiertes Stück drehen lassen kann, was präzise Drehungen des Roboters erschwert. Gelöst haben wir dieses Problem indem wir die Ausrichtung des Roboters mit Hilfe eines Gyroskops überprüfen. Dafür haben wir einen fertigen Code verwendet, von dem wir uns den aktuellen Drehwinkel um die z-Achse des Roboters als Variable zurückgeben lassen. Die absoluten Werte, die das Gyroskop ausgibt kann man dabei allerdings nicht wirklich verwenden, da es nur die Winkeländerungen aufakkumuliert, wobei nach kurzer Zeit ein wachsender Fehler entsteht. Aus diesem Grund lassen wir zu Beginn jeder Drehung den aktuellen Winkel als Startwinkel auslesen und lassen den Roboter in einer while-Schleife solange drehen bis die Differenz des aktuelle Winkels zum Startwinkel dem gewünschten Drehwinkel entspricht. Dadurch spielt der Drift des Gyroskops keine Rolle mehr.

void rechtsDrehen(int drehwinkel) 
{
  int richtungVorher = gyroAngle(); //Auslesen des Startwinkels
  digitalWrite(richtung1, LOW);     //Motoren werden auf entgegengesetzte Drehrichtungen gestellt
  digitalWrite(richtung2, HIGH);
 
  while ( gyroAngle() <= richtungVorher + drehwinkel) 
  {
    analogWrite(motor1, pwm1);
    analogWrite(motor2, 255 - pwm1);  //Invertierung der pwm, damit beide Motoren gleich schnell drehen
  }
  stoppen();
}

Abb.04: Rechtsdrehung des Roboters um 90° durch Winkeldifferenz


Kantenerkennung

Zur Kantenerkennung haben wir zwei Ultraschallsensoren genutzt, welche den Abstand des Roboters zum Boden messen. Die Sensoren selbst befinden sich ca. 2 cm über der Tischfläche. Nach der Messung wird dann zwischen zwei Fällen unterschieden. Misst der linke Sensor einen Abstand zum Boden, der größer als 6 cm ist, dreht sich der Roboter von der Kante um 90° weg also nach rechts. Misst der rechte Sensor einen Abstand größer 6 cm, dreht der Roboter sich um 90° nach links. Da die Ultraschallsensoren so platziert werden müssen, dass der Roboter nicht von der Kante fällt ehe der Ultraschallsensor diese Kante erkennt, haben wir uns entschieden zwei „Fühler“ am Roboter anzubringen. Diese bestehen aus zwei dünnen Holzstäben, welche am vorderen Teil des Roboters befestigt wurden. An der Unterseite der Fühler wurden dann die Ultraschallsensoren angebracht, sodass diese vorne und seitlich relativ zu den Rädern überstehen.
Durch diese Bauweise und der Unterscheidung zwischen den beiden Fällen, konnte auch bei hohen Geschwindigkeiten sichergestellt werden, dass der Roboter nicht vom Tisch fällt.


Hinderniserkennung

Zur Hinderniserkennung nutzten wir drei Infrarotsensoren, die jeweils den Abstand zu einem Objekt in Fahrtrichtung messen. Infrarotsensoren haben aufgrund des kleinen Messwinkels eine hohe Ortsauflösung, sodass Objekte, die zwar in Fahrtrichtung liegen jedoch kein Hindernis für den Roboter darstellen nicht erkannt werden. Unser erster Gedanke war es dabei, nur einen Infrarotsensor zu nutzen da unser Roboter sowieso sehr klein werden sollte. Durch Einbauen der Fühler ergab sich jedoch das Problem, dass diese den Roboter viel breiter machten als er eigentlich war, sodass die Hindernisse vor den Fühlern nicht erkannt wurden und der Roboter gegen Hindernisse stieß. Das warf die Frage auf, entweder den Infrarotsensor durch einen Ultraschallsensoren zu ersetzen oder an den Fühlern zwei weitere Infrarotsensoren anzubringen. Da jedoch alle digitale Pins schon besetzt waren, blieb uns nur die zweite Option offen.
Zur Berechnung des Abstandes in cm aus den vom Sensor übergebenen Spannungen nutzen wir eine vom Hersteller gegebene Gleichung:

distance = pow(3027.4 / analogRead(sensor1), 1.2134);

Unterschreitet der Roboter einen Abstand von 25 cm zu einem Objekt in Fahrtrichtung so dreht er sich, im Fall, dass diese Unterschreitung durch den Sensor am linken Fühler oder den mittleren Sensor gemessen wurde nach rechts und im Falle, dass der Sensor am rechten Fühler diese Unterschreitung gemessen hatte nach links.
Ein weiteres Problem das uns begegnete war, dass wenn kein Hindernis vor dem Roboter stand und die maximale Reichweite vom Sensor überschritten wurde, die gemessenen Abstände stark schwankten, sodass gelegentlich auch Werte kleiner 25cm berechnet wurden. Der Roboter drehte sich dann auch alle paar Sekunden einmal, ohne das sich ein Hindernis vor ihm befand. Nach langen Überlegungen und Modifikationen vom Code, lösten wir das Problem zum Teil durch das Anlöten von zwei Kondensatoren an dem Infrarotsensor zwischen VCC und GND. Eine weitere Methode die Schwankungen zu unterbinden war es, nicht nur das Resultat einer Messung auszuwerten, sondern den Durchschnitt von 10 aufgenommenen Messwerten zu nehmen und diese auszuwerten. Die „Spikes“ in den Messungen wurden so herausgefiltert und es gab keine starken Schwankungen mehr. Das Erkennen und Ausweichen von Hindernissen funktionierte dann zwar etwas langsamer als zuvor, jedoch ohne weitere Fehler.


Abb.05: Infrarotsensor mit gelöteten Kondensatoren


Linienverfolgung

Um das Abfahren einer schwarzen Linie zu ermöglichen, haben wir an der Unterseite der beiden Fühler je einen Farbsensor angebracht, welcher über einen digitalen Pin zurückgibt, ob er sich über einem schwarzen (HIGH) oder einem weißen (LOW) Untergrund befindet. Den Code haben wir so konzipiert, dass der Roboter sich selbstständig auf einer Linie positioniert, auf die er zufällig stößt und am Ende einer Linie einfach weiter durch den Raum fährt.

Hierfür dreht sich der Roboter, sobald ein Sensor einen schwarzen Untergrund detektiert, um einen kleinen Winkel zu der Seite, auf der auch der getriggerte Sensor liegt. Handelt es sich dabei um eine neue Linie, wird der Roboter sich dadurch immer weiter zur Linie hindrehen, da der getriggerte Sensor permanent über der Linie bleibt. Sobald sich beide Sensoren über der Linie befinden, ist der Roboter senkrecht zur Linie ausgerichtet und die Drehung wird gestoppt. Daraufhin fährt der Roboter ein kleines Stück nach vorne und dreht sich um 90°, wodurch sich die Linie jetzt zwischen den beiden Fühlern befindet.

Abb.06: Positionierung auf neuer Linie

Befindet sich die Linie bereits zwischen den Fühlern, bewirkt das Drehen in Richtung des getriggerten Sensors eine Korrektur der Bewegungsrichtung, sodass die Linie immer zwischen den Fühlern bleibt.

Abb.07: Richtungskorrektur

Ist das Ende einer Linie erreicht, wird keiner der Sensoren mehr getriggert und der Roboter bewegt sich normal weiter.

Dabei kann die Linienverfolgung auch jederzeit durch die anderen Funktionen unterbrochen werden, sodass die Vermeidung von Kanten und Hindernissen weiterhin sichergestellt ist. Dies führt allerdings auch häufig zu sehr unruhigen Bewegungen des Roboters und Abbruch der Linienverfolgung, wenn mehrere Sensoren gleichzeitig getriggert werden. Durch die Einführung der zwei Funktionsmodi, ließ sich das aber mindern.
Ein weiteres Problem ist, dass die Farbsensoren ständig von Hand auf die aktuellen Lichtverhältnisse eingestellt werden müssen, um eine zuverlässige Detektion der Untergrundfarbe zu ermöglichen.


Lichtverfolgung

Die Lichtverfolgung gehörte zu einer der einfacheren Funktionen des Roboters, bei der es keine großen Schwierigkeiten gab. Es wurden drei Photoransistoren am Roboter angebracht. An jedem Fühler einen und einen an der Hinterseite des Roboters. Dadurch kann der Roboter über 360° das helle Licht einer Lichtquelle erkennen. Ist das Licht an einem der Fühler heller, übergibt der Phototransistor also höhere Spannungswerte, dreht sich der Roboter zur Seite des Fühlers hin. Ist das Licht hingegen an der Hinterseite am hellsten, dreht der Roboter sich um 180° um die das Licht vor sich zu haben.
Um zu vermeiden, dass Messschwankungen oder schwache Lichtquellen, wie bsp. das Licht einer Glühbirne, Einfluss auf das Verhalten des Roboters haben, muss der Zustand „heller als“ neu definiert werden. Dazu haben wir festegelgt, dass die Differenz der Helligkeit eines Phototransistors zu den anderen einen gewissen Schwellwert überschreiten muss, damit der Roboter sich tatsächlich dreht. Dieser Schwellwert sollte abhängig von den Widerständen an den Phototransistoren und von den äußeren Lichtverhältnissen abhängig gemacht werden. In unserem Fall nutzten wir Widerstände in der Größenordnung von 4 kOhm und einen Schwellwert von 50. Somit ließ sich realisieren, dass der Roboter einer hellen Lichtquelle folgen kann.


Töne

Zum Abspielen von Reaktionstönen nutzen wir einen einfachen Piezolautsprecher. Beim Starten des Roboters wird ca. 5s lang der Theme Song von Pac Man abgespielt, welchen wir aus folgender Seite entnommen haben: https://github.com/robsoncouto/arduino-songs. Als Reaktion auf Kanten oder Hindernissen die er ausweicht spielt er eine zufällige Abfolge von 10 Tönen ab, wobei wir uns die random()-Funktion zur Hilfe nehmen.


Technische Daten

Bauteile:

  • 1x Arduino Nano
  • 2x Gleichstrommotoren
  • 1x Gyroskop (MPU-6050)
  • 2x Ultraschallsensoren
  • 3x IR-Sensoren
  • 2x Farbsensoren
  • 3x Fototransistoren
  • 1x Piezolautsprecher
  • 1x Schalter

Pinbelegung:

TX1 Schalter
D2 Piezolautsprecher A7 Fototransistor(rechts)
D3 Ultraschallsensor(links) : echo A6 Fototransistor(links)
D4 H-Brücke(rechts) : richtung A5 Gyroskop : SCL
D5 H-Brücke(links) : richtung A4 Gyroskop : SDA
D6 Ultraschallsensor(rechts) : trig A3 Fototransistor(hinten)
D7 Ultraschallsensor(rechts) : echo A2 IR-Sensor(links)
D8 Ultraschallsensor(links) : trig A1 IR-Sensor(rechts)
D9 H-Brücke(links) : drehzahl A0 IR-Sensor(mitte)
D10 H-Brücke(rechts) : drehzahl
D11 Farbsensor(links)
D12 Farbsensor(rechts)


Code

Ergebnis

Im Großen und Ganzen sind wir zufrieden mit dem Ergebnis unseres Projekts. Alle Muss-Funktionen haben wir erfüllen können und einen Teil einer Soll-Funktion. Der Roboter ist ziemlich agil und wendig, aber ein wenig größer als wir uns das eigentlich vorgestellt hatten. Designtechnisch kann noch einiges verbessert werden, um mehr Ähnlichkeit mit einem realen Insekt zu haben. Auch die Soll-Funktion auf äußere Berührung zu reagieren würde der Illusion eines realen Insekts mehr Ausdruck verleihen. Doch die unvorhergesehenen Schwierigkeiten des Projekts verzögerten alles insoweit, dass keine Zeit mehr für weitere Funktionen oder das Design blieb.
Zukünftige Gruppen, die dieses Projekt weiterführen wollen, können versuchen, die Funktion auf-äußere-Berührung-reagieren zu implementieren und den Roboter zusätzlich fernzusteuern. Eine fliegende Version des Insektroboters wäre eine sehr spannende aber auch gewagte Aufgabe der man sich zuwenden könnte. Je nach Geschmack kann der Roboter auch designtechnisch weiterentwickelt werden und die gesamte Konstruktion verkleinert werden.

projektesose21/insektpublic/start.txt · Zuletzt geändert: 2021/10/16 10:03 von d.golovko