Skip to content

Commit

Permalink
self driving car
Browse files Browse the repository at this point in the history
  • Loading branch information
elidakirigo committed Aug 23, 2023
1 parent e0b0aa6 commit e2ab6b1
Show file tree
Hide file tree
Showing 89 changed files with 4,667 additions and 0 deletions.
76 changes: 76 additions & 0 deletions Self-driving-car/1. Car driving mechanics/car.js
Original file line number Diff line number Diff line change
@@ -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)<this.friction){
this.speed=0;
}

if(this.speed!=0){
const flip=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();
}
}
45 changes: 45 additions & 0 deletions Self-driving-car/1. Car driving mechanics/controls.js
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
}
12 changes: 12 additions & 0 deletions Self-driving-car/1. Car driving mechanics/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<head>
<title>Self-driving car - No libraries</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="myCanvas"></canvas>
<script src="controls.js"></script>
<script src="car.js"></script>
<script src="main.js"></script>
</body>
</html>
15 changes: 15 additions & 0 deletions Self-driving-car/1. Car driving mechanics/main.js
Original file line number Diff line number Diff line change
@@ -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);
}
9 changes: 9 additions & 0 deletions Self-driving-car/1. Car driving mechanics/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
body{
margin:0;
background:darkgray;
overflow:hidden;
text-align:center;
}
#myCanvas{
background:lightgray;
}
147 changes: 147 additions & 0 deletions Self-driving-car/10. Live stream variant/car.js
Original file line number Diff line number Diff line change
@@ -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;i<roadBorders.length;i++){
if(polysIntersect(
[...this.polygon,this.polygon[0]],
roadBorders[i])
){
return true;
}
}
for(let i=0;i<traffic.length;i++){
const poly=traffic[i].polygon;
if(polysIntersect(
[...this.polygon,this.polygon[0]],
[...poly,poly[0]])
){
return true;
}
}
return false;
}

#createPolygon(){
const points=[];
const rad=Math.hypot(this.width,this.height)/2;
const alpha=Math.atan2(this.width,this.height);
points.push({
x:this.x-Math.sin(this.angle-alpha)*rad,
y:this.y-Math.cos(this.angle-alpha)*rad
});
points.push({
x:this.x-Math.sin(this.angle+alpha)*rad,
y:this.y-Math.cos(this.angle+alpha)*rad
});
points.push({
x:this.x-Math.sin(Math.PI+this.angle-alpha)*rad,
y:this.y-Math.cos(Math.PI+this.angle-alpha)*rad
});
points.push({
x:this.x-Math.sin(Math.PI+this.angle+alpha)*rad,
y:this.y-Math.cos(Math.PI+this.angle+alpha)*rad
});
return points;
}

#move(){
if(this.controls.forward){
this.speed+=this.acceleration;
}
if(this.controls.reverse){
this.speed-=this.acceleration;
}

if(this.speed!=0){
const flip=this.speed>0?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)<this.friction){
this.speed=0;
}

this.x-=Math.sin(this.angle)*this.speed;
this.y-=Math.cos(this.angle)*this.speed;
}

draw(ctx,drawSensor=false){
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<this.polygon.length;i++){
ctx.lineTo(this.polygon[i].x,this.polygon[i].y);
}
ctx.fill();
if(this.sensor && drawSensor){
this.sensor.draw(ctx);
}
}
}
52 changes: 52 additions & 0 deletions Self-driving-car/10. Live stream variant/controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
class Controls{
constructor(type){
this.forward=false;
this.left=false;
this.right=false;
this.reverse=false;

switch(type){
case "KEYS":
this.#addKeyboardListeners();
break;
case "DUMMY":
this.forward=true;
break;
}
}

#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;
}
}
}
}
18 changes: 18 additions & 0 deletions Self-driving-car/10. Live stream variant/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>JS - Self-driving Car - LIVE</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<canvas id="carCanvas"></canvas><canvas id="networkCanvas"></canvas>
<script src="visualizer.js"></script>
<script src="network.js"></script>
<script src="sensor.js"></script>
<script src="utils.js"></script>
<script src="road.js"></script>
<script src="controls.js"></script>
<script src="car.js"></script>
<script src="main.js"></script>
</body>
</html>
Loading

1 comment on commit e2ab6b1

@vercel
Copy link

@vercel vercel bot commented on e2ab6b1 Aug 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.