Files
Kill_LIFE/ai-agentic-embedded-base/tools/hw/drc/generate_custom_rules.py
T
Clément SAILLANT dda793c0ef feat(hw): add schops tool for schematic operations and kicad-cli integration
- Introduced `kicad_cli.sh` for local and Docker-based kicad-cli execution.
- Created `schops.py` for schematic operations including ERC, BOM, netlist exports, and bulk edits.
- Added README.md for schops with installation and usage instructions.
- Included requirements.txt for necessary Python packages.
- Implemented rules engine for applying field defaults and renaming nets.
- Added tests for rules engine functionality.
- Introduced scope guard script to enforce file modification policies based on PR labels.
- Created watch script to monitor KiCad files and trigger hardware gate on changes.
2026-02-19 00:00:33 +01:00

46 lines
1.9 KiB
Python

#!/usr/bin/env python3
"""Generate KiCad Custom Rules snippet from compliance profile.
This outputs a text snippet compatible with KiCad's Custom Rules (stored in *.kicad_dru).
Recommended workflow:
- run this generator
- paste/import into PCB Editor -> Board Setup -> Custom Rules
- commit the resulting <board>.kicad_dru (generated by KiCad) if you want it versioned
We keep it minimal and profile-driven: track width, clearance, via/hole sizes, annular ring.
"""
import argparse
from tools.compliance.common import load_profile, load_active_profile_name
def mm(v):
# format for KiCad constraints
return f"{v:.3f}mm"
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--profile", default="", help="Profile name (default: active profile)")
args = ap.parse_args()
prof_name = args.profile.strip() or load_active_profile_name()
prof = load_profile(prof_name)
rules = prof.get("pcb_rules") or {}
tw = float(rules.get("min_track_width_mm", 0.20))
cl = float(rules.get("min_clearance_mm", 0.20))
drill = float(rules.get("min_via_drill_mm", 0.30))
ar = float(rules.get("min_annular_ring_mm", 0.15))
out = []
out.append("(version 1)")
out.append(f"# Generated from compliance profile: {prof_name}")
out.append(f"# Min track width: {tw} mm; min clearance: {cl} mm; min drill: {drill} mm; min annular ring: {ar} mm")
out.append("")
out.append(f"(rule \"Track width (all layers)\" (condition \"A.Type == 'track'\") (constraint track_width (min {mm(tw)})) )")
out.append(f"(rule \"Clearance (track/pad/via)\" (condition \"A.Net != B.Net\") (constraint clearance (min {mm(cl)})) )")
out.append(f"(rule \"Hole diameter (all)\" (constraint hole_size (min {mm(drill)})) )")
out.append(f"(rule \"Annular ring width (plated)\" (condition \"A.isPlated()\") (constraint annular_width (min {mm(ar)})) )")
print("\n".join(out))
if __name__ == "__main__":
main()