Class: KerbalDyn::Orbit
- Inherits:
-
Object
- Object
- KerbalDyn::Orbit
- Defined in:
- lib/kerbaldyn/orbit.rb
Overview
The primary class for encapsulating an orbit around a primary body. At this time orbits are simplified to only consider the mass of the primary body, thus the orbit of the secondary body is around the center-of-mass of the primary body. This approximation works well for the Kerbal universe.
Constant Summary collapse
- BASE_PARAMETERS =
A list of the independent parameters that define an orbit for this class.
[:periapsis, :periapsis_velocity, :inclination, :longitude_of_ascending_node, :argument_of_periapsis, :mean_anomaly, :epoch]
- DEFAULT_OPTIONS =
A map of default values for initialization parameters.
BASE_PARAMETERS.inject({}) {|opts,param| opts[param] = 0.0; opts}.merge(:secondary_body => Body::TEST_PARTICLE)
Instance Attribute Summary collapse
-
#primary_body ⇒ Object
The body being orbited (required) Expected to be an instance of Planetoid.
-
#secondary_body ⇒ Object
The body in orbit (optional) Expected to be an instance of Planetoid.
Class Method Summary collapse
-
.bop ⇒ Object
:category: Library Methods.
-
.circular_orbit(primary_body, radius) ⇒ Object
Convenience method for creating a circular orbit about the given body.
-
.circular_orbit_of_period(primary_body, period) ⇒ Object
Convenience method for creating a circular orbit of a given period around a given body.
-
.duna ⇒ Object
:category: Library Methods.
-
.escape_orbit(primary_body, periapsis) ⇒ Object
Convenience method for creating an escape orbit around the given body.
-
.eve ⇒ Object
:category: Library Methods.
-
.from_string(string) ⇒ Object
Given a string, create an orbit for it.
-
.geostationary_orbit(primary_body) ⇒ Object
Convenience method for creating a geostationary orbit around the given body.
-
.gilly ⇒ Object
:category: Library Methods.
-
.ike ⇒ Object
:category: Library Methods.
-
.jool ⇒ Object
:category: Library Methods.
-
.kerbin ⇒ Object
:category: Library Methods.
-
.laythe ⇒ Object
:category: Library Methods.
-
.make(planet_ref) ⇒ Object
For data read in from data files, this private method DRYs the process.
-
.minmus ⇒ Object
:category: Library Methods.
-
.moho ⇒ Object
:category: Library Methods.
-
.mun ⇒ Object
:category: Library Methods.
-
.tylo ⇒ Object
:category: Library Methods.
-
.vall ⇒ Object
:category: Library Methods.
Instance Method Summary collapse
-
#apoapsis ⇒ Object
The apoapsis radius, if the eccentricity is less than one.
-
#apoapsis_velocity ⇒ Object
The apoapsis velocity, if the eccentricity is less than one.
-
#circularize ⇒ Object
Instantiates a new orbit with the same period and semimajor axis, zero inclination, and is circular.
-
#classification(delta = 0.000000001) ⇒ Object
(also: #kind)
Orbit classification, returns one of :subelliptical, :circular, :elliptical, :parabolic, or :hyperbolic.
-
#closed? ⇒ Boolean
Returns true if the orbit is a closed orbit (eccentricity < 1).
-
#eccentricity ⇒ Object
The orbit eccentricity.
-
#equivalent_gravity_sphere_of_influence ⇒ Object
This is yet another sphere of influence definition I came across, from the bottom of Wikipedia.
-
#gravitational_parameter ⇒ Object
Returns the gravitational parameter for this orbit.
-
#hill_sphere_radius ⇒ Object
The Hill Sphere radius.
-
#initialize(primary_body, options = {}) ⇒ Orbit
constructor
Create a new orbit.
-
#mean_angular_velocity ⇒ Object
This is the mean angular velocity (angle change per unit time) for this orbit.
-
#mean_motion ⇒ Object
This is the mean angular velocity (angle change per unit time) for this orbit.
-
#mean_velocity ⇒ Object
This is the velocity associated with the mean motion at the semimajor axis, This works out to be the velocity of an object in a circular orbit with the same period.
-
#open? ⇒ Boolean
Returns false if the orbit is closed.
-
#period ⇒ Object
The orbital period, if the eccentricity is less than one.
-
#primary_body_sphere_of_influence ⇒ Object
Returns the sphere of influence (SOI) for the primary body in the context of the two-body system.
-
#secondary_body_sphere_of_influence ⇒ Object
(also: #laplace_sphere_of_influence, #sphere_of_influence)
Returns the sphere of influence (SOI) for the secondary body in the context of the two-body system.
-
#semimajor_axis ⇒ Object
The orbit semimajor-axis.
-
#semiminor_axis ⇒ Object
The orbit semiminor_axis, if the eccentricity is less than one.
-
#specific_angular_momentum ⇒ Object
(also: #angular_momentum)
The specific angular momentum for this orbit; this is constant over the entire orbit.
-
#specific_energy ⇒ Object
(also: #vis_viva_energy)
The total specific energyy of the orbit; this is constant over the entire orbit.
-
#specific_kinetic_energy(v) ⇒ Object
The specific kinetic energy for any given velocity.
-
#specific_potential_energy(r) ⇒ Object
The specific potential energy for any given orbit radius.
Methods included from Mixin::ParameterAttributes
Constructor Details
#initialize(primary_body, options = {}) ⇒ Orbit
Create a new orbit.
The first argument should be the Body (usually a Planetoid) that is being orbited.
The second argument is a list of parameters which should include a size and eccentricity specification, and a may include other optional parameters.
To specify an orbit, at least one of the following pairs must be given:
-
periapsis, periapsis_velocity
-
periapsis, apoapsis
-
semimajor_axis, eccentricity
-
radius (assumes circular orbit)
The following additional parameters may be given:
-
inclination
-
longitude_of_ascending_node
-
argument_of_periapsis
-
mean_anomaly
-
epoch
169 170 171 172 173 174 175 176 177 178 |
# File 'lib/kerbaldyn/orbit.rb', line 169 def initialize(primary_body, ={}) # Set the primary planetoid self.primary_body = primary_body # Set the periapsis and periapsis_velocity from the options = replace_orbital_parameters() # Default all the base parameters to zero if not given. (, DEFAULT_OPTIONS) end |
Instance Attribute Details
#primary_body ⇒ Object
The body being orbited (required) Expected to be an instance of Planetoid.
184 185 186 |
# File 'lib/kerbaldyn/orbit.rb', line 184 def primary_body @primary_body end |
#secondary_body ⇒ Object
The body in orbit (optional) Expected to be an instance of Planetoid.
188 189 190 |
# File 'lib/kerbaldyn/orbit.rb', line 188 def secondary_body @secondary_body end |
Class Method Details
.bop ⇒ Object
:category: Library Methods
95 96 97 |
# File 'lib/kerbaldyn/orbit.rb', line 95 def self.bop return @bop ||= make(__method__) end |
.circular_orbit(primary_body, radius) ⇒ Object
Convenience method for creating a circular orbit about the given body. This is redundant to calling new with the option of :radius.
101 102 103 |
# File 'lib/kerbaldyn/orbit.rb', line 101 def self.circular_orbit(primary_body, radius) return self.new(primary_body, :radius => radius) end |
.circular_orbit_of_period(primary_body, period) ⇒ Object
Convenience method for creating a circular orbit of a given period around a given body.
107 108 109 110 111 |
# File 'lib/kerbaldyn/orbit.rb', line 107 def self.circular_orbit_of_period(primary_body, period) planetoid_angular_velocity = 2.0 * Math::PI / period radius = (primary_body.gravitational_parameter / planetoid_angular_velocity**2)**(1.0/3.0) return self.circular_orbit(primary_body, radius) end |
.duna ⇒ Object
:category: Library Methods
65 66 67 |
# File 'lib/kerbaldyn/orbit.rb', line 65 def self.duna return @duna ||= make(__method__) end |
.escape_orbit(primary_body, periapsis) ⇒ Object
Convenience method for creating an escape orbit around the given body.
119 120 121 122 |
# File 'lib/kerbaldyn/orbit.rb', line 119 def self.escape_orbit(primary_body, periapsis) periapsis_escape_velocity = Math.sqrt(2.0 * primary_body.gravitational_parameter / periapsis) return self.new(primary_body, :periapsis => periapsis, :periapsis_velocity => periapsis_escape_velocity) end |
.eve ⇒ Object
:category: Library Methods
55 56 57 |
# File 'lib/kerbaldyn/orbit.rb', line 55 def self.eve return @eve ||= make(__method__) end |
.from_string(string) ⇒ Object
Given a string, create an orbit for it. The string specification is one of:
- planetoid
-
The orbit for the planetoid around its parent body.
- planetoid@numberdesignator
-
Builds an orbit around the given planetoid with the given radius or altitude in meters. The designator is one of r or a for radius or altitude. Defaults to radius.
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/kerbaldyn/orbit.rb', line 129 def self.from_string(string) orbit_with_altitude_regex = /^([a-z]+)@([\d]+)([ra]{0,1})$/ expression = string.to_s.downcase case expression when /^([a-z]+)$/ planetoid_method = expression.to_sym raise ArgumentError, "Unknown planetoid: #{string}" unless Planetoid.planetoid_methods.include?(planetoid_method) self.send(planetoid_method) when orbit_with_altitude_regex matched, planetoid_name, distance, distance_designator = orbit_with_altitude_regex.match(expression).to_a planetoid_method = planetoid_name.to_sym raise ArgumentError, "Unknown planetoid: #{planetoid}" unless Planetoid.planetoid_methods.include?(planetoid_method) planetoid = Planetoid.send(planetoid_method) radius = (distance_designator=='a') ? (distance.to_f + planetoid.radius) : distance.to_f self.new(planetoid, :radius => radius) else raise ArgumentError, "Unknown orbit expression: #{string}" end end |
.geostationary_orbit(primary_body) ⇒ Object
Convenience method for creating a geostationary orbit around the given body.
114 115 116 |
# File 'lib/kerbaldyn/orbit.rb', line 114 def self.geostationary_orbit(primary_body) return self.circular_orbit_of_period(primary_body, primary_body.rotational_period) end |
.gilly ⇒ Object
:category: Library Methods
60 61 62 |
# File 'lib/kerbaldyn/orbit.rb', line 60 def self.gilly return @gilly ||= make(__method__) end |
.ike ⇒ Object
:category: Library Methods
70 71 72 |
# File 'lib/kerbaldyn/orbit.rb', line 70 def self.ike return @ike ||= make(__method__) end |
.jool ⇒ Object
:category: Library Methods
75 76 77 |
# File 'lib/kerbaldyn/orbit.rb', line 75 def self.jool return @jool ||= make(__method__) end |
.kerbin ⇒ Object
:category: Library Methods
35 36 37 |
# File 'lib/kerbaldyn/orbit.rb', line 35 def self.kerbin return @kerbin ||= make(__method__) end |
.laythe ⇒ Object
:category: Library Methods
80 81 82 |
# File 'lib/kerbaldyn/orbit.rb', line 80 def self.laythe return @laythe ||= make(__method__) end |
.make(planet_ref) ⇒ Object
For data read in from data files, this private method DRYs the process.
20 21 22 23 24 25 26 27 28 |
# File 'lib/kerbaldyn/orbit.rb', line 20 def self.make(planet_ref) # Get the data and dup it so we can muck with it. data = Data.fetch(:planet_data)[planet_ref][:orbit].dup # Get the primary/secondary body refs from it and then lookup to get the values. primary_body = Planetoid.send( data.delete(:primary_body) ) secondary_body = Planetoid.send( data.delete(:secondary_body) ) # Now construct the object. return self.new( primary_body, data.merge(:secondary_body => secondary_body) ).freeze end |
.minmus ⇒ Object
:category: Library Methods
45 46 47 |
# File 'lib/kerbaldyn/orbit.rb', line 45 def self.minmus return @minmus ||= make(__method__) end |
.moho ⇒ Object
:category: Library Methods
50 51 52 |
# File 'lib/kerbaldyn/orbit.rb', line 50 def self.moho return @moho ||= make(__method__) end |
.mun ⇒ Object
:category: Library Methods
40 41 42 |
# File 'lib/kerbaldyn/orbit.rb', line 40 def self.mun return @mun ||= make(__method__) end |
.tylo ⇒ Object
:category: Library Methods
90 91 92 |
# File 'lib/kerbaldyn/orbit.rb', line 90 def self.tylo return @tylo ||= make(__method__) end |
.vall ⇒ Object
:category: Library Methods
85 86 87 |
# File 'lib/kerbaldyn/orbit.rb', line 85 def self.vall return @vall ||= make(__method__) end |
Instance Method Details
#apoapsis ⇒ Object
The apoapsis radius, if the eccentricity is less than one.
342 343 344 345 346 347 348 |
# File 'lib/kerbaldyn/orbit.rb', line 342 def apoapsis if self.closed? return self.semimajor_axis * (1 + self.eccentricity) else return nil end end |
#apoapsis_velocity ⇒ Object
The apoapsis velocity, if the eccentricity is less than one.
351 352 353 354 355 356 357 358 359 |
# File 'lib/kerbaldyn/orbit.rb', line 351 def apoapsis_velocity if self.closed? e = self.eccentricity k = self.gravitational_parameter / self.semimajor_axis return Math.sqrt( (1-e)/(1+e) * k ) else return nil end end |
#circularize ⇒ Object
Instantiates a new orbit with the same period and semimajor axis, zero inclination, and is circular.
This is useful for idealizing orbits for rough calculations. – TODO: Figure out how to translate parameters such as mean anomaly and LAN. ++
368 369 370 371 372 373 374 |
# File 'lib/kerbaldyn/orbit.rb', line 368 def circularize return self.class.new(primary_body, { :secondary_body => self.secondary_body, :radius => self.semimajor_axis, :inclination => 0.0 }) end |
#classification(delta = 0.000000001) ⇒ Object Also known as: kind
Orbit classification, returns one of :subelliptical, :circular, :elliptical, :parabolic, or :hyperbolic.
Because of how floats work, a delta is given for evaluation of “critical” points such as circular and elliptical orbits. The default value is 1e-9, however other values may be given.
231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/kerbaldyn/orbit.rb', line 231 def classification(delta=0.000000001) e = self.eccentricity if( e.abs < delta ) return :circular elsif( (e-1.0).abs < delta ) return :parabolic elsif( e > 0.0 && e < 1.0 ) return :elliptical elsif( e > 1.0 ) return :hyperbolic elsif( e < 0.0 ) return :subelliptical end end |
#closed? ⇒ Boolean
Returns true if the orbit is a closed orbit (eccentricity < 1)
248 249 250 |
# File 'lib/kerbaldyn/orbit.rb', line 248 def closed? return self.eccentricity < 1.0 end |
#eccentricity ⇒ Object
The orbit eccentricity.
288 289 290 |
# File 'lib/kerbaldyn/orbit.rb', line 288 def eccentricity return (self.periapsis * self.periapsis_velocity**2 / self.gravitational_parameter) - 1 end |
#equivalent_gravity_sphere_of_influence ⇒ Object
This is yet another sphere of influence definition I came across, from the bottom of Wikipedia. This matched some numbers I got from a data dump, but don’t match empirical data from the conic patching in game.
217 218 219 |
# File 'lib/kerbaldyn/orbit.rb', line 217 def equivalent_gravity_sphere_of_influence return self.periapsis * (self.secondary_body.mass / self.primary_body.mass)**(1.0/3.0) end |
#gravitational_parameter ⇒ Object
Returns the gravitational parameter for this orbit. Note that this currently is G*M rather than G*(M+m).
259 260 261 |
# File 'lib/kerbaldyn/orbit.rb', line 259 def gravitational_parameter return self.primary_body.gravitational_parameter end |
#hill_sphere_radius ⇒ Object
The Hill Sphere radius. This comes from the approximation of L1/L2.
This is NOT the KSP SOI, for it, use kerbal_sphere_of_influence
210 211 212 |
# File 'lib/kerbaldyn/orbit.rb', line 210 def hill_sphere_radius return self.periapsis * (self.secondary_body.mass / (3.0*self.primary_body.mass))**(2.0/3.0) end |
#mean_angular_velocity ⇒ Object
This is the mean angular velocity (angle change per unit time) for this orbit.
320 321 322 323 324 325 326 |
# File 'lib/kerbaldyn/orbit.rb', line 320 def mean_angular_velocity if self.closed? return 2.0 * Math::PI / self.period else return nil end end |
#mean_motion ⇒ Object
This is the mean angular velocity (angle change per unit time) for this orbit.
This simply calls mean_angular_velocity
on self.
331 332 333 |
# File 'lib/kerbaldyn/orbit.rb', line 331 def mean_motion return self.mean_angular_velocity end |
#mean_velocity ⇒ Object
This is the velocity associated with the mean motion at the semimajor axis, This works out to be the velocity of an object in a circular orbit with the same period.
337 338 339 |
# File 'lib/kerbaldyn/orbit.rb', line 337 def mean_velocity return self.mean_motion * self.semimajor_axis end |
#open? ⇒ Boolean
Returns false if the orbit is closed.
253 254 255 |
# File 'lib/kerbaldyn/orbit.rb', line 253 def open? return !self.closed? end |
#period ⇒ Object
The orbital period, if the eccentricity is less than one.
311 312 313 314 315 316 317 |
# File 'lib/kerbaldyn/orbit.rb', line 311 def period if self.closed? return 2.0 * Math::PI * Math.sqrt( self.semimajor_axis**3 / self.gravitational_parameter ) else return nil end end |
#primary_body_sphere_of_influence ⇒ Object
Returns the sphere of influence (SOI) for the primary body in the context of the two-body system.
This is NOT the KSP SOI, for it, use kerbal_sphere_of_influence
194 195 196 |
# File 'lib/kerbaldyn/orbit.rb', line 194 def primary_body_sphere_of_influence return self.semimajor_axis * (self.primary_body.mass / self.secondary_body.mass)**(0.4) end |
#secondary_body_sphere_of_influence ⇒ Object Also known as: laplace_sphere_of_influence, sphere_of_influence
Returns the sphere of influence (SOI) for the secondary body in the context of the two-body system.
In 0.17, for Mun, this matches to better than 0.015% error, while the others are way off.
202 203 204 |
# File 'lib/kerbaldyn/orbit.rb', line 202 def secondary_body_sphere_of_influence return self.semimajor_axis * (self.secondary_body.mass / self.primary_body.mass)**(0.4) end |
#semimajor_axis ⇒ Object
The orbit semimajor-axis.
293 294 295 296 297 298 299 |
# File 'lib/kerbaldyn/orbit.rb', line 293 def semimajor_axis if self.closed? return self.periapsis / (1.0 - self.eccentricity) else return self.periapsis / (self.eccentricity - 1.0) end end |
#semiminor_axis ⇒ Object
The orbit semiminor_axis, if the eccentricity is less than one.
302 303 304 305 306 307 308 |
# File 'lib/kerbaldyn/orbit.rb', line 302 def semiminor_axis if self.closed? return self.semimajor_axis * Math.sqrt(1.0 - self.eccentricity**2) else return nil end end |
#specific_angular_momentum ⇒ Object Also known as: angular_momentum
The specific angular momentum for this orbit; this is constant over the entire orbit.
282 283 284 |
# File 'lib/kerbaldyn/orbit.rb', line 282 def specific_angular_momentum return self.periapsis * self.periapsis_velocity end |
#specific_energy ⇒ Object Also known as: vis_viva_energy
The total specific energyy of the orbit; this is constant over the entire orbit.
275 276 277 |
# File 'lib/kerbaldyn/orbit.rb', line 275 def specific_energy return self.specific_potential_energy(self.periapsis) + self.specific_kinetic_energy(self.periapsis_velocity) end |
#specific_kinetic_energy(v) ⇒ Object
The specific kinetic energy for any given velocity.
269 270 271 |
# File 'lib/kerbaldyn/orbit.rb', line 269 def specific_kinetic_energy(v) return 0.5 * v**2 end |
#specific_potential_energy(r) ⇒ Object
The specific potential energy for any given orbit radius.
264 265 266 |
# File 'lib/kerbaldyn/orbit.rb', line 264 def specific_potential_energy(r) return -self.gravitational_parameter / r end |