kicad-library-utils
kicad-library-utils copied to clipboard
Add F5.3 (4-9) courtyard clearance check
The courtyard clearance tolerance seems very tight, e.g. 0.5 +/- 0.05 mm for connectors. It would be good if the utils would check (and fix?) this.
Hey @aewallin Is this still an issue you encounter? I would like to look into it, if you still find any inconvinience with it. Maybe you can elaborate a little?
I assume the idea is to look at the fab-lines and all the copper. Make a union of them and offset that by the clearance. Then snap it to the 0.01mm grid. That should give you the proper courtyard. The same will also be possible for non connector parts.
The problem with automatic checking is that the scripts don't know which class of device they are working with. Is it a connector, a passive or a BGA? So selecting the proper clearance is not trivial.
And then there are quite a lot of corner cases (for example RJ45_Plug_Metz_AJP92A8813). But that might not be a real issue. We rather have a few more false positives than errors that are not found at all.
For checking KLC-compliance, at least the script could determine what the courtyard clearance is, and inform the user what category of component the courtyard is OK for. That check might not be trivial, for example if the part is a square and the courtyard is a square then the distance from the courtyard-line to the component will be sqrt(2) larger in the corners... Maybe just a minimum distance between courtyard and the part (pads+fab) is enough?
For generating the courtyard, probably it makes sense to use a library like Clipper (or similar) http://www.angusj.com/delphi/clipper.php The algorithm would first assemble the part geometry (pads+fab), and then do an offset from that to generate the courtyard.
KLC F.5.3, for reference:
1 Courtyard uses 0.05mm line width 2 All courtyard line elements are placed on a 0.01mm grid 3 If the component requires a courtyard on the back of the PCB, a corresponding courtyard must be provided on the B.CrtYd layer. 4 Where the courtyard depends on the dimensions of the physical part body, clearance is calculated from the nominal part dimensions. Courtyard clearance should adhere to the following requirements: 5 Unless otherwise specified, clearance is 0.25mm 6 Components smaller than 0603 should have a clearance of 0.15mm 7 Connectors should have a clearance of 0.5mm, in addition to the clearance required for mating of connector 8 Canned capacitors should have a clearance of 0.5mm 9 Crystals should have a clearance of 0.5mm 10 BGA devices should have a clearance of 1.0mm
I suggest to start with robust checking, refine that as needed, and then make courtyard creation a second step. That brings some benefit more quickly and allows discussion about how to create the courtyard to continue without holding up all activity.
FWIW (not much) I cobbled together something like this for an 'auto-courtyard' generator. I find it almost impossible to draw 'by-hand' a courtyard that is KLC compliant using the standard footprint editor. I think most advanced reviewers use FreeCAD which has better dimensioning and drawing tools.
the script below assumes there is no existing courtyard, reads the f.fab and pads into a bounding box, and adds a new (hopefully KLC compliant) bounding box, saves the footprint with a new name.
something like this would be cool to have as a button-press-operation (plugin?) in the footprint editor.
mod = kicad_mod.KicadMod(fname)
# BB to contain pads and F.Fab
box_all = kicad_mod.BoundingBox()
bb = mod.geometricBoundingBox('F.Fab')
bp = mod.overpadsBounds()
box_all.addBoundingBox(bb)
box_all.addBoundingBox(bp)
print "pads X", bp.xmin, bp.xmax
print "pads Y", bp.ymin, bp.ymax
print "fab X", bb.xmin, bb.xmax
print "fab Y", bb.ymin, bb.ymax
print "all X", box_all.xmin, box_all.xmax
print "all Y", box_all.ymin, box_all.ymax
# BB for Courtyard
crt = kicad_mod.BoundingBox(box_all.xmin, box_all.ymin, box_all.xmax, box_all.ymax)
clearance = 0.25
#clearance = 0.5 # CONNECTORS
crt.expand(clearance)
grid = rules.klc_constants.KLC_CRTYD_GRID
# snap to grid
gxmin, gxmax, gymin, gymax = round(crt.xmin/grid), round(crt.xmax/grid), round(crt.ymin/grid), round(crt.ymax/grid)
# new, snapped Courtyard BB
crt_grid = kicad_mod.BoundingBox( gxmin*grid, gymin*grid, gxmax*grid, gymax*grid )
print "crt X", crt.xmin, crt.xmax
print "crt Y", crt.ymin, crt.ymax
print "gcrt X", crt_grid.xmin, crt_grid.xmax
print "gcrt Y", crt_grid.ymin, crt_grid.ymax
# add Rectangle to footprint
mod.addRectangle( (crt_grid.xmin, crt_grid.ymin), (crt_grid.xmax, crt_grid.ymax), 'F.CrtYd', 0.05)
# write to disk
fname2 = fname[:-10]+"_AutoCrtYd.kicad_mod"
#mod.save(fname2)
mod.save()