korba 0.7.1 → 0.8.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 +5 -0
- data/lib/korba/car.rb +82 -0
- data/lib/korba/constant.rb +2 -1
- data/lib/korba/kep.rb +8 -0
- data/lib/korba/propagator/rk4.rb +63 -0
- data/lib/korba/propagator/sgp4.rb +2029 -0
- data/lib/korba/sgp4/elset_rec.rb +421 -419
- data/lib/korba/tle.rb +4 -4
- data/lib/korba/version.rb +1 -1
- data/lib/korba.rb +2 -1
- metadata +3 -2
- data/lib/korba/sgp4/sgp4.rb +0 -2027
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5dc3a4abbdd189f4388673e3960a615940a4feb68c359cce37a29ff47fa7efcb
|
|
4
|
+
data.tar.gz: c312b2be706e321242d0f4c762134ad82ea681348e5631ec36a13ed91c36db11
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f0cc15b9fa16cec125d3902e3b52e1336acf4246c72860049955c32456d1eaa0e56a2fd99953477d36141da23b3b8696ed0b8a611c80bc51e1249368c7f07f84
|
|
7
|
+
data.tar.gz: ffcbf5ed21c86f069d83276227c9db29e5b59d257d1630f5a1fb15eaff0550b881b1e7753fcc551ce6c647c49faf2bc84ee52efb015fbd9ad8efa9355b2da6ad
|
data/CHANGELOG.md
CHANGED
data/lib/korba/car.rb
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
module Korba
|
|
4
4
|
class Car
|
|
5
|
+
include OrbitUtils
|
|
6
|
+
|
|
5
7
|
attr_reader :object_name, :epoch, :x, :y, :z, :vx, :vy, :vz
|
|
6
8
|
|
|
7
9
|
def initialize(object_name:, epoch:, x:, y:, z:, vx:, vy:, vz:)
|
|
@@ -14,5 +16,85 @@ module Korba
|
|
|
14
16
|
@vy = vy
|
|
15
17
|
@vz = vz
|
|
16
18
|
end
|
|
19
|
+
|
|
20
|
+
def to_kep
|
|
21
|
+
inclination = rad_to_deg(Math.atan2(Math.sqrt(specific_angular_momentum_vector[0] ** 2 + specific_angular_momentum_vector[1] ** 2), specific_angular_momentum_vector[2]))
|
|
22
|
+
ra_of_asc_node = rad_to_deg(Math.atan2(specific_angular_momentum_vector[0], -specific_angular_momentum_vector[1]))
|
|
23
|
+
|
|
24
|
+
Kep.new(object_name:,
|
|
25
|
+
epoch:,
|
|
26
|
+
semi_major_axis:,
|
|
27
|
+
eccentricity:,
|
|
28
|
+
inclination:,
|
|
29
|
+
ra_of_asc_node:,
|
|
30
|
+
arg_of_pericenter: normalize_deg(arg_of_latitude - true_anomaly),
|
|
31
|
+
mean_anomaly: rad_to_deg(deg_to_rad(eccentric_anomaly) - eccentricity * Math.sin(deg_to_rad(eccentric_anomaly))))
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def position_vector
|
|
37
|
+
@position_vector ||= Vector[x, y, z]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def velocity_vector
|
|
41
|
+
@velocity_vector ||= Vector[vx, vy, vz]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def distance
|
|
45
|
+
@distance ||= position_vector.norm
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def velocity
|
|
49
|
+
@velocity ||= velocity_vector.norm
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def semi_major_axis
|
|
53
|
+
@semi_major_axis ||= Constant::GME * distance / (2 * Constant::GME - distance * velocity ** 2)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def eccentricity
|
|
57
|
+
@eccentricity ||= Math.sqrt(((semi_major_axis - distance) / semi_major_axis) ** 2 + (position_vector.dot(velocity_vector) ** 2) / (Constant::GME * semi_major_axis))
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def eccentric_anomaly
|
|
61
|
+
@eccentric_anomaly ||= rad_to_deg(Math.atan2(Math.sqrt(semi_major_axis / Constant::GME) * position_vector.dot(velocity_vector), semi_major_axis - distance))
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def true_anomaly
|
|
65
|
+
factor = (Math.cos(deg_to_rad(eccentric_anomaly)) - eccentricity) / (1 - eccentricity * Math.cos(deg_to_rad(eccentric_anomaly)))
|
|
66
|
+
rad_to_deg(Math.atan2(Math.sqrt(1 - factor ** 2), factor))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def angular_momentum_vector
|
|
70
|
+
@angular_momentum_vector ||= position_vector.cross(velocity_vector)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def raan_vector
|
|
74
|
+
@raan_vector ||= Vector[0, 0, 1].cross(angular_momentum_vector)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def eccentricity_vector
|
|
78
|
+
@eccentricity_vector ||= ((velocity ** 2 - Constant::GME / distance) * position_vector - (position_vector * velocity_vector) * velocity_vector) / Constant::GME
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def specific_angular_momentum_vector
|
|
82
|
+
@specific_angular_momentum_vector ||= position_vector.cross(velocity_vector)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def raan_vector
|
|
86
|
+
@raan_vector ||= Vector[0, 0, 1].cross(specific_angular_momentum_vector)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def arg_of_latitude
|
|
90
|
+
y = position_vector.dot(raan_vector)
|
|
91
|
+
x = position_vector.norm * raan_vector.norm
|
|
92
|
+
arg_of_latitude = (Math.atan2(
|
|
93
|
+
Math.sqrt(1 - (y / x) ** 2),
|
|
94
|
+
y / x
|
|
95
|
+
))
|
|
96
|
+
arg_of_latitude = 2 * Math::PI - arg_of_latitude if z < 0
|
|
97
|
+
rad_to_deg(arg_of_latitude)
|
|
98
|
+
end
|
|
17
99
|
end
|
|
18
100
|
end
|
data/lib/korba/constant.rb
CHANGED
data/lib/korba/kep.rb
CHANGED
|
@@ -42,6 +42,14 @@ module Korba
|
|
|
42
42
|
v_angle_factor = deg_to_rad(arg_of_pericenter + true_anomaly - path_angle)
|
|
43
43
|
vector_v = velocity * (-Math.sin(v_angle_factor) * vector_omega + (Math.cos(v_angle_factor)) * vector_m)
|
|
44
44
|
|
|
45
|
+
# NOTE: こっちでもいい
|
|
46
|
+
# factor_matrix = Matrix[[Math.cos(deg_to_rad(ra_of_asc_node)), -Math.sin(deg_to_rad(ra_of_asc_node)) * Math.cos(deg_to_rad(inclination))],
|
|
47
|
+
# [Math.sin(deg_to_rad(ra_of_asc_node)), Math.cos(deg_to_rad(ra_of_asc_node)) * Math.cos(deg_to_rad(inclination))],
|
|
48
|
+
# [0, Math.sin(deg_to_rad(inclination))]] *
|
|
49
|
+
# Matrix[[Math.cos(deg_to_rad(arg_of_pericenter)), -Math.sin(deg_to_rad(arg_of_pericenter))], [Math.sin(deg_to_rad(arg_of_pericenter)), Math.cos(deg_to_rad(arg_of_pericenter))]]
|
|
50
|
+
# vector_r = Vector[*(factor_matrix * Matrix[[Math.cos(deg_to_rad(true_anomaly)) - eccentricity], [Math.sqrt(1 - eccentricity ** 2) * Math.sin(deg_to_rad(true_anomaly))]] * semi_major_axis).to_a.flatten]
|
|
51
|
+
# vector_v = Vector[*(factor_matrix * Matrix[[-Math.sin(deg_to_rad(true_anomaly))], [Math.sqrt(1 - eccentricity ** 2) * Math.cos(deg_to_rad(true_anomaly))]] * Math.sqrt(Constant::GME * semi_major_axis) / vector_r.norm).to_a.flatten]
|
|
52
|
+
|
|
45
53
|
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])
|
|
46
54
|
end
|
|
47
55
|
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Korba
|
|
2
|
+
module Propagator
|
|
3
|
+
class Rk4
|
|
4
|
+
def initialize(initial_car, disable_j2: false)
|
|
5
|
+
@initial_car = initial_car
|
|
6
|
+
@disable_j2 = disable_j2
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def propagate(seconds_after_epoch, dt = 1.0)
|
|
10
|
+
steps = (seconds_after_epoch / dt).to_i
|
|
11
|
+
t = 0.0
|
|
12
|
+
y = Vector[@initial_car.x, @initial_car.y, @initial_car.z, @initial_car.vx, @initial_car.vy, @initial_car.vz]
|
|
13
|
+
|
|
14
|
+
steps.times do
|
|
15
|
+
y = step(t, y, dt)
|
|
16
|
+
t += dt
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
Car.new(
|
|
20
|
+
object_name: @initial_car.object_name,
|
|
21
|
+
epoch: @initial_car.epoch + seconds_after_epoch,
|
|
22
|
+
x: y[0],
|
|
23
|
+
y: y[1],
|
|
24
|
+
z: y[2],
|
|
25
|
+
vx: y[3],
|
|
26
|
+
vy: y[4],
|
|
27
|
+
vz: y[5],
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def step(t, y, dt)
|
|
34
|
+
k1 = f(t, y)
|
|
35
|
+
k2 = f(t + dt / 2.0, y + k1 * (dt / 2.0))
|
|
36
|
+
k3 = f(t + dt / 2.0, y + k2 * (dt / 2.0))
|
|
37
|
+
k4 = f(t + dt, y + k3 * dt)
|
|
38
|
+
|
|
39
|
+
y + (k1 + 2 * k2 + 2 * k3 + k4) * (dt / 6.0)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def f(t, y)
|
|
43
|
+
position_vector = Vector[y[0], y[1], y[2]]
|
|
44
|
+
velocity_vector = Vector[y[3], y[4], y[5]]
|
|
45
|
+
r = position_vector.magnitude
|
|
46
|
+
base_acceleration_vector = -Constant::GME * position_vector / (r ** 3)
|
|
47
|
+
acceleration_vector = @disable_j2 ? base_acceleration_vector : add_j2_effect(base_acceleration_vector, r, position_vector[2])
|
|
48
|
+
|
|
49
|
+
Vector[velocity_vector[0], velocity_vector[1], velocity_vector[2], acceleration_vector[0], acceleration_vector[1], acceleration_vector[2]]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def add_j2_effect(base_acceleration_vector, r, z)
|
|
53
|
+
j2_factor = (3.0 / 2.0) * Constant::J2 * (Constant::EARTH_RADIUS / r) ** 2
|
|
54
|
+
factor = 5 * (z / r) ** 2
|
|
55
|
+
[
|
|
56
|
+
base_acceleration_vector[0] * (1 + j2_factor * (1 - factor)),
|
|
57
|
+
base_acceleration_vector[1] * (1 + j2_factor * (1 - factor)),
|
|
58
|
+
base_acceleration_vector[2] * (1 + j2_factor * (3 - factor)),
|
|
59
|
+
]
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|