Κατασκευή και Προγραμματισμός ενός RTK ROVER
Πριν από 2 περίπου χρόνια είχα κατασκευάσει ένα RTK BASE-ROVER μονής συχνότητας που βασιζόταν την επίλυση από RTKNAVI του προγράμματος RTKLIB με χρήση 2 raspberry zero.
Ήρθε η ώρα να κάνουμε το επόμενο βήμα και να κατασκευάσουμε ένα πλήρη δέκτη GPS με τις δυνατότητες και την ακρίβεια των εταιρικών μοντέλων.
Στην προσπάθεια αυτή τον κύριο ρόλο παίζει ο δέκτης GPS. Έγινε επιλογή του νέου δέκτη zed-f9p της UBLOX ο οποίος έχει τα παρακάτω χαρακτηριστικά :
184 κανάλια GPS L1/L2 - GLONASS L1/L2 - GALILEO E1/E5 - BDS B1/B2 και QZSS L1/L2
RTK 20 hz
INPUT : UBX - RTCM 3.x
OUTPUT : NMEA - UBX - RTCM 3.x
Αποκτήθηκε μία μονάδα η οποία έχει USB και UART με κόστος 210 € :
Από το πίσω μέρος της μονάδας επιλέχτηκαν οι ακροδέκτες του UART και έγιναν οι ανάλογες κολλήσεις. Η έξοδος του UART συνδέθηκε με USB to UART προκειμένου να έχουμε δύο θύρες USB στη μονάδα του GPS.
Ως κεραία επιλέχθηκε μία Hg-Goyh7201 Rtk Cors Station Gnss Antenna στα 70 περίπου ευρώ.
Προχωράμε στα μικρο-υλικά :
Διακόπτης ON-OFF χωνευτός :
LED:
4 πράσινου χρώματος και ένα κόκκινου.
Στο κόκκινο led μπήκε σε σειρά μία αντίσταση 100 Ohm καθώς η τάση που θέλει το κόκκινο χρώμα είναι μικρότερη
Ένα RGB LED με 4 "πόδια". Ομοίως στο κόκκινο μπήκε αντίσταση 100 Ohm.
και ένα power bank 5000 mah και πάνω.
ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ του zed-f9p
Μέσω του προγράμματος U-CENTER της UBLOX έγινε ο προγραμματισμός του δέκτη GPS. Η έξοδος USB ορίστηκε σε έξοδος NMEA και η έξοδος UART σε είσοδο RTCM3 και έξοδο NMEA.
Η ώρα του RASPBERRY
Στο project έγινε χρήση ενός rasperry pi 3 B+ αν και μπορεί να χρησιμοποιηθεί και το 4 και πιθανόν το zero w.Αρχικά έγινε εγκατάσταση του Raspian
Στη συνέχεια από εδώ κατεβάσαμε το RTKLIB και εγκαταστήσαμε το str2str με τις παρακάτω εντολές :
cd rtklib/app/str2str/gcc
make
sudo cp str2str /usr/local/bin/str2str
sudo chmod +x /usr/local/bin/str2str
ενώ έγινε και εγκατάσταση του SOCAT με τις παρακάτω εντολές :
sudo apt-get update
sudo apt-get install socat
ενώ έγινε και εγκατάσταση του προγράμματος interceptty
Δημιουργούμε τους κανόνες tty για να αναφερόμαστε στη συσκευή GPS.
sudo nano /etc/udev/rules.d/10-myrules.rules
Αυτή η εντολή μας ανοίγει ένα επεξεργαστή κειμένου στον οποίο προσθέτουμε τα παρακάτω :
SUBSYSTEM=="tty",ATTRS{idVendor}=="10c4",ATTRS{idProduct}=="ea60",SYMLINK+="ttyLINK"
SUBSYSTEM=="tty",ATTRS{idVendor}=="1546",ATTRS{idProduct}=="01a9",SYMLINK+="ttyGPS"
SUBSYSTEM=="tty",ATTRS{idVendor}=="1546",ATTRS{idProduct}=="01a9",SYMLINK+="ttyGPS"
και κάνουμε επανεκκίνηση.
όπου στο αρχείο rtk2.sh αντικαθιστούμε τα USERNAME , PASSWORD , IP-ADDRESS , MOUND με τα δικά μας από το δίκτυο διορθώσεων που έχουμε. Καλό είναι να βάλουμε στο MOUND το moundpoint που μας δίνει VRS
Τέλος αφού κάνουμε τα αρχεία εκτελέσιμα με την εντολή chmod τα βάζουμε να εκτελούνται αυτόματα με την εκκίνηση κάνοντας τις ανάλογες αλλαγές στο lxsession/lxde-pi/autostart
Τελειώνοντας προσθέτουμε τον κώδικα python σε ένα νέο αρχείο RTK.py στο path /home/pi :
------------------------------------------------------------------------------------------------------------------------
import os
import serial
import pynmea2
from pygame import mixer
from gpiozero import LED
import time
mixer.init()
alert=mixer.Sound('/home/pi/Wellcome.wav')
alert.play()
time.sleep(1.5)
duration = alert.get_length()
time.sleep(duration)
port = "/dev/ttyDUMMY"
Fix=0
kNO = 0
kAUTO = 0
kFIX = 0
kFLOAT = 0
kDGPS = 0
kkk=0
# serialPort = serial.Serial(port, baudrate = 38400 )
red = LED(23)
blue = LED(24)
green = LED(25)
sat4 = LED(26)
sat6 = LED(19)
sat8 = LED(13)
sat10 = LED(6)
sat12 = LED(5)
sat4.off()
sat6.off()
sat8.off()
sat10.off()
sat12.off()
OK = 0
red.on()
sat4.on()
OP = 0
while OK < 1 :
try:
serialPort = serial.Serial(port, baudrate = 38400 )
OK = 1
except serial.SerialException:
# print ("WAIT",OP)
if OP < 100000 :
OP = OP + 1
else :
alert=mixer.Sound('/home/pi/STOP.wav')
alert.play()
time.sleep(1.5)
duration = alert.get_length()
time.sleep(duration)
os.system('sudo reboot')
serialPort.reset_input_buffer()
k3=0
while True:
str = serialPort.readline()
#print (str)
if str.find('GGA') > 0 and k3 > 50 :
serialPort.reset_input_buffer()
print ('------------------------------------------------------------------------------------------------------')
k3=0
else :
k3=k3+1
if str.find('GGA') > 0 :
try:
msg = pynmea2.parse(str)
Fix = msg.gps_qual
kkk=kkk+1
sat1= msg.num_sats
if sat1 == "00" or sat1 == "0" or sat1 == "":
sat = 0
sat4.off()
sat6.off()
sat8.off()
sat10.off()
sat12.off()
else :
sat = int(float(sat1))
if sat >0 and sat <= 4 :
sat4.on()
sat6.off()
sat8.off()
sat10.off()
sat12.off()
if sat > 4 and sat <= 6 :
sat4.on()
sat6.on()
sat8.off()
sat10.off()
sat12.off()
if sat > 6 and sat <= 8 :
sat4.on()
sat6.on()
sat8.on()
sat10.off()
sat12.off()
if sat > 8 and sat <= 10 :
sat4.on()
sat6.on()
sat8.on()
sat10.on()
sat12.off()
if sat > 10 :
sat4.on()
sat6.on()
sat8.on()
sat10.on()
sat12.on()
if Fix == 0 and kNO == 0 and kkk >= 30 :
print ("No Possition")
red.on()
blue.off()
green.off()
alert=mixer.Sound('/home/pi/NO.wav')
alert.play()
time.sleep(1.5)
duration = alert.get_length()
time.sleep(duration)
kNO = 1
kAUTO = 0
kFIX = 0
kFLOAT = 0
kDGPS = 0
#serialPort.reset_input_buffer()
if Fix == 1 and kAUTO == 0:
print ("AUTO")
red.on()
blue.off()
green.off()
alert=mixer.Sound('/home/pi/AUTO.wav')
alert.play()
time.sleep(1.5)
duration = alert.get_length()
time.sleep(duration)
kNO=0
kAUTO = 1
kFIX = 0
kFLOAT = 0
kDGPS = 0
#serialPort.reset_input_buffer()
if Fix == 2 and kDGPS == 0:
print ("DGPS")
red.on()
blue.off()
green.off()
alert=mixer.Sound('/home/pi/DGPS.wav')
alert.play()
time.sleep(1.5)
duration = alert.get_length()
time.sleep(duration)
kNO = 0
kAUTO = 0
kFIX = 0
kFLOAT = 0
kDGPS = 1
#serialPort.reset_input_buffer()
if Fix == 5 and kFLOAT == 0:
print ("float")
red.off()
blue.on()
green.off()
alert=mixer.Sound('/home/pi/Float.wav')
alert.play()
time.sleep(1.5)
duration = alert.get_length()
time.sleep(duration)
kNO = 0
kAUTO = 0
kFIX = 0
kFLOAT = 1
kDGPS = 0
#serialPort.reset_input_buffer()
if Fix == 4 and kFIX == 0:
print ("FIX")
red.off()
blue.off()
green.on()
alert=mixer.Sound('/home/pi/fix.wav')
alert.play()
time.sleep(1.5)
duration = alert.get_length()
time.sleep(duration)
kNO = 0
kAUTO = 0
kFIX = 1
kFLOAT = 0
kDGPS = 0
#serialPort.reset_input_buffer()
print "Timestamp: %s -- Lat: %s %s -- Lon: %s %s -- Altitude: %s %s -- Satellites: %s -- GPS : %s " % (msg.timestamp,msg.lat,msg.lat_dir,msg.lon,msg.lon_dir,msg.altitude,msg.altitude_units,msg.num_sats,msg.gps_qual)
except pynmea2.nmea.ChecksumError:
print('')
serialPort.reset_input_buffer()
except AttributeError:
print('')
serialPort.reset_input_buffer()
except pynmea2.nmea.ParseError:
print('Unable to parse data, trying again.')
serialPort.reset_input_buffer()
--------------------------------------------------------------------------------------------------------------------------
Για να μην γίνει λάθος αντιγραφή ολόκληρο το αρχείο βρίσκεται εδώ : https://drive.google.com/open?id=16iE48zcua7CmS0tKcVVePEtOPiiQIQRU
Θα πρέπει να εγκαταστήσουμε φυσικά τις δυνατότητες pyserial , pygame , gpozero και pynmea2 του Python πριν εκτελέσουμε το αρχείο.
Τέλος στο path /home/pi θα πρέπει να βάλουμε κάποια αρχεία wav.
το Wellcome.wav που θα παίζει με το ξεκίνημα.
το STOP.wav που παίζει όταν υπάρχει γενικό σφάλμα
το NO.wav όταν δεν υπάρχει σήμα GPS
το AUTO.wav όταν δεν υπάρχει RTK λύση.
το DGPS.wav για απλή διαφορική λύση.
το Float.wav για λύση Float
το fix.wav για fix λύση.
Για την δημιουργεία τους μπορείτε να κάνετε ηχογράφιση ή έτοιμους ήχους.
Φυσικά για να παίξει ο ήχος θέλει ....ηχεία.
Τέλος τα συνδέουμε ολα μαζί ως παρακάτω:
ΤΟ ΚΟΥΤΙ
Για το κουτί έγινε 3D σχεδιασμός στα κομάτια που βλέπουμε παρακάτω :
και ..... εκτύπωση σε 3D Printer
έγιναν οι συνέσεις των επιμέρους στοιχείων :
Τοποθετήθηκαν όλα στο κουτί και το τελικό αποτέλεσμα ήταν :
Για την λειτουργεία του έγινε χρήση ενός Android Tablet το οποίο λειτουγεί και ως hotspot για το GPS και με χρήση του προγράμματος για καταγραφή MyRTK STD της TopoDeSia.
Φυσικά είναι δυνατό να φτιαχτεί πρόγραμμα καταγρφής σε Android με χρήση python και το pnmea2 αλλά δεν θα ανακαλύψουμε τον τροχό από την αρχή.
ΔΟΚΙΜΗ ΑΚΡΙΒΕΙΑΣ
Για την δοκιμή του οργάνου έγινε μέτρηση σε τρία τριγωνομετρικά ΓΥΣ με υπολογισμό μέσου όρου μετρήσεων 120 sec σε κάθε τριγωνομετρικό. Για την ορθότητα των υπολογισμών το moundpoint ορίστικε σε RTK (σταθερή βάση) και όχι VRS. Υπολογίστικαν οι αποστάσεις απο τις συνεταγμένες των τριγωνομετρικών σε ΕΓΣΑ και έγινε σύγκριση με τις αποστάσεις των συντεταγμένων του GPS. Η αποκλιση που υπολογίστικε ήταν 0.012 m + 1 ppm που συμπίτει περίπου με την ακρίβεια του Product summary του zed-f9p που είναι 0.01 m + 1 ppm.
Με Λίγα Λόγια :
με κλίμακα 1-5
Δυσκολία κατασκευής κυκλώματος : 2
Δυσκολία προγραμματισμού : 3
Δυσκολία μονταρίσματος : 3
Τελικό αποτέλεσμα ..... αναμένεται.
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου