← Back to team overview

kicad-developers team mailing list archive

Re: layer based constraints

 

I have worked a bit more on the idea of the “layer based constraints”. We have already argued quite a bit about how one should tell KiCad about different constraints on different layers. But I think, we all more or less agree that there are realistic use cases where a constraint is not only dependent on the net, but also on the layer (and maybe other things).

So, the routine getConstraint() (with or without an ‘other’ item passed as argument) should get another argument: LAYER_NUM aLayer, because, as soon as the layer, in one way or the other, influences the minimal acceptable clearance between different nets, I have to distinguish between these nets. For all these connectedItems that are only on one layer (like tracks), the item can just check on which layer it is, and return the appropriate value. But there are also pads and vias. And here, it is not sufficient anymore to just ask “what is the miminal clearance around you”? Instead, I have to ask: What is the minimal clearance around you on layer two?” That’s why I inserted the additional argument aLayer. Of course, I included it on all connectedItems because of subtyping. A track, for example, just ignores it and takes its own layer as a reference.

Ok, then, I did another thing: ConnectedItems can show their clearance as a line around the item, which is one of the best features of KiCad, if you ask me. I LOVE this feature! But now, I had a problem with it. Again, if an item is on only one layer, it’s fine. Just show the clearance according to the layer of the track. But what about a pad? A pad can “sit” on all layers. So, which clearance to show? Possible anwers:

- none
- the net-based clearance (only feasable if we ARE separating net-based and layer-based clearances, and not mixing them in any way)
- all clearances, in the respective color
- the clearance according to the layer that is currently active, if it is a copper layer, and none if it is a non-copper layer.

I, for my personal branch, decided to pick the last solution. But this confronted me with another question: If I am on layer two, and there is a multi-layer pad, a track on layer two and a track on layer one. What do I expect to see? I decided that I would like to see the clearances on layer two. Nothing else. So, the pad shows me the clearance it has on layer two. And the pad, that is on layer two, shows me its clearance, and the track on layer shows no clearance line. I hacked this behavior and must say that I like it. I never checkt “always” at “show tracks clearances”, because it was just too much information. But with my patch, I now think I’m going to stay at this option. It shows my all clearances I have to respect on the layer that is currentla active (a.e. the layer on which I am placing tracks at the moment). After all, I don’t care about a layer two’s clearance if I’m on layer one.

