← Back to team overview

kicad-developers team mailing list archive

Re: Concerns about clearing disagreements before committing.



Thanks for your feedback to my plan.

> This is feedback but doesn't need a reply. (I'd rather you spend the
> time coding  :)
>> Proposed Plan for adding Nano Meters into PCBNEW as the Board Internal
>> Unit
>> ===========================================================================
>> Author:  Dick Hollenbeck  November 25, 2011
>> Introduction:
>> ============
>> This document sketches out a plan to move KiCad's PCBNEW program from
>> deci-mil
>> internal units to nanometer internal units. The changes to the code are
>> significant enough to describe the basic process before the work is
>> started.
>> Definitions:
>> ===========
>> *) Board Internal Units (BIU). This is a pseudonym for the engineering
>> units
>> used by a BOARD when it is in RAM, and only when it is in RAM. BIU is
>> essentially equal to nanometers in the future, and equal to deci-mils
>> currently.
>> A BIU refers typically to a measurement or a position on an XY grid,
>> and this is
>> because this grid is dimensioned in BIUs along both its X and Y axes.
>> Both X and
>> Y can be either positive or negative on this grid. In the case of
>> measurements
>> or scalars, there can be a radius, a diameter, a distance (length),
>> and all of
>> these can and should be expressed in BIUs, so long we are in RAM and
>> so long as
>> we are talking about the objects within the class BOARD instance. One
>> special
>> feature of XY points within the BIU coordinate system is that they
>> will always
>> be integers. In contrast, distances and other forms of measurements
>> are not
>> subject to the same limitation by the very nature of physics.
>> Coordinates are
>> always integers because we used signed whole numbers to represent
>> these BIU
>> coordinates.
>> *) Snap grid. A snap grid is a subset of the full set of possible XY
>> coordinates
>> in the BIU coordinate system. Points falling on the snap grid are
>> evenly spaced
>> in X and Y directions and are some integer multiple apart in this 2D
>> space,
>> greater than one BIU.
>> *) Metric Board. This is a pcb board that has a great number of
>> coordinates and
>> distances that happen to be some multiple of the BIU that is also a
>> multiple of
>> a metric engineering unit such as micrometers.
>> *) Imperial Board.  This is a pcb board that has a great number of
>> coordinates and
>> distances that happen to be some multiple of the BIU that is also a
>> multiple of
>> an imperial engineering unit such as mils or inches.
> I'm reading this such that you mean a board is either 'Metric' or
> 'Imperial' only in name? Otherwise I agree with brian. All of the
> technology I use is mixed between metric and imperial.
> That said, I don't mind a default units for a board file with a units
> tag on values in other units. As long as the values between board files
> and manufacturing files remain consistent and as expected.
>> Assumptions:
>> ===========
>> a) It is ok to modify the board file format in order to handle the BIU
>> change.
> Yes as long as we can automagically convert from old to new.
>> b) Boards saved on disk in the new format will not be readable using
>> old software.
> Yes, but a big fat warning at the transition point is needed so that
> those in need of stability can wait a few revisions...
>> c) Since we have no backwards compatibility obligation (see b) above),
>> we can
>> make significant changes to the file format while we have this disruption
>> opportunity.
>> General:
>> =======
>> With nano meters as the Board Internal Unit (BIU), a 32 bit signed
>> integer can
>> only hold about 2 meters of positive length and 2 meters of negative
>> length.
>> Moreover, because most of the bits within a 32 bit integer can be
>> "used up" to
>> hold a typical length within a board, it is very likely that if pure
>> 32 bit
>> integer math is done, such as the multiplication of two integers in
>> order to
>> calculate a hypotenuse, then there will be an overflow within the 32 bit
>> integer. (Another way to think of the BIU acronym is "Board Integer
>> Unit" instead
>> of as Board Internal Unit, to pave the way for the BFU, discussed below.)
>> Therefore all intermediate products, quotients, trig, and exponential
>> calculations should be done using some larger floating point type. By
>> larger,
>> bitness or number of bits is meant. Distances that do not have to be
>> rounded
>> back to integer immediately can and should stay in the larger floating
>> point
>> "value container" for as long as possible. The typedef name of this
>> floating
>> point type is BFU (Board Float Unit). The engineering units on a BFU
>> are the
>> same as on a BIU. A typedef is nice so that we can toggle between
>> double and
>> "long double" for various compilations, and so that when performing
>> casts, these
>> are brief textual expressions.
> Fixed point math, with all it's issues, is well traveled ground. There
> is lots of info out there on the issues and pitfalls. Since it appears
> kicad is trying to optimize on the size of the datatype, whomever
> implements it will have to do a lot of thinking about the operational
> domains to insure that the math is behaving as expected for all board
> designs. If you don't feel like doing all that work, you can cross your
> fingers, select a bigger type, and hope you get away with it.
> Floating point math is exactly the same. It has it's issues, they are
> well understood, and if you are optimizing on the size of the type you
> will have to think hard about the domain you use it in.
> The nice thing is that you are able to reason fairly well about the
> problem. You know what the manufacturing process is able to do. Panels
> are around 1 meter, traces are <100 um and unlikely to reach 10um.
> I guess what I'm saying is please consider doing the math before
> selecting your types. I think you'll find sticking with a single type
> for board internal units is the least error prone. Maybe save
> optimization for a second pass after things are working error free.

