Intelligent trafikledning med Internet saker (4 / 4 steg)
Steg 4: programmering
Programmet kommer att vara ett ständigt växande projekt. Om du vill ha tillgång till en uppdaterad version, skulle jag föreslå forking koden från min GitHub databas på följande länk:
https://github.com/TheInventorMan/IntelligentTraff...
Dock har jag klistrat in koden nedan för din bekvämlighet, även om detta är endast för den lokala enhet som kommer att hållas i fordonet. Alla finns serverfiler på reporäntan.
För er som är intresserade, är här en grundläggande beskrivning av den algoritm som används för:
- GPS tar emot läge, hastighet, rubrik och tid
- Enheten begär data från servern via 3G-dongle
- Servern svarar med en dataström, liknar en NMEA mening (men hey, det är ett enkelt protokoll)
- Dataströmmen är analyserad och ordnad in i en 2D-array, som innehåller de signaler platser, tider, motkrav, etc.
- Med hjälp av denna information, avgör enheten vilken signal närmar sig.
- Fönstret grönt ljus bestäms och åtgärder mot aktuell hastighet
- Enheten uppmanar föraren att påskynda, sakta ner eller bibehålla hastigheten för att fånga den signalen gröna fönster.
I framtiden, detta skulle kunna utvidgas till att omfatta icke-tidsinställda signaler (de med induktionsspolar under vägen), samt en "säkerhet buffer" ca 3 sekunder när fordonet kommer * knappt * göra det förbi signalen. Detta sätt föraren kommer aldrig köra några gula lampor (farliga). det blir lite tid över.
import mraa;
importera matematik;
Port initiering
var GPS = mraa. UART(0); var 3G = mraa. USB(0); fungerar inte ännu, en USB-värd portdrivrutinen kommer att genomföras i dess ställe var ökning = mraa.gpio(2); var upprätthålla = mraa.gpio(3); var minskningen = mraa.gpio(4); GPS.setBaudRate(9600);
Konstanter
var earthRadius = 6371000; radie av jorden i meter var degToRad = 0.01745329251; Radianer per grad var radToDeg = 57.2957795131; Grader per radian
fungera getLocation() {//Uses $GPGGA meddelanden för att avgöra aktuell plats var GPSLocation = [0,0,0,0]; while(1) {if(GPS.dataAvailable()) {var buffert = GPS.readStr(512); om (buffer.find("GPGGA")! = -1) {var rawNmea = buffer.substring(buffer.search("GPGGA"), buffer.search("\n")); var nmeaList = rawNmea.strip().split(","); var tid = 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; om (londir == "W") {lon = lon * -1;} om (latdir == "S") {lat = lat * -1; } var alt = nmeaList [9]. GPSLocation = [lat, lon, alt, tid]; återvända GPSLocation; }}}} funktion getVelocity() {//Uses $GPVTG meddelanden för att avgöra hastighet och riktning var GPSVel = [0,0]; while(1) {if(GPS.dataAvailable()) {var buffert = GPS.readStr(512); om (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]; återvända GPSVel; } } } }
fungera getLights() {var ljus = [7] [10]. //array av trafikljus timings, 10 närmaste belysning, 7 parametrar. Lat, Lon, NTime, Etime, TimeOffset, rubrik, avstånd / / requestData(); IF(3G.dataAvailable()) {var buffert = 3G.readStr(512); om (buffer.find("$$")! = -1) {lightData = buffer.substring(buffer.search("$$"), buffer.search("\n")); //light information specifikation följer GPS system, med "$$" betecknar början av en mening. lightList = nmeaData.strip().split(","); för (jag = 0; jag
funktion computeDistance (Latdeg1, Londeg1, Latdeg2, Londeg2) {var Lat1 = Latdeg1 * degToRad; var Lat2 = Latdeg2 * degToRad; var Lon1 = Londeg1 * degToRad; var Lon2 = Londeg2 * degToRad; var avståndet = 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 formel för att beräkna storcirkel avstånd}
funktion 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 rubriken = Math.atan2 (y, x).toDegrees(), retur nummer.}
Huvudserien while(1) {var temp [4], var currLat, var currLon; var currHdg; var currSpd; var ljus, var tid; var Dir; var currSignal; var t1, t2, temp = getLocation(); currLat = temp [0]; currLon = temp [1]; tid = temp [3]; temp = getVelocity(); currHdg = temp [0]; currSpd = temp [1]. Ljus = getLights(); för (jag = 0; jag < Lights.length(); i ++) {var hdg = computeHeading (currLat, currLon, ljus [0] [i], Lights[1][i]); if (hdg > 180) {lampor [5] [i] = 180 - computeHeading (currLat, currLon, ljus [0] [i], Lights[1][i]);} annat {lampor [5] [i] = computeHeading (currLat, currLon, lampor [0] [i], Lights[1][i]);} Lights [6] [i] = computeDistance (currLat, currLon, lampor [0] [i], Lights[1][i]); om (ljus [6] [i] < Lights[6][currSignal]) {currSignal = jag;}} om (hdg < 45 || hdg > 315 || 135 < hdg < 225) {//north-south trafik Dir = 0;} annat {Dir = 1;} om (Dir == 0) {t1 = lampor [4] [currSignal] + time % (ljus [2] [currSignal] + Lights[3][currSignal]); kan behöva fastställas t2 = lampor [4] [currSignal] + time % (ljus [2] [currSignal] + Lights[3][currSignal]) + lampor [2] [currSignal]; } annat {t1 = lampor [4] [currSignal] + time % (ljus [2] [currSignal] + Lights[3][currSignal]); T2 = lampor [4] [currSignal] + time % (ljus [2] [currSignal] + Lights[3][currSignal]) + ljus [3] [currSignal]; } om (t1 > Lights[6][currSignal]) {\\increase speed increase.write(1); maintain.write(0); decrease.write(0);} else om (t1 == Lights[6][currSignal]) {\\maintain speed increase.write(0); maintain.write(1); decrease.write(0);} annat {\\decrease speed increase.write(0); maintain.write(0); decrease.write(1);}
}