Full Self Driving in JavaScript
Ich habe mal wieder Lust auf ein Programmierprojekt. Dazu orientiere ich mich an einer Vorlage, nämlich an einer Serie von YouTube-Videos.
Obwohl ich programmieren kann, habe ich für das Internet immer PHP genutzt, früher auch Perl.
In JavaScript bin ich allerdings nie tiefer eingestiegen. Für dynamische Webinhalte ist die Sprache ganz praktisch und außerdem hat mein Lehrer, Radu Mariescu-Istodor, seine Beispiele alle in JavaScript geschrieben. 😉
Das FSD im Seitentitel bedeutet also Full Self Driving. Ich habe mir die Bezeichnung von Tesla geklaut, die ihren Autopiloten so nennen. Dazu gibt es übrigens sehr interessante Videos auf dem YouTube-Kanal Whole Mars Catalog. Auch wenn das jetzt nicht nach Autos oder Tesla klingt, dort findet ihr viele Videos darüber, wie sich der FSD von Tesla im (amerikanischen) Alltag so schlägt.
Darum geht es also: Ein System in JavaScript zu programmieren, mit dem Autos komplett autonom (auf dem Bildschirm) herumfahren können.
Dazu werde ich mich mit genetischen Algorithmen, neuronalen Netzwerken und Machine Learning auseinandersetzen müssen/dürfen. Auch der mathematische Einheitskreis, Sinus und Cosinus werden mir nicht erspart bleiben.
Yay, klingt nach ner Menge Spaß!
Und so soll es auch sein! 🙂
Das ganze Projekt wird sich über einen längeren Zeitraum hinziehen, je nachdem, wie viel Zeit und Lust ich dazu habe.
Begleitet mich gerne dabei hier auf meinem Blog!
Credits für die Anleitungen:
Alle Anleitungen und Inspirationen habe ich den Videos von Radu Mariescu-Istodor aus Finnland entnommen.
Unter dem Motto Coding with Radu findet ihr viele interessante Videos auf seinem YouTube-Kanal.
Hier kommt ihr direkt zu seiner Serie Self-driving Car:: Phase 1.
Grundsätzliches zur Programmierung
Ich werde eine ganz rudimentäre HTML-Seite erstellen. Auf dieser Seite wird das Canvas-Element als Leinwand verwendet.
Ein klein wenig CSS-Code macht die Leinwand sichtbar.
Alles andere passiert in externen JavaScript-Dateien. Es werden keinerlei JavaScript-Bibliotheken wie zum Beispiel jQuery oder Three.js genutzt.
Die Ergebnisse der einzelnen Projektphasen werde ich jeweils über einen eigenen Link auf dieser Website verfügbar machen.
Zusätzlich werde ich zur Veranschaulichung auch einige dieser Ergebnisse hier in meinen Artikeln direkt per iFrame einbinden.
In diesen Skripten wird sich dann das Self Driving Car nach und nach entwickeln.
- Wir fangen ganz langsam an und malen zunächst eine Straße auf die Leinwand.
- Dazu kommt dann ein erstes Auto. Das wird sich über Pfeiltasten steuern lassen.
- Das Auto wird mit Sensoren ausgestattet, um Hindernisse zu erkennen.
- Eine Kollisisonserkennung und -behandlung darf dann natürlich nicht fehlen.
- Später wird es ein Gehirn erhalten, um selbstständig fahren zu können.
- Die Leinwand wird nach und nach ergänzt um Kurven, Verkehrszeichen, Ampeln, weitere Autos, Häuser und Bäume.
- Natürlich wird es auch ein Navi geben.
Das später verwendete mathematische Modell und die Aktivierungsfunktionen im neuronalen Netz sind recht einfach gestaltet. Das kann man beliebig verfeinern und verkomplexitieren. Aber in der Video-Serie geht es vor allem um Nachvollziehbarkeit und Verständnis. Dafür reichen die verwendeten Modelle aus.
Wir bauen eine Straße
Als erstes müssen die drei grundlegenden Dateien erstellt werden:
- index.html – die Webseite
- style.css – Formatierungen
- main.js – der Programm-Code
HTML:
Diese Datei findet ihr auf https://sevke.net/js/cars/t1/index.html. Dort könnt ihr sie mit eurem Browser über die Funktion „Seitenquelltext anzeigen“ inspizieren. Da steht aber wirklich nicht viel drinnen.
CSS:
Die CSS-Datei könnt ihr euch direkt im Browser ansehen: https://sevke.net/js/cars/t1/style.css
JavaScript:
Es wird mehre JavaScript-Dateien geben, die ihr nur ausführen, aber nicht im Browser ansehen könnt.
n diesen Dateien befindet sich irgendwann das Endergebnis des ersten Teils des Projekts. Um auch die Zwischenschritte sichtbar machen zu können, speichere ich sie in zusätzlichen Dateien ab.
Zuerst zeichne ich eine Leinwand auf die Webseite und auf die Leinwand eine graue Straße.
Das Ergebnis findet ihr in https://sevke.net/js/cars/t1/t1-1-index.html
Das sieht dann wie folgt aus:
Spannend, nicht wahr? Na ja, ein bisschen Vorstellungskraft müsst ihr schon besitzen. 🙂 Aber das wird schon noch. Versprochen.
Die Leinwand ist also dunkelgrau und die Straße ist hellgrau. Die Straße ist quasi unendlich lang und erstreckt sich immer über den gesamten zur Verfügung stehenden Bildschirmbereich. Die Breite ist eingeschränkt, weil wir den Platz rechts daneben später noch benötigen werden.
Wir bauen ein Auto
Als nächstes setzen wir ein schickes Auto auf die Straße. Ihr ahnt es schon … ja, es wird wieder nur ein kleines Rechteck, diesmal in Rot (weil mein eigenes Auto auch rot ist),
Für das Auto erstellen wir eine Klasse Car in einer neuen JavaScript-Datei. Das Auto weiß dann, wo es ist und wie es sich auf die Leinwand zeichnet.
Ich zeichne es zunächst horizontal mittig ausgerichtet und relativ weit oben auf der Straße.
Hier seht ihr das Zwischenergebnis: https://sevke.net/js/cars/t1/t1-2-index.html
Und so sieht das aus:
Den Programmcode findet ihr in den Videos von Radu Mariescu-Istodor. Dort wird der Code nach und nach entwickelt und erklärt.
Wir machen jetzt weiter mit einer einfachen Tastatursteuerung des Autos per Pfeiltasten.
Das Auto bekommt ein Lenkrad
Dazu erstellen wir eine neue Klasse Controls. In ihr wird die Steuerung beschrieben.
Die verschiednen Klassen werden alle in der index.html eingebunden.
Die Steuerung soll vier Bewegungsrichtungen enthalten:
- vorwärts
- rückwärts
- links
- rechts
Dazu muss in der Klasse Controls überwacht werden, ob eine Taste gedrückt wird oder ob sie wieder losgelassen wird. Außerdem muss natürlich ausgewertet werden, um welche Taste es sich handelt.
Bei der Vorwärts- und Rückwärtsbewegung berücksichtigen wir außerdem eine maximale Geschwindigkeit, die das Fahrzeug erreichen kann, sowie eine Reifenreibung, die das Auto abbremst, wenn keine Taste mehr gedrückt, also nicht mehr beschleunigt wird.
Wenn das Auto rückwärts fährt, soll es nicht ganz so schnell sein wie vorwärts.
Das Ergebnis findet ihr auf https://sevke.net/js/cars/t1/t1-3-index.html
Und so sieht es aus:
Zum Steuern verwendet ihr die Cursor-/Pfeiltasten auf eurer Tastatur. Leider kollidieren sie mit der Steuerung des Browsers, so dass ihr das am besten direkt auf der Website unter https://sevke.net/js/cars/t1/t1-3-index.html ausprobiert.
Ihr werdet sofort bemerken, dass sich das Auto noch nicht um irgendwelche Begrenzungen der Straße kümmert. Es bewegt sich auch nicht so zur Seite, wie wir es von echten Autos her kennen. Aber in alten Videospielen bewegen sich Raumschiffe (Space Invaders) oder Autos manchmal genau so. Dafür würde das schon taugen.
Aber okay, das soll nicht so bleiben. EIn bisschen verwirrend finde ich, dass man das Auto nicht auf der Leinwand drehen kann. Ja, so kennt man das aus den gängigen Bildbearbeitungs-/Illustrationsprogrammen wie Affinity Photo und Affinity Designer. Da ist so ein Auto ein Objekt. In JavaScript auch. Aber nicht auf dem Canvas (=Leinwand). Sobald das Auto gezeichnet ist, ist es ein fester Bestandteil der Leinwand und kann nicht mehr verändert werden.
Für die Drehung des Autos muss also die gesamte Leinwand in die andere Richtung gedreht werden. Aber auch das hat einen Haken. Denn die Drehung erfolgt um den Koordinatenursprung und der sitzt links oben auf der Leinwand.
Die Vorgehensweise ist also:
- Leinwand sauber machen
- Parameter/Zustand der Leinwand zwischenspeichern
- Den Koordinatenursprung in die Mitte des Autos setzen
- Die Leinwand um diesen Mittelpunkt herum entsprechend ein Stückchen drehen
- Das Auto zeichnen
- Die Leinwand wieder auf die alten Parameter zurücksetzen
Damit sich das Auto nicht um sich selbst dreht, muss es zusätzlich bewegt werden, also das alte Auto gelöscht und ein neues gezeichnet werden.
Solange das Auto senkrecht oder waagerecht fährt, ist das leicht auszurechnen. Einfach die aktuelle Geschwindigkeit draufrechnen und es passt.
Bewegt sich das Auto aber schräg, so wäre das viel zu weit. Für die Berechnung der neuen X- und Y-Koordinaten müssen wir jetzt Sinus- und Cosinusfunktionen bemühen.
Am einfachsten versteht man das mit Hilfe des Einheitskreises, den ihr euch allerdings um 90 Grad nach links gedreht vorstellen müsst, weil sich unser Auto ja vorwärts nach oben bewegt.
So sieht er aus.
Jeder Mittelschüler lacht sich jetzt wahrscheinlich tot, aber sorry, ich habe das nie gebraucht und es ist echt schon ziemlich lange her, dass ich mich damit beschäftigen musste.
Ich erspare euch hier jetzt auch langwierige und -weilige Erklärungen. Wenn ihr mehr dazu wissen wollt, besucht ruhig die Webseite Studyflix.
Ich habe hier zuhause eine Sparringpartnerin, mit der ich das gut durchkauen konnte. 🙂
Für das Programm braucht man da aber nicht unbedingt so tief einzusteigen. Ihr könnt den Code ja einfach aus dem Video abschreiben.
Auf jeden Fall ist es jetzt möglich, das Auto mit Hilfe der Links-/Rechtstasten zu drehen und gleichzeitig zu fahren.
Und damit erhaltet ihr das Endergebnis dieser Folge auf https://sevke.net/js/cars/t1/index.html.
Bei mir auf dem PC ist das Auto ziemlich schnell. Aber ich lass das jetzt erst einmal so.
Hier noch das sichtbare Ergebnis per iFrame:
Wie geht es weiter?
Im nächsten Teil werden wir die Straße mit Fahrbahnmarkierungen ausstatten. Außerdem wird sich nicht mehr das Auto bewegen, sondern die Leinwand, so dass die Straße quasi unendlich lang wird.
Ich hoffe, ihr habe genauso viel Spaß an diesem Projekt wie ich!