products:kronos:rtkronos:unicorecomm_gps_rtk_devboard

This version is outdated by a newer approved version.DiffThis version (2021/04/04 12:05) is a draft.
Approvals: 0/1

This is an old revision of the document!


GPS RTK devboard from Unicorecomm


tags: RTK Unicorecomm, GPS

  1. Débranchez l'alimentation et mettez l'interrupteur d'alimentation en position éteinte (sur la gauche)
  2. Connectez la carte UB4B0 sur la carte de développement HPL-EVK
    • Via port série:
      • Si vous n'avez pas de port RS232, connectez le port RS232 COM3 à un convertisseur RS232↔USB.

La carte utilisé ici est un DFRobot Multiplexer v1.1, connecté sur le port B-232 (fil rouge PC TX → RX pin 3 RS-232, fil orange PC RX ← TX pin 2 RS-232, masse sur pin 5)

  • Via port ethernet:
    • La carte a comme adresse IP 192.168.0.100. Vous pouvez connecter votre ordinateur en direct sur la carte et définir l'adresse IP de votre ordinateur sur un sous-réseau valide (ex: adresse IP de l'ordinateur: 192.1680.42 et masque de sous-réseau 255.255.255.0).
    • Voir les commandes disponible dans le document TCP CONFIG pour changer l'adresse IP ou configurer le DHCP.
  1. Mettez sous tension en glissant l'interrupteur d'alimentation en position allumé (sur la droite)

Vous pouvez maintenant lancer UPrecise (plus récent) ou CDT (ne tient pas compte des satellites en L5) et configurer la connexion sur le port série de votre machine (baudrate 115200) ou sur l'adresse IP 192.168.0.100 si vous êtes en ethernet.

Vous avez aussi la possibilité d'utiliser une console série (putty sous Windows, dterm sous linux par exemple) ou une connexion par telnet sur le port 40000 (telnet 192.168.0.100 40000) si vous êtes connecté par ethernet afin d'envoyer directement des commandes de configuration au module GPS.

