From e2ab6b1587d231d755303e97b2258ce4008df9d2 Mon Sep 17 00:00:00 2001 From: elida Date: Wed, 23 Aug 2023 22:06:48 +0300 Subject: [PATCH] self driving car --- .../1. Car driving mechanics/car.js | 76 ++++++++ .../1. Car driving mechanics/controls.js | 45 +++++ .../1. Car driving mechanics/index.html | 12 ++ .../1. Car driving mechanics/main.js | 15 ++ .../1. Car driving mechanics/style.css | 9 + .../10. Live stream variant/car.js | 147 ++++++++++++++++ .../10. Live stream variant/controls.js | 52 ++++++ .../10. Live stream variant/index.html | 18 ++ .../10. Live stream variant/main.js | 74 ++++++++ .../10. Live stream variant/network.js | 87 +++++++++ .../10. Live stream variant/readme.txt | 10 ++ .../10. Live stream variant/road.js | 66 +++++++ .../10. Live stream variant/sensor.js | 111 ++++++++++++ .../10. Live stream variant/style.css | 12 ++ .../10. Live stream variant/utils.js | 50 ++++++ .../10. Live stream variant/visualizer.js | Bin 0 -> 6334 bytes Self-driving-car/2. Road definition/car.js | 76 ++++++++ .../2. Road definition/controls.js | 45 +++++ .../2. Road definition/index.html | 14 ++ Self-driving-car/2. Road definition/main.js | 23 +++ Self-driving-car/2. Road definition/road.js | 56 ++++++ Self-driving-car/2. Road definition/style.css | 9 + Self-driving-car/2. Road definition/utils.js | 3 + Self-driving-car/3. Artificial sensors/car.js | 80 +++++++++ .../3. Artificial sensors/controls.js | 45 +++++ .../3. Artificial sensors/index.html | 15 ++ .../3. Artificial sensors/main.js | 23 +++ .../3. Artificial sensors/road.js | 56 ++++++ .../3. Artificial sensors/sensor.js | 100 +++++++++++ .../3. Artificial sensors/style.css | 9 + .../3. Artificial sensors/utils.js | 23 +++ .../4. Collision detection/car.js | 114 ++++++++++++ .../4. Collision detection/controls.js | 45 +++++ .../4. Collision detection/index.html | 15 ++ .../4. Collision detection/main.js | 23 +++ .../4. Collision detection/road.js | 56 ++++++ .../4. Collision detection/sensor.js | 100 +++++++++++ .../4. Collision detection/style.css | 9 + .../4. Collision detection/utils.js | 40 +++++ Self-driving-car/5. Traffic simulation/car.js | 125 +++++++++++++ .../5. Traffic simulation/controls.js | 52 ++++++ .../5. Traffic simulation/index.html | 15 ++ .../5. Traffic simulation/main.js | 32 ++++ .../5. Traffic simulation/road.js | 56 ++++++ .../5. Traffic simulation/sensor.js | 119 +++++++++++++ .../5. Traffic simulation/style.css | 9 + .../5. Traffic simulation/utils.js | 40 +++++ Self-driving-car/6. Neural network/car.js | 141 +++++++++++++++ .../6. Neural network/controls.js | 52 ++++++ Self-driving-car/6. Neural network/index.html | 17 ++ Self-driving-car/6. Neural network/main.js | 38 ++++ Self-driving-car/6. Neural network/network.js | 68 ++++++++ Self-driving-car/6. Neural network/road.js | 56 ++++++ Self-driving-car/6. Neural network/sensor.js | 119 +++++++++++++ Self-driving-car/6. Neural network/style.css | 12 ++ Self-driving-car/6. Neural network/utils.js | 40 +++++ .../7. Visualizing neural networks/car.js | 141 +++++++++++++++ .../controls.js | 52 ++++++ .../7. Visualizing neural networks/index.html | 18 ++ .../7. Visualizing neural networks/main.js | 40 +++++ .../7. Visualizing neural networks/network.js | 68 ++++++++ .../7. Visualizing neural networks/road.js | 56 ++++++ .../7. Visualizing neural networks/sensor.js | 119 +++++++++++++ .../7. Visualizing neural networks/style.css | 12 ++ .../7. Visualizing neural networks/utils.js | 49 ++++++ .../visualizer.js | Bin 0 -> 7098 bytes .../8. Optimizing neural networks/car.js | 141 +++++++++++++++ .../8. Optimizing neural networks/controls.js | 52 ++++++ .../8. Optimizing neural networks/index.html | 22 +++ .../8. Optimizing neural networks/main.js | 87 +++++++++ .../8. Optimizing neural networks/network.js | 89 ++++++++++ .../8. Optimizing neural networks/road.js | 56 ++++++ .../8. Optimizing neural networks/sensor.js | 119 +++++++++++++ .../8. Optimizing neural networks/style.css | 31 ++++ .../8. Optimizing neural networks/utils.js | 49 ++++++ .../visualizer.js | Bin 0 -> 7098 bytes Self-driving-car/9. Fine-tuning/car.js | 165 ++++++++++++++++++ Self-driving-car/9. Fine-tuning/car.png | Bin 0 -> 6964 bytes Self-driving-car/9. Fine-tuning/controls.js | 52 ++++++ Self-driving-car/9. Fine-tuning/index.html | 22 +++ Self-driving-car/9. Fine-tuning/main.js | 87 +++++++++ Self-driving-car/9. Fine-tuning/network.js | 89 ++++++++++ Self-driving-car/9. Fine-tuning/road.js | 56 ++++++ Self-driving-car/9. Fine-tuning/sensor.js | 119 +++++++++++++ Self-driving-car/9. Fine-tuning/style.css | 31 ++++ Self-driving-car/9. Fine-tuning/utils.js | 54 ++++++ Self-driving-car/9. Fine-tuning/visualizer.js | Bin 0 -> 7098 bytes Self-driving-car/LICENSE | 21 +++ Self-driving-car/README.md | 16 ++ 89 files changed, 4667 insertions(+) create mode 100644 Self-driving-car/1. Car driving mechanics/car.js create mode 100644 Self-driving-car/1. Car driving mechanics/controls.js create mode 100644 Self-driving-car/1. Car driving mechanics/index.html create mode 100644 Self-driving-car/1. Car driving mechanics/main.js create mode 100644 Self-driving-car/1. Car driving mechanics/style.css create mode 100644 Self-driving-car/10. Live stream variant/car.js create mode 100644 Self-driving-car/10. Live stream variant/controls.js create mode 100644 Self-driving-car/10. Live stream variant/index.html create mode 100644 Self-driving-car/10. Live stream variant/main.js create mode 100644 Self-driving-car/10. Live stream variant/network.js create mode 100644 Self-driving-car/10. Live stream variant/readme.txt create mode 100644 Self-driving-car/10. Live stream variant/road.js create mode 100644 Self-driving-car/10. Live stream variant/sensor.js create mode 100644 Self-driving-car/10. Live stream variant/style.css create mode 100644 Self-driving-car/10. Live stream variant/utils.js create mode 100644 Self-driving-car/10. Live stream variant/visualizer.js create mode 100644 Self-driving-car/2. Road definition/car.js create mode 100644 Self-driving-car/2. Road definition/controls.js create mode 100644 Self-driving-car/2. Road definition/index.html create mode 100644 Self-driving-car/2. Road definition/main.js create mode 100644 Self-driving-car/2. Road definition/road.js create mode 100644 Self-driving-car/2. Road definition/style.css create mode 100644 Self-driving-car/2. Road definition/utils.js create mode 100644 Self-driving-car/3. Artificial sensors/car.js create mode 100644 Self-driving-car/3. Artificial sensors/controls.js create mode 100644 Self-driving-car/3. Artificial sensors/index.html create mode 100644 Self-driving-car/3. Artificial sensors/main.js create mode 100644 Self-driving-car/3. Artificial sensors/road.js create mode 100644 Self-driving-car/3. Artificial sensors/sensor.js create mode 100644 Self-driving-car/3. Artificial sensors/style.css create mode 100644 Self-driving-car/3. Artificial sensors/utils.js create mode 100644 Self-driving-car/4. Collision detection/car.js create mode 100644 Self-driving-car/4. Collision detection/controls.js create mode 100644 Self-driving-car/4. Collision detection/index.html create mode 100644 Self-driving-car/4. Collision detection/main.js create mode 100644 Self-driving-car/4. Collision detection/road.js create mode 100644 Self-driving-car/4. Collision detection/sensor.js create mode 100644 Self-driving-car/4. Collision detection/style.css create mode 100644 Self-driving-car/4. Collision detection/utils.js create mode 100644 Self-driving-car/5. Traffic simulation/car.js create mode 100644 Self-driving-car/5. Traffic simulation/controls.js create mode 100644 Self-driving-car/5. Traffic simulation/index.html create mode 100644 Self-driving-car/5. Traffic simulation/main.js create mode 100644 Self-driving-car/5. Traffic simulation/road.js create mode 100644 Self-driving-car/5. Traffic simulation/sensor.js create mode 100644 Self-driving-car/5. Traffic simulation/style.css create mode 100644 Self-driving-car/5. Traffic simulation/utils.js create mode 100644 Self-driving-car/6. Neural network/car.js create mode 100644 Self-driving-car/6. Neural network/controls.js create mode 100644 Self-driving-car/6. Neural network/index.html create mode 100644 Self-driving-car/6. Neural network/main.js create mode 100644 Self-driving-car/6. Neural network/network.js create mode 100644 Self-driving-car/6. Neural network/road.js create mode 100644 Self-driving-car/6. Neural network/sensor.js create mode 100644 Self-driving-car/6. Neural network/style.css create mode 100644 Self-driving-car/6. Neural network/utils.js create mode 100644 Self-driving-car/7. Visualizing neural networks/car.js create mode 100644 Self-driving-car/7. Visualizing neural networks/controls.js create mode 100644 Self-driving-car/7. Visualizing neural networks/index.html create mode 100644 Self-driving-car/7. Visualizing neural networks/main.js create mode 100644 Self-driving-car/7. Visualizing neural networks/network.js create mode 100644 Self-driving-car/7. Visualizing neural networks/road.js create mode 100644 Self-driving-car/7. Visualizing neural networks/sensor.js create mode 100644 Self-driving-car/7. Visualizing neural networks/style.css create mode 100644 Self-driving-car/7. Visualizing neural networks/utils.js create mode 100644 Self-driving-car/7. Visualizing neural networks/visualizer.js create mode 100644 Self-driving-car/8. Optimizing neural networks/car.js create mode 100644 Self-driving-car/8. Optimizing neural networks/controls.js create mode 100644 Self-driving-car/8. Optimizing neural networks/index.html create mode 100644 Self-driving-car/8. Optimizing neural networks/main.js create mode 100644 Self-driving-car/8. Optimizing neural networks/network.js create mode 100644 Self-driving-car/8. Optimizing neural networks/road.js create mode 100644 Self-driving-car/8. Optimizing neural networks/sensor.js create mode 100644 Self-driving-car/8. Optimizing neural networks/style.css create mode 100644 Self-driving-car/8. Optimizing neural networks/utils.js create mode 100644 Self-driving-car/8. Optimizing neural networks/visualizer.js create mode 100644 Self-driving-car/9. Fine-tuning/car.js create mode 100644 Self-driving-car/9. Fine-tuning/car.png create mode 100644 Self-driving-car/9. Fine-tuning/controls.js create mode 100644 Self-driving-car/9. Fine-tuning/index.html create mode 100644 Self-driving-car/9. Fine-tuning/main.js create mode 100644 Self-driving-car/9. Fine-tuning/network.js create mode 100644 Self-driving-car/9. Fine-tuning/road.js create mode 100644 Self-driving-car/9. Fine-tuning/sensor.js create mode 100644 Self-driving-car/9. Fine-tuning/style.css create mode 100644 Self-driving-car/9. Fine-tuning/utils.js create mode 100644 Self-driving-car/9. Fine-tuning/visualizer.js create mode 100644 Self-driving-car/LICENSE create mode 100644 Self-driving-car/README.md diff --git a/Self-driving-car/1. Car driving mechanics/car.js b/Self-driving-car/1. Car driving mechanics/car.js new file mode 100644 index 0000000..5fb3135 --- /dev/null +++ b/Self-driving-car/1. Car driving mechanics/car.js @@ -0,0 +1,76 @@ +class Car{ + constructor(x,y,width,height){ + this.x=x; + this.y=y; + this.width=width; + this.height=height; + + this.speed=0; + this.acceleration=0.2; + this.maxSpeed=3; + this.friction=0.05; + this.angle=0; + + this.controls=new Controls(); + } + + update(){ + this.#move(); + } + + #move(){ + if(this.controls.forward){ + this.speed+=this.acceleration; + } + if(this.controls.reverse){ + this.speed-=this.acceleration; + } + + if(this.speed>this.maxSpeed){ + this.speed=this.maxSpeed; + } + if(this.speed<-this.maxSpeed/2){ + this.speed=-this.maxSpeed/2; + } + + if(this.speed>0){ + this.speed-=this.friction; + } + if(this.speed<0){ + this.speed+=this.friction; + } + if(Math.abs(this.speed)0?1:-1; + if(this.controls.left){ + this.angle+=0.03*flip; + } + if(this.controls.right){ + this.angle-=0.03*flip; + } + } + + this.x-=Math.sin(this.angle)*this.speed; + this.y-=Math.cos(this.angle)*this.speed; + } + + draw(ctx){ + ctx.save(); + ctx.translate(this.x,this.y); + ctx.rotate(-this.angle); + + ctx.beginPath(); + ctx.rect( + -this.width/2, + -this.height/2, + this.width, + this.height + ); + ctx.fill(); + + ctx.restore(); + } +} \ No newline at end of file diff --git a/Self-driving-car/1. Car driving mechanics/controls.js b/Self-driving-car/1. Car driving mechanics/controls.js new file mode 100644 index 0000000..f302887 --- /dev/null +++ b/Self-driving-car/1. Car driving mechanics/controls.js @@ -0,0 +1,45 @@ +class Controls{ + constructor(){ + this.forward=false; + this.left=false; + this.right=false; + this.reverse=false; + + this.#addKeyboardListeners(); + } + + #addKeyboardListeners(){ + document.onkeydown=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=true; + break; + case "ArrowRight": + this.right=true; + break; + case "ArrowUp": + this.forward=true; + break; + case "ArrowDown": + this.reverse=true; + break; + } + } + document.onkeyup=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=false; + break; + case "ArrowRight": + this.right=false; + break; + case "ArrowUp": + this.forward=false; + break; + case "ArrowDown": + this.reverse=false; + break; + } + } + } +} \ No newline at end of file diff --git a/Self-driving-car/1. Car driving mechanics/index.html b/Self-driving-car/1. Car driving mechanics/index.html new file mode 100644 index 0000000..2942f9a --- /dev/null +++ b/Self-driving-car/1. Car driving mechanics/index.html @@ -0,0 +1,12 @@ + + + Self-driving car - No libraries + + + + + + + + + \ No newline at end of file diff --git a/Self-driving-car/1. Car driving mechanics/main.js b/Self-driving-car/1. Car driving mechanics/main.js new file mode 100644 index 0000000..0369821 --- /dev/null +++ b/Self-driving-car/1. Car driving mechanics/main.js @@ -0,0 +1,15 @@ +const canvas=document.getElementById("myCanvas"); +canvas.width=200; + +const ctx = canvas.getContext("2d"); +const car=new Car(100,100,30,50); + +animate(); + +function animate(){ + car.update(); + + canvas.height=window.innerHeight; + car.draw(ctx); + requestAnimationFrame(animate); +} \ No newline at end of file diff --git a/Self-driving-car/1. Car driving mechanics/style.css b/Self-driving-car/1. Car driving mechanics/style.css new file mode 100644 index 0000000..81d0b00 --- /dev/null +++ b/Self-driving-car/1. Car driving mechanics/style.css @@ -0,0 +1,9 @@ +body{ + margin:0; + background:darkgray; + overflow:hidden; + text-align:center; +} +#myCanvas{ + background:lightgray; +} \ No newline at end of file diff --git a/Self-driving-car/10. Live stream variant/car.js b/Self-driving-car/10. Live stream variant/car.js new file mode 100644 index 0000000..cbe2472 --- /dev/null +++ b/Self-driving-car/10. Live stream variant/car.js @@ -0,0 +1,147 @@ +class Car{ + constructor(x,y,width,height,controlType,maxSpeed=3){ + this.x=x; + this.y=y; + this.width=width; + this.height=height; + + this.speed=0; + this.acceleration=0.2; + this.maxSpeed=maxSpeed; + this.friction=0.05; + this.angle=0; + + this.damaged=false; + + this.useBrain=controlType=="AI"; + + if(controlType!="DUMMY"){ + this.sensor=new Sensor(); + this.brain=new NeuralNetwork( + [this.sensor.rayCount,4] + ); + } + this.controls=new Controls(controlType); + } + + update(roadBorders,traffic){ + if(!this.damaged){ + this.#move(); + this.polygon=this.#createPolygon(); + this.damaged=this.#assessDamage(roadBorders,traffic); + } + if(this.sensor){ + this.sensor.update(this.x,this.y,this.angle,roadBorders,traffic); + const offsets=this.sensor.readings.map( + s=>s==null?0:1-s.offset + ); + const outputs=NeuralNetwork.feedForward(offsets,this.brain); + if(this.useBrain){ + this.controls.forward=outputs[0]; + this.controls.left=outputs[1]; + this.controls.right=outputs[2]; + this.controls.reverse=outputs[3]; + } + } + } + + #assessDamage(roadBorders,traffic){ + for(let i=0;i0?1:-1; + if(this.controls.left){ + this.angle+=0.03*flip; + } + if(this.controls.right){ + this.angle-=0.03*flip; + } + } + + if(this.speed>this.maxSpeed){ + this.speed=this.maxSpeed; + } + if(this.speed<-this.maxSpeed/2){ + this.speed=-this.maxSpeed/2; + } + + if(this.speed>0){ + this.speed-=this.friction; + } + if(this.speed<0){ + this.speed+=this.friction; + } + if(Math.abs(this.speed){ + switch(event.key){ + case "ArrowLeft": + this.left=true; + break; + case "ArrowRight": + this.right=true; + break; + case "ArrowUp": + this.forward=true; + break; + case "ArrowDown": + this.reverse=true; + break; + } + } + document.onkeyup=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=false; + break; + case "ArrowRight": + this.right=false; + break; + case "ArrowUp": + this.forward=false; + break; + case "ArrowDown": + this.reverse=false; + break; + } + } + } +} \ No newline at end of file diff --git a/Self-driving-car/10. Live stream variant/index.html b/Self-driving-car/10. Live stream variant/index.html new file mode 100644 index 0000000..5e7eedf --- /dev/null +++ b/Self-driving-car/10. Live stream variant/index.html @@ -0,0 +1,18 @@ + + + + JS - Self-driving Car - LIVE + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Self-driving-car/10. Live stream variant/main.js b/Self-driving-car/10. Live stream variant/main.js new file mode 100644 index 0000000..1d7c213 --- /dev/null +++ b/Self-driving-car/10. Live stream variant/main.js @@ -0,0 +1,74 @@ +carCanvas.height=window.innerHeight; +carCanvas.width=200; +networkCanvas.height=window.innerHeight; +networkCanvas.width=298; + +const carCtx=carCanvas.getContext("2d"); +const networkCtx=networkCanvas.getContext("2d"); +const road=new Road(carCanvas.width/2,carCanvas.width*0.9); +const N=100; +const cars=generateCars(N); +const traffic=[ + new Car(100,-100,30,50,"DUMMY",2) +]; +let bestCar=cars[0]; +if(localStorage.getItem("bestBrain")){ + for(let i=0;i0){ + NeuralNetwork.mutate(cars[i].brain,0.4); + } + } +} + +animate(); + +function animate(){ + for(let i=0;ic.y==Math.min( + ...cars.map(c=>c.y) + )); + + carCanvas.height=window.innerHeight; + networkCanvas.height=window.innerHeight; + + carCtx.translate(0,-bestCar.y+carCanvas.height*0.7); + road.draw(carCtx); + for(let i=0;i { + for(let i=0;ilevel.biases[i]){ + level.outputs[i]=1; + }else{ + level.outputs[i]=0; + } + } + + return level.outputs; + } +} \ No newline at end of file diff --git a/Self-driving-car/10. Live stream variant/readme.txt b/Self-driving-car/10. Live stream variant/readme.txt new file mode 100644 index 0000000..6680c70 --- /dev/null +++ b/Self-driving-car/10. Live stream variant/readme.txt @@ -0,0 +1,10 @@ +Link to live stream: +https://youtu.be/NUjN2Mln_Gg + +Instructions: + +Call the save() and discard() methods in the browser console when you want to store a car's brain in local storage. + +Play with the number of cars simulated in parallel N (line 9) and the mutation amount (line 0.4) + +Changing properties of the neural network or the sensor requires you to call discard() in the console so that the old ones don't come from local storage. \ No newline at end of file diff --git a/Self-driving-car/10. Live stream variant/road.js b/Self-driving-car/10. Live stream variant/road.js new file mode 100644 index 0000000..3443ed7 --- /dev/null +++ b/Self-driving-car/10. Live stream variant/road.js @@ -0,0 +1,66 @@ +class Road{ + constructor(x,width,laneCount=3){ + this.x=x; + this.width=width; + this.laneCount=laneCount; + this.left=x-width/4; + this.right=x+width/4; + + const infinity=10000; + this.top=-infinity; + this.bottom=infinity; + + const topLeft={x:this.left,y:this.top}; + const bottomLeft={x:this.left,y:this.bottom}; + const topRight={x:this.right,y:this.top}; + const bottomRight={x:this.right,y:this.bottom}; + this.borders=[ + [topLeft], + [topRight] + ]; + for(let y=-1000;y<=0;y++){ + const x=Math.sin(y*0.01)*50; + this.borders[0].push({x:x+this.left,y:y}); + this.borders[1].push({x:x+this.right,y:y}); + } + this.borders[0].push(bottomLeft); + this.borders[1].push(bottomRight); + } + + getLaneCenter(laneIndex){ + const laneWidth=this.width/this.laneCount; + return this.left+laneWidth/2+ + Math.min(laneIndex,this.laneCount-1)*laneWidth; + } + + draw(ctx){ + ctx.lineWidth=5; + ctx.strokeStyle="white"; + + /* + ctx.setLineDash([20,20]); + for(let i=1;i<=this.laneCount-1;i++){ + const x=lerp( + this.left, + this.right, + i/this.laneCount + ); + ctx.beginPath(); + ctx.moveTo(x,this.top); + ctx.lineTo(x,this.bottom); + ctx.stroke(); + } + */ + + ctx.setLineDash([20,20]); + this.borders.forEach(border=>{ + ctx.beginPath(); + ctx.moveTo(border[0].x,border[0].y); + for(let i=1;i{ + for(let i=1;ie.offset); + const minOffset=Math.min(...offsets); + return touches.find(e=>e.offset==minOffset); + } + } + + #castRays(x,y,angle){ + this.rays=[]; + for(let i=0;i=0 && t<=1 && u>=0 && u<=1){ + return { + x:lerp(A.x,B.x,t), + y:lerp(A.y,B.y,t), + offset:t + } + } + } + + return null; +} + +//polylines +function polysIntersect(poly1, poly2){ + for(let i=0;i0?0:255; + return "rgba("+R+","+G+","+B+","+alpha+")"; +} + \ No newline at end of file diff --git a/Self-driving-car/10. Live stream variant/visualizer.js b/Self-driving-car/10. Live stream variant/visualizer.js new file mode 100644 index 0000000000000000000000000000000000000000..18b4df2407be08e5fa20f3bcb7925e69007887e6 GIT binary patch literal 6334 zcmd^D-%k@k5S~ZH_&<>PKufO$j2fd90xxQUgdkCqh6iYiEtEpq1FD4o(+B?+^_!b+ zZ}z&kcZEVsOw;y$?9R^2H}lQx{`uXYE*;PSpLzOB9sFP5zKg3L)S^CJ(^HzmJN^tP z#Jdph8n|oX?EziUHpYecKg0bA74a^lAqCX4o|i01BCmlty-4ajokCWhzCm`6YV?wp z>8)CMa(oxkkFZkBn(3btV!iXJW?Vs^CRS-3U3>{1_j%moBkRm)={eX}L=Yq^cO*f_*%TE#$i%^kgrHf0HX7Mc5ak zks%_Z18>>r`(##V1#&yIhFOeyhbs8E;>Bm*-UwU4xI7U%GFN`tqCO&_=p7|vwWlh| zGuod)4mr!nh@{`NPI8^!Yc+UlC5J?jyAID*kyY6m$oMxvVF~`puMeYG^2#rzM31cK z;-2c5W46W-nZ_@6gw>({eul?63Yb9xg{nl6AE`Lw_00V7z}Ycveq`gePIX$KwV#iF zEx;nadNjV88(%%a)xH-cgMU4BoWW5>%I}SmDc7;a?yBKJlo1i$5zh)blF@-;+5k)x zb7z3ezW|Qs(eD;``4DfJyIdTiYfc|gV))lYLs_lkuO^3BH^k=*ykCp{!_=4MN+ z!8J7KjWizsH*E>uUnx8J{t)B2?zHf|!K$&x{JQoaxrtf3nB9bo3(RN!crnUJjb)6S zJaw_V@bs#seX>$?;El2q1Gn5`XvA`lX*J=8q~zla$s*rWRE`GeD|TQ#SFs|rn)H|U zfth;>O*kT%7xGjKH;X;P`rIRJk5KpuSvKw+U~3{UKy5N{S;F%q9$HVi){*ENo!4sa z{+Rh^Z*?-hkMCr+FvBb@{sPNQzvt@TwC_!fFu(PI> zb6F}>9nrp@I~w&$z8KbQEE-Qfxv#9&>^4M3&psp4GS}cSUA~)Hy!&VXCEmH{eByn~ zBzFd2s(?O@_@qiZ^ntkJPtP#3&JiN4i;s?!0#@W*SOYOsNM)v^1YZQ0u@B*k#i+M@ z1%J%aC&HL<_GrG8+{y22x2LAd37ff+6)CIM-99Vqbpu3CTBW%Eyb!+q-!sDJg@?%n zJ0@n64N@oW#v7(@$X7+pTAF#Yef#ocC4j@@m9Lv$-cbSoREJlt*asapXRh|hZXUEfoQ+>$m?!FXq4qJZU{M*UP1 z&sw?V-M&KFdTB&7+68oCZRo{TrdL~A7I#bRmm08h^#hC8OY!+i2|JSl_H#p=f^9^7 zJfEfJUqyO@J!r<*WW`Akbt}I9SFDh%DyL}9CqsO8lU6@$PZ)G{j?39nzWExJf6LCv zen3Bw>)6+9M|>9U+Tocv;e9)IFTDTe?$W)_o6Pt=#)sgEKIYCxvwUZkvD8>cK~8?- oJ!RUCGS=7bZn94r^PDd7iK6j=oGeOLojhT7pCj7QDOlXlU-ph+od5s; literal 0 HcmV?d00001 diff --git a/Self-driving-car/2. Road definition/car.js b/Self-driving-car/2. Road definition/car.js new file mode 100644 index 0000000..5fb3135 --- /dev/null +++ b/Self-driving-car/2. Road definition/car.js @@ -0,0 +1,76 @@ +class Car{ + constructor(x,y,width,height){ + this.x=x; + this.y=y; + this.width=width; + this.height=height; + + this.speed=0; + this.acceleration=0.2; + this.maxSpeed=3; + this.friction=0.05; + this.angle=0; + + this.controls=new Controls(); + } + + update(){ + this.#move(); + } + + #move(){ + if(this.controls.forward){ + this.speed+=this.acceleration; + } + if(this.controls.reverse){ + this.speed-=this.acceleration; + } + + if(this.speed>this.maxSpeed){ + this.speed=this.maxSpeed; + } + if(this.speed<-this.maxSpeed/2){ + this.speed=-this.maxSpeed/2; + } + + if(this.speed>0){ + this.speed-=this.friction; + } + if(this.speed<0){ + this.speed+=this.friction; + } + if(Math.abs(this.speed)0?1:-1; + if(this.controls.left){ + this.angle+=0.03*flip; + } + if(this.controls.right){ + this.angle-=0.03*flip; + } + } + + this.x-=Math.sin(this.angle)*this.speed; + this.y-=Math.cos(this.angle)*this.speed; + } + + draw(ctx){ + ctx.save(); + ctx.translate(this.x,this.y); + ctx.rotate(-this.angle); + + ctx.beginPath(); + ctx.rect( + -this.width/2, + -this.height/2, + this.width, + this.height + ); + ctx.fill(); + + ctx.restore(); + } +} \ No newline at end of file diff --git a/Self-driving-car/2. Road definition/controls.js b/Self-driving-car/2. Road definition/controls.js new file mode 100644 index 0000000..f302887 --- /dev/null +++ b/Self-driving-car/2. Road definition/controls.js @@ -0,0 +1,45 @@ +class Controls{ + constructor(){ + this.forward=false; + this.left=false; + this.right=false; + this.reverse=false; + + this.#addKeyboardListeners(); + } + + #addKeyboardListeners(){ + document.onkeydown=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=true; + break; + case "ArrowRight": + this.right=true; + break; + case "ArrowUp": + this.forward=true; + break; + case "ArrowDown": + this.reverse=true; + break; + } + } + document.onkeyup=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=false; + break; + case "ArrowRight": + this.right=false; + break; + case "ArrowUp": + this.forward=false; + break; + case "ArrowDown": + this.reverse=false; + break; + } + } + } +} \ No newline at end of file diff --git a/Self-driving-car/2. Road definition/index.html b/Self-driving-car/2. Road definition/index.html new file mode 100644 index 0000000..c0113d6 --- /dev/null +++ b/Self-driving-car/2. Road definition/index.html @@ -0,0 +1,14 @@ + + + Self-driving car - No libraries + + + + + + + + + + + \ No newline at end of file diff --git a/Self-driving-car/2. Road definition/main.js b/Self-driving-car/2. Road definition/main.js new file mode 100644 index 0000000..a0ce815 --- /dev/null +++ b/Self-driving-car/2. Road definition/main.js @@ -0,0 +1,23 @@ +const canvas=document.getElementById("myCanvas"); +canvas.width=200; + +const ctx = canvas.getContext("2d"); +const road=new Road(canvas.width/2,canvas.width*0.9); +const car=new Car(road.getLaneCenter(1),100,30,50); + +animate(); + +function animate(){ + car.update(); + + canvas.height=window.innerHeight; + + ctx.save(); + ctx.translate(0,-car.y+canvas.height*0.7); + + road.draw(ctx); + car.draw(ctx); + + ctx.restore(); + requestAnimationFrame(animate); +} \ No newline at end of file diff --git a/Self-driving-car/2. Road definition/road.js b/Self-driving-car/2. Road definition/road.js new file mode 100644 index 0000000..5c824b6 --- /dev/null +++ b/Self-driving-car/2. Road definition/road.js @@ -0,0 +1,56 @@ +class Road{ + constructor(x,width,laneCount=3){ + this.x=x; + this.width=width; + this.laneCount=laneCount; + + this.left=x-width/2; + this.right=x+width/2; + + const infinity=1000000; + this.top=-infinity; + this.bottom=infinity; + + const topLeft={x:this.left,y:this.top}; + const topRight={x:this.right,y:this.top}; + const bottomLeft={x:this.left,y:this.bottom}; + const bottomRight={x:this.right,y:this.bottom}; + this.borders=[ + [topLeft,bottomLeft], + [topRight,bottomRight] + ]; + } + + getLaneCenter(laneIndex){ + const laneWidth=this.width/this.laneCount; + return this.left+laneWidth/2+ + Math.min(laneIndex,this.laneCount-1)*laneWidth; + } + + draw(ctx){ + ctx.lineWidth=5; + ctx.strokeStyle="white"; + + for(let i=1;i<=this.laneCount-1;i++){ + const x=lerp( + this.left, + this.right, + i/this.laneCount + ); + + ctx.setLineDash([20,20]); + ctx.beginPath(); + ctx.moveTo(x,this.top); + ctx.lineTo(x,this.bottom); + ctx.stroke(); + } + + ctx.setLineDash([]); + this.borders.forEach(border=>{ + ctx.beginPath(); + ctx.moveTo(border[0].x,border[0].y); + ctx.lineTo(border[1].x,border[1].y); + ctx.stroke(); + }); + } +} \ No newline at end of file diff --git a/Self-driving-car/2. Road definition/style.css b/Self-driving-car/2. Road definition/style.css new file mode 100644 index 0000000..81d0b00 --- /dev/null +++ b/Self-driving-car/2. Road definition/style.css @@ -0,0 +1,9 @@ +body{ + margin:0; + background:darkgray; + overflow:hidden; + text-align:center; +} +#myCanvas{ + background:lightgray; +} \ No newline at end of file diff --git a/Self-driving-car/2. Road definition/utils.js b/Self-driving-car/2. Road definition/utils.js new file mode 100644 index 0000000..eb88624 --- /dev/null +++ b/Self-driving-car/2. Road definition/utils.js @@ -0,0 +1,3 @@ +function lerp(A,B,t){ + return A+(B-A)*t; +} \ No newline at end of file diff --git a/Self-driving-car/3. Artificial sensors/car.js b/Self-driving-car/3. Artificial sensors/car.js new file mode 100644 index 0000000..49761de --- /dev/null +++ b/Self-driving-car/3. Artificial sensors/car.js @@ -0,0 +1,80 @@ +class Car{ + constructor(x,y,width,height){ + this.x=x; + this.y=y; + this.width=width; + this.height=height; + + this.speed=0; + this.acceleration=0.2; + this.maxSpeed=3; + this.friction=0.05; + this.angle=0; + + this.sensor=new Sensor(this); + this.controls=new Controls(); + } + + update(roadBorders){ + this.#move(); + this.sensor.update(roadBorders); + } + + #move(){ + if(this.controls.forward){ + this.speed+=this.acceleration; + } + if(this.controls.reverse){ + this.speed-=this.acceleration; + } + + if(this.speed>this.maxSpeed){ + this.speed=this.maxSpeed; + } + if(this.speed<-this.maxSpeed/2){ + this.speed=-this.maxSpeed/2; + } + + if(this.speed>0){ + this.speed-=this.friction; + } + if(this.speed<0){ + this.speed+=this.friction; + } + if(Math.abs(this.speed)0?1:-1; + if(this.controls.left){ + this.angle+=0.03*flip; + } + if(this.controls.right){ + this.angle-=0.03*flip; + } + } + + this.x-=Math.sin(this.angle)*this.speed; + this.y-=Math.cos(this.angle)*this.speed; + } + + draw(ctx){ + ctx.save(); + ctx.translate(this.x,this.y); + ctx.rotate(-this.angle); + + ctx.beginPath(); + ctx.rect( + -this.width/2, + -this.height/2, + this.width, + this.height + ); + ctx.fill(); + + ctx.restore(); + + this.sensor.draw(ctx); + } +} \ No newline at end of file diff --git a/Self-driving-car/3. Artificial sensors/controls.js b/Self-driving-car/3. Artificial sensors/controls.js new file mode 100644 index 0000000..f302887 --- /dev/null +++ b/Self-driving-car/3. Artificial sensors/controls.js @@ -0,0 +1,45 @@ +class Controls{ + constructor(){ + this.forward=false; + this.left=false; + this.right=false; + this.reverse=false; + + this.#addKeyboardListeners(); + } + + #addKeyboardListeners(){ + document.onkeydown=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=true; + break; + case "ArrowRight": + this.right=true; + break; + case "ArrowUp": + this.forward=true; + break; + case "ArrowDown": + this.reverse=true; + break; + } + } + document.onkeyup=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=false; + break; + case "ArrowRight": + this.right=false; + break; + case "ArrowUp": + this.forward=false; + break; + case "ArrowDown": + this.reverse=false; + break; + } + } + } +} \ No newline at end of file diff --git a/Self-driving-car/3. Artificial sensors/index.html b/Self-driving-car/3. Artificial sensors/index.html new file mode 100644 index 0000000..b42aa9d --- /dev/null +++ b/Self-driving-car/3. Artificial sensors/index.html @@ -0,0 +1,15 @@ + + + Self-driving car - No libraries + + + + + + + + + + + + \ No newline at end of file diff --git a/Self-driving-car/3. Artificial sensors/main.js b/Self-driving-car/3. Artificial sensors/main.js new file mode 100644 index 0000000..827675c --- /dev/null +++ b/Self-driving-car/3. Artificial sensors/main.js @@ -0,0 +1,23 @@ +const canvas=document.getElementById("myCanvas"); +canvas.width=200; + +const ctx = canvas.getContext("2d"); +const road=new Road(canvas.width/2,canvas.width*0.9); +const car=new Car(road.getLaneCenter(1),100,30,50); + +animate(); + +function animate(){ + car.update(road.borders); + + canvas.height=window.innerHeight; + + ctx.save(); + ctx.translate(0,-car.y+canvas.height*0.7); + + road.draw(ctx); + car.draw(ctx); + + ctx.restore(); + requestAnimationFrame(animate); +} \ No newline at end of file diff --git a/Self-driving-car/3. Artificial sensors/road.js b/Self-driving-car/3. Artificial sensors/road.js new file mode 100644 index 0000000..5c824b6 --- /dev/null +++ b/Self-driving-car/3. Artificial sensors/road.js @@ -0,0 +1,56 @@ +class Road{ + constructor(x,width,laneCount=3){ + this.x=x; + this.width=width; + this.laneCount=laneCount; + + this.left=x-width/2; + this.right=x+width/2; + + const infinity=1000000; + this.top=-infinity; + this.bottom=infinity; + + const topLeft={x:this.left,y:this.top}; + const topRight={x:this.right,y:this.top}; + const bottomLeft={x:this.left,y:this.bottom}; + const bottomRight={x:this.right,y:this.bottom}; + this.borders=[ + [topLeft,bottomLeft], + [topRight,bottomRight] + ]; + } + + getLaneCenter(laneIndex){ + const laneWidth=this.width/this.laneCount; + return this.left+laneWidth/2+ + Math.min(laneIndex,this.laneCount-1)*laneWidth; + } + + draw(ctx){ + ctx.lineWidth=5; + ctx.strokeStyle="white"; + + for(let i=1;i<=this.laneCount-1;i++){ + const x=lerp( + this.left, + this.right, + i/this.laneCount + ); + + ctx.setLineDash([20,20]); + ctx.beginPath(); + ctx.moveTo(x,this.top); + ctx.lineTo(x,this.bottom); + ctx.stroke(); + } + + ctx.setLineDash([]); + this.borders.forEach(border=>{ + ctx.beginPath(); + ctx.moveTo(border[0].x,border[0].y); + ctx.lineTo(border[1].x,border[1].y); + ctx.stroke(); + }); + } +} \ No newline at end of file diff --git a/Self-driving-car/3. Artificial sensors/sensor.js b/Self-driving-car/3. Artificial sensors/sensor.js new file mode 100644 index 0000000..699515f --- /dev/null +++ b/Self-driving-car/3. Artificial sensors/sensor.js @@ -0,0 +1,100 @@ +class Sensor{ + constructor(car){ + this.car=car; + this.rayCount=5; + this.rayLength=150; + this.raySpread=Math.PI/2; + + this.rays=[]; + this.readings=[]; + } + + update(roadBorders){ + this.#castRays(); + this.readings=[]; + for(let i=0;ie.offset); + const minOffset=Math.min(...offsets); + return touches.find(e=>e.offset==minOffset); + } + } + + #castRays(){ + this.rays=[]; + for(let i=0;i=0 && t<=1 && u>=0 && u<=1){ + return { + x:lerp(A.x,B.x,t), + y:lerp(A.y,B.y,t), + offset:t + } + } + } + + return null; +} \ No newline at end of file diff --git a/Self-driving-car/4. Collision detection/car.js b/Self-driving-car/4. Collision detection/car.js new file mode 100644 index 0000000..6566c3a --- /dev/null +++ b/Self-driving-car/4. Collision detection/car.js @@ -0,0 +1,114 @@ +class Car{ + constructor(x,y,width,height){ + this.x=x; + this.y=y; + this.width=width; + this.height=height; + + this.speed=0; + this.acceleration=0.2; + this.maxSpeed=3; + this.friction=0.05; + this.angle=0; + this.damaged=false; + + this.sensor=new Sensor(this); + this.controls=new Controls(); + } + + update(roadBorders){ + if(!this.damaged){ + this.#move(); + this.polygon=this.#createPolygon(); + this.damaged=this.#assessDamage(roadBorders); + } + this.sensor.update(roadBorders); + } + + #assessDamage(roadBorders){ + for(let i=0;ithis.maxSpeed){ + this.speed=this.maxSpeed; + } + if(this.speed<-this.maxSpeed/2){ + this.speed=-this.maxSpeed/2; + } + + if(this.speed>0){ + this.speed-=this.friction; + } + if(this.speed<0){ + this.speed+=this.friction; + } + if(Math.abs(this.speed)0?1:-1; + if(this.controls.left){ + this.angle+=0.03*flip; + } + if(this.controls.right){ + this.angle-=0.03*flip; + } + } + + this.x-=Math.sin(this.angle)*this.speed; + this.y-=Math.cos(this.angle)*this.speed; + } + + draw(ctx){ + if(this.damaged){ + ctx.fillStyle="gray"; + }else{ + ctx.fillStyle="black"; + } + ctx.beginPath(); + ctx.moveTo(this.polygon[0].x,this.polygon[0].y); + for(let i=1;i{ + switch(event.key){ + case "ArrowLeft": + this.left=true; + break; + case "ArrowRight": + this.right=true; + break; + case "ArrowUp": + this.forward=true; + break; + case "ArrowDown": + this.reverse=true; + break; + } + } + document.onkeyup=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=false; + break; + case "ArrowRight": + this.right=false; + break; + case "ArrowUp": + this.forward=false; + break; + case "ArrowDown": + this.reverse=false; + break; + } + } + } +} \ No newline at end of file diff --git a/Self-driving-car/4. Collision detection/index.html b/Self-driving-car/4. Collision detection/index.html new file mode 100644 index 0000000..b42aa9d --- /dev/null +++ b/Self-driving-car/4. Collision detection/index.html @@ -0,0 +1,15 @@ + + + Self-driving car - No libraries + + + + + + + + + + + + \ No newline at end of file diff --git a/Self-driving-car/4. Collision detection/main.js b/Self-driving-car/4. Collision detection/main.js new file mode 100644 index 0000000..827675c --- /dev/null +++ b/Self-driving-car/4. Collision detection/main.js @@ -0,0 +1,23 @@ +const canvas=document.getElementById("myCanvas"); +canvas.width=200; + +const ctx = canvas.getContext("2d"); +const road=new Road(canvas.width/2,canvas.width*0.9); +const car=new Car(road.getLaneCenter(1),100,30,50); + +animate(); + +function animate(){ + car.update(road.borders); + + canvas.height=window.innerHeight; + + ctx.save(); + ctx.translate(0,-car.y+canvas.height*0.7); + + road.draw(ctx); + car.draw(ctx); + + ctx.restore(); + requestAnimationFrame(animate); +} \ No newline at end of file diff --git a/Self-driving-car/4. Collision detection/road.js b/Self-driving-car/4. Collision detection/road.js new file mode 100644 index 0000000..5c824b6 --- /dev/null +++ b/Self-driving-car/4. Collision detection/road.js @@ -0,0 +1,56 @@ +class Road{ + constructor(x,width,laneCount=3){ + this.x=x; + this.width=width; + this.laneCount=laneCount; + + this.left=x-width/2; + this.right=x+width/2; + + const infinity=1000000; + this.top=-infinity; + this.bottom=infinity; + + const topLeft={x:this.left,y:this.top}; + const topRight={x:this.right,y:this.top}; + const bottomLeft={x:this.left,y:this.bottom}; + const bottomRight={x:this.right,y:this.bottom}; + this.borders=[ + [topLeft,bottomLeft], + [topRight,bottomRight] + ]; + } + + getLaneCenter(laneIndex){ + const laneWidth=this.width/this.laneCount; + return this.left+laneWidth/2+ + Math.min(laneIndex,this.laneCount-1)*laneWidth; + } + + draw(ctx){ + ctx.lineWidth=5; + ctx.strokeStyle="white"; + + for(let i=1;i<=this.laneCount-1;i++){ + const x=lerp( + this.left, + this.right, + i/this.laneCount + ); + + ctx.setLineDash([20,20]); + ctx.beginPath(); + ctx.moveTo(x,this.top); + ctx.lineTo(x,this.bottom); + ctx.stroke(); + } + + ctx.setLineDash([]); + this.borders.forEach(border=>{ + ctx.beginPath(); + ctx.moveTo(border[0].x,border[0].y); + ctx.lineTo(border[1].x,border[1].y); + ctx.stroke(); + }); + } +} \ No newline at end of file diff --git a/Self-driving-car/4. Collision detection/sensor.js b/Self-driving-car/4. Collision detection/sensor.js new file mode 100644 index 0000000..699515f --- /dev/null +++ b/Self-driving-car/4. Collision detection/sensor.js @@ -0,0 +1,100 @@ +class Sensor{ + constructor(car){ + this.car=car; + this.rayCount=5; + this.rayLength=150; + this.raySpread=Math.PI/2; + + this.rays=[]; + this.readings=[]; + } + + update(roadBorders){ + this.#castRays(); + this.readings=[]; + for(let i=0;ie.offset); + const minOffset=Math.min(...offsets); + return touches.find(e=>e.offset==minOffset); + } + } + + #castRays(){ + this.rays=[]; + for(let i=0;i=0 && t<=1 && u>=0 && u<=1){ + return { + x:lerp(A.x,B.x,t), + y:lerp(A.y,B.y,t), + offset:t + } + } + } + + return null; +} + +function polysIntersect(poly1, poly2){ + for(let i=0;ithis.maxSpeed){ + this.speed=this.maxSpeed; + } + if(this.speed<-this.maxSpeed/2){ + this.speed=-this.maxSpeed/2; + } + + if(this.speed>0){ + this.speed-=this.friction; + } + if(this.speed<0){ + this.speed+=this.friction; + } + if(Math.abs(this.speed)0?1:-1; + if(this.controls.left){ + this.angle+=0.03*flip; + } + if(this.controls.right){ + this.angle-=0.03*flip; + } + } + + this.x-=Math.sin(this.angle)*this.speed; + this.y-=Math.cos(this.angle)*this.speed; + } + + draw(ctx,color){ + if(this.damaged){ + ctx.fillStyle="gray"; + }else{ + ctx.fillStyle=color; + } + ctx.beginPath(); + ctx.moveTo(this.polygon[0].x,this.polygon[0].y); + for(let i=1;i{ + switch(event.key){ + case "ArrowLeft": + this.left=true; + break; + case "ArrowRight": + this.right=true; + break; + case "ArrowUp": + this.forward=true; + break; + case "ArrowDown": + this.reverse=true; + break; + } + } + document.onkeyup=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=false; + break; + case "ArrowRight": + this.right=false; + break; + case "ArrowUp": + this.forward=false; + break; + case "ArrowDown": + this.reverse=false; + break; + } + } + } +} \ No newline at end of file diff --git a/Self-driving-car/5. Traffic simulation/index.html b/Self-driving-car/5. Traffic simulation/index.html new file mode 100644 index 0000000..b42aa9d --- /dev/null +++ b/Self-driving-car/5. Traffic simulation/index.html @@ -0,0 +1,15 @@ + + + Self-driving car - No libraries + + + + + + + + + + + + \ No newline at end of file diff --git a/Self-driving-car/5. Traffic simulation/main.js b/Self-driving-car/5. Traffic simulation/main.js new file mode 100644 index 0000000..b5c622c --- /dev/null +++ b/Self-driving-car/5. Traffic simulation/main.js @@ -0,0 +1,32 @@ +const canvas=document.getElementById("myCanvas"); +canvas.width=200; + +const ctx = canvas.getContext("2d"); +const road=new Road(canvas.width/2,canvas.width*0.9); +const car=new Car(road.getLaneCenter(1),100,30,50,"KEYS"); +const traffic=[ + new Car(road.getLaneCenter(1),-100,30,50,"DUMMY",2) +]; + +animate(); + +function animate(){ + for(let i=0;i{ + ctx.beginPath(); + ctx.moveTo(border[0].x,border[0].y); + ctx.lineTo(border[1].x,border[1].y); + ctx.stroke(); + }); + } +} \ No newline at end of file diff --git a/Self-driving-car/5. Traffic simulation/sensor.js b/Self-driving-car/5. Traffic simulation/sensor.js new file mode 100644 index 0000000..d6c8ced --- /dev/null +++ b/Self-driving-car/5. Traffic simulation/sensor.js @@ -0,0 +1,119 @@ +class Sensor{ + constructor(car){ + this.car=car; + this.rayCount=5; + this.rayLength=150; + this.raySpread=Math.PI/2; + + this.rays=[]; + this.readings=[]; + } + + update(roadBorders,traffic){ + this.#castRays(); + this.readings=[]; + for(let i=0;ie.offset); + const minOffset=Math.min(...offsets); + return touches.find(e=>e.offset==minOffset); + } + } + + #castRays(){ + this.rays=[]; + for(let i=0;i=0 && t<=1 && u>=0 && u<=1){ + return { + x:lerp(A.x,B.x,t), + y:lerp(A.y,B.y,t), + offset:t + } + } + } + + return null; +} + +function polysIntersect(poly1, poly2){ + for(let i=0;is==null?0:1-s.offset + ); + const outputs=NeuralNetwork.feedForward(offsets,this.brain); + + if(this.useBrain){ + this.controls.forward=outputs[0]; + this.controls.left=outputs[1]; + this.controls.right=outputs[2]; + this.controls.reverse=outputs[3]; + } + } + } + + #assessDamage(roadBorders,traffic){ + for(let i=0;ithis.maxSpeed){ + this.speed=this.maxSpeed; + } + if(this.speed<-this.maxSpeed/2){ + this.speed=-this.maxSpeed/2; + } + + if(this.speed>0){ + this.speed-=this.friction; + } + if(this.speed<0){ + this.speed+=this.friction; + } + if(Math.abs(this.speed)0?1:-1; + if(this.controls.left){ + this.angle+=0.03*flip; + } + if(this.controls.right){ + this.angle-=0.03*flip; + } + } + + this.x-=Math.sin(this.angle)*this.speed; + this.y-=Math.cos(this.angle)*this.speed; + } + + draw(ctx,color){ + if(this.damaged){ + ctx.fillStyle="gray"; + }else{ + ctx.fillStyle=color; + } + ctx.beginPath(); + ctx.moveTo(this.polygon[0].x,this.polygon[0].y); + for(let i=1;i{ + switch(event.key){ + case "ArrowLeft": + this.left=true; + break; + case "ArrowRight": + this.right=true; + break; + case "ArrowUp": + this.forward=true; + break; + case "ArrowDown": + this.reverse=true; + break; + } + } + document.onkeyup=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=false; + break; + case "ArrowRight": + this.right=false; + break; + case "ArrowUp": + this.forward=false; + break; + case "ArrowDown": + this.reverse=false; + break; + } + } + } +} \ No newline at end of file diff --git a/Self-driving-car/6. Neural network/index.html b/Self-driving-car/6. Neural network/index.html new file mode 100644 index 0000000..1c31b4f --- /dev/null +++ b/Self-driving-car/6. Neural network/index.html @@ -0,0 +1,17 @@ + + + Self-driving car - No libraries + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Self-driving-car/6. Neural network/main.js b/Self-driving-car/6. Neural network/main.js new file mode 100644 index 0000000..81ce717 --- /dev/null +++ b/Self-driving-car/6. Neural network/main.js @@ -0,0 +1,38 @@ +const carCanvas=document.getElementById("carCanvas"); +carCanvas.width=200; +const networkCanvas=document.getElementById("networkCanvas"); +networkCanvas.width=300; + +const carCtx = carCanvas.getContext("2d"); +const networkCtx = networkCanvas.getContext("2d"); + +const road=new Road(carCanvas.width/2,carCanvas.width*0.9); +const car=new Car(road.getLaneCenter(1),100,30,50,"AI"); +const traffic=[ + new Car(road.getLaneCenter(1),-100,30,50,"DUMMY",2) +]; + +animate(); + +function animate(){ + for(let i=0;ilevel.biases[i]){ + level.outputs[i]=1; + }else{ + level.outputs[i]=0; + } + } + + return level.outputs; + } +} \ No newline at end of file diff --git a/Self-driving-car/6. Neural network/road.js b/Self-driving-car/6. Neural network/road.js new file mode 100644 index 0000000..5c824b6 --- /dev/null +++ b/Self-driving-car/6. Neural network/road.js @@ -0,0 +1,56 @@ +class Road{ + constructor(x,width,laneCount=3){ + this.x=x; + this.width=width; + this.laneCount=laneCount; + + this.left=x-width/2; + this.right=x+width/2; + + const infinity=1000000; + this.top=-infinity; + this.bottom=infinity; + + const topLeft={x:this.left,y:this.top}; + const topRight={x:this.right,y:this.top}; + const bottomLeft={x:this.left,y:this.bottom}; + const bottomRight={x:this.right,y:this.bottom}; + this.borders=[ + [topLeft,bottomLeft], + [topRight,bottomRight] + ]; + } + + getLaneCenter(laneIndex){ + const laneWidth=this.width/this.laneCount; + return this.left+laneWidth/2+ + Math.min(laneIndex,this.laneCount-1)*laneWidth; + } + + draw(ctx){ + ctx.lineWidth=5; + ctx.strokeStyle="white"; + + for(let i=1;i<=this.laneCount-1;i++){ + const x=lerp( + this.left, + this.right, + i/this.laneCount + ); + + ctx.setLineDash([20,20]); + ctx.beginPath(); + ctx.moveTo(x,this.top); + ctx.lineTo(x,this.bottom); + ctx.stroke(); + } + + ctx.setLineDash([]); + this.borders.forEach(border=>{ + ctx.beginPath(); + ctx.moveTo(border[0].x,border[0].y); + ctx.lineTo(border[1].x,border[1].y); + ctx.stroke(); + }); + } +} \ No newline at end of file diff --git a/Self-driving-car/6. Neural network/sensor.js b/Self-driving-car/6. Neural network/sensor.js new file mode 100644 index 0000000..d6c8ced --- /dev/null +++ b/Self-driving-car/6. Neural network/sensor.js @@ -0,0 +1,119 @@ +class Sensor{ + constructor(car){ + this.car=car; + this.rayCount=5; + this.rayLength=150; + this.raySpread=Math.PI/2; + + this.rays=[]; + this.readings=[]; + } + + update(roadBorders,traffic){ + this.#castRays(); + this.readings=[]; + for(let i=0;ie.offset); + const minOffset=Math.min(...offsets); + return touches.find(e=>e.offset==minOffset); + } + } + + #castRays(){ + this.rays=[]; + for(let i=0;i=0 && t<=1 && u>=0 && u<=1){ + return { + x:lerp(A.x,B.x,t), + y:lerp(A.y,B.y,t), + offset:t + } + } + } + + return null; +} + +function polysIntersect(poly1, poly2){ + for(let i=0;is==null?0:1-s.offset + ); + const outputs=NeuralNetwork.feedForward(offsets,this.brain); + + if(this.useBrain){ + this.controls.forward=outputs[0]; + this.controls.left=outputs[1]; + this.controls.right=outputs[2]; + this.controls.reverse=outputs[3]; + } + } + } + + #assessDamage(roadBorders,traffic){ + for(let i=0;ithis.maxSpeed){ + this.speed=this.maxSpeed; + } + if(this.speed<-this.maxSpeed/2){ + this.speed=-this.maxSpeed/2; + } + + if(this.speed>0){ + this.speed-=this.friction; + } + if(this.speed<0){ + this.speed+=this.friction; + } + if(Math.abs(this.speed)0?1:-1; + if(this.controls.left){ + this.angle+=0.03*flip; + } + if(this.controls.right){ + this.angle-=0.03*flip; + } + } + + this.x-=Math.sin(this.angle)*this.speed; + this.y-=Math.cos(this.angle)*this.speed; + } + + draw(ctx,color){ + if(this.damaged){ + ctx.fillStyle="gray"; + }else{ + ctx.fillStyle=color; + } + ctx.beginPath(); + ctx.moveTo(this.polygon[0].x,this.polygon[0].y); + for(let i=1;i{ + switch(event.key){ + case "ArrowLeft": + this.left=true; + break; + case "ArrowRight": + this.right=true; + break; + case "ArrowUp": + this.forward=true; + break; + case "ArrowDown": + this.reverse=true; + break; + } + } + document.onkeyup=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=false; + break; + case "ArrowRight": + this.right=false; + break; + case "ArrowUp": + this.forward=false; + break; + case "ArrowDown": + this.reverse=false; + break; + } + } + } +} \ No newline at end of file diff --git a/Self-driving-car/7. Visualizing neural networks/index.html b/Self-driving-car/7. Visualizing neural networks/index.html new file mode 100644 index 0000000..e9396ef --- /dev/null +++ b/Self-driving-car/7. Visualizing neural networks/index.html @@ -0,0 +1,18 @@ + + + Self-driving car - No libraries + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Self-driving-car/7. Visualizing neural networks/main.js b/Self-driving-car/7. Visualizing neural networks/main.js new file mode 100644 index 0000000..7d2974b --- /dev/null +++ b/Self-driving-car/7. Visualizing neural networks/main.js @@ -0,0 +1,40 @@ +const carCanvas=document.getElementById("carCanvas"); +carCanvas.width=200; +const networkCanvas=document.getElementById("networkCanvas"); +networkCanvas.width=300; + +const carCtx = carCanvas.getContext("2d"); +const networkCtx = networkCanvas.getContext("2d"); + +const road=new Road(carCanvas.width/2,carCanvas.width*0.9); +const car=new Car(road.getLaneCenter(1),100,30,50,"AI"); +const traffic=[ + new Car(road.getLaneCenter(1),-100,30,50,"DUMMY",2) +]; + +animate(); + +function animate(time){ + for(let i=0;ilevel.biases[i]){ + level.outputs[i]=1; + }else{ + level.outputs[i]=0; + } + } + + return level.outputs; + } +} \ No newline at end of file diff --git a/Self-driving-car/7. Visualizing neural networks/road.js b/Self-driving-car/7. Visualizing neural networks/road.js new file mode 100644 index 0000000..5c824b6 --- /dev/null +++ b/Self-driving-car/7. Visualizing neural networks/road.js @@ -0,0 +1,56 @@ +class Road{ + constructor(x,width,laneCount=3){ + this.x=x; + this.width=width; + this.laneCount=laneCount; + + this.left=x-width/2; + this.right=x+width/2; + + const infinity=1000000; + this.top=-infinity; + this.bottom=infinity; + + const topLeft={x:this.left,y:this.top}; + const topRight={x:this.right,y:this.top}; + const bottomLeft={x:this.left,y:this.bottom}; + const bottomRight={x:this.right,y:this.bottom}; + this.borders=[ + [topLeft,bottomLeft], + [topRight,bottomRight] + ]; + } + + getLaneCenter(laneIndex){ + const laneWidth=this.width/this.laneCount; + return this.left+laneWidth/2+ + Math.min(laneIndex,this.laneCount-1)*laneWidth; + } + + draw(ctx){ + ctx.lineWidth=5; + ctx.strokeStyle="white"; + + for(let i=1;i<=this.laneCount-1;i++){ + const x=lerp( + this.left, + this.right, + i/this.laneCount + ); + + ctx.setLineDash([20,20]); + ctx.beginPath(); + ctx.moveTo(x,this.top); + ctx.lineTo(x,this.bottom); + ctx.stroke(); + } + + ctx.setLineDash([]); + this.borders.forEach(border=>{ + ctx.beginPath(); + ctx.moveTo(border[0].x,border[0].y); + ctx.lineTo(border[1].x,border[1].y); + ctx.stroke(); + }); + } +} \ No newline at end of file diff --git a/Self-driving-car/7. Visualizing neural networks/sensor.js b/Self-driving-car/7. Visualizing neural networks/sensor.js new file mode 100644 index 0000000..d6c8ced --- /dev/null +++ b/Self-driving-car/7. Visualizing neural networks/sensor.js @@ -0,0 +1,119 @@ +class Sensor{ + constructor(car){ + this.car=car; + this.rayCount=5; + this.rayLength=150; + this.raySpread=Math.PI/2; + + this.rays=[]; + this.readings=[]; + } + + update(roadBorders,traffic){ + this.#castRays(); + this.readings=[]; + for(let i=0;ie.offset); + const minOffset=Math.min(...offsets); + return touches.find(e=>e.offset==minOffset); + } + } + + #castRays(){ + this.rays=[]; + for(let i=0;i=0 && t<=1 && u>=0 && u<=1){ + return { + x:lerp(A.x,B.x,t), + y:lerp(A.y,B.y,t), + offset:t + } + } + } + + return null; +} + +function polysIntersect(poly1, poly2){ + for(let i=0;i0?0:255; + return "rgba("+R+","+G+","+B+","+alpha+")"; +} + \ No newline at end of file diff --git a/Self-driving-car/7. Visualizing neural networks/visualizer.js b/Self-driving-car/7. Visualizing neural networks/visualizer.js new file mode 100644 index 0000000000000000000000000000000000000000..96d8c7848ea2630f8449294fb26d26f3352db451 GIT binary patch literal 7098 zcmeHM+fEcg5UoeW_zwgh*ky+WB`Q%DgE3JPBnF9^5FTI`WMEmz?jR`PKYj39)Kk+G zQ{8mWOmllO6PRmPbyuA_RbBh{PnY_%K_eXF^odfO4{_he)lb@@A)U~D8pAttj3~p~ z3~#%5(!=`=I-+HKnc@5m_j}a9yNr%0p@H?h>Bth9U5pz*Zw86`kT;~SkUyXfJ*HWD zZt3@p=|jslMt7{y)#EbgJ%}E4gt_&gZ3iRGI@>sJV7}k+e?)EALB5!_W;8{QYOH1l zt4U#joqR=p4f>mq4(+v&)xJYlpWa#;wd@(kgKd1hg>~{MUMb%VFjuyQvA0j_c8-fi z{x$nJh2?Byl*yf@hmf7p0!A?!QkupQ!czH4SI<0dJm2ynOC-pd*Ej@D8nwQbQQC^r z%4*uyNtDD{#FNjuqR~Cqw{QoReHbNMbiIT}+KAGadCAyk@Z=1vT7RC5gk~*W%@Q<< zeu=CR{F~7dX2UaioyYJF=CwvoVevUyhfY72h$J6tw$Hh72~thOgm}?L{~BhpUeni% zO=iACAKTJlAY@D=;n z)JGp+3C_HYN``V}>|aPs!5QvX5RpCD z=n(A0HPw8ea&S3=^XK(3lAhTyBwv5b`tw6!8Q%T1^NbYBRN_0{1$Kc3-bLz|=RKw2 z7;WnW)=TL986URk1HB{OZB<3TXxoO*`ZzQ$C!m*i#$6zGBH%}N#UiH~ZKC-yY%XKt zY&4bE>Q7*&>$jC*|00Gp_nQcg^+ec${y6oqURjjc9PDQ1dYS+7ab{~zfWA<6yxmAM z8RUPAjh}aRbc~f*=Qg9uM$c8_%NIE=uU&>utn%whI*x(#9*J=ZW>x}FT{FY2o@M5O39G?0P)drz^&Nv)b*R&p71x$DYMRUV_N zTtv?1y#;rVClJNlpX7JL${Ze&_zE=uTTO7xa`&O5hl6)CRkeXDS84=}ub5iHm8WrF z%RIu~FwIvVKS%D!b4Q)~a~JEaDb%*y_iJJYJAqx^F}k{o`L2$CIf&P0s;^a8lYLl) zuOzPu4Ii`u^W(lGcMHq&r)x{`vF0k%;f#}`eRBJ&@>fXq(~J8Wo^$cbj&DaVNZ>vU zS9rYB=la~gulIAn5Mwg1#}MPk^O4oP^+J9bGZj6B@{U5W3cKp7-vy89dUKasEM>ag SCYsz|Pr|)z7sJMLr}PgiU!J=F literal 0 HcmV?d00001 diff --git a/Self-driving-car/8. Optimizing neural networks/car.js b/Self-driving-car/8. Optimizing neural networks/car.js new file mode 100644 index 0000000..74709bc --- /dev/null +++ b/Self-driving-car/8. Optimizing neural networks/car.js @@ -0,0 +1,141 @@ +class Car{ + constructor(x,y,width,height,controlType,maxSpeed=3){ + this.x=x; + this.y=y; + this.width=width; + this.height=height; + + this.speed=0; + this.acceleration=0.2; + this.maxSpeed=maxSpeed; + this.friction=0.05; + this.angle=0; + this.damaged=false; + + this.useBrain=controlType=="AI"; + + if(controlType!="DUMMY"){ + this.sensor=new Sensor(this); + this.brain=new NeuralNetwork( + [this.sensor.rayCount,6,4] + ); + } + this.controls=new Controls(controlType); + } + + update(roadBorders,traffic){ + if(!this.damaged){ + this.#move(); + this.polygon=this.#createPolygon(); + this.damaged=this.#assessDamage(roadBorders,traffic); + } + if(this.sensor){ + this.sensor.update(roadBorders,traffic); + const offsets=this.sensor.readings.map( + s=>s==null?0:1-s.offset + ); + const outputs=NeuralNetwork.feedForward(offsets,this.brain); + + if(this.useBrain){ + this.controls.forward=outputs[0]; + this.controls.left=outputs[1]; + this.controls.right=outputs[2]; + this.controls.reverse=outputs[3]; + } + } + } + + #assessDamage(roadBorders,traffic){ + for(let i=0;ithis.maxSpeed){ + this.speed=this.maxSpeed; + } + if(this.speed<-this.maxSpeed/2){ + this.speed=-this.maxSpeed/2; + } + + if(this.speed>0){ + this.speed-=this.friction; + } + if(this.speed<0){ + this.speed+=this.friction; + } + if(Math.abs(this.speed)0?1:-1; + if(this.controls.left){ + this.angle+=0.03*flip; + } + if(this.controls.right){ + this.angle-=0.03*flip; + } + } + + this.x-=Math.sin(this.angle)*this.speed; + this.y-=Math.cos(this.angle)*this.speed; + } + + draw(ctx,color,drawSensor=false){ + if(this.damaged){ + ctx.fillStyle="gray"; + }else{ + ctx.fillStyle=color; + } + ctx.beginPath(); + ctx.moveTo(this.polygon[0].x,this.polygon[0].y); + for(let i=1;i{ + switch(event.key){ + case "ArrowLeft": + this.left=true; + break; + case "ArrowRight": + this.right=true; + break; + case "ArrowUp": + this.forward=true; + break; + case "ArrowDown": + this.reverse=true; + break; + } + } + document.onkeyup=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=false; + break; + case "ArrowRight": + this.right=false; + break; + case "ArrowUp": + this.forward=false; + break; + case "ArrowDown": + this.reverse=false; + break; + } + } + } +} \ No newline at end of file diff --git a/Self-driving-car/8. Optimizing neural networks/index.html b/Self-driving-car/8. Optimizing neural networks/index.html new file mode 100644 index 0000000..e48ea0f --- /dev/null +++ b/Self-driving-car/8. Optimizing neural networks/index.html @@ -0,0 +1,22 @@ + + + Self-driving car - No libraries + + + + +
+ + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/Self-driving-car/8. Optimizing neural networks/main.js b/Self-driving-car/8. Optimizing neural networks/main.js new file mode 100644 index 0000000..69c1235 --- /dev/null +++ b/Self-driving-car/8. Optimizing neural networks/main.js @@ -0,0 +1,87 @@ +const carCanvas=document.getElementById("carCanvas"); +carCanvas.width=200; +const networkCanvas=document.getElementById("networkCanvas"); +networkCanvas.width=300; + +const carCtx = carCanvas.getContext("2d"); +const networkCtx = networkCanvas.getContext("2d"); + +const road=new Road(carCanvas.width/2,carCanvas.width*0.9); + +const N=1; +const cars=generateCars(N); +let bestCar=cars[0]; +if(localStorage.getItem("bestBrain")){ + for(let i=0;ic.y==Math.min( + ...cars.map(c=>c.y) + )); + + carCanvas.height=window.innerHeight; + networkCanvas.height=window.innerHeight; + + carCtx.save(); + carCtx.translate(0,-bestCar.y+carCanvas.height*0.7); + + road.draw(carCtx); + for(let i=0;i { + for(let i=0;ilevel.biases[i]){ + level.outputs[i]=1; + }else{ + level.outputs[i]=0; + } + } + + return level.outputs; + } +} \ No newline at end of file diff --git a/Self-driving-car/8. Optimizing neural networks/road.js b/Self-driving-car/8. Optimizing neural networks/road.js new file mode 100644 index 0000000..5c824b6 --- /dev/null +++ b/Self-driving-car/8. Optimizing neural networks/road.js @@ -0,0 +1,56 @@ +class Road{ + constructor(x,width,laneCount=3){ + this.x=x; + this.width=width; + this.laneCount=laneCount; + + this.left=x-width/2; + this.right=x+width/2; + + const infinity=1000000; + this.top=-infinity; + this.bottom=infinity; + + const topLeft={x:this.left,y:this.top}; + const topRight={x:this.right,y:this.top}; + const bottomLeft={x:this.left,y:this.bottom}; + const bottomRight={x:this.right,y:this.bottom}; + this.borders=[ + [topLeft,bottomLeft], + [topRight,bottomRight] + ]; + } + + getLaneCenter(laneIndex){ + const laneWidth=this.width/this.laneCount; + return this.left+laneWidth/2+ + Math.min(laneIndex,this.laneCount-1)*laneWidth; + } + + draw(ctx){ + ctx.lineWidth=5; + ctx.strokeStyle="white"; + + for(let i=1;i<=this.laneCount-1;i++){ + const x=lerp( + this.left, + this.right, + i/this.laneCount + ); + + ctx.setLineDash([20,20]); + ctx.beginPath(); + ctx.moveTo(x,this.top); + ctx.lineTo(x,this.bottom); + ctx.stroke(); + } + + ctx.setLineDash([]); + this.borders.forEach(border=>{ + ctx.beginPath(); + ctx.moveTo(border[0].x,border[0].y); + ctx.lineTo(border[1].x,border[1].y); + ctx.stroke(); + }); + } +} \ No newline at end of file diff --git a/Self-driving-car/8. Optimizing neural networks/sensor.js b/Self-driving-car/8. Optimizing neural networks/sensor.js new file mode 100644 index 0000000..d6c8ced --- /dev/null +++ b/Self-driving-car/8. Optimizing neural networks/sensor.js @@ -0,0 +1,119 @@ +class Sensor{ + constructor(car){ + this.car=car; + this.rayCount=5; + this.rayLength=150; + this.raySpread=Math.PI/2; + + this.rays=[]; + this.readings=[]; + } + + update(roadBorders,traffic){ + this.#castRays(); + this.readings=[]; + for(let i=0;ie.offset); + const minOffset=Math.min(...offsets); + return touches.find(e=>e.offset==minOffset); + } + } + + #castRays(){ + this.rays=[]; + for(let i=0;i=0 && t<=1 && u>=0 && u<=1){ + return { + x:lerp(A.x,B.x,t), + y:lerp(A.y,B.y,t), + offset:t + } + } + } + + return null; +} + +function polysIntersect(poly1, poly2){ + for(let i=0;i0?0:255; + return "rgba("+R+","+G+","+B+","+alpha+")"; +} + \ No newline at end of file diff --git a/Self-driving-car/8. Optimizing neural networks/visualizer.js b/Self-driving-car/8. Optimizing neural networks/visualizer.js new file mode 100644 index 0000000000000000000000000000000000000000..96d8c7848ea2630f8449294fb26d26f3352db451 GIT binary patch literal 7098 zcmeHM+fEcg5UoeW_zwgh*ky+WB`Q%DgE3JPBnF9^5FTI`WMEmz?jR`PKYj39)Kk+G zQ{8mWOmllO6PRmPbyuA_RbBh{PnY_%K_eXF^odfO4{_he)lb@@A)U~D8pAttj3~p~ z3~#%5(!=`=I-+HKnc@5m_j}a9yNr%0p@H?h>Bth9U5pz*Zw86`kT;~SkUyXfJ*HWD zZt3@p=|jslMt7{y)#EbgJ%}E4gt_&gZ3iRGI@>sJV7}k+e?)EALB5!_W;8{QYOH1l zt4U#joqR=p4f>mq4(+v&)xJYlpWa#;wd@(kgKd1hg>~{MUMb%VFjuyQvA0j_c8-fi z{x$nJh2?Byl*yf@hmf7p0!A?!QkupQ!czH4SI<0dJm2ynOC-pd*Ej@D8nwQbQQC^r z%4*uyNtDD{#FNjuqR~Cqw{QoReHbNMbiIT}+KAGadCAyk@Z=1vT7RC5gk~*W%@Q<< zeu=CR{F~7dX2UaioyYJF=CwvoVevUyhfY72h$J6tw$Hh72~thOgm}?L{~BhpUeni% zO=iACAKTJlAY@D=;n z)JGp+3C_HYN``V}>|aPs!5QvX5RpCD z=n(A0HPw8ea&S3=^XK(3lAhTyBwv5b`tw6!8Q%T1^NbYBRN_0{1$Kc3-bLz|=RKw2 z7;WnW)=TL986URk1HB{OZB<3TXxoO*`ZzQ$C!m*i#$6zGBH%}N#UiH~ZKC-yY%XKt zY&4bE>Q7*&>$jC*|00Gp_nQcg^+ec${y6oqURjjc9PDQ1dYS+7ab{~zfWA<6yxmAM z8RUPAjh}aRbc~f*=Qg9uM$c8_%NIE=uU&>utn%whI*x(#9*J=ZW>x}FT{FY2o@M5O39G?0P)drz^&Nv)b*R&p71x$DYMRUV_N zTtv?1y#;rVClJNlpX7JL${Ze&_zE=uTTO7xa`&O5hl6)CRkeXDS84=}ub5iHm8WrF z%RIu~FwIvVKS%D!b4Q)~a~JEaDb%*y_iJJYJAqx^F}k{o`L2$CIf&P0s;^a8lYLl) zuOzPu4Ii`u^W(lGcMHq&r)x{`vF0k%;f#}`eRBJ&@>fXq(~J8Wo^$cbj&DaVNZ>vU zS9rYB=la~gulIAn5Mwg1#}MPk^O4oP^+J9bGZj6B@{U5W3cKp7-vy89dUKasEM>ag SCYsz|Pr|)z7sJMLr}PgiU!J=F literal 0 HcmV?d00001 diff --git a/Self-driving-car/9. Fine-tuning/car.js b/Self-driving-car/9. Fine-tuning/car.js new file mode 100644 index 0000000..34ec7f8 --- /dev/null +++ b/Self-driving-car/9. Fine-tuning/car.js @@ -0,0 +1,165 @@ +class Car{ + constructor(x,y,width,height,controlType,maxSpeed=3,color="blue"){ + this.x=x; + this.y=y; + this.width=width; + this.height=height; + + this.speed=0; + this.acceleration=0.2; + this.maxSpeed=maxSpeed; + this.friction=0.05; + this.angle=0; + this.damaged=false; + + this.useBrain=controlType=="AI"; + + if(controlType!="DUMMY"){ + this.sensor=new Sensor(this); + this.brain=new NeuralNetwork( + [this.sensor.rayCount,6,4] + ); + } + this.controls=new Controls(controlType); + + this.img=new Image(); + this.img.src="car.png" + + this.mask=document.createElement("canvas"); + this.mask.width=width; + this.mask.height=height; + + const maskCtx=this.mask.getContext("2d"); + this.img.onload=()=>{ + maskCtx.fillStyle=color; + maskCtx.rect(0,0,this.width,this.height); + maskCtx.fill(); + + maskCtx.globalCompositeOperation="destination-atop"; + maskCtx.drawImage(this.img,0,0,this.width,this.height); + } + } + + update(roadBorders,traffic){ + if(!this.damaged){ + this.#move(); + this.polygon=this.#createPolygon(); + this.damaged=this.#assessDamage(roadBorders,traffic); + } + if(this.sensor){ + this.sensor.update(roadBorders,traffic); + const offsets=this.sensor.readings.map( + s=>s==null?0:1-s.offset + ); + const outputs=NeuralNetwork.feedForward(offsets,this.brain); + + if(this.useBrain){ + this.controls.forward=outputs[0]; + this.controls.left=outputs[1]; + this.controls.right=outputs[2]; + this.controls.reverse=outputs[3]; + } + } + } + + #assessDamage(roadBorders,traffic){ + for(let i=0;ithis.maxSpeed){ + this.speed=this.maxSpeed; + } + if(this.speed<-this.maxSpeed/2){ + this.speed=-this.maxSpeed/2; + } + + if(this.speed>0){ + this.speed-=this.friction; + } + if(this.speed<0){ + this.speed+=this.friction; + } + if(Math.abs(this.speed)0?1:-1; + if(this.controls.left){ + this.angle+=0.03*flip; + } + if(this.controls.right){ + this.angle-=0.03*flip; + } + } + + this.x-=Math.sin(this.angle)*this.speed; + this.y-=Math.cos(this.angle)*this.speed; + } + + draw(ctx,drawSensor=false){ + if(this.sensor && drawSensor){ + this.sensor.draw(ctx); + } + + ctx.save(); + ctx.translate(this.x,this.y); + ctx.rotate(-this.angle); + if(!this.damaged){ + ctx.drawImage(this.mask, + -this.width/2, + -this.height/2, + this.width, + this.height); + ctx.globalCompositeOperation="multiply"; + } + ctx.drawImage(this.img, + -this.width/2, + -this.height/2, + this.width, + this.height); + ctx.restore(); + + } +} \ No newline at end of file diff --git a/Self-driving-car/9. Fine-tuning/car.png b/Self-driving-car/9. Fine-tuning/car.png new file mode 100644 index 0000000000000000000000000000000000000000..d969908cc3e90b514170aadaa7b353e86aacce67 GIT binary patch literal 6964 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 + switch(event.key){ + case "ArrowLeft": + this.left=true; + break; + case "ArrowRight": + this.right=true; + break; + case "ArrowUp": + this.forward=true; + break; + case "ArrowDown": + this.reverse=true; + break; + } + } + document.onkeyup=(event)=>{ + switch(event.key){ + case "ArrowLeft": + this.left=false; + break; + case "ArrowRight": + this.right=false; + break; + case "ArrowUp": + this.forward=false; + break; + case "ArrowDown": + this.reverse=false; + break; + } + } + } +} \ No newline at end of file diff --git a/Self-driving-car/9. Fine-tuning/index.html b/Self-driving-car/9. Fine-tuning/index.html new file mode 100644 index 0000000..e48ea0f --- /dev/null +++ b/Self-driving-car/9. Fine-tuning/index.html @@ -0,0 +1,22 @@ + + + Self-driving car - No libraries + + + + +
+ + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/Self-driving-car/9. Fine-tuning/main.js b/Self-driving-car/9. Fine-tuning/main.js new file mode 100644 index 0000000..0b4128d --- /dev/null +++ b/Self-driving-car/9. Fine-tuning/main.js @@ -0,0 +1,87 @@ +const carCanvas=document.getElementById("carCanvas"); +carCanvas.width=200; +const networkCanvas=document.getElementById("networkCanvas"); +networkCanvas.width=300; + +const carCtx = carCanvas.getContext("2d"); +const networkCtx = networkCanvas.getContext("2d"); + +const road=new Road(carCanvas.width/2,carCanvas.width*0.9); + +const N=100; +const cars=generateCars(N); +let bestCar=cars[0]; +if(localStorage.getItem("bestBrain")){ + for(let i=0;ic.y==Math.min( + ...cars.map(c=>c.y) + )); + + carCanvas.height=window.innerHeight; + networkCanvas.height=window.innerHeight; + + carCtx.save(); + carCtx.translate(0,-bestCar.y+carCanvas.height*0.7); + + road.draw(carCtx); + for(let i=0;i { + for(let i=0;ilevel.biases[i]){ + level.outputs[i]=1; + }else{ + level.outputs[i]=0; + } + } + + return level.outputs; + } +} \ No newline at end of file diff --git a/Self-driving-car/9. Fine-tuning/road.js b/Self-driving-car/9. Fine-tuning/road.js new file mode 100644 index 0000000..5c824b6 --- /dev/null +++ b/Self-driving-car/9. Fine-tuning/road.js @@ -0,0 +1,56 @@ +class Road{ + constructor(x,width,laneCount=3){ + this.x=x; + this.width=width; + this.laneCount=laneCount; + + this.left=x-width/2; + this.right=x+width/2; + + const infinity=1000000; + this.top=-infinity; + this.bottom=infinity; + + const topLeft={x:this.left,y:this.top}; + const topRight={x:this.right,y:this.top}; + const bottomLeft={x:this.left,y:this.bottom}; + const bottomRight={x:this.right,y:this.bottom}; + this.borders=[ + [topLeft,bottomLeft], + [topRight,bottomRight] + ]; + } + + getLaneCenter(laneIndex){ + const laneWidth=this.width/this.laneCount; + return this.left+laneWidth/2+ + Math.min(laneIndex,this.laneCount-1)*laneWidth; + } + + draw(ctx){ + ctx.lineWidth=5; + ctx.strokeStyle="white"; + + for(let i=1;i<=this.laneCount-1;i++){ + const x=lerp( + this.left, + this.right, + i/this.laneCount + ); + + ctx.setLineDash([20,20]); + ctx.beginPath(); + ctx.moveTo(x,this.top); + ctx.lineTo(x,this.bottom); + ctx.stroke(); + } + + ctx.setLineDash([]); + this.borders.forEach(border=>{ + ctx.beginPath(); + ctx.moveTo(border[0].x,border[0].y); + ctx.lineTo(border[1].x,border[1].y); + ctx.stroke(); + }); + } +} \ No newline at end of file diff --git a/Self-driving-car/9. Fine-tuning/sensor.js b/Self-driving-car/9. Fine-tuning/sensor.js new file mode 100644 index 0000000..d6c8ced --- /dev/null +++ b/Self-driving-car/9. Fine-tuning/sensor.js @@ -0,0 +1,119 @@ +class Sensor{ + constructor(car){ + this.car=car; + this.rayCount=5; + this.rayLength=150; + this.raySpread=Math.PI/2; + + this.rays=[]; + this.readings=[]; + } + + update(roadBorders,traffic){ + this.#castRays(); + this.readings=[]; + for(let i=0;ie.offset); + const minOffset=Math.min(...offsets); + return touches.find(e=>e.offset==minOffset); + } + } + + #castRays(){ + this.rays=[]; + for(let i=0;i=0 && t<=1 && u>=0 && u<=1){ + return { + x:lerp(A.x,B.x,t), + y:lerp(A.y,B.y,t), + offset:t + } + } + } + + return null; +} + +function polysIntersect(poly1, poly2){ + for(let i=0;i0?0:255; + return "rgba("+R+","+G+","+B+","+alpha+")"; +} + +function getRandomColor(){ + const hue=290+Math.random()*260; + return "hsl("+hue+", 100%, 60%)"; +} + \ No newline at end of file diff --git a/Self-driving-car/9. Fine-tuning/visualizer.js b/Self-driving-car/9. Fine-tuning/visualizer.js new file mode 100644 index 0000000000000000000000000000000000000000..96d8c7848ea2630f8449294fb26d26f3352db451 GIT binary patch literal 7098 zcmeHM+fEcg5UoeW_zwgh*ky+WB`Q%DgE3JPBnF9^5FTI`WMEmz?jR`PKYj39)Kk+G zQ{8mWOmllO6PRmPbyuA_RbBh{PnY_%K_eXF^odfO4{_he)lb@@A)U~D8pAttj3~p~ z3~#%5(!=`=I-+HKnc@5m_j}a9yNr%0p@H?h>Bth9U5pz*Zw86`kT;~SkUyXfJ*HWD zZt3@p=|jslMt7{y)#EbgJ%}E4gt_&gZ3iRGI@>sJV7}k+e?)EALB5!_W;8{QYOH1l zt4U#joqR=p4f>mq4(+v&)xJYlpWa#;wd@(kgKd1hg>~{MUMb%VFjuyQvA0j_c8-fi z{x$nJh2?Byl*yf@hmf7p0!A?!QkupQ!czH4SI<0dJm2ynOC-pd*Ej@D8nwQbQQC^r z%4*uyNtDD{#FNjuqR~Cqw{QoReHbNMbiIT}+KAGadCAyk@Z=1vT7RC5gk~*W%@Q<< zeu=CR{F~7dX2UaioyYJF=CwvoVevUyhfY72h$J6tw$Hh72~thOgm}?L{~BhpUeni% zO=iACAKTJlAY@D=;n z)JGp+3C_HYN``V}>|aPs!5QvX5RpCD z=n(A0HPw8ea&S3=^XK(3lAhTyBwv5b`tw6!8Q%T1^NbYBRN_0{1$Kc3-bLz|=RKw2 z7;WnW)=TL986URk1HB{OZB<3TXxoO*`ZzQ$C!m*i#$6zGBH%}N#UiH~ZKC-yY%XKt zY&4bE>Q7*&>$jC*|00Gp_nQcg^+ec${y6oqURjjc9PDQ1dYS+7ab{~zfWA<6yxmAM z8RUPAjh}aRbc~f*=Qg9uM$c8_%NIE=uU&>utn%whI*x(#9*J=ZW>x}FT{FY2o@M5O39G?0P)drz^&Nv)b*R&p71x$DYMRUV_N zTtv?1y#;rVClJNlpX7JL${Ze&_zE=uTTO7xa`&O5hl6)CRkeXDS84=}ub5iHm8WrF z%RIu~FwIvVKS%D!b4Q)~a~JEaDb%*y_iJJYJAqx^F}k{o`L2$CIf&P0s;^a8lYLl) zuOzPu4Ii`u^W(lGcMHq&r)x{`vF0k%;f#}`eRBJ&@>fXq(~J8Wo^$cbj&DaVNZ>vU zS9rYB=la~gulIAn5Mwg1#}MPk^O4oP^+J9bGZj6B@{U5W3cKp7-vy89dUKasEM>ag SCYsz|Pr|)z7sJMLr}PgiU!J=F literal 0 HcmV?d00001 diff --git a/Self-driving-car/LICENSE b/Self-driving-car/LICENSE new file mode 100644 index 0000000..d809b0a --- /dev/null +++ b/Self-driving-car/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Radu Mariescu-Istodor + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Self-driving-car/README.md b/Self-driving-car/README.md new file mode 100644 index 0000000..ef701cb --- /dev/null +++ b/Self-driving-car/README.md @@ -0,0 +1,16 @@ +# Self-driving-car + +This is the code I wrote during the Self-driving car (no libraries) JavaScript course: + + +The code will appear as the course progresses and will be divided into parts as follows: + 1. Car driving mechanics + 2. Road definition + 3. Artificial sensors + 4. Collision detection + 5. Traffic simulation + 6. Neural network + 7. Visualizing neural networks + 8. Optimizing neural networks + 9. Fine-tuning + 10. Live stream variant