Étape 4: programmation
Le programme sera un projet en constante évolution. Si vous souhaitez avoir accès à une version mise à jour, je dirais bifurquer le code de mon dépôt GitHub au lien suivant :
https://github.com/TheInventorMan/IntelligentTraff...
Cependant, j’ai collé le code ci-dessous pour votre commodité, même si c’est seulement pour le périphérique local qui sera conservé dans le véhicule. Les fichiers serveur sont tous situés sur le repo.
Pour ceux d'entre vous qui sont intéressés, voici un schéma de base de l’algorithme qu’utilise le programme :
- GPS reçoit localisation, vitesse, position et le temps
- Dispositif de demande des données du serveur via le dongle 3G
- Le serveur répond par un flux de données, semblable à celle d’une phrase NMEA (mais, bon, c’est un protocole facile)
- Flux de données est analysé et disposé dans un tableau 2D, contenant les emplacements des signaux, horaires, décalages, etc..
- À l’aide de ces informations, l’appareil détermine quel signal est proche.
- La fenêtre de lumière verte est déterminée et il mesure contre la vitesse actuelle
- Appareil demande pilote pour accélérer, ralentir ou maintenir la vitesse afin d’attraper la fenêtre verte du signal.
À l’avenir, cela pourrait être élargi pour inclure des signaux non-programmé (celles avec des bobines d’induction sous la route), ainsi que d’un "tampon de sécurité" d’environ 3 secondes lorsque le véhicule sera * peine * faire passé le signal. De cette façon, le pilote n’exécutera jamais les feux jaunes (dangereux) ; Il y aura quelques temps à perdre.
importer mraa ;
importer des mathématiques ;
Initialisation du port
var GPS = mraa. UART(0) ; var 3G = mraa. USB(0) ; ne fonctionne ne pas pour le moment, un pilote de port USB hôte aura lieu en son lieu var augmentation = mraa.gpio(2) ; maintenir la var = mraa.gpio(3) ; diminution de la var = mraa.gpio(4) ; GPS.setBaudRate(9600) ;
Constantes
var earthRadius = 6371000 ; rayon de la terre en mètres var degToRad = 0.01745329251 ; Radians par degré var radToDeg = 57.2957795131 ; Degrés par radian
function getLocation() {//Uses la $GPGGA des messages pour déterminer l’emplacement actuel var GPSLocation = [0,0,0,0]; while(1) {if(GPS.dataAvailable()) {var buffer = GPS.readStr(512) ; if (buffer.find("GPGGA")! = -1) {var rawNmea = buffer.substring(buffer.search("GPGGA"), buffer.search("\n")) ; var nmeaList = rawNmea.strip().split(",") ; var temps = nmeaList [1]; var latraw = nmeaList [2]; var latdir = nmeaList [3]; var lonraw = nmeaList [4]; var londir = nmeaList [5]; var lat = (latraw.substring(0,2)) + (latraw.substring(2)) 60 ; var lon = (lonraw.substring(0,3)) + (lonraw.substring(3,0)) 60 ; if (londir == "W") {lon = lon * -1;} si (latdir == "S") {lat = Lat * -1 ; } var alt = nmeaList [9] ; GPSLocation = [lat, lon, alt, temps] ; Return GPSLocation ; }}}} function getVelocity() {//Uses $GPVTG messages afin de déterminer la vitesse et la direction var GPSVel = [0,0]; while(1) {if(GPS.dataAvailable()) {var buffer = GPS.readStr(512) ; if (buffer.find("GPVTG")! = -1) {var nmeaData = buffer.substring(buffer.search("GPVTG"), buffer.search("\n")) ; var nmeaList = nmeaData.strip().split(",") ; var hdg = nmeaList [1]; var rawVel = nmeaList [7]; var vel = rawVel / 3,6 ; GPSVel = [hdg, vel] ; Return GPSVel ; } } } }
function getLights() {var lumières = [7] [10]; //array des minutages de feux tricolores, 10 lumières le plus proche, 7 paramètres. Lat, Lon, NTime, Etime, TimeOffset, Cap, Distance / / données() ; if(3G.dataAvailable()) {var buffer = 3G.readStr(512) ; if (buffer.find("$$")! = -1) {lightData = buffer.substring(buffer.search("$$"), buffer.search("\n")) ; //light informations spécification suit le système de GPS, avec "$$" indiquant le début d’un phrase. LISTECLAIRAGES = nmeaData.strip().split(",") ; pour (j’ai = 0; j’ai
function computeDistance (Latdeg1, Londeg1, Latdeg2, Londeg2) {var Lat1 = Latdeg1 * degToRad ; var Lat2 = Latdeg2 * degToRad ; var Lon1 = Londeg1 * degToRad ; var Lon2 = Londeg2 * degToRad ; var distance = 2 * earthRadius * Math.asin(sqrt((Math.sin(Lat2-Lat1/2)) ^ 2 + (Math.cos(Lat1) * Math.cos(Lat2) * (Math.sin(Lon2-Lon1/2))^2))); //Use haversine formule pour calculer la distance orthodromique}
function computeHeading (Latdeg1, Londeg1, Latdeg2, Londeg2) {var Lat1 = Latdeg1 * degToRad ; var Lat2 = Latdeg2 * degToRad ; var Lon1 = Londeg1 * degToRad ; var Lon2 = Londeg2 * degToRad ; var y = Math.sin(Lon2-Lon1) * Math.cos(Lat2) ; var x = Math.cos(Lat1)*Math.sin(Lat2) - Math.sin(Lat1)*Math.cos(Lat2)*Math.cos(Lon2-Lon1) ; var rubrique = Math.atan2 (y, x).toDegrees() ; return position;}
Séquence principale while(1) {var temp [4]; var currLat ; var currLon ; var currHdg ; var currSpd ; var lumières ; var temps ; var Dir ; var currSignal ; var t1, t2 ; temp = getLocation() ; currLat = temp [0]; currLon = temp [1]; Durée = temp [3]; temp = getVelocity() ; currHdg = temp [0]; currSpd = temp [1] ; Lumières = getLights() ; pour (j’ai = 0; j’ai < Lights.length(); i ++) {var hdg = computeHeading (currLat, currLon, lumières [0] [i], Lights[1][i]) ; if (hdg > 180) {lumières [5], [i] = 180 - computeHeading (currLat, currLon, lumières [0] [i], Lights[1][i]);} else {lumières [5], [i] = computeHeading (currLat, currLon, lumières [0] [i], Lights[1][i]);} Lumières [6] [i] = computeDistance (currLat, currLon, lumières [0] [i], Lights[1][i]) ; Si (lumières [6] [i] < Lights[6][currSignal]) {currSignal = i;}} Si (hdg < 45 || hdg > 315 || 135 < hdg < 225) {//north-south trafic Dir = 0;} else {Dir = 1;} si (Dir == 0) {t1 = Lights [4] [currSignal] + temps % (Lights [2] [currSignal] + Lights[3][currSignal]) ; devrez peut-être fixer t2 = Lights [4] [currSignal] + temps % (Lights [2] [currSignal] + Lights[3][currSignal]) + Lights [2] [currSignal] ; } else {t1 = Lights [4] [currSignal] + temps % (Lights [2] [currSignal] + Lights[3][currSignal]) ; T2 = Lights [4] [currSignal] + temps % (Lights [2] [currSignal] + Lights[3][currSignal]) + feux [3] [currSignal] ; } Si (t1 > Lights[6][currSignal]) {\\increase vitesse increase.write(1) ; maintain.write(0) ; decrease.write(0);} ElseIf (t1 == Lights[6][currSignal]) {\\maintain vitesse increase.write(0) ; maintain.write(1) ; decrease.write(0);} else {\\decrease vitesse increase.write(0) ; maintain.write(0) ; decrease.write(1);}
}