Files
CCSDS_study/test/Tianwen-1-frame-analysis-v2.md
2026-05-05 21:54:35 +08:00

256 lines
6.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 对应的时间戳。
理解这些变量后,整个脚本的结构就比较清楚了。