A simpler problem (hopefully) - Integrating predicted trajectory

HarvesteR

Member
Joined
Apr 22, 2008
Messages
386
Reaction score
15
Points
18
Hello once again!

My last endeavour at predicting an orbital trajectory proved to be way over my head... so I'm going by a simpler approach...

I've decided to step ahead of the simulation, and predict the next position over a few iterations, in the hope that this way I'll get to see something that looks at least remotely similar to Orbiter's Orbit MFD.

So, this method seems to work better than the last, but there is a problem...

My orbit prediction seems to be slightly off, so at the end of 256 iterations, that tiny error amounts to a major inaccuracy... see here:

OrbitPredictionGoneBad.png


As you can see, the predicted trajectory is spiralling down... obviously this is not what actually happens if you play out the orbit... gradually, as the ship advances, the error margin for any particular point lessens (as it takes less prediction iterations to get there)

So, my theory about what's wrong here is that I'm moving my position forward along it's velocity vector, and grabbing the gravitational vector for the predicted position... then I add this new gravity vector into the last calculated velocity, and move the last known position along the new velocity...

the cause is the gravitational sampling... It's getting an outdated velocity, so the acceleration is always one frame late... the problem is that to calculate the correct gravitational pull, I'd have to add the current velocity into the last known position, which is impossible since to know the current velocity, I have to know the current gravitation...

Here's some code to help understand the matter:

Code:
        Vector3 pos = FlightState.position;
        Vector3 vel = FlightState.velocity;

        Vector3 lastPos = pos;
        Vector3 lastVel = vel;

        for (int i = 0; i < 256; i++)
        {
            Vector3 gravity = Gravitation.getGeeForceAtPosition(lastPos + lastVel);
            Vector3 currVel = lastVel + gravity;

            Vector3 currPos = lastPos + currVel;
            points[i] = currPos;

            lastPos = currPos;
            lastVel = currVel;
        }

The ship's initial position comes from the static FlightState properties... then I loop forward in advance of the simulation.

Currently there are no other forces acting on the ship... just gravity (as long as the engines are off... which they are).. there is no atmospheric drag yet, and the planet is perfectly spherical

The Gravitation.getGeeForceAtPosition function returns the gravity vector at the sampled position... this position is where the problem is at.

The points array is just the list of known positions for the plot (it's declared somewhere else and pretty much irrelevant to the matter)

Any help right now would be immensely appreciated :thumbup:

Cheers
 
Last edited:

RisingFury

OBSP developer
Addon Developer
Joined
Aug 15, 2008
Messages
6,427
Reaction score
492
Points
173
Location
Among bits and Bytes...
Use Runge-Kutta instead. You'll find it documented among the tech notes in Orbiter folder.

Also:

Vector3 currVel = lastVel + gravity;
Vector3 currPos = lastPos + currVel;

s = s0 + v * t
v = v0 + a * t
So, unless your unit of time equals 1, you're adding together apples and oranges and asking how many bannanas you have...
 

HarvesteR

Member
Joined
Apr 22, 2008
Messages
386
Reaction score
15
Points
18
I think I got it!!

I got confused with the order of things... I guess I tried to step ahead of myself too ;)

Here's how it looks now!

OrbitPredictionNowWorks.png

The orbit is completely stable now!! no more spiralling... since there's no drag, if you set your orbit to hit the surface at a specific point, you're quite likely to hit it (as long as you don't touch any more controls later ;) ).

Here's the new integration code:
Code:
        Vector3 pos = FlightState.position;
        Vector3 vel = FlightState.velocity;

        Vector3 currPos = pos;
        Vector3 currVel = vel;

        for (int i = 0; i < sampleCount; i++)
        {
            Vector3 gravity = Gravitation.getGeeForceAtPosition(currPos);

            Vector3 nextVel = currVel + gravity;
            Vector3 nextPos = currPos + nextVel;
            
            points[i] = currPos;


            currPos = nextPos;
            currVel = nextVel;
        }

Oh, didn't see your reply! I haven't implemented a configurable delta time yet... right now I'm just simulating stepping ahead frame by frame... (so yeah, my unit of time was equal one so far...)

Next comes just that.


Alright!! one step further with my game now!!

EDIT: After playing with it for a while, I see now that there is some light variation over time... I think it might be related to rotation... since the position is taken from the command capsule's pivot point, and not the ship's actual center of mass... with a rotation fast enough, you can see the orbit wobble quite a bit...

Anyhow, this is accurate enough for now... I was able to bombard the launch pad with the ship on a ballistic trajectory, from over 90 degrees away... I crashed within 100m of target, and only needed to make small corrections :)

Cheers
 
Last edited:

RisingFury

OBSP developer
Addon Developer
Joined
Aug 15, 2008
Messages
6,427
Reaction score
492
Points
173
Location
Among bits and Bytes...
The simple integration you set up right now is stable for orbits with a decently high radius. My guess is that the orbit will spiral in or out if you decrease the radius.
 

HarvesteR

Member
Joined
Apr 22, 2008
Messages
386
Reaction score
15
Points
18
Hmm it might be... but at the moment my test planet is only 10km in radius, with 1G at surface level, and it's working well...

Later on the planet will be a lot larger, so I'm hoping it will prove more accurate over larger scales, since gravitational pull will vary a lot less between steps.

If later on I find that it's too unreliable, I'll probably switch to Runge-Kutta.

this integration isn't controlling the ship's position... that is being handled by PhysX... this integrator merely serves to step ahead of the actual physics, so I can plot out an orbit.

My sim isn't as realistic as Orbiter... there will be some shortcuts and compromises from reality. (most likely I will hard-code any orbits that should be stable, so that moons don't start falling from the sky due to floating point errors)

Cheers

EDIT: Just to follow up, today I restructured the gravitation sampler function to incorporate multiple gravity sources... then I added a small moon just to test it out :)
You were right, on smaller orbits the prediction does spiral a bit, but that I think is due to the periapsis shifting around due to the influence of the other bodies...

In any case, it's quite accurate enough for my needs... I put my craft on a crash course with the launch pad, from a hundred km away (at the moon... don't laugh at my placeholder scales), and hit it dead on, with no mid-course corrections.

Cheers again!
 
Last edited:

HarvesteR

Member
Joined
Apr 22, 2008
Messages
386
Reaction score
15
Points
18
Hmm... I was reading up on Runge-Kutta integration today, and realised that this thing I got here isn't Euler integration (by definition) anymore...

Euler integration plots ahead given an initial position and constant acceleration... in this case, this would result in my orbit stretching out at a tangent all the time (as was the case with my first attempt)...

What this has become is closer to a 1st order RK integration than Euler, since I'm grabbing a new acceleration and acceleration change (aka a derivative) at each step...

for this to become a full-blown RK4 integration, all I need is to step forward 4 times, and do the weighted sums thing, to get a more precise step.

This was a good read today. I had no idea RK was so simple... I had always thought of it as a complicated monster... I might just go on ahead and make the switch :D

Cheers
 
Last edited:
Top