Skip to content

Commit

Permalink
Merge pull request #2415 from Dunbaratu/fixes_2413_g0
Browse files Browse the repository at this point in the history
added constant:g0, and edited the doc more about G vs G0.
  • Loading branch information
erendrake authored Jan 29, 2019
2 parents ca3a6d1 + a23eac7 commit 3d8d28b
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 8 deletions.
62 changes: 60 additions & 2 deletions doc/source/math/basic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ constants about the universe that you may find handy in your math operations. P
- Description

* - :global:`G`
- Newton's Gravitational Constant
- Newton's Gravitational Constant.
* - :global:`g0
- gravity acceleration (m/s^2) at sea level on Earth.
* - :global:`E`
- Base of the natural log (Euler's number)
* - :global:`PI`
Expand All @@ -41,7 +43,63 @@ constants about the universe that you may find handy in your math operations. P

.. global:: Constant:G

Newton's Gravitational Constant, 6.67384E-11::
Newton's Gravitational Constant that the game's planetary
bodies are implying in their configuration data.
(6.67384E-11 as of the last update to these documents).

Note, the stock KSP game never technically records a value
for G in its data. kOS derives this value by calculating it
based on the Sun's Mass and its Gravitational Parameter. It
is possible for a mod (or perhaps a future release of KSP, if
mistakes were made) to define a universe in which Newton's
Gravitational Constant, G, isn't actually constant at all
within that game universe, and instead varies from one sphere
of influence to the next. Such a universe would be breaking
some laws of physics by a lot, but it is technically possible
in the game's data model. Due to this strange misfeature in
the game's data model, it is probably safer to always have
your scripts use the body's Mu in your formulas instead of
explicitly doing mass*G to derive it.

Do NOT confuse this with ``Constant:g0`` below.

Example::

PRINT "Gravitational parameter of Kerbin, calculated:".
PRINT constant:G * Kerbin:Mass.
PRINT "Gravitational parameter of Kerbin, hardcoded:".
PRINT Kerbin:Mu.
PRINT "The above two numbers had *better* agree.".
PRINT "If they do not, then your solar system is badly configured.".

.. global:: Constant:g0

Standard value the game uses for acceleration due to
gravity at sea level on Earth. (9.80655 m/s^2 as
of the last update to these documents).

Do NOT confuse this with ``Constant:G`` above.

The place where this matters the most is in ISP
calculations. The rocket equation using ISP
contains an inherent conversion from mass to weight
that basically means, "what would this mass of fuel
have weighed at g0?". Some kind of official standard
value of g0 is needed to use ISP to predict truly
accurately how much fuel will be burned in a scenario.

In pretty much any other calculation other than using
ISP in the Rocketry Equation, you should probably
not use g0 and instead calculate your local gravity
more precisely based on your actual radius to the body
center. Not only because this is more accurate, but
because the g0 you see here is NOT the g0 you would
actually have on Kerbin's sea level. It's the g0 on
Earth, which is what the game's ISP numbers are using.
Kerbin's sea level g0 is ever so slightly different
from Earth's g0 (but not by much.)

::

PRINT "Gravitational parameter of Kerbin is:".
PRINT constant:G * Kerbin:Mass.
Expand Down
8 changes: 8 additions & 0 deletions src/kOS.Safe/Encapsulation/ConstantValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,18 @@ public static double GravConst
get { return gravConstBeingUsed; }
set { gravConstBeingUsed = value; }
}

private static double g0 = 9.80665; // Typically accepted Earth value. Will override with KSP game value.
public static double G0
{
get { return g0; }
set { g0 = value; }
}

static ConstantValue()
{
AddGlobalSuffix<ConstantValue>("G", new StaticSuffix<ScalarValue>(() => GravConst));
AddGlobalSuffix<ConstantValue>("G0", new StaticSuffix<ScalarValue>(() => G0));
AddGlobalSuffix<ConstantValue>("E", new StaticSuffix<ScalarValue>(() => Math.E));
AddGlobalSuffix<ConstantValue>("PI", new StaticSuffix<ScalarValue>(() => Math.PI));
AddGlobalSuffix<ConstantValue>("C", new StaticSuffix<ScalarValue>(() => 299792458.0, "Speed of light in m/s"));
Expand Down
33 changes: 27 additions & 6 deletions src/kOS/Module/kOSProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using kOS.Safe.Execution;
using UnityEngine;
using kOS.Safe.Encapsulation;
Expand Down Expand Up @@ -427,7 +428,7 @@ public void InitObjects()
}
objectsInitialized = true;

CalcGravConstFromKSP();
CalcConstsFromKSP();

shared = new SharedObjects();

Expand Down Expand Up @@ -504,13 +505,33 @@ public void InitObjects()
InitProcessorTracking();
}

// The official value of "G" changes over time as standards bodies re-calculate it.
// This code below ensures we're using whatever value KSP itself is using. (KSP updated
// it once in the past, so hardcoding it as a literal in kOS code isn't such a good idea.)
// The official value of some physics constants change over time as standards bodies re-calculate them.
// This code below ensures we're using whatever value KSP itself is using.
// The reason this code is *here* not in ConstantValue is because ConstantValue can't call
// the KSP API. It's in kOS.Safe.
private void CalcGravConstFromKSP()
{
private void CalcConstsFromKSP()
{
// GravitationalAcceleration did not exist in PhysicsGlobals prior to KSP 1.6.x.
// This code has to use reflection to avoid calling it on older backports:
Type physGlobType = typeof(PhysicsGlobals);
if (physGlobType != null)
{
// KSP often changes its mind whether a member is a Field or Property, so let's write this
// to future-proof against them changing which it is by trying both ways:
FieldInfo asField = (physGlobType.GetField("GravitationalAcceleration", BindingFlags.Public | BindingFlags.Static));
if (asField != null)
ConstantValue.G0 = (double) asField.GetValue(null);
else
{
PropertyInfo asProperty = (physGlobType.GetProperty("GravitationalAcceleration", BindingFlags.Public | BindingFlags.Static));
if (asProperty != null)
ConstantValue.G0 = (double)asProperty.GetValue(null, null);
}
}
// Fallback: Note if none of the above work, G0 still does have a reasonable value because we
// hardcode it to a literal in ConstantValue before doing any of the above work.


// Cannot find anything in KSP's API exposing their value of G, so this indirect means
// of calculating it from an arbitrary body is used:
CelestialBody anyBody = FlightGlobals.fetch.bodies.FirstOrDefault();
Expand Down

0 comments on commit 3d8d28b

Please sign in to comment.