GPS.lla2ecef()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 17
rs 9.4285
cc 1
1
from math import sqrt, pi, sin, cos, log, atan, atan2
2
3
4
def deg2rad(deg):
5
    """Converts degrees to radians"""
6
    return deg * pi / 180
7
8
9
def rad2deg(rad):
10
    """Converts radians to degrees"""
11
    return rad * 180 / pi
12
  
13
14
class WGS84:
15
    """General parameters defined by the WGS84 system"""
16
    #Semimajor axis length (m)
17
    a = 6378137.0
18
    #Semiminor axis length (m)
19
    b = 6356752.3142
20
    #Ellipsoid flatness (unitless)
21
    f = (a - b) / a
22
    #Eccentricity (unitless)
23
    e = sqrt(f * (2 - f))
24
    #Speed of light (m/s)
25
    c = 299792458.
26
    #Relativistic constant
27
    F = -4.442807633e-10
28
    #Earth's universal gravitational constant
29
    mu = 3.986005e14
30
    #Earth rotation rate (rad/s)
31
    omega_ie = 7.2921151467e-5
32
33
    def g0(self, L):
34
        """acceleration due to gravity at the elipsoid surface at latitude L"""
35
        return 9.7803267715 * (1 + 0.001931851353 * sin(L)**2) / \
36
                        sqrt(1 - 0.0066943800229 * sin(L)**2)
37
                      
38
39
class GPS:
40
    """Working class for GPS module"""
41
    wgs84 = WGS84()
42
    fGPS = 1023
43
    fL1 = fGPS * 1.54e6
44
    fL2 = fGPS * 1.2e6
45
    
46
    def lla2ecef(self, lla):
47
        """Convert lat, lon, alt to Earth-centered, Earth-fixed coordinates.
48
Input: lla - (lat, lon, alt) in (decimal degrees, decimal degees, m)
49
Output: ecef - (x, y, z) in (m, m, m)
50
"""
51
        #Decompose the input
52
        lat = deg2rad(lla[0])
53
        lon = deg2rad(lla[1])
54
        alt = lla[2]
55
        #Calculate length of the normal to the ellipsoid
56
        N = self.wgs84.a / sqrt(1 - (self.wgs84.e * sin(lat))**2)
57
        #Calculate ecef coordinates
58
        x = (N + alt) * cos(lat) * cos(lon)
59
        y = (N + alt) * cos(lat) * sin(lon)
60
        z = (N * (1 - self.wgs84.e**2) + alt) * sin(lat)
61
        #Return the ecef coordinates
62
        return (x, y, z)
63
64
    def ecef2lla(self, ecef, tolerance=1e-9):
65
        """Convert Earth-centered, Earth-fixed coordinates to lat, lon, alt.
66
Input: ecef - (x, y, z) in (m, m, m)
67
Output: lla - (lat, lon, alt) in (decimal degrees, decimal degrees, m)
68
"""
69
        #Decompose the input
70
        x = ecef[0]
71
        y = ecef[1]
72
        z = ecef[2]
73
        #Calculate lon
74
        lon = atan2(y, x)
75
        #Initialize the variables to calculate lat and alt
76
        alt = 0
77
        N = self.wgs84.a
78
        p = sqrt(x**2 + y**2)
79
        lat = 0
80
        previousLat = 90
81
        #Iterate until tolerance is reached
82
        while abs(lat - previousLat) >= tolerance:
83
            previousLat = lat
84
            sinLat = z / (N * (1 - self.wgs84.e**2) + alt)
85
            lat = atan((z + self.wgs84.e**2 * N * sinLat) / p)
86
            N = self.wgs84.a / sqrt(1 - (self.wgs84.e * sinLat)**2)
87
            alt = p / cos(lat) - N
88
        #Return the lla coordinates
89
        return (rad2deg(lat), rad2deg(lon), alt)
90