使用 JavaScript 构建飞机雷达系统

2025-05-25

使用 JavaScript 构建飞机雷达系统

几年前,我偶然听到了Thomas Watson一场精彩演讲,他讲述了自己如何构建AirplaneJS。这是一款 Web 应用,可以接收飞机的ADS-B无线电信号,并在浏览器的地图上实时显示。我之前完全不知道 JavaScript 也能实现这个功能,所以开始研究它。

我尝试了一下这个项目,并开始思考是否有办法让它更进一步。考虑到 AirplaneJS 在服务器上使用 Node.js,我决定尝试一下,看看能否使用 Web USB 将其变成一个纯前端项目。几周前我终于让它运行起来了🥳,所以决定写一篇关于它的文章。

我仍在学习有关 USB 协议以及如何解码 ADS-B 信号的知识,因此这篇文章不会深入探讨这个主题。

在我开始之前,这里有一个演示:

GIF 显示一架飞机从我上方飞过,数据显示在我的笔记本电脑屏幕上。

这是演示站点的链接

RTL-SDR加密狗

该项目的主要组件包括Web USB APIRTL-SDR 加密狗 + 天线以及一些 JavaScript 代码。

如今,大多数飞机都会广播 ADS-B 数据,即广播式自动相关监视 (ADS-B)。这是一种监视技术,允许飞机在无人驾驶飞机的情况下广播其飞行状态,这意味着无需飞行员输入任何信息。
这些数据包括飞机的位置、经纬度、速度、代码等。
空中交通管制员会定期将这些数据发送给空中交通管制员。然而,使用带天线的软件定义无线电 (SDR) 加密狗,你可以拦截这些信息,从而构建你自己的飞机雷达系统📡。

您可以购买或构建不同类型的天线,但我个人使用的是偶极天线。

由于数据以1090MHz的频率广播,因此偶极子的尺寸需要用以下公式计算:

In feet:

Total length = 468 / Frequency in MHz // Gives the total lengh of the dipole

Length of each branch = Total length / 2

---

In cm:

Total length = 14264 / Frequency in MHz // Gives the total lengh of the dipole

Length of each branch = Total length / 2
Enter fullscreen mode Exit fullscreen mode

如果更方便的话,可以使用在线计算器。

对于这个项目,它给我的总长度大约为 13 厘米,因此偶极子的每个部分应该约为 6.5 厘米。

通过 Web USB 连接到加密狗

Web USB API是一种浏览器 API,允许您通过 USB 连接并与插入计算机的设备进行通信。

要使用它,你需要首先检查你的浏览器是否支持它。你可以使用以下代码来检查:

if(navigator.usb){
    console.log("The Web USB API is supported!")
} else {
    console.log("I'm afraid this won't work")
}
Enter fullscreen mode Exit fullscreen mode

然后,您需要指定应用要连接到哪个设备。您可以列出所有当前连接的设备,也可以指定一个过滤器,在其中传递设备的供应商 ID 和产品 ID。
在 Mac 上,您可以通过以下方式找到这些 ID:将设备插入电脑,点击 Apple 图标 > 关于本机 > 系统报告,然后查看“硬件”>“USB”下的列表。

Mac 上的设置屏幕截图,显示了有关 USB 设备的详细信息。

上图显示供应商 ID 是0x0bda,产品 ID 是,0x2838因此我可以在代码中使用它。

出于安全原因,Web USB API 需要由用户交互触发,因此我在屏幕上有一个按钮来启动连接过程。

第一个要调用的方法navigator.usbrequestDevice

button.onclick = () => {
  navigator.usb
    .requestDevice({
      filters: [
        {
          vendorId: 0x0bda,
          productId: 0x2838,
        }
      ],
    })
};
Enter fullscreen mode Exit fullscreen mode

它返回一个承诺,其中包含列表中选定的设备。下一步是与该设备建立会话,选择配置并声明接口:

.then((device) => device.open());
.then(() => device.selectConfiguration(1))
.then(() => device.claimInterface(0)) 
Enter fullscreen mode Exit fullscreen mode

配置和界面是特定于设备的。我在网上找不到关于我正在使用的特定设备的信息,所以我尝试了不同的值,直到成功……

这些步骤成功执行后,设备应该已连接。现在,需要设置频率和采样率。
为此,我使用了Sandeep Mistry开发的rtlsdrjs库。如果您决定使用它来创建类似的项目,我将其用作频率(1090MHz)和采样率。10900000002000000

