ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ADS-B收发闭环:从RTL-SDR接收1090MHz到Mode S报文编码与发射

ADS-B收发闭环:从RTL-SDR接收1090MHz到Mode S报文编码与发射 简介这是一份基于MATLAB实现的ADS-B收发与解码学习资源面向航空通信、信号处理方向的学生或业余无线电爱好者。通过地面天线捕获飞机广播的ADS-B信号配合代码可解析并生成实时航迹地图帮助理解1090MHz ES数据链的报文结构、前导脉冲检测与比特解调流程。压缩包共6个文件包含4个.m源码脚本覆盖信号读取、同步头识别、错误率计算等核心模块另有1份PDF设计报告和1个README说明文档便于对照代码快速上手。资源包整体仅1.16MB轻量易用已有417人学习。读者可从中获取完整的MATLAB处理链路、二进制数据解码的工程化实现思路以及配套的算法说明文档适合作为ADS-B入门项目或课程设计与毕业设计的参考蓝本。1. 这套收发项目到底在解决什么问题ADS-B 接收是 SDR 圈最经典的入门场景之一1090MHz、脉冲位置调制、RTL-SDR 十几美元的硬件成本跑起 dump1090 就能看到头顶航班的呼号、经纬度和速度。标题里真正值得琢磨的其实是 Transmitter 这半边——大部分开源工程只做接收解码能逆着流程把 Mode S 报文编码成基带脉冲并送到发射端的才是完整的射频闭环。ADS-Bcode 这个后缀正好点出了另外一层ICAO 地址、CPR 位置编码、CRC 奇偶校验这些报文层面的细节才是把收发链路串起来的关键。master 后缀对应的工程背景也很直接。master 分支是 Git 仓库的默认主分支带这个字样的项目通常同时维护 dev 和 feature 分支收下来第一步不是急着改代码而是先确认默认分支是否包含最近一次构建产物再决定直接编译还是切到 dev。联调目标分两段接收段要能从 I/Q 数据里解出 DF17 报文的 ICAO 地址和位置发射段要能生成格式正确的 112 bit 测试序列。适合读这篇内容的读者多半已经跑通过“看飞机”这一步现在想拆开链路研究报文格式、奇偶校验和脉冲成形或者手头有带发射能力的 SDR 设备准备做收发闭环。下面按接收、解码、发射、联调四个环节推进调试命令和 Python 代码都可以直接复用。2. 接收端改造用 RTL-SDR 搭起 1090MHz 监听链路2.1 驱动安装与设备参数检查ADS-B 报文占用的 1090MHz 频段是民航应答机下行频点信号采用脉冲位置调制单个报文长度只有 112 bit。接收端的处理流程可以拆成四步天线口信号经过带通滤波后进入 RTL-SDR 的 R820T2 调谐器下变频到中频RTL2832U 芯片按 2MHz 采样率输出 I/Q 复数数据软件通过相关运算识别 Preamble 脉冲序列定位报文起点最后按 1µs 的 bit 周期判决 0/1 并交给解码层。RTL-SDR 之所以是业余接收的首选不是灵敏度有多高而是因为它覆盖 24MHz 到 1.7GHz把 1090MHz 设在中心频率后留出的带宽足够容纳 PPM 脉冲的频谱分量。安装驱动的常见做法如下以 Ubuntu/Debian 为例sudo apt update sudo apt install rtl-sdr lsusb | grep -i rtl rtl_test -tapt install rtl-sdr会同时装入 librtlsdr 和 rtl_test、rtl_sdr 等命令行工具。lsusb用于确认设备枚举正常正常情况下能看到 Realtek RTL2832U 相关的条目。rtl_test -t连续输出采样率、增益列表等信息只有末尾出现Supported gain values才说明调谐器驱动正常。老内核上常见的问题是系统自动绑定了 DVB 驱动导致 rtl_test 报错Failed to open rtlsdr device此时要把内核模块加入黑名单再重新插拔一次。先用 rtl_sdr 导出一段原始 I/Q 数据再交给后续工具解析是调试早期最稳妥的排查方式。下面这条命令把采集链路和解码链路分隔开后续解不出报文时能快速定位rtl_sdr -f 1090000000 -s 2000000 -g 40 -n 16000000 capture.bin ls -lh capture.bin-f把中心频率锁定在 1090MHz-s指定 2MHz 采样率-g固定增益 40dB-n表示采集 1600 万个采样点。2MHz 采样率对 ADS-B 是合理的经验值PPM 脉冲最短宽度 0.5µs按奈奎斯特至少需要 4MHz 采样才能完整保留上升沿但实际解码器在前导码相关后只取脉冲判决点2MHz 足够稳定还原电平。固定 40dB 增益是为了在联调阶段让测试结果可复现打开 AGC 反而会把弱信号和底噪抬到同一水平干扰对发射机输出功率的判断。2.2 dump1090 首次启用的关键参数拿到 I/Q 数据后下一步就是启用 dump1090 这类解码工具看实时航迹。dump1090 的一代版本由 Salvatore Sanfilippo 发布后续的 dump1090-fa 和 dump1090-mutability 各自维护不同的编译目标和 Web 界面。克隆代码后需要先确认默认分支再编译git clone https://github.com/flightaware/dump1090.git cd dump1090 git branch -a git checkout master makegit branch -a会列出本地和远程分支清单标题里带 master 字样的仓库默认就在 master 分支但如果远程仓库已经把主分支迁移到 main就要从-a的输出里找对应名字再checkout。make编译成功后在当前目录生成可执行文件不同分支的输出名可能是dump1090也可能是dump1090-fa看 Makefile 里的 OUTPUT 变量即可。编译失败时先确认 libusb-1.0、librtlsdr-dev、libncurses-dev 三个依赖都在这三项是最常见的缺项。首次运行不要开完整 Web UI用一条最简命令确认收发链路是否打通./dump1090 --device-index 0 --gain 49 --net --net-http-port 8080--gain 49把 RTL-SDR 增益固定在 49dB室内天线场景下这个值通常比自动增益更稳定--net开启 TCP 端口--net-http-port 8080让本机浏览器能访问实时列表和地图。日志里出现DF17计数增长时说明链路已经通可以再叠加--agc看高密度场景下的表现。下表是调试时最常用的几个参数对照参考可以省掉反复翻 README 的时间参数作用调试建议--device-index 0选择 RTL-SDR 设备序号多插几台设备时按rtl_test -t输出对照--gain 49固定增益 49dB联调阶段固定增益便于复现--agc自动增益控制信号饱和或底部噪声抬高时开启--modeac解码 Mode A/C 二次雷达信号需要对照机场场面目标时使用--net-ber输出比特层面的错误率调整发射端脉冲成形时最有参考价值日志里反复出现Bad CRC或Signal below threshold时先用 2.1 里导出的 capture.bin 做离线测试。同一份 I/Q 数据跑两次解码结果一致说明问题出在采集链路否则往系统负载或 USB 带宽抢占方向查。ADS-B 报文只有 112 bit校验失败率偏高的原因里采样率被降、增益压限、USB 控制器带宽不足三个方向各占三成按这个顺序排查比换天线更有效。3. ADS-B 报文解码从 Mode S 位流到可读航迹3.1 Mode S 帧结构Preamble、DF 类型与奇偶校验上一章结尾看到的Bad CRC根源就在 112 bit 报文的最后 24 bit。Mode S 报文在时间轴上分为两段Preamble 占 8µs由 0、1、2、3µs 四个固定位置的 0.5µs 脉冲组成紧接着是 1µs 一 bit 的数据块。接收端通过 Preamble 与本地采样序列做相关运算来定位报文起点一旦前导码检测偏差超过 1µs后面的 bit 判决基本就全错了。数据块的高 5 bit 是下行链路格式 DF决定报文类型和长度。DF17 和 DF18 是 ADS-B 最常见的两种DF17 来自装备 ADS-B Out 的应答机DF18 来自地面 TIS-B 转发站两者都是 112 bit区别在 ME 字段的语义编排。还有一类 DF11 短报文只有 56 bit用于应答机自发广播不属于 ADS-B 位置消息解码时通常直接过滤。各字段的位置分布如下比特位区间字段名含义0–4DF下行格式标识DF17 的二进制为 100015–7CA/CF应答机能力或飞行状态8–31ICAO24 bit 全球唯一地址码32–87ME消息扩展字段承载位置、速度、呼号88–111PICRC-24 校验位校验位是理解 Mode S 的一个关键点它不只是检错还兼作前导码的相位参考。计算方法是把前 88 bit 视为一个二进制多项式对生成多项式 G(x)0x1FFF409 求余余数填入最后 24 bit接收端对整个 112 bit 重新求余结果应为 0。这个生成多项式不是通用 CRC-24如果从网上复制标准 CRC 实现直接改位数校验永远对不上。3.2 用 Python 解析一条完整报文下面这段代码保留了解码链路的核心分支CRC 校验和 DF17 字段拆解。完整仓库里的解码器还会先做前导码相关峰值检测再做位同步和 CRC 反查这里把这两步之外的部分压缩到最小可运行形态。GENERATOR 0x1FFF409 # Mode S 专用生成多项式 def crc_mode_s(bits_112: str) - int: raw int(bits_112, 2).to_bytes(14, big) crc 0 for b in raw[:11]: # 前 11 字节是数据区 crc ^ (b 16) for _ in range(8): if crc 0x800000: crc ((crc 1) ^ GENERATOR) 0xFFFFFF else: crc (crc 1) 0xFFFFFF return crc def parse_df17(msg_hex: str): bits .join(f{int(c, 16):04b} for c in msg_hex) df int(bits[0:5], 2) if df ! 17: return None icao int(bits[8:32], 2) me bits[32:88] rem crc_mode_s(bits) ok (rem int(bits[88:112], 2)) return {crc_ok: ok, icao: f{icao:06X}, me: me}crc_mode_s的内层循环每轮处理一个 bit8 次循环完成一个字节的处理变量crc保持在 24 bit 宽度最高位为 1 时与生成多项式异或对应 LFSR 的直接除法。parse_df17先把十六进制字符串展开成 112 bit再按表中的位置切片取出 DF、ICAO、ME最后比对计算出的余数与报文尾部 24 bit得到crc_ok标记。实际解析时应该把crc_ok为 False 的报文直接丢弃不参与后续的航迹关联。ME 字段的解析里位置信息使用 CPR 紧凑位置编码。CPR 把地球按纬度和经度划分成多个区域偶格式帧给出某个区域内的精细位置奇格式帧给出相对相邻区域的偏移只有偶奇两帧都收到才能解出无歧义的全球坐标。调试中看到飞行器坐标在几十公里间跳变几乎可以断定是只有一种格式帧参与了解码。这部分逻辑在开源工程里通常集中在mode_s.c或adsb.c中把 CPR 解码函数单独抽出来做单元测试能快速定位奇偶帧配对的问题。4. 发射端设计从 ADS-B 编码到测试信号生成4.1 发射端硬件选型与频谱合规标题里的 Transmitter-Receiver 到了发射这半边很多从接收入门的开发者会卡在第一道坎用什么设备发、发多大功率、发出去合不合规。先给结论在地面做闭环测试时发射设备不接天线改经一个 20dB 以上的固定衰减器直接连接收机 SMA 口功率控制在 0dBm 以下信号只在测试台内部流转不对空辐射。这样既能验证编码和脉冲成形又不会对民航频段产生实质干扰。硬件平台按成本从低到高有三种选择。单片机和 ASK 射频模块的组合最便宜但 1090MHz 的 ASK 模块普遍存在上升沿拖尾脉冲宽度偏移超过 0.1µs 就会显著抬高 BER需要额外加整形滤波调试难度反而最高。带发射功能的 SDR 是当前性价比较高的方向HackRF 和 USRP 都能直接输出 1090MHz 中心频率的基带信号配合 GNU Radio 可以自由修改脉冲成形系数。第三种是软件无线电外设加锁相环方案频率稳定度最好成本也最高一般只在需要严格频谱模板的场合才考虑。从工程链路看SDR 方案把问题集中在“位流生成”和“脉冲成形”两层。GNU Radio 里的典型流图是File Source 读取二进制位流经 Repeat 块把每个 bit 重复成 10 个采样点再接低通滤波器限制带宽最后接 UHD: USRP Sink 或 Osmocom Sink。低通滤波器的截止频率取 10MHz 到 15MHz 之间是常见做法过高会保留脉冲边沿的高频分量过低则会让 PPM 的判决点电平塌陷。4.2 生成符合 1090ES 格式的位流1090ES 的物理层调制可以总结成一句话每个 bit 周期 1µs逻辑“1”的脉冲出现在前 0.5µs逻辑“0”的脉冲出现在后 0.5µs前导码的 4 个脉冲位置固定。生成符合规范的位流关键在于 CRC 回填和 PPM 展开两步顺序不能颠倒——先算校验位再做脉冲成形。以下 Python 脚本先构造 DF17 报文的 88 bit 数据区调用 3.2 节的crc_mode_s算出 24 bit 校验位回填再按 20MHz 采样率展开成 PPM 波形import numpy as np def build_df17_message(icao, me_hex): me int(me_hex, 16) data format(17, 05b) format(5, 03b) \ format(icao, 024b) format(me, 056b) crc crc_mode_s(data 0 * 24) return data format(crc, 024b) def bits_to_ppm(bits, fs20_000_000): samples_per_bit fs // 1_000_000 half samples_per_bit // 2 wave [] for ch in bits: if ch 1: wave.extend([1.0] * half [0.0] * half) else: wave.extend([0.0] * half [1.0] * half) return np.array(wave, dtypenp.float32) msg build_df17_message(0xABCDEF, 0123456789ABCDEF) pp bits_to_ppm(msg) pp.tofile(adsb_test_frame.raw)build_df17_message把 DF 固定为 17、能力字段固定为 5把 24 bit ICAO 地址和 56 bit ME 字段按位宽拼进 88 bit随后用crc_mode_s对前 88 bit 求余得到的 24 bit 校验位追加到末尾凑齐 112 bit。bits_to_ppm中fs // 1_000_000算出每个 bit 对应的采样点数20MHz 下为 20 个点前 10 个点电平为 1、后 10 个点为 0正好对应 0.5µs 的占空比。生成的adsb_test_frame.raw可以直接作为 GNU Radio 的 File Source 输入。PPM 展开里最容易出错的参数是脉冲宽度和上升时间。ADS-B 规范里上升时间要求不超过 0.05µs但软件生成时只要保证判决点处电平正确即可不必刻意追求 0.05µs 以内的边沿。实际联调时观察接收端上报的--net-ber数值BER 在 10^-3 以下不影响解码高于 10^-2 就要回头检查脉冲宽度是否被重采样拉偏。相关参数的经验对照如下参数建议值对解码的影响采样率20MHz接收端取整数分频低于 4MHz 时 PPM 判决点不足低通滤波带宽10–15MHz过窄会压平脉冲边沿脉冲占空比50%偏移 20% 以上抬升 BER输出功率0dBm 以下经衰减器进入接收端超过接收动态范围后产生削顶失真5. 收发联调衰减器闭环与三个边界参数5.1 最小衰减闭环怎么搭接收端和发射端都在同一台机器上时联调就是最简单的闭环发射端软件生成 PPM 波形并上变频到 1090MHz输出端接 20dB 衰减器再经同轴线进入 RTL-SDR 的 SMA 口。这一步的额外投入只有一个衰减器和两根 SMA 线既避免了对空辐射的问题又屏蔽了外界干扰让解码结果只反映发射链路的质量。联调最先看的指标是 dump1090 上报的报文数量与--net-ber值。先以固定增益 39dB 运行接收端再让发射端循环发送同一帧测试报文30 秒内应能看到几百次解码记录。如果一条报文都没有按“发射端低通滤波是否启用、衰减器是否反接、中心频率是否漂移”三个方向排查。频率漂移在 SDR 上很少见反而是衰减器功率余量选错了会把信号压到接收灵敏度以下表现为偶尔出现一条报文又立刻消失。5.2 三个容易忽略的边界参数第一个是采样率不一致。发射端用 20MHz 生成波形接收端却按 2.4MHz 采集会产生频谱混叠表现为高位 bit 随机翻转。联调时统一采用整数倍关系比如发射 20MHz、接收 2MHz并让发射端的低通滤波上限低于接收端采样率的一半。采样率不对齐时 BER 会高到无法解码而且表现和前导码相关失败很像容易误判为天线问题。第二个边界参数是 CRC 字节序。第 3 章的crc_mode_s按大端字节序列计算如果平台是 x86 小端直接用字节数组填充 24 bit 校验位就会错位。正确做法是始终把报文当作一串 bit 流处理只在最后的tofile阶段按主机字节序写出。很多“生成端自己看很正常、接收端 CRC 通不过”的情况问题都出在这一层。第三个边界参数是接收端增益的压限点。RTL-SDR 的 ADC 只有 8 bit发射功率偏大时前端被推到饱和区底噪和信号一起被削平表现为解码数不升反降。判断方法很简单把增益从 49dB 降到 29dB如果解码数反而上升说明前面已经过载。下面这组对照可以当作联调起点的参考衰减链接收端起始增益现象判断20dB29dB → 49dB高增益时报文数骤降前端压限衰减加到 30dB 以上30dB29dB → 39dB报文数平稳上升处于线性区微调增益找峰值40dB29dB → 39dB报文数几乎不随增益变化信号接近灵敏度下限抬升发射功率或减小衰减正确的联调顺序是先把发射端输出经衰减链压到 -30dBm 附近再让接收端增益从 30dB 起步向上扫记录每个增益档位下 30 秒内的解码数递增区间。找到报文数峰值对应的增益后再回过去微调发射端的脉冲宽度和低通带宽观察--net-ber的浮动范围。如果 40dB 衰减下报文数依然稳定说明发射链路余量充足可以继续压缩衰减值直到 BER 开始上升为止。本文还有配套的精品资源点击获取
返回列表