kerbaldyn 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +2 -0
- data/Gemfile +11 -0
- data/README.rdoc +57 -0
- data/Rakefile +23 -0
- data/kerbaldyn.gemspec +30 -0
- data/lib/kerbaldyn.rb +14 -0
- data/lib/kerbaldyn/body.rb +48 -0
- data/lib/kerbaldyn/constants.rb +12 -0
- data/lib/kerbaldyn/data.rb +56 -0
- data/lib/kerbaldyn/data/planet_data.json +249 -0
- data/lib/kerbaldyn/mixin.rb +2 -0
- data/lib/kerbaldyn/mixin/options_processor.rb +17 -0
- data/lib/kerbaldyn/mixin/parameter_attributes.rb +38 -0
- data/lib/kerbaldyn/orbit.rb +379 -0
- data/lib/kerbaldyn/orbital_maneuver.rb +6 -0
- data/lib/kerbaldyn/orbital_maneuver/base.rb +159 -0
- data/lib/kerbaldyn/orbital_maneuver/bielliptic.rb +61 -0
- data/lib/kerbaldyn/orbital_maneuver/burn_event.rb +57 -0
- data/lib/kerbaldyn/orbital_maneuver/hohmann.rb +48 -0
- data/lib/kerbaldyn/orbital_maneuver/inclination_change.rb +0 -0
- data/lib/kerbaldyn/part.rb +15 -0
- data/lib/kerbaldyn/part/base.rb +154 -0
- data/lib/kerbaldyn/part/fuel_tank.rb +11 -0
- data/lib/kerbaldyn/part/generic.rb +10 -0
- data/lib/kerbaldyn/part/liquid_fuel_engine.rb +69 -0
- data/lib/kerbaldyn/part/mixin.rb +1 -0
- data/lib/kerbaldyn/part/mixin/fuel_tank.rb +35 -0
- data/lib/kerbaldyn/part/rcs_fuel_tank.rb +10 -0
- data/lib/kerbaldyn/part/solid_rocket.rb +30 -0
- data/lib/kerbaldyn/part_library.rb +55 -0
- data/lib/kerbaldyn/planetoid.rb +214 -0
- data/lib/kerbaldyn/version.rb +13 -0
- data/spec/bielliptic_orbital_maneuver_spec.rb +60 -0
- data/spec/constants_spec.rb +9 -0
- data/spec/hohmann_orbital_maneuver_spec.rb +385 -0
- data/spec/options_processor_spec.rb +33 -0
- data/spec/orbit_spec.rb +357 -0
- data/spec/orbital_maneuver_base_spec.rb +74 -0
- data/spec/parameter_attributes_spec.rb +82 -0
- data/spec/part_library_spec.rb +21 -0
- data/spec/part_spec.rb +218 -0
- data/spec/planetoid_spec.rb +117 -0
- data/spec/spec_helper.rb +110 -0
- data/spec/support/parts/RCSFuelTank/part.cfg +42 -0
- data/spec/support/parts/fuelTank/part.cfg +48 -0
- data/spec/support/parts/liquidEngine1/part.cfg +60 -0
- data/spec/support/parts/liquidEngine2/part.cfg +64 -0
- data/spec/support/parts/solidBooster/part.cfg +67 -0
- data/spec/support/planet_test_data.json +340 -0
- metadata +95 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe KerbalDyn::Mixin::OptionsProcessor do
|
4
|
+
|
5
|
+
class OptionsProcessorTestClass
|
6
|
+
include KerbalDyn::Mixin::OptionsProcessor
|
7
|
+
DEFAULTS = {:foo => :default}
|
8
|
+
|
9
|
+
def initialize(opts={})
|
10
|
+
process_options(opts, DEFAULTS)
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :foo
|
14
|
+
attr_accessor :alpha
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should set valid keys' do
|
18
|
+
obj = OptionsProcessorTestClass.new(:foo => :bar, :alpha => :beta)
|
19
|
+
obj.foo.should == :bar
|
20
|
+
obj.alpha.should == :beta
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should error on invalid keys' do
|
24
|
+
lambda {OptionsProcessorTestClass.new(:miss => :sunshine)}.should raise_error(NoMethodError)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should use a block as a defaults hook' do
|
28
|
+
obj = OptionsProcessorTestClass.new
|
29
|
+
obj.foo.should == :default
|
30
|
+
obj.alpha.should == nil
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/spec/orbit_spec.rb
ADDED
@@ -0,0 +1,357 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe KerbalDyn::Orbit do
|
4
|
+
|
5
|
+
describe 'Circularize' do
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@planet = KerbalDyn::Planetoid.new('Test Planet', :gravitational_parameter => 3.5316e12, :radius => 600000)
|
9
|
+
@satellite = KerbalDyn::Planetoid.test_particle
|
10
|
+
@elliptical = KerbalDyn::Orbit.new(@planet, :secondary_body => @satellite, :periapsis => 700000.0, :apoapsis => 3e6, :inclination => 0.2)
|
11
|
+
@circular = @elliptical.circularize
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should have the same primary body' do
|
15
|
+
@circular.primary_body.should == @elliptical.primary_body
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should have the same secondary body' do
|
19
|
+
@circular.secondary_body.should == @elliptical.secondary_body
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should be circular' do
|
23
|
+
@circular.kind.should == :circular
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should have the same semimajor_axis' do
|
27
|
+
@circular.semimajor_axis.should == @elliptical.semimajor_axis
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should have zero inclination' do
|
31
|
+
@circular.inclination.should be_within(1e-9).of(0.0)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should have the same period' do
|
35
|
+
@circular.period.should be_within_six_sigma_of(@elliptical.period)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should have a periapsis and apoapsis velocity that is the same as original mean velocity.' do
|
39
|
+
@circular.mean_velocity.should be_within_six_sigma_of(@elliptical.mean_velocity)
|
40
|
+
@circular.periapsis_velocity.should be_within_six_sigma_of(@elliptical.mean_velocity)
|
41
|
+
@circular.apoapsis_velocity.should be_within_six_sigma_of(@elliptical.mean_velocity)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'Orbit Types' do
|
47
|
+
|
48
|
+
describe 'Circular Orbit' do
|
49
|
+
before(:all, &BeforeFactory.earth)
|
50
|
+
before(:all, &BeforeFactory.earth_geostationary_orbit)
|
51
|
+
|
52
|
+
it 'should be closed' do
|
53
|
+
@orbit.closed?.should be_true
|
54
|
+
@orbit.open?.should be_false
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should be circular' do
|
58
|
+
@orbit.kind.should == :circular
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should have zero eccentricity' do
|
62
|
+
@orbit.eccentricity.should be_within(0.000001).of(0.0)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should have the parent body gravitational parameter' do
|
66
|
+
@orbit.gravitational_parameter.should be_within_four_sigma_of(@gravitational_parameter)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should have the right specific kinetic energy' do
|
70
|
+
@orbit.specific_kinetic_energy(@orbital_velocity).should be_within_four_sigma_of(@orbital_specific_kinetic_energy)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should have the right specific potential energy' do
|
74
|
+
@orbit.specific_potential_energy(@orbital_radius).should be_within_four_sigma_of(@orbital_specific_potential_energy)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should have total specific energy that is the sum of kinetic and poential specific energy' do
|
78
|
+
@orbit.specific_energy.should be_within_four_sigma_of( @orbital_specific_kinetic_energy + @orbital_specific_potential_energy )
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should have the right rotational momentum' do
|
82
|
+
@orbit.specific_angular_momentum.should be_within_four_sigma_of( @orbital_specific_angular_momentum )
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should have a semimajor_axis equal to the radius' do
|
86
|
+
@orbit.semimajor_axis.should be_within_six_sigma_of(@orbital_radius)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should have a semiminor_axis equal to the radius' do
|
90
|
+
@orbit.semiminor_axis.should be_within_six_sigma_of(@orbital_radius)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should have a periapsis equal to the radius' do
|
94
|
+
@orbit.periapsis.should be_within_six_sigma_of(@orbital_radius)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should have an apoapsis equal to the radius' do
|
98
|
+
@orbit.apoapsis.should be_within_six_sigma_of(@orbital_radius)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should have the expected period' do
|
102
|
+
@orbit.period.should be_within_four_sigma_of(@orbital_period)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should have the expected mean_angular_velocity' do
|
106
|
+
@orbit.mean_angular_velocity.should be_within_four_sigma_of(2.0*Math::PI / @orbital_period)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should have the correct periapsis_velocity' do
|
110
|
+
@orbit.periapsis_velocity.should be_within_four_sigma_of(@orbital_velocity)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should have the correct apoapsis_velocity' do
|
114
|
+
@orbit.apoapsis_velocity.should be_within_four_sigma_of(@orbital_velocity)
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
describe 'Elliptical Orbit' do
|
120
|
+
before(:all, &BeforeFactory.earth)
|
121
|
+
before(:all, &BeforeFactory.geostationary_transfer_orbit)
|
122
|
+
|
123
|
+
it 'should be of kind elliptical' do
|
124
|
+
@orbit.kind.should == :elliptical
|
125
|
+
end
|
126
|
+
|
127
|
+
[
|
128
|
+
:periapsis,
|
129
|
+
:apoapsis,
|
130
|
+
:periapsis_velocity,
|
131
|
+
:apoapsis_velocity,
|
132
|
+
:eccentricity,
|
133
|
+
:semimajor_axis
|
134
|
+
].each do |parameter|
|
135
|
+
it "should calculate the correct #{parameter} value" do
|
136
|
+
expected_value = instance_variable_get("@#{parameter}")
|
137
|
+
@orbit.send(parameter).should be_within_three_sigma_of(expected_value)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
describe 'Parabolic Orbit' do
|
144
|
+
before(:all, &BeforeFactory.earth)
|
145
|
+
before(:all, &BeforeFactory.earth_escape_orbit)
|
146
|
+
|
147
|
+
it 'should have the correct escape velocity' do
|
148
|
+
@orbit.periapsis_velocity.should be_within_six_sigma_of(@escape_velocity)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should be of kind :parabolic' do
|
152
|
+
@orbit.kind.should == :parabolic
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should have an eccentricity of 1' do
|
156
|
+
@orbit.eccentricity.should be_within_six_sigma_of(1.0)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should have a total specific energy of zero' do
|
160
|
+
@orbit.specific_energy.should be_within(1e-6).of(0.0)
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
describe 'Hyperbolic Orbit' do
|
166
|
+
before(:all, &BeforeFactory.earth)
|
167
|
+
before(:all, &BeforeFactory.earth_hyperbolic_orbit)
|
168
|
+
|
169
|
+
it 'should be of kind :hyperbolic' do
|
170
|
+
@orbit.kind.should == :hyperbolic
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should have an eccentricity greater than 1' do
|
174
|
+
@orbit.eccentricity.should > 1.0
|
175
|
+
@orbit.eccentricity.should be_within_four_sigma_of(@eccentricity)
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
describe 'Eccentricity Independent Quantities' do
|
183
|
+
|
184
|
+
before(:all) do
|
185
|
+
@primary_planetoid = KerbalDyn::Planetoid.new('Kerbin', :mass => 5.29e22, :radius => 600e3)
|
186
|
+
@secondary_planetoid = KerbalDyn::Planetoid.new('Mun', :mass => 9.76e20, :radius => 200e3)
|
187
|
+
@semimajor_axis = 12000e3
|
188
|
+
@secondary_soi = 2430e3
|
189
|
+
@primary_soi = 59.26e6
|
190
|
+
@orbit = KerbalDyn::Orbit.new(@primary_planetoid, :secondary_body => @secondary_planetoid, :semimajor_axis => @semimajor_axis, :eccentricity => 0.0)
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'should calculate SOI of primary body' do
|
194
|
+
@orbit.primary_body_sphere_of_influence.should be_within_four_sigma_of(@primary_soi)
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'should cacluate SOI of secondary body' do
|
198
|
+
@orbit.secondary_body_sphere_of_influence.should be_within_four_sigma_of(@secondary_soi)
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'should default to the secondary body SOI' do
|
202
|
+
@orbit.sphere_of_influence.should be_within_four_sigma_of(@secondary_soi)
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
describe 'Orbit Initializers and Factory Methods' do
|
208
|
+
before(:all, &BeforeFactory.earth)
|
209
|
+
|
210
|
+
describe 'constructing orbits from periapsis and periapsis velocity' do
|
211
|
+
before(:all, &BeforeFactory.geostationary_transfer_orbit)
|
212
|
+
|
213
|
+
it 'should create from the initializer' do
|
214
|
+
orbit = KerbalDyn::Orbit.new(@planetoid, :periapsis => @periapsis, :periapsis_velocity => @periapsis_velocity)
|
215
|
+
[:periapsis, :apoapsis, :periapsis_velocity, :apoapsis_velocity, :eccentricity, :semimajor_axis].each do |parameter|
|
216
|
+
orbit.send(parameter).should be_within_three_sigma_of( instance_variable_get("@#{parameter}") )
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
describe 'constructing orbits from periapsis and apoapsis' do
|
223
|
+
before(:all, &BeforeFactory.geostationary_transfer_orbit)
|
224
|
+
|
225
|
+
it 'should create from the initializer' do
|
226
|
+
orbit = KerbalDyn::Orbit.new(@planetoid, :periapsis => @periapsis, :apoapsis => @apoapsis)
|
227
|
+
[:periapsis, :apoapsis, :periapsis_velocity, :apoapsis_velocity, :eccentricity, :semimajor_axis].each do |parameter|
|
228
|
+
orbit.send(parameter).should be_within_three_sigma_of( instance_variable_get("@#{parameter}") )
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
describe 'constructing orbits from semimajor_axis and eccentricity' do
|
235
|
+
before(:all, &BeforeFactory.geostationary_transfer_orbit)
|
236
|
+
|
237
|
+
it 'should create from the initializer' do
|
238
|
+
orbit = KerbalDyn::Orbit.new(@planetoid, :semimajor_axis => @semimajor_axis, :eccentricity => @eccentricity)
|
239
|
+
[:periapsis, :apoapsis, :periapsis_velocity, :apoapsis_velocity, :eccentricity, :semimajor_axis].each do |parameter|
|
240
|
+
orbit.send(parameter).should be_within_three_sigma_of( instance_variable_get("@#{parameter}") )
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
describe 'constructing cicular orbits from a radius' do
|
247
|
+
before(:all, &BeforeFactory.earth_geostationary_orbit)
|
248
|
+
|
249
|
+
it 'should be creatable from the initializer' do
|
250
|
+
orbit = KerbalDyn::Orbit.new(@planetoid, :radius => @geostationary_orbit_radius)
|
251
|
+
orbit.eccentricity.should be_within(1e-9).of(0.0)
|
252
|
+
orbit.periapsis.should be_within_four_sigma_of(@geostationary_orbit_radius)
|
253
|
+
orbit.periapsis_velocity.should be_within_four_sigma_of(@geostationary_orbit_velocity)
|
254
|
+
orbit.apoapsis.should be_within_four_sigma_of(@geostationary_orbit_radius)
|
255
|
+
orbit.apoapsis_velocity.should be_within_four_sigma_of(@geostationary_orbit_velocity)
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'should be creatable from the factory method' do
|
259
|
+
orbit = KerbalDyn::Orbit.circular_orbit(@planetoid, @geostationary_orbit_radius)
|
260
|
+
orbit.eccentricity.should be_within(1e-9).of(0.0)
|
261
|
+
orbit.periapsis.should be_within_four_sigma_of(@geostationary_orbit_radius)
|
262
|
+
orbit.periapsis_velocity.should be_within_four_sigma_of(@geostationary_orbit_velocity)
|
263
|
+
orbit.apoapsis.should be_within_four_sigma_of(@geostationary_orbit_radius)
|
264
|
+
orbit.apoapsis_velocity.should be_within_four_sigma_of(@geostationary_orbit_velocity)
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'should construct using the orbital period' do
|
268
|
+
orbit = KerbalDyn::Orbit.circular_orbit_of_period(@planetoid, @orbital_period)
|
269
|
+
orbit.eccentricity.should be_within(1e-9).of(0.0)
|
270
|
+
orbit.periapsis.should be_within_four_sigma_of(@geostationary_orbit_radius)
|
271
|
+
orbit.periapsis_velocity.should be_within_four_sigma_of(@geostationary_orbit_velocity)
|
272
|
+
orbit.apoapsis.should be_within_four_sigma_of(@geostationary_orbit_radius)
|
273
|
+
orbit.apoapsis_velocity.should be_within_four_sigma_of(@geostationary_orbit_velocity)
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|
277
|
+
|
278
|
+
describe 'constructing geostationary orbits' do
|
279
|
+
before(:all, &BeforeFactory.earth_geostationary_orbit)
|
280
|
+
|
281
|
+
it 'should construct geostationary orbit' do
|
282
|
+
orbit = KerbalDyn::Orbit.geostationary_orbit(@planetoid)
|
283
|
+
orbit.eccentricity.should be_within(1e-9).of(0.0)
|
284
|
+
orbit.periapsis.should be_within_four_sigma_of(@geostationary_orbit_radius)
|
285
|
+
orbit.apoapsis.should be_within_four_sigma_of(@geostationary_orbit_radius)
|
286
|
+
orbit.apoapsis_velocity.should be_within_four_sigma_of(@geostationary_orbit_velocity)
|
287
|
+
orbit.periapsis_velocity.should be_within_four_sigma_of(@geostationary_orbit_velocity)
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
|
292
|
+
describe 'constructing escape orbits' do
|
293
|
+
|
294
|
+
it 'should construct an escape orbit' do
|
295
|
+
@periapsis = (@planetoid.radius * 2.0) # Just picked one at pseudo-random.
|
296
|
+
orbit = KerbalDyn::Orbit.escape_orbit(@planetoid, @periapsis)
|
297
|
+
orbit.eccentricity.should be_within(1e-9).of(1.0)
|
298
|
+
orbit.specific_energy.should be_within(1e-6).of(0.0)
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
describe 'Orbit Library' do
|
306
|
+
|
307
|
+
PLANET_TEST_DATA.each do |planet_key, test_data|
|
308
|
+
data = test_data[:orbit]
|
309
|
+
|
310
|
+
describe "#{data[:name]}" do
|
311
|
+
|
312
|
+
before(:all) do
|
313
|
+
@library_method = planet_key
|
314
|
+
@orbit = KerbalDyn::Orbit.send(@library_method)
|
315
|
+
end
|
316
|
+
|
317
|
+
it 'should be memoized' do
|
318
|
+
unique_ids = [@orbit, KerbalDyn::Orbit.send(@library_method)].map {|obj| obj.object_id}.uniq
|
319
|
+
unique_ids.length.should == 1
|
320
|
+
end
|
321
|
+
|
322
|
+
it 'should be frozen' do
|
323
|
+
@orbit.should be_frozen
|
324
|
+
end
|
325
|
+
|
326
|
+
it "should have the primary_body #{data[:primary_body]}" do
|
327
|
+
@orbit.primary_body.should == KerbalDyn::Planetoid.send( data[:primary_body] )
|
328
|
+
end
|
329
|
+
|
330
|
+
it "should have the secondary_body #{data[:secondary_body]}" do
|
331
|
+
@orbit.secondary_body.should == KerbalDyn::Planetoid.send( data[:secondary_body] )
|
332
|
+
end
|
333
|
+
|
334
|
+
|
335
|
+
data.each do |property, expected_value|
|
336
|
+
next if [:primary_body, :secondary_body, :name].include?(property)
|
337
|
+
it "should have #{property} of #{expected_value}" do
|
338
|
+
value = @orbit.send(property)
|
339
|
+
case expected_value
|
340
|
+
when Float
|
341
|
+
if( expected_value.abs < 1e-15 )
|
342
|
+
value.should be_within(1e-15).of(expected_value)
|
343
|
+
else
|
344
|
+
value.should be_within_five_sigma_of(expected_value)
|
345
|
+
end
|
346
|
+
else
|
347
|
+
value.should == expected_value
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe KerbalDyn::OrbitalManeuver::Base do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@dummy_body = KerbalDyn::Body.test_particle
|
7
|
+
@dummy_orbit = KerbalDyn::Orbit.new(@dummy_body)
|
8
|
+
|
9
|
+
@body = KerbalDyn::Planetoid.kerbin
|
10
|
+
@orbit1 = KerbalDyn::Orbit.new(@body, :radius => 100e3)
|
11
|
+
@orbit2 = KerbalDyn::Orbit.new(@body, :radius => 12000e3)
|
12
|
+
@maneuver = KerbalDyn::OrbitalManeuver::Base.new(@orbit1, @orbit2)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should check that the initial and final orbits are orbiting the same body' do
|
16
|
+
@orbit1.primary_body.should == @orbit2.primary_body
|
17
|
+
lambda { KerbalDyn::OrbitalManeuver::Base.new(@orbit1, @orbit2) }.should_not raise_error
|
18
|
+
|
19
|
+
@orbit1.primary_body.should_not == @dummy_orbit.primary_body
|
20
|
+
lambda { KerbalDyn::OrbitalManeuver::Base.new(@orbit1, @dummy_orbit) }.should raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should have an initial_orbit' do
|
24
|
+
@maneuver.initial_orbit.should == @orbit1
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should have a final_orbit' do
|
28
|
+
@maneuver.final_orbit.should == @orbit2
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should have delta_time' do
|
32
|
+
@maneuver.should respond_to(:delta_time)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should map delta_t to delta_time' do
|
36
|
+
# Override delta_time just like a subclass would.
|
37
|
+
maneuver = @maneuver.dup.tap {|m| m.stub(:delta_time){:jeb}}
|
38
|
+
|
39
|
+
# The real test.
|
40
|
+
maneuver.delta_t.should == maneuver.delta_time
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'delta_v' do
|
44
|
+
|
45
|
+
class SettableDeltaVelocitiesTestOrbitalManeuver < KerbalDyn::OrbitalManeuver::Base
|
46
|
+
attr_reader :delta_velocities
|
47
|
+
attr_writer :delta_velocities
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should give a list of delta velocities' do
|
51
|
+
KerbalDyn::OrbitalManeuver::Base.new(@dummy_orbit, @dummy_orbit).delta_velocities.should == []
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should give the sums of the absolute velocities as delta_v' do
|
55
|
+
maneuver = SettableDeltaVelocitiesTestOrbitalManeuver.new(@dummy_orbit, @dummy_orbit).tap {|m| m.delta_velocities = [5, -2, 4, 0]}
|
56
|
+
maneuver.delta_velocity.should == 11
|
57
|
+
maneuver.delta_v.should == 11
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should sum an empty velocity list to zero' do
|
61
|
+
maneuver = SettableDeltaVelocitiesTestOrbitalManeuver.new(@dummy_orbit, @dummy_orbit).tap {|m| m.delta_velocities = []}
|
62
|
+
maneuver.delta_velocity.should == 0
|
63
|
+
maneuver.delta_v.should == 0
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should sum a single negative velocity to its absolute value' do
|
67
|
+
maneuver = SettableDeltaVelocitiesTestOrbitalManeuver.new(@dummy_orbit, @dummy_orbit).tap {|m| m.delta_velocities = [-2]}
|
68
|
+
maneuver.delta_velocity.should == 2
|
69
|
+
maneuver.delta_v.should == 2
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|