Integrate A1 carrier PCB CAD updates
- Add pinned STEP-derived DE-9 mechanical measurements and provenance - Refresh placement, routing, silkscreen, and nominal CAD envelopes - Document provisional dimensions, assumptions, and validation status
This commit is contained in:
@@ -109,10 +109,10 @@ def boundary(radius):
|
||||
edge = 0.5 + radius + MARGIN
|
||||
mask = np.broadcast_to((X < 100 + edge) | (X > 182 - edge) |
|
||||
(Y < 100 + edge) | (Y > 180 - edge), (NY, NX)).copy()
|
||||
mask |= (X < 136 + edge) & (Y > 161 - edge)
|
||||
mask |= (X < 136 + edge) & (Y < 119 + edge)
|
||||
# Expand the RF reservation by copper radius plus numerical safety margin.
|
||||
r = radius + MARGIN
|
||||
mask |= (X >= 110 - r) & (X <= 131 + r) & (Y <= 113 + r)
|
||||
mask |= (X >= 110 - r) & (X <= 131 + r) & (Y >= 119 - r) & (Y <= 132 + r)
|
||||
return mask
|
||||
|
||||
|
||||
@@ -275,13 +275,15 @@ def main():
|
||||
if ROOT.joinpath('~serial-carrier.kicad_pcb.lck').exists():
|
||||
parser.error('PCB editor lock exists; close the PCB before routing')
|
||||
original_bytes = PCB.read_bytes()
|
||||
project = ROOT / 'serial-carrier.kicad_pro'
|
||||
project_before = project.read_bytes()
|
||||
board = p.LoadBoard(str(PCB))
|
||||
before = identity(board)
|
||||
if board.GetCopperLayerCount() != 2 or len(board.GetFootprints()) != 13:
|
||||
parser.error('unexpected board structure; review router assumptions')
|
||||
if len(board.Zones()) != 1 or not board.Zones()[0].GetIsRuleArea():
|
||||
parser.error('unexpected zones; router supports only the original RF rule area')
|
||||
outline = [(100, 100), (182, 100), (182, 180), (136, 180), (136, 161), (100, 161)]
|
||||
outline = [(136, 100), (182, 100), (182, 180), (100, 180), (100, 119), (136, 119)]
|
||||
expected_edges = {frozenset((a, b)) for a, b in zip(outline, outline[1:] + outline[:1])}
|
||||
actual_edges = {frozenset(((p.ToMM(e.GetStart().x), p.ToMM(e.GetStart().y)),
|
||||
(p.ToMM(e.GetEnd().x), p.ToMM(e.GetEnd().y))))
|
||||
@@ -292,7 +294,7 @@ def main():
|
||||
contour = reserve.Outline().COutline(0)
|
||||
rf_points = {(p.ToMM(contour.CPoint(i).x), p.ToMM(contour.CPoint(i).y))
|
||||
for i in range(contour.PointCount())}
|
||||
if (rf_points != {(110, 100), (131, 100), (131, 113), (110, 113)} or
|
||||
if (rf_points != {(110, 119), (131, 119), (131, 132), (110, 132)} or
|
||||
not all(reserve.IsOnLayer(layer) for layer in LAYERS) or
|
||||
not all((reserve.GetDoNotAllowTracks(), reserve.GetDoNotAllowVias(),
|
||||
reserve.GetDoNotAllowZoneFills()))):
|
||||
@@ -313,8 +315,9 @@ def main():
|
||||
if len(netpads) > 1:
|
||||
name = netpads[0].GetNetname()
|
||||
for length, a, b in pairs_for_net(netpads):
|
||||
# Short local links first, then the long signal fanout; ground last.
|
||||
priority = (name == '/GND', length)
|
||||
# Reserve short ground escapes before signal fanout can box them in.
|
||||
# Long ground links still run last, preserving space for signal paths.
|
||||
priority = (name == '/GND' and length > 15, length)
|
||||
work.append((priority, net, name, a, b))
|
||||
work.sort(key=lambda w: (w[0], w[2]))
|
||||
start_time = time.monotonic()
|
||||
@@ -354,7 +357,8 @@ def main():
|
||||
raise RuntimeError('PCB changed or editor opened during routing; refusing overwrite')
|
||||
# Check a serialized candidate before replacing the user's board.
|
||||
candidate = ROOT / 'validation/pcb-routing-candidate.kicad_pcb'
|
||||
p.SaveBoard(str(candidate), board)
|
||||
assert p.SaveBoard(str(candidate), board, True)
|
||||
assert project.read_bytes() == project_before, 'project settings changed'
|
||||
assert identity(p.LoadBoard(str(candidate))) == before, 'saved identity mismatch'
|
||||
candidate.replace(PCB)
|
||||
ROOT.joinpath('validation/pcb-routing-run.json').write_text(json.dumps(report, indent=2)+'\n')
|
||||
|
||||
Reference in New Issue
Block a user