kicad:EasyEDA→KiCad 工程(Board1/Board2)、库、脚本与评审文档(IC 引脚、风扇、热、EDL 供电、布局规则)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
@@ -0,0 +1,58 @@
|
||||
"""Run native DRC, schematic parity, and render the two unrouted PCB boards."""
|
||||
from collections import Counter
|
||||
import json
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
|
||||
import pcbnew as pcb
|
||||
|
||||
from bootstrap_pcb import ROOT, OUT, mating_check, verify_import
|
||||
from check_hardware import Board
|
||||
|
||||
CLI = 'D:/KiCad/bin/kicad-cli.exe'
|
||||
|
||||
|
||||
def run(args, output):
|
||||
result = subprocess.run([CLI, *args], capture_output=True, encoding='utf-8',
|
||||
errors='replace', timeout=120)
|
||||
output.with_suffix(output.suffix+'.log').write_text(result.stdout+result.stderr,encoding='utf-8')
|
||||
if result.returncode or not output.exists():
|
||||
raise RuntimeError(f'KiCad failed ({result.returncode}); see {output}.log')
|
||||
|
||||
|
||||
def main():
|
||||
reports, boards = {}, []
|
||||
for n in (1,2):
|
||||
name = f'PhoneRail-Board{n}'
|
||||
path = ROOT/name/(name+'.kicad_pcb')
|
||||
source = Board(n)
|
||||
source.compile(CLI,OUT)
|
||||
board = pcb.LoadBoard(str(path))
|
||||
checks = verify_import(board,source,n)
|
||||
boards.append(board)
|
||||
drc = OUT/f'Board{n}-drc.json'
|
||||
run(['pcb','drc','--format','json','--schematic-parity','-o',str(drc),str(path)],drc)
|
||||
data = json.loads(drc.read_text(encoding='utf-8'))
|
||||
checks['drc_violations'] = dict(Counter(v['type'] for v in data.get('violations',[])))
|
||||
checks['unconnected_items'] = len(data.get('unconnected_items',[]))
|
||||
checks['schematic_parity'] = data.get('schematic_parity',[])
|
||||
assert not checks['schematic_parity'], f'{name}: schematic parity mismatch'
|
||||
assert not data.get('violations'), f'{name}: DRC geometry/library violation; see {drc}'
|
||||
roundtrip = OUT/f'{name}-roundtrip.kicad_pcb'
|
||||
pcb.SaveBoard(str(roundtrip),board)
|
||||
verify_import(pcb.LoadBoard(str(roundtrip)),source,n)
|
||||
checks['native_save_roundtrip'] = 'passed'
|
||||
for face,layers in [('top','F.Cu,Edge.Cuts,Dwgs.User'),('bottom','B.Cu,Edge.Cuts,Dwgs.User')]:
|
||||
svg = OUT/f'Board{n}-{face}.svg'
|
||||
run(['pcb','export','svg','--mode-single','--layers',layers,'--page-size-mode','2',
|
||||
'--exclude-drawing-sheet','-o',str(svg),str(path)],svg)
|
||||
reports[name] = checks
|
||||
print(name, 'DRC', checks['drc_violations'], 'unconnected',checks['unconnected_items'],
|
||||
'schematic parity',len(checks['schematic_parity']),flush=True)
|
||||
reports['mated_pins_checked'] = mating_check(*boards)
|
||||
reports['status'] = 'UNROUTED_PLACEMENT_START'
|
||||
(OUT/'verification.json').write_text(json.dumps(reports,indent=2,ensure_ascii=False)+'\n',encoding='utf-8')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
在新工单中引用
屏蔽一个用户