Advertisement
Guest User

SimpleOrbitalMechanics0.002

a guest
Aug 27th, 2012
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 43.37 KB | None | 0 0
  1. -- SimpleOrbitalMechanics is a purely calculation based lua library, with some constants hardcoded for Kerbal Space Program
  2. -- v0.002
  3. -- v0.002 changes: added constant globalg, globalG and globalc.  Added RL_MilkyWay_Sol_Earth_Moon.  Added calcSomGMFromaSop, calcSomDeltaVFromIspTsmTem, calcSomIspFromTsmTemDv.  Renamed argument 'Period' to SiderealOrbitalPeriod in the renamed calcSomSemiMajorAxisFromSopGm (was calcSomSemiMajorAxisFromPeriodGm)
  4. -- to use, put
  5. -- require "SimpleOrbitalMechanics"
  6. -- in your lua script, or run it with
  7. -- dofile("SimpleOrbitalMechanics")
  8. -- Original Work Copyright 2012, Nadrek, insofar as any elements are protectable by copyright
  9. -- licensed under your choice of GPLv2, GPLv3, or Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)  http://www.gnu.org/licenses/gpl-2.0.html  or  http://www.gnu.org/licenses/gpl.html  or  http://creativecommons.org/licenses/by-sa/3.0/
  10. -- KSP specific functions will have KSP in the name; other functions will not, and can be used for real life calculations as well.
  11.  
  12. -- This script is primarily reference material and pure math; there is no dependency on KSP.
  13. -- This script is useful not only for playing with Kerbal Space Program (KSP), but also for calculating
  14. --   actual real life orbital mechanics around a variety of celestial bodies.
  15. -- While there are both RL and KSP data here, all data is entirely hardcoded, and no one kind of data
  16. --   will interfere with other kinds of use - the Real Life (RL) data will not interfere with playing KSP,
  17. --   and the KSP data will not interfere with RL usage.
  18. -- Orbital references include http://what-when-how.com/remote-sensing-from-air-and-space/a-few-standard-orbits-orbital-mechanics-interlude-remote-sensing/
  19. --     http://www.braeunig.us/space/orbmech.htm
  20. --     http://www.faqs.org/faqs/space/math/
  21.  
  22. -- global variables used in this script will be prepended with "globalSom" to avoid conflicts with globals from other scripts.
  23.  
  24. function globalSomOverallInit()
  25.   -- GM is the gravitational parameter (u) (used for orbiting objects of insignificant mass... like your spaceship or satellite)
  26.   -- KSP... refers to objects in Kerbal Space Program
  27.   -- RL... refers to objects in real life
  28.  
  29.  
  30.   -- Initialize our arrays.  Yes, a two dimensional array would be better, but this is very simple to understand and write.
  31.   globalSomCelestialBodyName = {} -- Universe_Galaxy_SolarSystem_BodyOrbitingSun_BodyOrbitingPriorBody
  32.   globalSomCelestialBodyGM = {} -- in m^3/s^2
  33.   globalSomCelestialBodySiderealRotationalPeriod = {} -- in seconds
  34.   globalSomCelestialBodyMinStableAltitude = {} -- in meters
  35.   globalSomCelestialBodyHillSphereOfInfluence = {} -- in meters
  36.   globalSomCelestialBodyEquatorialSurfaceGravity = {} -- in m/s^2
  37.   globalSomCelestialBodyEquatorialRadius = {} -- in meters
  38.  
  39.   -- WARNING: DO NOT DEPEND ON THE OFFSET REMAINING THE SAME!!!  USE THE NAME FIELD INSTEAD!!!
  40.  
  41.   -- KSP_Galaxy1_Kerbol_Kerbin per http://kerbalspaceprogram.com/~kerbalsp/wiki/index.php?title=Kerbin 20120813
  42.   --  and per http://kspwiki.nexisonline.net/wiki/Kerbin 20120813
  43.   globalSomCelestialBodyName[1] = "KSP_Galaxy1_Kerbol_Kerbin"
  44.   globalSomCelestialBodyGM[1] = 3530461000000 -- in m^3/s^2
  45.   globalSomCelestialBodySiderealRotationalPeriod[1] = 21600 -- in seconds (6 hours * 60 min/hr * 60 sec/min)
  46.   globalSomCelestialBodyMinStableAltitude[1] = 70000 -- in meters
  47.   globalSomCelestialBodyHillSphereOfInfluence[1] = 84275000 -- in meters
  48.   globalSomCelestialBodyEquatorialSurfaceGravity[1] = 9.8068 -- in m/s^2
  49.   globalSomCelestialBodyEquatorialRadius[1] = 600000 -- in meters
  50.  
  51.   -- KSP_Galaxy1_Kerbol_Kerbin_Mun per http://kerbalspaceprogram.com/~kerbalsp/wiki/index.php?title=Mun 20120813
  52.   --  and per http://kspwiki.nexisonline.net/wiki/Mun 20120813
  53.   globalSomCelestialBodyName[2] = "KSP_Galaxy1_Kerbol_Kerbin_Mun"
  54.   globalSomCelestialBodyGM[2] = 65136000000 -- in m^3/s^2
  55.   globalSomCelestialBodySiderealRotationalPeriod[2] = 147600 -- in seconds (41 hours * 60 min/hr * 60 sec/min)
  56.   globalSomCelestialBodyMinStableAltitude[2] = 4700 -- in meters
  57.   globalSomCelestialBodyHillSphereOfInfluence[2] = 2430000 -- in meters
  58.   globalSomCelestialBodyEquatorialSurfaceGravity[2] = 1.628 -- in m/s^2
  59.   globalSomCelestialBodyEquatorialRadius[2] = 200000 -- in meters
  60.  
  61.   -- KSP_Galaxy1_Kerbol_Kerbin_Minmus per http://kspwiki.nexisonline.net/wiki/Minmus 20120813
  62.   globalSomCelestialBodyName[3] = "KSP_Galaxy1_Kerbol_Kerbin_Minmus"
  63.   globalSomCelestialBodyGM[3] = 2825505000 -- in m^3/s^2
  64.   globalSomCelestialBodySiderealRotationalPeriod[3] = 1077379 -- in seconds (299.272 hours * 60 min/hr * 60 sec/min, and equal to Orbital Period)
  65.   globalSomCelestialBodyMinStableAltitude[3] = 5900 -- in meters
  66.   globalSomCelestialBodyHillSphereOfInfluence[3] = 2713000  -- in meters
  67.   globalSomCelestialBodyEquatorialSurfaceGravity[3] = 1.628 -- in m/s^2
  68.   globalSomCelestialBodyEquatorialRadius[3] = 60000 -- in meters
  69.  
  70.   -- RL_MilkyWay_Sol_Earth per https://en.wikipedia.org/wiki/Earth 20120813
  71.   --   and per http://www.earthobservatory.nasa.gov/Features/OrbitsCatalog/ 20120813
  72.   globalSomCelestialBodyName[4] = "RL_MilkyWay_Sol_Earth"
  73.   globalSomCelestialBodyGM[4] = 398600441800000 -- in m^3/s^2
  74.   globalSomCelestialBodySiderealRotationalPeriod[4] = 86164.098903691 -- sidereal rotation, stellar day, in seconds ((23 hours * 60 min/hr + 56 min) * 60 sec/min)+4.1 sec
  75.   globalSomCelestialBodyMinStableAltitude[4] = 180000 -- in meters
  76.   globalSomCelestialBodyHillSphereOfInfluence[4] = 1500000000  -- in meters
  77.   globalSomCelestialBodyEquatorialSurfaceGravity[4] = 9.780327 -- in m/s^2
  78.   globalSomCelestialBodyEquatorialRadius[4] = 6378100 -- in meters
  79.  
  80.  
  81.   -- RL_MilkyWay_Sol_Earth_Moon per https://en.wikipedia.org/wiki/Moon 20120820
  82.   --   and per https://en.wikipedia.org/wiki/List_of_mountains_on_the_Moon 20120820
  83.   --   and per https://en.wikipedia.org/wiki/Standard_gravitational_parameter 20120820
  84.   --   and per https://en.wikipedia.org/wiki/Sphere_of_influence_%28astrodynamics%29 20120820
  85.   globalSomCelestialBodyName[5] = "RL_MilkyWay_Sol_Earth_Moon"
  86.   globalSomCelestialBodyGM[5] = 4902777900000 -- in m^3/s^2
  87.   globalSomCelestialBodySiderealRotationalPeriod[5] = 2360584.6848 -- sidereal rotation, stellar day, in seconds (27.321582 days * 24 hr/day * 60 min/hr * 60 sec/min)
  88.   globalSomCelestialBodyMinStableAltitude[5] = 11300 -- in meters
  89.   globalSomCelestialBodyHillSphereOfInfluence[5] =  66100000 -- in meters
  90.   globalSomCelestialBodyEquatorialSurfaceGravity[5] = 1.622 -- in m/s^2
  91.   globalSomCelestialBodyEquatorialRadius[5] = 1738140 -- in meters
  92.  
  93.  
  94.   -- math.pi will do instead of a global, but if you like, try: globalPi = 3.1415926535897932384 -- a couple more digits than double precision can handle, to near-maximize accuracy
  95.   globale = 2.7182818284590452353 -- a couple more significant digits than double precision can handle, to near-maximize accuracy
  96.   globalg = 9.80665 -- in meters per second squared, standard gravity (i.e. 1g, originally based on the acceleration of a body in freefall on Earth at sea level at a geodetic latitude of 45 degrees per https://en.wikipedia.org/wiki/Standard_gravity
  97.   globalG = 6.67384*10^(-11) -- meters^3/kg/s^2 2010 CODATA graviational constant per https://en.wikipedia.org/wiki/Gravitational_constant
  98. end
  99.  
  100. function globalSomMainBodyReset(MainBodyName)
  101.   -- MainBodyName must be one of RL_MilkyWay_Sol_Earth, KSP_Galaxy1_Kerbol_Kerbin_Mun, KSP_Galaxy1_Kerbol_Kerbin, or KSP_Galaxy1_Kerbol_Kerbin_Minmus
  102.  
  103.   -- in case we don't find the name we're looking for, set to defaults.
  104.   globalSomMainBodyNumber = nil
  105.   globalSomMainBodyName = nil
  106.   globalSomMainBodyGM = nil
  107.   globalSomMainBodySiderealRotationalPeriod = nil
  108.   globalSomMainBodyMinStableAltitude = nil
  109.   globalSomMainBodyHillSphereOfInfluence = nil
  110.   globalSomMainBodyEquatorialSurfaceGravity = nil
  111.   globalSomMainBodyEquatorialRadius = nil
  112.  
  113.  
  114.   local i
  115.   -- Loop through however many known Celestial Body Names we have
  116.   for i = 1, #globalSomCelestialBodyName do
  117.     -- If the name of that celestial body matches the name we were given, let's use that entry's data!
  118.     if MainBodyName == globalSomCelestialBodyName[i] then
  119.       globalSomMainBodyNumber = i + 0 -- this looks strange, but simply assigning = i ends up with #globalSomCelestialBodyName - presumably it acts as pointer assignment instead
  120.       globalSomMainBodyName = MainBodyName
  121.       globalSomMainBodyGM = globalSomCelestialBodyGM[i] -- in km^3/s^2
  122.       globalSomMainBodySiderealRotationalPeriod = globalSomCelestialBodySiderealRotationalPeriod[i] -- in seconds
  123.       globalSomMainBodyMinStableAltitude = globalSomCelestialBodyMinStableAltitude[i] -- in meters
  124.       globalSomMainBodyHillSphereOfInfluence = globalSomCelestialBodyHillSphereOfInfluence[i] -- in meters
  125.       globalSomMainBodyEquatorialSurfaceGravity = globalSomCelestialBodyEquatorialSurfaceGravity[i] -- in m/s^2
  126.       globalSomMainBodyEquatorialRadius = globalSomCelestialBodyEquatorialRadius[i] -- in meters
  127.     end
  128.   end
  129.  
  130.   if globalSomMainBodyNumber == nil then
  131.     print "ERROR: Unknown MainBodyName in globalSomMainBodyReset"
  132.     print "  expecting RL_MilkyWay_Sol_Earth, KSP_Galaxy1_Kerbol_Kerbin, KSP_Galaxy1_Kerbol_Kerbin_Mun, or KSP_Galaxy1_Kerbol_Kerbin_Minmus"
  133.   end
  134.  
  135. end
  136.  
  137.  
  138.  
  139. function calcSomSemiMajorAxisOrbitingSphereFromApPeMbr(Ap, Pe, MainBodyRadius)
  140.   -- Ap is the Apoapsis in meters
  141.   -- Pe is the Periapsis in meters
  142.   -- MainBodyRadius is the equatorial radius of the body being orbited in meters
  143.   -- The semi-major axis (a) of an ellipse (or a circle) is half the longest dimension of the
  144.   --   total ellipse; in other words, for a small body of trivial mass (your spaceship or satellite)
  145.   --   compared to the body it orbits (the mainBody), it's the Apoapsis plus the body it orbit's radius
  146.   --   (since it's assumed to orbit the center of the body), plus the same for Periapsis, divided by two.
  147.   -- This is deliberately coded for maximum readability.
  148.   return ((Ap + MainBodyRadius) + (Pe + MainBodyRadius))/2
  149. end
  150.  
  151.  
  152. function calcSomPeorapFromaAporpeMbr(a, Aporpe, MainBodyRadius)
  153.   -- a is the semi-major axis in meters
  154.   -- Aporpe is either Apoapsis or Periapsis, in meters - this returns the other one.
  155.   -- MainBodyRadius is the equatorial radius of the body being orbited in meters
  156.   -- This returns the opposite apsis from whatever you entered, in meters
  157.   --   i.e. if you feed it Apoapsis, it tells you Periapsis
  158.   --   i.e. if you feed it Periapsis, it tells you Apoapsis
  159.   return (2*a-(Aporpe + MainBodyRadius*2))
  160. end
  161.  
  162. function calcSomSiderealOrbitalPeriodFromaGm(a, GM)
  163.   -- a is the semi-major axis in meters
  164.   -- GM is the standard gravitational parameter in m^3/s^2 (also known as u)
  165.   -- returns the sidereal orbital period in seconds
  166.   -- For the equation, please see http://en.wikipedia.org/wiki/Orbital_period
  167.   return (2 * math.pi * (a^3/GM)^0.5)
  168. end
  169.  
  170. function calcSomSemiMajorAxisFromSopGm(SiderealOrbitalPeriod, GM)
  171.   -- SiderealOrbitalPeriod is the sidereal orbital period in seconds
  172.   -- GM is the standard gravitational parameter in m^3/s^2 (also known as u)
  173.   -- returns the semi-major axis (a) in meters
  174.   -- For the equation, please see http://en.wikipedia.org/wiki/Orbital_period and derive a = ...
  175.   return ((GM*(SiderealOrbitalPeriod/(2*math.pi))^2 )^(1/3))
  176. end
  177.  
  178. function calcSomGMFromaSop(a, SiderealOrbitalPeriod)
  179.   -- a is the semi-major axis in meters
  180.   -- SiderealOrbitalPeriod is the sidereal orbital period in seconds
  181.   -- returns GM, the standard gravitational parameter in m^3/s^2 (also known as u)
  182.   -- [[ Ex:
  183.   --   print(calcSomGMFromaSop(42164140, 86164))
  184.   -- ]]
  185.   -- new in v0.002
  186.   return ((a^(3))/((SiderealOrbitalPeriod/(2*math.pi))^2))
  187. end
  188.  
  189. function calcSomSiderealOrbitalPeriodFromApPeMbrGm(Ap, Pe, MainBodyRadius, GM)
  190.   -- relies on globalSomOverallInit
  191.   -- Ap is the Apoapsis in meters
  192.   -- Pe is the Periapsis in meters
  193.   -- MainBodyRadius is the equatorial radius of the body being orbited in meters
  194.   -- GM is the standard gravitational parameter in m^3/s^2
  195.   -- returns the sidereal orbital period in seconds
  196.   local semiMajorAxis = calcSomSemiMajorAxisOrbitingSphereFromApPeMbr(Ap, Pe, MainBodyRadius)
  197.   return calcSomSiderealOrbitalPeriodFromaGm(semiMajorAxis, GM)
  198. end
  199.  
  200.  
  201. function calcSomOrbitalVelocityFromaGmRfcb(a, GM, RadiusFromCentralBody)
  202.   -- a is the semi-major axis in meters
  203.   -- GM is the standard gravitational parameter in m^3/s^2 (also known as u)
  204.   -- RadiusFromCentralBody is the distance in meters from the orbiting object to
  205.   --   the center of gravity it's orbiting (i.e. the center of the planet)
  206.   -- returns the orbital velocity in m/s
  207.   return ((GM*(2/RadiusFromCentralBody - 1/a))^0.5)
  208. end
  209.  
  210.  
  211. function calcSomOrbitalVelocityFromaGmAltaslMbr(a, GM, AltitudeASL, MainBodyRadius)
  212.   -- a is the semi-major axis in meters
  213.   -- GM is the standard gravitational parameter in m^3/s^2 (also known as u)
  214.   -- AltitudeASL is the altitude above sea level in meters
  215.   -- MainBodyRadius is the equatorial radius of the body being orbited in meters
  216.   -- returns the orbital velocity in m/s
  217.   local RadiusFromCentralBody = AltitudeASL + MainBodyRadius
  218.   return calcSomOrbitalVelocityFromaGmRfcb(a, GM, RadiusFromCentralBody)
  219. end
  220.  
  221.  
  222. function calcSomGMFromaOvRfcb(a, OrbitalVelocity, RadiusFromCentralBody)
  223.   -- a is the semi-major axis in meters
  224.   -- OrbitalVelocity is the orbital velocity in m/s
  225.   -- RadiusFromCentralBody is the distance in meters from the orbiting object to
  226.   --   the center of gravity it's orbiting (i.e. the center of the planet)
  227.   -- returns GM, the standard gravitational parameter in m^3/s^2 (also known as u)
  228.   return (OrbitalVelocity^2 / (2/RadiusFromCentralBody - 1/a))
  229. end
  230.  
  231.  
  232. function calcSomGMFromaOvAltaslMbr(a, OrbitalVelocity, AltitudeASL, MainBodyRadius)
  233.   -- a is the semi-major axis in meters
  234.   -- OrbitalVelocity is the orbital velocity in m/s
  235.   -- AltitudeASL is the altitude above sea level in meters
  236.   -- MainBodyRadius is the equatorial radius of the body being orbited in meters
  237.   -- returns GM, the standard gravitational parameter in m^3/s^2 (also known as u)
  238.   local RadiusFromCentralBody = AltitudeASL + MainBodyRadius
  239.   return calcSomGMFromaOvRfcb(a, OrbitalVelocity,RadiusFromCentralBody)
  240. end
  241.  
  242.  
  243. function guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe(a, OrbitalVelocity, AltitudeASL, MarginOfError)
  244.   -- a is the semi-major axis in meters
  245.   -- OrbitalVelocity is the orbital velocity in m/s
  246.   -- AltitudeASL is the altitude above sea level in meters
  247.   -- returns the SimpleOrbitalMechanics name of the body we think we're orbiting.
  248.   --   suitable to pass to globalSomMainBodyReset, or UNKNOWN if it cannot tell
  249.   -- NOTE: This goes through both RL and KSP bodies!
  250.   -- NOTE: You actually have to be in orbit first.
  251.   -- NOTE: Depends on globalSomOverallInit() having parameters for the body in question, and
  252.   --   having been called before now.
  253.   -- This is _extremely_ simplistic - we're just going to go through all the planets
  254.   --   we know about, and check each one.  First one we find that matches closely enough wins!
  255.  
  256.   local i
  257.   -- Loop through however many known Celestial Body Names we have
  258.   for i = 1, #globalSomCelestialBodyName do
  259.     -- If the name of that celestial body matches the name we were given, let's use that entry's data!
  260.     if math.abs((calcSomGMFromaOvAltaslMbr(a, OrbitalVelocity, AltitudeASL, globalSomCelestialBodyEquatorialRadius[i]))/globalSomCelestialBodyGM[i] - 1.0) < MarginOfError then
  261.       return globalSomCelestialBodyName[i]
  262.     end
  263.   end
  264.  
  265.   -- if we got here, it's because we didn't find a match and return with it from inside the for loop
  266.   return "UNKNOWN"
  267. end
  268.  
  269.  
  270.  
  271. function calcSomPeorapFromAporpeMbrGmSop(Aporpe, MainBodyRadius, GM, SiderealOrbitalPeriod)
  272.   -- Aporpe is either Apoapsis or Periapsis, in meters - you don't even need to know which
  273.   -- MainBodyRadius is the equatorial radius of the body being orbited in meters
  274.   -- GM is the standard gravitational parameter in m^3/s^2
  275.   -- SiderealOrbitalPeriod is the sidereal orbital period in seconds you wish the orbit to have
  276.   -- returns the Peorap (if given Apoapsis, returns Periapsis; if given Periapsis, returns Apoapsis
  277.   --   - and if you don't know which you're giving it going in, whichever is bigger at the end is Apoapsis)
  278.   -- This is deliberately coded for maximum readability; even a genius Kerbal should be able to follow
  279.   --   these instructions, if they take then slow and do them one small step at a time.
  280.  
  281.   -- NOTE: Molniya orbits circle twice per day, so the SiderealOrbitalPeriod needs to be half the SiderealRotationalPeriod
  282.   -- NOTE: Tundra orbits circle once per day, so the SiderealOrbitalPeriod needs to be equal to the SiderealRotationalPeriod
  283.  
  284.   -- a is the semi-major axis, which we'll use to calculate the Peorap shortly.
  285.   local a = calcSomSemiMajorAxisFromSopGm(SiderealOrbitalPeriod, GM)
  286.  
  287.   -- now that we have the semi-major axis, we can calculate the Peorap
  288.   -- i.e. if we were given the Ap, let's find the Pe.  If we were given the Pe, find the Ap.
  289.   local Peorap = calcSomPeorapFromaAporpeMbr(a, Aporpe, MainBodyRadius)
  290.  
  291.   -- WARNING WARNING WARNING - there's every chance this orbit will kill you or send you out of the local orbit!!!!
  292.   --  Use isSomOrbitStableFromApPeHsoiMsa to check it before using!!!
  293.  
  294.   return Peorap
  295. end
  296.  
  297. function calcSomMolniyaPeorapFromAporpeMbrGmSrp(Aporpe, MainBodyRadius, GM, SiderealRotationalPeriod)
  298.   -- Aporpe is either Apoapsis or Periapsis, in meters - you don't even need to know which
  299.   -- MainBodyRadius is the equatorial radius of the body being orbited in meters
  300.   -- GM is the standard gravitational parameter in m^3/s^2
  301.   -- SiderealRotationalPeriod is the sidereal rotational period in seconds of the body being orbited
  302.   -- returns the Peorap (if given Apoapsis, returns Periapsis; if given Periapsis, returns Apoapsis
  303.   --   - and if you don't know which you're giving it going in, whichever is bigger at the end is Apoapsis)
  304.   --   for a Molniya orbit, i.e. a semisynchronous orbit (two orbits per day)
  305.   -- NOTE: See calcSomPeorapFromAporpeMbrGmSop for details
  306.  
  307.   -- NOTE: Molniya orbits circle twice per day, so the SiderealOrbitalPeriod needs to be half the SiderealRotationalPeriod
  308.   local molniyaSiderealOrbitalPeriod = SiderealRotationalPeriod / 2
  309.   return calcSomPeorapFromAporpeMbrGmSop(Aporpe, MainBodyRadius, GM, molniyaSiderealOrbitalPeriod)
  310.  
  311.   -- WARNING WARNING WARNING - there's every chance this orbit will kill you or send you out of the local orbit!!!!
  312.   --  Use isSomOrbitStableFromApPeHsoiMsa to check it before using!!!
  313.  
  314. end
  315.  
  316. function calcSomApPeFromAporpePeorap(Aporpe, Peorap)
  317.   -- Aporpe is either Apoapsis or Periapsis, in meters - you don't even need to know which
  318.   -- Peorap is either Periapsis or Apoapsis, in meters - you don't even need to know which
  319.   -- returns Ap, Pe
  320.   --[[ Ex:
  321.        do
  322.        local localAp, localPe = calcSomApPeFromAporpePeorap(75000,3095000)
  323.        print("Ap: " .. localAp .. " Pe: " .. localPe)
  324.        end
  325.        ]]
  326.  
  327.   -- We'll find out which is which because the bigger one is the Ap.  If they're equal (perfectly circular orbit), who cares!
  328.   return math.max(Aporpe, Peorap), math.min(Aporpe, Peorap)
  329. end
  330.  
  331.  
  332.  
  333. function calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe(HillSphereOfInfluence, MinStableAltitude, MainBodyRadius, GM, SiderealRotationalPeriod, MarginOfError)
  334.   -- HillSphereOfInfluence is the range in meters at which the gravity of the body is effective
  335.   -- MinStableAltitude is the altitude above sea level in meters at which orbiting is safe and stable
  336.   --   i.e. it's above both the atmosphere's effects, and the tallest mountains.
  337.   -- MainBodyRadius is the equatorial radius of the body being orbited in meters
  338.   -- GM is the standard gravitational parameter in m^3/s^2
  339.   -- SiderealRotationalPeriod is the sidereal rotational period in seconds of the body being orbited
  340.   -- MarginOfError 0.001 means allow 0.1% for a "safety zone" above the minimum stable altitude, or below the Hill sphere of influence.
  341.   -- Returns Ap and Pe of the best possible Molniya orbit for a given body
  342.   --   Returns -1, -1 if no stable Molniya orbit is possible
  343.   --[[ ex.
  344.     do
  345.     local localAp, localPe = calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe(1500000000, 180000, 6378100, 398600441800000, 86164.098903691, 1.777777777)
  346.     print("Ap " .. localAp .. " Pe " .. localPe)
  347.     end
  348.     ]]
  349.   -- For oblate celestial bodies, of course, the inclination of the actual orbit must be 63.4 or 116.6 degrees, so the effect of the oblate equitorial belt is nullified.
  350.  
  351.   -- First, let's see if we can get a stable Molniya orbit with MinStableAltitude (including MarginOfError) as the Periapsis
  352.   --   this would be the ideal Molniya orbit, with maximum Apoapsis dwell time.
  353.   local Ap = calcSomMolniyaPeorapFromAporpeMbrGmSrp(MinStableAltitude * (1 + MarginOfError), MainBodyRadius, GM, SiderealRotationalPeriod)
  354.   if isSomOrbitStableFromApPeHsoiMsa(Ap, MinStableAltitude  * (1 + MarginOfError), HillSphereOfInfluence, MinStableAltitude) == 0 then
  355.    -- isSomOrbitStableFromApPeHsoiMsa returns 0 for a stable orbit.
  356.    return Ap, MinStableAltitude * (1 + MarginOfError)
  357.   end
  358.  
  359.   -- Well, if we're here, it wasn't a stable orbit.  We've got one more shot; let's see if we can get a crappy Molniya orbit
  360.   --   Perhaps if the Apoapsis is the Hill sphere of influence (minus a 1000 meter buffer), we can get a periapsis that works
  361.   local Pe = calcSomMolniyaPeorapFromAporpeMbrGmSrp(HillSphereOfInfluence  * (1 - MarginOfError), MainBodyRadius, GM, SiderealRotationalPeriod)
  362.   if isSomOrbitStableFromApPeHsoiMsa(HillSphereOfInfluence  * (1 - MarginOfError), Pe, HillSphereOfInfluence, MinStableAltitude) == 0 then
  363.     return HillSphereOfInfluence  * (1 - MarginOfError), Pe
  364.   end
  365.  
  366.   -- And if we made it past both tries, it's just not going to happen.
  367.   return -1, -1
  368.  
  369. end
  370.  
  371.  
  372. function isSomOrbitStableFromApPeHsoiMsa(Ap, Pe, HillSphereOfInfluence, MinStableAltitude)
  373.   -- Ap is the Apoapsis in meters
  374.   -- Pe is the Periapsis in meters
  375.   -- HillSphereOfInfluence is the range in meters at which the gravity of the body is effective
  376.   -- MinStableAltitude is the altitude above sea level in meters at which orbiting is safe and stable
  377.   --   i.e. it's above both the atmosphere's effects, and the tallest mountains.
  378.  
  379.  
  380.   -- technically, this is simple bit flags.  
  381.   -- 0 = stable
  382.   -- 1 = burn up in atmosphere
  383.   -- 2 = escape SOI
  384.   -- 3 = both burn up and escape SOI (whichever comes first)
  385.   -- 4 = your Apoapsis is greater than your Periapsis, which is just wrong.
  386.   returnValueisSomOrbitStableFromApPeHsoiMsa = 0 -- this should be a local, but when set to local scope the additions inside the ifs fail completely.
  387.   if Pe < MinStableAltitude then
  388.     returnValueisSomOrbitStableFromApPeHsoiMsa = returnValueisSomOrbitStableFromApPeHsoiMsa + 1
  389.   end
  390.   if Ap > HillSphereOfInfluence then
  391.     returnValueisSomOrbitStableFromApPeHsoiMsa = returnValueisSomOrbitStableFromApPeHsoiMsa + 2
  392.   end
  393.   if Pe > Ap then
  394.     returnValueisSomOrbitStableFromApPeHsoiMsa = returnValueisSomOrbitStableFromApPeHsoiMsa + 4
  395.   end
  396.   return returnValueisSomOrbitStableFromApPeHsoiMsa
  397.  
  398. end
  399.  
  400.  
  401. function calcSomDeltaVFromIspTsmTem(Isp, TotalStartingMass, TotalEndingMass)
  402.   -- Isp is the Specific Impulse in seconds
  403.   -- TotalStartingMass is the total mass before the burn, including fuel - units must be the same as TotalEndingMass
  404.   -- TotalEndingMass is the total mass after the burn, including remaining fuel - units must be the same as TotalStartingMass
  405.   -- returns Delta-V in meters per second.
  406.   --[[ ex:
  407.         print(calcSomDeltaVFromIspTsmTem(390,15,10))
  408.     ]]
  409.   -- reference is Tsiolkovsky rocket equation https://en.wikipedia.org/wiki/Rocket_equation
  410.   --   Total Delta-V = Isp * g * ln(TotalMass/DryMass)
  411.   return Isp * globalg * math.log(TotalStartingMass/TotalEndingMass)
  412. end
  413.  
  414.  
  415. function calcSomIspFromTsmTemDv(TotalStartingMass, TotalEndingMass, DeltaV)
  416.   -- TotalStartingMass is the total mass before the burn, including fuel - units must be the same as TotalEndingMass
  417.   -- TotalEndingMass is  the total mass after the burn, including remaining fuel - units must be the same as TotalStartingMass
  418.   -- returns Isp, the Specific Impulse in seconds
  419.   --[[ ex:
  420.         print(calcSomIspFromTsmTemDv(15,10,1550))
  421.     ]]
  422.   -- reference is Tsiolkovsky rocket equation https://en.wikipedia.org/wiki/Rocket_equation
  423.   --   Total Delta-V = Isp * g * ln(TotalMass/DryMass)
  424.   return DeltaV/(globalg * math.log(TotalStartingMass/TotalEndingMass))
  425. end
  426.  
  427.  
  428.  
  429.  
  430. function testSomTestHarness()
  431.   -- If you get messages, then something broke!
  432.  
  433.   assert(calcSomSemiMajorAxisOrbitingSphereFromApPeMbr(4501000, 72001, 600000)>=2886500,"calcSomSemiMajorAxisOrbitingSphereFromApPeMbr test 1 Eccentric Kerbin orbit failed")
  434.   assert(calcSomSemiMajorAxisOrbitingSphereFromApPeMbr(4501000, 72001, 600000)<=2886501,"calcSomSemiMajorAxisOrbitingSphereFromApPeMbr test 2 Eccentric Kerbin orbit failed")
  435.  
  436.   assert(calcSomPeorapFromaAporpeMbr(750000, 75000, 600000)==225000,"calcSomPeorapFromaAporpeMbr test 1 Silly Kerbin orbit failed")
  437.  
  438.   assert(calcSomSiderealOrbitalPeriodFromaGm(26378000,398600441800000)>=42633,"calcSomSiderealOrbitalPeriodFromaGm test 1 GPS Earth orbit failed")
  439.   assert(calcSomSiderealOrbitalPeriodFromaGm(26378000,398600441800000)<=42637,"calcSomSiderealOrbitalPeriodFromaGm test 2 GPS Earth orbit failed")
  440.  
  441.   assert(calcSomSemiMajorAxisFromSopGm(86164,398600441800000)>=42164138,"calcSomSemiMajorAxisFromSopGm test 1 Geosync Earth orbit failed")
  442.   assert(calcSomSemiMajorAxisFromSopGm(86164,398600441800000)<=42164142,"calcSomSemiMajorAxisFromSopGm test 2 Geosync Earth orbit failed")
  443.  
  444.   assert(calcSomGMFromaSop(42164140, 86164)<=398600451800000,"calcSomGMFromaSop test 1 Geosync Earth orbit failed")
  445.   assert(calcSomGMFromaSop(42164140, 86164)>=398600431800000,"calcSomGMFromaSop test 1 Geosync Earth orbit failed")
  446.  
  447.   assert(calcSomSiderealOrbitalPeriodFromApPeMbrGm(20314000, 20047000, 6378100, 398600441800000)>=43072,"calcSomSiderealOrbitalPeriodFromApPeMbrGm test 1 GPS Earth orbit failed")
  448.   assert(calcSomSiderealOrbitalPeriodFromApPeMbrGm(20314000, 20047000, 6378100, 398600441800000)<=43076,"calcSomSiderealOrbitalPeriodFromApPeMbrGm test 2 GPS Earth orbit failed")
  449.  
  450.   assert(calcSomOrbitalVelocityFromaGmRfcb(750000,3530461000000,750000)>=2169,"calcSomOrbitalVelocityFromaGmRfcb test 1 150km Kerbin circular orbit failed.")
  451.   assert(calcSomOrbitalVelocityFromaGmRfcb(750000,3530461000000,750000)<=2170,"calcSomOrbitalVelocityFromaGmRfcb test 2 150km Kerbin circular orbit failed.")
  452.  
  453.   assert(calcSomOrbitalVelocityFromaGmAltaslMbr(725000,3530461000000,125000,600000)>=2206,"calcSomOrbitalVelocityFromaGmAltaslMbr test 1 125km Kerbin circular orbit failed.")
  454.   assert(calcSomOrbitalVelocityFromaGmAltaslMbr(725000,3530461000000,125000,600000)<=2207,"calcSomOrbitalVelocityFromaGmAltaslMbr test 2 125km Kerbin circular orbit failed.")
  455.  
  456.   assert(calcSomGMFromaOvRfcb(362941.275006862,383.306541880459,399135.253432537)>=65138373282,"calcSomGMFromaOvRfcb test 1 126610-199271m Kerbin Mun orbit failed.")
  457.   assert(calcSomGMFromaOvRfcb(362941.275006862,383.306541880459,399135.253432537)<=65138373302,"calcSomGMFromaOvRfcb test 2 126610-199271m Kerbin Mun orbit failed.")
  458.   assert(calcSomGMFromaOvAltaslMbr(468746.649196013,407.483188333337,227130.402050318,200000)>=65138680733,"calcSomGMFromaOvAltaslMbr test 1 197405-340087km Kerbin Mun orbit failed.")
  459.   assert(calcSomGMFromaOvAltaslMbr(468746.649196013,407.483188333337,227130.402050318,200000)<=65138680753,"calcSomGMFromaOvAltaslMbr test 2 197405-340087km Kerbin Mun orbit failed.")
  460.  
  461.   assert(guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe(468780,394.1,242942,0.01)=="KSP_Galaxy1_Kerbol_Kerbin_Mun","guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe test 1 Kerbin Mun failed.")
  462.   assert(guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe(65955,207.0,5950,0.01)=="KSP_Galaxy1_Kerbol_Kerbin_Minmus","guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe test 2 Kerbin Minmus failed.")
  463.   assert(guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe(2187000,1130.4,1839000,0.01)=="KSP_Galaxy1_Kerbol_Kerbin","guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe test 3 Kerbin failed.")
  464.   assert(guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe(42164138,3075,35786000,0.01)=="RL_MilkyWay_Sol_Earth","guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe test 4 Earth Geosync failed.")
  465.   assert(guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe(5,5,5,0.0001)=="UNKNOWN","guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe test 5 Unknown orbit failed.")
  466.  
  467.   assert(calcSomPeorapFromAporpeMbrGmSop(703000, 6378100, 398600441800000, 5928)>=699653,"calcSomMolniyaPeorapFromAporpeMbrGmSrp test 1 Classic Earth Landsat failed")
  468.   assert(calcSomPeorapFromAporpeMbrGmSop(703000, 6378100, 398600441800000, 5928)<=699657,"calcSomMolniyaPeorapFromAporpeMbrGmSrp test 2 Classic Earth Landsat failed")
  469.   assert(calcSomMolniyaPeorapFromAporpeMbrGmSrp(500000, 6378100, 398600441800000, 86164.098903691)>=39867327,"calcSomMolniyaPeorapFromAporpeMbrGmSrp test 1 Classic Earth Molniya failed")
  470.   assert(calcSomMolniyaPeorapFromAporpeMbrGmSrp(500000, 6378100, 398600441800000, 86164.098903691)<=39867330,"calcSomMolniyaPeorapFromAporpeMbrGmSrp test 2 Classic Earth Molniya failed")
  471.   assert(calcSomMolniyaPeorapFromAporpeMbrGmSrp(39867328.3148597, 6378100, 398600441800000, 86164.098903691)>=499998,"calcSomMolniyaPeorapFromAporpeMbrGmSrp test 3 Classic Earth Molniya failed")
  472.   assert(calcSomMolniyaPeorapFromAporpeMbrGmSrp(39867328.3148597, 6378100, 398600441800000, 86164.098903691)<=500002,"calcSomMolniyaPeorapFromAporpeMbrGmSrp test 4 Classic Earth Molniya failed")
  473.   do
  474.     local localAp, localPe = calcSomApPeFromAporpePeorap(75000,3095000)
  475.     assert(localAp==3095000,"calcSomApPeFromAporpePeorap test 1 Pe first failed")
  476.     assert(localPe==75000,"calcSomApPeFromAporpePeorap test 2 Pe first failed")
  477.     local localAp, localPe = calcSomApPeFromAporpePeorap(2,1)
  478.     assert(localAp==2,"calcSomApPeFromAporpePeorap test 3 Ap first failed")
  479.     assert(localPe==1,"calcSomApPeFromAporpePeorap test 4 Ap first failed")
  480.   end
  481.  
  482.   do
  483.     local localAp, localPe = calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe(1500000000, 180000, 6378100, 398600441800000, 86164.098903691, 1.777777777)
  484.     assert(localAp>=39867318,"calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe test 1 Earth classic Molniya failed.")
  485.     assert(localAp<=39867338,"calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe test 2 Earth classic Molniya failed.")
  486.     assert(localPe>=499998,"calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe test 3 Earth classic Molniya failed.")
  487.     assert(localPe<=500002,"calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe test 4 Earth classic Molniya failed.")
  488.     local localAp, localPe = calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe(2430000, 4700, 200000, 65136000000, 147600, 0.01)
  489.     assert(localAp>=2405690,"calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe test 5 Kerbin Mun crappy Molniya failed.")
  490.     assert(localAp<=2405710,"calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe test 6 Kerbin Mun crappy Molniya failed.")
  491.     assert(localPe>=1352323,"calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe test 7 Kerbin Mun crappy Molniya failed.")
  492.     assert(localPe<=1352343,"calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe test 8 Kerbin Mun crappy Molniya failed.")
  493.     local localAp, localPe = calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe(2130000, 4700, 200000, 65136000000, 197600, 0.01)
  494.     assert(localAp == (-1),"calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe test 9 Impossible Molniya failed.") -- parenthesis around the -1 is required to get the desired  error
  495.     assert(localPe == (-1),"calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe test 10 Impossible Molniya failed.") -- parenthesis around the -1 is required to get the desired  error
  496.   end
  497.  
  498.   assert(calcSomDeltaVFromIspTsmTem(390,15,10)<=1551.5,"calcSomDeltaVFromIspTsmTem test 1 failed")
  499.   assert(calcSomDeltaVFromIspTsmTem(390,15,10)>=1549.5,"calcSomDeltaVFromIspTsmTem test 2 failed")
  500.  
  501.  
  502.   assert(calcSomIspFromTsmTemDv(15,10,1550)<=390.5,"calcSomIspFromTsmTemDv test 1 failed")
  503.   assert(calcSomIspFromTsmTemDv(15,10,1550)>=388.5,"calcSomIspFromTsmTemDv test 2 failed")
  504.  
  505.   assert(isSomOrbitStableFromApPeHsoiMsa(100000,10000,200000,5000)==0,"isSomOrbitStableFromApPeHsoiMsa test 1 (stable orbit) failed")
  506.   assert(isSomOrbitStableFromApPeHsoiMsa(100000,10000,200000,10001)==1,"isSomOrbitStableFromApPeHsoiMsa test 2 (areobrake orbit) failed")
  507.   assert(isSomOrbitStableFromApPeHsoiMsa(200001,10000,200000,5000)==2,"isSomOrbitStableFromApPeHsoiMsa test 3 (escape orbit) failed")
  508.   assert(isSomOrbitStableFromApPeHsoiMsa(200001,10000,200000,10001)==3,"isSomOrbitStableFromApPeHsoiMsa test 4 (deathtrap orbit) failed")
  509.   assert(isSomOrbitStableFromApPeHsoiMsa(20000,30000,200000,5000)==4,"isSomOrbitStableFromApPeHsoiMsa test 5 (stupid orbit) failed")
  510.   print "Tests complete."
  511. end
  512.  
  513.  
  514.  
  515. function helpSomSimpleOrbitalMechanics1()
  516.   print "Usage: globalSomOverallInit()"
  517.   print "   Initializes unchanging global variables"
  518.   print "Usage: globalSomMainBodyReset(MainBodyName)"
  519.   print "   Initialized global variables that change based on the body"
  520.   print "   that is being orbited."
  521.   print "   MainBodyName must be one of RL_MilkyWay_Sol_Earth, KSP_Galaxy1_Kerbol_Kerbin_Mun, KSP_Galaxy1_Kerbol_Kerbin, or KSP_Galaxy1_Kerbol_Kerbin_Minmus"
  522.   print "Usage: calcSomSemiMajorAxisOrbitingSphereFromApPeMbr(Ap, Pe, MainBodyRadius)"
  523.   print "   Returns the semi-major axis based on Ap the Apoapsis,"
  524.   print "   Pe the Periapsis, and MainBodyRadius, the equatorial radius"
  525.   print "   of the body being orbited (assumed to be a sphere; at this time"
  526.   print "   the effects of a highly oblate body with a high inclination"
  527.   print "   orbit have not been investigated."
  528.   print "   All units must be the same.  I.e. for a 50x125km orbit around"
  529.   print "   Kerbin, calcSomSemiMajorAxisOrbitingSphereFromApPeMbr(125000,50000,600000)"
  530.   print "Usage: calcSomGMFromaSop(a, SiderealOrbitalPeriod)"
  531.   print "   a is the semi-major axis in meters"
  532.   print "   SiderealOrbitalPeriod is the sidereal orbital period in seconds"
  533.   print "   returns GM, the standard gravitational parameter in m^3/s^2 (also known as u)"
  534.   print "   Ex: print(calcSomGMFromaSop(42164140, 86164))"
  535.   print "Usage: calcSomPeorapFromaAporpeMbr(a, Aporpe, MainBodyRadius)"
  536.   print "   a is the semi-major axis in meters"
  537.   print "   Aporpe is either Apoapsis or Periapsis, in meters"
  538.   print "   MainBodyRadius is the equatorial radius of the body being orbited in meters"
  539.   print "   This returns the opposite apsis from whatever you entered, in meters"
  540.   print "   i.e. if you feed it Apoapsis, it tells you Periapsis"
  541.   print "   i.e. if you feed it Periapsis, it tells you Apoapsis"
  542.   print "Usage: calcSomSiderealOrbitalPeriodFromaGm(a, GM)"
  543.   print "   Returns the period in seconds of the orbit, given a,"
  544.   print "   the semi-major axis in meters, and GM, the gravitational"
  545.   print "   parameter in m^3/s^2 of the body being orbited."
  546.   print "Usage: calcSomSemiMajorAxisFromSopGm(SiderealOrbitalPeriod, GM)"
  547.   print "  SiderealOrbitalPeriod is the sidereal orbital period in seconds"
  548.   print "  GM is the standard gravitational parameter in m^3/s^2"
  549.   print "  returns the semi-major axis (a) in meters"
  550. end
  551.  
  552. function helpSomSimpleOrbitalMechanics2()
  553.   print "Usage: calcSomSiderealOrbitalPeriodFromApPeMbrGm(Ap, Pe, MainBodyRadius, GM)"
  554.   print "   Returns the period in seconds of the orbit, given Ap"
  555.   print "   the Apoapsis, Pe the Periapsis, and GM the gravitational"
  556.   print "   parameter of the body being orbited."
  557.   print "Usage: calcSomOrbitalVelocityFromaGmRfcb(a, GM, RadiusFromCentralBody)"
  558.   print "   a is the semi-major axis in meters"
  559.   print "   GM is the standard gravitational parameter in m^3/s^2 (also known as u)"
  560.   print "   RadiusFromCentralBody is the distance in meters from the orbiting object"
  561.   print "     to the center of gravity it's orbiting (i.e. the center of the planet)"
  562.   print "   returns the orbital velocity in m/s"
  563.   print "Usage: calcSomOrbitalVelocityFromaGmAltaslMbr(a, GM, AltitudeASL, MainBodyRadius)"
  564.   print "   a is the semi-major axis in meters"
  565.   print "   GM is the standard gravitational parameter in m^3/s^2 (also known as u)"
  566.   print "   AltitudeASL is the altitude above sea level in meters"
  567.   print "   MainBodyRadius is the equatorial radius of the body being orbited in meters"
  568.   print "Usage: calcSomGMFromaOvRfcb(a, OrbitalVelocity, RadiusFromCentralBody)"
  569.   print "   a is the semi-major axis in meters"
  570.   print "   OrbitalVelocity is the orbital velocity in m/s"
  571.   print "   RadiusFromCentralBody is the distance in meters from the orbiting object to"
  572.   print "     the center of gravity it's orbiting (i.e. the center of the planet)"
  573.   print "   returns GM, the standard gravitational parameter in m^3/s^2 (also known as u)"
  574. end
  575.  
  576. function helpSomSimpleOrbitalMechanics3()  
  577.   print "Usage: calcSomGMFromaOvAltaslMbr(a, OrbitalVelocity, AltitudeASL, MainBodyRadius)"
  578.   print "   a is the semi-major axis in meters"
  579.   print "   OrbitalVelocity is the orbital velocity in m/s"
  580.   print "   AltitudeASL is the altitude above sea level in meters"
  581.   print "   MainBodyRadius is the equatorial radius of the body being orbited in meters"
  582.   print "   returns GM, the standard gravitational parameter in m^3/s^2 (also known as u)"
  583.   print "Usage: guessSomWhatBodyIsTheMainBodyFromaOvAltaslMoe(a, OrbitalVelocity, AltitudeASL, MarginOfError)"
  584.   print "   a is the semi-major axis in meters"
  585.   print "   OrbitalVelocity is the orbital velocity in m/s"
  586.   print "   AltitudeASL is the altitude above sea level in meters"
  587.   print "   returns the SimpleOrbitalMechanics name of the body we think we're orbiting."
  588.   print "     suitable to pass to globalSomMainBodyReset, or UNKNOWN if it cannot tell"
  589.   print "Usage: calcSomPeorapFromAporpeMbrGmSop(Aporpe, MainBodyRadius, GM, SiderealOrbitalPeriod)"
  590.   print "   Aporpe is either Apoapsis or Periapsis, in meters - you don't even need to know which"
  591.   print "   MainBodyRadius is the equatorial radius of the body being orbited in meters"
  592.   print "   GM is the standard gravitational parameter in m^3/s^2"
  593.   print "   SiderealOrbitalPeriod is the sidereal orbital period in seconds you wish the orbit to have"
  594.   print "   returns the Peorap (if given Apoapsis, returns Periapsis; if given Periapsis, returns Apoapsis"
  595.   print "      and if you don't know which you're giving it going in, whichever is bigger at the end is Apoapsis)"
  596.   print "   WARNING WARNING WARNING - there's every chance this orbit will kill you or send you out of the local orbit!!!!"
  597.   print "      Use isSomOrbitStableFromApPeHsoiMsa to check your orbit before using!!!"
  598. end
  599.  
  600. function helpSomSimpleOrbitalMechanics4()  
  601.   print "Usage: calcSomMolniyaPeorapFromAporpeMbrGmSrp(Aporpe, MainBodyRadius, GM, SiderealRotationalPeriod)"
  602.   print "   Aporpe is either Apoapsis or Periapsis, in meters - you don't even need to know which"
  603.   print "   MainBodyRadius is the equatorial radius of the body being orbited in meters"
  604.   print "   GM is the standard gravitational parameter in m^3/s^2"
  605.   print "   SiderealRotationalPeriod is the sidereal rotational period in seconds of the body being orbited"
  606.   print "   returns the Peorap (if given Apoapsis, returns Periapsis; if given Periapsis, returns Apoapsis"
  607.   print "      and if you don't know which you're giving it going in, whichever is bigger at the end is Apoapsis)"
  608.   print "      for a Molniya orbit, i.e. a semisynchronous orbit (two orbits per day)"
  609.   print "   WARNING WARNING WARNING - there's every chance this orbit will kill you or send you out of the local orbit!!!!"
  610.   print "      Use isSomOrbitStableFromApPeHsoiMsa to check your orbit before using!!!"
  611.   print "Usage: calcSomApPeFromAporpePeorap(Aporpe, Peorap)"
  612.   print "   Aporpe is either Apoapsis or Periapsis, in meters - you don't even need to know which"
  613.   print "   Peorap is either Periapsis or Apoapsis, in meters - you don't even need to know which"
  614.   print "   returns Ap, Pe"
  615.   print "   Ex: "
  616.   print "       local localAp, localPe = calcSomApPeFromAporpePeorap(75000,3095000)"
  617.   print "       print(\"Ap: \" .. localAp .. \" Pe: \" .. localPe)"
  618.   print "Usage: testSomTestHarness()"
  619.   print "   Just run it - if you get a message, something's broken.  Read this code for usage guidance!!!"
  620.   print "Usage: isSomOrbitStableFromApPeHsoiMsa(Ap, Pe, HillSphereOfInfluence, MinStableAltitude)"
  621.   print "   Returns 0 for stable, 1 for burn up in atmosphere, 2 for escape"
  622.   print "   sphere of influence (SOI), and 3 for burn up AND escape SOI"
  623.   print "   All values must be in the same units, including Ap Apoapsis,"
  624.   print "   Pe Periapsis, HillSphereOfInfluence the Hill sphere of"
  625.   print "   gravitational influence, and MinStableAltitude, the minimum"
  626.   print "   altitude to be out of the atmosphere and above the highest"
  627.   print "   mountain."
  628. end
  629.  
  630. function helpSomSimpleOrbitalMechanics5()
  631.   print "Usage: calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe(HillSphereOfInfluence, MinStableAltitude, MainBodyRadius, GM, SiderealRotationalPeriod, MarginOfError)"
  632.   print "   HillSphereOfInfluence is the range in meters at which the gravity of the body is effective"
  633.   print "   MinStableAltitude is the altitude above sea level in meters at which orbiting is safe and stable"
  634.   print "     i.e. it's above both the atmosphere's effects, and the tallest mountains."
  635.   print "   MainBodyRadius is the equatorial radius of the body being orbited in meters"
  636.   print "   GM is the standard gravitational parameter in m^3/s^2"
  637.   print "   SiderealRotationalPeriod is the sidereal rotational period in seconds of the body being orbited"
  638.   print "   MarginOfError 0.001 means allow 0.1% for a \"safety zone\" above the minimum stable altitude, or below the Hill sphere of influence."
  639.   print "   Returns Ap and Pe of the best possible Molniya orbit for a given body"
  640.   print "     Returns -1, -1 if no stable Molniya orbit is possible"
  641.   print "   ex."
  642.   print "       do"
  643.   print "       local localAp, localPe = calcSomMolniyaApPeFromHsoiMsaMbrGmSrpMoe(1500000000, 180000, 6378100, 398600441800000, 86164.098903691, 1.777777777)"
  644.   print "       print(\"Ap \" .. localAp .. \" Pe \" .. localPe)"
  645.   print "       end"
  646.   print "   For oblate celestial bodies, of course, the inclination of the actual orbit must be 63.4 or 116.6 degrees, so the effect"
  647.   print "     of the oblate equitorial belt is nullified."
  648.   print "Usage: calcSomDeltaVFromIspTsmTem(Isp, TotalStartingMass, TotalEndingMass)"
  649.   print "   Isp is the Specific Impulse in seconds"
  650.   print "   TotalStartingMass is the total mass before the burn, including fuel - units must be the same as TotalEndingMass"
  651.   print "   TotalEndingMass is the total mass after the burn, including remaining fuel - units must be the same as TotalStartingMass"
  652.   print "   returns Delta-V in meters per second."
  653.   print "   Ex:"
  654.   print "     print(calcSomDeltaVFromIspTsmTem(390,15,10))"
  655.   print "Usage: calcSomIspFromTsmTemDv(TotalStartingMass, TotalEndingMass, DeltaV)"
  656.   print "   TotalStartingMass is the total mass before the burn, including fuel - units must be the same as TotalEndingMass"
  657.   print "   TotalEndingMass is the total mass after the burn, including remaining fuel - units must be the same as TotalStartingMass"
  658.   print "   returns Isp, the Specific Impulse in seconds"
  659.   print "   Ex:"
  660.   print "     print(calcSomIspFromTsmTemDv(15,10,1550))"
  661. end
  662.  
  663. globalSomOverallInit() -- initialize required variables up front
  664.  
  665. print "Usage: helpSomSimpleOrbitalMechanics1() through helpSomSimpleOrbitalMechanics5()"
  666. print "   gives detailed help on all Som functions."
  667. print "   Som functions relate to orbital mechanics as a whole, in real life and in KSP."
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement