martinber/vor-python-decoder

GitHub: martinber/vor-python-decoder

从WAV录音文件中解码VOR航空导航信号,通过分析参考信号与可变信号的相位差来计算接收者相对于VOR天线的方位角。

Stars: 50 | Forks: 8

# vor-python-decoder 确定你相对于 [VOR](https://en.wikipedia.org/wiki/VHF_omnidirectional_range) 天线的方位角。你可以 使用 RTL-SDR 和偶极子天线。 使用 Python3, numpy, scipy 和 matplotlib。 经过少量调优,我们能够以小于 3° 的 误差确定我们的方位角。 这是作为一个期末项目匆忙制作的,所以不要指望它是一个可靠的 实时解码器。另一方面,如果你是 numpy/scipy/python 派,我们认为代码非常简单,我们找到的其他替代方案是基于 [GNU-Radio](http://www.housedillon.com/posts/vors-and-sdrs-part-3-supplemental-materials/), [GNU-Radio](https://www.rtl-sdr.com/using-an-rtl-sdr-to-decode-vor-aircraft-navigation-beacons-in-real-time/) 或 [C](https://www.rtl-sdr.com/an-open-source-vor-receiver-for-airspy-and-rtl-sdr/) 的。 **在 `/docs` 文件夹中有一份西班牙语的报告和演示文稿** 由 Martín Bernardi, Augusto Remedi 和 Ignacio Rittano 制作。 ## 注意 你可能需要首先从一个已知位置测量你的方位角,并 将 `ANGLE_OFFSET = 114` 更改为另一个值。一旦你调整了该值,你 应该能得到准确的结果。更多信息请参见 [本节](#filter-delays)。 ## 用法 首先确定 VOR 天线的频率并调谐你的 SDR。你应该 使用 AM 解调,并使带宽足够宽,以便两个边带都能 进入滤波器。 你会每隔几秒钟听到一个识别电台的摩尔斯电码和一个 持续的高频嘶嘶声 ([示例](https://github.com/martinber/vor-python-decoder/blob/master/samples/293deg_long_1.wav))。 该程序将此解调后的 AM 音频录音作为输入,格式为 WAV 文件: ``` ./decoder.py ./recording.wav ``` 它将在你的终端上打印出到你位置的方位角。 使用超过 1 秒的录音是没有意义的。在 `/samples` 文件夹中有一些示例,每个文件名都有它们被录制位置的方位角,这是使用地图测量的。 ## 工作原理 ![频谱](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/769936c0f1111215.png) 就我们而言,你可以假设发射器发送两个 30Hz 音调,我们将它们命名为 REF(参考)和 VAR(可变)信号。REF 音调 以 AM 调制,连同摩尔斯电码一起。 另一方面,VAR 信号存在于 FM 副载波上。所以你需要 首先解调 AM 载波(获得 REF 和摩尔斯码),然后隔离 FM 副载波进行第二次解调。最终结果是 30Hz VAR 音调。 通过比较 REF 和 VAR 音调之间的相位差,你可以 直接确定你的方位角。 在实践中,事情要困难一些,例如你有 CVOR(常规 VOR)和 DVOR(多普勒 VOR),它们有一些区别。这个程序应该至少适用于 CVOR 信标。 AM 解调已经由 GQRX 或 SDR# 完成,所以这个程序执行的 步骤是: - 使用截止频率约为 500Hz 的低通滤波器来获取 REF 信号。 - 解调 FM 副载波以获取 VAR 信号。 - 首先使用带通滤波器隔离位于 9.96kHz 的 FM 信号。 - 与 9.96Hz 复指数相乘,将 FM 信号置于 0Hz 中心。在此步骤期间,我们得到了一个复正交信号。 - FM 解调是通过观察我们在上一步得到的 复信号的角度来进行的。 [更多信息](https://witestlab.poly.edu/blog/capture-and-decode-fm-radio/) - 对两个信号进行互相关,以确定两者之间的相位 差。相位差就是到你的 位置的方位角。 你可以编辑程序并将 `PLOT_STEPS` 设置为 `True`,以绘制执行的 步骤的频谱。 ### 滤波器延迟 在比较两个信号之间的相位差之前,考虑到每个滤波器的延迟是非常 重要的。我们使用了 FIR 滤波器,它 产生 (N-1)/2 的延迟,其中 N 是抽头数。出于这个原因,我们 在一个变量中存储每个滤波器产生的延迟,所以最后,就在 比较之前,我们对齐两个信号。 然而,这个程序有一个问题,在我们的测试中,结果 总是偏离 114°。我们认为问题可能是我们没有考虑到 FM 解调产生的一些延迟。 无论如何,我们只是增加了一个额外的 114° 延迟。这为我们在 所做的每次录音中提供了一致的结果。 ## 我们的结果 我们在 [TRC VOR 信标](https://ourairports.com/navaids/TRC/Rio_Cuarto_VOR_AR/) 周围 的不同位置进行了一些简短录音。 ![位置地图](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/7ecc47b904111217.png) [这些点的 KMZ 文件](./docs/vor_tests.kmz) 在确定了前面提到的 114° 值后,每次测量都 在 +/-3° 以内: - A 点:235.8°,看地图应该在 234° 左右 - B 点:291.6°,看地图应该在 293° 左右 - C 点:178.2°,看地图应该在 177° 左右 ## 截图 使用 GQRX 接收: ![VOR 信号的 GQRX 截图](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/6522676f8d111219.png) ![另一张 VOR 信号的 GQRX 截图](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/edcf3c5522111220.png) WAV 录音(在 GQRX 解调之后): ![输入](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/07e6678b61111221.png) 使用带通滤波器隔离 FM 副载波后的信号: ![FM 已滤波](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/78f79c3925111222.png) 与复指数相乘将 FM 副载波 置于 0Hz 中心后的信号: ![FM 居中](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/1aae8fc1f0111223.png) 上一步的抽取: ![FM 居中并抽取](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/04468dd7ca111224.png) 未显示 FM 解调的频谱图像(VAR 信号)或 输入信号上的低通滤波器的频谱(REF 信号)。但你可以在 下图中看到这两个信号,该图比较了两者之间的相位。 ![相位比较](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/b3d61a8cb7111226.png)
标签:AM解调, DSP, Matplotlib, NumPy, Python, RTL-SDR, SciPy, SDR, VHF全向信标, VOR, WAV文件处理, 信号解码, 导航, 数字信号处理, 方位角计算, 无后门, 无线电监测, 航空电子, 软件无线电, 频谱分析