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