Added simple test for the position file/s

This commit is contained in:
Salvador E. Tropea 2020-04-27 16:28:01 -03:00
parent 954dfa25bf
commit 9fc7653e9b
6 changed files with 447 additions and 0 deletions

View File

@ -0,0 +1,209 @@
(kicad_pcb (version 20171130) (host pcbnew 5.1.5+dfsg1-2~bpo10+1)
(general
(thickness 1.6)
(drawings 4)
(tracks 0)
(zones 0)
(modules 3)
(nets 1)
)
(page A4)
(layers
(0 F.Cu signal)
(31 B.Cu signal)
(32 B.Adhes user)
(33 F.Adhes user)
(34 B.Paste user)
(35 F.Paste user)
(36 B.SilkS user)
(37 F.SilkS user)
(38 B.Mask user)
(39 F.Mask user)
(40 Dwgs.User user)
(41 Cmts.User user)
(42 Eco1.User user)
(43 Eco2.User user)
(44 Edge.Cuts user)
(45 Margin user)
(46 B.CrtYd user)
(47 F.CrtYd user)
(48 B.Fab user)
(49 F.Fab user)
)
(setup
(last_trace_width 0.25)
(trace_clearance 0.2)
(zone_clearance 0.508)
(zone_45_only no)
(trace_min 0.2)
(via_size 0.8)
(via_drill 0.4)
(via_min_size 0.4)
(via_min_drill 0.3)
(uvia_size 0.3)
(uvia_drill 0.1)
(uvias_allowed no)
(uvia_min_size 0.2)
(uvia_min_drill 0.1)
(edge_width 0.05)
(segment_width 0.2)
(pcb_text_width 0.3)
(pcb_text_size 1.5 1.5)
(mod_edge_width 0.12)
(mod_text_size 1 1)
(mod_text_width 0.15)
(pad_size 1.524 1.524)
(pad_drill 0.762)
(pad_to_mask_clearance 0.051)
(solder_mask_min_width 0.25)
(aux_axis_origin 0 0)
(visible_elements FFFFFF7F)
(pcbplotparams
(layerselection 0x010fc_ffffffff)
(usegerberextensions false)
(usegerberattributes false)
(usegerberadvancedattributes false)
(creategerberjobfile false)
(excludeedgelayer true)
(linewidth 0.100000)
(plotframeref false)
(viasonmask false)
(mode 1)
(useauxorigin false)
(hpglpennumber 1)
(hpglpenspeed 20)
(hpglpendiameter 15.000000)
(psnegative false)
(psa4output false)
(plotreference true)
(plotvalue true)
(plotinvisibletext false)
(padsonsilk false)
(subtractmaskfromsilk false)
(outputformat 1)
(mirror false)
(drillshape 1)
(scaleselection 1)
(outputdirectory ""))
)
(net 0 "")
(net_class Default "Esta es la clase de red por defecto."
(clearance 0.2)
(trace_width 0.25)
(via_dia 0.8)
(via_drill 0.4)
(uvia_dia 0.3)
(uvia_drill 0.1)
)
(module Resistor_THT:R_Box_L13.0mm_W4.0mm_P9.00mm (layer F.Cu) (tedit 5AE5139B) (tstamp 5EA76EC0)
(at 110 45)
(descr "Resistor, Box series, Radial, pin pitch=9.00mm, 2W, length*width=13.0*4.0mm^2, http://www.produktinfo.conrad.com/datenblaetter/425000-449999/443860-da-01-de-METALLBAND_WIDERSTAND_0_1_OHM_5W_5Pr.pdf")
(tags "Resistor Box series Radial pin pitch 9.00mm 2W length 13.0mm width 4.0mm")
(fp_text reference R3 (at 4.5 -3.25) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value R_Box_L13.0mm_W4.0mm_P9.00mm (at 4.5 3.25) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text user 300 (at 4.5 0) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_line (start 11.25 -2.25) (end -2.25 -2.25) (layer F.CrtYd) (width 0.05))
(fp_line (start 11.25 2.25) (end 11.25 -2.25) (layer F.CrtYd) (width 0.05))
(fp_line (start -2.25 2.25) (end 11.25 2.25) (layer F.CrtYd) (width 0.05))
(fp_line (start -2.25 -2.25) (end -2.25 2.25) (layer F.CrtYd) (width 0.05))
(fp_line (start 11.12 -2.12) (end 11.12 2.12) (layer F.SilkS) (width 0.12))
(fp_line (start -2.12 -2.12) (end -2.12 2.12) (layer F.SilkS) (width 0.12))
(fp_line (start -2.12 2.12) (end 11.12 2.12) (layer F.SilkS) (width 0.12))
(fp_line (start -2.12 -2.12) (end 11.12 -2.12) (layer F.SilkS) (width 0.12))
(fp_line (start 11 -2) (end -2 -2) (layer F.Fab) (width 0.1))
(fp_line (start 11 2) (end 11 -2) (layer F.Fab) (width 0.1))
(fp_line (start -2 2) (end 11 2) (layer F.Fab) (width 0.1))
(fp_line (start -2 -2) (end -2 2) (layer F.Fab) (width 0.1))
(pad 2 thru_hole circle (at 9 0) (size 2 2) (drill 1) (layers *.Cu *.Mask))
(pad 1 thru_hole circle (at 0 0) (size 2 2) (drill 1) (layers *.Cu *.Mask))
(model ${KISYS3DMOD}/Resistor_THT.3dshapes/R_Box_L13.0mm_W4.0mm_P9.00mm.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)
(module Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder (layer B.Cu) (tedit 5B36C52B) (tstamp 5EA76DE9)
(at 110 35 270)
(descr "Resistor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal with elongated pad for handsoldering. (Body size source: https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator")
(tags "resistor handsolder")
(attr smd)
(fp_text reference R2 (at 0 1.65 270) (layer B.SilkS)
(effects (font (size 1 1) (thickness 0.15)) (justify mirror))
)
(fp_text value R_0805_2012Metric_Pad1.15x1.40mm_HandSolder (at 0 -1.65 270) (layer B.Fab)
(effects (font (size 1 1) (thickness 0.15)) (justify mirror))
)
(fp_text user 150 (at 0 0 270) (layer B.Fab)
(effects (font (size 0.5 0.5) (thickness 0.08)) (justify mirror))
)
(fp_line (start 1.85 -0.95) (end -1.85 -0.95) (layer B.CrtYd) (width 0.05))
(fp_line (start 1.85 0.95) (end 1.85 -0.95) (layer B.CrtYd) (width 0.05))
(fp_line (start -1.85 0.95) (end 1.85 0.95) (layer B.CrtYd) (width 0.05))
(fp_line (start -1.85 -0.95) (end -1.85 0.95) (layer B.CrtYd) (width 0.05))
(fp_line (start -0.261252 -0.71) (end 0.261252 -0.71) (layer B.SilkS) (width 0.12))
(fp_line (start -0.261252 0.71) (end 0.261252 0.71) (layer B.SilkS) (width 0.12))
(fp_line (start 1 -0.6) (end -1 -0.6) (layer B.Fab) (width 0.1))
(fp_line (start 1 0.6) (end 1 -0.6) (layer B.Fab) (width 0.1))
(fp_line (start -1 0.6) (end 1 0.6) (layer B.Fab) (width 0.1))
(fp_line (start -1 -0.6) (end -1 0.6) (layer B.Fab) (width 0.1))
(pad 2 smd roundrect (at 1.025 0 270) (size 1.15 1.4) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.217391))
(pad 1 smd roundrect (at -1.025 0 270) (size 1.15 1.4) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.217391))
(model ${KISYS3DMOD}/Resistor_SMD.3dshapes/R_0805_2012Metric.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)
(module Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder (layer F.Cu) (tedit 5B36C52B) (tstamp 5EA76D80)
(at 105 35 90)
(descr "Resistor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal with elongated pad for handsoldering. (Body size source: https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator")
(tags "resistor handsolder")
(attr smd)
(fp_text reference R1 (at 0 -1.65 90) (layer F.SilkS)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text value R_0805_2012Metric_Pad1.15x1.40mm_HandSolder (at 0 1.65 90) (layer F.Fab)
(effects (font (size 1 1) (thickness 0.15)))
)
(fp_text user 100 (at 0 0 90) (layer F.Fab)
(effects (font (size 0.5 0.5) (thickness 0.08)))
)
(fp_line (start 1.85 0.95) (end -1.85 0.95) (layer F.CrtYd) (width 0.05))
(fp_line (start 1.85 -0.95) (end 1.85 0.95) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.85 -0.95) (end 1.85 -0.95) (layer F.CrtYd) (width 0.05))
(fp_line (start -1.85 0.95) (end -1.85 -0.95) (layer F.CrtYd) (width 0.05))
(fp_line (start -0.261252 0.71) (end 0.261252 0.71) (layer F.SilkS) (width 0.12))
(fp_line (start -0.261252 -0.71) (end 0.261252 -0.71) (layer F.SilkS) (width 0.12))
(fp_line (start 1 0.6) (end -1 0.6) (layer F.Fab) (width 0.1))
(fp_line (start 1 -0.6) (end 1 0.6) (layer F.Fab) (width 0.1))
(fp_line (start -1 -0.6) (end 1 -0.6) (layer F.Fab) (width 0.1))
(fp_line (start -1 0.6) (end -1 -0.6) (layer F.Fab) (width 0.1))
(pad 2 smd roundrect (at 1.025 0 90) (size 1.15 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.217391))
(pad 1 smd roundrect (at -1.025 0 90) (size 1.15 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.217391))
(model ${KISYS3DMOD}/Resistor_SMD.3dshapes/R_0805_2012Metric.wrl
(at (xyz 0 0 0))
(scale (xyz 1 1 1))
(rotate (xyz 0 0 0))
)
)
(gr_line (start 100 25) (end 100 50) (layer Edge.Cuts) (width 0.05) (tstamp 5EA7192F))
(gr_line (start 100 50) (end 125 50) (layer Edge.Cuts) (width 0.05))
(gr_line (start 125 25) (end 125 50) (layer Edge.Cuts) (width 0.05) (tstamp 5EA76EFC))
(gr_line (start 100 25) (end 125 25) (layer Edge.Cuts) (width 0.05) (tstamp 5EA76F1D))
)

