Internal BoM: XYRS support

- Now the `bom` output can generate files like `position`
This commit is contained in:
Salvador E. Tropea 2022-02-11 11:45:43 -03:00
parent ed4ff70033
commit edbe29740b
11 changed files with 180 additions and 5 deletions

View File

@ -62,6 +62,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
`solder_mask_color`, `silk_screen_color` and `pcb_finish`)
- Report generation (for design house) (#93)
- Internal BoM: two other options for the sorting criteria.
- Internal BoM: XYRS support (you can generate position files using it)
### Changed
- Internal BoM: now components with different Tolerance, Voltage, Current

View File

@ -48,6 +48,7 @@
* [Github Actions](#usage-of-github-actions)
* [Notes about Gerber format](#notes-about-gerber-format)
* [Notes about the position file](#notes-about-the-position-file)
* [XYRS files](#xyrs-files)
* [Credits](#credits)
## Introduction
@ -771,6 +772,7 @@ Next time you need this list just use an alias, like this:
* BoM (Bill of Materials)
* Type: `bom`
* Description: Used to generate the BoM in CSV, HTML, TSV, TXT, XML or XLSX format using the internal BoM.
This output can generate XYRS files (pick and place files).
Is compatible with KiBoM, but doesn't need to update the XML netlist because the components
are loaded from the schematic.
Important differences with KiBoM output:
@ -793,6 +795,7 @@ Next time you need this list just use an alias, like this:
- `name`: [string=''] Name to identify this source. If empty we use the name of the schematic.
- `number`: [number=1] Number of boards to build (components multiplier). Use negative to substract.
- `ref_id`: [string=''] A prefix to add to all the references from this project.
- `bottom_negative_x`: [boolean=false] Use negative X coordinates for footprints on bottom layer (for XYRS).
- `columns`: [list(dict)|list(string)] List of columns to display.
Can be just the name of the field.
* Valid keys:
@ -894,9 +897,11 @@ Next time you need this list just use an alias, like this:
- `output`: [string='%f-%i%I%v.%x'] filename for the output (%i=bom). Affected by global options.
- `ref_id`: [string=''] A prefix to add to all the references from this project. Used for multiple projects.
- `ref_separator`: [string=' '] Separator used for the list of references.
- `sort_style`: [string='type_value'] [type_value,type_value_ref,ref] Sorting criteria.
- `source_by_id`: [boolean=false] Generate the `Source BoM` column using the reference ID instead of the project name.
- `units`: [string='millimeters'] [millimeters,inches] Units used for the positions ('Footprint X' and 'Footprint Y' columns).
- `use_alt`: [boolean=false] Print grouped references in the alternate compressed style eg: R1-R7,R18.
- `use_aux_axis_as_origin`: [boolean=true] Use the auxiliary axis as origin for coordinates (KiCad default) (for XYRS).
- `variant`: [string=''] Board variant, used to determine which components
are output to the BoM..
- `xlsx`: [dict] Options for the XLSX format.
@ -2770,6 +2775,16 @@ The internal list of rotations is:
|`^PowerPAK_SO-8_Single` | 270.0 |
|`^HTSSOP-28-1EP_4.4x9.7mm*` | 270.0 |
### XYRS files
XYRS files are just BoM files in CSV format that includes pick and place data (**X** position, **Y** position, **R**otation and **S**ide).
You can generate them using the internal BoM generator (`bom` output).
The following fields contains the needed information:
- `Footprint X`
- `Footprint Y`
- `Footprint Rot`
- `Footprint Side`
## Credits

View File

@ -48,6 +48,7 @@
* [Github Actions](#usage-of-github-actions)
* [Notes about Gerber format](#notes-about-gerber-format)
* [Notes about the position file](#notes-about-the-position-file)
* [XYRS files](#xyrs-files)
* [Credits](#credits)
## Introduction
@ -1379,6 +1380,16 @@ The internal list of rotations is:
|`^PowerPAK_SO-8_Single` | 270.0 |
|`^HTSSOP-28-1EP_4.4x9.7mm*` | 270.0 |
### XYRS files
XYRS files are just BoM files in CSV format that includes pick and place data (**X** position, **Y** position, **R**otation and **S**ide).
You can generate them using the internal BoM generator (`bom` output).
The following fields contains the needed information:
- `Footprint X`
- `Footprint Y`
- `Footprint Rot`
- `Footprint Side`
## Credits

View File

@ -65,6 +65,7 @@ outputs:
output: '%f-%i%I%v.%x'
# BoM (Bill of Materials):
# This output can generate XYRS files (pick and place files).
# Is compatible with KiBoM, but doesn't need to update the XML netlist because the components
# are loaded from the schematic.
# Important differences with KiBoM output:
@ -86,6 +87,8 @@ outputs:
number: 1
# [string=''] A prefix to add to all the references from this project
ref_id: ''
# [boolean=false] Use negative X coordinates for footprints on bottom layer (for XYRS)
bottom_negative_x: false
# [list(dict)|list(string)] List of columns to display.
# Can be just the name of the field
columns:
@ -240,12 +243,16 @@ outputs:
ref_id: ''
# [string=' '] Separator used for the list of references
ref_separator: ' '
# [string='type_value'] [type_value,type_value_ref,ref] Sorting criteria
sort_style: 'type_value'
# [boolean=false] Generate the `Source BoM` column using the reference ID instead of the project name
source_by_id: false
# [string='millimeters'] [millimeters,inches] Units used for the positions ('Footprint X' and 'Footprint Y' columns)
units: 'millimeters'
# [boolean=false] Print grouped references in the alternate compressed style eg: R1-R7,R18
use_alt: false
# [boolean=true] Use the auxiliary axis as origin for coordinates (KiCad default) (for XYRS)
use_aux_axis_as_origin: true
# [string=''] Board variant, used to determine which components
# are output to the BoM.
variant: ''

View File

@ -16,6 +16,7 @@ from .units import compare_values, comp_match, get_last_warning
from .bom_writer import write_bom
from .columnlist import ColumnList
from ..misc import DNF, W_FIELDCONF
from ..gs import GS
from .. import log
logger = log.get_logger()
@ -302,7 +303,7 @@ class ComponentGroup(object):
fld=value, ref=ref))
self.fields[field] += " " + value
def update_fields(self, conv, usealt=False):
def update_fields(self, conv, bottom_negative_x, x_origin, y_origin, usealt=False):
for c in self.components:
for f, v in c.get_user_fields():
self.update_field(f, v, c.ref)
@ -330,9 +331,12 @@ class ComponentGroup(object):
self.fields[ColumnList.COL_PART_LIB_L] = comp.lib
self.fields[ColumnList.COL_DATASHEET_L] = comp.datasheet
self.fields[ColumnList.COL_FP_L] = comp.footprint
self.fields[ColumnList.COL_FP_X_L] = "{:.4f}".format(comp.footprint_x * conv)
self.fields[ColumnList.COL_FP_Y_L] = "{:.4f}".format(comp.footprint_y * conv)
self.fields[ColumnList.COL_FP_ROT_L] = comp.footprint_rot
pos_x = (comp.footprint_x - x_origin) * conv
if bottom_negative_x and comp.bottom:
pos_x = -pos_x
self.fields[ColumnList.COL_FP_X_L] = "{:.4f}".format(pos_x)
self.fields[ColumnList.COL_FP_Y_L] = "{:.4f}".format(-(comp.footprint_y - y_origin) * conv)
self.fields[ColumnList.COL_FP_ROT_L] = "{:.4f}".format(comp.footprint_rot)
self.fields[ColumnList.COL_FP_SIDE_L] = "bottom" if comp.bottom else "top"
self.fields[ColumnList.COL_FP_LIB_L] = comp.footprint_lib
self.fields[ColumnList.COL_SHEETPATH_L] = comp.sheet_path_h
@ -451,11 +455,18 @@ def group_components(cfg, components):
decimal_point = locale.localeconv()['decimal_point']
if decimal_point == '.':
decimal_point = None
# Coordinates origin for XYRS
x_origin = 0.0
y_origin = 0.0
if cfg.use_aux_axis_as_origin:
(x_origin, y_origin) = GS.get_aux_origin()
logger.debug('Using auxiliar origin: x={} y={}'.format(x_origin, y_origin))
# Process the groups
for g in groups:
# Sort the references within each group
g.sort_components()
# Fill the columns
g.update_fields(cfg.conv_units, cfg.use_alt)
g.update_fields(cfg.conv_units, cfg.bottom_negative_x, x_origin, y_origin, cfg.use_alt )
if cfg.normalize_values:
g.fields[ColumnList.COL_VALUE_L] = normalize_value(g.components[0], decimal_point)
# Sort the groups

View File

@ -386,6 +386,10 @@ class BoMOptions(BaseOptions):
""" Show the stats about how many of the components are SMD/THT. You must provide the PCB """
self.units = 'millimeters'
""" [millimeters,inches] Units used for the positions ('Footprint X' and 'Footprint Y' columns) """
self.bottom_negative_x = False
""" Use negative X coordinates for footprints on bottom layer (for XYRS) """
self.use_aux_axis_as_origin = True
""" Use the auxiliary axis as origin for coordinates (KiCad default) (for XYRS) """
self.sort_style = 'type_value'
""" [type_value,type_value_ref,ref] Sorting criteria """
self._format_example = 'CSV'
@ -634,6 +638,7 @@ class BoMOptions(BaseOptions):
class BoM(BaseOutput): # noqa: F821
""" BoM (Bill of Materials)
Used to generate the BoM in CSV, HTML, TSV, TXT, XML or XLSX format using the internal BoM.
This output can generate XYRS files (pick and place files).
Is compatible with KiBoM, but doesn't need to update the XML netlist because the components
are loaded from the schematic.
Important differences with KiBoM output:

View File

@ -0,0 +1,62 @@
Designator,Val,Package,Mid X,Mid Y,Rotation,Layer
C1,1uF,R_0402_1005Metric,111.2000,-69.8500,270.0000,top
C2,0.1uF,R_0402_1005Metric,112.2000,-69.8500,270.0000,top
C3,4.7uF,R_0603_1608Metric,117.6020,-66.2685,270.0000,top
C4,1uF,R_0603_1608Metric,118.6000,-81.3000,270.0000,top
C5,22uF,R_0603_1608Metric,117.6000,-71.3000,180.0000,top
C6,4.7uF,R_0402_1005Metric,111.5060,-61.9760,270.0000,top
C7,10uF,R_0402_1005Metric,121.6660,-62.7380,90.0000,top
C8,0.1uF,R_0402_1005Metric,122.9360,-62.7380,90.0000,top
D1,D_Schottky,D_SOD-123,115.3000,-81.0000,180.0000,top
D2,D_Schottky,D_SOD-123,109.4000,-68.8000,90.0000,top
D3,D_Schottky,D_SOD-123,118.8000,-88.8840,270.0000,top
D4,D_Schottky,D_SOD-123,131.5000,-89.9000,270.0000,top
D5,D_Schottky,D_SOD-123,145.2880,-87.8840,270.0000,top
D6,D_Schottky,D_SOD-123,149.3000,-79.4000,0.0000,top
D7,D_Schottky,D_SOD-123,125.2000,-88.8840,270.0000,top
D8,D_Schottky,D_SOD-123,138.9000,-90.0000,270.0000,top
D9,D_Schottky,D_SOD-123,149.2000,-85.5000,0.0000,top
D10,D_Schottky,D_SOD-123,149.2000,-73.3000,0.0000,top
D11,Green,LED_0603_1608Metric,149.9000,-63.8000,0.0000,top
D12,Green,LED_0603_1608Metric,153.2000,-63.8000,0.0000,top
D13,Red,LED_0603_1608Metric,156.5000,-63.8000,0.0000,top
D14,Red,LED_0603_1608Metric,159.7000,-63.8000,0.0000,top
J2,USB_B_Micro,USB_Micro-B_Molex-105017-0001,105.4100,-66.0400,270.0000,top
Q1,Q_NPN_BEC,SOT-23,121.1580,-66.0400,180.0000,top
Q2,Q_NPN_BEC,SOT-23,121.1580,-69.8500,180.0000,top
Q3,Q_NMOS_GSD,SOT-23,121.8000,-89.4080,90.0000,top
Q4,Q_NMOS_GDS,SOT-23,134.6000,-90.5000,90.0000,top
Q5,Q_NMOS_GDS,SOT-23,148.5900,-89.9160,90.0000,top
Q6,Q_NMOS_GDS,SOT-23,149.8000,-76.4000,180.0000,top
Q7,Q_NMOS_GDS,SOT-23,128.2000,-90.6780,90.0000,top
Q8,Q_NMOS_GDS,SOT-23,141.9000,-89.6620,90.0000,top
Q9,Q_NMOS_GDS,SOT-23,149.8000,-82.5000,180.0000,top
Q10,Q_NMOS_GDS,SOT-23,149.8000,-70.3000,180.0000,top
R1,10kR,R_0402_1005Metric,117.6020,-62.2300,180.0000,top
R2,10kR,R_0402_1005Metric,117.6020,-63.5000,180.0000,top
R3,10kR,R_0402_1005Metric,110.2360,-61.9760,270.0000,top
R4,100R,R_0402_1005Metric,122.6820,-86.6140,90.0000,top
R5,100R,R_0402_1005Metric,134.2000,-88.2000,0.0000,top
R6,100R,R_0402_1005Metric,145.3000,-84.9000,180.0000,top
R7,100R,R_0402_1005Metric,147.4000,-77.1150,90.0000,top
R8,100R,R_0402_1005Metric,129.2860,-88.2650,180.0000,top
R9,100R,R_0402_1005Metric,141.1380,-86.8520,0.0000,top
R10,100R,R_0402_1005Metric,147.4470,-82.5500,270.0000,top
R11,100R,R_0402_1005Metric,147.3200,-70.9000,270.0000,top
R12,47R,R_0402_1005Metric,150.2000,-65.3000,0.0000,top
R13,47R,R_0402_1005Metric,153.0000,-65.3000,0.0000,top
R14,150R,R_0402_1005Metric,155.9000,-65.3000,0.0000,top
R15,150R,R_0402_1005Metric,159.0000,-65.3000,0.0000,top
R16,10kR,R_0402_1005Metric,126.2000,-83.6000,180.0000,top
R17,10kR,R_0402_1005Metric,121.1580,-86.3600,0.0000,top
R18,10kR,R_0402_1005Metric,136.2710,-88.1380,180.0000,top
R19,10kR,R_0402_1005Metric,144.3990,-83.4390,0.0000,top
R20,10kR,R_0402_1005Metric,145.9230,-77.4700,90.0000,top
R21,10kR,R_0402_1005Metric,127.3810,-88.2650,0.0000,top
R22,10kR,R_0402_1005Metric,142.7480,-86.8680,270.0000,top
R23,10kR,R_0402_1005Metric,144.3990,-82.0420,0.0000,top
R24,10kR,R_0402_1005Metric,147.3200,-68.8570,270.0000,top
SW1,SW_Push,TS-1187A,114.0000,-58.1660,0.0000,top
U1,AZ1117-3.3,SOT-223-3_TabPin2,117.3000,-75.8000,180.0000,top
U2,CP2104,QFN-24-1EP_4x4mm_P0.5mm_EP2.6x2.6mm,113.9040,-66.0400,270.0000,top
U3,ESP32-WROOM-32,ESP32-WROOM-32,134.3660,-70.3580,0.0000,top
1 Designator Val Package Mid X Mid Y Rotation Layer
2 C1 1uF R_0402_1005Metric 111.2000 -69.8500 270.0000 top
3 C2 0.1uF R_0402_1005Metric 112.2000 -69.8500 270.0000 top
4 C3 4.7uF R_0603_1608Metric 117.6020 -66.2685 270.0000 top
5 C4 1uF R_0603_1608Metric 118.6000 -81.3000 270.0000 top
6 C5 22uF R_0603_1608Metric 117.6000 -71.3000 180.0000 top
7 C6 4.7uF R_0402_1005Metric 111.5060 -61.9760 270.0000 top
8 C7 10uF R_0402_1005Metric 121.6660 -62.7380 90.0000 top
9 C8 0.1uF R_0402_1005Metric 122.9360 -62.7380 90.0000 top
10 D1 D_Schottky D_SOD-123 115.3000 -81.0000 180.0000 top
11 D2 D_Schottky D_SOD-123 109.4000 -68.8000 90.0000 top
12 D3 D_Schottky D_SOD-123 118.8000 -88.8840 270.0000 top
13 D4 D_Schottky D_SOD-123 131.5000 -89.9000 270.0000 top
14 D5 D_Schottky D_SOD-123 145.2880 -87.8840 270.0000 top
15 D6 D_Schottky D_SOD-123 149.3000 -79.4000 0.0000 top
16 D7 D_Schottky D_SOD-123 125.2000 -88.8840 270.0000 top
17 D8 D_Schottky D_SOD-123 138.9000 -90.0000 270.0000 top
18 D9 D_Schottky D_SOD-123 149.2000 -85.5000 0.0000 top
19 D10 D_Schottky D_SOD-123 149.2000 -73.3000 0.0000 top
20 D11 Green LED_0603_1608Metric 149.9000 -63.8000 0.0000 top
21 D12 Green LED_0603_1608Metric 153.2000 -63.8000 0.0000 top
22 D13 Red LED_0603_1608Metric 156.5000 -63.8000 0.0000 top
23 D14 Red LED_0603_1608Metric 159.7000 -63.8000 0.0000 top
24 J2 USB_B_Micro USB_Micro-B_Molex-105017-0001 105.4100 -66.0400 270.0000 top
25 Q1 Q_NPN_BEC SOT-23 121.1580 -66.0400 180.0000 top
26 Q2 Q_NPN_BEC SOT-23 121.1580 -69.8500 180.0000 top
27 Q3 Q_NMOS_GSD SOT-23 121.8000 -89.4080 90.0000 top
28 Q4 Q_NMOS_GDS SOT-23 134.6000 -90.5000 90.0000 top
29 Q5 Q_NMOS_GDS SOT-23 148.5900 -89.9160 90.0000 top
30 Q6 Q_NMOS_GDS SOT-23 149.8000 -76.4000 180.0000 top
31 Q7 Q_NMOS_GDS SOT-23 128.2000 -90.6780 90.0000 top
32 Q8 Q_NMOS_GDS SOT-23 141.9000 -89.6620 90.0000 top
33 Q9 Q_NMOS_GDS SOT-23 149.8000 -82.5000 180.0000 top
34 Q10 Q_NMOS_GDS SOT-23 149.8000 -70.3000 180.0000 top
35 R1 10kR R_0402_1005Metric 117.6020 -62.2300 180.0000 top
36 R2 10kR R_0402_1005Metric 117.6020 -63.5000 180.0000 top
37 R3 10kR R_0402_1005Metric 110.2360 -61.9760 270.0000 top
38 R4 100R R_0402_1005Metric 122.6820 -86.6140 90.0000 top
39 R5 100R R_0402_1005Metric 134.2000 -88.2000 0.0000 top
40 R6 100R R_0402_1005Metric 145.3000 -84.9000 180.0000 top
41 R7 100R R_0402_1005Metric 147.4000 -77.1150 90.0000 top
42 R8 100R R_0402_1005Metric 129.2860 -88.2650 180.0000 top
43 R9 100R R_0402_1005Metric 141.1380 -86.8520 0.0000 top
44 R10 100R R_0402_1005Metric 147.4470 -82.5500 270.0000 top
45 R11 100R R_0402_1005Metric 147.3200 -70.9000 270.0000 top
46 R12 47R R_0402_1005Metric 150.2000 -65.3000 0.0000 top
47 R13 47R R_0402_1005Metric 153.0000 -65.3000 0.0000 top
48 R14 150R R_0402_1005Metric 155.9000 -65.3000 0.0000 top
49 R15 150R R_0402_1005Metric 159.0000 -65.3000 0.0000 top
50 R16 10kR R_0402_1005Metric 126.2000 -83.6000 180.0000 top
51 R17 10kR R_0402_1005Metric 121.1580 -86.3600 0.0000 top
52 R18 10kR R_0402_1005Metric 136.2710 -88.1380 180.0000 top
53 R19 10kR R_0402_1005Metric 144.3990 -83.4390 0.0000 top
54 R20 10kR R_0402_1005Metric 145.9230 -77.4700 90.0000 top
55 R21 10kR R_0402_1005Metric 127.3810 -88.2650 0.0000 top
56 R22 10kR R_0402_1005Metric 142.7480 -86.8680 270.0000 top
57 R23 10kR R_0402_1005Metric 144.3990 -82.0420 0.0000 top
58 R24 10kR R_0402_1005Metric 147.3200 -68.8570 270.0000 top
59 SW1 SW_Push TS-1187A 114.0000 -58.1660 0.0000 top
60 U1 AZ1117-3.3 SOT-223-3_TabPin2 117.3000 -75.8000 180.0000 top
61 U2 CP2104 QFN-24-1EP_4x4mm_P0.5mm_EP2.6x2.6mm 113.9040 -66.0400 270.0000 top
62 U3 ESP32-WROOM-32 ESP32-WROOM-32 134.3660 -70.3580 0.0000 top

View File

@ -0,0 +1 @@
../5_1_6/light_control_cpl_jlc_nc.csv
1 ../5_1_6/light_control_cpl_jlc_nc.csv

View File

@ -0,0 +1 @@
../5_1_6/light_control_cpl_jlc_nc.csv
1 ../5_1_6/light_control_cpl_jlc_nc.csv

View File

@ -249,6 +249,16 @@ def test_position_rot_4(test_dir):
ctx.clean_up(keep_project=True)
def test_position_rot_5(test_dir):
prj = 'light_control'
ctx = context.TestContext(test_dir, 'test_position_rot_5', prj, 'simple_position_rot_5', POS_DIR)
ctx.run()
output = prj+'_cpl_jlc.csv'
ctx.expect_out_file(output)
ctx.compare_txt(output, prj+'_cpl_jlc_nc.csv')
ctx.clean_up(keep_project=True)
def test_rot_bottom(test_dir):
ctx = context.TestContext(test_dir, 'test_rot_bottom', 'comp_bottom', 'simple_position_rot_bottom', POS_DIR)
ctx.run()

View File

@ -0,0 +1,51 @@
kibot:
version: 1
filters:
- name: fix_rotation
comment: 'Adjust rotation for JLC'
type: rot_footprint
- name: only_smd
comment: 'Only SMD parts'
type: generic
exclude_virtual: true
exclude_tht: true
variants:
- name: rotated
comment: 'Just a place holder for the rotation filter'
type: kibom
variant: rotated
pre_transform: fix_rotation
dnf_filter: only_smd
outputs:
- name: 'position'
comment: "Pick and place file, JLC style"
type: bom
options:
variant: rotated
output: '%f_cpl_jlc.%x'
units: millimeters
group_fields: []
sort_style: ref
use_aux_axis_as_origin: false
csv:
hide_pcb_info: true
hide_stats_info: true
columns:
- field: References
name: Designator
- field: Value
name: Val
- field: Footprint
name: Package
- field: Footprint X
name: Mid X
- field: Footprint Y
name: Mid Y
- field: Footprint Rot
name: Rotation
- field: Footprint Side
name: Layer