EEVblog Electronics Community Forum

Electronics => PCB/EDA/CAD => KiCad => Topic started by: Eka on May 29, 2019, 05:26:33 pm

Title: Placement by calculated X,Y,R values???
Post by: Eka on May 29, 2019, 05:26:33 pm
I know about array and polar placement methods. What I want to do is calculate the placement of components, then automatically place the components based on my calculations.

.csv List could be like:
Code: [Select]
U1,12.5,15.045,90,front
U2,16.5,14.355,120,front
U3,20.5,13.890,245,back

The components would already be loaded into KiCad via the normal schematic -> KiCad interface. I just want an easy way to set their position and orientation based on some complex math calculated in another program. When there are a few components, the absolute placement dialog works, but I want to place hundreds.

I find it no problem to auto generate simple lines, arcs, etc, then insert them into the KiCad file. Modules, which parts are stored as, are complex and a pain to create/edit simply with scripts. I could spend the effort to figure out how to edit them, but is there an easier way?
Title: Re: Placement by calculated X,Y,R values???
Post by: stryker on May 29, 2019, 09:45:20 pm
It looks like what you're wanting to do would be very possible with a python script that you'd run after importing the netlist.  Modules have the methods SetPosition(x,y), SetOrientation(degrees) which takes a parameter that's in 1/10th degrees, and potentially Flip() would help with placement on the top/bottom granted a fresh netlist import would put everything on the top.  To be certain you could use isFlipped() first to see where it is.
Title: Re: Placement by calculated X,Y,R values???
Post by: Eka on May 29, 2019, 10:37:56 pm
OK, that looks like it'll do what I want. Now to learn how to do it. I see the documentation is look at the source code. |O At least the ability to do it is there. OK, time to raid other's scripts to hopefully shortcut my learning curve.
Title: Re: Placement by calculated X,Y,R values???
Post by: Harjit on May 30, 2019, 05:10:36 am
Take a look at the tools here:
https://github.com/MitjaNemec/Kicad_action_plugins
Title: Re: Placement by calculated X,Y,R values???
Post by: thinkfat on May 30, 2019, 02:14:16 pm
If you solve that, would be interested in the solution. After manually placing 96 LEDs in a grid, don't want to do that again in the next project.

Gesendet von meinem Nokia 6.1 mit Tapatalk

Title: Re: Placement by calculated X,Y,R values???
Post by: stryker on May 30, 2019, 09:06:39 pm
After manually placing 96 LEDs in a grid, don't want to do that again in the next project.
One of the plugins from the github link @Harjit posted Place footprints (https://github.com/MitjaNemec/Kicad_action_plugins#place-footprints) might be able to help with that already
Title: Re: Placement by calculated X,Y,R values???
Post by: Rerouter on May 30, 2019, 09:21:29 pm
Thinkfat for a fixed grid of components. You can use custom grid to set the X and Y spacing and just drop them on the grid.
Title: Re: Placement by calculated X,Y,R values???
Post by: donotdespisethesnake on June 01, 2019, 08:27:28 am
I thought I would have a go since I might find it useful for a current project.

This handles a single footprint, and you probably have a more efficient way to handle >1, but that is standard Python.

Code: [Select]
from pcbnew import *

"""
To run from KiCad script console in pcbnew:

1. Open the console with Tools->Scripting Console
2. Save open files before running script!
3. type the following command in the console window:

execfile ("c:/python_progs/test_pcb/move_footprint.py")

change "c:/python_progs/test_pcb/" to where you stored "move_footprint.py".

Bob Cousins 2019
"""

def MoveFootprint(Filename, ref, x, y, rot, layer):
    if Filename:
        my_board = pcbnew.LoadBoard (Filename)
    else:
        my_board = GetBoard()

    for module in my_board.GetModules():

        if module.GetReference() == ref:

            print ("module ref %s %s" % ( module.GetReference(), my_board.GetLayerName(module.Reference().GetLayer())))

            module.SetPosition (wxPointMM(x,y))

            module.SetOrientation( rot * 10.0)

            if module.IsFlipped() and layer == 'top':
                module.Flip(wxPointMM(x,y))
            elif not module.IsFlipped() and layer == 'bottom':
                module.Flip(wxPointMM(x,y))

#
MoveFootprint(None, "S2", 40, 10, 90, 'bottom')

Refresh()