R2:底板 / 刀片布局布线脚本、快照、截图与规划文档更新(含外壳、打印件、布线归档)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
"""对账 4:封装库完整性。
|
||||
|
||||
三项:
|
||||
1. 原理图里每个元件引用的封装,库里都有;
|
||||
2. 封装的焊盘号集合 ⊇ 符号的引脚号集合(少一个焊盘 = 网络接不上,PCB 里才会暴露);
|
||||
3. 文件能被 KiCad 解析(交给 kicad-cli 做)。
|
||||
"""
|
||||
import json, os, re, sys, collections
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from k_netlist import parse_pads
|
||||
|
||||
ROOT = os.path.dirname(os.path.abspath(__file__))
|
||||
SRC = os.path.join(ROOT, "eda_src")
|
||||
PRETTY = os.path.join(os.path.dirname(ROOT), "kicad", "lib", "PhoneRail.pretty")
|
||||
|
||||
|
||||
def fp_pads(path):
|
||||
s = open(path, encoding="utf-8").read()
|
||||
return {m.group(1) for m in re.finditer(r'\(pad "([^"]*)"', s)}
|
||||
|
||||
|
||||
def main():
|
||||
have = {}
|
||||
for f in os.listdir(PRETTY):
|
||||
if f.endswith(".kicad_mod"):
|
||||
have[f[:-10]] = fp_pads(os.path.join(PRETTY, f))
|
||||
ok = True
|
||||
for board in ("Board1", "Board2"):
|
||||
base = parse_pads(os.path.join(SRC, board, "netlist.asc"))
|
||||
want = collections.Counter(base["parts"].values())
|
||||
missing = sorted(n for n in want if n and n not in have)
|
||||
print(f"[{board}] 引用封装 {len(want)} 种", end="")
|
||||
if missing:
|
||||
print(f" ✘ 库里缺 {len(missing)}: {missing[:6]}"); ok = False
|
||||
else:
|
||||
print(" ✔ 全部存在")
|
||||
# 焊盘号 vs 引脚号
|
||||
tree = json.load(open(os.path.join(SRC, "_tree.json"), encoding="utf-8"))
|
||||
pages = next(x for x in tree["boards"] if x["board"] == board)["pages"]
|
||||
bad = []
|
||||
for p in pages:
|
||||
g = json.load(open(os.path.join(SRC, board, p["name"] + ".geom.json"), encoding="utf-8"))
|
||||
for c in (g["prims"]["Component"] or []):
|
||||
if c["ComponentType"] != "part":
|
||||
continue
|
||||
fp = (c.get("Footprint") or {}).get("name")
|
||||
if fp not in have:
|
||||
continue
|
||||
pins = {str(q["PinNumber"]) for q in (c.get("__pins") or [])}
|
||||
miss = pins - have[fp]
|
||||
if miss:
|
||||
bad.append((c["Designator"], fp, sorted(miss)[:4]))
|
||||
if bad:
|
||||
print(f" ✘ 引脚号在封装里找不到对应焊盘 {len(bad)}: {bad[:4]}"); ok = False
|
||||
else:
|
||||
print(" ✔ 焊盘号覆盖全部引脚号")
|
||||
print("\n" + ("封装库检查通过 ✔" if ok else "封装库有问题 ✘"))
|
||||
sys.exit(0 if ok else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
在新工单中引用
屏蔽一个用户