CoolFace
Apppublic

RustX/Autonomous_Driving_Simulation

sourceHugging Faceupdated 3y agoView on Hugging Face
3likes
car.js146 linesDownload Raw Back to root
1class Car{2    constructor(x,y,width,height,controlType,maxSpeed=3){3        this.x=x;4        this.y=y;5        this.width=width;6        this.height=height;7 8        this.speed=0;9        this.acceleration=0.2;10        this.maxSpeed=maxSpeed;11        this.friction=0.05;12        this.angle=0;13 14        this.damaged=false;15 16        this.useBrain=controlType=="AI";17 18        if(controlType!="DUMMY"){19            this.sensor=new Sensor();20            this.brain=new NeuralNetwork(21                [this.sensor.rayCount,6,4]22            );23        }       24        this.controls=new Controls(controlType);25    }26 27    update(roadBorders,traffic){28        if(!this.damaged){29            this.#move();30            this.polygon=this.#createPolygon();31            this.damaged=this.#assessDamage(roadBorders,traffic);32        }33        if(this.sensor){34            this.sensor.update(this.x,this.y,this.angle,roadBorders,traffic);35            const offsets=this.sensor.readings.map(36                s=>s==null?0:1-s.offset37            );38            const outputs=NeuralNetwork.feedForward(offsets,this.brain);39            if(this.useBrain){40                this.controls.forward=outputs[0];41                this.controls.left=outputs[1];42                this.controls.right=outputs[2];43                this.controls.reverse=outputs[3];44            }45        }     46    }47 48    #assessDamage(roadBorders,traffic){49        for(let i=0;i<roadBorders.length;i++){50            if(polysIntersect(51                [...this.polygon,this.polygon[0]],52                roadBorders[i])53                ){54                return true;55            }56        }57        for(let i=0;i<traffic.length;i++){58            const poly=traffic[i].polygon;59            if(polysIntersect(60                [...this.polygon,this.polygon[0]],61                [...poly,poly[0]])62                ){63                return true;64            }65        }66        return false;67    }68 69    #createPolygon(){70        const points=[];71        const rad=Math.hypot(this.width,this.height)/2;72        const alpha=Math.atan2(this.width,this.height);73        points.push({74            x:this.x-Math.sin(this.angle-alpha)*rad,75            y:this.y-Math.cos(this.angle-alpha)*rad76        });77        points.push({78            x:this.x-Math.sin(this.angle+alpha)*rad,79            y:this.y-Math.cos(this.angle+alpha)*rad80        });81        points.push({82            x:this.x-Math.sin(Math.PI+this.angle-alpha)*rad,83            y:this.y-Math.cos(Math.PI+this.angle-alpha)*rad84        });85        points.push({86            x:this.x-Math.sin(Math.PI+this.angle+alpha)*rad,87            y:this.y-Math.cos(Math.PI+this.angle+alpha)*rad88        });89        return points;90    }91 92    #move(){93        if(this.controls.forward){94            this.speed+=this.acceleration; 95         }96         if(this.controls.reverse){97             this.speed-=this.acceleration;98         }99 100         if(this.speed!=0){101             const flip=this.speed>0?1:-1;102             if(this.controls.left){103                 this.angle+=0.03*flip;104             }105             if(this.controls.right){106                 this.angle-=0.03*flip;107             }108         }109 110         if(this.speed>this.maxSpeed){111             this.speed=this.maxSpeed;112         }113         if(this.speed<-this.maxSpeed/2){114             this.speed=-this.maxSpeed/2;115         }116 117         if(this.speed>0){118             this.speed-=this.friction;119         }120         if(this.speed<0){121             this.speed+=this.friction;122         }123         if(Math.abs(this.speed)<this.friction){124             this.speed=0;125         }126         this.x-=Math.sin(this.angle)*this.speed;127         this.y-=Math.cos(this.angle)*this.speed;128    }129 130    draw(ctx,drawSensor=false){131        if(this.damaged){132            ctx.fillStyle="gray";133        }else{134            ctx.fillStyle="black";135        }136        ctx.beginPath();137        ctx.moveTo(this.polygon[0].x,this.polygon[0].y);138        for(let i=1;i<this.polygon.length;i++){139            ctx.lineTo(this.polygon[i].x,this.polygon[i].y);140        }141        ctx.fill();142        if(this.sensor && drawSensor){143            this.sensor.draw(ctx);144        }145    }146}