GNSS La tecnología RTK se puede utilizar en muchas aplicaciones. Normalmente, se toman medidas y luego se exportan a una computadora para analizar los datos. Este es el caso más común.
Pero para ciertas aplicaciones, es posible que necesite enviar sus datos GNSS RTK a su computadora/servidor en tiempo real, para poder tomar medidas inmediatamente sin tener que esperar algunas horas para procesar los datos.
Las aplicaciones populares que requieren el envío de la posición en tiempo real a un servidor incluyen: gestión de flotas y logística, transporte público y de pasajeros, seguimiento de activos, monitoreo de vida silvestre, …
En este tutorial, explicaremos cómo configurar un servidor con Node-RED, que es una herramienta popular para la programación visual, para que puedas comenzar tu propio proyecto, también cubriremos cómo configurar tu receptor GNSS y el complemento para enviar los datos a este servidor.
Hardware requerido
- Servidor Linux remoto
Aunque usaremos lo anterior en nuestro ejemplo, también puedes ejecutar Node-RED localmente en una máquina Windows/Linux, en una RaspberryPi, Docker, Android, Cloud, … - Android smartphone
- RTK Portable Bluetooth Kit
- Como alternativa, cualquier otro receptor GNSS con 4G NTRIP Domina el, WiFi NTRIP Master or Ethernet NTRIP Master plugins
Programa requerido
- GNSS Master aplicación para Android
Instalación de Node-RED
Servidor Linux remoto
En nuestro caso estamos utilizando la distribución AlmaLinux.
Abra una terminal en su servidor y ejecute los siguientes comandos:
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
Puede comprobar si la instalación se realizó correctamente escribiendo:/usr/local/bin/node-red --version
Si todo está bien, verás la versión mostrada en la terminal.
Otros dispositivos/sistemas operativos
Puede encontrar instrucciones en la página oficial del proyecto Node-RED para diferentes sistemas.
Abra el puerto TCP en su servidor
Puede que esto no siempre sea necesario, pero es posible que necesites abrir el puerto TCP para permitir conexiones entrantes.
Utilizaremos el puerto TCP 2222 durante todo este ejemplo, deberás escribir en la terminal de tu servidor:iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
Ejecutar Node-RED
Escriba este comando: /usr/local/bin/node-red &
Vaya a su navegador y escriba:
172.123.123.123:1880
Donde 172.123.123.123 debe ser la dirección IP de su servidor.
Si todo está bien, deberías ver algo como esto:
Prepara tu primer flujo
En Node-RED, los proyectos se llaman Flujos.
Prepararemos un nuevo flujo para escuchar las conexiones TCP entrantes e imprimir lo que se reciba en una ventana de depuración.
Busque en el panel izquierdo el nodo llamado tcp en, arrástrelo y suéltelo en el lienzo de flujo.
Busca también el depurar nodo y conectarlos entre sí de esta manera:
En Node-RED, los proyectos se llaman Flujos.
Prepararemos un nuevo flujo para escuchar las conexiones TCP entrantes e imprimir lo que se reciba en una ventana de depuración.
Busque en el panel izquierdo el nodo llamado tcp en, arrástrelo y suéltelo en el lienzo de flujo.
Busca también el depurar nodo y conectarlos entre sí de esta manera:
Haga doble clic en el nodo TCP y configure el puerto TCP donde desea escuchar, en este ejemplo: 2222.
Establezca también para transmitir cadenas delimitadas por \r\n.
Después de hacer esto Haga clic en el botón Implementar en la esquina superior derecha de la pantalla.
Este botón ejecutará los bloques después de cualquier modificación.
Conecte su receptor GNSS a Node-RED
RTK Portable Bluetooth Kit con dispositivo Android
- Conecte su Kit Bluetooth Portátil vía BT a su dispositivo Android.
- Abierto GNSS Master aplicación, conéctese al módulo BT en Conexión del receptor GNSS.
- Establezca la entrada de corrección si es necesario
- En la salida de datos del receptor, seleccione Cliente TCP e ingrese la dirección IP de su servidor en Dirección TCP y 2222 en Puerto TCP. Haga clic en Conectar.
- Eso es todo, si haces doble clic en la ventana de depuración en Node-RED deberías ver algo como esto, con todos los datos recibidos:
Otros receptores GNSS con complementos 4G, WiFi o Ethernet
Si tienes un receptor GNSS diferente también puedes lograr los mismos resultados, incluso sin un dispositivo Android.
Asegúrate de enviar al puerto COM del complemento XBee los mensajes que deseas enviar a tu servidor, normalmente deseas enviar, al menos, NMEA GGA.
Luego, configura tu 4G, WiFi o Ethernet NTRIP Master Complementos con la funcionalidad de cliente TCP con los mismos parámetros que hemos utilizado anteriormente, el servidor TCP es la dirección IP de su servidor, el puerto TCP es 2222.
Así de simple 🙂
Hacer algo con los datos
Bueno, hasta ahora no es muy emocionante ¿verdad?
Está bien ver transmisiones NMEA en vivo en su servidor, pero queremos ver algunas de las capacidades de Node-RED.
En el siguiente ejemplo, le mostraremos cómo analizar el flujo de entrada para obtener la latitud y la longitud y trazaremos la ubicación en vivo en un mapa con un rastro que muestra las ubicaciones antiguas.
En primer lugar, elimine su flujo actual.
Haga clic en el menú superior derecho > Administrar paleta > Instalar > buscar node-red-contrib-web-worldmap e instalarlo.
Regrese al menú > Importar > Portapapeles y pegue el siguiente código:
[
{
"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": []
}
]
Debería ver algo como esto:
Haga doble clic en el nodo del mapa mundial.
En el menú desplegable de la lista Mapa, seleccione OpenStreetMap u otra capa, haga clic en Listo:
Presione la tecla Despliegue .
Puedes acceder desde tu navegador al mapa en vivo aquí:
172.123.123.123:1880/mapamundi/
donde la dirección IP debe ser la misma que la de su servidor.
Verá un mapa con un marcador que muestra la ubicación de su receptor GNSS, actualizándose en tiempo real, puede acercar o alejar la imagen a su gusto.
Te recomendamos que eches un vistazo a cada uno de los nodos de tu flujo para entender mejor qué hacen, modificarlos y ver qué cambia.
Encontrarás muchos tutoriales y herramientas de IA que también te ayudarán si quieres hacer algo un poco más avanzado.
¡Que se diviertan!
Si desea apagar Node-RED, haga lo siguiente:iptables -A INPUT -p tcp --dport 2222 -j REJECT
tipo ps aux | grep node , encuentre el proceso del nodo si y elimine el proceso mediante:kill NODE_PROCESS_ID