In my project, I need to simulate a spacecraft reentering the atmosphere. I have an event detector to detect the actual collision with the Earth ellipsoid and stop the propagation then.
I need to go all the way to the actual surface to be able to compute a somewhat relevant uncertainty ellipsoid.
The problem is that if the solar radiation pressure is enabled, an error shows up whenever the spacecraft is below the surface (inside the ellipsoid).
The thing is, the way event detectors work during a propagation, is that we MUST go beyond the event, see that its g() function switched sign, and then use dichotomy (or Brent, TOMS748, or any similar root-finding technique) to solve more precisely for the time of the event.
We therefore MUST go inside the ellipsoid, even if it is just 1 millimeter, to end the propagation gracefully.
In this state, it seems impossible to enable SRP AND propagate until the spacecraft touches the ground.
Note that I have a single numerical propagator that simulates many different orbital phases, where SRP is a significant factor, all the way to touchdown after a controlled reentry burn.
Unless the SRP can be turned off in the middle of the propagation using an event, it seems impossible to solve this problem in the current state of Orekit.
What I would suggest gets changed in a future version of Orekit, is two things :
instead of popping a critical error that ruins the entire propagation, a warning message be written in stderr in the likes of “hey watch out, your satellite is below ground, check that it’s coherent with what you are trying to achieve, but alright mate, I’ll continue normally for now, just be careful”
it must return Vector3D.ZERO for the acceleration due to sun radiation pressure when the point is inside the ellipsoid.
Why this makes sense (in my opinion) :
Being underground is analoguous to being in the Earth’s shadow cone = no sunlight
It enables simple reentry computations (the specific example described above)
It is less restrictive to the user
It still allows the user to be notified that maybe something is wrong, but isn’t necessarily wrong.
It allows the propagation to run its course and exit gracefully (a.k.a does not break the rest of the logic around the propagation).
It prevents the user from having to put try-catch blocks everywhere.
Try-catch does not fix entirely my “detect when hitting the Earth” problem
Real-life analogy : If I go in a cave, I don’t receieve any sunlight, but it does not break the fabric of the universe to do so. If I measure the solar radiation with something like a Crookes radiometer, it will simply not turn, because no light reaches it (because we are underground in a cave).
PS : I use Orekit 12.2 in my project, which is not the latest version.
The thing is that it’s far from being the only exception that can natively interrupt a propagation. Needing a smaller step for an adaptive integrator and reaching a hyperbolic orbit are other examples that I encounter more often than not. So at this point it’s pretty much a philosophy in the library and if we decide to change one, we’d need to change 'em all. Personally I’m not against it, however I think the behaviour should then be to stop the propagation (as if an event has done it) rather than just print warnings, since there’s no native logging system with Orekit.
Anyhow, I believe there is an easy workaround in your particular case. You should create a new ForceModel wrapping the native one and catching the exception in the method acceleration. With Orekit 13, you can do that very easily with the interface ForceModelModifier. And I assume you’re using SolarRadiationPressure? This is the most complex model, but there are other simpler ones (cylindrical shadow) and I’m not sure they’ll crash like this.
For what it’s worth, do you have a custom atmospheric density model or something ? If not I don’t recommend propagating until 0km altitude, the result would be physically wrong anyway.
When computing re-entry, we usually stop computation way above ellipsoid. I have seen 100km used as a stop criterion. There are several reasons for this, the behavior of solar radiation pressure could be just one additional reason to add to the list. The fact is that using space flight dynamics equations for atmospheric flight is really pushing the models too far. In your case, solar radiation pressure at low altitudes is probably moot considering atmospheric drag is several orders of magnitude above, and most importantly it is very difficult to predict. So once you have reached 100km altitude (or 80 km, or whatever), you just enter uncertainty zone, where everything can happen. The spacecraft will break up into several pieces with different area to mass ratios, tumbling attitude, some parts will vaporize while the heavy ones (structural pieces, motors, batteries) will reach ground. I am not sure the equations we provide are suited for this. Breakup models are a different field on its own and we don’t provide it.
This is an interesting work-around that I may look further into.
I am using Orekit 12.2 and it’s probably not going to change in the short term.
I’m only using the base Orekit MSIS2000 model for the atmosphere, nothing custom.
I agree that stopping the simulation at this point makes sense. I would generally speaking prefer this behavior on all the exceptions that can occur during a propagation, so that at least we can get the generated trajectory. An error message can also be printed in stderr to leave a trace of what’s happening.
Lastly, I’m aware that propagating a single invincible, unbreakable object down to 0 km altitude is not really realistic at all, but for my use case I only need a rough approximation of where the satellite might hit the surface (along with a simple calculation for an uncertainty ellipse).