kerbaldyn 0.7.0 → 0.8.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/README.rdoc +46 -2
- data/bin/kerbaldyn +84 -0
- data/lib/kerbaldyn/orbit.rb +36 -7
- data/lib/kerbaldyn/orbital_maneuver/hohmann.rb +2 -2
- data/lib/kerbaldyn/part/base.rb +15 -4
- data/lib/kerbaldyn/part_library.rb +11 -1
- data/lib/kerbaldyn/planetoid.rb +5 -8
- data/lib/kerbaldyn/version.rb +1 -1
- data/spec/orbit_spec.rb +1 -1
- data/spec/part_library_spec.rb +39 -7
- data/spec/part_spec.rb +15 -3
- data/spec/support/parts/erroredPart/part.cfg +67 -0
- data/spec/support/parts/parachuteLarge/part.cfg +65 -0
- metadata +8 -2
data/README.rdoc
CHANGED
@@ -8,7 +8,38 @@ A library for Kerbal Space Program (KSP) calculation and simulation tools.
|
|
8
8
|
|
9
9
|
[Planetoid] - Encapsulates parameters relating to suns, planets, and moons, such as Kerbal and Mun.
|
10
10
|
[Orbit] - Encapsulates parameters relating to orbits about a body.
|
11
|
-
[
|
11
|
+
[OrbitalManeuver] - Encapsulates parameters for orbit changes.
|
12
|
+
|
13
|
+
[Part] - Parses part information into something meaningful.
|
14
|
+
[Part Library] - Allows organization of collections of parts.
|
15
|
+
|
16
|
+
= Examples
|
17
|
+
|
18
|
+
Calculate the speed and period of an orbit 5000 m above Mun:
|
19
|
+
mun = KerbalDyn::Planetoid.mun
|
20
|
+
orbit = KerbalDyn::Orbit.new(mun, :radius => (mun.radius + 5000))
|
21
|
+
orbit.periapsis_velocity
|
22
|
+
orbit.period
|
23
|
+
This should produce a speed of 563.7 m/s and a period of 2285 seconds (38.1 minutes)
|
24
|
+
|
25
|
+
To get information about a Hohmann transfer from the above 5000 m orbit to a
|
26
|
+
25000 m orbit, you could take the following additional steps:
|
27
|
+
destination_orbit = KerbalDyn::Orbit.new(mun, :radius => (mun.radius + 25000))
|
28
|
+
transfer = KerbalDyn::OrbitalManeuver::Hohmann.new(orbit, destination_orbit)
|
29
|
+
transfer.delta_t
|
30
|
+
transfer.velocities
|
31
|
+
transfer.delta_v
|
32
|
+
This instructs us that a prograde burn from the starting speed of 563.7 m/s to
|
33
|
+
576.65 m/s will put us on an intercept orbit whose apoapsis is at 25000 m; furthermore,
|
34
|
+
1227 seconds later (20.5 minutes) we will reach apoapsis and should do another
|
35
|
+
burn from the apoapsis velocity of 525.4 m/s up to 538 m/s to circularize the
|
36
|
+
orbit.
|
37
|
+
|
38
|
+
In the above calculation, if there was a Command Module in a circular orbit at
|
39
|
+
25000 m, and we were in a LEM at 5000 m, we can calculate the phase angle that
|
40
|
+
the Command Module should be ahead of us when we do our first burn as:
|
41
|
+
transfer.mean_lead_angle
|
42
|
+
which gives 0.2071 radians, or 11.87 degrees.
|
12
43
|
|
13
44
|
= Author
|
14
45
|
|
@@ -17,17 +48,30 @@ jeff@paploo.net
|
|
17
48
|
|
18
49
|
= TODO
|
19
50
|
|
51
|
+
Library:
|
20
52
|
* Refactor planetoid and orbit tests to use a JSON data file from a game dump.
|
21
|
-
* Add
|
53
|
+
* Add Elephant Cache to Orbital Manuever methods so that we do not rebuild and recalculate everything all the time.
|
54
|
+
* Finish Part and Part Library.
|
55
|
+
|
56
|
+
Binary Utilities:
|
22
57
|
* Build a tool for calculating lead angles: kerbaldyn leadangle kerbin@100a mun
|
23
58
|
* Build a tool for outputting body information in standard units: kerbaldyn info minmus
|
24
59
|
* Build a tool for calculating the delta-v of hohmann vs various bielliptic transfers: kerbaldyn transfer kerbin@900r minmus
|
25
60
|
* Build a tool for listing parts of a type with important specs, sorted in useful ways: kerbaldyn partlist --type liquidfuelengine --sort isp
|
26
61
|
|
62
|
+
Web:
|
63
|
+
* Make the CLI bin tools accessible via a Sinatra based mobile interface so that you can hit a local server from your phone.
|
64
|
+
|
27
65
|
Notes:
|
28
66
|
* Remember that bielliptic transfer high altitudes are theoretically limited by the SOI.
|
29
67
|
* Can specify orbits by planet@400a or planet@400r for 400km alt or 400km radius respectively.
|
30
68
|
|
69
|
+
= Version History
|
70
|
+
[0.8.0 - 2012-Nov-02] Additions and bugfixes.
|
71
|
+
* (FEATURE) Part and PartLibrary completed just in time to realise it won't work with 0.18.
|
72
|
+
* (FIX) The SOI calculation now uses the empirically tested version from in the game.
|
73
|
+
[0.7.0 - 2012-Oct-02] Initial Public Release.
|
74
|
+
|
31
75
|
= License
|
32
76
|
|
33
77
|
Copyright (c) 2012, Jeffrey C. Reinecke
|
data/bin/kerbaldyn
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
require File.expand_path( File.join( File.dirname(__FILE__), '..', 'lib', 'kerbaldyn' ) )
|
6
|
+
|
7
|
+
module KerbalDyn
|
8
|
+
class Application
|
9
|
+
|
10
|
+
def initialize(argv)
|
11
|
+
@command, *@args = argv
|
12
|
+
@ioout = STDOUT
|
13
|
+
@ioerr = STDERR
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :command
|
17
|
+
attr_reader :args
|
18
|
+
attr_reader :error
|
19
|
+
|
20
|
+
attr_reader :ioout
|
21
|
+
attr_reader :ioerr
|
22
|
+
|
23
|
+
def run
|
24
|
+
begin
|
25
|
+
dispatch
|
26
|
+
rescue Exception => e
|
27
|
+
@error = e
|
28
|
+
ioerr.puts "ERROR: #{e.message}"
|
29
|
+
ioerr.puts e.backtrace.join("\n")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def dispatch
|
34
|
+
#TODO: Figure out the patterns in argument processing and how to extract that.
|
35
|
+
case command
|
36
|
+
when 'info'
|
37
|
+
planet = args.first.downcase
|
38
|
+
raise ArgumentError, "Unknown planet #{planet}." unless KerbalDyn::Planetoid.planetoid_methods.include?(planet.to_sym)
|
39
|
+
planetoid = KerbalDyn::Planetoid.send(planet)
|
40
|
+
orbit = KerbalDyn::Orbit.send(planet)
|
41
|
+
ioout.puts "PLANETOID"
|
42
|
+
ioout.puts [:name, :gravitational_parameter, :radius, :rotational_period, :surface_gravity].map {|method| "#{method.to_s.rjust(32)}: #{planetoid.send(method).inspect.rjust(20)}"}.join("\n")
|
43
|
+
ioout.puts "ORBIT"
|
44
|
+
ioout.puts [:apoapsis, :periapsis, :period, :mean_velocity, :sphere_of_influence].map {|method| "#{method.to_s.rjust(32)}: #{orbit.send(method).inspect.rjust(20)}"}.join("\n")
|
45
|
+
when 'leadangle'
|
46
|
+
initial_orbit = KerbalDyn::Orbit.from_string( args[0] )
|
47
|
+
final_orbit = KerbalDyn::Orbit.from_string( args[1] )
|
48
|
+
maneuver = KerbalDyn::OrbitalManeuver::Hohmann.new(initial_orbit, final_orbit)
|
49
|
+
ioout.puts "LEAD ANGLE: #{maneuver.mean_lead_angle * 180.0 / Math::PI} deg"
|
50
|
+
ioout.puts "DELTA V : #{maneuver.delta_v.round} m/s"
|
51
|
+
ioout.puts "DELTA T : #{maneuver.delta_t.round} sec"
|
52
|
+
when 'transfer'
|
53
|
+
# It seems as though if r_final / r_initial < 13(ish), then hohmann always wins, and when > 15(ish) bielliptic always wins?
|
54
|
+
initial_orbit = KerbalDyn::Orbit.from_string( args[0] )
|
55
|
+
final_orbit= KerbalDyn::Orbit.from_string( args[1] )
|
56
|
+
hohmann = KerbalDyn::OrbitalManeuver::Hohmann.new(initial_orbit, final_orbit)
|
57
|
+
ioout.puts( [:delta_v, :delta_t].map {|parameter| hohmann.send(parameter).round}.inspect )
|
58
|
+
|
59
|
+
min_radius = [initial_orbit.semimajor_axis, final_orbit.semimajor_axis].max
|
60
|
+
max_radius = initial_orbit.primary_body_sphere_of_influence
|
61
|
+
n = 1000
|
62
|
+
biellipticals = (0..n).map do |i|
|
63
|
+
#radius = (i/n.to_f)*(max_radius - min_radius) + min_radius
|
64
|
+
radius = (i/n.to_f)*(19*min_radius) + min_radius
|
65
|
+
bielliptic = KerbalDyn::OrbitalManeuver::Bielliptic.new(initial_orbit, final_orbit, :transfer_radius => radius)
|
66
|
+
#ioout.puts( ([i, radius/min_radius] + [:transfer_radius, :delta_v, :delta_t].map {|parameter| bielliptic.send(parameter).round}).inspect )
|
67
|
+
bielliptic
|
68
|
+
end
|
69
|
+
|
70
|
+
surface_radius = initial_orbit.primary_body.radius
|
71
|
+
min_delta_v = biellipticals.map {|bielliptic| bielliptic.delta_v}.min
|
72
|
+
biellipticals.select do |bielliptic|
|
73
|
+
(bielliptic.delta_v - min_delta_v).abs < 1.0
|
74
|
+
end.each do |bielliptic|
|
75
|
+
ioout.puts( [:transfer_radius, :delta_v, :delta_t].map {|parameter| bielliptic.send(parameter).round}.inspect )
|
76
|
+
end
|
77
|
+
when 'partlist'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
KerbalDyn::Application.new(ARGV).run
|
data/lib/kerbaldyn/orbit.rb
CHANGED
@@ -121,6 +121,32 @@ module KerbalDyn
|
|
121
121
|
return self.new(primary_body, :periapsis => periapsis, :periapsis_velocity => periapsis_escape_velocity)
|
122
122
|
end
|
123
123
|
|
124
|
+
# Given a string, create an orbit for it. The string specification is one of:
|
125
|
+
# [{planetoid}] The orbit for the planetoid around its parent body.
|
126
|
+
# [{planetoid}@{number}{designator}] Builds an orbit around the given planetoid with the given radius
|
127
|
+
# or altitude in meters. The designator is one of r or a for radius
|
128
|
+
# or altitude. Defaults to radius.
|
129
|
+
def self.from_string(string)
|
130
|
+
orbit_with_altitude_regex = /^([a-z]+)@([\d]+)([ra]{0,1})$/
|
131
|
+
|
132
|
+
expression = string.to_s.downcase
|
133
|
+
case expression
|
134
|
+
when /^([a-z]+)$/
|
135
|
+
planetoid_method = expression.to_sym
|
136
|
+
raise ArgumentError, "Unknown planetoid: #{string}" unless Planetoid.planetoid_methods.include?(planetoid_method)
|
137
|
+
self.send(planetoid_method)
|
138
|
+
when orbit_with_altitude_regex
|
139
|
+
matched, planetoid_name, distance, distance_designator = orbit_with_altitude_regex.match(expression).to_a
|
140
|
+
planetoid_method = planetoid_name.to_sym
|
141
|
+
raise ArgumentError, "Unknown planetoid: #{planetoid}" unless Planetoid.planetoid_methods.include?(planetoid_method)
|
142
|
+
planetoid = Planetoid.send(planetoid_method)
|
143
|
+
radius = (distance_designator=='a') ? (distance.to_f + planetoid.radius) : distance.to_f
|
144
|
+
self.new(planetoid, :radius => radius)
|
145
|
+
else
|
146
|
+
raise ArgumentError, "Unknown orbit expression: #{string}"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
124
150
|
# Create a new orbit.
|
125
151
|
#
|
126
152
|
# The first argument should be the Body (usually a Planetoid) that is being orbited.
|
@@ -172,26 +198,29 @@ module KerbalDyn
|
|
172
198
|
# Returns the sphere of influence (SOI) for the secondary body in the context
|
173
199
|
# of the two-body system.
|
174
200
|
#
|
175
|
-
#
|
201
|
+
# In 0.17, for Mun, this matches to better than 0.015% error, while the others are *way* off.
|
176
202
|
def secondary_body_sphere_of_influence
|
177
203
|
return self.semimajor_axis * (self.secondary_body.mass / self.primary_body.mass)**(0.4)
|
178
204
|
end
|
179
|
-
alias_method :
|
205
|
+
alias_method :laplace_sphere_of_influence, :secondary_body_sphere_of_influence
|
180
206
|
|
181
|
-
# The Hill Sphere radius.
|
207
|
+
# The Hill Sphere radius. This comes from the approximation of L1/L2.
|
182
208
|
#
|
183
209
|
# This is NOT the KSP SOI, for it, use +kerbal_sphere_of_influence+
|
184
210
|
def hill_sphere_radius
|
185
211
|
return self.periapsis * (self.secondary_body.mass / (3.0*self.primary_body.mass))**(2.0/3.0)
|
186
212
|
end
|
187
213
|
|
188
|
-
|
189
|
-
#
|
190
|
-
|
214
|
+
# This is yet another sphere of influence definition I came across, from the bottom of
|
215
|
+
# Wikipedia. This matched some numbers I got from a data dump, but don't match
|
216
|
+
# empirical data from the conic patching in game.
|
217
|
+
def equivalent_gravity_sphere_of_influence
|
191
218
|
return self.periapsis * (self.secondary_body.mass / self.primary_body.mass)**(1.0/3.0)
|
192
219
|
end
|
193
|
-
alias_method :kerbal_soi, :kerbal_sphere_of_influence
|
194
220
|
|
221
|
+
# Alias to the sphere of influence used in game.
|
222
|
+
alias_method :sphere_of_influence, :secondary_body_sphere_of_influence
|
223
|
+
alias_method :soi, :sphere_of_influence
|
195
224
|
|
196
225
|
# Orbit classification, returns one of :subelliptical, :circular, :elliptical,
|
197
226
|
# :parabolic, or :hyperbolic.
|
@@ -22,8 +22,8 @@ module KerbalDyn
|
|
22
22
|
# The elliptical orbit used to transfer from the initial_orbit to the
|
23
23
|
# final_orbit.
|
24
24
|
def transfer_orbit
|
25
|
-
r1 = initial_orbit.periapsis
|
26
|
-
r2 = final_orbit.apoapsis
|
25
|
+
r1 = self.initial_orbit.periapsis
|
26
|
+
r2 = self.final_orbit.apoapsis
|
27
27
|
# TODO: It should be the Orbit's job to min/max periapsis and apoapsis, and then set angles appropriately.
|
28
28
|
return @transfer_orbit ||= Orbit.new(self.initial_orbit.primary_body, :periapsis => [r1,r2].min, :apoapsis => [r1,r2].max)
|
29
29
|
end
|
data/lib/kerbaldyn/part/base.rb
CHANGED
@@ -21,6 +21,7 @@ module KerbalDyn
|
|
21
21
|
|
22
22
|
# Initialize the attributes container.
|
23
23
|
attributes = {}
|
24
|
+
errors = []
|
24
25
|
line_count = 0
|
25
26
|
|
26
27
|
# Parse the lines.
|
@@ -38,12 +39,12 @@ module KerbalDyn
|
|
38
39
|
key,value = line.split('=', 2).map {|s| s.strip}
|
39
40
|
attributes[key] = value
|
40
41
|
else
|
41
|
-
|
42
|
+
errors << {:type => :unknown_line, :message => "Unhandled line in #{spec_file.to_s}:#{line_count}: #{line.inspect}"}
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
46
|
# Now instantiate the right kind of part.
|
46
|
-
return self.module_class(attributes['module']).new(attributes)
|
47
|
+
return self.module_class(attributes['module']).new(attributes).tap {|p| p.send(:errors=, errors)}
|
47
48
|
end
|
48
49
|
|
49
50
|
# Return the class to instantiate for a given +module+ attribute.
|
@@ -69,6 +70,16 @@ module KerbalDyn
|
|
69
70
|
# being said, this is provided for special/power use cases.
|
70
71
|
attr_reader :attributes
|
71
72
|
|
73
|
+
# Return any errors with this part (usually found during parsing),
|
74
|
+
# or an empty array if there were none.
|
75
|
+
def errors
|
76
|
+
return @errors || []
|
77
|
+
end
|
78
|
+
|
79
|
+
# Private method used to set the errors.
|
80
|
+
attr_writer :errors
|
81
|
+
private :errors=
|
82
|
+
|
72
83
|
# Return the raw attribute value by string or symbol.
|
73
84
|
#
|
74
85
|
# It is generally preferrable to use the accessor method.
|
@@ -85,8 +96,8 @@ module KerbalDyn
|
|
85
96
|
end
|
86
97
|
|
87
98
|
# Returns a JSON encoded form of the to_hash result.
|
88
|
-
def to_json
|
89
|
-
return self.to_hash.to_json
|
99
|
+
def to_json(*args)
|
100
|
+
return self.to_hash.to_json(*args)
|
90
101
|
end
|
91
102
|
|
92
103
|
def name
|
@@ -33,7 +33,7 @@ module KerbalDyn
|
|
33
33
|
return @parts.each(&block)
|
34
34
|
end
|
35
35
|
|
36
|
-
# The
|
36
|
+
# The length
|
37
37
|
def length
|
38
38
|
return @parts.length
|
39
39
|
end
|
@@ -48,6 +48,16 @@ module KerbalDyn
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
# Returns all the parts in the library, in an array.
|
52
|
+
def to_a
|
53
|
+
return @parts.to_a.dup
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns the parts library as JSONified parts.
|
57
|
+
def to_json(*args)
|
58
|
+
return @parts.to_json(*args)
|
59
|
+
end
|
60
|
+
|
51
61
|
end
|
52
62
|
end
|
53
63
|
|
data/lib/kerbaldyn/planetoid.rb
CHANGED
@@ -19,6 +19,11 @@ module KerbalDyn
|
|
19
19
|
private :make
|
20
20
|
end
|
21
21
|
|
22
|
+
# Returns an array of the planetoid methods
|
23
|
+
def self.planetoid_methods
|
24
|
+
return @planet_methods ||= [:kerbol, :moho, :eve, :gilly, :kerbin, :mun, :minmus, :duna, :ike, :jool, :laythe, :vall, :tylo, :bop]
|
25
|
+
end
|
26
|
+
|
22
27
|
# :category: Library Methods
|
23
28
|
# The Kerbal Sun.
|
24
29
|
def self.kerbol
|
@@ -166,14 +171,6 @@ module KerbalDyn
|
|
166
171
|
return self.angular_velocity * (self.radius + h)
|
167
172
|
end
|
168
173
|
|
169
|
-
# Equitorial linear velocity of the planetoid.
|
170
|
-
#
|
171
|
-
# If a value is gien, then this is used as the height above the surface for
|
172
|
-
# the calculation.
|
173
|
-
def equitorial_velocity(h=0.0)
|
174
|
-
return self.angular_velocity * (self.radius + h)
|
175
|
-
end
|
176
|
-
|
177
174
|
# Calculates the escape velocity of the planetoid.
|
178
175
|
def escape_velocity
|
179
176
|
return Math.sqrt( 2.0 * self.gravitational_parameter / self.radius )
|
data/lib/kerbaldyn/version.rb
CHANGED
data/spec/orbit_spec.rb
CHANGED
@@ -333,7 +333,7 @@ describe KerbalDyn::Orbit do
|
|
333
333
|
|
334
334
|
|
335
335
|
data.each do |property, expected_value|
|
336
|
-
next if [:primary_body, :secondary_body, :name].include?(property)
|
336
|
+
next if [:primary_body, :secondary_body, :name, :kerbal_sphere_of_influence].include?(property)
|
337
337
|
it "should have #{property} of #{expected_value}" do
|
338
338
|
value = @orbit.send(property)
|
339
339
|
case expected_value
|
data/spec/part_library_spec.rb
CHANGED
@@ -2,19 +2,51 @@ require File.join(File.dirname(__FILE__), 'spec_helper')
|
|
2
2
|
|
3
3
|
describe KerbalDyn::PartLibrary do
|
4
4
|
|
5
|
-
|
5
|
+
before(:each) do
|
6
|
+
@parts = [
|
7
|
+
KerbalDyn::Part::Generic.new(:name => 'part1'),
|
8
|
+
KerbalDyn::Part::Generic.new(:name => 'part2').tap {|p| p.send(:errors=, [{:error => :foo, :message => 'bar'}])}
|
9
|
+
]
|
6
10
|
|
7
|
-
|
11
|
+
@library = KerbalDyn::PartLibrary.new(*@parts)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should be enumerable' do
|
15
|
+
@library.should respond_to(:each)
|
16
|
+
@library.class.included_modules.should include(Enumerable)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should respond to length' do
|
20
|
+
@library.should respond_to(:length)
|
21
|
+
@library.length.should == @parts.length
|
22
|
+
end
|
8
23
|
|
9
|
-
it 'should
|
24
|
+
it 'should export as JSON' do
|
25
|
+
json = @library.to_json
|
26
|
+
|
27
|
+
json.should be_kind_of(String)
|
28
|
+
lambda {JSON.parse(json)}.should_not raise_error
|
29
|
+
JSON.parse(json).should be_kind_of(Array)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should export as CSV' do
|
33
|
+
pending "Need to stub CSV output on test parts first."
|
34
|
+
end
|
10
35
|
|
11
|
-
|
36
|
+
describe 'parts directory parser' do
|
12
37
|
|
13
|
-
|
38
|
+
before(:each) do
|
39
|
+
@parts_directory = File.join(File.dirname(__FILE__), 'support', 'parts')
|
40
|
+
@library = KerbalDyn::PartLibrary.load_parts(@parts_directory)
|
41
|
+
end
|
14
42
|
|
15
|
-
|
43
|
+
it 'should be composed of parts' do
|
44
|
+
@library.reject {|part| part.kind_of?(KerbalDyn::Part::Base)}.should == []
|
45
|
+
end
|
16
46
|
|
17
|
-
it 'should
|
47
|
+
it 'should have a length of 7' do
|
48
|
+
@library.length.should == 7
|
49
|
+
end
|
18
50
|
|
19
51
|
end
|
20
52
|
|
data/spec/part_spec.rb
CHANGED
@@ -61,7 +61,9 @@ describe KerbalDyn::Part do
|
|
61
61
|
part_json.should == attributes_json
|
62
62
|
end
|
63
63
|
|
64
|
-
it 'should export as CSV'
|
64
|
+
it 'should export as CSV' do
|
65
|
+
pending "This will need a predefined set of properties to output."
|
66
|
+
end
|
65
67
|
|
66
68
|
end
|
67
69
|
|
@@ -85,7 +87,11 @@ describe KerbalDyn::Part do
|
|
85
87
|
@part.class.name.should =~ Regexp.new( 'KerbalDyn::Part::' + @part[:module] + "$")
|
86
88
|
end
|
87
89
|
|
88
|
-
it 'should default to instantiating as generic'
|
90
|
+
it 'should default to instantiating as generic' do
|
91
|
+
part_dir = File.join(@parts_directory, 'parachuteLarge')
|
92
|
+
part = KerbalDyn::Part::Base.load_part(part_dir)
|
93
|
+
part.class.name.should == 'KerbalDyn::Part::Generic'
|
94
|
+
end
|
89
95
|
|
90
96
|
it 'should return nil if no part was found' do
|
91
97
|
dir_path = File.join(@parts_directory, 'tardis') # Doesn't exist.
|
@@ -93,7 +99,13 @@ describe KerbalDyn::Part do
|
|
93
99
|
part.should == nil
|
94
100
|
end
|
95
101
|
|
96
|
-
it 'should log parse errors'
|
102
|
+
it 'should log parse errors' do
|
103
|
+
dir_path = File.join(@parts_directory, 'erroredPart')
|
104
|
+
part = KerbalDyn::Part::Base.load_part(dir_path)
|
105
|
+
|
106
|
+
part.errors.should be_kind_of(Array)
|
107
|
+
part.errors.length.should > 0
|
108
|
+
end
|
97
109
|
|
98
110
|
end
|
99
111
|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
// this is a sample config file, for determining a good file format for defining part parameters
|
2
|
+
// comment line - ignored by cfg parser
|
3
|
+
// empty lines, or lines without a '=' sign are also ignored
|
4
|
+
// all other lines are split at the '=' sign, and the left operand is used to know what parameter we are setting
|
5
|
+
// diferent parameters require data in different formats (see docs), and each module has it's own parameters (again, see docs)
|
6
|
+
// each assignment must be in a single line. Lines without assignments will be ignored. (You CAN turn on word wrap, though)
|
7
|
+
// each keyword here relates to an existing variable in the assigned module. If the keyword isn't found, it is ignored.
|
8
|
+
// conversely, if a keyword is left unassigned (as in not in the file), it will be initialized with it's default value
|
9
|
+
// This is done automatically, so any public variable defined in the loaded module can be accessed this way (provided it's value can be parsed)
|
10
|
+
|
11
|
+
|
12
|
+
// --- general parameters ---
|
13
|
+
name = parachuteLarge
|
14
|
+
module = HParachutes
|
15
|
+
author = HarvesteR
|
16
|
+
|
17
|
+
Here is an error line!
|
18
|
+
|
19
|
+
// --- asset parameters ---
|
20
|
+
mesh = model.mu
|
21
|
+
scale = 0.1
|
22
|
+
|
23
|
+
rescaleFactor = 1
|
24
|
+
|
25
|
+
// --- node definitions ---
|
26
|
+
// definition format is Position X, Position Y, Position Z, Up X, Up Y, Up Z, size
|
27
|
+
node_stack_bottom = 0.0, -0.020649, 0.0, 0.0, 1.0, 0.0, 1
|
28
|
+
node_attach = 0.0, -0.020649, 0.0, 0.0, -1.0, 0.0
|
29
|
+
|
30
|
+
// --- FX definitions ---
|
31
|
+
sound_parachute_open = activate
|
32
|
+
sound_parachute_single = deploy
|
33
|
+
|
34
|
+
// --- editor parameters ---
|
35
|
+
cost = 850
|
36
|
+
category = 3
|
37
|
+
subcategory = 0
|
38
|
+
title = Mk16-XL Parachute
|
39
|
+
|
40
|
+
description = The Mk16-XL Parachute is a double-sized variant of the Mk16, now with only 50% of the structural integrity!
|
41
|
+
|
42
|
+
// attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision
|
43
|
+
attachRules = 1,1,0,1,0
|
44
|
+
|
45
|
+
// --- standard part parameters ---
|
46
|
+
mass = 0.3
|
47
|
+
dragModelType = default
|
48
|
+
angularDrag = 3
|
49
|
+
crashTolerance = 12
|
50
|
+
maxTemp = 3100
|
51
|
+
|
52
|
+
breakingForce = 100
|
53
|
+
breakingTorque = 50
|
54
|
+
|
55
|
+
stageOffset = -1
|
56
|
+
|
57
|
+
// --- parachute parameters ---
|
58
|
+
useAGL = True
|
59
|
+
autoDeployDelay = 3.0
|
60
|
+
minAirPressureToOpen = 0.01
|
61
|
+
deployAltitude = 500
|
62
|
+
closedDrag = 0.22
|
63
|
+
semiDeployedDrag = 1
|
64
|
+
fullyDeployedDrag = 500
|
65
|
+
|
66
|
+
// ----- DO NOT EDIT BELOW THIS POINT ------
|
67
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
// this is a sample config file, for determining a good file format for defining part parameters
|
2
|
+
// comment line - ignored by cfg parser
|
3
|
+
// empty lines, or lines without a '=' sign are also ignored
|
4
|
+
// all other lines are split at the '=' sign, and the left operand is used to know what parameter we are setting
|
5
|
+
// diferent parameters require data in different formats (see docs), and each module has it's own parameters (again, see docs)
|
6
|
+
// each assignment must be in a single line. Lines without assignments will be ignored. (You CAN turn on word wrap, though)
|
7
|
+
// each keyword here relates to an existing variable in the assigned module. If the keyword isn't found, it is ignored.
|
8
|
+
// conversely, if a keyword is left unassigned (as in not in the file), it will be initialized with it's default value
|
9
|
+
// This is done automatically, so any public variable defined in the loaded module can be accessed this way (provided it's value can be parsed)
|
10
|
+
|
11
|
+
|
12
|
+
// --- general parameters ---
|
13
|
+
name = parachuteLarge
|
14
|
+
module = HParachutes
|
15
|
+
author = HarvesteR
|
16
|
+
|
17
|
+
// --- asset parameters ---
|
18
|
+
mesh = model.mu
|
19
|
+
scale = 0.1
|
20
|
+
|
21
|
+
rescaleFactor = 1
|
22
|
+
|
23
|
+
// --- node definitions ---
|
24
|
+
// definition format is Position X, Position Y, Position Z, Up X, Up Y, Up Z, size
|
25
|
+
node_stack_bottom = 0.0, -0.020649, 0.0, 0.0, 1.0, 0.0, 1
|
26
|
+
node_attach = 0.0, -0.020649, 0.0, 0.0, -1.0, 0.0
|
27
|
+
|
28
|
+
// --- FX definitions ---
|
29
|
+
sound_parachute_open = activate
|
30
|
+
sound_parachute_single = deploy
|
31
|
+
|
32
|
+
// --- editor parameters ---
|
33
|
+
cost = 850
|
34
|
+
category = 3
|
35
|
+
subcategory = 0
|
36
|
+
title = Mk16-XL Parachute
|
37
|
+
|
38
|
+
description = The Mk16-XL Parachute is a double-sized variant of the Mk16, now with only 50% of the structural integrity!
|
39
|
+
|
40
|
+
// attachment rules: stack, srfAttach, allowStack, allowSrfAttach, allowCollision
|
41
|
+
attachRules = 1,1,0,1,0
|
42
|
+
|
43
|
+
// --- standard part parameters ---
|
44
|
+
mass = 0.3
|
45
|
+
dragModelType = default
|
46
|
+
angularDrag = 3
|
47
|
+
crashTolerance = 12
|
48
|
+
maxTemp = 3100
|
49
|
+
|
50
|
+
breakingForce = 100
|
51
|
+
breakingTorque = 50
|
52
|
+
|
53
|
+
stageOffset = -1
|
54
|
+
|
55
|
+
// --- parachute parameters ---
|
56
|
+
useAGL = True
|
57
|
+
autoDeployDelay = 3.0
|
58
|
+
minAirPressureToOpen = 0.01
|
59
|
+
deployAltitude = 500
|
60
|
+
closedDrag = 0.22
|
61
|
+
semiDeployedDrag = 1
|
62
|
+
fullyDeployedDrag = 500
|
63
|
+
|
64
|
+
// ----- DO NOT EDIT BELOW THIS POINT ------
|
65
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kerbaldyn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-08 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: A library for Kerbal Space Program (KSP) calculation and simulation tools.
|
15
15
|
email: jeff@paploo.net
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- lib/kerbaldyn/planetoid.rb
|
49
49
|
- lib/kerbaldyn/version.rb
|
50
50
|
- lib/kerbaldyn.rb
|
51
|
+
- bin/kerbaldyn
|
51
52
|
- spec/bielliptic_orbital_maneuver_spec.rb
|
52
53
|
- spec/constants_spec.rb
|
53
54
|
- spec/hohmann_orbital_maneuver_spec.rb
|
@@ -59,9 +60,11 @@ files:
|
|
59
60
|
- spec/part_spec.rb
|
60
61
|
- spec/planetoid_spec.rb
|
61
62
|
- spec/spec_helper.rb
|
63
|
+
- spec/support/parts/erroredPart/part.cfg
|
62
64
|
- spec/support/parts/fuelTank/part.cfg
|
63
65
|
- spec/support/parts/liquidEngine1/part.cfg
|
64
66
|
- spec/support/parts/liquidEngine2/part.cfg
|
67
|
+
- spec/support/parts/parachuteLarge/part.cfg
|
65
68
|
- spec/support/parts/RCSFuelTank/part.cfg
|
66
69
|
- spec/support/parts/solidBooster/part.cfg
|
67
70
|
- spec/support/planet_test_data.json
|
@@ -86,6 +89,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
89
|
- - ! '>='
|
87
90
|
- !ruby/object:Gem::Version
|
88
91
|
version: '0'
|
92
|
+
segments:
|
93
|
+
- 0
|
94
|
+
hash: 3608283605174890953
|
89
95
|
requirements: []
|
90
96
|
rubyforge_project:
|
91
97
|
rubygems_version: 1.8.24
|