Space Engineers

Space Engineers

Not enough ratings
Programmable block interface for OSE
By Knsgf
This guide lists all properties and actions that OSE exports to Programmable block.
   
Award
Favorite
Favorited
Unfavorite
IMyCockpit and IMyRemoteControl actions and properties
To facilitate orbital navigation, OSE adds several action buttons to cockpits and RC blocks.
The first 2 actions select mode in which inertia dampers operate:
  • IDFullStopActivate - in this mode ID will bring a ship to a full stop, like in vanilla game,
  • IDCirculariseActivate - in this mode ID will attempt to circularise ship's orbit at current altitude, while minimising plane change.

The following actions allow a ship to perform various orbital manoeuvres. They do not require a ship to point in any particular direction and can be activated even if inertia dampers are turned off. To stop a manoeuvre, simply apply the corresponding action again.
  • IDProgradeActivate - fires engines in direction of ship's velocity,
  • IDRetrogradeActivate - fires engines in direction opposite of ship's velocity,
  • IDNormalActivate - fires engines perpendicular to orbital plane in positive normal direction,
  • IDAntiNormalActivate - fires engines perpendicular to orbital plane in negative normal direction,
  • IDInwardActivate - fires engines perpendicular to ship's velocity in radial direction,
  • IDOutwardActivate - fires engines perpendicular to ship's velocity in anti-radial direction.

Scripts can query current ID mode and running manoeuvre by calling
GetValue<int>("CurrentIDMode") on a cockpit or remote control block:
Value
Mode or manoeuvre
0
Full stop, no manoeuvre
1
Circularise, no manoeuvre
2
Prograde
3
Retrograde
4
Normal
5
Anti-normal
6
Outward
7
Inward
IMyProgrammableBlock properties
OSE exposes several read-only delegate properties, which allow scripts to obtain extensive information about spacecraft's orbit. These functions are described in detail below.
Property
Type
Summary
ComputeOrbitElements
Func<string, string, bool>
Pre-calculates primary elements
ComputeOrbitElementsFromVectors
Func<string, Vector3D, Vector3D, bool>
Pre-calculates primary elements from state vectors
GetReferenceBodyName
Func<string>
Gets reference planet's name
GetPrimaryVectors
Action<Vector3D[]>
Retrieves primary vector elements
GetPrimaryScalars
Action<double[]>
Retrieves primary scalar elements
GetDerivedElements
Action<double[]>
Retrieves derived elements, which do not depend on ship's position
GetPositionalElements
Action<double?, double[]>
Retrieves ship's positional elements
GetStateVectors
Action<double, Vector3D[]>
Retrieves ship's state vectors

In addition to the above, OSE exports some auxiliary convenience functions:
Property
Type
Summary
ConvertTrueAnomalyToMean
Func<double, double, double>
Computes mean anomaly from true for orbit with given eccentricity
ConvertMeanAnomalyToTrue
Func<double, double, double>
Computes true anomaly from mean for orbit with given eccentricity
ComputeOrbitNormal
Func<double, double, Vector3D>
Computes orbit normal vector from given inclination and LAN
ComputeOrbitIntersections
Func<double, double, double, double, double, double, ValueTuple<double, double>?>
Computes orbit intersection points
ConvertRadialToTtrueAnomaly
Func<Vector3D, Vector3D, Vector3D, double, double>
Gets true anomaly from specified radius vector
ComputeOrbitElements()
Pre-calculates orbital elements for a given grid with respect to a specified planet. Doesn't return any elements by itself; those are retrieved using subsequent "Get..." calls.

Declaration
bool ComputeOrbitElements(string planetName, string gridName);

Parameters
  • planetName - exact name of the planet to use as a reference. Passing null auto-selects gravitationally dominant body,
  • gridName - exact name of the grid to get orbit elements from. If null, computes elements of Programmable block's ship.

Return value
true if specified planet and grid were located, false otherwise.

Notes:
  • Both planetName and gridName are case-sensitive,
  • In worlds with no planets, this function always returns false,
  • If <AllowScriptsToInspectOrbitOfAnyShip> tag is set to false in OSE.CFG, and the grid with gridName has no blocks owned by or allied with calling PB's owner then result will also be false.
ComputeOrbitElementsFromVectors()
Pre-calculates orbital elements from arbitrary state vectors with respect to a specified planet. Like ComputeOrbitElements(), it doesn't return any elements by itself.

Declaration
bool ComputeOrbitElementsFromVectors(string planetName, Vector3D radius, Vector3D velocity);

Parameters
  • planetName - exact name of the planet to use as a reference,
  • radius - location relative to planet,
  • velocity - self-explanatory.

Return value
true if specified planet was located and radius vector is non-zero, false otherwise.

Notes:
  • planetName is case-sensitive,
  • In worlds with no planets, this function always returns false.
GetReferenceBodyName()
Retrieves the name of the planet used in prior call to ComputeOrbitElements() or ComputeOrbitElementsFromVectors().

Declaration
string GetReferenceBodyName();

Return Value
Exact name of the planet, with respect to which orbital elements were calculated. Returns null if no call to ComputeOrbitElements() was made.
GetPrimaryVectors()
Gets primary orbit vectors. Requires prior call of ComputeOrbitElements() or ComputeOrbitElementsFromVectors().

Declaration
void GetPrimaryVectors(Vector3D[] output);

Parameter
output - an array of at least 6 elements, which is filled with the following values:
Index
Value
[0]
Specific angular momentum - a vector perpendicular to orbital plane whose magnitude is equal to areal velocity
[1]
Ascending node vector - unit vector that lies in XZ plane and points from the centre of the planet towards ascending node
[2]
Eccentricity vector pointing from the centre of the planet towards periapsis with length equal to orbit eccentricity
[3]
Local gravitational acceleration vector
[4]
Radius vector pointing from the centre of the planet towards ship's current position
[5]
Ship's velocity at current position
GetPrimaryScalars()
Gets primary orbit scalar elements. Requires prior call of ComputeOrbitElements() or ComputeOrbitElementsFromVectors().

Declaration
void GetPrimaryScalars(double[] output);

Parameter
output - an array with a length of least 7, which is filled with the following values:
Index
Value
[0]
Reference planet's radius
[1]
Semi-major axis
[2]
Eccentricity
[3]
Inclination in (-π, π) range
[4]
Longitude of ascending node, measured anti-clockwise from (X = 1, Y = 0, Z = 0) vector in XZ plane when viewed from -Y direction
[5]
Argument of periapsis in (0, 2π) range
[6]
Shp's current true anomaly in (0, 2π) range
GetDerivedElements()
Gets non-positional derived orbit elements. Requires prior call of ComputeOrbitElements() or ComputeOrbitElementsFromVectors().

Declaration
void GetDerivedElements(double[] output);

Parameter
output - an array with length of at least 5, which is filled with the following values:
Index
Value
[0]
Length of semi-latus rectum
[1]
Periapsis distance from the centre of the planet
[2]
Apoapsis distance from the centre of the planet
[3]
Mean motion - the amount of time for the ship to advance 1 radian in orbit on average
[4]
Orbit period. If orbit is hyperbolic, this value is set to -1.
GetPositionalElements()
Gets position-dependent orbit elements. Requires prior call of ComputeOrbitElements() or ComputeOrbitElementsFromVectors().

Declaration
void GetPositionalElements(double? trueAnomaly, double[] output);

Parameters
  • trueAnomaly - specifies custom position in orbit to use. When null, uses ship's current position,
  • output - an array with at least 7 elements, which is filled with the following values:
Index
Value
[0]
Mean anomaly at specified position. For elliptic orbits this value lies in (0, 2π) range. For hyperbolic trajectories, mean anomaly is positive on outbound leg and negative on inbound leg*.
[1]
Time elapsed since last periapsis passage. For hyperbolic orbits this can be negative, in which case it represents time remaining until periapsis passage.
[2]
Minimum circular orbit velocity at specified position
[3]
Minimum escape orbit velocity at specified position
[4]
Predicted speed at specified position
[5]
Angle of velocity at specified position - an angle between velocity vector and a vector perpendicular to radial
[6]
Predicted distance from planet centre at specified position

* hyperbolic orbits have a "prohibited" true anomaly region centred around π, which gets wider as eccentricity grows. When function receives such invalid true anomaly value, mean anomaly will be set to zero.
GetStateVectors()
Gets predicted radius vector and velocity at given position. Requires prior call of ComputeOrbitElements() or ComputeOrbitElementsFromVectors().