View File

@ -0,0 +1,178 @@
"""
Tests of position file
The 3Rs.kicad_pcb has R1 on top, R2 on bottom and a thru-hole component R3 on top.
We test:
- Separated files, mm, only SMD
- Unified file, mm, only SMD
- Unified file, mm, not only SMD
- Separated files, inches, only SMD
For debug information use:
pytest-3 --log-cli-level debug
"""
from . import plotting_test_utils
import os
import mmap
import re
import logging
def expect_file_at(filename):
assert(os.path.isfile(filename))
def get_pos_top_filename(board_name):
return board_name + '-top.pos'
def get_pos_bot_filename(board_name):
return board_name + '-bottom.pos'
def get_pos_both_filename(board_name):
return board_name + '-both.pos'
def expect_position(pos_data, side, ref, x, y, expected, inches=False):
"""
Check if a component is or isn't in the file
"""
#expr = rb'^'+ref.encode()+rb'\s+\S+\s+\S+\s+([\d\.]+)\s+([\d\.]+)\s+([\d\.]+)\s+(\S+)$'
expr = rb'^'+ref.encode()+rb'\s+\S+\s+\S+\s+([-\d\.]+)\s+([-\d\.]+)\s+([-\d\.]+)\s+(\S+)\s*$'
m = re.search(expr, pos_data, re.MULTILINE)
if m:
logging.debug("Position found for " + ref)
else:
logging.debug("Position not found for " + ref)
if expected:
assert(m)
if inches:
x = x/25.4
y = y/25.4
assert(abs(float(x) - float(m.group(1))) < 0.001)
assert(abs(float(y) + float(m.group(2))) < 0.001)
assert(side == m.group(4).decode())
#logging.debug(ref+' '+str(x)+' '+str(y)+' -> '+m.group(1).decode()+' '+m.group(2).decode()+' '+m.group(3).decode()+' '+m.group(4).decode())
else:
assert(m is None)
def get_mmapped_data(filename):
with open(filename) as fo:
return mmap.mmap(fo.fileno(), 0, access=mmap.ACCESS_READ)
def test_3Rs_position():
ctx = plotting_test_utils.KiPlotTestContext('3Rs_position')
ctx.board_name = '3Rs'
ctx.load_yaml_config_file('simple_position.yaml')
ctx.do_plot()
pos_dir = ctx.cfg.resolve_output_dir_for_name('position')
pos_top = os.path.join(pos_dir, get_pos_top_filename(ctx.board_name))
pos_bot = os.path.join(pos_dir, get_pos_bot_filename(ctx.board_name))
expect_file_at(pos_top)
expect_file_at(pos_bot)
top = get_mmapped_data(pos_top)
bot = get_mmapped_data(pos_bot)
expect_position(top, 'top', 'R1', 105, 35, True)
expect_position(bot, 'bottom', 'R1', 105, 35, False)
expect_position(top, 'top', 'R2', 110, 35, False)
expect_position(bot, 'bottom', 'R2', 110, 35, True)
expect_position(top, 'top', 'R3', 110, 45, False)
expect_position(bot, 'bottom', 'R3', 110, 45, False)
ctx.clean_up()
def test_3Rs_position_unified():
ctx = plotting_test_utils.KiPlotTestContext('3Rs_position_unified')
ctx.board_name = '3Rs'
ctx.load_yaml_config_file('simple_position_unified.yaml')
ctx.do_plot()
pos_dir = ctx.cfg.resolve_output_dir_for_name('position')
pos_both = os.path.join(pos_dir, get_pos_both_filename(ctx.board_name))
expect_file_at(pos_both)
both = get_mmapped_data(pos_both)
expect_position(both, 'top', 'R1', 105, 35, True)
expect_position(both, 'bottom', 'R2', 110, 35, True)
expect_position(both, '', 'R3', 110, 45, False)
ctx.clean_up()
def test_3Rs_position_unified_th():
ctx = plotting_test_utils.KiPlotTestContext('3Rs_position_unified_th')
ctx.board_name = '3Rs'
ctx.load_yaml_config_file('simple_position_unified_th.yaml')
ctx.do_plot()
pos_dir = ctx.cfg.resolve_output_dir_for_name('position')
pos_both = os.path.join(pos_dir, get_pos_both_filename(ctx.board_name))
expect_file_at(pos_both)
both = get_mmapped_data(pos_both)
expect_position(both, 'top', 'R1', 105, 35, True)
expect_position(both, 'bottom', 'R2', 110, 35, True)
expect_position(both, 'top', 'R3', 110, 45, True)
ctx.clean_up()
def test_3Rs_position_inches():
ctx = plotting_test_utils.KiPlotTestContext('3Rs_position_inches')
ctx.board_name = '3Rs'
ctx.load_yaml_config_file('simple_position_inches.yaml')
ctx.do_plot()
pos_dir = ctx.cfg.resolve_output_dir_for_name('position')
pos_top = os.path.join(pos_dir, get_pos_top_filename(ctx.board_name))
pos_bot = os.path.join(pos_dir, get_pos_bot_filename(ctx.board_name))
expect_file_at(pos_top)
expect_file_at(pos_bot)
top = get_mmapped_data(pos_top)
bot = get_mmapped_data(pos_bot)
expect_position(top, 'top', 'R1', 105, 35, True, True)
expect_position(bot, 'bottom', 'R1', 105, 35, False, True)
expect_position(top, 'top', 'R2', 110, 35, False, True)
expect_position(bot, 'bottom', 'R2', 110, 35, True, True)
expect_position(top, 'top', 'R3', 110, 45, False, True)
expect_position(bot, 'bottom', 'R3', 110, 45, False, True)
ctx.clean_up()

