LakeMaps / boat

Lake Maps' boat control software
Open Software License 3.0
3 stars 0 forks source link

Update GPS data to include units, 🎬 #80

Closed whymarrh closed 7 years ago

whymarrh commented 7 years ago

Closes #73 (this PR supersedes that one) Closes #77 (this PR supersedes that one too) Closes #53* Closes #54†

This PR updates the representations of the GPS data to include units. Previously we were storing "unitless" numbers and specifying the types implicitly (e.g. comments and documentation) and now we are moving to Quantitys with Units. This API (similar to #73 and #77, the first two attempts) is heavily inspired by the JSR 363 specification but I've tried my darnedest to have an API that can be checked at compile time which unfortunately requires a slightly different API. I do think it would be possible to expose a javax.measure wrapper for the types introduced here so it's not completely pooh-poohing the standard.

The two main types in the API are Unit and Quantity (again, similar to JSR 363). Unit represents a hierarchy of units. Quantity represents a pairing of a value with an unit. All quantity values are double-precision floating-point format numbers (i.e. double).

Compile-time safety

Code using the API should fail to compile if it's wrong:

val oneInch = Quantity(1, Inch)
val oneMetre = Quantity(1, Metre)
val result = oneMetre + oneInch // This does not compile

An explicit version that compiles:

val oneInch = Quantity(1, Inch)
val oneMetre = Quantity(1, Metre)
val result = oneMetre + oneInch.convert(Metre) // Works

(I haven't actually implemented an Inch, the above is for demonstration purposes only.)

What's the catch?

Using extension functions is kinda gross I guess.


* I've migrated the position values from dddmm.mmmm and ddmm.mmmm to decimal degrees[1].

† This PR actually does convert the speed to m/s 🚀 🎆 👏 🎉 (unlike #73 and #77).

1. Which was already completed in 604710d725bc1275defb117895121dfba989f0d9 but I've taken the opportunity to move it into the GPS subproject properly. (As a side note to a side note: I was previously of the opinion that the GPS subproject should try to represent the GPS data in an OO way that doesn't transform the data. I no longer feel that way and think it's fine if the GPS project does sane conversions so long as we still have access to the underlying NMEA sentence that produced a value.)