[Ovmsdev] SIM808/SIM908 GPS accuracy
cheesemanedward at gmail.com
Tue Feb 7 10:00:04 HKT 2017
Float gets slightly worse when it gets multiplied by 3600*2048.
180*3600*2048 = 1327104000, represented in IEEE754 as 0x4E9E3400. 0x4E9E33FF is 1327103872, 128 less, giving a resolution of 1.9meters
Every calculation with float can cause 1m order errors. Having resolution in the centimetre range puts calculation error well under the inaccuracy of the GPS.
This is still only critical if you need to know which lane you are in :)
Oh, good time to point out that C18 actually doesn’t follow IEEE754 exactly: rather than the usual [sign, exponent, fraction] notation, it swaps the bit order to [exponent, sign, fraction].
I can kind of see why - with the 8bit processor, having the 8 bit exponent aligned with the MSbyte could save a number of bit shift operations among many other byte aligned actions.
Sign becomes the MSB of the three remaining bytes.
I wonder if this is the source of error in the original atof()?
> On 7/02/2017, at 12:47 PM, Edward Cheeseman wrote:
> So, while I’ve dabbled in this stuff I didn’t get a PhD in its analysis! Lets give it a go: (please point out any errors found)
> OVMS native format:
> Appears to be signed seconds * 2048. I haven’t delved into documentation here, just what I saw in the gps2latlon().
> Circumference at Equator is worst case. So a native unit represents a maximum of 40,075,017m / ( 360d * 60m * 60s *2048) = 15mm.
> Certainly enough, and just fits into 32bit at 31.3bits. Looks like someone designed it that way.
> Floating point number accuracy:
> Worst case accuracy is at 180degrees. IEEE754 binary32 is: 0x43340000 -> +(s) 0x86(e) 0x340000(f). One less is 0x4333FFFF -> 179.999985 degrees.
> Worst case resolution is 0.000015 degrees or 40,075,017(m) / 360(d) * 0.000015(d) = 1.670m
> By implied bit, I gather this relates to the fact that at close to 0degrees, the precision would be much greater. I live near 180degrees so this has less relevance to me than say someone in the UK.
> SIM908 reports DDDMM.MMMMMM, a resolution of 0.0000000167 degrees or 1.9mm
> SIM808 reports DDD.DDDDDD, a resolution of 0.000001 degrees or 111mm
> Clearly going through floating point is throwing away some information, but there is no way we can use all the resolution reported by the SIM908.
> Is this worth the reduction in code readability (and maintainability)?
> is the integer math any better? On the SIM908 version, the worst I’ve seen is 0.00000025deg error -> 28mm. That’s not to say I’ve done much testing by any means.
> Adopting the change probably comes down to other considerations than resolution.
>> On 7/02/2017, at 10:53 AM, HONDA S-2000 wrote:
>> Hi Edward,
>> 32-bit float does indeed store 23 bits of significand, but there is an additional implicit bit, making the total 24 bits. When you also consider the separate sign bit, 32-bit float has as much precision as a 25-bit signed fixed-point integer.
>> Adjusting your math without any other adjustments, that would imply a resolution of 1.2 meters and perhaps 2.5 meters unrounded.
>> However, I don't quite follow your calculations since floating point always carries a certain number of significant digits, regardless of the exponent. Can you show why the circumference divided by a fixed precision would reflect the ability and precision of a floating point calculation? It's a snowy day here, and I don't have my floating point thinking cap...
More information about the OvmsDev