The boost::polygon library was written by two guys from Intel.

I assumed they had access to the instruction sets, knew something about how their
processors worked, and how other computers that might run their library work.  In a modern
era, it is sometime difficult to keep up with the ever increasing capabilities of modern
desktop processors.  The guys from Intel undertook to solve problems very similar to the
ones we have.

boost::polygon works, and works well.

I extracted the essence of their choices when writing my plan.

Basically it uses the latter of your two pathways, which is to simply use enough bits, but
this only needs to happen in the intermediate product and quotients, so this means that
you don't store these in 32 bit ints.  You use the larger bitness types.  We are on track
to use 80 bits of intermediate containers, if we follow my plan.

>> Format Strings:
>> ==============
>> Because all our save to disk functions use printf() style format
>> strings, we
>> discuss how to construct a format string in the most usable way. There
>> should be
>> a printf() style format string like "%.6g" for the BFU (cast to a hard
>> coded
>> double) enclosed within a #define and its name should be FMT_ENG. This
>> format
>> string will be used at least for saving BOARD and MODULE files, and
>> perhaps
>> more.
>> FMT_ENG stands for "format string for ENGineering units used out in
>> the file". A
>> define is needed simply to provide consistency across many sites of
>> usage. BIUs
>> will be scaled before being written to disk in every most every case,
>> and since
>> scaling is a multiplication, it means casting one of the factors to
>> BFU, and
>> then this product is output with a printf() style function using the
>> string segment.
>> That is, the FMT_ENG will be suitable for use with a BFU type. When
>> BFU is set
>> to double, then FMT_ENG will be set to "%.6g". When BFU is set to long
>> double
>> then FMT_ENG will be set to "%.6lg". For example:
>> typedef double          BFU;
>> #define FMT_ENG         ".%6g"
>> #else
>> typedef long double     BFU;
>> #define FMT_ENG         ".%6Lg"
>> #endif
>> A format string can then be built up using compile time concatenation of
>> strings, like this:
>> fprintf( fp, "Value: " FMT_ENG " " FMT_ENG "\n", BFU( biu1 * scale),
>> BFU( biu2 * scale ) );
>> The 3rd and 4th arguments are BFUs, and the casting is done after the
>> multiply
>> since the scaling factor is already a double or perhaps even a long
>> double. The
>> final argument needs to match the format string, so the final product
>> is wrapped
>> in a BFU, which could actually be a truncation down to 64 bit float
>> from 80 bit
>> float. The key points are: the calculation must be done in a float
>> type at least
>> as bit-wide as BFU, and that the value actually passed to fprintf()
>> must match
>> the format string.
> The main constraint is that the in-file-format of then numbers need to
> be human readable. And in a sense, the in-file values ARE the board. If
> you are going truncate/round the numbers to be a little but nicer to
> read, fine, but then make ABSOLUTELY SURE that you truncate new values
> before using them. If I load up kicad, design a board and print it
> before saving, I'll get a different board than if I load the same board
> from a file, because it's values have not been truncated yet.
> If your printing/export routines truncate the same way a file save does
> before any other operation (like 4:6 formatting) then it will work ok.

No truncations are planned.  Any information in a BIU will always be retained on disk.  As
Brian pointed out, this is 10 significant digits of information, worst case because 
limits.h has

#define MAX_INT 2147483647

I count 10 digits.

When we scale, regardless of the scaling factor, we still have 10 significant digits of
trustworthy information, not more.  The "%.10g" format string will truncate trailing
zeros, whereas %f does not.  This gives you the human readability. 

The file on disk will likely be in mm, meaning we are in sweet spot of fewest digits per
number, with maximum human readability.

Thanks for your feedback.  I think we have enough to start coding.

Let me know if there is any part of this that you (collectively you) want to contribute.

See the repo for the latest copy.

For me, this is about enough talk now.


Follow ups