GNSS RTK技术的应用范围很广,通常情况下,你会进行一些测量,然后将其导出到计算机进行分析。这是最常见的情况。
但对于某些应用程序,您可能需要实时将 GNSS RTK 数据发送到您的计算机/服务器,这样您就可以立即采取行动,而无需等待几个小时来处理数据。
需要将实时位置发送到服务器的流行应用包括:车队管理和物流、叫车和公共交通、资产跟踪、野生动物监测……
在本教程中,我们将解释如何使用 Node-RED(一种流行的可视化编程工具)设置服务器,以便您可以启动自己的项目,我们还将介绍如何配置您的 GNSS 接收器和插件以将数据发送到该服务器。
所需硬件
- 远程 Linux 服务器
虽然我们将在示例中使用上述内容,但您也可以在 Windows/Linux 机器、RaspberryPi、Docker、Android、Cloud 等上本地运行 Node-RED。 - 安卓 smartphone
- RTK Portable Bluetooth Kit
- 作为替代方案,任何其他具有 4G NTRIP 总音量, WiFi NTRIP Master or Ethernet NTRIP Master 插件
所需软件
- GNSS Master Android的应用程序
Node-RED 的安装
远程 Linux 服务器
在我们的例子中,我们使用 AlmaLinux 发行版。
打开服务器的终端并运行以下命令:
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
您可以通过输入以下命令检查安装是否成功:/usr/local/bin/node-red --version
如果一切正常,您将看到终端上显示的版本。
其他设备/操作系统
您可以在 Node-RED 官方项目页面上找到有关 不同的系统.
在服务器上打开 TCP 端口
这可能并不总是必要的,但您可能需要打开 TCP 端口以允许传入连接。
在本例中我们将使用 TCP 端口 2222,您应该在服务器终端上输入:iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
运行 Node-RED
输入以下命令: /usr/local/bin/node-red &
转到浏览器并输入:
172.123.123.123:1880
其中 172.123.123.123 必须是您的服务器的 IP 地址。
如果一切正常,您应该会看到类似这样的内容:
准备您的第一个流程
在 Node-RED 中,项目被称为流。
我们将准备一个新的流程来监听传入的 TCP 连接并将接收到的任何内容打印到调试窗口中。
在左侧面板上搜索名为 TCP 输入,将其拖放到流程画布上。
还搜索 调试 节点并将它们连接在一起,如下所示:
在 Node-RED 中,项目被称为流。
我们将准备一个新的流程来监听传入的 TCP 连接并将接收到的任何内容打印到调试窗口中。
在左侧面板上搜索名为 TCP 输入,将其拖放到流程画布上。
还搜索 调试 节点并将它们连接在一起,如下所示:
双击节点中的 tcp 并设置您想要监听的 TCP 端口,在此示例中为:2222。
还设置为以 \r\n 分隔的流字符串。
这样做之后 点击部署按钮 在屏幕的右上方。
此按钮将在任何修改后运行块。
将您的 GNSS 接收器连接到 Node-RED
RTK Portable Bluetooth Kit 使用 Android 设备
- 通过 BT 将您的便携式蓝牙套件连接到您的 Android 设备。
- 可选 GNSS Master 应用程序,连接到 GNSS 接收器连接中的 BT 模块。
- 如果需要,设置校正输入
- 在“接收器数据输出”中,选择“TCP 客户端”,并在“TCP 地址”中输入服务器的 IP 地址,在“TCP 端口”中输入 2222。点击“连接”。
- 就这样,如果你双击 Node-RED 中的调试窗口,你应该会看到类似这样的内容,其中所有数据都被接收了:
其他带有 4G、WiFi 或以太网插件的 GNSS 接收器
如果您有不同的 GNSS 接收器,即使没有 Android 设备,您也可以获得相同的结果。
确保将要发送到服务器的消息输出到 XBee 插件 COM 端口,通常至少要发送 NMEA GGA。
然后,配置您的 4G、WiFi 或 Ethernet NTRIP Master 使用与之前相同的参数,为插件添加 TCP 客户端功能,TCP 服务器是您的服务器 IP 地址,TCP 端口是 2222。
就这么简单 🙂
对数据进行处理
好吧,到目前为止还不是很令人兴奋,对吧?
在您的服务器上查看实时 NMEA 流是可以的,但我们想看看 Node-RED 的一些功能。
在下一个示例中,我们将向您展示如何解析输入流以获取纬度和经度,并且我们将在地图上绘制实时位置,并用显示旧位置的轨迹。
首先,删除您当前的流程。
点击右上角菜单 > 管理调色板 > 安装 > 搜索 node-red-contrib-web-worldmap 并安装它。
返回菜单 > 导入 > 剪贴板并粘贴以下代码:
[
{
"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": []
}
]
你应该看到这样的东西:
双击世界地图节点。
在地图列表下拉菜单中,选择 OpenStreetMap 或其他图层,单击完成:
按 部署 按钮。
您可以通过浏览器访问此处的实时地图:
172.123.123.123:1880/世界地图/
其中 IP 地址必须与您的服务器的 IP 地址相同。
您将看到一张带有标记的地图,显示您的 GNSS 接收器位置,实时更新,您可以随意放大/缩小。
我们建议您查看流程中的每个节点,以便更好地了解它们的作用、修改它们并查看有什么变化。
如果您想做一些更高级的事情,您会发现大量的教程和 AI 工具也会为您提供帮助。
玩得开心!
如果您想关闭 Node-RED,请执行以下操作:iptables -A INPUT -p tcp --dport 2222 -j REJECT
类型 ps aux | grep node ,找到节点进程并通过以下方式终止该进程:kill NODE_PROCESS_ID
和
