INDEX PULSE, INPUT SCALE, and Cumulative Error
- torinwalker
- Offline
- New Member
Less
More
- Posts: 4
- Thank you received: 0
30 Dec 2012 21:22 - 30 Dec 2012 21:40 #28177
by torinwalker
INDEX PULSE, INPUT SCALE, and Cumulative Error was created by torinwalker
I have an encoder with a 25,000 count-per-revolution (100,000 pulses per rev in quadrature) that I want to affix directly to a rotary table, rather than to the motor driving the worm/gear. I mistakenly purchased this one and later realized I should have purchased one that evenly divides by 360 (e.g. 18000 CPR or 72000 ppr in quadrature.) Now I'm stuck with it.
The problem I see with this is in the division of the pulse count by the machine units. For example, on an ANGULAR axis with a 100000 PPR, dividing by 360 degrees yields 277.7777... counts per degree.
This means that with a precision of four decimal places, I will encounter a cumulative error of .0001 degrees per degree, and after one full rotation, an error of 0.036 degrees. After two full rotations, .072. By the tenth rotation, the axis will be misaligned by nearly half a degree.
The only way I can see to correct for this cumulative error is to "rewind" the table back to the beginning, otherwise this small error will eventually result in a much larger error affecting machining accuracy. However, due to the very slow rotation of this table, it is unacceptable to have to rotate my table in reverse after each full turn. Typically, a machining operation involves loading a part, rotating and drilling, then exchanging parts and repeating. The program could run all day this way - again, rotating the table back through 360 between parts is too slow and not at all acceptable.
So, I have a question: What is the behavior of the INDEX on an ANGULAR axis? Does it serve to reset the machine state to zero? Or, does Linux depend on the rotary pulse only to determine its current relative position?
Torin...
The problem I see with this is in the division of the pulse count by the machine units. For example, on an ANGULAR axis with a 100000 PPR, dividing by 360 degrees yields 277.7777... counts per degree.
This means that with a precision of four decimal places, I will encounter a cumulative error of .0001 degrees per degree, and after one full rotation, an error of 0.036 degrees. After two full rotations, .072. By the tenth rotation, the axis will be misaligned by nearly half a degree.
The only way I can see to correct for this cumulative error is to "rewind" the table back to the beginning, otherwise this small error will eventually result in a much larger error affecting machining accuracy. However, due to the very slow rotation of this table, it is unacceptable to have to rotate my table in reverse after each full turn. Typically, a machining operation involves loading a part, rotating and drilling, then exchanging parts and repeating. The program could run all day this way - again, rotating the table back through 360 between parts is too slow and not at all acceptable.
So, I have a question: What is the behavior of the INDEX on an ANGULAR axis? Does it serve to reset the machine state to zero? Or, does Linux depend on the rotary pulse only to determine its current relative position?
Torin...
Last edit: 30 Dec 2012 21:40 by torinwalker.
Please Log in or Create an account to join the conversation.
- torinwalker
- Offline
- New Member
Less
More
- Posts: 4
- Thank you received: 0
30 Dec 2012 21:40 #28178
by torinwalker
Replied by torinwalker on topic INDEX PULSE, INPUT SCALE, and Cumulative Error
Looks like I found my answer shortly after I posted:
In the Linux CNC encoder (9) man page, one can set the "encoder.N.index-enable" flag to true which will cause the count and position to be reset upon each encounter of the a rising edge of an index pulse.
Looks like my error will not keep accumulating after all, but I still must deal with the perpetual psychological damage of knowing I'm +/- 0.0036 degrees out just before the pulse.
Don't laugh. On a 10" diameter, it corresponds to .1" of error which is appalling.
Torin...
In the Linux CNC encoder (9) man page, one can set the "encoder.N.index-enable" flag to true which will cause the count and position to be reset upon each encounter of the a rising edge of an index pulse.
Looks like my error will not keep accumulating after all, but I still must deal with the perpetual psychological damage of knowing I'm +/- 0.0036 degrees out just before the pulse.
Don't laugh. On a 10" diameter, it corresponds to .1" of error which is appalling.
Torin...
Please Log in or Create an account to join the conversation.
30 Dec 2012 22:53 #28181
by BigJohnT
Replied by BigJohnT on topic INDEX PULSE, INPUT SCALE, and Cumulative Error
The scale can have a precision greater than 4 decimal places. I'm not exactly sure but I think it is... in the manual.
John
John
Please Log in or Create an account to join the conversation.
30 Dec 2012 23:04 - 30 Dec 2012 23:23 #28182
by PCW
Replied by PCW on topic INDEX PULSE, INPUT SCALE, and Cumulative Error
Encoder scale is a 32 bit float so about 7 digits of accuracy
The error in not accumulative per degree but per turn.
For example, if you have a encoder count of 50000 this is divided by 277.7777
yielding 180.00005040001411200395. This error is much less than one encoder count
(.0036 degrees).
With ~7 decimal precision, you need to go about 30 turns to get off by
one encoder count equivalent.
BTW 277.7778 is about 3 times closer to 277.777777... than 277.7777
The error in not accumulative per degree but per turn.
For example, if you have a encoder count of 50000 this is divided by 277.7777
yielding 180.00005040001411200395. This error is much less than one encoder count
(.0036 degrees).
With ~7 decimal precision, you need to go about 30 turns to get off by
one encoder count equivalent.
BTW 277.7778 is about 3 times closer to 277.777777... than 277.7777
Last edit: 30 Dec 2012 23:23 by PCW.
Please Log in or Create an account to join the conversation.
- torinwalker
- Offline
- New Member
Less
More
- Posts: 4
- Thank you received: 0
31 Dec 2012 00:02 - 31 Dec 2012 01:15 #28184
by torinwalker
Replied by torinwalker on topic INDEX PULSE, INPUT SCALE, and Cumulative Error
I think I've found a way to solve it. It occurred over breakfast after the encoder(9) man page had a chance to sink in.
But first, there are a couple of responses here, so let me address each of them:
An encoder count of 50000 / 360 = 138.888...
The encoder manual suggests a 32-bit float, signed, so that gives me 31 bits of precision, 21 after the decimal. Using a 32-bit float converter, it appears I can get up to nearly 5 decimal places (i.e. 277.77776, 277.77777, 277.77778 are all equivalent with 277.77777 being the mean).
I started writing this post, calculating all the values, but then discovered I was off by an order of magnitude. The error is one order larger than I originally though. I finally broke down and wrote a program to confirm what I suspected:
Using 32 and 64-bit values side by each in the program, I used 64-bits as a reference and subtracted the 32-bit value to get the error. For a single count (277.77777) this works out to:
0.0000067817
Throwing this into excel, and calculating the error for a 10" diameter ring, I get:
(idx in degrees, error in degrees, error in inches at radius of part)
30 0.000203451 0.006391587
60 0.000406901 0.012783173
90 0.000610352 0.01917476
120 0.000813802 0.025566346
150 0.001017253 0.031957933
180 0.001220703 0.038349519
210 0.001424154 0.044741106
240 0.001627604 0.051132692
270 0.001831055 0.057524279
300 0.002034505 0.063915865
330 0.002237956 0.070307452
I thought the error would be cumulative, but it varies depending on the single precision rounding error (whether up or down), but the error is still very significant.
The result came out as follows:
But wait... it gets better. Over breakfast, I remembered something I read in the integrator's manual and it occurred to me that Linux CNC can also express ANGULAR machine units in "Gradians" (400 per full turn), so I can eliminate this error altogether by expressing encoder counts in Gradians instead of degrees, and use 250 counts per gradian. This way, the error is eliminated, and since machine units are independent of GCode values, I can still express GCode in degrees.
I believe with this, I can rotate my table in one direction forever and no error will accumulate. I just hope the Linux CNC team doesn't deprecate Gradians... ever.
Torin...
But first, there are a couple of responses here, so let me address each of them:
An encoder count of 50000 / 360 = 138.888...
The encoder manual suggests a 32-bit float, signed, so that gives me 31 bits of precision, 21 after the decimal. Using a 32-bit float converter, it appears I can get up to nearly 5 decimal places (i.e. 277.77776, 277.77777, 277.77778 are all equivalent with 277.77777 being the mean).
I started writing this post, calculating all the values, but then discovered I was off by an order of magnitude. The error is one order larger than I originally though. I finally broke down and wrote a program to confirm what I suspected:
Using 32 and 64-bit values side by each in the program, I used 64-bits as a reference and subtracted the 32-bit value to get the error. For a single count (277.77777) this works out to:
0.0000067817
Throwing this into excel, and calculating the error for a 10" diameter ring, I get:
(idx in degrees, error in degrees, error in inches at radius of part)
30 0.000203451 0.006391587
60 0.000406901 0.012783173
90 0.000610352 0.01917476
120 0.000813802 0.025566346
150 0.001017253 0.031957933
180 0.001220703 0.038349519
210 0.001424154 0.044741106
240 0.001627604 0.051132692
270 0.001831055 0.057524279
300 0.002034505 0.063915865
330 0.002237956 0.070307452
I thought the error would be cumulative, but it varies depending on the single precision rounding error (whether up or down), but the error is still very significant.
float sp_INPUT_SCALE = 277.77777f;
double dp_INPUT_SCALE = 277.7777777777778;
System.out.println("SP (32bit float) of 100k counts / 360 degrees (cast to float) = " + (100000f/360f));
System.out.println("SP (64bit float) of 100k counts / 360 degrees (cast to double) = " + (100000d/360d));
System.out.println("Difference (error) = " + ((100000d/360d) - (100000f/360f)) );
System.out.println("SP (32bit float) of value 277.77775 @ 5 places = " + 277.77775f);
System.out.println("SP (32bit float) of value 277.77776 @ 5 places = " + 277.77776f);
System.out.println("SP (32bit float) of value 277.77777 @ 5 places = " + 277.77777f);
System.out.println("SP (32bit float) of value 277.77778 @ 5 places = " + 277.77778f);
System.out.println("SP (32bit float) of value 277.77779 @ 5 places = " + 277.77779f);
for (int i = 0; i < 360; i+=30) {
System.out.println("At index of " + i + " degrees:");
System.out.println(" SP Degrees = " + i * sp_INPUT_SCALE);
System.out.println(" DP Degrees = " + i * dp_INPUT_SCALE);
double error = ((i * dp_INPUT_SCALE) - (i * sp_INPUT_SCALE));
System.out.println(" Error = " + error);
System.out.println(" Error (inches) @ 10\" diam = " + (double)(error * 31.415926) );
}
The result came out as follows:
SP (32bit float) of 100k counts / 360 degrees (cast to float) = 277.77777
SP (64bit float) of 100k counts / 360 degrees (cast to double) = 277.77777777777777
Difference (error) = 6.781684021461842E-6
SP (32bit float) of value 277.77775 @ 5 places = 277.77774
SP (32bit float) of value 277.77776 @ 5 places = 277.77777
SP (32bit float) of value 277.77777 @ 5 places = 277.77777
SP (32bit float) of value 277.77778 @ 5 places = 277.77777
SP (32bit float) of value 277.77779 @ 5 places = 277.7778
At index of 0 degrees:
SP Degrees = 0.0
DP Degrees = 0.0
Error = 0.0
Error (inches) @ 10" diam = 0.0
At index of 30 degrees:
SP Degrees = 8333.333
DP Degrees = 8333.333333333336
Error = 3.2552083575865254E-4
Error (inches) @ 10" diam = 0.010226538487651982
At index of 60 degrees:
SP Degrees = 16666.666
DP Degrees = 16666.66666666667
Error = 6.510416715173051E-4
Error (inches) @ 10" diam = 0.020453076975303963
At index of 90 degrees:
SP Degrees = 25000.0
DP Degrees = 25000.000000000004
Error = 3.637978807091713E-12
Error (inches) @ 10" diam = 1.1429047299316153E-10
At index of 120 degrees:
SP Degrees = 33333.332
DP Degrees = 33333.33333333334
Error = 0.0013020833430346102
Error (inches) @ 10" diam = 0.040906153950607926
At index of 150 degrees:
SP Degrees = 41666.664
DP Degrees = 41666.66666666667
Error = 0.002604166671517305
Error (inches) @ 10" diam = 0.08181230744405396
At index of 180 degrees:
SP Degrees = 50000.0
DP Degrees = 50000.00000000001
Error = 7.275957614183426E-12
Error (inches) @ 10" diam = 2.2858094598632305E-10
At index of 210 degrees:
SP Degrees = 58333.332
DP Degrees = 58333.33333333334
Error = 0.0013020833430346102
Error (inches) @ 10" diam = 0.040906153950607926
At index of 240 degrees:
SP Degrees = 66666.664
DP Degrees = 66666.66666666669
Error = 0.0026041666860692203
Error (inches) @ 10" diam = 0.08181230790121585
At index of 270 degrees:
SP Degrees = 75000.0
DP Degrees = 75000.00000000001
Error = 1.4551915228366852E-11
Error (inches) @ 10" diam = 4.571618919726461E-10
At index of 300 degrees:
SP Degrees = 83333.33
DP Degrees = 83333.33333333334
Error = 0.00520833334303461
Error (inches) @ 10" diam = 0.16362461488810792
At index of 330 degrees:
SP Degrees = 91666.664
DP Degrees = 91666.66666666669
Error = 0.0026041666860692203
Error (inches) @ 10" diam = 0.08181230790121585
But wait... it gets better. Over breakfast, I remembered something I read in the integrator's manual and it occurred to me that Linux CNC can also express ANGULAR machine units in "Gradians" (400 per full turn), so I can eliminate this error altogether by expressing encoder counts in Gradians instead of degrees, and use 250 counts per gradian. This way, the error is eliminated, and since machine units are independent of GCode values, I can still express GCode in degrees.
I believe with this, I can rotate my table in one direction forever and no error will accumulate. I just hope the Linux CNC team doesn't deprecate Gradians... ever.
Torin...
Last edit: 31 Dec 2012 01:15 by torinwalker.
Please Log in or Create an account to join the conversation.
31 Dec 2012 00:40 #28187
by PCW
Replied by PCW on topic INDEX PULSE, INPUT SCALE, and Cumulative Error
The error is _not_ accumulated per pulse count, the raw (integer) encoder count is multiplied
by the inverse of the scale factor in the encoder component.
The internal scaling math done in double precision but accuracy is limited to about
7 decimal places (24 bits) due to the scale factor being a single precision
IEEE754 floating point number.
So even using degrees will not cause a significant error unless you have a larger (>100) number of turns
by the inverse of the scale factor in the encoder component.
The internal scaling math done in double precision but accuracy is limited to about
7 decimal places (24 bits) due to the scale factor being a single precision
IEEE754 floating point number.
So even using degrees will not cause a significant error unless you have a larger (>100) number of turns
Please Log in or Create an account to join the conversation.
- torinwalker
- Offline
- New Member
Less
More
- Posts: 4
- Thank you received: 0
31 Dec 2012 01:21 - 31 Dec 2012 06:29 #28191
by torinwalker
Replied by torinwalker on topic INDEX PULSE, INPUT SCALE, and Cumulative Error
PCW,
Ah... I get it now. I was thinking in terms of calculating the pulse count to arrive at a distance to travel, not as a means of determining distance already traveled from home/index
Plugging the encoder counts into excel, deriving the nearest whole encoder count, I get the following error then:
(I had to edit this - I forgot to divide by 360 degrees)
This turns out to be not too bad after all.
PCM, thanks for correcting my understanding.
Torin...
Ah... I get it now. I was thinking in terms of calculating the pulse count to arrive at a distance to travel, not as a means of determining distance already traveled from home/index
Plugging the encoder counts into excel, deriving the nearest whole encoder count, I get the following error then:
Degrees Closest Actual Degrees Distance
Integer Degrees Error Error
Pulse (10" diam)
30 8333 29.99880084 0.001199 0.000105
60 16667 60.00120168 -0.001202 -0.000105
90 25000 90.00000252 -0.000003 0.000000
120 33333 119.9988034 0.001197 0.000104
150 41667 150.0012042 -0.001204 -0.000105
180 50000 180.000005 -0.000005 0.000000
210 58333 209.9988059 0.001194 0.000104
240 66667 240.0012067 -0.001207 -0.000105
270 75000 270.0000076 -0.000008 -0.000001
300 83333 299.9988084 0.001192 0.000104
330 91667 330.0012092 -0.001209 -0.000106
(I had to edit this - I forgot to divide by 360 degrees)
This turns out to be not too bad after all.
PCM, thanks for correcting my understanding.
Torin...
Last edit: 31 Dec 2012 06:29 by torinwalker. Reason: Corrected some calculation errors
Please Log in or Create an account to join the conversation.
Time to create page: 0.083 seconds