GNSS RTK-technologie kan in veel toepassingen worden gebruikt. Meestal voert u enkele metingen uit en exporteert u deze vervolgens naar een computer om de gegevens te analyseren. Dit is het meest voorkomende geval.
Voor bepaalde toepassingen kan het echter nodig zijn om uw GNSS RTK-gegevens in realtime naar uw computer/server te sturen, zodat u direct actie kunt ondernemen en niet uren hoeft te wachten op de verwerking van de gegevens.
Populaire toepassingen waarbij de positie in realtime naar een server moet worden verzonden, zijn onder meer: wagenparkbeheer en logistiek, taxidiensten en openbaar vervoer, het volgen van activa, het monitoren van wilde dieren, …
In deze tutorial leggen we uit hoe je een server instelt met Node-RED, een populaire tool voor visuele programmering, zodat je je eigen project kunt starten. We leggen ook uit hoe je je GNSS-ontvanger en plug-in configureert om de gegevens naar deze server te sturen.
Vereiste hardware
- Externe Linux-server
Hoewel we in ons voorbeeld het bovenstaande gebruiken, kunt u Node-RED ook lokaal uitvoeren op een Windows/Linux-machine, op een Raspberry Pi, Docker, Android, Cloud, … - Android smartphone
- RTK Portable Bluetooth Kit
- Als alternatief kan elke andere GNSS-ontvanger met 4G NTRIP Master, WiFi NTRIP Master or Ethernet NTRIP Master plugins
Vereiste software
- GNSS Master app voor Android
Installatie van Node-RED
Externe Linux-server
In ons geval gebruiken we de AlmaLinux-distributie.
Open een terminal op uw server en voer de volgende opdrachten uit:
sudo dnf module reset -y nodejs
sudo dnf module enable -y nodejs:20
sudo dnf install -y nodejs npm gcc-c++ make
# then:
sudo npm i -g --unsafe-perm node-red
U kunt controleren of de installatie succesvol is door het volgende te typen:/usr/local/bin/node-red --version
Als alles in orde is, ziet u de versie op de terminal.
Andere apparaten/besturingssystemen
Instructies vindt u op de officiële Node-RED-projectpagina voor verschillende systemen.
Open de TCP-poort op uw server
Dit is niet altijd nodig, maar het kan nodig zijn om de TCP-poort te openen om inkomende verbindingen toe te staan.
In dit voorbeeld gebruiken we TCP-poort 2222. Typ het volgende in uw serverterminal:iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
Voer Node-RED uit
Typ deze opdracht: /usr/local/bin/node-red &
Ga naar uw browser en typ:
172.123.123.123:1880
Hierbij moet 172.123.123.123 het IP-adres van uw server zijn.
Als alles in orde is, ziet u zoiets:
Bereid je eerste flow voor
In Node-RED worden projecten Flows genoemd.
We gaan een nieuwe stroom voorbereiden die luistert naar binnenkomende TCP-verbindingen en alles wat ontvangen wordt, afdrukt in een debugvenster.
Zoek op het linkerpaneel naar het knooppunt genaamd tcp in, sleep het naar het flowcanvas en zet het neer.
Zoek ook de debug knooppunt en verbind ze als volgt met elkaar:
In Node-RED worden projecten Flows genoemd.
We gaan een nieuwe stroom voorbereiden die luistert naar binnenkomende TCP-verbindingen en alles wat ontvangen wordt, afdrukt in een debugvenster.
Zoek op het linkerpaneel naar het knooppunt genaamd tcp in, sleep het naar het flowcanvas en zet het neer.
Zoek ook de debug knooppunt en verbind ze als volgt met elkaar:
Dubbelklik op TCP in Node en stel de TCP-poort in waarnaar u wilt luisteren, in dit voorbeeld: 2222.
Ook in te stellen op streamstrings gescheiden door \r\n.
Nadat je dit hebt gedaan Klik op de knop Implementeren rechtsboven in het scherm.
Met deze knop worden de blokken na elke wijziging uitgevoerd.
Sluit uw GNSS-ontvanger aan op Node-RED
RTK Portable Bluetooth Kit met Android-apparaat
- Verbind uw draagbare Bluetooth-kit via BT met uw Android-apparaat.
- Open GNSS Master app, maak verbinding met de BT-module in GNSS-ontvangerverbinding.
- Stel indien nodig correctie-invoer in
- Selecteer bij 'Ontvangergegevensuitvoer' de optie 'TCP-client' en voer het IP-adres van uw server in bij 'TCP-adres' en 2222 bij 'TCP-poort'. Klik op 'Verbinden'.
- Dat is alles. Als u dubbelklikt op het debugvenster in Node-RED, zou u zoiets moeten zien, waarbij alle gegevens worden ontvangen:
Andere GNSS-ontvangers met 4G-, WiFi- of Ethernet-plug-ins
Als u over een andere GNSS-ontvanger beschikt, kunt u dezelfde resultaten behalen, zelfs zonder Android-apparaat.
Zorg ervoor dat u de berichten die u naar uw server wilt sturen naar de COM-poort van de XBee-plug-in stuurt. Meestal wilt u op zijn minst de berichten verzenden die u naar uw server wilt sturen. NMEA GGA.
Configureer vervolgens uw 4G, WiFi of Ethernet NTRIP Master plugins met de TCP-clientfunctionaliteit met dezelfde parameters als we eerder hebben gedaan, TCP-server is het IP-adres van uw server, TCP-poort is 2222.
Zo simpel is het 🙂
Doe iets met de data
Oké, tot nu toe is het niet zo heel spannend, toch?
U kunt de NMEA-streams live op uw server bekijken, maar we willen graag een aantal mogelijkheden van Node-RED zien.
In het volgende voorbeeld laten we u zien hoe u de invoerstroom kunt parseren om de breedtegraad en lengtegraad te verkrijgen. Ook zetten we de actuele locatie uit op een kaart met een trace die de oude locaties weergeeft.
Verwijder eerst uw huidige stroom.
Klik op het menu rechtsboven > Palet beheren > Installeren > zoek naar node-red-contrib-web-wereldkaart en installeren.
Ga terug naar het menu > Importeren > Klembord en plak de volgende code:
[
{
"id": "tab1",
"type": "tab",
"label": "GNSS Live Map + Track",
"disabled": false,
"info": ""
},
{
"id": "tcpInNmea2222",
"type": "tcp in",
"z": "tab1",
"name": "NMEA TCP 2222",
"server": "server",
"host": "",
"port": "2222",
"datamode": "stream",
"datatype": "utf8",
"newline": "\\r\\n",
"topic": "",
"base64": false,
"x": 150,
"y": 140,
"wires": [
[
"fnGGA"
]
]
},
{
"id": "fnGGA",
"type": "function",
"z": "tab1",
"name": "Filter GGA → {lat,lon}",
"func": "// Allman style\nfunction nmeaToDecimal(raw, hemi)\n{\n if (!raw || !hemi)\n {\n return null;\n }\n const isLat = (hemi === 'N' || hemi === 'S');\n const degDigits = isLat ? 2 : 3;\n const deg = parseInt(raw.slice(0, degDigits), 10);\n const min = parseFloat(raw.slice(degDigits));\n if (Number.isNaN(deg) || Number.isNaN(min))\n {\n return null;\n }\n let dec = deg + (min / 60.0);\n if (hemi === 'S' || hemi === 'W')\n {\n dec = -dec;\n }\n return dec;\n}\n\nif (typeof msg.payload !== 'string')\n{\n return null;\n}\n\nconst line = msg.payload.trim();\nif (!line.startsWith('$') || line.indexOf('GGA,') === -1)\n{\n return null;\n}\n\nconst f = line.split(',');\nconst lat = nmeaToDecimal(f[2], f[3]);\nconst lon = nmeaToDecimal(f[4], f[5]);\nif (lat == null || lon == null)\n{\n return null;\n}\n\nmsg.payload = { lat, lon };\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 410,
"y": 140,
"wires": [
[
"fnToWorldmap"
]
]
},
{
"id": "fnToWorldmap",
"type": "function",
"z": "tab1",
"name": "Marker + Track",
"func": "// Input: msg.payload={lat,lon}\n// Output1 → worldmap marker\n// Output2 → worldmap-tracks polyline (then wired into worldmap)\n\nif (!msg.payload || msg.payload.lat == null || msg.payload.lon == null)\n{\n return null;\n}\n\nconst lat = Number(msg.payload.lat);\nconst lon = Number(msg.payload.lon);\nconst name = \"GPS-1\"; // keep constant per device\nconst now = Date.now();\n\nconst base =\n{\n name: name,\n lat: lat,\n lon: lon,\n layer: \"GNSS\",\n time: now, // helps pruning\n icon: \"fa-location-arrow\",\n popup: `Lat: ${lat.toFixed(6)}
Lon: ${lon.toFixed(6)}
UTC: ${new Date(now).toISOString()}`\n};\n\nreturn [ { payload: base }, { payload: base } ];",
"outputs": 2,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 650,
"y": 140,
"wires": [
[
"worldmap",
"dbgMarker"
],
[
"tracks"
]
]
},
{
"id": "tracks",
"type": "worldmap-tracks",
"z": "tab1",
"name": "Track GNSS (layer GNSS)",
"depth": "1000",
"layer": "GNSS",
"doors": "",
"x": 930,
"y": 180,
"wires": [
[
"worldmap"
]
]
},
{
"id": "worldmap",
"type": "worldmap",
"z": "tab1",
"name": "Live Map (/worldmap)",
"lat": "0",
"lon": "0",
"zoom": "2",
"layer": "OSM",
"cluster": "",
"maxage": "",
"usermenu": "show",
"layers": "show",
"panit": "false",
"panlock": "false",
"zoomlock": "false",
"hiderightclick": "false",
"coords": "none",
"showgrid": "false",
"showruler": "false",
"showlayer": "true",
"showmenu": "true",
"path": "/worldmap",
"overlist": "DR,CO,RA,DN,HM",
"maplist": "OSM,Esri Terrain,Esri Satellite",
"mapname": "",
"mapurl": "",
"mapopt": "",
"kmlurl": "",
"devicelabel": "name",
"layercontrol": "false",
"x": 930,
"y": 120,
"wires": []
},
{
"id": "dbgMarker",
"type": "debug",
"z": "tab1",
"name": "Marker payload",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"statusVal": "",
"statusType": "auto",
"x": 930,
"y": 220,
"wires": []
},
{
"id": "hint",
"type": "comment",
"z": "tab1",
"name": "Send NMEA (\\r\\n delimited) to TCP 2222. Open http://:1880/worldmap",
"info": "",
"x": 330,
"y": 90,
"wires": []
}
]
Je zou zoiets als dit moeten zien:
Dubbelklik op het wereldkaartknooppunt.
Selecteer OpenStreetMap of een andere laag in de vervolgkeuzelijst Kaart en klik op Gereed:
Druk op de Implementeren knop.
Via uw browser kunt u hier toegang krijgen tot de livekaart:
172.123.123.123:1880/wereldkaart/
waarbij het IP-adres hetzelfde moet zijn als dat van uw server.
U ziet een kaart met een markering die de locatie van uw GNSS-ontvanger aangeeft. Deze kaart wordt in realtime bijgewerkt en u kunt naar wens in- en uitzoomen.
Wij raden u aan om elk van de knooppunten in uw stroom te bekijken om beter te begrijpen wat ze doen, ze aan te passen en te zien welke veranderingen er zijn.
Er zijn ook tal van tutorials en AI-tools beschikbaar die u kunnen helpen als u iets geavanceerder wilt doen.
Veel plezier!
Als u Node-RED wilt afsluiten, doet u het volgende:iptables -A INPUT -p tcp --dport 2222 -j REJECT
type dan: ps aux | grep node , vind het knooppuntproces en beëindig het proces door:kill NODE_PROCESS_ID