dimanche 17 mars 2019

RTK moving base suite

J'ai enfin fait quelques tests de performance du GPS RTK.

Sur mes premiers tests, les résultats étaient très décevants, avec une précision de l'ordre du mètre seulement.
Le Rover restait bloqué en RTK Float (qualité n°5 de la trame GGA), jamais en RTK fix.

En creusant un peu sur le net, j'ai vu que la réception du signal devait être de bonne qualité. Et que mes petites antennes seules ne suffisaient pas atteindre la qualité nécessaire, même avec le ciel dégagé.

Pour améliorer la qualité, il faut augmenter le gain de l'antenne. Pour cela il faut utiliser une "ground plate", un support métallique qui permet de concentrer les ondes un peu comme une parabole.
J'ai pu vérifier avec U-Center que les gains augmentaient de manière importante en plaçant un couvercle de boite de gateau sous les antennes GPS (+5dB au moins).

Grâce à cette modification, j'observe une bien meilleure position (variation de l'ordre de +/-10cm, même sans passer en qualité fix (4). Cela n'arrive d'ailleurs quasiment jamais, peut-être 1 seconde de temps en temps. Et je ne semble pas le seul à avoir ce problème.

La précision est satisfaisante sans cela, mais elle peut se dégrader sans que cela soit visible (le HDOP reste autour de 0.7m). A creuser donc.

Autre soucis : la fréquence de retour de la position GPS (renvoyée en RF depuis le Rover vers le PC connecté à la base) est de l'ordre de 2Hz seulement (la fréquence remonte bien à 4Hz comme souhaité quand je coupe l'envoie des messages RTCM ou quand je passe les messages RCTM directement en USB via le PC. La limitation est donc dans le débit en 433MHz et le baurate de 57600).


import serial
import time # Optional (if using time.sleep() below)
import pynmea2
import time

serBase = serial.Serial(port='/dev/ttyACM1', timeout=1)
serRover = serial.Serial(port='/dev/ttyUSB0', timeout=1, baudrate=57600)

buf = ''
while (True):
    if (serBase.inWaiting()>0): #if incoming bytes are waiting to be read from the serial input buffer
        data = serBase.read(serBase.inWaiting())
        x = data.split('$GNGGA')
    serRover.write(x[0]) # RTCM data is sent before nmea
        if len(x)>1:
          try:
            msgBase = pynmea2.parse('$GNGGA'+x[1])
          except:
            pass
    if (serRover.inWaiting()>0): #if incoming bytes are waiting to be read from the serial input buffer
        data = serRover.read(serRover.inWaiting())
    data = buf + data
        if data.find('\r\n')<0:
          buf=data
        else:
          buf=''
          try:
            msgRover = pynmea2.parse(data)
            print ('dNorth: ', float(msgRover.gps_qual),msgRover.horizontal_dil, (float(msgRover.lat)-float(msgBase.lat))*1852)
          except:
            print("An exception occurred", data)
    time.sleep(0.01) # Optional: sleep 10 ms (0.01 sec) once per loop to let other threads on your PC run during this time.