rtk-rs / gnss-rtk

Precise Point Positioning (PPP) and Real Time Kinematics (RTK) in Rust
Mozilla Public License 2.0
31 stars 9 forks source link

Improve CI/CD #27

Open gwbres opened 3 months ago

gwbres commented 3 months ago

Testing navigation under CI / CD

The solver is currently not fully tested under CI / CD. The main equation and functions are not. Some preliminary work have been introduced to correct that, but it requires more work.

@ChristopherRabotin, could you tell me a little more about Kani that you use in Hifitime ? Is that an open solution ? The problem in GNSS-RTK being (once we have a solution to provide input data) that it has several options. For example, let say you want to validate the PPP solver, you need to at least verify it works with all major options: 3 navigation methods and 3 navigation modes, that's 9 combination. Could Kani help in building effecient and smart tests ?

ChristopherRabotin commented 3 months ago

I don't remember the testing philosophy of your code at the moment (à froid). In testing, I typically distinguish unit testing and integration testing. More recently, I've started adding the examples to the test suite. I aim to have 80% coverage of the code or more through both unit testing (that live in the src folder) and integration testing (that live in the tests folder). The integration testing is more of a use case demo : if I user needed to do X, how would they do it? Then set up the whole problem there. I've also found the rstest crate to be very helpful because you can set up test fixtures so that any number of tests can reuse the same initialization code for example (I use that to not repeat the downloading of the almanac).

Kani is useful for finding bugs like arithmetic overflows or relatively simple "round trip" errors (like initialize a duration from its nanoseconds and then check that grabbing the nanoseconds out matches exactly the original input). I don't think that would be helpful in gnss-rtk because Kani is too low level.

gwbres commented 3 months ago

Kani is useful for finding bugs like arithmetic overflows or relatively simple "round trip" errors (like initialize a duration from its nanoseconds and then check that grabbing the nanoseconds out matches exactly the original input)

Thank you very much, yeah that does not really apply here

and integration testing (that live in the tests folder). The integration testing is more of a use case demo : if I user needed to do X, how would they do it? Then set up the whole problem there. I've also found the rstest crate to be very

testing the solver falls within integration tests. We need to simulate an application that uses that piece of code. Providing the test input is tedious but not complex. I would say the complexity relies in testing all possible configurations, and testing correctly. Results are floating point numbers, therefore you have the rounding issue. We also have to define what is the minimum expected performance for a given configuration (complex). In most cases we're testing the navigation filter, which improves itself the further you average. Let's say a typical starting point (in static application) is about 1m error. The solver will probably reach 0.01m in about 10E3 averages in basic setup. Ideally we want to be able to test up to that point, with the notion of performance improvements, as we iterate. PPP (ultimate strategy) reduces the averaging time, so ideally you also want to verify that as well

ChristopherRabotin commented 3 months ago

I have a similar use case with the orbit determination tests. In these, I test that the norm of the difference between the expected solution and the computed solution is decently close (eg less than 5 meters).

gwbres commented 3 months ago

Following your indications right now, I'm simply augmenting the existing examples and integrate them to CI/CD.

All I need is a text parser so we can provide input data easily. That data will come from well known RINEX filesets, but that is not important. All is important is to master that data and what we can expect from it. It also does not matter which constellation(s) it comes from, we only need a single dataset.

Actually, to be complete we will want two datasets. One sampled by a static rover, one sampled by a moving rover, so we can test both scenarios.

I have never stimulated GNSS-RTK with dynamic data, for the simple reason that I only work with Open RINEX Data, and those are provided by reference geodetic sites that do not move by definition. Those are great and the only option to test PPP surveying, which is the most demanding task by definition and that we have pretty much tackled.

It is normal to obtain "poorer" results with moving rovers. But IMO harder to tester as well. When the navigation filter is set to Kalman (99% of applications), it requires full mastery of the Kalman filter specifications. More precisely, it requires complexifing the Phi Matrix which I only implemented as unitary diagonal at the moment. Unitary diagonal is not a good form because you typically want to index those values on the std deviation of the errors. In navigation, we're talking about x, y, z, and local clock error (to constellation), and possibly others, since I'm not quite familiar with KF in navigation yet. KF is anyways a topic of its own, that can already be improved even for static applications and if off topic here. I also have a strategy to approach the topic of KF filter, which I want to discuss here

We will have two examples