Le Logiciel Raspberry Car – Tâche de surveillance GPS (1/5)
En utilisant les techniques de la partie précédente, le code de la tache de récupération des infos GPS effectuant le travail suivant :
- Initialiser la connexion
- En boucle :
- lire tout ce qui vient de la carte GPS
- Analyser toutes les données pour juste donner juste la position (quand il y en a une)
- Pose le verrou
GPS : Bloquer la mémoire pour la dernière position GPS
- Action sécurisée : Mettre de côté la dernière position trouvée avec l’heure
- Débloquer le verrou GPS (cela a duré quelque millisecondes)
- Attendre un peu pour avoir des nouvelles données de la carte
ressemble à :
def watch_gps( gpsPort):
# la demande d'utilisation des variables dans lesquelles la thread GPS stocke ce qu'elle a trouvé
global lastGpsPositionMeasured;
global lastGpsLongitude;
global lastGpsLattitude;
global lastGpsSpeed
global lastGpsElevation;
global lastGpsMeasureTime;
global lastGpsTime
# ?
GPIO.setmode(GPIO.BOARD)
# Enable Serial Communication
port = serial.Serial(gpsPort, 115200);
port.timeout=1;
print ("GPS : Starting Up Serial Monitor")
# on vide toutes les entrees et sorties du ports USB pour la carte GPS
port.flushInput()
port.flushOutput()
# la sequence d initialisation
port.write('AT\r\n'.encode('ascii'))
rcv = port.read(100)
print(C_GPS_READ+"GPS : ",rcv, ENDC)
time.sleep(.1)
port.write('AT+CGNSPWR=1\r\n'.encode('ascii')) # to power the GPS
rcv = port.read(100)
print(C_GPS_READ+"GPS : ",rcv, ENDC)
time.sleep(.1)
port.write('AT+CGNSIPR=115200\r\n'.encode('ascii')) # Set the baud rate of GPS
rcv = port.read(100)
print(C_GPS_READ+"GPS : ",rcv, ENDC)
time.sleep(.1)
port.write('AT+CGNSTST=1\r\n'.encode('ascii')) # Send data received to UART
rcv = port.read(100)
print(C_GPS_READ+"GPS : ",rcv, ENDC)
time.sleep(.1)
port.write('AT+CGNSINF\r\n'.encode('ascii')) # Print the GPS information
rcv = port.read(200)
print(C_GPS_READ+"GPS : ",rcv, ENDC)
time.sleep(.1)
ck=1
while ck==1:
# lecture de la prochaine ligne depuis la carte GPS
line = port.read_until("\r\n".encode('ascii'));
lineStr = line.decode('ascii');
# en mode debug complet, on affiche chaque ligne renvoyée par la carte
if FULL_DEBUG_GPS == True :
if (len(lineStr)>2):
lineStr2 = lineStr[0: len(lineStr)-2];
print(C_GPS_READ+"GPS :",lineStr2, ENDC);
# si la ligne est une ligne de position GPS (commencent par $GNRMC
if (lineStr.startswith("$GNRMC")) :
# on extrait la ligne sans les deux caracteres de fin de ligne
lineStr = lineStr[0: len(lineStr)-2];
# en mode debug GPS seulement, on affiche ces lignes
if SMALL_DEBUG_GPS == True :
print(C_GPS_READ+"GPS :",lineStr, ENDC);
# on decoupe la ligne selon les morceaux séparés par des virgules
items = lineStr.split(",");
# on recupere les morceaux de la ligne qui correspondent au champs utiles
timeStr = items[1]; # l'heure connue par le GPS
lat = items[3]; # la latitude
lon = items[5]; # la longitude
speed = items[7]; # la vitesse
elevation=items[8] # l'altitude
dateStr = items[9]; # la date connue par le GPS
# si les champs longitude et latitude ne sont pas vide, alors on va memoriser les
if ((len(lat)>0) and (len(lon)>0)) :
# on decode la latitude comme dans le programme d'exemple
s3=lat[2:len(lat)]
s3=Decimal(s3)
s3=s3/60
s33=int(lat[0:2])
s3 = s3 + s33
s3 = int(s3*1000000)/1000000
# on decode la longituide comme dans le programme d'exemple
s5=lon[3:len(lon)]
s5=Decimal(s5)
s5=s5/60
s55=int(lon[0:3])
s5 = s5 + s55
s5 = int(s5*1000000)/1000000
# on crée une chaine datetime au format ISO avec les morceaux optebnus de la carte,
# et on la fait analyser par le datetime python
theDatetime = datetime.strptime(dateStr+'-'+timeStr+'000Z+0000',"%d%m%y-%H%M%S.%fZ%z");
# on cree le timestamp (Unix) correspondant : le nombre de secondes depuis le 1/1/1970
theDateTimeTimestamp = datetime.timestamp(theDatetime);
# on decode la vitesse , et on la convertit de mph to kph
theSpeed = float(speed)*1.609;
#on decode l'altitude
theElevation = float(elevation);
# en mode debug standard, on fait un joli affichage des infos GPS
# la constante C_GPS permet d'afficher dans une couleur particulière pour le GPS (facile à lire)
if DEBUG_GPS == True :
print(C_GPS+"--------------------------------------------", ENDC)
print(C_GPS+"GPS : TIME :", datetime.fromtimestamp(theDateTimeTimestamp), ENDC )
print(C_GPS+"GPS : LAT. :", s3 , ENDC)
print(C_GPS+"GPS : LONG. :", s5 , ENDC)
print(C_GPS+"GPS : ELEV :", theElevation , ENDC)
print(C_GPS+"GPS : SPEED :", theSpeed , ENDC)
print(C_GPS+"--------------------------------------------", ENDC)
# on va placer les valeurs lues dans les variables globales
# mais pour eviter qu'une autre thread les lise pendant qu'on les modifie on demande le verrou
# et on le libère une fois les valeurs stoquées
threadGpsLock.acquire()
# on indique qu'on a eu une nouvelle mesure reussie
lastGpsPositionMeasured = True
# on memorise l'heure
lastGpsMeasureTime = int(datetime.timestamp(datetime.now()));
# on memorise le resultta du GPS
lastGpsLongitude = s5;
lastGpsLattitude = s3;
lastGpsSpeed = theSpeed;
lastGpsElevation = theElevation;
lastGpsTime = int(theDateTimeTimestamp)
# et on libère le verrou une fois les valeurs stoquées
threadGpsLock.release()