GNSS La tecnologia RTK può essere utilizzata in numerose applicazioni. Solitamente si effettuano delle misurazioni e poi si esportano i dati su un computer per analizzarli. Questo è il caso più comune.
Tuttavia, per alcune applicazioni potrebbe essere necessario inviare i dati GNSS RTK al computer/server in tempo reale, in modo da poter intervenire immediatamente senza dover attendere alcune ore per elaborare i dati.
Le applicazioni più diffuse che richiedono l'invio della posizione in tempo reale a un server includono: gestione della flotta e logistica, servizi di ride-hailing e trasporto pubblico, tracciamento delle risorse, monitoraggio della fauna selvatica, …
In questo tutorial spiegheremo come configurare un server con Node-RED, uno strumento popolare per la programmazione visuale, in modo che tu possa avviare il tuo progetto. Spiegheremo anche come configurare il tuo ricevitore GNSS e il plugin per inviare i dati a questo server.
Hardware richiesto
- Server Linux remoto
Sebbene nel nostro esempio utilizzeremo quanto sopra, puoi anche eseguire Node-RED localmente su una macchina Windows/Linux, su un RaspberryPi, Docker, Android, Cloud, … - Android smartphone
- RTK Portable Bluetooth Kit
- In alternativa, qualsiasi altro ricevitore GNSS con 4G NTRIP Master, WiFi NTRIP Master or Ethernet NTRIP Master i plugin
Software richiesto
- GNSS Master app per Android
Installazione di Node-RED
Server Linux remoto
Nel nostro caso utilizziamo la distribuzione AlmaLinux.
Apri un terminale sul tuo server ed esegui i seguenti comandi:
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
Puoi verificare se l'installazione è riuscita digitando:/usr/local/bin/node-red --version
Se tutto è ok, vedrai la versione visualizzata sul terminale.
Altri dispositivi/OS
Puoi trovare le istruzioni sulla pagina ufficiale del progetto Node-RED per sistemi diversi.
Apri la porta TCP sul tuo server
Questo potrebbe non essere sempre necessario, ma potrebbe essere necessario aprire la porta TCP per consentire le connessioni in entrata.
In questo esempio utilizzeremo la porta TCP 2222, sul terminale del server dovresti digitare:iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
Esegui Node-RED
Digita questo comando: /usr/local/bin/node-red &
Vai al tuo browser e digita:
172.123.123.123:1880
Dove 172.123.123.123 deve essere l'indirizzo IP del tuo server.
Se tutto è a posto, dovresti vedere qualcosa di simile a questo:
Prepara il tuo primo flusso
In Node-RED i progetti sono chiamati Flussi.
Prepareremo un nuovo flusso per ascoltare le connessioni TCP in arrivo e per stampare tutto ciò che viene ricevuto in una finestra di debug.
Cerca nel pannello di sinistra il nodo chiamato tcp in, trascinalo e rilascialo sulla tela del flusso.
Cerca anche il mettere a punto nodo e collegarli insieme in questo modo:
In Node-RED i progetti sono chiamati Flussi.
Prepareremo un nuovo flusso per ascoltare le connessioni TCP in arrivo e per stampare tutto ciò che viene ricevuto in una finestra di debug.
Cerca nel pannello di sinistra il nodo chiamato tcp in, trascinalo e rilascialo sulla tela del flusso.
Cerca anche il mettere a punto nodo e collegarli insieme in questo modo:
Fare doppio clic sul nodo TCP e impostare la porta TCP su cui si desidera ascoltare, in questo esempio: 2222.
Imposta anche per trasmettere in streaming le stringhe delimitate da \r\n.
Dopo aver fatto questo fare clic sul pulsante Distribuisci in alto a destra sullo schermo.
Questo pulsante eseguirà i blocchi dopo ogni modifica.
Collega il tuo ricevitore GNSS a Node-RED
RTK Portable Bluetooth Kit con dispositivo Android
- Collega il tuo kit Bluetooth portatile tramite BT al tuo dispositivo Android.
- Apri GNSS Master app, connettersi al modulo BT in Connessione ricevitore GNSS.
- Imposta l'input di correzione se necessario
- In Output dati del ricevitore, seleziona Client TCP e inserisci l'indirizzo IP del tuo server in Indirizzo TCP e 2222 in Porta TCP. Fai clic su Connetti.
- Ecco fatto, se fai doppio clic sulla finestra di debug in Node-RED dovresti vedere qualcosa di simile a questo, con tutti i dati ricevuti:
Altri ricevitori GNSS con plugin 4G, WiFi o Ethernet
Se si dispone di un ricevitore GNSS diverso, è possibile ottenere gli stessi risultati anche senza un dispositivo Android.
Assicurati di inviare alla porta COM del plugin XBee i messaggi che vuoi inviare al tuo server, di solito vuoi inviare almeno, NMEA GGA.
Quindi, configura il tuo 4G, WiFi o Ethernet NTRIP Master plugin con funzionalità client TCP con gli stessi parametri di quelli usati in precedenza, il server TCP è l'indirizzo IP del server, la porta TCP è 2222.
Semplicemente così 🙂
Fai qualcosa con i dati
Ok, finora non è stato molto entusiasmante, vero?
È accettabile vedere flussi NMEA in tempo reale sul tuo server, ma vogliamo vedere alcune delle funzionalità di Node-RED.
Nel prossimo esempio, ti mostreremo come analizzare il flusso di input per ottenere latitudine e longitudine e tracceremo la posizione in tempo reale su una mappa con una traccia che mostra le posizioni precedenti.
Per prima cosa, elimina il flusso attuale.
Fare clic sul menu in alto a destra > Gestisci palette > Installa > cercare nodo-rosso-contrib-web-mappa-del-mondo e installarlo.
Torna al menu > Importa > Appunti e incolla il seguente codice:
[
{
"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": []
}
]
Dovresti vedere qualcosa di simile a questo:
Fare doppio clic sul nodo della mappa del mondo.
Nel menu a discesa Elenco mappe, seleziona OpenStreetMap o un altro livello, quindi fai clic su Fine:
Premere il tasto Schierare pulsante.
Puoi accedere alla mappa live dal tuo browser qui:
172.123.123.123:1880/mappa del mondo/
dove l'indirizzo IP deve essere lo stesso del tuo server.
Vedrai una mappa con un indicatore che mostra la posizione del tuo ricevitore GNSS, aggiornata in tempo reale; puoi ingrandire o ridurre la visualizzazione a tuo piacimento.
Ti consigliamo di dare un'occhiata a ciascuno dei nodi del tuo flusso per capire meglio a cosa servono, modificarli e vedere cosa cambia.
Troverai molti tutorial e strumenti di intelligenza artificiale che ti aiuteranno anche se vuoi fare qualcosa di un po' più avanzato.
Divertiti!
Se vuoi arrestare Node-RED, procedi come segue:iptables -A INPUT -p tcp --dport 2222 -j REJECT
Digitare ps aux | grep node , trova il processo del nodo se e uccidi il processo tramite:kill NODE_PROCESS_ID
e