最后,transferIn当从设备接收到数据时,该方法就会执行。

.transferIn(1, 256000)
.then((result) => {
    const data = new Uint8Array(result.data.buffer);
    console.log(data);
})
Enter fullscreen mode Exit fullscreen mode

此代码返回如下所示的原始数据:

控制台中打印的实时数据

处理和格式化后,它看起来像这样:

JSON 对象显示包括速度、高度、纬度、经度等属性。

处理原始 ADS-B 数据

项目的这部分很大程度上依赖于现有的工作。我需要更深入地研究S模式通信协议如何解码数据,但这份S模式和ADS-B信号解码指南似乎是一个很好的开始。

到目前为止,据我了解,ADS-B 消息主要包含两个部分:前导码和数据块。数据块由 112 位组成,分为 5 个部分:

+----------+----------+-------------+------------------------+-----------+
|  DF (5)  |  CA (3)  |  ICAO (24)  |         ME (56)        |  PI (24)  |
+----------+----------+-------------+------------------------+-----------+
Enter fullscreen mode Exit fullscreen mode
  • DF:下行链路格式
  • CA:应答器能力
  • 国际民航组织飞机地址
  • 我:留言
  • PI:奇偶校验ID

第 33-88 位专用于消息。无需赘述,此部分的前 5 位表示类型代码。如果此类型代码介于 1 至 4 之间,则该 ADS-B 消息为飞机识别消息;如果类型代码介于 5-8 之间,则该消息为地面位置消息,等等。
此类型代码很重要,因为它指示了消息其余部分的内容。

包含 ADS-B 消息类型代码的表格

十六进制格式的原始 ADS-B 消息示例如下所示:

8D4840D6202CC371C32CE0576098
Enter fullscreen mode Exit fullscreen mode

以二进制表示,其含义为:

1000110101001000010000001101011000100000001011001100001101110001110000110010110011100000010101110110000010011000
Enter fullscreen mode Exit fullscreen mode

如果您关注的话,您也许可以猜出这是多少位......

...

...

...

112!

如果我们使用前面显示的表格,我们可以将这个二进制文件分成各个部分:

+--------+--------+--------------+-------------------------+-------------------+
| DF (5) | CA (3) |   ICAO (24)  |         ME (56)         |      PI (24)      |
+--------+--------+--------------+-------------------------+-------------------+
| 10001  | 101    | 010010000100 | 00100000001011001100001 | 01010111011000001 |
|        |        | 000011010110 | 10111000111000011001011 | 0011000           |
|        |        | 000011010110 | 0011100000              |                   |
|        |        |              |                         |                   |
+--------+--------+--------------+-------------------------+-------------------+
Enter fullscreen mode Exit fullscreen mode

它使它更容易阅读,但现在我们还可以将每一个转换成十进制:

+--------+--------+--------------+-------------------------+-------------------+
| DF (5) | CA (3) |   ICAO (24)  |         ME (56)         |      PI (24)      |
+--------+--------+--------------+-------------------------+-------------------+
| 17     | 5      | 4735190      | [4]...                  | ...               |
+--------+--------+--------------+-------------------------+-------------------+
Enter fullscreen mode Exit fullscreen mode

该消息的前5位为十进制值4,这意味着这是一条飞机识别消息。如果我理解正确的话,根据我找到的表格,消息的其余部分应该包含有关飞机类别及其呼号的数据。

ADS-B飞机识别码

利用这些数据,您可以使用planespotters.net等在线工具并搜索ICAO代码以获取有关您正在跟踪的飞机的更多信息。

处理完所有这些数据后,结果是一个包含海拔、纬度、经度等信息的 JSON 对象。

将数据处理为 JSON 对象

如果需要的话,可以查看repo

最终设置

最后,我的设置如下:

屋顶上安装有天线的笔记本电脑

—-

这篇文章并不是很深入,但希望它有意义!

我真的非常高兴能够使用 Web USB 来完成这个项目,这是我多年来一直想做的事情!

我还需要进一步学习,但我还有一些其他项目的想法,想围绕这项技术来构建,我非常兴奋!只是深入研究一个我完全不了解的东西需要花费很多时间😅……

其他资源

文章来源:https://dev.to/devdevcharlie/building-an-aircraft-radar-system-in-javascript-4ml8
PREV
Creating a Github action to detect toxic comments using TensorFlow.js
NEXT
揭秘 OAuth 2.0 - 教程与入门