Files
CCSDS_study/test/Tianwen-1-frame-analysis-v2.md

256 lines
6.7 KiB
Markdown
Raw Normal View History

2026-05-05 21:54:35 +08:00
# 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 对应的时间戳。
理解这些变量后,整个脚本的结构就比较清楚了。