korba 0.3.0 → 0.5.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 +8 -0
- data/README.md +21 -1
- data/lib/korba/car.rb +18 -0
- data/lib/korba/kep.rb +19 -2
- data/lib/korba/kepler_equation_fucntion.rb +20 -0
- data/lib/korba/newton_function.rb +25 -0
- data/lib/korba/orbit_utils.rb +52 -3
- data/lib/korba/tle.rb +16 -10
- data/lib/korba/version.rb +1 -1
- data/lib/korba.rb +3 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d844574b98c6fe33241edac6be121c39c8a509b405ab1d5478aca0de1426465
|
4
|
+
data.tar.gz: 72ba006521490f7e0670ebb800457b34738df3ebbc6fd75cdcfa56259816610e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f169b773a67dd872046d08f605c7c6319930a069133c4b8732a8e7bf6953d0a64fd065b75404990cf69ac2d2892e014f6977385ae07b652e20267e2b1ebcc3e
|
7
|
+
data.tar.gz: 135c8c52c2cc1b25aa543c087ec4a6c9f3ac784c3042864398363f5258b08a9e1e0463dc2a6afe6dc150765e1183d6131e9bc32db39d5fb7b362c0f48055c6a4
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -38,7 +38,7 @@ orbit.height_at_perigee
|
|
38
38
|
orbit.height_at_apogee
|
39
39
|
# => 420372.03623388056
|
40
40
|
|
41
|
-
orbit.to_kep
|
41
|
+
kep = orbit.to_kep
|
42
42
|
# =>
|
43
43
|
# #<Korba::Kep:xxxxxxxxxxxxxxxx
|
44
44
|
# @arg_of_pericenter=314.0303,
|
@@ -49,8 +49,28 @@ orbit.to_kep
|
|
49
49
|
# @object_name="ISS (ZARYA)",
|
50
50
|
# @ra_of_asc_node=174.9565,
|
51
51
|
# @semi_major_axis=6793877.649839985>
|
52
|
+
|
53
|
+
kep.to_car
|
54
|
+
# =>
|
55
|
+
# #<Korba::Car:xxxxxxxxxxxxxxxx
|
56
|
+
# @epoch="2024-12-07T20:37:24.085055",
|
57
|
+
# @object_name="ISS (ZARYA)",
|
58
|
+
# @vx=6150.772410883998,
|
59
|
+
# @vy=2489.3298780751356,
|
60
|
+
# @vz=-3816.0301666253677,
|
61
|
+
# @x=4019753.8621700387,
|
62
|
+
# @y=-3623966.518673545,
|
63
|
+
# @z=4114361.6934797494>
|
64
|
+
|
52
65
|
```
|
53
66
|
|
67
|
+
## References
|
68
|
+
|
69
|
+
- 宇宙工学シリーズ 3 人工衛星と宇宙探査機
|
70
|
+
- https://www.coronasha.co.jp/np/isbn/9784339012316/
|
71
|
+
- 人工衛星の軌道 概論
|
72
|
+
- https://www.coronasha.co.jp/np/isbn/9784339046403/
|
73
|
+
|
54
74
|
## Development
|
55
75
|
|
56
76
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/korba/car.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Korba
|
4
|
+
class Car
|
5
|
+
attr_reader :object_name, :epoch, :x, :y, :z, :vx, :vy, :vz
|
6
|
+
|
7
|
+
def initialize(object_name:, epoch:, x:, y:, z:, vx:, vy:, vz:)
|
8
|
+
@object_name = object_name
|
9
|
+
@epoch = epoch
|
10
|
+
@x = x
|
11
|
+
@y = y
|
12
|
+
@z = z
|
13
|
+
@vx = vx
|
14
|
+
@vy = vy
|
15
|
+
@vz = vz
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/korba/kep.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
require "matrix"
|
3
3
|
|
4
4
|
module Korba
|
5
5
|
class Kep
|
6
|
-
include
|
6
|
+
include OrbitUtils
|
7
7
|
|
8
8
|
attr_reader :object_name, :epoch, :semi_major_axis, :eccentricity, :inclination, :ra_of_asc_node, :arg_of_pericenter, :mean_anomaly
|
9
9
|
|
@@ -17,5 +17,22 @@ module Korba
|
|
17
17
|
@arg_of_pericenter = arg_of_pericenter
|
18
18
|
@mean_anomaly = mean_anomaly
|
19
19
|
end
|
20
|
+
|
21
|
+
def to_car
|
22
|
+
vector_n = Vector[
|
23
|
+
Math.sin(deg_to_rad(inclination)) * Math.sin(deg_to_rad(ra_of_asc_node)),
|
24
|
+
-Math.sin(deg_to_rad(inclination)) * Math.cos(deg_to_rad(ra_of_asc_node)),
|
25
|
+
Math.cos(deg_to_rad(inclination))
|
26
|
+
]
|
27
|
+
vector_omega = Vector[Math.cos(deg_to_rad(ra_of_asc_node)), Math.sin(deg_to_rad(ra_of_asc_node)), 0]
|
28
|
+
vector_m = vector_n.cross(vector_omega)
|
29
|
+
|
30
|
+
r_angle_factor = deg_to_rad(arg_of_pericenter + true_anomaly)
|
31
|
+
vector_r = distance * (Math.cos(r_angle_factor) * vector_omega + Math.sin(r_angle_factor) * vector_m)
|
32
|
+
v_angle_factor = deg_to_rad(arg_of_pericenter + true_anomaly - path_angle)
|
33
|
+
vector_v = velocity * (-Math.sin(v_angle_factor) * vector_omega + (Math.cos(v_angle_factor)) * vector_m)
|
34
|
+
|
35
|
+
Car.new(object_name:, epoch:, x: vector_r[0], y: vector_r[1], z: vector_r[2], vx: vector_v[0], vy: vector_v[1], vz: vector_v[2])
|
36
|
+
end
|
20
37
|
end
|
21
38
|
end
|
@@ -0,0 +1,20 @@
|
|
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
|
@@ -0,0 +1,25 @@
|
|
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
|
data/lib/korba/orbit_utils.rb
CHANGED
@@ -4,15 +4,64 @@ module Korba
|
|
4
4
|
module OrbitUtils
|
5
5
|
def semi_major_axis
|
6
6
|
# a = (μ / n^2)^(1/3) m
|
7
|
-
(
|
7
|
+
(Constant::GME / (mean_motion * 2 * Math::PI / 86400.0) ** 2.0) ** (1.0 / 3.0)
|
8
8
|
end
|
9
9
|
|
10
10
|
def height_at_perigee
|
11
|
-
semi_major_axis * (1 - eccentricity) -
|
11
|
+
semi_major_axis * (1 - eccentricity) - Constant::EARTH_RADIUS
|
12
12
|
end
|
13
13
|
|
14
14
|
def height_at_apogee
|
15
|
-
semi_major_axis * (1 + eccentricity) -
|
15
|
+
semi_major_axis * (1 + eccentricity) - Constant::EARTH_RADIUS
|
16
|
+
end
|
17
|
+
|
18
|
+
def eccentric_anomaly
|
19
|
+
f = KeplerEquationFunction.new(eccentricity:, mean_anomaly:)
|
20
|
+
x = [deg_to_rad(mean_anomaly)]
|
21
|
+
nlsolve(f, x)
|
22
|
+
rad_to_deg(x[0])
|
23
|
+
end
|
24
|
+
|
25
|
+
def true_anomaly
|
26
|
+
factor = (Math.cos(deg_to_rad(eccentric_anomaly)) - eccentricity) / (1 - eccentricity * Math.cos(deg_to_rad(eccentric_anomaly)))
|
27
|
+
rad_to_deg(Math.acos(factor))
|
28
|
+
end
|
29
|
+
|
30
|
+
def distance
|
31
|
+
semi_major_axis * (1 - eccentricity * Math.cos(deg_to_rad(eccentric_anomaly)))
|
32
|
+
end
|
33
|
+
|
34
|
+
def velocity
|
35
|
+
Math.sqrt(Constant::GME * (2 / distance - 1 / semi_major_axis))
|
36
|
+
end
|
37
|
+
|
38
|
+
def path_angle
|
39
|
+
factor = Math.sqrt(Constant::GME * semi_major_axis * (1 - eccentricity ** 2)) / (distance * velocity)
|
40
|
+
rad_to_deg(Math.acos(factor))
|
41
|
+
end
|
42
|
+
|
43
|
+
def deg_to_rad(deg)
|
44
|
+
rad = deg * Math::PI / 180.0
|
45
|
+
normalize_rad(rad)
|
46
|
+
end
|
47
|
+
|
48
|
+
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
|
51
|
+
normalize_rad(normalize_rad) if normalize_rad != rad
|
52
|
+
normalize_rad
|
53
|
+
end
|
54
|
+
|
55
|
+
def rad_to_deg(rad)
|
56
|
+
deg = rad * 180.0 / Math::PI
|
57
|
+
normalize_deg(deg)
|
58
|
+
end
|
59
|
+
|
60
|
+
def normalize_deg(deg)
|
61
|
+
deg = deg + 360 if deg < 0
|
62
|
+
normalized_deg = deg > 360 ? deg - 360 : deg
|
63
|
+
normalize_deg(normalized_deg) if normalized_deg != deg
|
64
|
+
normalized_deg
|
16
65
|
end
|
17
66
|
end
|
18
67
|
end
|
data/lib/korba/tle.rb
CHANGED
@@ -3,9 +3,9 @@ require_relative "orbit_utils"
|
|
3
3
|
|
4
4
|
module Korba
|
5
5
|
class Tle
|
6
|
-
include
|
6
|
+
include OrbitUtils
|
7
7
|
|
8
|
-
attr_reader :tle_json, :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, :object_name, :object_id, :epoch, :mean_motion, :eccentricity, :inclination, :ra_of_asc_node, :arg_of_pericenter, :mean_anomaly
|
9
9
|
|
10
10
|
def initialize(tle = nil, type: :string)
|
11
11
|
return if tle.nil?
|
@@ -19,19 +19,25 @@ module Korba
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def to_kep
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
22
|
+
Kep.new(object_name:,
|
23
|
+
epoch:,
|
24
|
+
semi_major_axis:,
|
25
|
+
eccentricity:,
|
26
|
+
inclination:,
|
27
|
+
ra_of_asc_node:,
|
28
|
+
arg_of_pericenter:,
|
29
|
+
mean_anomaly:)
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_car
|
33
|
+
kep = to_kep
|
34
|
+
kep.to_car
|
30
35
|
end
|
31
36
|
|
32
37
|
private
|
33
38
|
|
34
39
|
def initialize_from_string(tle_string)
|
40
|
+
@tle_string = tle_string
|
35
41
|
lines = tle_string.split(/\R/)
|
36
42
|
@object_name = lines.shift if lines.size > 2
|
37
43
|
parse_line1(lines[0].split(" "))
|
data/lib/korba/version.rb
CHANGED
data/lib/korba.rb
CHANGED
@@ -4,6 +4,9 @@ require_relative "korba/version"
|
|
4
4
|
require_relative "korba/constant"
|
5
5
|
require_relative "korba/tle"
|
6
6
|
require_relative "korba/kep"
|
7
|
+
require_relative "korba/car"
|
8
|
+
require_relative "korba/orbit_utils"
|
9
|
+
require_relative "korba/kepler_equation_fucntion"
|
7
10
|
|
8
11
|
module Korba
|
9
12
|
end
|
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.5.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-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Orbital elements calculation library
|
14
14
|
email:
|
@@ -22,8 +22,11 @@ files:
|
|
22
22
|
- README.md
|
23
23
|
- Rakefile
|
24
24
|
- lib/korba.rb
|
25
|
+
- lib/korba/car.rb
|
25
26
|
- lib/korba/constant.rb
|
26
27
|
- lib/korba/kep.rb
|
28
|
+
- lib/korba/kepler_equation_fucntion.rb
|
29
|
+
- lib/korba/newton_function.rb
|
27
30
|
- lib/korba/orbit_utils.rb
|
28
31
|
- lib/korba/tle.rb
|
29
32
|
- lib/korba/version.rb
|
@@ -50,7 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
50
53
|
- !ruby/object:Gem::Version
|
51
54
|
version: '0'
|
52
55
|
requirements: []
|
53
|
-
rubygems_version: 3.5.
|
56
|
+
rubygems_version: 3.5.23
|
54
57
|
signing_key:
|
55
58
|
specification_version: 4
|
56
59
|
summary: Orbital elements calculation library
|