62 行
2.5 KiB
Python
62 行
2.5 KiB
Python
"""Inject measurement-route faults in memory without saving the production PCB."""
|
|
import argparse
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
|
|
import pcbnew as pcb
|
|
|
|
from kelvin_checks import check_measurement_branches
|
|
from schematic_maintenance import ROOT
|
|
|
|
|
|
def run_case(case):
|
|
path = ROOT / 'PhoneRail-Board1/PhoneRail-Board1.kicad_pcb'
|
|
branches = json.loads((ROOT / 'pcb-routing-rules.json').read_text(encoding='utf-8'))['measurement_branches']
|
|
board = pcb.LoadBoard(str(path))
|
|
tracks = {t.m_Uuid.AsString(): t for t in board.GetTracks()}
|
|
track = tracks[branches[0]['track_uuids'][0]]
|
|
if case == 'missing_segment':
|
|
board.Remove(track)
|
|
elif case == 'load_branch_on_sense_trace':
|
|
a, b = track.GetStart(), track.GetEnd()
|
|
mid = pcb.VECTOR2I((a.x+b.x)//2, (a.y+b.y)//2)
|
|
branch = pcb.PCB_TRACK(board)
|
|
branch.SetStart(mid)
|
|
branch.SetEnd(pcb.VECTOR2I(mid.x+pcb.FromMM(1), mid.y))
|
|
branch.SetWidth(pcb.FromMM(.5))
|
|
branch.SetLayer(track.GetLayer())
|
|
branch.SetNet(track.GetNet())
|
|
board.Add(branch)
|
|
result = check_measurement_branches(board, branches)
|
|
if case == 'baseline':
|
|
assert not result['errors'] and len(result['branches']) == 10, result
|
|
elif case == 'missing_segment':
|
|
assert any(e['kind'] == 'kelvin_missing_items' for e in result['errors']), result
|
|
else:
|
|
assert any('branch_join_outside_shunt_land' in e.get('issues', []) for e in result['errors']), result
|
|
return {'case': case, 'passed': True, 'detected_errors': result['errors']}
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('--case', choices=('baseline', 'missing_segment', 'load_branch_on_sense_trace'))
|
|
args = parser.parse_args()
|
|
folder = ROOT / 'out/local-routing-r3'
|
|
if args.case:
|
|
result = run_case(args.case)
|
|
(folder / f'kelvin-probe-{args.case}.json').write_text(json.dumps(result, indent=2)+'\n', encoding='utf-8')
|
|
return
|
|
results = []
|
|
# Isolate native KiCad object ownership for each destructive in-memory probe.
|
|
for case in ('baseline', 'missing_segment', 'load_branch_on_sense_trace'):
|
|
subprocess.run([sys.executable, __file__, '--case', case], check=True, timeout=60)
|
|
results.append(json.loads((folder / f'kelvin-probe-{case}.json').read_text(encoding='utf-8')))
|
|
out = folder / 'kelvin-probe.json'
|
|
out.write_text(json.dumps({'passed': True, 'cases': results}, indent=2)+'\n', encoding='utf-8')
|
|
print(json.dumps(results))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|