diff --git a/tests/board_samples/kicad_5/comp_bottom.kicad_pcb b/tests/board_samples/kicad_5/comp_bottom.kicad_pcb new file mode 100644 index 00000000..f70483c1 --- /dev/null +++ b/tests/board_samples/kicad_5/comp_bottom.kicad_pcb @@ -0,0 +1,157 @@ +(kicad_pcb (version 20171130) (host pcbnew 5.1.9-73d0e3b20d~88~ubuntu21.04.1) + + (general + (thickness 1.6) + (drawings 0) + (tracks 0) + (zones 0) + (modules 1) + (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.1) + (segment_width 0.2) + (pcb_text_width 0.3) + (pcb_text_size 1.5 1.5) + (mod_edge_width 0.15) + (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) + (aux_axis_origin 97.0026 97.0026) + (visible_elements FFFFFF7F) + (pcbplotparams + (layerselection 0x010fc_ffffffff) + (usegerberextensions false) + (usegerberattributes true) + (usegerberadvancedattributes true) + (creategerberjobfile true) + (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 "This is the default net class." + (clearance 0.2) + (trace_width 0.25) + (via_dia 0.8) + (via_drill 0.4) + (uvia_dia 0.3) + (uvia_drill 0.1) + ) + + (module Package_DFN_QFN:QFN-12-1EP_3x3mm_P0.5mm_EP1.65x1.65mm (layer B.Cu) (tedit 5DC5F6A3) (tstamp 601B53A7) + (at 100 100) + (descr "QFN, 12 Pin (http://www.analog.com/media/en/package-pcb-resources/package/pkg_pdf/ltc-legacy-qfn/QFN_12_%2005-08-1855.pdf), generated with kicad-footprint-generator ipc_noLead_generator.py") + (tags "QFN NoLead") + (attr smd) + (fp_text reference U1 (at 0 2.82) (layer B.SilkS) + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + ) + (fp_text value QFN-12-1EP_3x3mm_P0.5mm_EP1.65x1.65mm (at 0 -2.82) (layer B.Fab) + (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) + ) + (fp_line (start 0.885 1.61) (end 1.61 1.61) (layer B.SilkS) (width 0.12)) + (fp_line (start 1.61 1.61) (end 1.61 0.885) (layer B.SilkS) (width 0.12)) + (fp_line (start -0.885 -1.61) (end -1.61 -1.61) (layer B.SilkS) (width 0.12)) + (fp_line (start -1.61 -1.61) (end -1.61 -0.885) (layer B.SilkS) (width 0.12)) + (fp_line (start 0.885 -1.61) (end 1.61 -1.61) (layer B.SilkS) (width 0.12)) + (fp_line (start 1.61 -1.61) (end 1.61 -0.885) (layer B.SilkS) (width 0.12)) + (fp_line (start -0.885 1.61) (end -1.61 1.61) (layer B.SilkS) (width 0.12)) + (fp_line (start -0.75 1.5) (end 1.5 1.5) (layer B.Fab) (width 0.1)) + (fp_line (start 1.5 1.5) (end 1.5 -1.5) (layer B.Fab) (width 0.1)) + (fp_line (start 1.5 -1.5) (end -1.5 -1.5) (layer B.Fab) (width 0.1)) + (fp_line (start -1.5 -1.5) (end -1.5 0.75) (layer B.Fab) (width 0.1)) + (fp_line (start -1.5 0.75) (end -0.75 1.5) (layer B.Fab) (width 0.1)) + (fp_line (start -2.12 2.12) (end -2.12 -2.12) (layer B.CrtYd) (width 0.05)) + (fp_line (start -2.12 -2.12) (end 2.12 -2.12) (layer B.CrtYd) (width 0.05)) + (fp_line (start 2.12 -2.12) (end 2.12 2.12) (layer B.CrtYd) (width 0.05)) + (fp_line (start 2.12 2.12) (end -2.12 2.12) (layer B.CrtYd) (width 0.05)) + (fp_text user %R (at 0 0) (layer B.Fab) + (effects (font (size 0.75 0.75) (thickness 0.11)) (justify mirror)) + ) + (pad "" smd roundrect (at 0.41 -0.41) (size 0.67 0.67) (layers B.Paste) (roundrect_rratio 0.25)) + (pad "" smd roundrect (at 0.41 0.41) (size 0.67 0.67) (layers B.Paste) (roundrect_rratio 0.25)) + (pad "" smd roundrect (at -0.41 -0.41) (size 0.67 0.67) (layers B.Paste) (roundrect_rratio 0.25)) + (pad "" smd roundrect (at -0.41 0.41) (size 0.67 0.67) (layers B.Paste) (roundrect_rratio 0.25)) + (pad 13 smd rect (at 0 0) (size 1.65 1.65) (layers B.Cu B.Mask)) + (pad 12 smd roundrect (at -0.5 1.4625) (size 0.25 0.825) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (pad 11 smd roundrect (at 0 1.4625) (size 0.25 0.825) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (pad 10 smd roundrect (at 0.5 1.4625) (size 0.25 0.825) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (pad 9 smd roundrect (at 1.4625 0.5) (size 0.825 0.25) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (pad 8 smd roundrect (at 1.4625 0) (size 0.825 0.25) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (pad 7 smd roundrect (at 1.4625 -0.5) (size 0.825 0.25) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (pad 6 smd roundrect (at 0.5 -1.4625) (size 0.25 0.825) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (pad 5 smd roundrect (at 0 -1.4625) (size 0.25 0.825) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (pad 4 smd roundrect (at -0.5 -1.4625) (size 0.25 0.825) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (pad 3 smd roundrect (at -1.4625 -0.5) (size 0.825 0.25) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (pad 2 smd roundrect (at -1.4625 0) (size 0.825 0.25) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (pad 1 smd roundrect (at -1.4625 0.5) (size 0.825 0.25) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) + (model ${KISYS3DMOD}/Package_DFN_QFN.3dshapes/QFN-12-1EP_3x3mm_P0.5mm_EP1.65x1.65mm.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + +) diff --git a/tests/board_samples/kicad_5/comp_bottom.sch b/tests/board_samples/kicad_5/comp_bottom.sch new file mode 100644 index 00000000..a5781379 --- /dev/null +++ b/tests/board_samples/kicad_5/comp_bottom.sch @@ -0,0 +1,27 @@ +EESchema Schematic File Version 4 +EELAYER 30 0 +EELAYER END +$Descr A4 11693 8268 +encoding utf-8 +Sheet 1 1 +Title "" +Date "" +Rev "" +Comp "" +Comment1 "" +Comment2 "" +Comment3 "" +Comment4 "" +$EndDescr +$Comp +L Comparator:LTC6752xUD-3 U1 +U 1 1 601AFEFD +P 4125 3375 +F 0 "U1" H 4469 3421 50 0000 L CNN +F 1 "LTC6752xUD-3" H 4469 3330 50 0000 L CNN +F 2 "Package_DFN_QFN:QFN-12-1EP_3x3mm_P0.5mm_EP1.65x1.65mm" H 4125 2725 50 0001 C CNN +F 3 "https://www.analog.com/media/en/technical-documentation/data-sheets/6752fc.pdf" H 4025 3375 50 0001 C CNN + 1 4125 3375 + 1 0 0 -1 +$EndComp +$EndSCHEMATC diff --git a/tests/test_plot/test_position.py b/tests/test_plot/test_position.py index b9a15760..75e48155 100644 --- a/tests/test_plot/test_position.py +++ b/tests/test_plot/test_position.py @@ -29,7 +29,10 @@ if prev_dir not in sys.path: from utils import context POS_DIR = 'positiondir' -positions = {'R1': (105, 35, 'top'), 'R2': (110, 35, 'bottom'), 'R3': (110, 45, 'top')} +positions = {'R1': (105, 35, 'top', 90), + 'R2': (110, 35, 'bottom', 270), + 'R3': (110, 45, 'top', 0), + 'U1': (100, 100, 'bottom', 90)} CSV_EXPR = r'^"%s",[^,]+,[^,]+,([-\d\.]+),([-\d\.]+),([-\d\.]+),(\S+)$' ASCII_EXPR = r'^%s\s+\S+\s+\S+\s+([-\d\.]+)\s+([-\d\.]+)\s+([-\d\.]+)\s+(\S+)\s*$' @@ -47,7 +50,7 @@ def expect_position(ctx, file, comp, no_comp=[], inches=False, csv=False, neg_x= texts.append(ASCII_EXPR % k) res = ctx.search_in_file(file, texts) for k in comp: - x, y, side = positions[k] + x, y, side, angle = positions[k] if inches: x = x/25.4 y = y/25.4 @@ -56,6 +59,7 @@ def expect_position(ctx, file, comp, no_comp=[], inches=False, csv=False, neg_x= matches = res.pop(0) assert(abs(float(x) - float(matches[0])) < 0.001) assert(abs(float(y) + float(matches[1])) < 0.001) + assert(angle == float(matches[2])) assert(side == matches[3]) # Components that must not be found @@ -224,3 +228,12 @@ def test_position_rot_2(test_dir): ctx.compare_txt(output) ctx.compare_txt(prj+'_bom_jlc.csv') ctx.clean_up() + + +def test_rot_bottom(test_dir): + ctx = context.TestContext(test_dir, 'test_rot_bottom', 'comp_bottom', 'simple_position_rot_bottom', POS_DIR) + ctx.run() + pos_bot = ctx.get_pos_both_filename() + ctx.expect_out_file(pos_bot) + expect_position(ctx, pos_bot, ['U1'], neg_x=True) + ctx.clean_up() diff --git a/tests/yaml_samples/simple_position_rot_bottom.kibot.yaml b/tests/yaml_samples/simple_position_rot_bottom.kibot.yaml new file mode 100644 index 00000000..4fa53288 --- /dev/null +++ b/tests/yaml_samples/simple_position_rot_bottom.kibot.yaml @@ -0,0 +1,23 @@ +# Example KiBot config file for a basic 2-layer board +kibot: + version: 1 + +variants: + - name: default + comment: 'Just a place holder for the rotation filter' + type: kibom + variant: default + pre_transform: _rot_footprint + +outputs: + - name: 'position' + comment: "Pick and place file" + type: position + dir: positiondir + options: + variant: default + format: ASCII # CSV or ASCII format + units: millimeters # millimeters or inches + separate_files_for_front_and_back: false + only_smd: true + bottom_negative_x: true