Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace OrbitalState with ANISE::Orbit #33

Merged
merged 27 commits into from
Aug 18, 2024
Merged

Replace OrbitalState with ANISE::Orbit #33

merged 27 commits into from
Aug 18, 2024

Conversation

gwbres
Copy link
Contributor

@gwbres gwbres commented Aug 13, 2024

Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
@gwbres
Copy link
Contributor Author

gwbres commented Aug 14, 2024

@ChristopherRabotin,

Looking good, I just need to conclude all replacement, double check the [m]/[km] unit. I hope to conclude this today

There are only 3 sensitive points:

  • we need to rotate Orbit in two separate places in this whole process. For that, I have the Rot3 matrix.
  • when we only have resolved once, velocity is not known. Therefore all atitude filters or related calculations need to be bypassed (that's what I previously coded). I intend to use with_velocity_km_s, see [update_velocity] in src/solver.rs
  • Orbit seems to lack a feature that we could use in the long term, but that is purely a detail.
    The user may want to navigate in Fixed Altitude. This reduce the need to gather only 2 SV in sight.
    Depending on user specs, I modify the final solutions. For example, in TimeOnly mode, I make sure all orbital attitudes are null, to avoid non sense and emphasize how we navigated. It could be could if Orbit had a set_height_km or with_height_km (height_km() mirror), so we emphasize that the user specs are in used. But I have no idea how complex it can be

@gwbres
Copy link
Contributor Author

gwbres commented Aug 14, 2024

I think I will use the rotation that discards velocities at all times.
I always manually set the velocity, by derivating the previous solution (Past Orbit) myself.
I also manually set it after the rotations have been applied, so that works

Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
src/candidate.rs Show resolved Hide resolved
-16029029.85873581 / 1.0E3,
-5905924.153143198 / 1.0E3,
Epoch::from_str("2020-06-20T00:00:00 GPST").unwrap(),
EARTH_J2000, //wrong ! wgs84
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using the ITRF93 frame or IAU_EARTH_FRAME here. In one application that I have, we use the ITRF93 frame and it matches with some internal verification.

Copy link
Contributor Author

@gwbres gwbres Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two key structures to my apps, are Solver within this very crate, and QcContext in the rinex libs.
Both of them now have an Almanac and a Frame defintion. The frame needs to be ECEF in these kind of applications. The almanac is built with until_2035() and it retrieves an ITRF93 frame, because you told me this in previous conversations.

Is it safe to use ITRF93 anytime I need an ECEF ?
What is the difference between IAU and all the other ECEF (ITRF93, EARTH_J2000..) ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, actually, the ITRF93 is not defined with until_2035: NASA JPL updates this frame daily. It's the high precision frame that includes all of the latest Earth orientation parameters, and it is an Earth centered Earth fixed frame. The IAU_EARTH_FRAME is also an ECEF frame, which is less precise than the ITRF93. It is provided by the International Astronomy Union, and is within a few millidegrees of the ITRF93 frame. The Earth J2000 frame however is not an Earth fixed frame, and is instead an inertial frame (whose acceleration with respect to the stars is zero).

Copy link
Contributor Author

@gwbres gwbres Aug 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you very much for taking the time to explain once again.
It is natural to require remote access for ITRF models, but then I don't understand why the current form seems to work.

  1. ANISE should throw an error instead, when I try to obtain the ITRF93 model while the Almanac was built with until_2035. Are we sure what's happening inside your core is what you intend ? I'm able to express orbits and navigate
  2. I use EARTH_J2000 lazily, because I have seen you use it in several places. For example when obtaining unit vectors (r_hat) between Earth and Sun, we used EARTH_J2000 and SUN_J2000. The bottom line I guess, is I have no idea if some operations may require inertial frames while others may require fixed frames.

In my mind, at least that's what I foresaw, I'd like to propose an interface for either "autonomous" deployment (no remote access) limited to basic ECEF models, and "cloud" deployment, where the best models can be used. So we can always deploy and always work

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ANISE will throw an error if you try to perform any rotation or translation from the ITRF93 frame to any other frame and the ITRF93 frame is not loaded. Let me know if that isn't the case, because I would be very surprised (and it would be a bug).

In astrodynamics, we tend to use J2000 or the International Celestial Reference Frame (ICRF) which are both inertial frame, which is why it's used everywhere in the documentation of the ANISE or Nyx. You want to use inertial frames when you're concerned with the position of your vehicle with respect to the stars or planets. When you're concerned with the latitude or longitude, you need to express the state of the spacecraft with respect to the celestial object for which you're computing that latitude and longitude. That's because the latitude of your vehicle depends on the exact orientation of the Earth (for example) at a given time. In other words, whenever you need information about a spacecraft that is relative to the orientation of a celestial object with respect to the stars, you need to use the body fixed frame.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will have to save this answer somewhere 😄

Ok so because I'm not 100% finished here and the rotations are not applied yet (-> small 10m errors), I have not run into the problem (in other words, all the calculations I do are feasible).
I am about to implement the rotations, I will just leave it as is to see if we indeed fall into the coordinates system error.

I will try to "rework" my coordinates system definition at the same time, but I'm not sure how to do that yet

src/tests/mod.rs Show resolved Hide resolved
@ChristopherRabotin
Copy link
Contributor

Out of curiosity, are the results just as good with these changes as they were before?

Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
@gwbres
Copy link
Contributor Author

gwbres commented Aug 15, 2024

Out of curiosity, are the results just as good with these changes as they were before?

I have finished the conversion, and it does not work. The Bancroft solver unit test is in failure, with millions on meter errors.
The bancroft solver is the simplistic solver that we use on first iteration.

It only needs

  • 4 pseudo range measurement ([m]): this has not changed, that I know the exact values this test
  • 4 onboard clock corrections ([dt]): this has not changed, that I know the exact values for this test
  • 4 SV orbital state ([Orbit]) for which I know x, y, z exactly for this test.
    I build the Orbit::from_position(x, y, z, t, Frame) where t is the Epoch of sampling. Modifying t does not impact, you can see that I used to set Epoch::default() for this test. Modifying the Frame does not impact either, I even tried SUN_J2000. So basically I have no idea what is happening. It's like Orbit::from_position is said to expect km, but interprates m internally.

Signed-off-by: Guillaume W. Bres <[email protected]>
@ChristopherRabotin
Copy link
Contributor

Quelle dommage... Je peux passer un peu de temps de week-end à essayer de comprendre pourquoi le premier solver ne fonctionne pas. C'est assez surprenant. Est-ce que ça pourrait être une erreur d'unité ?

Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
@gwbres
Copy link
Contributor Author

gwbres commented Aug 16, 2024

Est-ce que ça pourrait être une erreur d'unité ?

Hoestly the code has not changed much, and i double checked everything 5 times.
I convert everything to km for your API, and convert everything back to meters.
It's almost like either x/y/z are swapped or a 1.0E3 factor should be removed.
Does orbit::from_position accept negative coordinates ? all my coordinates are expressed as ECEF

@ChristopherRabotin
Copy link
Contributor

Yes, the from_position initializer accepts negative positions. I can have a closer look over the weekend.

Signed-off-by: Guillaume W. Bres <[email protected]>
@gwbres
Copy link
Contributor Author

gwbres commented Aug 17, 2024

I decided to continue and adapt rinex-cli to this and it passed. So if showed that there was an error in the test "setup".
There was an index error somewhere (pointless). It's too much for me & myself to manage, especially considering I'm focused on topics that are very far from this (RTK, PPP. etc...).

Now the solver runs into more problematic issues.
The SV orbital state is expressed at transmission time, while ground states are expressed at reception time.
Because Epoch were not part of the Orbital state calculations, it used to pass.
Your API has internal verifications that prohibits all these calculations. Mainly, I need the geodetic and elevation/azimuth/slant range all the time.

This does not simplify things.
I presume this hapens (the Epoch consideration) because you manage velocities correctly (up to 6x6 correct rotations).

Note that I'm also trying to come up with a Self::build_almanac infaillible method, that could leave options to retrieve the highest precision kernels, like you told me a couple of days ago

Signed-off-by: Guillaume W. Bres <[email protected]>
@gwbres
Copy link
Contributor Author

gwbres commented Aug 17, 2024

Also, could you please explain what is the new method to rotate an Orbit ?
Considering that my rotations do not require frame conversion (to_frame = from_frame = same frame),
and to my understanding, I can handle velocities "externally", that means I define velocity myself, with with_velocity_km_s and am not interested in rotations that could apply to the 6x6 matrix. But yet, I'm not 100% that is the best option and it might be possible, in the future, that it is better for us that nyx handles all terms itself

Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
@gwbres
Copy link
Contributor Author

gwbres commented Aug 18, 2024

Hello, the upgrade is completed.

It as not been easy once again... I think I will pause all of these upgrades.
The only topic I can see that should be upgraded in the near future, is to replace "my" implementation of the Kalman filter by yours, which is obviously more thourough: #24

The most important aspect of this PR is that we have a correct ITRF93 frame ecosystem now.

Now that I'm getting familiar with ANISE, I might be in better position to tacke the kepler problem.
But I feel I have lost too much time on this, so we'll see later.. I have too many topics that need more attention than this.

Signed-off-by: Guillaume W. Bres <[email protected]>
Signed-off-by: Guillaume W. Bres <[email protected]>
@gwbres gwbres merged commit b9b0686 into main Aug 18, 2024
1 check passed
@gwbres gwbres deleted the orbit branch August 18, 2024 10:36
@ChristopherRabotin
Copy link
Contributor

Good work, that was a lot! I think that the filter in Nyx could be useful, but I need to add the batch least squares for some of my work as well, and for this I'll take inspiration for your implementation.

@gwbres
Copy link
Contributor Author

gwbres commented Aug 18, 2024

I simply copied what ESA explains p142 and 143, KF being the next paragraph

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants