tengai 0.0.1
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/.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>:
|