gps.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. import machine
  2. import time
  3. import struct
  4. class NMEA(object):
  5. def __init__(self, id):
  6. self.__id = str(id)
  7. class Value(object):
  8. def __init__(self, v, u, t=(0,0,0.0)):
  9. self.__val = float(v)
  10. self.__unit = u
  11. self.__time = t
  12. def value(self):
  13. return self.__val
  14. def unit(self):
  15. return self.__unit
  16. def time(self):
  17. return self.__time
  18. def rad(self):
  19. return self.__val * math.pi / 180
  20. def __repr__(self):
  21. return "%f %s" % (self.value(), self.unit())
  22. def __float__(self):
  23. return float(self.__val)
  24. class Distance(Value):
  25. def __init__(self, v, u, t):
  26. super().__init__(v, u, t)
  27. class Position(Value):
  28. def __init__(self, v, u, t):
  29. super().__init__(v if u in ("N", "E") else -v, u, t)
  30. def __sub__(self, other):
  31. return Position(self.value() - other.value())
  32. class Speed(Value):
  33. def __init__(self, v, u, t):
  34. super().__init__(v, u, t)
  35. def to_kmh(self):
  36. if self.unit() in ("knot", "N"):
  37. return Speed(self.value() * 1.85200, "kmh", self.time())
  38. return self
  39. def to_knot(self):
  40. if self.unit() in ("kmh", "K"):
  41. return Speed(self.value() / 1.85200, "knot", self.time())
  42. return self
  43. class Course(Value):
  44. def __init__(self, v, t):
  45. super().__init__(v, "D", t)
  46. class Location(object):
  47. def __init__(self):
  48. self.__valid = False
  49. self.__lat = None
  50. self.__long = None
  51. self.__alt = None
  52. self.__height = None
  53. self.__speed = None
  54. self.__course = None
  55. self.__satellites = -1
  56. def __repr__(self):
  57. return "Satelittes: %s, %s\n\tLat/long: %s/%s\n\tAlt/h: %s/%s\n\tSpeed/course: %s/%s" % (
  58. self.__satellites, repr(self.__valid),
  59. self.__lat, self.__lat,
  60. self.__alt, self.__height,
  61. self.__speed, self.__course,
  62. )
  63. def set(self, msgid, segment):
  64. data = segment.split(",")
  65. if msgid == b'$GPGGA':
  66. if len(data) >= 6 and data[5] in ("1", "2", "6"):
  67. t = self.__time_from_seg(data[0])
  68. self.__set_lat(data[1], data[2], t)
  69. self.__set_long(data[3], data[4], t)
  70. if self.__satellites < 0 and self.__seg_set(data, 6):
  71. self.__satellites = int(data[6])
  72. if self.__seg_set(data, 7):
  73. self.__alt = Distance(data[7], "M", t)
  74. if self.__seg_set(data, 8):
  75. self.__height = Distance(data[8], "M", t)
  76. elif msgid == b'$GPGLL':
  77. if len(data) >= 6 and data[5] == "A":
  78. t = self.__time_from_seg(data[4])
  79. self.__set_lat(data[0], data[1], t)
  80. self.__set_long(data[2], data[3], t)
  81. elif msgid == b'$GPRMC':
  82. if len(data) >= 6 and data[1] == "A":
  83. t = self.__time_from_seg(data[0])
  84. self.__set_lat(data[2], data[3], t)
  85. self.__set_long(data[4], data[5], t)
  86. self.__set_speed(data[6], "N", t)
  87. self.__set_course(data[7], t)
  88. elif msgid == b'$GPVTG':
  89. if len(data) >= 7 and data[2] == "T":
  90. self.__set_speed(data[4], data[6], (0, 0, 0.0))
  91. self.__set_course(data[5], data[0], (0, 0, 0.0))
  92. elif msgid == b'$GPGSV':
  93. if self.__seg_set(data, 2) and data[0] == data[1]:
  94. self.__satellites = int(data[2])
  95. elif msgid == b'$GPMSS':
  96. pass
  97. self.__valid = False if self.__lat is None or self.__long is None else True
  98. return self.valid()
  99. def valid(self):
  100. return self.__valid
  101. def __seg_set(self, d, i):
  102. return len(d) >= (i + 1) and len(d[i]) != 0
  103. def __set_speed(self, v, u, t):
  104. if len(v) == 0:
  105. return None
  106. if self.__speed is None or self.__speed.time() < t:
  107. self.__speed = Speed(v, u, t)
  108. def __set_course(self, v, t):
  109. if len(v) == 0:
  110. return None
  111. print("Course", v, t)
  112. if self.__course is None or self.__course.time() < t:
  113. self.__course = Course(v, t)
  114. def __set_lat(self, v, d, t):
  115. if len(v) == 0:
  116. return None
  117. if self.__lat is None or self.__lat.time() < t:
  118. self.__lat = Position(float(v[0:2]) + (float(v[2:]) / 60), d, t)
  119. def __set_long(self, v, d, t):
  120. if len(v) == 0:
  121. return None
  122. if self.__long is None or self.__long.time() < t:
  123. self.__long = Position(float(v[0:3]) + (float(v[3:]) / 60), d, t)
  124. def __time_from_seg(self, ts):
  125. return (int(ts[0:2]), int(ts[2:4]), float(ts[4:]))
  126. class Data(object):
  127. def __init__(self, pins=("P3", "P4"), baud=9600):
  128. self.__com = machine.UART(1, pins=pins, baudrate=baud)
  129. self.__location = None
  130. self.__last_update = time.time()
  131. def new_location(self, ttw=5):
  132. if time.time() - (self.__last_update + ttw) < 0:
  133. return False
  134. self.__data = Location()
  135. data = []
  136. while self.__com.any():
  137. tmp_data = self.__com.readline()
  138. if tmp_data[0:1] == b'$':
  139. self.__update(data)
  140. data = [tmp_data]
  141. elif len(data) != 0:
  142. data.append(tmp_data)
  143. else:
  144. self.__update(data)
  145. return self.__data.valid()
  146. def get_location(self):
  147. return self.__data
  148. def __update(self, data):
  149. if len(data) == 0:
  150. return False
  151. data = b''.join(data)
  152. if data[len(data)-1:len(data)] not in (b'\n', b'\r'):
  153. return False
  154. if data[len(data)-1:len(data)] != b'\n':
  155. data += '\n'
  156. if self.__data.set(data[0:6], ("%s" % (data[7:len(data)-2],))[2:-1]):
  157. self.__last_update = time.time()