tengai 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +8 -0
- data/Gemfile +3 -0
- data/README.md +47 -0
- data/Rakefile +52 -0
- data/ext/horizons/body_data_sheet_parser.rb +350 -0
- data/ext/horizons/body_data_sheet_parser.rl +52 -0
- data/ext/horizons/vector_ephemeris_parser.rb +4400 -0
- data/ext/horizons/vector_ephemeris_parser.rl +115 -0
- data/lib/tengai/body.rb +22 -0
- data/lib/tengai/client.rb +34 -0
- data/lib/tengai/ephemeris.rb +56 -0
- data/lib/tengai/parsers/ephemeris_table_parser.rb +20 -0
- data/lib/tengai/requests/ephemeris_request.rb +131 -0
- data/lib/tengai/vector_ephemeris_table.rb +36 -0
- data/lib/tengai/version.rb +5 -0
- data/lib/tengai.rb +27 -0
- data/tengai.gemspec +63 -0
- data/test/fixtures/bodies/10.txt +23 -0
- data/test/fixtures/bodies/399.txt +29 -0
- data/test/fixtures/bodies/499.txt +25 -0
- data/test/fixtures/bodies/501.txt +13 -0
- data/test/fixtures/ephemerides/mars_observed_by_earth_from_2012_12_28_to_29.txt +270 -0
- data/test/fixtures/ephemerides/mars_vectors_from_solar_system_center.txt +61 -0
- data/test/fixtures/major_bodies.txt +300 -0
- data/test/fixtures.rb +21 -0
- data/test/integration/body_integration_test.rb +26 -0
- data/test/integration/ephemeris_integration_test.rb +32 -0
- data/test/test_helper.rb +13 -0
- data/test/unit/body_data_sheet_parser_test.rb +25 -0
- data/test/unit/body_test.rb +35 -0
- data/test/unit/ephemeris_table_parser_test.rb +19 -0
- data/test/unit/ephemeris_test.rb +22 -0
- data/test/unit/vector_ephemeris_parser_test.rb +47 -0
- data/test/unit/vector_ephemeris_table_test.rb +30 -0
- metadata +178 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
=begin
|
2
|
+
%%{
|
3
|
+
|
4
|
+
machine ephemeris_parser;
|
5
|
+
|
6
|
+
action mark { mark = p }
|
7
|
+
|
8
|
+
action target_body_id {
|
9
|
+
target_body_id = data[mark..p].pack('c*')
|
10
|
+
}
|
11
|
+
|
12
|
+
action center_body_id {
|
13
|
+
center_body_id = data[mark..p].pack('c*')
|
14
|
+
}
|
15
|
+
|
16
|
+
action start_time {
|
17
|
+
start_time = data[mark..p].pack('c*')
|
18
|
+
}
|
19
|
+
|
20
|
+
action stop_time {
|
21
|
+
stop_time = data[mark..p].pack('c*')
|
22
|
+
}
|
23
|
+
|
24
|
+
action step_size {
|
25
|
+
step_size = data[mark..p].pack('c*')
|
26
|
+
}
|
27
|
+
|
28
|
+
action ephemeris_table {
|
29
|
+
ephemeris_table = data[mark..p - 1].pack('c*')
|
30
|
+
}
|
31
|
+
|
32
|
+
action ephemeris_columns {
|
33
|
+
ephemeris_columns = data[mark..p].pack('c*')
|
34
|
+
}
|
35
|
+
|
36
|
+
ws = [ \t\r\n];
|
37
|
+
|
38
|
+
adbc = ('A.D.'|'B.C.');
|
39
|
+
year = digit{4};
|
40
|
+
month = upper lower{2};
|
41
|
+
date = digit{2};
|
42
|
+
hours = digit{2};
|
43
|
+
minutes = digit{2};
|
44
|
+
seconds = digit{2} '.' digit{4};
|
45
|
+
tz = ('C'|'U') 'T';
|
46
|
+
datetime = adbc ' ' year '-' month '-' date ' ' hours ':' minutes ':' seconds ' ' tz;
|
47
|
+
|
48
|
+
hr = '*'+ '\n';
|
49
|
+
|
50
|
+
time_unit = ('minute' [s]? | 'calendar year' [s]?);
|
51
|
+
|
52
|
+
body_name = (alnum | space)*;
|
53
|
+
body_id = digit*;
|
54
|
+
|
55
|
+
target_body = 'Target body name:' space body_name space
|
56
|
+
'(' body_id >mark @target_body_id ')'
|
57
|
+
ws* '{' any* '}' '\n';
|
58
|
+
|
59
|
+
center_body = 'Center body name:' space body_name space
|
60
|
+
'(' body_id >mark @center_body_id ')'
|
61
|
+
ws* '{' any* '}' '\n';
|
62
|
+
|
63
|
+
start_time = 'Start time' ' '* ':' ' ' datetime >mark %start_time space* '\n';
|
64
|
+
stop_time = 'Stop time' ' '* ':' ' ' datetime >mark %stop_time space* '\n';
|
65
|
+
step_size = 'Step-size' ' '* ':' ' ' (digit+ ' '* time_unit) >mark $step_size '\n';
|
66
|
+
|
67
|
+
ephemeris_columns = ('JDCT' (' ' | alpha | ',')*)
|
68
|
+
>mark @ephemeris_columns :> '\n';
|
69
|
+
|
70
|
+
soe = '$$SOE' '\n';
|
71
|
+
eoe = '$$EOE' '\n';
|
72
|
+
ephemeris_table = any*;
|
73
|
+
ephemeris = soe any* >mark %ephemeris_table :> eoe;
|
74
|
+
|
75
|
+
main := (
|
76
|
+
any*
|
77
|
+
target_body
|
78
|
+
center_body
|
79
|
+
any*
|
80
|
+
start_time
|
81
|
+
stop_time
|
82
|
+
step_size
|
83
|
+
any*
|
84
|
+
hr
|
85
|
+
ephemeris_columns
|
86
|
+
hr
|
87
|
+
ephemeris
|
88
|
+
any*
|
89
|
+
);
|
90
|
+
|
91
|
+
}%%
|
92
|
+
=end
|
93
|
+
|
94
|
+
require 'date'
|
95
|
+
module Tengai
|
96
|
+
class VectorEphemerisParser
|
97
|
+
def self.parse(data, ephemeris_table_parser=EphemerisTableParser)
|
98
|
+
data = data.unpack('c*') if data.is_a? String
|
99
|
+
eof = data.length
|
100
|
+
|
101
|
+
%% write init;
|
102
|
+
%% write exec;
|
103
|
+
|
104
|
+
{ target_body_id: target_body_id.to_i,
|
105
|
+
center_body_id: center_body_id.to_i,
|
106
|
+
start_time: DateTime.parse(start_time),
|
107
|
+
stop_time: DateTime.parse(stop_time),
|
108
|
+
step_size: step_size,
|
109
|
+
ephemeris_table: ephemeris_table_parser.parse(
|
110
|
+
"#{ephemeris_columns}\n#{ephemeris_table}") }
|
111
|
+
end
|
112
|
+
|
113
|
+
%% write data;
|
114
|
+
end
|
115
|
+
end
|
data/lib/tengai/body.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
$:.unshift File.dirname(File.dirname(File.dirname(__FILE__)))
|
2
|
+
require 'ext/horizons/body_data_sheet_parser'
|
3
|
+
require 'virtus'
|
4
|
+
|
5
|
+
module Tengai
|
6
|
+
class Body
|
7
|
+
include Virtus
|
8
|
+
attribute :revised_on, Date
|
9
|
+
attribute :name, String
|
10
|
+
attribute :id, Integer
|
11
|
+
|
12
|
+
def self.find(client, body, parser=BodyDataSheetParser)
|
13
|
+
data = client.cmd('String' => body.to_s, 'Match' => /<cr>:\s*$/)
|
14
|
+
data = parser.parse(data)
|
15
|
+
self.new(data)
|
16
|
+
end
|
17
|
+
|
18
|
+
def ==(other)
|
19
|
+
id == other.id
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'net/telnet'
|
2
|
+
|
3
|
+
module Tengai
|
4
|
+
class Client
|
5
|
+
HOST = 'horizons.jpl.nasa.gov'.freeze
|
6
|
+
PORT = '6775'.freeze
|
7
|
+
PROMPT = /Horizons>/.freeze
|
8
|
+
|
9
|
+
def initialize(telnet=Net::Telnet)
|
10
|
+
@telnet = telnet
|
11
|
+
connect!
|
12
|
+
end
|
13
|
+
|
14
|
+
def connect!
|
15
|
+
@connection = @telnet.new(
|
16
|
+
'Host' => HOST,
|
17
|
+
'Port' => PORT,
|
18
|
+
'Prompt' => PROMPT)
|
19
|
+
@connection.waitfor 'Match' => PROMPT
|
20
|
+
end
|
21
|
+
|
22
|
+
def disconnect
|
23
|
+
@connection.close
|
24
|
+
end
|
25
|
+
|
26
|
+
def connection
|
27
|
+
@connection
|
28
|
+
end
|
29
|
+
|
30
|
+
def cmd(*args, &blk)
|
31
|
+
connection.cmd(*args, &blk)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
$:.unshift File.dirname(File.dirname(__FILE__))
|
2
|
+
require 'tengai/requests/ephemeris_request'
|
3
|
+
require 'tengai/vector_ephemeris_table'
|
4
|
+
require 'virtus'
|
5
|
+
|
6
|
+
module Tengai
|
7
|
+
class Ephemeris
|
8
|
+
include Virtus
|
9
|
+
attribute :target_body_id, Integer
|
10
|
+
attribute :center_body_id, Integer
|
11
|
+
attribute :start_time, DateTime
|
12
|
+
attribute :stop_time, DateTime
|
13
|
+
attribute :step_size, Integer
|
14
|
+
attribute :ephemeris_table, VectorEphemerisTable
|
15
|
+
|
16
|
+
def initialize(client, data)
|
17
|
+
super(data)
|
18
|
+
@client = client
|
19
|
+
end
|
20
|
+
|
21
|
+
def target_body
|
22
|
+
@target_body ||= Tengai::Body.find(@client, target_body_id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def ephemeris_table=(table)
|
26
|
+
@ephemeris_table = VectorEphemerisTable.new_with_table(table)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Public: fetch an ephemeris table for a given body using the client
|
30
|
+
#
|
31
|
+
# client - Tengai::Client
|
32
|
+
# body - a Tengai::Body instance whose ephemeris is needed
|
33
|
+
# options - A Hash of options for refining the ephemeris table
|
34
|
+
# :start_time - The Time beginning of the ephemeris
|
35
|
+
# :stop_time - The Time end of the ephemeris
|
36
|
+
# :interval - The resolution of the table in minutes
|
37
|
+
def self.fetch(client, body, options={})
|
38
|
+
start_time = options[:start_time] || Date.today.to_time # defaults start at today
|
39
|
+
stop_time = options[:stop_time] || (Date.today + 1).to_time # and end tomorrow
|
40
|
+
interval = options[:interval] || 1440
|
41
|
+
|
42
|
+
# Inject dependencies
|
43
|
+
request = options[:request] || EphemerisRequest
|
44
|
+
parser = options[:parser] || VectorEphemerisParser
|
45
|
+
|
46
|
+
data = request.fetch(
|
47
|
+
client, body.id,
|
48
|
+
start_time: start_time,
|
49
|
+
stop_time: stop_time,
|
50
|
+
interval: interval)
|
51
|
+
data = parser.parse(data)
|
52
|
+
|
53
|
+
new(client, data)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module Tengai
|
4
|
+
class EphemerisTableParser
|
5
|
+
def self.parse(table)
|
6
|
+
empty_nils = ->(value) { value || '' }
|
7
|
+
strip = ->(value) { value.strip }
|
8
|
+
|
9
|
+
table = CSV.parse(
|
10
|
+
table,
|
11
|
+
headers: true,
|
12
|
+
header_converters: [empty_nils, strip, :symbol],
|
13
|
+
converters: [empty_nils, strip])
|
14
|
+
|
15
|
+
table.map do |row|
|
16
|
+
row.to_hash.tap {|r| r.delete(:'') }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module Tengai
|
2
|
+
class EphemerisRequest
|
3
|
+
SYSTEM_PROMPT = %r{Horizons>}.freeze
|
4
|
+
DEFAULT_PROMPT = %r{<cr>:\s*$}
|
5
|
+
TABLE_PROMPT = %r{Observe, Elements, Vectors \[o,e,v,\?\] :\s*$}.freeze
|
6
|
+
FIRST_OBSERVER_PROMPT = %r{Coordinate center \[ <id>,coord,geo \] :\s*$}.freeze
|
7
|
+
SUBSEQUENT_OBSERVER_PROMPT = %r{Use previous center \[ cr=\(y\), n, \? \] :\s*$}.freeze
|
8
|
+
OBSERVER_PROMPT = Regexp.union(FIRST_OBSERVER_PROMPT, SUBSEQUENT_OBSERVER_PROMPT).freeze
|
9
|
+
CONFIRM_OBSERVER_PROMPT = %r{Confirm selected station \[ y/n \] -->\s*$}.freeze
|
10
|
+
REFERNCE_PLANE_PROMPT = %r{Reference plane \[eclip, frame, body \] :\s*}.freeze
|
11
|
+
START_TIME_PROMPT = %r{Starting (C|U)T .* :\s*$}.freeze
|
12
|
+
END_TIME_PROMPT = %r{Ending \s* (C|U)T .* :\s*$}.freeze
|
13
|
+
INTERVAL_PROMPT = %r{Output interval \[ex: 10m, 1h, 1d, \? \] :\s*$}.freeze
|
14
|
+
ACCEPT_DEFAULT_OUTPUT_PROMPT = %r{Accept default output \[ cr=\(y\), n, \?\] :\s*$}.freeze
|
15
|
+
OUTPUT_REFERENCE_FRAME_PROMPT = %r{Output reference frame \[J2000, B1950\] :\s*$}.freeze
|
16
|
+
CORRECTIONS_PROMPT = %r{Corrections \[ 1=NONE, 2=LT, 3=LT\+S \] :\s*$}.freeze
|
17
|
+
OUTPUT_UNITS = %r{Output units \[1=KM-S, 2=AU-D, 3=KM-D\] :\s*$}.freeze
|
18
|
+
CSV_FORMAT_PROMPT = %r{Spreadsheet CSV format \[ YES, NO \] :\s*$}.freeze
|
19
|
+
LABEL_CARTESIAN_OUTPUT_PROMPT = %r{Label cartesian output \[ YES, NO \] :\s*$}.freeze
|
20
|
+
SELECT_OUTPUT_TABLE_TYPE_PROMPT = %r{Select output table type \[ 1-6, \? \] :\s*$}.freeze
|
21
|
+
SELECT_QUANTITIES_PROMPT = %r{Select table quantities \[ <#,#\.\.>, \?\] :\s*$}.freeze
|
22
|
+
COMPLETED_PROMPT = %r{>>> Select\.\.\. \[A\]gain, \[N\]ew-case, \[F\]tp, \[K\]ermit, \[M\]ail, \[R\]edisplay, \? :\s*$}.freeze
|
23
|
+
|
24
|
+
ANY_PROMPT = Regexp.union(
|
25
|
+
DEFAULT_PROMPT, TABLE_PROMPT, OBSERVER_PROMPT, CONFIRM_OBSERVER_PROMPT,
|
26
|
+
REFERNCE_PLANE_PROMPT, START_TIME_PROMPT, END_TIME_PROMPT, INTERVAL_PROMPT,
|
27
|
+
ACCEPT_DEFAULT_OUTPUT_PROMPT, SELECT_QUANTITIES_PROMPT, COMPLETED_PROMPT,
|
28
|
+
OUTPUT_REFERENCE_FRAME_PROMPT, CORRECTIONS_PROMPT, OUTPUT_UNITS,
|
29
|
+
CSV_FORMAT_PROMPT, LABEL_CARTESIAN_OUTPUT_PROMPT,
|
30
|
+
SELECT_OUTPUT_TABLE_TYPE_PROMPT, SYSTEM_PROMPT).freeze
|
31
|
+
|
32
|
+
TIME_FORMAT = '%Y-%b-%d %H:%M'.freeze
|
33
|
+
|
34
|
+
def initialize(client, body, options={})
|
35
|
+
@client = client
|
36
|
+
@body = body.to_s
|
37
|
+
@start_time = options[:start_time]
|
38
|
+
@stop_time = options[:stop_time]
|
39
|
+
@interval = options[:interval] || 1440
|
40
|
+
@options = options
|
41
|
+
@state = :ready
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.fetch(client, body, options={})
|
45
|
+
new(client, body, options).fetch
|
46
|
+
end
|
47
|
+
|
48
|
+
# Public: initiates the ephemeris request
|
49
|
+
#
|
50
|
+
# Examples:
|
51
|
+
#
|
52
|
+
# Tengai::EphemerisRequest.new(Tengai::Client.new, 499).fetch
|
53
|
+
# # => #<Tengai::EphemerisRequest @data=""B\n \r\n Working ... \b\b- \r\n\e[?1h\e=\r*...">
|
54
|
+
#
|
55
|
+
# Returns the the request (self)
|
56
|
+
def fetch
|
57
|
+
raise "Not ready" unless @state == :ready
|
58
|
+
@state = :fetching
|
59
|
+
send_command(@body)
|
60
|
+
@data
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
def table
|
65
|
+
case @options[:table]
|
66
|
+
when :observer then 'o'
|
67
|
+
when :vector then 'v'
|
68
|
+
when :orbital_elements then 'e'
|
69
|
+
else 'v'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def observer
|
74
|
+
@options[:observer] || '500@0'
|
75
|
+
end
|
76
|
+
|
77
|
+
def send_command(command, prompt=ANY_PROMPT)
|
78
|
+
Tengai.log "> #{command}"
|
79
|
+
result = @client.cmd('String' => command, 'Match' => prompt) do |data|
|
80
|
+
Tengai.log '< ' + data
|
81
|
+
end
|
82
|
+
receive_data(result)
|
83
|
+
end
|
84
|
+
|
85
|
+
def receive_data(data)
|
86
|
+
case data
|
87
|
+
when DEFAULT_PROMPT
|
88
|
+
send_command 'E'
|
89
|
+
when TABLE_PROMPT
|
90
|
+
send_command table
|
91
|
+
when FIRST_OBSERVER_PROMPT
|
92
|
+
send_command observer
|
93
|
+
when SUBSEQUENT_OBSERVER_PROMPT
|
94
|
+
send_command 'n'
|
95
|
+
when CONFIRM_OBSERVER_PROMPT
|
96
|
+
send_command 'y'
|
97
|
+
when REFERNCE_PLANE_PROMPT
|
98
|
+
send_command 'frame'
|
99
|
+
when START_TIME_PROMPT
|
100
|
+
send_command @start_time.strftime(TIME_FORMAT)
|
101
|
+
when END_TIME_PROMPT
|
102
|
+
send_command @stop_time.strftime(TIME_FORMAT)
|
103
|
+
when INTERVAL_PROMPT
|
104
|
+
send_command @interval.to_s + 'm'
|
105
|
+
when ACCEPT_DEFAULT_OUTPUT_PROMPT
|
106
|
+
send_command 'n'
|
107
|
+
when OUTPUT_REFERENCE_FRAME_PROMPT
|
108
|
+
send_command 'J2000'
|
109
|
+
when CORRECTIONS_PROMPT
|
110
|
+
send_command '1'
|
111
|
+
when OUTPUT_UNITS
|
112
|
+
send_command '2'
|
113
|
+
when CSV_FORMAT_PROMPT
|
114
|
+
send_command 'YES'
|
115
|
+
when LABEL_CARTESIAN_OUTPUT_PROMPT
|
116
|
+
send_command 'YES'
|
117
|
+
when SELECT_OUTPUT_TABLE_TYPE_PROMPT
|
118
|
+
send_command '03'
|
119
|
+
when SELECT_QUANTITIES_PROMPT
|
120
|
+
send_command 'B'
|
121
|
+
when COMPLETED_PROMPT
|
122
|
+
@data = data
|
123
|
+
send_command 'N'
|
124
|
+
when Client::PROMPT
|
125
|
+
@state = :ready
|
126
|
+
else
|
127
|
+
puts "Unexpected data: #{data}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'virtus'
|
3
|
+
|
4
|
+
class VectorEphemerisTable
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
def initialize(rows)
|
8
|
+
@rows = rows
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.new_with_table(rows)
|
12
|
+
new(rows.map(&Row.method(:new)))
|
13
|
+
end
|
14
|
+
|
15
|
+
def each(&block)
|
16
|
+
@rows.each(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
class Row
|
20
|
+
include Virtus
|
21
|
+
attribute :jdct, DateTime
|
22
|
+
attribute :x, Float
|
23
|
+
attribute :y, Float
|
24
|
+
attribute :z, Float
|
25
|
+
attribute :vx, Float
|
26
|
+
attribute :vy, Float
|
27
|
+
attribute :vz, Float
|
28
|
+
attribute :lt, Float
|
29
|
+
attribute :rg, Float
|
30
|
+
attribute :rr, Float
|
31
|
+
|
32
|
+
def jdct=(julian)
|
33
|
+
super DateTime.jd(julian.to_f)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/tengai.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
$:.unshift File.join(File.dirname(File.dirname(__FILE__)), 'ext')
|
3
|
+
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
require 'tengai/version'
|
7
|
+
require 'tengai/client'
|
8
|
+
require 'tengai/body'
|
9
|
+
require 'tengai/ephemeris'
|
10
|
+
|
11
|
+
require 'horizons/vector_ephemeris_parser'
|
12
|
+
require 'tengai/parsers/ephemeris_table_parser'
|
13
|
+
|
14
|
+
module Tengai
|
15
|
+
class << self
|
16
|
+
attr_accessor :debug
|
17
|
+
attr_reader :logger
|
18
|
+
|
19
|
+
def log(message)
|
20
|
+
logger.debug { message } if debug
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
@logger ||= ::Logger.new(STDOUT)
|
25
|
+
|
26
|
+
self.debug = false
|
27
|
+
end
|
data/tengai.gemspec
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
$LOAD_PATH.unshift 'lib'
|
2
|
+
$LOAD_PATH.unshift 'ext'
|
3
|
+
require 'tengai/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'tengai'
|
7
|
+
s.version = Tengai::VERSION.dup
|
8
|
+
s.summary = 'Ruby wrapper for the NASA HORIZONS telnet system'
|
9
|
+
s.description = 'Ruby wrapper for the NASA HORIZONS telnet system'
|
10
|
+
s.homepage = 'http://github.com/zacstewart/tengai'
|
11
|
+
s.authors = ['Zac Stewart']
|
12
|
+
s.email = ['zgstewart@gmail.com']
|
13
|
+
|
14
|
+
s.require_paths = ['lib']
|
15
|
+
|
16
|
+
s.add_dependency 'virtus'
|
17
|
+
|
18
|
+
s.add_development_dependency 'pry'
|
19
|
+
s.add_development_dependency 'rake'
|
20
|
+
s.add_development_dependency 'mocha'
|
21
|
+
s.add_development_dependency 'simplecov'
|
22
|
+
s.add_development_dependency 'forgery'
|
23
|
+
|
24
|
+
s.files = %w(
|
25
|
+
.gitignore
|
26
|
+
.ruby-gemset
|
27
|
+
.ruby-version
|
28
|
+
.travis.yml
|
29
|
+
Gemfile
|
30
|
+
README.md
|
31
|
+
Rakefile
|
32
|
+
ext/horizons/body_data_sheet_parser.rb
|
33
|
+
ext/horizons/body_data_sheet_parser.rl
|
34
|
+
ext/horizons/vector_ephemeris_parser.rb
|
35
|
+
ext/horizons/vector_ephemeris_parser.rl
|
36
|
+
lib/tengai.rb
|
37
|
+
lib/tengai/body.rb
|
38
|
+
lib/tengai/client.rb
|
39
|
+
lib/tengai/ephemeris.rb
|
40
|
+
lib/tengai/parsers/ephemeris_table_parser.rb
|
41
|
+
lib/tengai/requests/ephemeris_request.rb
|
42
|
+
lib/tengai/vector_ephemeris_table.rb
|
43
|
+
lib/tengai/version.rb
|
44
|
+
tengai.gemspec
|
45
|
+
test/fixtures.rb
|
46
|
+
test/fixtures/bodies/10.txt
|
47
|
+
test/fixtures/bodies/399.txt
|
48
|
+
test/fixtures/bodies/499.txt
|
49
|
+
test/fixtures/bodies/501.txt
|
50
|
+
test/fixtures/ephemerides/mars_observed_by_earth_from_2012_12_28_to_29.txt
|
51
|
+
test/fixtures/ephemerides/mars_vectors_from_solar_system_center.txt
|
52
|
+
test/fixtures/major_bodies.txt
|
53
|
+
test/integration/body_integration_test.rb
|
54
|
+
test/integration/ephemeris_integration_test.rb
|
55
|
+
test/test_helper.rb
|
56
|
+
test/unit/body_data_sheet_parser_test.rb
|
57
|
+
test/unit/body_test.rb
|
58
|
+
test/unit/ephemeris_table_parser_test.rb
|
59
|
+
test/unit/ephemeris_test.rb
|
60
|
+
test/unit/vector_ephemeris_parser_test.rb
|
61
|
+
test/unit/vector_ephemeris_table_test.rb
|
62
|
+
)
|
63
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
*******************************************************************************
|
2
|
+
Revised : Sep 12, 1996 Sun 10
|
3
|
+
Physical: May 29, 2012
|
4
|
+
|
5
|
+
PHYSICAL PROPERTIES:
|
6
|
+
GM (10^11 km^3/s^2) = 1.32712440018 Mass (10^30 kg) = 1.9891
|
7
|
+
Radius (photosphere) = 6.963(10^5) km Angular diam at 1 AU = 1919.3"
|
8
|
+
Solar Radius (IAU) = 6.955(10^5) km Mean density = 1.408 g/cm^3
|
9
|
+
Surface gravity = 274.0 m/s^2 Moment of inertia = 0.059
|
10
|
+
Escape velocity = 617.7 km/s Adopted sidereal per = 25.38 d
|
11
|
+
Pole (RA,DEC in deg.) = 286.13,63.87 Obliquity to ecliptic = 7 deg 15'
|
12
|
+
Solar constant (1 AU) = 1367.6 W/m^2 Solar lumin.(erg/s) = 3.846(10^33)
|
13
|
+
Mass-energy conv rate = 4.3(10^12 gm/s) Effective temp (K) = 5778
|
14
|
+
Surf. temp (photosphr)= 6600 K (bottom) Surf. temp (photosphr)= 4400 K (top)
|
15
|
+
Photospheric depth = ~400 km Chromospheric depth = ~2500 km
|
16
|
+
Sunspot cycle = 11.4 yr Cycle 22 sunspot min. = 1991 A.D.
|
17
|
+
|
18
|
+
Motn. rel to nrby strs= apex : RA=271 deg; DEC=+30 deg
|
19
|
+
speed: 19.4 km/s = 0.0112 AU/day
|
20
|
+
Motn. rel to 2.73K BB = apex : l=264.7+-0.8; b=48.2+-0.5
|
21
|
+
speed: 369 +-11 km/s
|
22
|
+
*******************************************************************************
|
23
|
+
Select ... [E]phemeris, [F]tp, [M]ail, [R]edisplay, ?, <cr>:
|
@@ -0,0 +1,29 @@
|
|
1
|
+
*******************************************************************************
|
2
|
+
Revised: Apr 03, 2003 Earth 399
|
3
|
+
|
4
|
+
PHYSICAL PROPERTIES:
|
5
|
+
Mean radius, km = 6371.01+-0.02 Mass, 10^24 kg = 5.9736
|
6
|
+
Equ. radius, km = 6378.136 Mass layers:
|
7
|
+
Polar axis, km = 6356.752 Atmos = 5.1 x 10^18 kg
|
8
|
+
Flattening = 1/298.257 oceans = 1.4 x 10^21 kg
|
9
|
+
Density, gm cm^-3 = 5.515 crust = 2.6 x 10^22 kg
|
10
|
+
J2 (GEM T2, 1990) = 0.0010826265 mantle = 4.043 x 10^24 kg
|
11
|
+
gp, m s^-2 (polar) = 9.8321863685 outer core = 1.835 x 10^24 kg
|
12
|
+
ge, m s^-2 (equatorial) = 9.7803267715 inner core = 9.675 x 10^22 kg
|
13
|
+
go, m s^-2 = 9.82022 Fluid core rad = 3480 km
|
14
|
+
GM, km^3 s^-2 = 398600.440 Inner core rad = 1215 km
|
15
|
+
Mean rot. rate, rad s^-1 = 7.292115*10^-5 Surface Area:
|
16
|
+
Sidereal period, hr = 23.93419 land = 1.48 x 10^8 km
|
17
|
+
Mean solar day, days = 1.002738 sea = 3.62 x 10^8 km
|
18
|
+
Moment of inertia = 0.3308 Love no., k2 = 0.299
|
19
|
+
Mean Temperature, K = 270 Atm. pressure = 1.0 bar
|
20
|
+
Solar constant, W/m^2 = 1367.6 Vis. mag. V(1,0) = -3.86
|
21
|
+
Volume, 10^10 km^3 = 108.321 Geometric albedo = 0.367
|
22
|
+
|
23
|
+
DYNAMICAL CHARACTERISTICS:
|
24
|
+
Obliquity to orbit, deg = 23.45 Sidereal period = 1.0000174 yrs
|
25
|
+
Orbit velocity, km s^-1 = 29.7859 Sidereal period = 365.25636 days
|
26
|
+
Mean daily motion, n = 0.9856474 deg/d Escape velocity = 11.186 km s^-2
|
27
|
+
Hill's sphere radius = 234.9 Magnetic moment = 0.61 gauss Rp^3
|
28
|
+
*******************************************************************************
|
29
|
+
Select ... [E]phemeris, [F]tp, [M]ail, [R]edisplay, ?, <cr>:
|
@@ -0,0 +1,25 @@
|
|
1
|
+
*******************************************************************************
|
2
|
+
Revised: Sep 28, 2012 Mars 499 / 4
|
3
|
+
|
4
|
+
GEOPHYSICAL DATA (updated 2009-May-26):
|
5
|
+
Mean radius (km) = 3389.9(2+-4) Density (g cm^-3) = 3.933(5+-4)
|
6
|
+
Mass (10^23 kg ) = 6.4185 Flattening, f = 1/154.409
|
7
|
+
Volume (x10^10 km^3) = 16.318 Semi-major axis = 3397+-4
|
8
|
+
Sidereal rot. period = 24.622962 hr Rot. Rate (x10^5 s) = 7.088218
|
9
|
+
Mean solar day = 1.0274907 d Polar gravity ms^-2 = 3.758
|
10
|
+
Mom. of Inertia = 0.366 Equ. gravity ms^-2 = 3.71
|
11
|
+
Core radius (km) = ~1700 Potential Love # k2 = 0.153 +-.017
|
12
|
+
|
13
|
+
Grav spectral fact u = 14 (x10^5) Topo. spectral fact t = 96 (x10^5)
|
14
|
+
Fig. offset (Rcf-Rcm) = 2.50+-0.07 km Offset (lat./long.) = 62d / 88d
|
15
|
+
GM (km^3 s^-2) = 42828.3 Equatorial Radius, Re = 3394.0 km
|
16
|
+
GM 1-sigma (km^3 s^-2)= +- 0.1 Mass ratio (Sun/Mars) = 3098708+-9
|
17
|
+
|
18
|
+
Atmos. pressure (bar) = 0.0056 Max. angular diam. = 17.9"
|
19
|
+
Mean Temperature (K) = 210 Visual mag. V(1,0) = -1.52
|
20
|
+
Geometric albedo = 0.150 Obliquity to orbit = 25.19 deg
|
21
|
+
Mean sidereal orb per = 1.88081578 y Orbit vel. km/s = 24.1309
|
22
|
+
Mean sidereal orb per = 686.98 d Escape vel. km/s = 5.027
|
23
|
+
Hill's sphere rad. Rp = 319.8 Mag. mom (gauss Rp^3) = < 1x10^-4
|
24
|
+
*******************************************************************************
|
25
|
+
Select ... [E]phemeris, [F]tp, [M]ail, [R]edisplay, ?, <cr>:
|
@@ -0,0 +1,13 @@
|
|
1
|
+
*******************************************************************************
|
2
|
+
Revised: Jan 08, 2004 Io / (Jupiter) 501
|
3
|
+
|
4
|
+
SATELLITE PHYSICAL PROPERTIES:
|
5
|
+
Radius (km) = 1821.3 +- 0.2 Density (g cm^-3) = 3.530 +-.006
|
6
|
+
Mass (10^20 kg ) = 893.3 +- 1.5 Geometric Albedo = 0.6
|
7
|
+
|
8
|
+
SATELLITE ORBITAL DATA:
|
9
|
+
Semi-major axis, a (km) = 421.769 (10^3) Orbital period = 1.769138 d
|
10
|
+
Eccentricity, e = 0.0041 Rotational period = Synchronous
|
11
|
+
Inclination, i (deg) = 0.036
|
12
|
+
*******************************************************************************
|
13
|
+
Select ... [E]phemeris, [F]tp, [M]ail, [R]edisplay, ?, <cr>:
|