KiCAD Coordinate System
Categories:
4 minute read
I’ve found the KiCAD coordinate system to be confusing. Here’s what I had to learn while building the JigsApp system generally and the kicad-testpoints plugin specifically.
The origin and axis settings are global preferences for the PCB editor (pcbnew) and can be accessed from all of the KiCAD programs (eeschema, project, pcbnew, Symbol Editor, Footprint Editor, Gerber Viewer, Image Convertor, Calculator Tools, Drawing Sheet Editor, and 3D Viewer).
The origin type and axes settings can only be changed for the PCB Editor.
These settings only change the mapping that shows up in the editor. The origin positions (grid and drill/file/aux) are stored in the PCB file but the mapping preferences are not. This can be confusing when using different instances of KiCAD that aren’t configured the same way.
Origins
There are three types of origins in KiCAD:
- Page Origin: Top left corner of the page. This is the default and is the internal coordinate system. This is the point vectors are relative to in the python API.
- Drill/File (AKA Aux) Origin: Sets the relative origin in the PCB editor. Has no effect on the absolute position of objects. The position of the object is read relative to this point when set but still will be relative to the page origin when scripting. The marker for this is a red cross in a circle.
- Grid Origin: Sets the starting point of the grid. This typically stays constant once the design has started. This is normally the same as the drill origin (if placed). The marker is a grey x in a circle.
Axes
Internally (and by default) the axes follow a pixel coordinate system where the origin is in the top left with x increasing to the right and y increasing downwards.
Gerbers use a Cartesian coordinate system which means that your centroid file, drill file, and gerber outputs say one thing and KiCAD says another. Not great and it’s something to keep in mind. The place I find this most infuriating is the centroid file (A.K.A. component placement or pick-n-place). If we export the centroid then use that to place the parts either manually or nievlly with a script then the placement will be mirrored!
The axes directions can be changed in the same preference window as the origin point but this won’t change the internal position. When writing a script then this needs to be kept in mind.
Preferences
The PCB Editor is the only program that you can set the origin or axes direction in and the preference cannot be accessed using the python API. If you change your axes and origin in the PCB Editor you’re still using the pixel coordinates in the footprint editor!
Scripting
I prefer to refer to the origin of a board as the reference point. This is usually the center of the boards bounding box but it may be the center of a sensor (ex. a photodiode) or an emitter (ex. a laser diode). In the design I place the drill origin where it needs to go (usually placing it at the center of the board which is a footprint so it has a snap-able center point). I then keep everything in Cartesian coordinates relative to the origin and multiply y by -1 which will put us back in pixel coordinates.
For my KiCAD plugins I’ll be adding the option to use the drill/file/aux origin or the page origin and limit the axes to Cartesian coordinates.
Transforming Coordinates
For an arbitrary origin point
$$ \text{origin} == (x_0, y_0) $$
and a pcbnew location
$$ \text{pt} == (x, y) $$
we want the mapped location to the new coordinates
$$ \text{pt’} == (x’, y’). $$
Since we want the opposite direction in y and the same in x:
$$ x’ = x - x_0 $$
$$ y’ = y_0 - y. $$
To transform back: $$ x = x’ + x_0 $$
$$ y = y_0 - y’. $$
If your origin position is set to the page origin then all the y’ values are going to be negative. Transform to native KiCAD coordinates when setting positions and back when reading them. The user setting of the axes will not effect the outcome.
Suggestions List
- Use Cartesian coordinates. Set the X to increase to the right and Y to increase upwards. Your EDA and manufacturing outputs will then agree.
- Use Cartesian coordinates until the last second when scripting. Hide the distinction as deep as possible.
- Choose an educated reference point on your board and set that as the drill/file origin