How does Spaceflight simulator predict flight-paths?
Asked Answered
D

2

1

I am trying to make a game with Unity that uses rockets that are in orbit and can transition to different planets, but I need to predict the rocket path in real-time, depending on the current velocity/direction of the rocket allot like spaceflight simulator does.

I have managed to get realistic physics and orbits when adding gravitational forces to a rigidBody:

    var sateliteCords = Satelite.transform.position;
    var planetCords = gameObject.transform.position;
    var distance = sateliteCords - planetCords;
    distanceFromSatelite = Vector3.Distance(Satelite.transform.position, gameObject.transform.position);
    F = (Gravity * Mass) / Mathf.Pow(distanceFromSatelite,2);
    forces = (distance / Mathf.Sqrt(Mathf.Pow(distance.x, 2)+ Mathf.Pow(distance.y, 2)+ Mathf.Pow(distance.z, 2))) * -F;
    Satelite.GetComponent<Rigidbody>().AddForce(forces * Time.deltaTime, ForceMode.Force);

but I don't know how to predict future points in time to give me the orbit shape.

I have tried "speeding up the simulation" with Time.timeScale = 50; but it isn't fast enough. I read somewhere that I need a copy of the solar system running independently form the unity updates, and calculate the rocket trajectory from there but I don't know how to approach that.

I'm a bit of a noob when it comes to physics simulations so can one of you geniuses please help?

Dicarlo answered 18/9, 2019 at 16:6 Comment(6)
You could simulate the physics in parallel but 1. Unity doesn't support that, so you would have to implement your own physics engine and 2. it would probably be needlessly computationally intensive. A better approach could be to use patched conic approximation to approximate orbital trajectories. I don't know of any canonical guides on this but here's a slideshow I found on google that could get you started: maia.ub.edu/dsg/wsem/documents/PatchedConics.pdfAudiophile
If you can break this question down into smaller pieces we can probably answer those pieces but as written, I'd say this question is too broad. Writing a whole patched conics approximator from scratch is too broad for one answer.Audiophile
@Audiophile Unity actually does support that now. It has been implemented since 2018.3. See Multi-Scene Physics on this page. --- As for guides on implementation, I don't know of any either, but I haven't looked into it. There might be some blogposts about it if you look into KSP (Kerbal Space Program).Brandie
@XenoRo Neat! I had no idea that existed. Looking further into it, it looks like you can use that to simulate multiple timesteps within the current Update call. Not sure how performant that is but that could do the trick!Audiophile
@Audiophile thanks so much for the info, I have found a much easier solution but I will look into patched conic approximations in the future because I do want to start learning a bit of astrophysics and things (most of it's still over my head)Dicarlo
@XenoRo Thanks for the answer, never heard of this and that it's REALLY good to know for the future.Dicarlo
M
3

Here's what your code is actually doing:

var sateliteCords = Satelite.transform.position;
var planetCords = gameObject.transform.position;
var distance = sateliteCords - planetCords;
distanceFromSatelite = distance.magnitude;

F = (Gravity * Mass) / Mathf.Pow(distanceFromSatelite,2);
forces = distance / distanceFromSatellite * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces * Time.deltaTime, ForceMode.Force);

You can further reduce it by doing:

var distance = sateliteCords - planetCords;
distanceSqrMag = distance.sqrMagnitude;

F = (Gravity * Mass) / distanceSqrMag;
forces = distance.normalized * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces * Time.deltaTime, ForceMode.Force);

Now that the code is much simpler, I can find a crucial mistake. ForceMode.Force already multiplies the Force by Time.deltaTime. What you want here is to switch to ForceMode.Impulse, or remove the deltaTime.

F = (Gravity * Mass) / distanceSqrMag;
forces = distance.normalized * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces, ForceMode.Force);

Or better yet, assuming Mass is the mass of the satellite, and gravity is not a general constant, but just the local gravity of your planet. ForceMode.Force divides the force by the mass of the rigidbody it is applied on.

F = Gravity / distanceSqrMag;
forces = distance.normalized * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces, ForceMode.Acceleration);

Now that's all out the way, you can do a very simple approximation by doing something like

var currentPos = _rigidBody.position;
var prevPos = currentPos;
var currentVelocity = _rigidBody.velocity;
var planetCords = gameObject.transform.position;

for (int i = 0; i < stepCount; i++)
{
    var distance = planetCords - currentPos;

    var forceMag = Gravity / distance.sqrMagnitude;
    forces = distance.normalized * forceMag;
    currentVelocity  += forces * Time.fixedDeltaTime;

    currentPos += currentVelocity * Time.fixedDeltaTime;

    //Replace by a TrailRenderer you reset each frame
    Debug.DrawLine(prevPos, currentPos, Color.Red, Time.deltaTime);
    prevPos = currentPos;
}

Note that this code is untested, I probably made a mistake here or there, but that's the gist of it.

Don't worry about getting any difference in trajectory, this is exactly what unity does to predict positions. No need for fancy calculations when you got all the computing power you need.

If you want more than one-body gravity simulation, it's simple. Either apply the gravity of all planets, or simply the gravity of the closest planet taking its mass into account. I recommend the former if you have less than a dozen planets.

You don't need conics, or advanced math, or any of that. You're not kerbal space program. Sometime brute force is the best solution.

Missal answered 18/9, 2019 at 18:19 Comment(7)
It worked perfectly! I can't believe how fast my computer generated that many points! Thank you so much!! you saved me so much headache :)Dicarlo
Ah I thought the asker was asking about a long distance involving n bodies. good answer.Audiophile
Just a note: In environments with no drag (ie out of atmospheres) it can be calculated deterministically (no approximations) with orbital maths. You can then display with lines by approximating just the path with the technique of your choice (hint: a bezier path based on periapsis and apoapsis works great). This saves performance by not having to do repeated calculations with forces and positions. Basically, you eliminate the physics side of the approximations; which is the heaviest. See Orbital EccentricityBrandie
That is how KSP (Kerbal Space Program) does it. And I strongly suspect it is how Spaceflight Simulator does too. --- The downside is that it can handle only a single planetary/orbital body. N-body physics gets a LOT more complicated, and is where physics approximations are more widely used.Brandie
@XenoRo The problem is that this doesn't work for n-bodies, for which I believe the math gets much much more complex. It would also require to replace the physics engine by this mathematical prediction, which is simple, but might interfere with having collisions or other forces in his game. Another problem would be implementing drag, and recalculating the orbit every time the force is applied.Missal
On the first and third points, you are just repeating what I already pointed out. On the second point, why would it require replacing the physics engine? We are talking about the visual path prediction here, calculated ahead-of-time, not how the physics will behave in real time.Brandie
Unity doesn't apply forces in a mathematically perfect manner. Using conics would create an error unless you use it for movement as well as predictions.Missal
P
0

I think the game doesn't use the physics to predict the orbit because of computation and instability of the orbit.

And I think ellipse can do the orbit trajectory with sin cos computation and will influence the rb velocity by the direction of the rocket in the ellipse arc. it also creates a stable orbit since orbit is an ellipse(close).

What I mean of unstable orbit is that when you tried to traject or trailed the orbit, it doesn't close the orbit into ellipse.

Pantaloon answered 7/2 at 11:19 Comment(1)
Your answer makes it sound like you tried this. Do you have any code or additional information you could share to add understanding given that the existing answer was accepted?Coagulant

© 2022 - 2024 — McMap. All rights reserved.