summaryrefslogtreecommitdiff
path: root/Documentation/biu-plan.txt
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/biu-plan.txt')
-rw-r--r--Documentation/biu-plan.txt243
1 files changed, 243 insertions, 0 deletions
diff --git a/Documentation/biu-plan.txt b/Documentation/biu-plan.txt
new file mode 100644
index 0000000..6fe9267
--- /dev/null
+++ b/Documentation/biu-plan.txt
@@ -0,0 +1,243 @@
+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.
+
+Assumptions:
+===========
+
+a) It is ok to modify the board file format in order to handle the BIU change.
+
+b) Boards saved on disk in the new format will not be readable using old software.
+
+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.
+
+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 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 FMT_ENG
+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:
+
+#if USE_DOUBLE_BFU
+typedef double BFU;
+#define FMT_ENG ".%10g"
+#else
+typedef long double BFU;
+#define FMT_ENG ".%10Lg"
+#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.
+
+Choosing BIU Units:
+==================
+
+BIUs are only used when a BOARD or MODULE is in RAM. A BIU is equivalent to
+either a 1) deci-mil or 2) nanometer, depending on how the source code is
+compiled. It is not a runtime decision. Form 1) is needed only during the
+preparation phase of the source code transition to nanometers. After the
+transition, only nanometers will be used in the compilation. No runtime
+switching is needed or wanted. Again, BIUs can only be one or the other for a
+given compilation, and this will swing based on a single #define.
+
+Eventually we may want to actually use "BIU" as our integer type in source code
+for those lengths which pertain to the board coordinate space. This would give
+us the ability to easily modify it, go to a larger bitness, make the source code
+more readable, and keep the type information out of the variable name. This
+would mean having a point and/or size class based on BIU as the contained
+integer types. This is a nice to have, but not immediately mandatory.
+
+There will be a number of places within the source code which will have to be
+doctored up to use the BFU casting. It will take some time to find all these
+sites. During this time it should be possible to continue using deci-mils as the
+BIU for source compilation.
+
+There are a quite a number of path ways in and out of BOARDs and MODULEs. Most
+everyone of these pathways involve conversion or scaling of BIUs. An example of
+a pathway in is a BOARD disk file loading function. An example of a pathway out
+of a BOARD is a disk file saving function. Likewise for MODULEs. We can
+characterize the load and save functions by their source and destination
+representations of lengths.
+
+BOARDs and MODULEs will soon have a new format, which is basically the existing
+format expressed in um or nm (TBD) rather than in deci-mils. For discussion, we
+will say this new format is in mm, even though it may end up being in um. In
+another year or two we will switch to s-expressions, or sooner if there is a
+volunteer.
+
+Here are the required immediate need BOARD load functions:
+
+1) Legacy to deci-mil loader. This loader uses a floating point scaling factor
+of unity, since destination is a RAM BOARD using deci-mils as its BIU.
+
+2) Legacy to nanometer loader. This loader uses a floating point scaling factor
+of 2540, since destination is a RAM BOARD using nanometers as its BIU, and
+the source format is using deci-mils.
+
+3) mm to nanometer loader. This loader uses a floating point scaling factor
+of 1000000, since the destination is a RAM BOARD using nanometers as its BIU.
+
+There is no need for a nm to deci-mil loader. (Once somebody saves a file in the
+new format, that format is used going forward, or its backup in the old format.)
+
+Now duplicate the above 3 loader types for MODULEs.
+
+Here are the required immediate need BOARD save functions:
+
+1) deci-mil to deci-mil, using a floating point scaling factor of unity. It
+should be possible to use trailing zero suppression on the deci-mils to get a
+BOARD that is identical to an old BOARD, and this can be used to test the new
+save function, using "diff" with whitespace ignore. This saver is only in play
+when the BIU is compiled to be deci-mils.
+
+2) nanometer to mm, using a floating point scaling factor of 1/1000000. This
+saver is only in play when the BIU is compiled to be nanometers.
+
+Now duplicate the above 3 saver types for MODULEs.
+
+New BOARD and MODULE files will have a new field in them identifying the
+engineering units used, say mm.
+
+In actuality, the source code to all 3 loaders, and to all 3 savers can be the
+same source code with a single variable in each case for scaling.
+
+All 6 loaders and all 6 savers should be written in parallel with existing
+loaders and savers, so that we can toggle usage back and forth between the two
+for awhile. This means we do not gut existing savers and loaders until the new
+ones are debugged and stable.
+
+The new savers and loaders are to be done in the context of a plug-in
+architecture, described elsewhere.
+
+Angles and Rotations:
+====================
+
+Internally we are switching from using an int to hold 1/10 of degrees angle to a
+typedef called DEGREES. The allowed values that DEGREES can hold will be
+enforced by the user interface policy, decided elsewhere. The engineering units
+in the DEGREES type is degrees, no longer tenths of degrees.
+
+/// a value used to hold rotations or angles.
+typedef double DEGREES;
+
+
+User Interface Changes:
+======================
+
+All these changes have to be done in a way where they hinge on one #ifdef.
+
+*) The grid dimension choices will have to be changed.
+
+*) The drawing routines will have to be changed to handle the case that BIU is
+compiled to be nm. Work towards getting legacy drawing code capable of handling
+a compile time #define to control a single scaling factor. Only the scaling
+factor should need be changed in the final state. Up until then, the work
+required is to inject the BFU casting where needed along with the scaling
+factor(s).
+
+*) Remove any funky imperial to metric conversion functions which tried to hide/mask
+problems with lack of BIU precision.
+
+*) There may be some fix ups pertaining to "near enough" type testing involving
+the user's mouse position, other than bounding box hit testing which should take
+care of itself (in BIUs). This has more to do with near-ness to a line type
+tests, and these are thought to best be done in screen coordinates anyway, not
+BIUs.
+
+Work Tasks:
+==========
+
+*) Within PCBNEW, find math expressions involving BIUs and cast them to BFUs
+early enough so that the compiler generates code in the BFU realm.
+
+*) Find a way to consistently round values from BFUs back to BIUs, and put that
+code in place. This could be done using a set accessor on a BIU, or other way.
+
+*) Fix the User Interface issues mentioned above, and more found later.
+
+*) Write the 4 new load and save functions. Vladimir recently committed code
+which can be a starting point for some of these functions, except that the new
+ones should reside within a PLUGIN object where we can save the scaling factor
+variable as a member field of the plugin. In order to meet the requirements
+of all 3 board loaders, we may have to dynamically change the scaling factor
+depending on what we find in the *.brd file and how the plugin is compiled.
+