feat: implement to_wgs84_extended#85
Conversation
6539462 to
09a1b09
Compare
Implement a closed-form ECEF to WGS84 algorithm based on the following paper: https://link.springer.com/article/10.1007/s00190-024-01821-w by Quan&Zhang (2024). This was proposed in helsing-ai#65, as this algorithm is newer and does not have the same height limitations as the current implementation. The paper states accurate calculations between -6.33e6m and 1e10m, much better than the current -10_000m to 50_000m. A trade off is a ~57% runtime increase on my machine (47.4ns vs 74.6ns). This commit also introduces a benchmark to test both implementations against each other. There is an optimization in the paper (Appendix 1 Step 2) that is currently not implemented as it relies on a threshold describing the distance of the point to the astroid. This threshold is only defined as "near" by the paper. Testing a naive threshold improved the performance by ~13.5% which brought the increase down to ~38.9% (47.4ns vs 65.8ns). As I do not know at which threshold the optimization can be used, it is not used as of now.
09a1b09 to
31fcaba
Compare
jonhoo
left a comment
There was a problem hiding this comment.
Thanks for taking this on!
| let h = | ||
| (w * i + n - SEMI_MAJOR_AXIS * FloatMath::sqrt(FloatMath::powi(i, 2) + n_c)) / s; |
There was a problem hiding this comment.
Since we know (?) that e^2 != 0 for the Earth, I believe we can use the "accelerated" formula for h here.
There was a problem hiding this comment.
Oh, you are totally right...
Even if this library should get ported to other bodies in the future, it should still hold in reality.
There was a problem hiding this comment.
Well, this is a little awkward. With the "optimization" the performance regresses on my machine. 🤔
I'll put both versions in the commit for now and I'd appreciate, if you could test both versions on your machine and see if the behavior is the same for you.
There was a problem hiding this comment.
Hah, that's odd. And presumably they produce the same results?
jpteb
left a comment
There was a problem hiding this comment.
Thank you for the quick review!
The resolved comments will be fixed in the following commit. Otherwise there are still some questions open.
| #[doc(alias = "l")] | ||
| const L: f64 = (SEMI_MAJOR_AXIS * SEMI_MAJOR_AXIS) * (ECCENTRICITY_SQ * ECCENTRICITY_SQ); | ||
| #[doc(alias = "6*l")] | ||
| const SIX_L: f64 = 6.0 * L; |
There was a problem hiding this comment.
You're right, that "optimization" is too eager
| #[doc(alias = "l")] | ||
| const L: f64 = (SEMI_MAJOR_AXIS * SEMI_MAJOR_AXIS) * (ECCENTRICITY_SQ * ECCENTRICITY_SQ); | ||
| #[doc(alias = "6*l")] | ||
| const SIX_L: f64 = 6.0 * L; |
There was a problem hiding this comment.
Also a style question, I see that you used n. for integral values, would you prefer, if I changed my code to do the same?
| let h = | ||
| (w * i + n - SEMI_MAJOR_AXIS * FloatMath::sqrt(FloatMath::powi(i, 2) + n_c)) / s; |
There was a problem hiding this comment.
Well, this is a little awkward. With the "optimization" the performance regresses on my machine. 🤔
I'll put both versions in the commit for now and I'd appreciate, if you could test both versions on your machine and see if the behavior is the same for you.
jpteb
left a comment
There was a problem hiding this comment.
I think this should be it.
Comments I wasn't sure about are unresolved, so you can decide on them 👍🏼
|
I have received an answer from the author of the paper! Secondly, on the calculation of Thinking about this more, in practice we do not care about the values close to the astroid at all. The astroid extends 42700m on the semi-major axis and 42841m on the semi-minor axis from the origin. So it is a pretty small area inside or close to Earth's core. See Figure 1 of https://link.springer.com/article/10.1007/s00190-010-0419-x |
jonhoo
left a comment
There was a problem hiding this comment.
This looks great now, thank you! And exciting that you heard back from the authors 🎉
|
After thinking some more about this, I actually think I'd like to make |
|
Releasing in #94 🎉 |
|
It was a pleasure! Thank you for the great review, finishing up the work and merging it! |
Implement a closed-form ECEF to WGS84 algorithm based on the following paper: https://link.springer.com/article/10.1007/s00190-024-01821-w by Quan&Zhang (2024).
This was proposed in #65, as this algorithm is newer and does not have the same height limitations as the current implementation. The paper states accurate calculations between -6.33e6 m and 1e10 m, much better than the current -10000 m to 50000 m. A trade off is a ~57% runtime increase on my machine (47.4ns vs 74.6ns). This PR also introduces a benchmark to test both implementations against each other. There is an optimization in the paper (Appendix 1 Step 2) that is currently not implemented as it relies on a threshold describing the distance of the point to the astroid. This threshold is only defined as "near" by the paper. Testing a naive threshold improved the performance by ~13.5% which brought the increase down to ~38.9% (47.4ns vs 65.8ns). As I do not know at which threshold the optimization can be used, it is not used as of now.
Below is a violin plot created by Criterion: