-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutdf.go
248 lines (209 loc) · 5.92 KB
/
utdf.go
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
// Package utdfgo overview
// Spacecraft UTDF Packet Decoder
package utdfgo
import (
"encoding/hex"
"fmt"
"io/ioutil"
"math"
"strconv"
"time"
)
// speed of light consant
const sol = 299792.458
// full circle is 2^32
const fullCircle = 4294967296
const twoPi = 2 * math.Pi
// utdf packets are 75 bytes long
const bufferSize = 75
// UTDF data type creation
type UTDF []byte
// Run read in entire file then chunk into utdf packets
func Run(filename string) ([]UTDF, error) {
var utdfArr []UTDF
utdfFile, err := ioutil.ReadFile(filename)
check(err)
for i := 0; i < len(utdfFile); i += bufferSize {
end := i + bufferSize
if end > len(utdfFile) {
end = len(utdfFile)
}
if err = checkUTDF(utdfFile[i:end]); err != nil {
return nil, ErrBadFile
}
utdfArr = append(utdfArr, utdfFile[i:end])
}
return utdfArr, nil
}
// START TIME BASED FUNCTIONS
// taken from byte 6
// GetYear gets last two digits of current year
func (utdf UTDF) GetYear() int {
year := int(utdf[5])
if year < 70 {
year += 2000
} else {
year += 1900
}
return year
}
// taken from bytes 11:14
// GetSeconds get seconds of year
func (utdf UTDF) GetSeconds() int {
scY := (int(utdf[10]) << 24) + (int(utdf[11]) << 16) + (int(utdf[12]) << 8) + int(utdf[13])
return scY
}
// taken from bytes 15:18
// GetMicroseconds get microseconds of seconds
func (utdf UTDF) GetMicroseconds() int {
mcS := (int(utdf[14]) << 24) + (int(utdf[15]) << 16) + (int(utdf[16]) << 8) + int(utdf[17])
return mcS
}
// GetEpoch create UTC epoch
func (utdf UTDF) GetEpoch() int64 {
ytd := time.Date(utdf.GetYear(), 1, 1, 0, 0, 0, 0, time.UTC).Unix()
epoch := int(ytd) + utdf.GetSeconds() + utdf.GetMicroseconds()/1000000
return int64(epoch)
}
// GetTimestamps gets timestamp from utdf packet
func (utdf UTDF) GetTimestamps() string {
return fmt.Sprintf("Year: %d, Epoch: %d, Seconds: %d, Microseconds: %d", utdf.GetYear(), utdf.GetEpoch(), utdf.GetSeconds(), utdf.GetMicroseconds())
}
// END TIME BASED FUNCTIONS
// START ANGLE + ELEVATION BASED FUNCTIONS
// taken from bytes 19:22
// GetAzimuth get angle_data[0] and calculate azimuth
func (utdf UTDF) GetAzimuth() float64 {
azi := (int(utdf[18]) << 24) + (int(utdf[19]) << 16) + (int(utdf[20]) << 8) + int(utdf[21])
aAngle := calculateAngle(azi)
return aAngle
}
// taken from bytes 23-26
// GetElevation get angle_data[1] and calculate elevation
func (utdf UTDF) GetElevation() float64 {
e := (int(utdf[22]) << 24) + (int(utdf[23]) << 16) + (int(utdf[24]) << 8) + int(utdf[25])
eAngle := calculateAngle(e)
return eAngle
}
// END ANGLE + ELEVATION BASED FUNCTIONS
// START RANGE + DOPPLER BASED FUNCTIONS
// GetRangeDelay calculate range delay hi low count
func (utdf UTDF) GetRangeDelay() (float64, float64) {
rd := (int(utdf[26]) << 40) + (int(utdf[27]) << 32) + (int(utdf[28]) << 24) + (int(utdf[29]) << 16) + (int(utdf[30]) << 8) + int(utdf[31])
rdHi, rdLo := calculateRD(rd)
return float64(rdHi), float64(rdLo)
}
// GetRange calculate spacecraft range
func (utdf UTDF) GetRange() float64 {
rh, rl := utdf.GetRangeDelay()
r := (((rh + rl) - 0) * float64(sol) / 2000000)
return r
}
// GetDopplerDelay get doppler hi low count
func (utdf UTDF) GetDopplerDelay() (float64, float64) {
d := (int(utdf[32]) << 40) + (int(utdf[33]) << 32) + (int(utdf[34]) << 24) + (int(utdf[35]) << 16) + (int(utdf[36]) << 8) + int(utdf[37])
dHi, dLo := calculateRD(d)
return float64(dHi), float64(dLo)
}
// GetDoppler get spacecraft doppler count
func (utdf UTDF) GetDoppler() float64 {
dh, dl := utdf.GetDopplerDelay()
d := (((dh + dl) - 0) * float64(sol) / 2000000)
return d
}
// END RANGE BASED FUNCTIONS
// START MISC FUNCTIONS
// taken from bytes 39:40
// GetAGC get AGC
func (utdf UTDF) GetAGC() float32 {
agc := (int(utdf[38]) << 8) + int(utdf[39])
return float32(agc)
}
// taken from bytes 41:44
// GetTransmitFreq get transmit frequency
func (utdf UTDF) GetTransmitFreq() string {
tf := (int(utdf[40]) << 24) + (int(utdf[41]) << 16) + (int(utdf[42]) << 8) + int(utdf[43])
hz := float64(tf) * 10
return fmt.Sprintf("%1.10v", hz)
}
// taken from byte 45
// GetAntennaType get antenna type
func (utdf UTDF) GetAntennaType() byte {
at := utdf[44]
return at
}
// taken from byte 46
// GetPADID get antenna padid
func (utdf UTDF) GetPADID() int8 {
pid := utdf[45]
return int8(pid)
}
// taken from byte 47
// GetRecieveAntennaType get receive antenna type
func (utdf UTDF) GetRecieveAntennaType() byte {
at := utdf[46]
return at
}
// taken from byte 48
// GetRecievePADID get receive antenna padid
func (utdf UTDF) GetRecievePADID() int8 {
pid := utdf[45]
return int8(pid)
}
// taken from bytes 49:50
// GetSystemMode get system mode
func (utdf UTDF) GetSystemMode() int {
m := (int(utdf[48]) << 8) + int(utdf[49])
return m
}
// taken from byte 51
// GetDataValidation get data validity
func (utdf UTDF) GetDataValidation() byte {
dv := utdf[50]
return dv
}
// taken from byte 52
// GetFrequencyBand get frequency band
func (utdf UTDF) GetFrequencyBand() byte {
fb := utdf[51]
return fb
}
// taken from bytes 53:54
// GetTrackingInfo get tracking type and data
func (utdf UTDF) GetTrackingInfo() int {
ti := (int(utdf[52]) << 8) + int(utdf[53])
return ti
}
// END MISC FUNCTIONS
// GetSIC get spacecraft ID
func (utdf UTDF) GetSIC() uint64 {
sic := utdf[6:8]
sicE := hex.EncodeToString(sic)
n, err := strconv.ParseUint(sicE, 16, 16)
check(err)
return n
}
// GetVID get vehicle ID
func (utdf UTDF) GetVID() uint64 {
vid := utdf[9:10]
vidE := hex.EncodeToString(vid)
n, err := strconv.ParseUint(vidE, 16, 16)
check(err)
return n
}
func (utdf UTDF) isValid() bool {
valid := true
defer func() {
if r := recover(); r != nil {
valid = false
}
}()
if utdf.GetYear() > time.Now().Year() {
valid = false
}
return valid
}
// ToString currently just used for testing correct return values
func (utdf UTDF) ToString() string {
return fmt.Sprintf("%s\t\t%1.15v\t%1.15v\t%1.15v", utdf.GetTimestamps(), utdf.GetAzimuth(), utdf.GetElevation(), utdf.GetRange())
}