Initial Ti375 GNSS IMU board design and documentation
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Compensate Freerouting 2.3.0's KiCad-10 DSN clearance scale mismatch.
|
||||
|
||||
KiCad exports widths and clearances in micrometres. Freerouting 2.3.0 keeps
|
||||
the widths but internally imports DSN clearance values at one quarter of the
|
||||
intended physical value. Scaling only ``(clearance N)`` entries by four makes
|
||||
the router's physical rules match the source KiCad board. Coordinates, track
|
||||
widths, vias, drills, padstacks, and keepouts are deliberately untouched.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
CLEARANCE = re.compile(r"(\(clearance\s+)(\d+(?:\.\d+)?)")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("input", type=Path)
|
||||
parser.add_argument("output", type=Path)
|
||||
parser.add_argument("--factor", type=float, default=4.0)
|
||||
args = parser.parse_args()
|
||||
|
||||
source = args.input.read_text()
|
||||
original = [float(match.group(2)) for match in CLEARANCE.finditer(source)]
|
||||
if not original:
|
||||
raise RuntimeError(f"No clearance rules found in {args.input}")
|
||||
|
||||
def scale(match: re.Match[str]) -> str:
|
||||
value = float(match.group(2)) * args.factor
|
||||
rendered = str(int(value)) if value.is_integer() else f"{value:g}"
|
||||
return match.group(1) + rendered
|
||||
|
||||
converted, count = CLEARANCE.subn(scale, source)
|
||||
scaled = [float(match.group(2)) for match in CLEARANCE.finditer(converted)]
|
||||
assert count == len(original) == len(scaled)
|
||||
assert all(after == before * args.factor
|
||||
for before, after in zip(original, scaled, strict=True))
|
||||
# A conversion must never touch the board geometry or trace-width rules.
|
||||
assert source.count("(width ") == converted.count("(width ")
|
||||
assert source.count("(polygon ") == converted.count("(polygon ")
|
||||
args.output.write_text(converted)
|
||||
print(f"Scaled {count} clearance rules by {args.factor:g}x")
|
||||
print(f"Saved {args.output}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user