GNSS A tecnologia RTK pode ser usada em muitas aplicações. Normalmente, você faz algumas medições e as exporta para um computador para analisar os dados. Este é o caso mais comum.
Mas, para certas aplicações, pode ser necessário enviar seus dados GNSS RTK para seu computador/servidor em tempo real, para que você possa tomar ações imediatamente, sem esperar algumas horas para processar os dados.
Aplicações populares que exigem que a posição em tempo real seja enviada para um servidor incluem: gerenciamento de frotas e logística, transporte por aplicativo e transporte público, rastreamento de ativos, monitoramento de vida selvagem, …
Neste tutorial, explicaremos como configurar um servidor com o Node-RED, que é uma ferramenta popular para programação visual, para que você possa iniciar seu próprio projeto. Também abordaremos como configurar seu receptor GNSS e plugin para enviar os dados para este servidor.
Hardware necessário
- Servidor Linux remoto
Embora usaremos o acima em nosso exemplo, você também pode executar o Node-RED localmente em uma máquina Windows/Linux, em um RaspberryPi, Docker, Android, Nuvem, … - Android smartphone
- RTK Portable Bluetooth Kit
- Como alternativa, qualquer outro receptor GNSS com 4G NTRIP Mestre, WiFi NTRIP Master or Ethernet NTRIP Master plugins
Software necessário
- GNSS Master app para Android
Instalação do Node-RED
Servidor Linux remoto
No nosso caso, estamos usando a distribuição AlmaLinux.
Abra um terminal no seu servidor e execute os seguintes 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
Você pode verificar se a instalação foi bem-sucedida digitando:/usr/local/bin/node-red --version
Se tudo estiver ok, você verá a versão exibida no terminal.
Outros dispositivos/SO
Você pode encontrar instruções na página oficial do projeto Node-RED para sistemas diferentes.
Abra a porta TCP no seu servidor
Isso pode não ser sempre necessário, mas pode ser necessário abrir a porta TCP para permitir conexões de entrada.
Usaremos a porta TCP 2222 durante todo este exemplo, você deve digitar no terminal do seu servidor:iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
Execute o Node-RED
Digite este comando: /usr/local/bin/node-red &
Acesse seu navegador e digite:
172.123.123.123:1880
Onde 172.123.123.123 deve ser o endereço IP do seu servidor.
Se tudo estiver ok, você deverá ver algo assim:
Prepare seu primeiro fluxo
No Node-RED, os projetos são chamados de Fluxos.
Prepararemos um novo fluxo para escutar conexões TCP de entrada e imprimir o que for recebido em uma janela de depuração.
Pesquise no painel esquerdo, o nó chamado tcp em, arraste e solte-o na tela de fluxo.
Pesquise também o depurar nó e conecte-os assim:
No Node-RED, os projetos são chamados de Fluxos.
Prepararemos um novo fluxo para escutar conexões TCP de entrada e imprimir o que for recebido em uma janela de depuração.
Pesquise no painel esquerdo, o nó chamado tcp em, arraste e solte-o na tela de fluxo.
Pesquise também o depurar nó e conecte-os assim:
Clique duas vezes no tcp no nó e defina a porta TCP onde você deseja escutar, neste exemplo: 2222.
Defina também para transmitir strings delimitadas por \r\n.
Depois de fazer isso clique no botão Implantar no canto superior direito da tela.
Este botão executará os blocos após qualquer modificação.
Conecte seu receptor GNSS ao Node-RED
RTK Portable Bluetooth Kit com dispositivo Android
- Conecte seu Kit Bluetooth Portátil via BT ao seu dispositivo Android.
- Abra GNSS Master aplicativo, conecte-se ao módulo BT em Conexão do receptor GNSS.
- Defina a entrada de correção, se necessário
- Em Saída de Dados do Receptor, selecione Cliente TCP e insira o endereço IP do seu servidor em Endereço TCP e 2222 em Porta TCP. Clique em Conectar.
- Isso é tudo, se você clicar duas vezes na janela de depuração no Node-RED, deverá ver algo assim, com todos os dados sendo recebidos:
Outros receptores GNSS com plug-ins 4G, WiFi ou Ethernet
Se você tiver um receptor GNSS diferente, também poderá obter os mesmos resultados, mesmo sem um dispositivo Android.
Certifique-se de enviar para a porta COM do plugin XBee as mensagens que você deseja enviar para o seu servidor, normalmente você deseja enviar, pelo menos, NMEA GGA.
Em seguida, configure seu 4G, WiFi ou Ethernet NTRIP Master Plugins com a funcionalidade de cliente TCP com os mesmos parâmetros que usamos anteriormente: servidor TCP é o endereço IP do seu servidor e a porta TCP é 2222.
Simples assim 🙂
Faça algo com os dados
Ok, até aqui não foi nada emocionante, certo?
Não há problema em ver transmissões NMEA ao vivo no seu servidor, mas queremos ver alguns dos recursos do Node-RED.
No próximo exemplo, mostraremos como analisar o fluxo de entrada para obter a latitude e a longitude e plotaremos a localização ao vivo em um mapa com um rastreamento mostrando as localizações antigas.
Primeiro, exclua seu fluxo atual.
Clique no menu superior direito > Gerenciar paleta > Instalar > pesquisar por nó-vermelho-contrib-web-mapa-mundi e instalá-lo.
Volte ao menu > Importar > Área de transferência e cole o seguinte 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": []
}
]
Você deveria ver algo assim:
Clique duas vezes no nó do mapa-múndi.
Na lista suspensa Mapa, selecione OpenStreetMap ou outra camada e clique em Concluído:
Pressione o botão Implementar botão.
Você pode acessar o mapa ao vivo do seu navegador aqui:
172.123.123.123:1880/mapa-múndi/
onde o endereço IP deve ser o mesmo do seu servidor.
Você verá um mapa com um marcador mostrando a localização do seu receptor GNSS, atualizando em tempo real. Você pode aumentar ou diminuir o zoom quando quiser.
Recomendamos que você dê uma olhada em cada um dos nós do seu fluxo para entender melhor o que eles fazem, modificá-los e ver o que muda.
Você encontrará muitos tutoriais e ferramentas de IA que também ajudarão você se quiser fazer algo um pouco mais avançado.
Diverta-se!
Se você quiser desligar o Node-RED, faça o seguinte:iptables -A INPUT -p tcp --dport 2222 -j REJECT
tipo ps aux | grep node , encontre o processo do nó se e mate o processo por:kill NODE_PROCESS_ID