Depuis la console UPrecise (ou n'importe quelle moyen de communication avec le GPS), envoyez les commandes suivantes:

Remplacez LAT, LONG et HEIGHT avec les coordonnées connues de la base.

UNLOGALL COM2
FIX NONE
MODE BASE LAT LONG HEIGHT
LOG COM2 RTCM1006 ontime 10
LOG COM2 RTCM1033 ontime 10
LOG COM2 RTCM1074 ontime 1
LOG COM2 RTCM1084 ontime 1
LOG COM2 RTCM1094 ontime 1
LOG COM2 RTCM1124 ontime 1

La ligne 3 permet de configurer les paramètres de calcul automatique de la position. Le format est le suivant:
MODE BASE TIME SECONDS HORIZONTAL VERTICAL

  • HORIZONTAL et VERTICAL correspondent à l'écart type autorisé en latitude/longitude et altitude en mètre;
  • SECONDS correspond au timeout dans le cas où la précision demandé n'est pas atteinte.
UNLOGALL COM2
FIX NONE
MODE BASE TIME 60 1.5 2.5
LOG COM2 RTCM1006 ontime 10
LOG COM2 RTCM1033 ontime 10
LOG COM2 RTCM1074 ontime 1
LOG COM2 RTCM1084 ontime 1
LOG COM2 RTCM1094 ontime 1
LOG COM2 RTCM1124 ontime 1

Sous Linux et OSX, lancez la commande dmesg -w et connectez le port USB afin de voir sur quel port la carte est attribué.

Sur Windows, le format du port est COMx, `x` étant un nombre défini par Windows. Lancez le Gestionnaire de périphérique et branchez le port USB pour repérer le port attribué par Windows

Voici un exemple de code Python utilisant la bibliothèque [[https://github.com/pyserial/pyserial|pyserial}} pour configurer la carte pour qu'elle transmette sa meilleure position connue toutes les secondes:

#!/usr/bin/python3
  2 # pip install typing pyserial 
  3 from typing import NamedTuple, Union
  4 
  5 import threading
  6 import serial
  7 import re
  8 import datetime
  9 from time import time, sleep
 10 
 11 
 12 BestPosition = NamedTuple('BestPosition', [
 13     ('gps_week', int),
 14     ('gps_sec', float),
 15     ('solution_type', str),
 16     ('position_type', str),
 17     ('gps_latitude', str),
 18     ('gps_longitude', str),
 19     ('gps_altitude', str),
 20     ('gps_date', str)
 21 ])
 22 
 23 class UB4B0_rover():
 24 
 25     def __init__(self, port, baudrate=115200, timeout=3):
 26         self.serial = serial.Serial(port=port, baudrate=baudrate, timeout=timeout)
 27         self.lock = threading.Lock()
 28 
 29         # Send rover configuration
 30         self.send_command('UNLOGALL', waitResp=False) # Remove previous logs
 31         self.send_command('FIX none', waitResp=False) # Remove any previousl fixed position (base station)
 32         self.send_command('SAVECONFIG', waitResp=False) # Save configuration
 33 
 34     def close(self):
 35         self.serial.close()
 36 
 37     def write(self, data: bytes):
 38         with self.lock:
 39             self.serial.write(data)
 40 
 41     def send_command(self, command: str, waitResp: bool = True) -> str:
 42         with self.lock:
 43             # Flush input buffer
 44             self.serial.reset_input_buffer()
 45 
 46             # Send command
 47             self.serial.write(bytes(command + '\r\n', 'utf-8'))
 48             # Expected response should be `$command,{command},response: OK*{checksum}\r\n`
 49             # There is no info how the checksum is calculated, so skip it
 50             expected_resp = '$command,{command},response: OK*'.format(command=command)
 51             # Check that the command has been correctly received by the GPS 
 52             resp = self.serial.readline().decode('utf-8')
 53             if expected_resp not in resp:
 54                 raise ValueError('Invalid reponse, got:\n {}'.format(resp))
 55             if waitResp == True:
 56                 resp = self.serial.readline().decode('utf-8')
 57                 return resp
 58 
 59     def get_best_position(self) -> Union[None, BestPosition]:
 60         bestpos = self.send_command("LOG BESTPOSA once")
 61         if bestpos.startswith("#BESTPOSA") is False:
 62             return None
 63         if "INSUFFICIENT_OBS" in bestpos:
 64             return None
 65 
 66         # Get every field (separators are ',', ';', '*')
 67         parser = r"([^,\*;]+)"
 68         matches = re.findall(parser, bestpos)
 69         # Example of valid data: "#BESTPOSA,COM2,0,86.0,FINE,1991,402429.800,00000000,929861713,18;SOL_COMPUTED,NARROW_FLOAT,48.58252933494,7.76681014722,144.8847,48.4450,WGS84,0.1256,0.1388,0.3033,"0",0.800,0.000,11,10,10,5,0,00,0,13*d7c1d0b0"
 70         # Documentation on the BESTPOSA command can be found on the previous command manual
 71         # TODO: better & safer matching
 72         if len(matches) is not 32:
 73             return None
 74 
 75         gps_week = int(float(matches[5]))
 76         gps_sec = float(matches[6])
 77 
 78         datetimeformat = "%Y-%m-%dT%H:%M:%S.%f"
 79         epoch = datetime.datetime.strptime("1980-01-06T00:00:00.000", datetimeformat)
 80         elapsed = datetime.timedelta(days=gps_week*7, seconds=gps_sec)
 81         # Warning: the following date doesn't take account of leap seconds! (substract 16 seconds @ 2018-06-11)
 82         gps_date = datetime.datetime.strftime(epoch + elapsed, datetimeformat)
 83 
 84         best_position = BestPosition(
 85             gps_week      = gps_week,
 86             gps_sec       = gps_sec,
 87             solution_type = matches[10],
 88             position_type = matches[11],
 89             gps_latitude  = matches[12],
 90             gps_longitude = matches[13],
 91             gps_altitude  = matches[14],
 92             gps_date=gps_date
 93         )
 94 
 95         return best_position
 96 
 97 if __name__ == '__main__':
 98     rover = UB4B0_rover(port='/dev/ttyUSB0')
 99 
100     while True:
101         t = time()
102         try:
103             best_position = rover.get_best_position()
104             print(best_position)
105         except ValueError as e:
106             print("Invalid data received: {}".format(e))
107 
108         # Wait 1 second between two measurements
109         # TODO: use PPS signal to check when new position is available
110         if time() - t < 1:
111             sleep(1 - (time() - t))

  • products/kronos/rtkronos/unicorecomm_gps_rtk_devboard.1617537926.txt.gz
  • Last modified: 2021/04/04 12:05
  • by manu