Files
skills-win/altium-kicad/references/playbook.md
T
2026-09-09 09:51:06 +08:00

228 lines
11 KiB
Markdown
Raw 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.
# Altium → KiCad 迁移 Playbook
两次真实迁移(XMOD_V1.0:10层/1191元件/15页;GQ_EXCT7G_V1:ADRV9009 板)踩出来的东西。
SKILL.md 只写「怎么走」,这里写「为什么」和「踩了会怎样」。遇到卡壳先回来查这里。
---
## 1. 为什么必须先转 ASCII
KiCad 10.0.4 的 Altium **原理图**解析器不支持 AD26 的二进制 `.SchDoc`。直接
`File → Import Non-KiCad Project → Altium Project` 会报:
```
Header already parsed
```
PCB 解析器是好的,只有原理图这一侧不行。二进制 `.SchDoc` 是 CFB 复合文档
(文件头 `D0 CF 11 E0`),ASCII 版则以 `|HEADER=Protel for Windows` 开头。
Altium 侧的出路是 `IServerDocument.DoFileSave('ASCII')`,没有 CLI,只能跑
DelphiScript。两个坑:
- **不要经 MCP 驱动这个脚本**。`obj_run_process(ScriptingSystem:RunScript)` 会与
桥接自己的 `StartMCPServer` 脚本冲突挂起 —— Altium 一次只能跑一个脚本。
正确姿势:**先停掉 eda-agent**,再在 Altium GUI 里 `File → Run Script` 手动跑。
- **DelphiScript 的 `FindFirst` 枚举不可靠**,脚本里的文件名必须是硬编码列表。
`stage_ascii.py stage` 就是干这个的:用 Python 枚举出实际的 `.SchDoc`,把名字
灌进生成的 `.pas` 里。
转换只对 staging 副本做,原始工程一个字节都不能动。
---
## 2. eda-agent(altium MCP)桥接的脾气
桥接不是常驻服务,是 Altium GUI 里跑的一个轮询 DelphiScript:
- **约 10 分钟空闲会自己停**。跑长任务中途回来发现 `app_ping` 不通是常态,
重跑 `Dispatcher.pas → StartMCPServer` 即可,图里 `check_altium_bridge` 的
回环就是为这个留的。
- **一次只能跑一个脚本**,所以任何别的 DelphiScript 都要先停桥接。
- 开启路径:`DXP/Preferences → Scripting System → Global Projects → Install`
选 `Altium_API.PrjScr`,然后 `File → Run Script → Dispatcher.pas →
StartMCPServer → Run`,状态窗出现 `MCP: idle` 就是通了。
- **eda-agent 生不了 Gerber**。`proj_run_output(gerber)` 在没有 OutJob 的工程上
是空操作。Altium 侧的 Gerber 只能让用户在 GUI 里
`File → Fabrication Outputs → Gerber Files` 手动导。
---
## 3. KiCad 导入这一步没有自动化通道
整工程导入必须在 **KiCad 主程序(工程管理器)** 里点:
`File → Import Non-KiCad Project → Altium Project...`
源选 **staging 里的 `_ascii` 版 `.PrjPCB`**,目标选 target_dir。
`kicad-cli pcb import --format altium` 只能转 PCB 单板,**不要拿它替换主板** ——
那样会切断原理图↔PCB 的关联。它有用的地方是另转一份到 `_migration/cli_pcb/`
当几何参考/对照。
导入完成后常见的两个结构问题:
- **扁平层次**:导入器不生成 sheet 符号,所有页平铺;还可能把某一页当成根图。
Save All 时可能生成重复的 `.kicad_sch`(例如 `12.XC7Z100_HP.kicad_sch` 多一份)。
确认无引用后删掉重复文件即可,页数要能对回基线。
- **`IEEE_SYMBOL` 未处理记录**:IEEE 装饰符号被跳过,无害,不用管。
文件数核对就是拿「Altium 原理图页数 + 1 块 PCB」对
`target_dir` 下的 `*.kicad_sch` + `*.kicad_pcb` 计数。
---
## 4. 导入后 PCB 的两个必修项
### 4.1 BGA / 平面焊盘丢网络(假短路的真凶)
Altium 用**负片内电层**隐式连接电源和地,焊盘本身不带网络信息。KiCad 没有这套
机制,导入时这些焊盘就空着网络。XMOD 实测 **527 个 BGA 电源/地焊盘丢网络**,
DRC 里表现为 103 个「GND vs 空网络」短路。
修法:拿阶段 0 导出的 Altium 网表真值(`netlist_tabular.csv` 的
component/pin/net)程序化回填。`fix_pcb.py` 就是干这个的,先 `--dry-run` 看量。
回填后还会剩一批查不到真值的空网络焊盘 —— 多是 RJ45 屏蔽壳、机械/安装孔焊盘,
按实际情况单独指派 GND(XMOD 是 18 个)。
### 4.2 覆铜 zone 的本地 clearance(异 net 避让偏大的真凶)
这是最容易白费力气的一个坑。Altium 导入器把**每一块 zone 的本地 Clearance
写成 KiCad 默认的 0.5mm**,落在 `.kicad_pcb` 里长这样:
```
(zone ... (connect_pads (clearance 0.5)) ...)
```
而 **zone 的本地值会盖过网络类 clearance**。所以只改 `.kicad_pro` 的网络类
(比如 0.2mm)或板级规则,铺铜避让一点都不会变 —— 必须逐块 zone 改。
目标值取 Altium 的 **polygon clearance**(InPolygon 规则,去基线
`pcb_design_rules.json` 查;XMOD 和 GQ 实测都是 **0.254mm**,但别照抄)。
**热焊盘不用动**:KiCad 的 `thermal_gap` 0.1651mm 已经匹配 Altium
`PolygonConnect` 的 AirGap 0.165mm。
改完必须重填铺铜。大板上 **SWIG/pcbnew 的 refill 容易超时甚至段错误**,
去 KiCad GUI 里按 `B`,或者走 IPC 后端。
### 4.3 DRC 数字的正常轨迹
导入只搬几何,规则用的是 KiCad 默认(比 Altium 严),所以初始 DRC 会很吓人。
XMOD 的轨迹供参考:按基线改完 `.kicad_pro` 规则 **2878 → 1481**(错误
1810→414,track/via/drill 三类规则误报各 199 清零);再回填 527 个焊盘网络 +
重填铺铜后 clearance 282→0、via_dangling 199→15、shorting 103→92。
残留的 92 是板角铺铜畸变和连接器,不是真短路。
---
## 5. 网表比对:比 partition,不比网络名
两个工具的命名规则不同,逐名比对必然一片红。要比的是**等价类**:把网表归约成
「每个引脚 → 它所在网络的全部节点集合」,两侧集合相等即电气一致。
三个归一化,少一个就出假差异:
1. **KiCad 网名有前导 `/`**(层次路径),Altium 没有 → 剥掉。
XMOD 初比出的 16 个差异全是 `R_I-` vs `/R_I-` 这种。
2. **Altium tabular 导出有 `net=?` 的重复行**(隐藏的电源/平面引脚被重复列出)。
XMOD 原始 9511 行里有 4500 行是 `?`,去重后才是 5011 个真实节点。
3. **KiCad 扁平结构下整体导出网表会漏页** —— XMOD 整体导出只拿到根图的 98 个
节点。必须**逐页** `kicad-cli sch export netlist --format kicadxml` 再按网名合并
(5011 节点 / 1186 元件 / 1477 网)。格式必须是 **kicadxml**;PADS 格式会漏掉
单节点网(只得 4154)。
XMOD 终判:5011=5011 节点全同、0 单边节点、等价类集合完全相等(1473=1473)、
0 实质差异 → **网表 100% 一致**。
`netcmp.py` 把上面全部实现了,包括逐页导出。
---
## 6. Gerber / 几何比对:什么叫「100% 一致」
**跨工具 byte/像素级一致不可能**,这不是没做好,是物理上做不到:aperture、
坐标格式、填充算法、字体引擎、正负片全都不同。所以判定基准必须先界定清楚:
**判定 = 逐层制造几何等价。** 离散铜(走线/焊盘/过孔/孔/板框)要零差异;
铺铜填充纹理、丝印字形、负片内电层属于**工具固有容差项**。
### 6.1 决定性证据是矢量比对,不是栅格 XOR
栅格 XOR(pygerber 渲染后逐像素)只能给「像什么程度」的百分比,说服力有限。
矢量比对是逐条逐个匹配走线和过孔,对上就是同一块板。
XMOD 的矢量结论:**走线 12144=12144、过孔 4808=4808 逐条逐个相同,
`TOTAL_DISCRETE_DIFF=0`**。
坐标变换只有 2 个自由参数(平移),由两侧过孔质心解出;用 2 个参数去对上
几千个图元,对上了就是实证而不是曲线拟合。Altium 与 KiCad 之间是**纯平移,
无翻转无镜像**(XMOD 实测 `KiCad = Altium + (38.501, −180.004)`)。
注意 Altium 的 y 轴向上、KiCad 向下,变换里 y 要取负。
容差取 **30um**:eda-agent 读出的 Altium 坐标是整数 mil,读数精度本身
±12.7um,两端各一次就接近 25um;KiCad 侧是精确的。
`dump_kicad_vec.py` + `cmp_vec.py` 实现这一套,Altium 侧的 JSON 格式见
`vector-compare.md`。
### 6.2 栅格比对的参考数值(XMOD 逐层)
| 层 | 差异 | 判定 |
|----|------|------|
| 焊盘 Paste | 0.035% | 完全一致(也用来验证平移变换的精度) |
| 板框 Profile | 0.34% | 一致 |
| 外层铜 F_Cu | 1.04% | 基本一致 |
| 阻焊 Mask | ~2% | 扩展量微差 |
| 丝印 Silk | 42–70% | 字体引擎不同,固有 |
| 内电层 GND/POWER ×5 | 反相后 ~12% | Altium 负片 vs KiCad 正片 |
| 内层信号 ×3 | 高 | 铺铜覆盖/填充差异 |
看到丝印 70% 不要慌,那是字体,不是错。负片内电层必须**先反相**才能比。
### 6.3 三个不可消除的工具固有差异(已查明根因,不是缺陷)
1. **负片内电层**:KiCad 架构里没有「内电层」这种层类型,也没有负片输出能力。
与 Altium 的负片格式无法一致,但**物理铜等价**——制板厂显影结果相同。
2. **铺铜填充纹理**:填充算法不同(热焊盘辐条/网格/反焊盘),即使轮廓和网络
完全相同也不可能逐像素一致。
3. **丝印字体**:字体引擎不同。
验收报告里要把这三条明确列为容差项,别当缺陷去修 —— 修不掉。
---
## 7. Altium 侧 Gerber 手动导出参数
eda-agent 生不了,让用户在 Altium 里导,参数要对齐 KiCad 侧:
- `File → Fabrication Outputs → Gerber Files`:单位 mm、精度 4:6、
Embedded RS274X、**不镜像**、**绝对原点**
- `File → Fabrication Outputs → NC Drill Files`
- 输出落在 `Project Outputs for <工程名>\`,复制到 `_migration/gerber/altium/`
KiCad 侧对应:`kicad-cli pcb export gerbers`(精度 6、绝对原点)+
`kicad-cli pcb export drill`(Excellon、mm)。
---
## 8. 证据目录约定
全部落在 `<target_dir>\_migration\`:
```
altium_baseline/ 阶段0 基线真值:stats / nets / bom / stackup / pcb_design_rules.json
reference/ 参考网表(netlist_tabular.csv) + 原理图 PDF
altium_source_snapshot/ 只读源副本
convert_to_ascii.pas 由 stage_ascii.py 生成
ascii_convert_log.txt DelphiScript 跑完的日志
cli_pcb/ kicad-cli 忠实导入的 PCB(仅作几何参考,不替换主板)
netcmp/ xml_*.xml 逐页网表 + diff.json + 报告
gerber/ altium_vec/ kicad_vec/ layer_map.json + 比对报告
backup/ 每次改板前的 .kicad_pcb 快照
verification_report.md 最终验收报告
```
XMOD 的基线真值(作为「基线该长什么样」的样例):15 页 / 元件 1191(PCB 1186)/
管脚 9511 / 网络 1474 / 10 层 / 走线 21296 · 过孔 4808 · 焊盘 5154 /
未布线 0 / 224×150mm / 41 条设计规则。