# Tianwen-1-frame-analysis-v2.py 新手说明 这个文件是一个“天问一号遥测帧分析脚本”。如果用新手的话说,它做的事情就是: > 读取一大包二进制遥测数据,把它拆成一帧一帧,再按航天器 ID、虚拟信道和 APID 分类,最后把不同数据字段画成图片保存下来,方便人工观察这些遥测字段怎么变化。 ## 输入数据 脚本读取的数据文件是: ```text /home/zjz/CCSDS_study/Tianwen/tianwen1_frames_20200730.u8 ``` 这个文件是一串连续的原始字节。脚本认为每 220 个字节是一帧 AOS frame,所以会把它整理成: ```text 帧数 x 220字节 ``` 也就是一个二维数组,每一行代表一帧。 ## 依赖的本地模块 脚本主要依赖两个本地文件: ```text Tianwen/ccsds.py Tianwen/tianwen1_tm.py ``` `ccsds.py` 负责解析 CCSDS AOS 帧和 Space Packet。 `tianwen1_tm.py` 负责把天问一号的原始时间戳转换成 `numpy.datetime64`,这样 matplotlib 才能按时间画图。 ## 为什么要设置 matplotlib 的 Agg 后端 WSL 下直接调用 `plt.show()` 经常会因为没有图形界面而报错。 所以脚本使用: ```python matplotlib.use("Agg") ``` 意思是:不要弹出图形窗口,只把图保存成 PNG 文件。 所有图片最后会保存到: ```text /home/zjz/CCSDS_study/Tianwen/frame_analysis_figures ``` ## 脚本整体流程 脚本主要分成以下几步: 1. 设置路径和 matplotlib 环境。 2. 读取 `tianwen1_frames_20200730.u8`。 3. 把原始字节按 220 字节切成 AOS 帧。 4. 用 `ccsds.AOSFrame.parse(...)` 解析每一帧。 5. 统计 AOS 主头中的版本号、航天器 ID、虚拟信道 ID。 6. 分别分析 `Spacecraft 82 / VC 1`、`Spacecraft 245 / VC 3`、`Spacecraft 245 / VC 1`。 7. 从 AOS 帧中重组 Space Packet。 8. 按 APID 把 Space Packet 分类。 9. 对多个 APID 的载荷字段按 `uint8`、`int16` 或 `float64` 解释。 10. 绘制时间序列图、帧丢失图、APID 热力图。 11. 用 `savefig(...)` 保存所有图片。 ## 关键概念解释 ### AOS Frame AOS Frame 可以理解为“航天器遥测传输的一帧”。每一帧里有头部字段,也有承载的数据。 本脚本中每帧固定 220 字节。 ### Spacecraft ID `spacecraft_id` 用来区分数据属于哪个航天器或数据源。 脚本主要关注: ```text 82 245 ``` ### Virtual Channel `virtual_channel_id` 是虚拟信道编号。同一个航天器 ID 下可以有多个虚拟信道。 脚本重点分析: ```text Spacecraft 82, Virtual channel 1 Spacecraft 245, Virtual channel 3 Spacecraft 245, Virtual channel 1 ``` 其中 `Spacecraft 245 / VC 1` 是后面 APID 分析的主要数据来源。 ### Space Packet AOS 帧中承载的是 Space Packet 数据流。一个 Space Packet 可能跨越多个 AOS 帧,所以脚本调用: ```python ccsds.extract_space_packets(...) ``` 把它们重新拼接出来。 ### APID APID 是 Space Packet 里的应用标识。新手可以先把它理解成“数据类型编号”。 不同 APID 里的载荷含义可能不同,所以脚本会按 APID 分组分析。 ## 图片保存逻辑 脚本新增了 `save_all_figures(output_dir)` 函数。 它会做这些事: 1. 找出当前 matplotlib 里所有还打开的 figure。 2. 从每张图的标题中生成文件名。 3. 调用: ```python fig.savefig(path, dpi=150, bbox_inches="tight") ``` 4. 保存成 PNG。 5. 保存后关闭 figure,释放内存。 文件名类似: ```text figure_001_spacecraft_82_virtual_channel_1_frame_loss.png figure_002_apid_1_spacecraft_82_virtual_channel_1.png ``` ## 各分析段落在做什么 ### Spacecraft 82 Virtual channel 1 这一段会: - 筛选出 SC 82 / VC 1 的 AOS 帧。 - 检查帧计数是否连续。 - 打印插入区时间戳。 - 重组 Space Packet。 - 按 APID 分类。 - 为每个 APID 画载荷热力图。 ### Spacecraft 245 Virtual channel 3 这一段主要检查 VC 3 是否像固定填充数据。 它会查看某些字节区间的唯一值,比如是否一直是 `0xaa`。 ### Spacecraft 245 Virtual channel 1 这是主要遥测数据通道。 这一段会: - 检查帧计数。 - 提取时间戳。 - 重组 Space Packet。 - 统计所有 APID。 - 按 APID 分组并画热力图。 ### APID 1280 / 1281 这些 APID 的载荷被按大端 `int16` 解释。 也就是说,每两个字节被看成一个 16 位整数,然后画出这些整数随时间的变化。 ### APID 1288 / 1287 这些 APID 的部分载荷被按大端 `float64` 解释。 脚本还对这些浮点序列做了 1 阶和 2 阶多项式拟合,并画出“原始值减拟合值”的残差。 新手可以理解为: > 先把整体趋势去掉,再看剩下的小变化。 ### APID 2 / 3 原 notebook 这里变量名写了 APID 2 和 APID 3,但代码实际两边都取了 APID 2。 脚本保留了原逻辑,并在代码注释里特别说明了这一点。 ### APID 454 / 462 / 1536 这些段落分别按 `uint8` 或 `int16` 查看指定字节位置的变化。 目的不是完全解码每个遥测字段,而是先通过画图观察哪些字节像计数器、哪些字节像连续变化的遥测量。 ## 运行方式 在项目根目录下可以运行: ```bash /home/zjz/CCSDS_study/ccsds/bin/python /home/zjz/CCSDS_study/test/Tianwen-1-frame-analysis-v2.py ``` 运行结束后,查看图片目录: ```text /home/zjz/CCSDS_study/Tianwen/frame_analysis_figures ``` ## 常见提示 运行时可能看到类似: ```text Broken stream. Last frame count ..., current frame count ... ``` 这是 `ccsds.py` 发出的 warning,意思是帧计数中间不连续,可能有丢帧或数据中断。 这不是 Python 程序崩溃,也不影响脚本继续保存图片。 ## 新手视角总结 这个脚本不是一个“完整解码所有遥测含义”的程序,而是一个“探索和观察遥测数据结构”的分析脚本。 它先把原始二进制文件拆成 AOS 帧,再把 AOS 帧里的 Space Packet 拼出来,然后按照 APID 分组。分组之后,它把某些字节当成整数或浮点数画出来,让我们通过图片观察这些字段是否有规律。 简单说: ```text 原始二进制数据 -> AOS 帧 -> Space Packet -> APID 分组 -> 字节/整数/浮点数曲线 -> PNG 图片 ``` 如果你是新手,建议先从这几个变量看起: - `frames`:原始帧字节数组。 - `aos`:解析后的 AOS 帧对象。 - `sc245_vc1`:筛选出的主要遥测虚拟信道。 - `sc245_vc1_packets`:从 AOS 帧中重组出来的 Space Packet。 - `sc245_vc1_by_apid`:按 APID 分类后的 packet 字典。 - `channels`:某个 APID 的载荷被解释成数值后的矩阵。 - `timestamps`:每个 packet 对应的时间戳。 理解这些变量后,整个脚本的结构就比较清楚了。