80 行
3.7 KiB
Python
80 行
3.7 KiB
Python
"""Rotate J1 by 180 degrees and place its mating face at the left board edge."""
|
|
import hashlib
|
|
import json
|
|
import shutil
|
|
|
|
import pcbnew as pcb
|
|
|
|
import route_local_r1 as base
|
|
from schematic_maintenance import ROOT
|
|
|
|
OUT = ROOT / 'out/input-connector-r1'
|
|
|
|
|
|
def snapshot(board):
|
|
return {f.GetReference(): (f.GetPosition().x, f.GetPosition().y, f.GetOrientationDegrees(),
|
|
f.GetLayer(), [(p.GetNumber(), p.GetPosition().x, p.GetPosition().y,
|
|
p.GetNetname()) for p in f.Pads()])
|
|
for f in board.GetFootprints()}
|
|
|
|
|
|
def copper(board):
|
|
return {t.m_Uuid.AsString(): (t.GetStart().x, t.GetStart().y, t.GetEnd().x, t.GetEnd().y,
|
|
t.GetLayer(), t.GetWidth(), t.GetNetname()) for t in board.GetTracks()}
|
|
|
|
|
|
def main():
|
|
assert not (OUT / 'verification.json').exists(), 'Completed checkpoint exists'
|
|
OUT.mkdir(parents=True, exist_ok=True)
|
|
base.OUT = OUT
|
|
path = base.BOARD
|
|
start_hash = hashlib.sha256(path.read_bytes()).hexdigest()
|
|
backup = OUT / ('before-' + path.name)
|
|
if backup.exists():
|
|
assert hashlib.sha256(backup.read_bytes()).hexdigest() == start_hash, 'Source changed since failed attempt'
|
|
else:
|
|
shutil.copy2(path, backup)
|
|
board = pcb.LoadBoard(str(path))
|
|
before, tracks = snapshot(board), copper(board)
|
|
initial = base.unconnected_count(board)
|
|
part = next(f for f in board.GetFootprints() if f.GetReference() == 'J1')
|
|
assert part.GetOrientationDegrees() == 90
|
|
assert not any(t.GetNetname() in {p.GetNetname() for p in part.Pads()} for t in board.GetTracks()), 'Review existing input copper first'
|
|
part.SetOrientationDegrees(270)
|
|
part.SetPosition(pcb.VECTOR2I(pcb.FromMM(58.4), pcb.FromMM(67)))
|
|
part.Reference().SetTextAngle(pcb.EDA_ANGLE(0, pcb.DEGREES_T))
|
|
part.Reference().SetPosition(pcb.VECTOR2I(pcb.FromMM(58.4), pcb.FromMM(59)))
|
|
candidate = path.with_name('PhoneRail-Board1-input-candidate.kicad_pcb')
|
|
temporary = [candidate.with_suffix(s) for s in ('.kicad_pcb', '.kicad_pro', '.kicad_dru', '.kicad_prl')]
|
|
assert all(not p.exists() for p in temporary)
|
|
try:
|
|
for suffix in ('.kicad_pro', '.kicad_dru'):
|
|
shutil.copy2(path.with_suffix(suffix), candidate.with_suffix(suffix))
|
|
pcb.SaveBoard(str(candidate), board)
|
|
report = base.drc(candidate, 'drc')
|
|
assert not report['violations'], report['violations']
|
|
reloaded = pcb.LoadBoard(str(candidate))
|
|
after = snapshot(reloaded)
|
|
assert all(value == after[ref] for ref, value in before.items() if ref != 'J1')
|
|
assert copper(reloaded) == tracks
|
|
assert base.unconnected_count(reloaded) == initial
|
|
assert sorted((p[0], p[3]) for p in before['J1'][4]) == sorted((p[0], p[3]) for p in after['J1'][4])
|
|
assert hashlib.sha256(path.read_bytes()).hexdigest() == start_hash
|
|
shutil.copy2(candidate, path)
|
|
result = {'status': 'PLACEMENT_CORRECTED_NOT_RELEASED', 'reference': 'J1',
|
|
'before_position_mm': [63, 67], 'after_position_mm': [58.4, 67],
|
|
'before_angle_deg': 90, 'after_angle_deg': 270,
|
|
'mating_face': 'Left/outward; nominal outline x=50.25041mm, board edge x=50mm',
|
|
'native_drc_violations': 0, 'other_footprints_preserved': len(before)-1,
|
|
'existing_track_segments_preserved': len(tracks), 'unconnected_items': initial,
|
|
'board_sha256': hashlib.sha256(path.read_bytes()).hexdigest()}
|
|
(OUT / 'verification.json').write_text(json.dumps(result, indent=2)+'\n', encoding='utf-8')
|
|
print(json.dumps(result))
|
|
finally:
|
|
for p in temporary:
|
|
p.unlink(missing_ok=True)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|