You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
11 KiB

14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
14 years ago
  1. Proposed Plan for adding Nano Meters into PCBNEW as the Board Internal Unit
  2. ===========================================================================
  3. Author: Dick Hollenbeck November 25, 2011
  4. Introduction:
  5. ============
  6. This document sketches out a plan to move KiCad's PCBNEW program from deci-mil
  7. internal units to nanometer internal units. The changes to the code are
  8. significant enough to describe the basic process before the work is started.
  9. Definitions:
  10. ===========
  11. *) Board Internal Units (BIU). This is a pseudonym for the engineering units
  12. used by a BOARD when it is in RAM, and only when it is in RAM. BIU is
  13. essentially equal to nanometers in the future, and equal to deci-mils currently.
  14. A BIU refers typically to a measurement or a position on an XY grid, and this is
  15. because this grid is dimensioned in BIUs along both its X and Y axes. Both X and
  16. Y can be either positive or negative on this grid. In the case of measurements
  17. or scalars, there can be a radius, a diameter, a distance (length), and all of
  18. these can and should be expressed in BIUs, so long we are in RAM and so long as
  19. we are talking about the objects within the class BOARD instance. One special
  20. feature of XY points within the BIU coordinate system is that they will always
  21. be integers. In contrast, distances and other forms of measurements are not
  22. subject to the same limitation by the very nature of physics. Coordinates are
  23. always integers because we used signed whole numbers to represent these BIU
  24. coordinates.
  25. *) Snap grid. A snap grid is a subset of the full set of possible XY coordinates
  26. in the BIU coordinate system. Points falling on the snap grid are evenly spaced
  27. in X and Y directions and are some integer multiple apart in this 2D space,
  28. greater than one BIU.
  29. Assumptions:
  30. ===========
  31. a) It is ok to modify the board file format in order to handle the BIU change.
  32. b) Boards saved on disk in the new format will not be readable using old software.
  33. c) Since we have no backwards compatibility obligation (see b) above), we can
  34. make significant changes to the file format while we have this disruption
  35. opportunity.
  36. General:
  37. =======
  38. With nano meters as the Board Internal Unit (BIU), a 32 bit signed integer can
  39. only hold about 2 meters of positive length and 2 meters of negative length.
  40. Moreover, because most of the bits within a 32 bit integer can be "used up" to
  41. hold a typical length within a board, it is very likely that if pure 32 bit
  42. integer math is done, such as the multiplication of two integers in order to
  43. calculate a hypotenuse, then there will be an overflow within the 32 bit
  44. integer. (Another way to think of the BIU acronym is "Board Integer Unit" instead
  45. of as Board Internal Unit, to pave the way for the BFU, discussed below.)
  46. Therefore all intermediate products, quotients, trig, and exponential
  47. calculations should be done using some larger floating point type. By larger,
  48. bitness or number of bits is meant. Distances that do not have to be rounded
  49. back to integer immediately can and should stay in the larger floating point
  50. "value container" for as long as possible. The typedef name of this floating
  51. point type is BFU (Board Float Unit). The engineering units on a BFU are the
  52. same as on a BIU. A typedef is nice so that we can toggle between double and
  53. "long double" for various compilations, and so that when performing casts, these
  54. are brief textual expressions.
  55. Format Strings:
  56. ==============
  57. Because all our save to disk functions use printf() style format strings, we
  58. discuss how to construct a format string in the most usable way. There should be
  59. a printf() style format string like "%.6g" for the BFU (cast to a hard coded
  60. double) enclosed within a #define and its name should be FMT_ENG. This format
  61. string will be used at least for saving BOARD and MODULE files, and perhaps
  62. more.
  63. FMT_ENG stands for "format string for ENGineering units used out in the file". A
  64. define is needed simply to provide consistency across many sites of usage. BIUs
  65. will be scaled before being written to disk in most every case, and since
  66. scaling is a multiplication, it means casting one of the factors to BFU, and
  67. then this product is output with a printf() style function using the FMT_ENG
  68. string segment.
  69. That is, the FMT_ENG will be suitable for use with a BFU type. When BFU is set
  70. to double, then FMT_ENG will be set to "%.6g". When BFU is set to long double
  71. then FMT_ENG will be set to "%.6Lg". For example:
  72. #if USE_DOUBLE_BFU
  73. typedef double BFU;
  74. #define FMT_ENG ".%10g"
  75. #else
  76. typedef long double BFU;
  77. #define FMT_ENG ".%10Lg"
  78. #endif
  79. A format string can then be built up using compile time concatenation of
  80. strings, like this:
  81. fprintf( fp, "Value: " FMT_ENG " " FMT_ENG "\n", BFU( biu1 * scale), BFU( biu2 * scale ) );
  82. The 3rd and 4th arguments are BFUs, and the casting is done after the multiply
  83. since the scaling factor is already a double or perhaps even a long double. The
  84. final argument needs to match the format string, so the final product is wrapped
  85. in a BFU, which could actually be a truncation down to 64 bit float from 80 bit
  86. float. The key points are: the calculation must be done in a float type at least
  87. as bit-wide as BFU, and that the value actually passed to fprintf() must match
  88. the format string.
  89. Choosing BIU Units:
  90. ==================
  91. BIUs are only used when a BOARD or MODULE is in RAM. A BIU is equivalent to
  92. either a 1) deci-mil or 2) nanometer, depending on how the source code is
  93. compiled. It is not a runtime decision. Form 1) is needed only during the
  94. preparation phase of the source code transition to nanometers. After the
  95. transition, only nanometers will be used in the compilation. No runtime
  96. switching is needed or wanted. Again, BIUs can only be one or the other for a
  97. given compilation, and this will swing based on a single #define.
  98. Eventually we may want to actually use "BIU" as our integer type in source code
  99. for those lengths which pertain to the board coordinate space. This would give
  100. us the ability to easily modify it, go to a larger bitness, make the source code
  101. more readable, and keep the type information out of the variable name. This
  102. would mean having a point and/or size class based on BIU as the contained
  103. integer types. This is a nice to have, but not immediately mandatory.
  104. There will be a number of places within the source code which will have to be
  105. doctored up to use the BFU casting. It will take some time to find all these
  106. sites. During this time it should be possible to continue using deci-mils as the
  107. BIU for source compilation.
  108. There are a quite a number of path ways in and out of BOARDs and MODULEs. Most
  109. everyone of these pathways involve conversion or scaling of BIUs. An example of
  110. a pathway in is a BOARD disk file loading function. An example of a pathway out
  111. of a BOARD is a disk file saving function. Likewise for MODULEs. We can
  112. characterize the load and save functions by their source and destination
  113. representations of lengths.
  114. BOARDs and MODULEs will soon have a new format, which is basically the existing
  115. format expressed in um or nm (TBD) rather than in deci-mils. For discussion, we
  116. will say this new format is in mm, even though it may end up being in um. In
  117. another year or two we will switch to s-expressions, or sooner if there is a
  118. volunteer.
  119. Here are the required immediate need BOARD load functions:
  120. 1) Legacy to deci-mil loader. This loader uses a floating point scaling factor
  121. of unity, since destination is a RAM BOARD using deci-mils as its BIU.
  122. 2) Legacy to nanometer loader. This loader uses a floating point scaling factor
  123. of 2540, since destination is a RAM BOARD using nanometers as its BIU, and
  124. the source format is using deci-mils.
  125. 3) mm to nanometer loader. This loader uses a floating point scaling factor
  126. of 1000000, since the destination is a RAM BOARD using nanometers as its BIU.
  127. There is no need for a nm to deci-mil loader. (Once somebody saves a file in the
  128. new format, that format is used going forward, or its backup in the old format.)
  129. Now duplicate the above 3 loader types for MODULEs.
  130. Here are the required immediate need BOARD save functions:
  131. 1) deci-mil to deci-mil, using a floating point scaling factor of unity. It
  132. should be possible to use trailing zero suppression on the deci-mils to get a
  133. BOARD that is identical to an old BOARD, and this can be used to test the new
  134. save function, using "diff" with whitespace ignore. This saver is only in play
  135. when the BIU is compiled to be deci-mils.
  136. 2) nanometer to mm, using a floating point scaling factor of 1/1000000. This
  137. saver is only in play when the BIU is compiled to be nanometers.
  138. Now duplicate the above 3 saver types for MODULEs.
  139. New BOARD and MODULE files will have a new field in them identifying the
  140. engineering units used, say mm.
  141. In actuality, the source code to all 3 loaders, and to all 3 savers can be the
  142. same source code with a single variable in each case for scaling.
  143. All 6 loaders and all 6 savers should be written in parallel with existing
  144. loaders and savers, so that we can toggle usage back and forth between the two
  145. for awhile. This means we do not gut existing savers and loaders until the new
  146. ones are debugged and stable.
  147. The new savers and loaders are to be done in the context of a plug-in
  148. architecture, described elsewhere.
  149. Angles and Rotations:
  150. ====================
  151. Internally we are switching from using an int to hold 1/10 of degrees angle to a
  152. typedef called DEGREES. The allowed values that DEGREES can hold will be
  153. enforced by the user interface policy, decided elsewhere. The engineering units
  154. in the DEGREES type is degrees, no longer tenths of degrees.
  155. /// a value used to hold rotations or angles.
  156. typedef double DEGREES;
  157. User Interface Changes:
  158. ======================
  159. All these changes have to be done in a way where they hinge on one #ifdef.
  160. *) The grid dimension choices will have to be changed.
  161. *) The drawing routines will have to be changed to handle the case that BIU is
  162. compiled to be nm. Work towards getting legacy drawing code capable of handling
  163. a compile time #define to control a single scaling factor. Only the scaling
  164. factor should need be changed in the final state. Up until then, the work
  165. required is to inject the BFU casting where needed along with the scaling
  166. factor(s).
  167. *) Remove any funky imperial to metric conversion functions which tried to hide/mask
  168. problems with lack of BIU precision.
  169. *) There may be some fix ups pertaining to "near enough" type testing involving
  170. the user's mouse position, other than bounding box hit testing which should take
  171. care of itself (in BIUs). This has more to do with near-ness to a line type
  172. tests, and these are thought to best be done in screen coordinates anyway, not
  173. BIUs.
  174. Work Tasks:
  175. ==========
  176. *) Within PCBNEW, find math expressions involving BIUs and cast them to BFUs
  177. early enough so that the compiler generates code in the BFU realm.
  178. *) Find a way to consistently round values from BFUs back to BIUs, and put that
  179. code in place. This could be done using a set accessor on a BIU, or other way.
  180. *) Fix the User Interface issues mentioned above, and more found later.
  181. *) Write the 4 new load and save functions. Vladimir recently committed code
  182. which can be a starting point for some of these functions, except that the new
  183. ones should reside within a PLUGIN object where we can save the scaling factor
  184. variable as a member field of the plugin. In order to meet the requirements
  185. of all 3 board loaders, we may have to dynamically change the scaling factor
  186. depending on what we find in the *.brd file and how the plugin is compiled.