Declaration
void GetStateVectors(double trueAnomaly, Vector3D[] output);

Parameters
  • trueAnomaly - specifies custom position in orbit to use,
  • output - a two-element array, which is filled with the following values:
Index
Value
[0]
Predicted location with respect to planet centre at specified position
[1]
Predicted velocity at specified position
ConvertTrueAnomalyToMean()
Calculates mean anomaly from true for orbit with given eccentricity. It's typically used to estimate the amount of time the ship will take to reach certain position. To convert mean anomaly interval to elapsed time, simply multiply the former by mean motion.

Declaration
double ConvertTrueAnomalyToMean(double eccentricity, double trueAnomaly);

Paramaters
  • eccentricity - self-explanatory,
  • trueAnomaly - self-explanatory,

Return value
Returns mean anomaly. For elliptic orbits this value lies in (0, 2π) range. For hyperbolic trajectories, mean anomaly is positive on outbound leg and negative on inbound leg.

Note
Hyperbolic orbits have a "prohibited" region centred around π, which gets wider as eccentricity grows. When function receives such invalid true anomaly value, it'll return zero.
ConvertMeanAnomalyToTrue()
Calculates true anomaly from mean for orbit with given eccentricity. It's typically used to estimate ship's position after certain amount of time. To convert time interval into mean anomaly interval, simply divide the former by mean motion.

Declaration
double ConvertMeanAnomalyToTrue(double eccentricity, double meanAnomaly);

Paramaters
  • eccentricity - self-explanatory,
  • meanAnomaly - self-explanatory,

Return value
Returns true anomaly in (0, 2π) range. For eccentricities extremely close to 1 it's possible for this function to return NaN.
ComputeOrbitNormal()
Calculates orbit normal vector from given inclination and longitude of ascending node. Typically used for plane alignment.

Declaration
Vector3D ComputeOrbitNormal(double inclination, double LAN);

Parameters
  • inclination - angle between orbital and XZ plane,
  • LAN - longitude of ascending node, measured anti-clockwise from (X = 1, Y = 0, Z = 0) vector in XZ plane.

Return value
A unit vector perpendicular to orbital plane pointing in positive normal direction.
ComputeOrbitIntersections()
Computes intersection points of 2 co-planar orbits.

Declaration
ValueTuple<double, double>? ComputeOrbitIntersections(double shipEcc, double targetEcc, double shipSLR, double targetSLR, double shipLPE, double targetLPE);

Parameters
  • shipEcc - eccentricity of ship's orbit,
  • targetEcc - eccentricity of target's orbit,
  • shipSLR - semi-latus rectum of ship's orbit,
  • targetSLR - semi-latus rectum of target's orbit,
  • shipLPE - longitude of periapsis* on ship's orbit,
  • targetLPE - longitude of periapsis* on target's orbit.

Return value
  • If orbits don't intersect, returns null,
  • Otherwise, the result is a tuple containing true longitudes** of 2 points where orbits intersect.

Notes
* Longitude of periapsis := Longitude of ascending node + Argument of periapsis.
** True longitude := Longitude of ascending node + Argument of periapsis + True anomaly.

ConvertRadialToTtrueAnomaly()
Calculates true anomaly from given radius vector.

Declaration
double ConvertRadialToTtrueAnomaly(Vector3D radial, Vector3D normal, Vector3D ascendingNode, double argumentOfPeriapsis)

Parameters
  • radial - a vector pointing from the centre of the planet towards given location in orbital plane. The function will atomatically align vector to orbit as needed,
  • normal - a vector perpendicular to orbital plane corresponding to counter-clockwise direction,
  • ascendingNode - a vector that lies in XZ plane and points from the centre of the planet towards ascending node,
  • argumentOfPeriapsis - an angle between ascending node and periapsis.

Return value
True anomaly in (0, 2π) range. If specified radial is perpendicular to orbital plane, returns -1.

