korba 0.5.0 → 0.6.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/korba/sgp4/elset_rec.rb +432 -0
- data/lib/korba/sgp4/sgp4.rb +2027 -0
- data/lib/korba/tle.rb +83 -5
- data/lib/korba/version.rb +1 -1
- data/lib/korba.rb +2 -0
- metadata +4 -2
data/lib/korba/tle.rb
CHANGED
@@ -5,7 +5,10 @@ module Korba
|
|
5
5
|
class Tle
|
6
6
|
include OrbitUtils
|
7
7
|
|
8
|
-
attr_reader :tle_json, :tle_string, :
|
8
|
+
attr_reader :tle_json, :tle_string, :object_id, :object_name, :epoch_datetime, :julian_date,
|
9
|
+
:satellite_number, :classification_type, :epoch, :mean_motion_dot, :mean_motion_ddot, :bstar, :element_set_no,
|
10
|
+
:inclination, :ra_of_asc_node, :eccentricity, :arg_of_pericenter, :mean_anomaly, :mean_motion, :revolution_number,
|
11
|
+
:element_set_record, :epoch_days
|
9
12
|
|
10
13
|
def initialize(tle = nil, type: :string)
|
11
14
|
return if tle.nil?
|
@@ -16,6 +19,8 @@ module Korba
|
|
16
19
|
when :json
|
17
20
|
initialize_from_json(tle)
|
18
21
|
end
|
22
|
+
set_epoch_datetime_and_julian_date
|
23
|
+
set_element_set_record_values
|
19
24
|
end
|
20
25
|
|
21
26
|
def to_kep
|
@@ -34,6 +39,18 @@ module Korba
|
|
34
39
|
kep.to_car
|
35
40
|
end
|
36
41
|
|
42
|
+
def propagate_to(minutesAfterEpoch)
|
43
|
+
r = [0, 0, 0]
|
44
|
+
v = [0, 0, 0]
|
45
|
+
|
46
|
+
@element_set_record.error = 0
|
47
|
+
SGP4.sgp4(@element_set_record, minutesAfterEpoch, r, v)
|
48
|
+
@sgp4Error = @element_set_record.error
|
49
|
+
r = r.map { _1 * 1000 }
|
50
|
+
v = v.map { _1 * 1000 }
|
51
|
+
Car.new(object_name:, epoch:, x: r[0], y: r[1], z: r[2], vx: v[0], vy: v[1], vz: v[2])
|
52
|
+
end
|
53
|
+
|
37
54
|
private
|
38
55
|
|
39
56
|
def initialize_from_string(tle_string)
|
@@ -46,12 +63,31 @@ module Korba
|
|
46
63
|
|
47
64
|
def parse_line1(line1_strings)
|
48
65
|
# TODO: object_id
|
66
|
+
@satellite_number = line1_strings[1][0..4].to_i
|
67
|
+
@classification_type = line1_strings[1][-1]
|
49
68
|
# For now, only supports years after 2000
|
50
69
|
epoch_year = line1_strings[3][0..1].to_i + 2000
|
51
|
-
|
52
|
-
# Subtract 1 from
|
53
|
-
epoch_time = Time.new(epoch_year, 1, 1, 0, 0, 0, "+00:00") + (
|
70
|
+
@epoch_days = line1_strings[3][2..].to_f
|
71
|
+
# Subtract 1 from epoch_days because January 1st is considered day 1
|
72
|
+
epoch_time = Time.new(epoch_year, 1, 1, 0, 0, 0, "+00:00") + (epoch_days - 1) * 24 * 60 * 60
|
54
73
|
@epoch = epoch_time.strftime("%Y-%m-%dT%H:%M:%S.%6N")
|
74
|
+
|
75
|
+
mean_motion_dot_sign = line1_strings[4][0] == "-" ? -1 : 1
|
76
|
+
mean_motion_dot_value_start = line1_strings[4].size == 10 ? 1 : 0
|
77
|
+
@mean_motion_dot = mean_motion_dot_sign * "0#{line1_strings[4][mean_motion_dot_value_start..]}".to_f
|
78
|
+
|
79
|
+
mean_motion_ddot_sign = line1_strings[5][0] == "-" ? -1 : 1
|
80
|
+
mean_motion_ddot_value_start = line1_strings[5].size == 8 ? 1 : 0
|
81
|
+
mean_motion_ddot_exponent = line1_strings[5][mean_motion_ddot_value_start + 5..mean_motion_ddot_value_start + 6].to_i
|
82
|
+
@mean_motion_ddot =
|
83
|
+
mean_motion_ddot_sign * "0.#{line1_strings[5][mean_motion_ddot_value_start..mean_motion_ddot_value_start + 4]}".to_f * 10 ** mean_motion_ddot_exponent
|
84
|
+
|
85
|
+
bstar_sign = line1_strings[6][0] == "-" ? -1 : 1
|
86
|
+
bstar_value_start = line1_strings[6].size == 8 ? 1 : 0
|
87
|
+
bstar_exponent = line1_strings[6][bstar_value_start + 5..bstar_value_start + 6].to_i
|
88
|
+
@bstar = bstar_sign * "0.#{line1_strings[6][bstar_value_start..bstar_value_start + 4]}".to_f * 10 ** bstar_exponent
|
89
|
+
|
90
|
+
@element_set_no = line1_strings[8][0..2].to_i
|
55
91
|
end
|
56
92
|
|
57
93
|
def parse_line2(line2_strings)
|
@@ -60,20 +96,62 @@ module Korba
|
|
60
96
|
@eccentricity = "0.#{line2_strings[4]}".to_f
|
61
97
|
@arg_of_pericenter = line2_strings[5].to_f
|
62
98
|
@mean_anomaly = line2_strings[6].to_f
|
63
|
-
@mean_motion = line2_strings[7].to_f
|
99
|
+
@mean_motion = line2_strings[7][0..10].to_f
|
100
|
+
@revolution_number = line2_strings[7][11..15].to_i
|
64
101
|
end
|
65
102
|
|
66
103
|
def initialize_from_json(tle_json)
|
67
104
|
@tle_json = tle_json
|
68
105
|
@object_name = tle_json[:OBJECT_NAME]
|
69
106
|
@object_id = tle_json[:OBJECT_ID]
|
107
|
+
@satellite_number = tle_json[:NORAD_CAT_ID]
|
108
|
+
@classification_type = tle_json[:CLASSIFICATION_TYPE]
|
70
109
|
@epoch = tle_json[:EPOCH]
|
110
|
+
@mean_motion_dot = tle_json[:MEAN_MOTION_DOT]
|
111
|
+
@mean_motion_ddot = tle_json[:MEAN_MOTION_DDOT]
|
112
|
+
@bstar = tle_json[:BSTAR]
|
113
|
+
@element_set_no = tle_json[:ELEMENT_SET_NO]
|
71
114
|
@mean_motion = tle_json[:MEAN_MOTION]
|
72
115
|
@eccentricity = tle_json[:ECCENTRICITY]
|
73
116
|
@inclination = tle_json[:INCLINATION]
|
74
117
|
@ra_of_asc_node = tle_json[:RA_OF_ASC_NODE]
|
75
118
|
@arg_of_pericenter = tle_json[:ARG_OF_PERICENTER]
|
76
119
|
@mean_anomaly = tle_json[:MEAN_ANOMALY]
|
120
|
+
@revolution_number = tle_json[:REV_AT_EPOCH]
|
121
|
+
end
|
122
|
+
|
123
|
+
def set_epoch_datetime_and_julian_date
|
124
|
+
@epoch_datetime = Time.new(@epoch + " UTC")
|
125
|
+
@julian_date = SGP4.jday(
|
126
|
+
epoch_datetime.year, epoch_datetime.mon, epoch_datetime.day, epoch_datetime.hour, epoch_datetime.min, epoch_datetime.sec
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
def set_element_set_record_values
|
131
|
+
@element_set_record = ElsetRec.new
|
132
|
+
@element_set_record.whichconst = 3 # wgs84
|
133
|
+
@element_set_record.epochyr = epoch_datetime.year
|
134
|
+
@element_set_record.epochdays = epoch_days
|
135
|
+
@element_set_record.jdsatepoch = julian_date[0]
|
136
|
+
@element_set_record.jdsatepochF = julian_date[1]
|
137
|
+
|
138
|
+
@element_set_record.classification = classification_type
|
139
|
+
@element_set_record.elnum = element_set_no
|
140
|
+
@element_set_record.revnum = revolution_number
|
141
|
+
@element_set_record.satnum = satellite_number
|
142
|
+
@element_set_record.bstar = bstar
|
143
|
+
@element_set_record.inclo = deg_to_rad(inclination)
|
144
|
+
@element_set_record.nodeo = deg_to_rad(ra_of_asc_node)
|
145
|
+
@element_set_record.argpo = deg_to_rad(arg_of_pericenter)
|
146
|
+
@element_set_record.mo = deg_to_rad(mean_anomaly)
|
147
|
+
@element_set_record.ecco = eccentricity
|
148
|
+
|
149
|
+
xpdotp = 1440.0 / (2.0 * Math::PI)
|
150
|
+
@element_set_record.no_kozai = mean_motion / xpdotp
|
151
|
+
@element_set_record.ndot = mean_motion_dot / (xpdotp * 1440.0)
|
152
|
+
@element_set_record.nddot = mean_motion_ddot / (xpdotp * 1440.0 * 1440.0)
|
153
|
+
# update element_set_record
|
154
|
+
SGP4.sgp4init("a", @element_set_record)
|
77
155
|
end
|
78
156
|
end
|
79
157
|
end
|
data/lib/korba/version.rb
CHANGED
data/lib/korba.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: korba
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kk0000-kk
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
11
|
+
date: 2024-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Orbital elements calculation library
|
14
14
|
email:
|
@@ -28,6 +28,8 @@ files:
|
|
28
28
|
- lib/korba/kepler_equation_fucntion.rb
|
29
29
|
- lib/korba/newton_function.rb
|
30
30
|
- lib/korba/orbit_utils.rb
|
31
|
+
- lib/korba/sgp4/elset_rec.rb
|
32
|
+
- lib/korba/sgp4/sgp4.rb
|
31
33
|
- lib/korba/tle.rb
|
32
34
|
- lib/korba/version.rb
|
33
35
|
- sig/korba.rbs
|