I will upload a branch eventually so you guys can have a look at it. Not so much to press my implementation of it into a release (there's no chance for it, either ;-), but more to let you get a feeling of it, because I really think this is an issue. I think, a good CAE tool should take the layer into account when it comes to constraints. And as KiCad IS a very good tool, it is proven by induction, that KiCad should be able to handle this! :-) Just kidding....

Now, there are still other things, like, for example, constraints between two defined nets, area based constraints... all the fancy stuff. Of course, we could add also these things as additional parameters... or we could pass an object containing all important parameters an item has to know to calculate the clearance. Or... hmmm... just a reference to the caller item: - Item xy, tell me, please, how much clearance I have to keep to you. I am item yz.
- Item yz, on what layer are you? And what’s your net?
- Ok, Item xy, please stay 2mm away from me.

Oh, I almost forgot: There is another thing that, as I suppose, is quite connected to this issue: Pads with defined pad-stacks. Say, I want to insert a pad on the outer layers, but on the inner layers, there should be no copper (or less copper). This surely influences the clearance. Again, the clearance strongly depends on the layer on which I am approaching the pad.


What do you think? Is this worth a blue-print?
I really really like the idea of implementing such a thing. I am, actually, now starting to work productively with my patch (but only as a hobbyist) and up to now, I really like also the slightly changed look-and-feel as described above.

- I can define clearance and width constraints for every layer (which is, as I said, very useful to me because of manufactuer’s constraints) - I am shown all clearances (max of net-based and layer based) on the active layer - when I place a track with the “standard” thickness setting, it gets me the actual thickness of the net on the layer I am. - When I switch layers (a.e. place a via) the width changes according to the new rules (same net, but different layer, again, the max i taken).
- It, of course, also gives me the the updated clearance.
- Pads: It shows me the clearance for the actual layer (or none, of it is not a copper layer). - copper fills are taking taking care of the different layer constraints around pads.
- DRC I didn’t check intensively yet, but should work.

I am very well aware that it’s a bad idea to just take this first realization into the main branch instead of really thinking about future features, and how to do it right. As I said, I don't intend this branch to be merged as-is, but more as a basepoint for some discussion.


Greets
Simon


-----Ursprüngliche Nachricht----- From: Dick Hollenbeck
Sent: Sunday, April 28, 2013 3:12 PM
To: kicad-developers@xxxxxxxxxxxxxxxxxxx
Subject: Re: [Kicad-developers] layer based constraints

On 04/27/2013 12:10 PM, Lorenzo Marcantonio wrote:
On Sat, Apr 27, 2013 at 11:11:54AM -0500, Dick Hollenbeck wrote:
But how important is that really?  Will it result in a reduction in pay?

The "common" user has been a hobbyist, and is becoming a corporate employee as the
software gets better.

OK, even most of the corporate employees have probably 0% of
understanding a boolean expression. Unless he's a digital designer :D
woes on him in that case

So while I agree, I think the importance of this concern is minimal. Actually zero. If we like it, that should be good enough. We are corporate employees, and are paying to make this software useable for our needs. You said yourself the same thing.

Agree on that. But if it's possible to make it usable for the
non-programmer people (without too much work) then it's better.
Otherwise I'd looking for components using grep instead of the component
browser for example (the sad thing is that often grepping is more
effective...)

Great idea, do it.  It seems we are all still open to the best ideas.

In a previous message I wrote about how CAM350/gerbtool do DRC. The CAM
products are for 60% DRC beasts so they know how to do their job:D

Eagle has a simple netclass-to-netclass clearance. I haven't used any
other of the 'big ones' (Altium, Allegro, PADS or Expedition) so I don't
really know how they handle it. Many entry level products don't have even
a netclass notion, so we already are way above them:D

Is there a way we can provide a python expression, but do most of the work in C++?, by implementing the functions being called in C++ behind the expression, by following the
python C API.

This is a slight variation on the original idea, which can be a way to turbo charge it,
maybe to cut out a few lookups at runtime.

Obviously the python expressions can all be "pre-compiled", but I don't think they can be "pre-evalutated" when "both" is in play, since that is a dynamic match maker.

Caching (memoizing, actually) strategies for the python calls would
depend on the data available to the call. Assuming the function is pure
(i.e. depending only on the passed parameters) you could cull *a lot* of
calls.

Example (in C, I don't know python enough): function returning
the clearance (one of the contended values) between two netclasses and
the current layer; with only the minimum data we'd have:

int dynamic_clearance(const char *netclass1, const char *netclass2,
                      const char *layer);

*iif* the implementation is pure, as from the hypothesis, there are no
external dependancies and no collateral effects so *every* call with
a tuple (triplet) would always return the same value. Put it in a map
(memoize it) and you have just resolved the clearance issues between
these two classes on that layer with just one python call. AFAIK
memoizing is a standard idiom in python, too.

More flexibility reduces optimization possibilities. Let's say we pass
the netnames too (don't ask why, maybe the user wants more granularity
than netnames, no idea)

int dynamic_clearance(const char *netclass1, const char *netclass2,
                      const char *netname1, const char *netname2,
                      const char *layer);

Here memoizing is a lot less effective... you only cache clearance
between two nets (the netclasses are actually redundant and passed as
convenience). However you would optimize the common case of buses
wandering around the board. Still a good improvement, probably.

At the other end, if the decision function has the whole segment
information at hand:

int dynamic_clearance(const char *netclass1, const char *netclass2,
                      const char *netname1, const char *netname2,
                      const char *layer, int stuff, int other_stuff...)

Then we gain *no* performance since (ideally) every segment is tested
against any other segment just once. In fact caching overhead would
probably make it slower than without.

That said, maybe a python call is just so fast that the big time is
spent computing distances maybe. Or the bottleneck is in the string
comparison. If it was LUA instead of Python I'd say to directly call the
function without any doubt (LUA strings are interned so the string
equality is pointer equality for example, and the byte code interpreter
is... well, fast).

As you said instrumented profiling is needed, at least to compare the cost
of a python call to the rest of the stuff in the DRC routines.


Caching is an interesting idea to keep in our toolbox. I think C++ has some great potential in developing some wrapper classes for making use of python expessions fairly
painless.  It is an area I hope to contribute to when I have some more time.

Each year we host a large memorial day party here at the ranch, and often have a pig roast on a spit. The preparations for that can get overwhelming and start weeks in advance. So this has reached full scale as of this weekend. Time is more scarce than ever.

Dick






_______________________________________________
Mailing list: https://launchpad.net/~kicad-developers
Post to     : kicad-developers@xxxxxxxxxxxxxxxxxxx
Unsubscribe : https://launchpad.net/~kicad-developers
More help : https://help.launchpad.net/ListHelp


Follow ups

References