Note
For all 3 vector parameters, only direction is important; length is ignored.
Example script
Below is a sample script which calculates time remaining till intersection of ship's current orbital plane and target orbit, specified by inclination and LAN.
const double targetInc = 0.0, targetLAN = 0.0; enum PrimVec { SAM, ANV, EcV, LGV, Rad, Vel }; enum PrimScal { RBR, SMA, Ecc, Inc, LAN, AoP, TrA }; enum SecScal { SLR, PeR, ApR, MnM, OrP }; Func<string, string, bool> ComputeOrbitElements = null; Action<Vector3D[]> GetPrimaryVectors = null; Action<double[]> GetPrimaryScalars = null, GetDerivedElements = null; Func<double, double, Vector3D> ComputeOrbitNormal = null; Func<Vector3D, Vector3D, Vector3D, double, double> ConvertRadialToTtrueAnomaly = null; Func<double, double, double> ConvertTrueAnomalyToMean = null; Vector3D[] vectors = new Vector3D[6]; double[] primElements = new double[7], secElements = new double[5]; public Program() { Runtime.UpdateFrequency = UpdateFrequency.Update100; } public void Main() { if (ComputeOrbitElements == null) { // It's not recommended to initialise delegates in constructor, as the latter // might get called before OSE has registered it properties, // which would cause the script to crash. if (Me.GetProperty("ComputeOrbitElements") == null) return; ComputeOrbitElements = Me.GetValue<Func<string, string, bool>>("ComputeOrbitElements"); GetPrimaryVectors = Me.GetValue<Action<Vector3D[]>>("GetPrimaryVectors"); GetPrimaryScalars = Me.GetValue<Action<double[]>>("GetPrimaryScalars"); GetDerivedElements = Me.GetValue<Action<double[]>>("GetDerivedElements"); ComputeOrbitNormal = Me.GetValue<Func<double, double, Vector3D>>("ComputeOrbitNormal"); ConvertRadialToTtrueAnomaly = Me.GetValue<Func<Vector3D, Vector3D, Vector3D, double, double>>("ConvertRadialToTtrueAnomaly"); ConvertTrueAnomalyToMean = Me.GetValue<Func<double, double, double>> ("ConvertTrueAnomalyToMean"); } bool result = ComputeOrbitElements(null, null); if (!result) { Echo("Calculation failed"); return; } GetPrimaryVectors(vectors); GetPrimaryScalars(primElements); GetDerivedElements(secElements); Vector3D ownNormal = vectors[(int) PrimVec.SAM]; Vector3D targetNormal = ComputeOrbitNormal(targetInc, targetLAN); double relativeInclination = Math.Acos(Vector3D.Dot(ownNormal, targetNormal) / (ownNormal.Length() * targetNormal.Length())); Vector3D intersectionAN = Vector3D.Cross(targetNormal, ownNormal); double eccentricity = primElements[(int) PrimScal.Ecc]; double meanMotion = secElements[(int) SecScal.MnM]; double orbitPeriod = secElements[(int) SecScal.OrP]; double shipMeanAnomaly = ConvertTrueAnomalyToMean(eccentricity, primElements[(int) PrimScal.TrA]); double intersectionTrueAnomaly = ConvertRadialToTtrueAnomaly(intersectionAN, ownNormal, vectors[(int) PrimVec.ANV], primElements[(int) PrimScal.AoP]); double timeToAN = (ConvertTrueAnomalyToMean(eccentricity, intersectionTrueAnomaly) - shipMeanAnomaly) * meanMotion; if (timeToAN < 0.0 && eccentricity < 1.0) timeToAN += orbitPeriod; double timeToDN = (ConvertTrueAnomalyToMean(eccentricity, intersectionTrueAnomaly + Math.PI) - shipMeanAnomaly) * meanMotion; if (timeToDN < 0.0 && eccentricity < 1.0) timeToDN += orbitPeriod; Echo($"Relative inc.: {relativeInclination * 180.0 / Math.PI:F0} deg."); Echo($"Time to AN: {timeToAN:F0} s\nTime to DN: {timeToDN:F0} s"); }
3 Comments
Knsgf  [author] 29 Sep, 2020 @ 1:49pm 
Forgot to adjust signature of the 5th delegate; the script works now.
anzellott 29 Sep, 2020 @ 1:02pm 
"Caught Exception During Excecution Of Script: Object Refrence Not Set To An Instance Of Object At Program Save Or Something"
That's What I Think The Important Part Of It Is
anzellott 29 Sep, 2020 @ 12:59pm 
Uh, While Using Tjis Script On A World With OSE And Planets Smaller Than 19km, I Got This Error, And This Made The Script, Well, Unsusable, And I Had To Eyeball The Orbital maneuvers

The Error Was Like Something About A Refrence or something