-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprop.go
More file actions
106 lines (87 loc) · 1.8 KB
/
prop.go
File metadata and controls
106 lines (87 loc) · 1.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package gpelements
import (
"time"
sat "github.com/jsmorph/go-satellite"
sgp4 "github.com/morphism/sgp4go"
)
var HigherPrecisionSGP4 = true
func (e *Elements) SGP4() (*sgp4.TLE, error) {
_, line1, line2, err := e.MarshalTLE()
if err != nil {
return nil, err
}
tle, err := sgp4.NewTLE(line1, line2)
if err != nil {
return nil, err
}
if HigherPrecisionSGP4 {
tle.Set(time.Time(*e.Epoch),
e.MeanMotionDot,
e.MeanMotionDDot,
e.BStar,
e.Inclination,
e.RightAscension,
e.Eccentricity,
e.ArgOfPericenter,
e.MeanAnomaly,
e.MeanMotion,
e.RevAtEpoch)
}
return tle, nil
}
// Vect is a 3-vector.
type Vect struct {
X, Y, Z float32
}
// Ephemeris represents position and velocity.
type Ephemeris struct {
// V is velocity.
V Vect
// C is Cartesian position.
ECI Vect
}
func Prop(o *sgp4.TLE, t time.Time) (Ephemeris, error) {
p, v, err := o.PropUnixMillis(t.UnixNano() / 1000 / 1000)
var e Ephemeris
if err == nil {
e = Ephemeris{
ECI: Vect{float32(p[0]), float32(p[1]), float32(p[2])},
V: Vect{float32(v[0]), float32(v[1]), float32(v[2])},
}
}
return e, err
}
func TimeToGST(t time.Time) (float64, float64) {
var (
y = t.Year()
m = int(t.Month())
d = t.Day()
h = t.Hour()
min = t.Minute()
sec = t.Second()
ns = t.Nanosecond()
)
return sat.GSTimeFromDateNano(y, m, d, h, min, sec, ns)
}
type LatLonAlt struct {
Lat, Lon, Alt float32
}
func ECIToLLA(t time.Time, p Vect) (*LatLonAlt, error) {
gmst, _ := TimeToGST(t)
x := sat.Vector3{
X: float64(p.X),
Y: float64(p.Y),
Z: float64(p.Z),
}
// sat.ECIToLLA is very slow.
alt, _, ll := sat.ECIToLLA(x, gmst)
d, err := sat.LatLongDeg(ll)
if err != nil {
return nil, err
}
return &LatLonAlt{
Lat: float32(d.Latitude),
Lon: float32(d.Longitude),
Alt: float32(alt),
}, nil
}