这套航天仿真自动化程序,是我本科阶段写过体量最大的一组桌面自动化脚本。原来的工作需要从 Word 里找轨道、频段、地球站和链路参数,再逐项填进 Visualyse,等待仿真完成后截图、抄数、画图,最后把结果放进固定格式的报告。

单次操作并不难,难的是对象一多,重复点击和复制就会占掉大量时间,而且任何一处填错都会传到最终报告。我没有把它写成一个几千行的单体脚本,而是拆成参数整理、软件填写、结果截图、OCR、绘图和报告生成几组工具。

整条流水线

flowchart TD
    A["原始 Word 参数文档"] --> B["结构解析与分单元整理"]
    B --> C["轨道 / 频段 / 地球站 / 链路 Excel"]
    C --> D["Visualyse GUI 自动填写"]
    D --> E["运行仿真并批量截图"]
    E --> F["PaddleOCR 提取最坏值与时长"]
    D --> G["仿真日志"]
    G --> H["Matplotlib 绘制干扰曲线"]
    F --> I["上下行结果汇总与校验"]
    H --> J["docxtpl 模板报告"]
    I --> J
    J --> K["Word COM 转换最终 DOC"]

这几个模块可以分开调试,但它们约定了相同的目录和命名规则。截图编号、Excel 文件名和模板变量一旦对不上,后面的 OCR 和报告就找不到输入,所以文件协议和代码本身一样重要。

先把 Word 参数变成机器能读的表

AutoUnZiper 负责解析原始 Word。它按标题层级遍历段落、表格和图片,把每个一级标题拆成独立处理单元,再生成对应的内容提取文档与数据汇总表。

接下来脚本会从汇总表继续整理出申报频段、轨道参数、地球站信息和链路参数。频率范围需要兼容 MHz、GHz、不同连接符和中英文标点,最后统一成 MHz 区间。两组频段存在交集时,才继续生成对应的上行或下行参数。

这一步看似只是格式转换,实际解决了后续自动填写最难的问题:GUI 脚本不应该再理解几十种 Word 排版。它只读取列名和行数据,输入结构稳定以后,软件自动化才有可能重复执行。

归档里有大量已经拆分好的 Excel、内容提取文档和图片,说明这部分不是只针对一个样例写的。不同文档的标题、空表、缺失列和重复波束名都出现过,我在代码里逐步补上了标准化、默认值和日志。

在没有 API 的桌面软件里自动填写

Visualyse 没有适合这套流程的稳定批量接口,所以 AutoSetter 使用 PyWinAuto 的 UI Automation 查找窗口和控件,再用 PyAutoGUI 补充鼠标、滚轮、拖动和截图。

我没有完全依赖固定坐标。程序先查找可见的 Visualyse 进程,连接主窗口,再按控件文本和类型定位 TreeItem、Edit、Button 等元素。确实无法通过 UIA 操作的区域,才根据窗口边界和相邻控件位置计算点击坐标。

自动填写分成几组动作:

  • 建立地球站并填写经纬度;
  • 建立卫星或轨道对象并填写半长轴、偏心率、倾角等参数;
  • 复制和配置上下行链路;
  • 根据频率重叠结果增加干扰关系;
  • 保存、启动仿真,并等待运行状态结束;
  • 展开指定结果项,按固定规则截取设置与统计画面。

长时间桌面自动化必须能停。我给程序增加了全局运行状态和键盘监听,按 EscCtrl+C 可以中止;每个大步骤执行前都会检查状态。窗口滚动后,脚本还会重新确认控件是否进入可见区域,而不是盲点原坐标。

截图不能只靠人工抄数

仿真结果中的最坏值、超标时长和工作时长来自界面截图。AutoOCR 使用 PaddleOCR 3.0 的中文模型在 CPU 上识别,再把一张图里的文本先拼成完整字符串,最后用正则提取数据。

先拼接再匹配是我后来补上的改动。早期逐行匹配时,Threshold is exceeded for ... out of ... 这类信息只要被 OCR 拆成两行,就会漏掉。完整文本能够容忍换行和部分空格变化,正则也同时兼容几种常见识别结果。

截图按组编号,每组最多包含下行长时、下行短时、下行工作时长、上行最坏值和上行工作时长。脚本会自动判断一组里实际有哪些图片,不强迫所有场景同时存在上下行数据。

提取完成后,我计算干扰占比,并检查上下行工作时长是否一致、长短时最坏值是否一致,以及指标是否越过设定阈值。异常单元会在 Excel 中用条件格式标出,方便人工复核。OCR 的作用不是替代复核,而是把人工注意力集中到少数可疑结果上。

日志绘图和报告模板

截图之外,仿真软件还会输出按时间排列的日志。AutoDrawer 用 Pandas 读取日志,Matplotlib 和 Seaborn 绘制干扰曲线,并画出对应阈值线。每张图按约定编号保存,后面的 Word 模板可以直接找到。

AutoWriter 读取整理后的轨道、频段、地球站、链路和上下行结果,再用 docxtpl 把文字、表格与图片填入模板。项目同时维护了不同仿真对象和两套报告版式,公共逻辑保持一致,差异留在模板与映射里。

报告先生成临时 .docx,随后通过 Word COM 转成要求的 .doc 格式。转换成功后删除临时文件;如果 Word COM 失败,则保留 .docx 和错误日志,避免整次仿真结果因为最后一步失败而丢失。

我现在会怎样继续改

这套程序已经把原本分散的人工步骤连成了可重复流程,但它仍然带着很明显的项目现场痕迹:部分路径和模式写在脚本配置里,五个模块需要按顺序运行,GUI 自动化也会受到窗口缩放和软件版本影响。

如果继续维护,我会先增加统一的 YAML 配置和任务清单,再用一个调度入口串联模块,同时为每个处理单元保存状态。某个单元 OCR 失败时,只重跑这一单元,不必重新填写全部仿真。GUI 部分还应该记录控件截图和失败现场,减少远程排错时的信息缺失。

这次项目让我明白,桌面自动化的价值不只是替人点击。真正省时间的是把输入、软件状态、截图、结构化结果和最终文档放进同一条可追踪的数据流。只自动填写前半段,后面仍靠人工抄表,整体效率不会有本质变化。