korba 0.6.0 → 0.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +2 -0
- data/lib/korba/kep.rb +17 -7
- data/lib/korba/keplers_equation.rb +46 -0
- data/lib/korba/orbit_utils.rb +16 -12
- data/lib/korba/tle.rb +4 -5
- data/lib/korba/version.rb +1 -1
- data/lib/korba.rb +1 -1
- data/mise.toml +2 -0
- metadata +5 -8
- data/lib/korba/kepler_equation_fucntion.rb +0 -20
- data/lib/korba/newton_function.rb +0 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d032139625c6722891cef771fc76ffb90e8b082f89146ebb860a5f8034004b15
|
|
4
|
+
data.tar.gz: 354e2f0f7c382059bf7a424ffd952c32b56b6ae616b5c7bd42f50a148d2f42c3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6f73a3a19efff8c89299173d67dbfa1aaf754ce1c0828148f7bd3933cd57d8de8ba74352cc12849fcd405882c964f345353e1f6d4204b4e451d00a8a6ebf5337
|
|
7
|
+
data.tar.gz: 293456b12a49007bb1f1c1acc6201fcf99678e5427b1c81942d9f1e53ab5c9cc8716ffdeaaa562846c45ef2b245400f7d73758a05494da91df1528da9e06cba0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## [0.7.1] - 2026-04-05
|
|
2
|
+
|
|
3
|
+
- FIX: Fixed calculation when orbital inclination and eccentricity are 0
|
|
4
|
+
|
|
5
|
+
## [0.7.0] - 2026-04-01
|
|
6
|
+
|
|
7
|
+
- FIX: Use SGP4 for TLE to Cartesian conversion
|
|
8
|
+
- FIX: Remove Newton's method library and implement Kepler equation processing
|
|
9
|
+
|
|
1
10
|
## [0.6.0] - 2024-12-27
|
|
2
11
|
|
|
3
12
|
- Enable use SGP4
|
data/README.md
CHANGED
data/lib/korba/kep.rb
CHANGED
|
@@ -19,13 +19,23 @@ module Korba
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def to_car
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
# 特異点対応: inclinationが0(または極めて小さい)場合の処理
|
|
23
|
+
is_equatorial = inclination.abs < 1e-10
|
|
24
|
+
|
|
25
|
+
if is_equatorial
|
|
26
|
+
# 赤道面内の場合、x軸を基準にする
|
|
27
|
+
vector_omega = Vector[1.0, 0.0, 0.0]
|
|
28
|
+
vector_m = Vector[0.0, 1.0, 0.0]
|
|
29
|
+
vector_n = Vector[0.0, 0.0, 1.0]
|
|
30
|
+
else
|
|
31
|
+
vector_n = Vector[
|
|
32
|
+
Math.sin(deg_to_rad(inclination)) * Math.sin(deg_to_rad(ra_of_asc_node)),
|
|
33
|
+
-Math.sin(deg_to_rad(inclination)) * Math.cos(deg_to_rad(ra_of_asc_node)),
|
|
34
|
+
Math.cos(deg_to_rad(inclination))
|
|
35
|
+
]
|
|
36
|
+
vector_omega = Vector[Math.cos(deg_to_rad(ra_of_asc_node)), Math.sin(deg_to_rad(ra_of_asc_node)), 0.0]
|
|
37
|
+
vector_m = vector_n.cross(vector_omega)
|
|
38
|
+
end
|
|
29
39
|
|
|
30
40
|
r_angle_factor = deg_to_rad(arg_of_pericenter + true_anomaly)
|
|
31
41
|
vector_r = distance * (Math.cos(r_angle_factor) * vector_omega + Math.sin(r_angle_factor) * vector_m)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Korba
|
|
4
|
+
class KeplersEquation
|
|
5
|
+
include OrbitUtils
|
|
6
|
+
|
|
7
|
+
attr_reader :eccentricity, :mean_anomaly
|
|
8
|
+
|
|
9
|
+
def initialize(eccentricity:, mean_anomaly:)
|
|
10
|
+
super()
|
|
11
|
+
@eccentricity = eccentricity
|
|
12
|
+
@mean_anomaly = mean_anomaly
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
MAX_ITERATIONS = 1000
|
|
16
|
+
def solve(tolerance = 1e-10)
|
|
17
|
+
m_rad = deg_to_rad(mean_anomaly)
|
|
18
|
+
|
|
19
|
+
if eccentricity < 0.8
|
|
20
|
+
en = m_rad
|
|
21
|
+
else
|
|
22
|
+
en = Math::PI
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
MAX_ITERATIONS.times do
|
|
26
|
+
# f(E) = E - e*sin(E) - M
|
|
27
|
+
# f'(E) = 1 - e*cos(E)
|
|
28
|
+
|
|
29
|
+
sin_en = Math.sin(en.to_f)
|
|
30
|
+
cos_en = Math.cos(en.to_f)
|
|
31
|
+
|
|
32
|
+
f = en - eccentricity * sin_en - m_rad
|
|
33
|
+
f_dot = 1 - eccentricity * cos_en
|
|
34
|
+
|
|
35
|
+
# 更新
|
|
36
|
+
delta = f / f_dot
|
|
37
|
+
en = en - delta
|
|
38
|
+
|
|
39
|
+
# 収束判定
|
|
40
|
+
break if delta.abs < tolerance
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
en
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/korba/orbit_utils.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Korba
|
|
|
4
4
|
module OrbitUtils
|
|
5
5
|
def semi_major_axis
|
|
6
6
|
# a = (μ / n^2)^(1/3) m
|
|
7
|
-
(Constant::GME / (mean_motion * 2 * Math::PI / 86400.0) ** 2.0) ** (1.0 / 3.0)
|
|
7
|
+
(Constant::GME / (mean_motion * 2.0 * Math::PI / 86400.0) ** 2.0) ** (1.0 / 3.0)
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def height_at_perigee
|
|
@@ -16,15 +16,17 @@ module Korba
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def eccentric_anomaly
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
nlsolve(f, x)
|
|
22
|
-
rad_to_deg(x[0])
|
|
19
|
+
kepler = KeplersEquation.new(eccentricity:, mean_anomaly:)
|
|
20
|
+
rad_to_deg(kepler.solve)
|
|
23
21
|
end
|
|
24
22
|
|
|
25
23
|
def true_anomaly
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
e_rad = deg_to_rad(eccentric_anomaly)
|
|
25
|
+
y = Math.sqrt(1 - eccentricity ** 2) * Math.sin(e_rad)
|
|
26
|
+
x = Math.cos(e_rad) - eccentricity
|
|
27
|
+
|
|
28
|
+
# atan2(y, x) で正確な位相(-pi から pi)を求める
|
|
29
|
+
rad_to_deg(Math.atan2(y, x))
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
def distance
|
|
@@ -32,10 +34,12 @@ module Korba
|
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def velocity
|
|
35
|
-
Math.sqrt(Constant::GME * (2 / distance - 1 / semi_major_axis))
|
|
37
|
+
Math.sqrt(Constant::GME * (2.0 / distance - 1.0 / semi_major_axis))
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
def path_angle
|
|
41
|
+
return 0.0 if eccentricity < 1e-15
|
|
42
|
+
|
|
39
43
|
factor = Math.sqrt(Constant::GME * semi_major_axis * (1 - eccentricity ** 2)) / (distance * velocity)
|
|
40
44
|
rad_to_deg(Math.acos(factor))
|
|
41
45
|
end
|
|
@@ -46,8 +50,8 @@ module Korba
|
|
|
46
50
|
end
|
|
47
51
|
|
|
48
52
|
def normalize_rad(rad)
|
|
49
|
-
rad = rad + 2 * Math::PI if rad < 0
|
|
50
|
-
normalize_rad = rad > 2 * Math::PI ? rad - 2 * Math::PI : rad
|
|
53
|
+
rad = rad + 2.0 * Math::PI if rad < 0
|
|
54
|
+
normalize_rad = rad > 2.0 * Math::PI ? rad - 2.0 * Math::PI : rad
|
|
51
55
|
normalize_rad(normalize_rad) if normalize_rad != rad
|
|
52
56
|
normalize_rad
|
|
53
57
|
end
|
|
@@ -58,8 +62,8 @@ module Korba
|
|
|
58
62
|
end
|
|
59
63
|
|
|
60
64
|
def normalize_deg(deg)
|
|
61
|
-
deg = deg + 360 if deg < 0
|
|
62
|
-
normalized_deg = deg > 360 ? deg - 360 : deg
|
|
65
|
+
deg = deg + 360.0 if deg < 0
|
|
66
|
+
normalized_deg = deg > 360.0 ? deg - 360.0 : deg
|
|
63
67
|
normalize_deg(normalized_deg) if normalized_deg != deg
|
|
64
68
|
normalized_deg
|
|
65
69
|
end
|
data/lib/korba/tle.rb
CHANGED
|
@@ -5,7 +5,7 @@ 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, :sattelite_id, :object_name, :epoch_datetime, :julian_date,
|
|
9
9
|
:satellite_number, :classification_type, :epoch, :mean_motion_dot, :mean_motion_ddot, :bstar, :element_set_no,
|
|
10
10
|
:inclination, :ra_of_asc_node, :eccentricity, :arg_of_pericenter, :mean_anomaly, :mean_motion, :revolution_number,
|
|
11
11
|
:element_set_record, :epoch_days
|
|
@@ -35,8 +35,7 @@ module Korba
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def to_car
|
|
38
|
-
|
|
39
|
-
kep.to_car
|
|
38
|
+
propagate_to(0)
|
|
40
39
|
end
|
|
41
40
|
|
|
42
41
|
def propagate_to(minutesAfterEpoch)
|
|
@@ -62,7 +61,7 @@ module Korba
|
|
|
62
61
|
end
|
|
63
62
|
|
|
64
63
|
def parse_line1(line1_strings)
|
|
65
|
-
# TODO:
|
|
64
|
+
# TODO: sattelite_id
|
|
66
65
|
@satellite_number = line1_strings[1][0..4].to_i
|
|
67
66
|
@classification_type = line1_strings[1][-1]
|
|
68
67
|
# For now, only supports years after 2000
|
|
@@ -103,7 +102,7 @@ module Korba
|
|
|
103
102
|
def initialize_from_json(tle_json)
|
|
104
103
|
@tle_json = tle_json
|
|
105
104
|
@object_name = tle_json[:OBJECT_NAME]
|
|
106
|
-
@
|
|
105
|
+
@sattelite_id = tle_json[:OBJECT_ID]
|
|
107
106
|
@satellite_number = tle_json[:NORAD_CAT_ID]
|
|
108
107
|
@classification_type = tle_json[:CLASSIFICATION_TYPE]
|
|
109
108
|
@epoch = tle_json[:EPOCH]
|
data/lib/korba/version.rb
CHANGED
data/lib/korba.rb
CHANGED
|
@@ -6,7 +6,7 @@ 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/
|
|
9
|
+
require_relative "korba/keplers_equation"
|
|
10
10
|
require_relative "korba/sgp4/elset_rec"
|
|
11
11
|
require_relative "korba/sgp4/sgp4"
|
|
12
12
|
|
data/mise.toml
ADDED
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.
|
|
4
|
+
version: 0.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kk0000-kk
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies: []
|
|
13
12
|
description: Orbital elements calculation library
|
|
14
13
|
email:
|
|
@@ -25,13 +24,13 @@ files:
|
|
|
25
24
|
- lib/korba/car.rb
|
|
26
25
|
- lib/korba/constant.rb
|
|
27
26
|
- lib/korba/kep.rb
|
|
28
|
-
- lib/korba/
|
|
29
|
-
- lib/korba/newton_function.rb
|
|
27
|
+
- lib/korba/keplers_equation.rb
|
|
30
28
|
- lib/korba/orbit_utils.rb
|
|
31
29
|
- lib/korba/sgp4/elset_rec.rb
|
|
32
30
|
- lib/korba/sgp4/sgp4.rb
|
|
33
31
|
- lib/korba/tle.rb
|
|
34
32
|
- lib/korba/version.rb
|
|
33
|
+
- mise.toml
|
|
35
34
|
- sig/korba.rbs
|
|
36
35
|
homepage: https://github.com/kk0000-kk/korba
|
|
37
36
|
licenses: []
|
|
@@ -40,7 +39,6 @@ metadata:
|
|
|
40
39
|
homepage_uri: https://github.com/kk0000-kk/korba
|
|
41
40
|
source_code_uri: https://github.com/kk0000-kk/korba
|
|
42
41
|
changelog_uri: https://github.com/kk0000-kk/korba/blob/main/CHANGELOG.md
|
|
43
|
-
post_install_message:
|
|
44
42
|
rdoc_options: []
|
|
45
43
|
require_paths:
|
|
46
44
|
- lib
|
|
@@ -55,8 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
55
53
|
- !ruby/object:Gem::Version
|
|
56
54
|
version: '0'
|
|
57
55
|
requirements: []
|
|
58
|
-
rubygems_version: 3.
|
|
59
|
-
signing_key:
|
|
56
|
+
rubygems_version: 3.7.2
|
|
60
57
|
specification_version: 4
|
|
61
58
|
summary: Orbital elements calculation library
|
|
62
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
|