Completed
Push — master ( d35909...f740b5 )
by Yannick
06:46
created

Predict_TLE   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 220
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 220
rs 10
c 0
b 0
f 0
wmc 29
lcom 0
cbo 1

4 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 78 3
B Checksum_Good() 0 25 6
C Good_Elements() 0 32 14
B createChecksum() 0 24 6
1
<?php
2
/**
3
 * Ported from gpredict to PHP by Bill Shupp.  License: GPL 2.
4
 */
5
6
require_once 'Exception.php';
7
8
/**
9
 * Predict_TLE
10
 *
11
 * All routines for parsing and validating NORAD two line element sets
12
 */
13
class Predict_TLE
14
{
15
    public $header;     /* Header line of TLE file */
16
    public $line1;      /* Line 1 of TLE */
17
    public $line2;      /* Line 2 of TLE */
18
    public $epoch;      /*!< Epoch Time in NORAD TLE format YYDDD.FFFFFFFF */
19
    public $epoch_year; /*!< Epoch: year */
20
    public $epoch_day;  /*!< Epoch: day of year */
21
    public $epoch_fod;  /*!< Epoch: Fraction of day. */
22
    public $xndt2o;     /*!< 1. time derivative of mean motion */
23
    public $xndd6o;     /*!< 2. time derivative of mean motion */
24
    public $bstar;      /*!< Bstar drag coefficient. */
25
    public $xincl;      /*!< Inclination */
26
    public $xnodeo;     /*!< R.A.A.N. */
27
    public $eo;         /*!< Eccentricity */
28
    public $omegao;     /*!< argument of perigee */
29
    public $xmo;        /*!< mean anomaly */
30
    public $xno;        /*!< mean motion */
31
32
    public $catnr;      /*!< Catalogue Number.  */
33
    public $elset;      /*!< Element Set number. */
34
    public $revnum;     /*!< Revolution Number at epoch. */
35
36
    public $sat_name;   /*!< Satellite name string. */
37
    public $idesg;      /*!< International Designator. */
38
    public $status;     /*!< Operational status. */
39
40
    /* values needed for squint calculations */
41
    public $xincl1;
42
    public $xnodeo1;
43
    public $omegao1;
44
45
46
    /* Converts the strings in a raw two-line element set  */
47
    /* to their intended numerical values. No processing   */
48
    /* of these values is done, e.g. from deg to rads etc. */
49
    /* This is done in the select_ephemeris() function.    */
50
    public function __construct($header, $line1, $line2)
51
    {
52
        if (!$this->Good_Elements($line1, $line2)) {
53
            throw new Predict_Exception('Invalid TLE contents');
54
        }
55
56
        $this->header = $header;
57
        $this->line1  = $line1;
58
        $this->line2  = $line2;
59
60
        /** Decode Card 1 **/
61
        /* Satellite's catalogue number */
62
        $this->catnr = (int) substr($line1, 2, 5);
63
64
        /* International Designator for satellite */
65
        $this->idesg = substr($line1, 9, 8);
66
67
        /* Epoch time; this is the complete, unconverted epoch. */
68
        /* Replace spaces with 0 before casting, as leading spaces are allowed */
69
        $this->epoch = (float) str_replace(' ', '0', substr($line1, 18, 14));
70
71
        /* Now, convert the epoch time into year, day
72
           and fraction of day, according to:
73
74
           YYDDD.FFFFFFFF
75
        */
76
77
        // Adjust for 2 digit year through 2056
78
        $this->epoch_year = (int) substr($line1, 18, 2);
79
        if ($this->epoch_year > 56) {
80
            $this->epoch_year = $this->epoch_year + 1900;
81
        } else {
82
            $this->epoch_year = $this->epoch_year + 2000;
83
        }
84
85
        /* Epoch day */
86
        $this->epoch_day = (int) substr($line1, 20, 3);
87
88
        /* Epoch fraction of day */
89
        $this->epoch_fod = (float) substr($line1, 23, 9);
90
91
92
        /* Satellite's First Time Derivative */
93
        $this->xndt2o = (float) substr($line1, 33, 10);
94
95
        /* Satellite's Second Time Derivative */
96
        $this->xndd6o = (float) (substr($line1, 44, 1) . '.' . substr($line1, 45, 5) . 'E' . substr($line1, 50, 2));
97
98
        /* Satellite's bstar drag term
99
           FIXME: How about buff[0] ????
100
        */
101
        $this->bstar = (float) (substr($line1, 53, 1) . '.' . substr($line1, 54, 5) . 'E' . substr($line1, 59, 2));
102
103
        /* Element Number */
104
        $this->elset = (int) substr($line1, 64, 4);
105
106
        /** Decode Card 2 **/
107
        /* Satellite's Orbital Inclination (degrees) */
108
        $this->xincl = (float) substr($line2, 8, 8);
109
110
        /* Satellite's RAAN (degrees) */
111
        $this->xnodeo = (float) substr($line2, 17, 8);
112
113
        /* Satellite's Orbital Eccentricity */
114
        $this->eo = (float) ('.' . substr($line2, 26, 7));
115
116
        /* Satellite's Argument of Perigee (degrees) */
117
        $this->omegao = (float) substr($line2, 34, 8);
118
119
        /* Satellite's Mean Anomaly of Orbit (degrees) */
120
        $this->xmo = (float) substr($line2, 43, 8);
121
122
        /* Satellite's Mean Motion (rev/day) */
123
        $this->xno = (float) substr($line2, 52, 11);
124
125
        /* Satellite's Revolution number at epoch */
126
        $this->revnum = (float) substr($line2, 63, 5);
127
    }
128
129
    /* Calculates the checksum mod 10 of a line from a TLE set and */
130
    /* returns true if it compares with checksum in column 68, else false.*/
131
    /* tle_set is a character string holding the two lines read    */
132
    /* from a text file containing NASA format Keplerian elements. */
133
    /* NOTE!!! The stuff about two lines is not quite true.
134
       The function assumes that tle_set[0] is the begining
135
       of the line and that there are 68 elements - see the consumer
136
    */
137
    public function Checksum_Good($tle_set)
138
    {
139
        if (strlen($tle_set) < 69) {
140
            return false;
141
        }
142
143
        $checksum = 0;
144
145
        for ($i = 0; $i < 68; $i++) {
146
            if (($tle_set[$i] >= '0') && ($tle_set[$i] <= '9')) {
147
                $value = $tle_set[$i] - '0';
148
            } else if ($tle_set[$i] == '-' ) {
149
                $value = 1;
150
            } else {
151
                $value = 0;
152
            }
153
154
            $checksum += $value;
155
        }
156
157
        $checksum   %= 10;
158
        $check_digit = $tle_set[68] - '0';
159
160
        return $checksum == $check_digit;
161
    }
162
163
    /* Carries out various checks on a TLE set to verify its validity */
164
    /* $line1 is the first line of the TLE, $line2 is the second line */
165
    /* from a text file containing NASA format Keplerian elements. */
166
    public function Good_Elements($line1, $line2)
167
    {
168
        /* Verify checksum of both lines of a TLE set */
169
        if (!$this->Checksum_Good($line1) || !$this->Checksum_Good($line2)) {
170
            return false;
171
        }
172
173
        /* Check the line number of each line */
174
        if (($line1[0] != '1') || ($line2[0] != '2')) {
175
            return false;
176
        }
177
178
        /* Verify that Satellite Number is same in both lines */
179
        if (strncmp($line1[2], $line2[2], 5) != 0) {
180
            return false;
181
        }
182
183
        /* Check that various elements are in the right place */
184
        if (($line1[23] != '.') ||
185
            ($line1[34] != '.') ||
186
            ($line2[11] != '.') ||
187
            ($line2[20] != '.') ||
188
            ($line2[37] != '.') ||
189
            ($line2[46] != '.') ||
190
            ($line2[54] != '.') ||
191
            (strncmp(substr($line1, 61), ' 0 ', 3) != 0)) {
192
193
            return false;
194
        }
195
196
        return true;
197
    }
198
199
    /**
200
     * A function to allow checksum creation of a line.  This is driven by
201
     * the fact that some TLEs from SpaceTrack are missing checksum numbers.
202
     * You can use this to create a checksum for a line, but you should
203
     * probably have confidence that the TLE data itself is good.  YMMV.
204
     *
205
     * @throws Predict_Exception if the line is not exactly 68 chars
206
     * @return string
207
     */
208
    static public function createChecksum($line)
209
    {
210
        if (strlen($line) != 68) {
211
            throw Predict_Exception('Invalid line, needs to e 68 chars');
212
        }
213
214
        $checksum = 0;
215
216
        for ($i = 0; $i < 68; $i++) {
217
            if (($line[$i] >= '0') && ($line[$i] <= '9')) {
218
                $value = (int) $line[$i];
219
            } else if ($line[$i] == '-' ) {
220
                $value = 1;
221
            } else {
222
                $value = 0;
223
            }
224
225
            $checksum += $value;
226
        }
227
228
        $checksum %= 10;
229
230
        return $checksum;
231
    }
232
}
233