View File

@ -0,0 +1,15 @@
# Example KiPlot config file for a basic 2-layer board
kiplot:
version: 1
outputs:
- name: 'position'
comment: "Pick and place file"
type: position
dir: positiondir
options:
format: ASCII # CSV or ASCII format
units: millimeters # millimeters or inches
separate_files_for_front_and_back: true
only_smd: true

View File

@ -0,0 +1,15 @@
# Example KiPlot config file for a basic 2-layer board
kiplot:
version: 1
outputs:
- name: 'position'
comment: "Pick and place file"
type: position
dir: positiondir
options:
format: ASCII # CSV or ASCII format
units: inches # millimeters or inches
separate_files_for_front_and_back: true
only_smd: true

View File

@ -0,0 +1,15 @@
# Example KiPlot config file for a basic 2-layer board
kiplot:
version: 1
outputs:
- name: 'position'
comment: "Pick and place file"
type: position
dir: positiondir
options:
format: ASCII # CSV or ASCII format
units: millimeters # millimeters or inches
separate_files_for_front_and_back: false
only_smd: true

View File

@ -0,0 +1,15 @@
# Example KiPlot config file for a basic 2-layer board
kiplot:
version: 1
outputs:
- name: 'position'
comment: "Pick and place file"
type: position
dir: positiondir
options:
format: ASCII # CSV or ASCII format
units: millimeters # millimeters or inches
separate_files_for_front_and_back: false
only_smd: false