Skip to content

Instantly share code, notes, and snippets.

@gisikw
Last active September 18, 2016 18:23
Show Gist options
  • Save gisikw/7a03547bc58a1b509f8a to your computer and use it in GitHub Desktop.
Save gisikw/7a03547bc58a1b509f8a to your computer and use it in GitHub Desktop.

Equidistant Satellites from Launch

This is a quick walkthrough about how you might calculate equidistant launches for a kOS-driven satellite network.

Note: It's unlikely that this will work perfectly. Tiny variations in how KSP handles air resistance, computing physics, etc, means that you'll still want to perform some minor corrections once these things get to orbit. This is the epitome of "sensitivity to initial conditions"

Starting Assumptions

Let's assume that we want to get four satellites equally spaced from launch. For convenience, we'll also assume that the orbital period is 360 seconds (you can get the real orbital period you're looking for using SHIP:OBT:PERIOD on the first craft you launch. This just makes the calculations simpler). Since we want them evenly spaced out, Satellite 2 should be 90° behind Satellite 1 in its orbit, with the same orbital period.

So we know that if we were able to go instantly from the launchpad to a stable orbit directly above, we'd wait to launch Sat2 until Sat1 was 90° ahead of us. Of course, we'd also be cheating ;)

Working Backward

So, in order to actually get Sat2 into orbit, we need to launch from the space center, which is going to take some time, and change our longitude while we do it.

Now, this is going to mean that our perfect 90° angle isn't going to work. We have to account for the time it will take for us to get up into orbit. Let's take a look at what that might look like:

Granted, it would be really hard to estimate this, but thankfully, we could track those values when we launch Sat1, by doing something like the following:

SET launchStart TO TIME:SECONDS.
// Launch!
// Orbit!
// Circularize!
SET launchTime TO TIME:SECONDS - launchStart.

If we imagine that it took us, say, 60 seconds to get from the launchpad to our circularized orbit, then we just need to make sure that Sat1 is 60 seconds behind our 90° spacing before we launch Sat2. Since it takes 360 seconds for Sat1 to orbit, that means we want to launch when Sat1 is 30° (90° - 60°) ahead of us when we launch. That way, by the time we're in orbit, it'll be in that sweet 90° position.

But Wait! There's More!

While our craft is getting to orbit, its longitude is changing. So we need to factor in that time as well. Let's update our Sat1 script to give us some more data:

SET launchStart TO TIME:SECONDS.
SET lngStart TO SHIP:LONGITUDE.
// Launch!
// Orbit!
// Circularize!
SET launchTime TO TIME:SECONDS - launchStart.
SET launchDegrees TO SHIP:LONGITUDE - lngStart.

Note: This is assuming that the longitude doesn't cross over from 175 to -165, etc. Ensuring that we handle the wrap-around is important, but I'll leave that as an exercise for the reader.

After we run this script on Sat1, we discover that it takes 60 seconds to get to orbit, but in that time, we advance by 12°. So Sat1 can actually get a bit further in its orbit before we launch. Rather than the 30° we computed earlier, we should wait until it's 42° ahead of us. By the time our ship has launched and circularized, Sat1 will be a marvelous 90° ahead of us, and we'll be well on our way to an equidistant satellite network.

Final Pseudocode

To wrap this up, let's update our Sat1 script to make our launchTime and launchDegrees available for subsequent craft:

SET launchStart TO TIME:SECONDS.
SET lngStart TO SHIP:LONGITUDE.
// Launch!
// Orbit!
// Circularize!
LOG "SET launchTime TO " + (TIME:SECONDS - launchStart) + "." TO launchStats.ks.
LOG "SET launchDegrees TO " + (SHIP:LONGITUDE - lngStart) + "." TO launchStats.ks.
COPY launchStats.ks TO 0.

Finally, we can write the prefix to our Sat2 script using those values:

SET targetShip TO VESSEL("Sat1").
SET desiredDegrees TO 90.

COPY launchStats.ks FROM 0.
RUN launchStats.ks.

FUNCTION DEGREES_AHEAD_OF_US(ves) {
  // Left as an exercise for the reader
}

SET targetAdvanceDuringLaunch TO (launchTime/targetShip:OBT:PERIOD) * 360.
WAIT UNTIL DEGREES_AHEAD_OF_US(targetShip) = (
  desiredDegrees               // Our goal
  - targetAdvanceDuringLaunch  // The amount the target will advance while we launch
  + launchDegrees              // The amount we advance during launch
).
// Launch!
// Orbit!
// Circularize!

Happy flying! Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment