Scene Components

Controllers

GSController

GSController is responsible for:

  • creating an instance of GravityEngine (GE)

  • detecting the bodies to be added to the GE

  • detecting the display controllers that will coordinate displaying of those bodies that have display components attached

  • evolving the GE system based on Update() and potentially LateUpdate() Unity callbacks

There can be multiple instances of this class in the scene and they will all operate independently.

The inspector view is:

GSController

GSBody Add: This determines which GSBody components are to be added to this controller on scene start.

  • CHILDREN: Find all GSBody components in the hierarchy below this object

  • LIST: Provide an explicit list of GSBody objects in the inspector. When selected the inspector will provide a field to list GSBody scene elements

  • SCENE: Scan the entire scene for GSBody components

Evolve Mode: The internal evolution used by the underlying GravityEngine. The key distinction is that immediate mode runs the GE physics loop as part of the GSController update cycle. This means that all GE API calls can be used at any point in other scripts. The use a job mode means that the GSController update will schedule the physics job during Update() and then ask for the job to complete in LateUpdate(). GravityEngine will not allow direct API interaction if a job is running in the background and instead interaction is done by requesting a callback on the completion of the physics job via GravityEngine.PhyLoopCompleteCallbackAdd().

(Note that I expect to develop a mode that runs the job from one Update() cycle to the next frame Update() in a later release).

The modes are:

  • IMMEDIATE: Run physics (and particles if present) in the GSController update loop. Allows direct GE API use

  • IJOB_LATEUPDATE: Schedule physics core as a Job in Update. Complete in LateUpdate(). Requires GE interactions via callbacks.

  • IMMEDIATE_FIXEDUPDATE: Run physics/particles based on FixedUpdate() timing and update display code on the Unity Update() call. (generally useful to configure display code to use Display Mode = INTERPOLATE)

Integrator: N-body evolution (GRAVITY mode in GSBody) requires numerical integration of the forces. This is the core of the physics engine. The precision of the simulation is highly dependent on the choice of the integration method and the selection of timestep and scaling.

  • LEAPFROG: Use first order Leapfrog/Verlet. Very efficient and conserves energy well.

  • RK4: Fourth order Runge-Kutta. The workhorse method in the numerical differential equation world. Does more computations per time step that Leapfrog

Integrator Steps/Orbit: The number of steps the integrator should take for the reference orbit described by the orbit mass scale and orbit length scale below. 200 steps is a reasonable default for orbits that are not highly eccentric. If the resulting time step is longer than the typical time per frame (scaled appropriately) then the timestep will be made smaller resulting in more steps per orbit than specified here.

Default Length Units: The choice of world units for the GSController and the units in which most GE API calls will return values (the exception being recorded output). See scaling

Force All Bodies to Default Units Button: This button switches all GSBody objects under control of this GSController to the default units set in this controller.

Game Sec Per Orbit: For the specified orbit scale and mass adjust the run time scaling so that one orbit takes this long.

Orbit Scale: The size of a typical orbit in the scene in the default units.

Orbit Mass Scale: The mass of the central body for a typical orbit. Generally the mass of the heaviest object in the scene.

Autoset Orbit/Mass Scale Button: This button will scan the GSBody objects that are set to be part of this controller and determine the maximum mass in the collection and an average orbit distance.

Scaling Details (Foldout): Shows the value of dt that was determined based on the default scaling and game sec per orbit.

Trajectory Prediction (Foldout) See Trajectories for an overview of this feature. GSDisplayBody components may elect to have a future projection path plotted with a LineRenderer. This is generally used when N-body motion is happening and a simple orbit extrapolation with GSDisplayOrbit is not sufficiently accurate due to the effects of other masses.

Time Ahead: The world time interval for which a trajectory will evolved into the future.

Number of Steps: The number of steps used in recording each future trajectory.

Start World Time (Foldout) These field specify the start world time. This is optional and is used when either:

  • there are orbits initialized with two-line element information (embedded in this info is a time at which the info is valid)

  • orbits have been build with the solar system builder with orbit elements defined at a specific time

The start time must be set to a value equal or later than the latest time in any of the GSBody components. (This is because e.g. the SGP4 propagator cannot compute times before the TLE start time). This can be done automatically by using the utility button to scan for the latest TLE start time and set the GSC time accordingly.

An additional button can be used to set the start time based on the current time.

Debug Keys: When enabled the controller will check for specific key presses during the Update() phase:

  • D: dump the internal GE state to the console (implemented as a callback so will get a coherent dump in job mode)

  • P: pause/go the execution of GE

  • 1-9: adjust the amount of world time evolved for each game second. The zoom factors are (1-9): 1f, 2f, 3f, 4f, 5f, 10f, 20f, 50f, 100f.

GSDisplay

The display of objects, orbit paths and trajectories is handled by the GSDisplay component. It detects (or is given) a set of objects that implement the GSDisplayObject base class. Most commonly this will be GSDisplayBody and GSDisplayOrbit components. The display bodies will typically have some graphics object (a sphere or mesh) that will show the body in the scene.

There can multiple instances of display controllers and more than one display body to represent a GSBody in a GSController. This allows e.g. a mini-map to be displayed.

The origin of the displayed system is the transform position of the GSDisplay and the rotation will adjust the overall rotation. The scale of the transform will not adjust the scale, this is done by a specific field in the GSDisplay inspector. The scale used in the component is the factor used to map from the default world space units specified in the GSController to position values of the display objects (e.g. GSDisplayBody). GSDisplay does provide a tool to set this value automatically once the scene has been configured with GSBody objects.

The GSDisplay inspector view is:

GSDisplay

Active When true, this component will display the display objects it is responsible for.

GSController The GSController that is controlling the bodies to be displayed. If the controller is the parent this will be detected automatically.

Display Scale the scale factor to apply to the position in world units to be used for display of body positions and orbits. As a general rule Unity prefers position values of less than 1E5 units in the transform of a game object. Values beyond this will generate warnings.

Auto Scale Foldout Display scaling is intended to limit the maximum transform position to something “reasonable” in the context of the game scene. This may be a few hundred position units or up to the Unity soft limit of 100,000. In dimensionless units this may be a simple factor (even 1.0) but when more real-world units (Earth orbits, solar system) are defined determining a reasonable value gets more complicated. The “Scan Scene and Set Scale” button helps.

Max Scene Dimension Defines the scene distance to be used for the object in world space with the largest position value

Scan Scene and Set Scale (button) Computes a display scale value and fills in the field. This operates by asking the associated GSController for the initial position of each body that will be displayed by this component. The maximum value is then divided by the maximum scene dimension to determine a scale factor.

AddMode Determines how the display objects under the control of this GSDisplay will be found

  • CHILDREN: Find all objects that are attached to children of the GSDisplay component

  • LIST: Use the list of objects provided (a list entry will appear when this is selected)

  • SCENE: scan the scene for all objects extending GSDisplayObject

XZ Orbital Plane Locate orbits in the Unity XZ plane. This results in the display coordinates of an object at world position \((x, y, z)\) to be displayed at \((x, z, y)\). This shift from the right-handed physics coordinate system to Unity’s left-handed coordinate system make the orbits match the usual form with respect to rotation directions and ascending/descending node positions. See RH vs LH Coordinates.

Display Mode

  • DIRECT: Show the current scaled positions from the GE. Note that due to numerical step size this may jitter ahead or behind of the elapsed game time by a small amount.

  • INTERPOLATE: Adjust the displayed positions by interpolating the position to the exact game time based on the given velocity.

World Center This optional field allows the display controller to center the scene on a position of a specific GSBody. This can be useful to maintain the player ship at the origin and to give all other scene objects a position and velocity relative to the ship.

Per Body Elements: GSBody

The GSBody component is the component that describes a body that will be evolved using GE2. As a result it contains a lot of details. The overall inpsector view is show below. Each section is then described in further detail below.

GSBody_MP

GSBody is a key scene component used to describe a body that GravityEngine will evolve according to N-body physics or under the control of a specific propagator. It allows for the initial conditions of the body to be specified in a variety of ways:

  • absolute position and velocity

  • position and velocity relative to another GSBody

  • orbital elements with respect to another GSBody

  • fixed in the scene

  • Earth satellite two-line element state information (from e.g. celestrak.org)

‘GSBody` also describes how GE is to evolve the body, see the description of ‘Propagator’ below.

The first two inspector fields are common to all input formats:

GSBody_MP

Mass: The mass of the object. In dimensionless units this value is arbitrary and only it’s value relative to other bodies is important. In dimension-full units this is in kilograms and typically very large (e.g. Earth is of order E24 kg). Spaceships and satellites are typically given zero mass since they have no appreciable effect on e.g. the Earth they are orbiting. Massless objects are maintained separately in GravityEngine since these objects do not affect others the force they impart on other bodies can be skipped resulting in less CPU use. Note that in an N-body system the massive interactions grow as \(N^2\). The smaller the number of massive objects, the better.

Propagator:

  • GRAVITY: Evolve using N-body Newtonian gravitation i.e. “normal gravity”

  • KEPLER: Evolve deterministically along a conic around a specified central body using Kepler’s equation

  • PKEPLER: Evolve deterministically along a conic around the Earth modelling the J2 non-spherical Earth and optionally adding drag

  • SGP4_RAILS: Evolve using the SGP4 Earth satellite propagator. This propagator includes J2, atmosphere and effects of the moon and sun for larger orbits.

  • FIXED: Maintain the body in a fixed position.

  • EPHEMERIS: Evolve the body according to a table of R, V values for specific times, interpolating as required.

  • UNASSIGNED: No choice made. Will result in an error when scene is played.

There are several inspector views depending on the input format selected. Several of them are shown below. Before describing them we describe the remaining common input field: Patched.

Optional Physical Info

GSBody_RV

The optional foldout “Optional Physical Info” provides a place to specify some physical attributes of celestial bodies that may be useful to the display and game code. (If the SolarSystemBuilder is used, this information will be filled in when the values are known to the JPL Horions database).

The radius of the objects (in GSBody default units) can be specified.

Information on the rotation of the body can also be specified by providing the rotation rate (in radians/world seconds) and the rotation axis.

Patched: A body may elect to use some of the on-rails propagators (most commonly KEPLER) in patched mode.

RV Initial Data

GSBody_RV

The inspector fields for the RV data are simple double fields for the values of the position and velocity vector in the specified units.

These values may be given in absolute terms or relative to some other GSBody.

Orbit Initial Data

A body in orbit around another body can be specified by providing the classical orbital elements (COE) or minor variations in which instead of specifying the semi-major axis size, the apoapsis/periapsis (for Earth this would apogee/perigee) can be provided. A separate option exists for specifying a hyperbola where only the periapsis is required.

GSBody_COE

The orbital elements divide into the those describing size/shape and orientation. See FIG XX.

Semi-Major Axis: (size) indicates the size from the true center of an ellipse to the farthest point.

Eccentricity (e): The shape of the orbit. Closed orbits (\((e < 1)\)) are circular when \(e=0\) and more elongated as \(e\) gets close to \(1\). Orbits with \(e > 1\) are hyperbolas and the COE_HYPERBOLA input mode is a better choice.

The next parameters relate to the orientation of the orbit in space.

Inclination (i):

OmegaU/RAAN (\(\Omega\)):

OmegaL/Argument of Periapsis (\(\omega\)):

True Anomaly (\(\nu\)):

An alternative to defining the shape and size with (\(a, e\)) is to use the periapsis and apoapsis. This can be done by selecting COE_ApoPeri as the input mode.

Two Line Element

For Earth satellites on-line databases provide state information at a given time (also referred to as epoch). Historically these were “computer card friendly” so they are formatted in a somewhat odd two line, 80 character format. For example from Celestrak.org for the International Space Station

ISS (ZARYA)             
1 25544U 98067A   24011.38118347  .00015819  00000+0  28198-3 0  9997
2 25544  51.6404  17.2554 0003852  20.7619 339.3526 15.50260516434080

This can be pasted directly into the text field when the SGP4_ONRAILS input mode is selected.

GSBody_Ephemeris

Note the use of this input format assumes the scene has an Earth with the correct mass (it will check and warn you if not) and some form of units other that DIMENSIONLESS has been selected.

Ephemeris

The path of a body can be directed from a file providing a CSV table of values of the form \((t, r_x, r_y, r_z, v_x, v_y, v_z)\). When the Ephemeris propagator is selected the initial data for the body will come from the ephemeris file and is not configurable in the inspector.

The .txt file should be placed in a Resources folder somewhere within the project and then the name of the resource (without the .txt extension) is provided in the inspector field.

A toggle box also indicates if the positions are relative to some center body or are absolute world position units.

GSBody_Ephemeris

An example of this operation can be found in the going further sample Ephemeris.

Display Objects

The display of GE2 objects is controlled by a separate component than the component describing their initial conditions and propagation. This allows decoupling of display and evolution allowing e.g.

  • zoomed in views to select only the bodies of interest to render. For example, if zoomed in on Jupiter and its moon, there is little point in displaying Mercury in the scene.

  • multiple display views of the same objects, with different visual representations e.g. a mini-map with labels and dots

The display of a set of objects is the GSDisplay component described above. The objects it will display will make use of one of the following components.

GSDisplayBody

GSDisplayBody holds a reference to a GSBody. When the GSController has completed a physics update cycle it will direct the GSDisplay to display all objects that have registered to display themselves. This will result in the transform position of the game object containing the GSDisplayBody to updated with the physics position, scaled from world space by the GSDisplay scale and then positioned in the scene with respect to the GSDisplay position and rotation information.

GSDisplayBody

A display body may also elect to indicate that a look-ahead trajectory is to be computed. This is used when there are N-body effects and a simple orbit prediction does not show the correct future path of a body. This is a potentially CPU expensive operation, especially if there are frequent maneuvers that require trajectories to be re-calculated.

GSBody The GSBody that is to be displayed with this component.

Show Trajectory If enabled the future evolution/propagation of this body will be computed by the GSController/GECore. Internally this will result in the creation of a GECore clone that runs the time ahead (by the amount specified in the GSController) and records the future positions. These positions are then used to populate a line renderer for this display body as specified in the Line for Trajectory field.

Optional Display Object Fields

Rotation Display Object Typically a game object with a GSDisplayObject has a child with some renderable mesh to represent the object in the scene. This may be a simple sphere (in the case of celestial bodies) or a mesh for a ship. There are a number of attributes linked to a physical celestial body that can be useful in the display. If the planet radius is known, it can be used to scale the sphere mesh accordingly. If there is a rotation axis and rate provided the information can be used to apply a rotation to the game object holding the sphere mesh. This is done if the Rotate Display Object toggle is enabled.

GSDisplayBody

There is one toggle Earth@Time Offset that is unique to the special case of a rotating Earth. An issue arises with the initial rotation of the Earth in cases where it is important that the relative alignment of the Earth texture correspond to a specific world time. This is described in more detail in the discussion of Earth Orbit with Map.

Velocity Align Display Object The model of a display object can be aligned with the velocity of the body. This is useful when modeling a rocket launch to keep the axis of the rocket aligned with the velocity as the rocket ascends to orbit (while pitching over as it climbs). This mode is selected by the enum value VEL_ALIGN.

When set the fields to be filled in are:

Display GO Axis: Which axis of the display object is to be aligned with the velocity vector.

Display GO Yaw (deg): How is the object to be aligned on this axis (i.e. rotation around the velocity vector)

GSDisplayBody

GSDisplayOrbit

This component displays the orbit of a body around a central mass. The plot of the orbit assumes the central mass is the only mass having a significant effect on the orbiting body and that the mass of the orbiting body is very small or zero. If the orbiting body is not nearly massless then the resulting system will in reality be rotating around the center mass of the binary pair and must be handled differently. See XXX.

An orbit may be displayed for an existing display body in the scene (if ‘Track GSDisplayBody’ is selected) or the orbit may be specified explicitly using any of the input modes that are defined for a GSBody. See gsbody. This can be useful in cases where the scene wished to show a target orbit (e.g. geosynchronous parking orbit) without requiring a specific body to be in that orbit.

The GSDisplay that is managing the display orbit component will be called each update cycle and compute an updated orbit path and fill in the LineRenderer specified in the display orbit component. It will also update the orbit parameters in the inspector, if this is visible in the Unity editor.

GSDisplayOrbit

The fields in the inspector are:

Enabled: Check box to indicate the component should update the line renderer and inspector values.

Frames Between Updates Number of Update() frames between updates to the orbit display line renderer. Computing all the points on an orbit path can consume significant runtime when many orbits are displayed. This parameter allows the update to be performed less often. The GSDisplay code that manages this ensures that the orbit computation for multiple display orbits is spread out over multiple frames to avoid “bursty” updates.

Track GSDisplayBody: If enabled indicated that the orbit to be plotted is the orbit of a specified GSDisplayBody with respect to a center object (also a GSDisplayBody). If this option is not selected the inspector will look different and will display the same style of input as appears in a GSBody to specify the initial data for the body (RV, COE etc.)

GSDisplayBody To Track: Reference to the body to show the orbit of

Center Display Body: Reference to the object the tracked body is in orbit around.

Line Renderer: Reference to the line renderer to be used to display the orbit

Number of Points: Number of points to plot for the orbit

Orbit Elements in Inspector

When running the inspector will show the orbit elements as the scene runs.

GSDisplayBody

GSOrbitPoint

A specific point in an orbit can be visualized by using the GSDisplayOrbitPoint component. This takes a reference to a GSDisplayOrbit and then provides a selection of the standard points in an elliptical orbit. Alternately an orbit position can be specified by a the orbital angle (true anomaly) expressed in degrees.

Note that depending on the orbit shape, not all orbit locations are valid:

  • a circular orbit does not have an apoapsis or periapsis since all points are equidistant from the center. (a phase of 0 will be used if this applies)

  • ascending and descending node only apply to an inclined orbit (a phase of 0 will be used for a flat orbit)

GSDisplayBody

The enum for the orbit point has values:

GSDisplayBody

GSDisplayOrbitSegment

An alternative to display the entire orbit of a body is to display a segment of an orbit. This is used in the multi-maneuver scene to show sections of orbits that are between orbit changes due to maneuvers. The overall component is similar to full orbit display but additional information about the from and to locations in the orbit are required. A position in an orbit can be expressed as one of several choices:

GSDisplayOrbitSegPoint

This allows the selection of the typical orbit points (apoapsis, periapsis, nodes; assuming these are valid for the orbit shape) or the position of a specific GSBody or an absolute position vector.

The full inspector view is:

GSDisplayOrbitSeg

GSTransferShip

One of the workhorse components in GE2 is GSTransferShip. It handles the “make it so” task of orbital mechanics. How does a ship in orbit A get to point B or rendezvous with a ship in orbit B?

At a high-level, the component needs to know:

  • the ship to maneuver

  • the target orbit or ship

  • reach orbit, rendezvous or intercept

When the transfer is initiated (either with the key press ‘T’ if enabled, or with a call to the Transfer() method) the code will compute the maneuvers required to accomplish the indicated end state. GSTransferShip is a scene component wrapper for the TransferShip script, a non-Mono class that does the core calculations and in turn relies on scripts that compute Hohmann and Lambert transfers. For pure scripting applications this script can be used directly.

GSDisplayBody

The inspector fields are:

GSController: The GSController component that has responsibility for both the ship and the center body.

Ship: A reference to the GSBody for the ship that will be maneuvering

Center Body: A reference to the GSBody that the ship is in orbit around.

Transfer Mode: A selector that determines what the target of the transfer is (e.g. orbit vs another ship). Depending on the selection there will be input requested to denote a target ship (GSBody) or a target orbit (GSDisplayOrbit)

  • SHIP_TO_ORBIT: Transfer to the indicated target orbit

  • TARGET_ORBIT: Transfer to the same orbit as the target ship

  • TARGET_RDVS: Transfer to rendezvous with the target ship.

  • TARGET_INTERCEPT: Transfer to intercept the target (do not match target velocity with a final maneuver)

  • SHIP_TO_POINT: Transfer to the specified point

  • CIRCULARIZE: Circularize the orbit at the current position. Does not require any target information.

Lambert Always: Require the computed transfer to always be a Lambert transfer even if both the initial and final orbits are circular.

Lambert Time Factor: A Lambert transfer requires a transfer time to be specified. To make this dimensionless the script will determine the time for the minimum energy Lambert transfer and then adjust the time by multiplying by this factor. For a minimum energy transfer this is set to 1.0, faster: < 1.0, slower > 1.0.

Circularity Threshold The eccentricity limit below which an orbit will be considered circular and a Hohmann transfer will be possible.

There are two UI/debug options:

Press T to Transfer: Enables checking for the press of the ‘T’ key and initiates a transfer when it is pressed.

Transfer At Start: Initiates the transfer as soon as the scene has started and GE2 has initialized.