59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
|
|
import serial
|
|||
|
|
import pynmea2
|
|||
|
|
import time
|
|||
|
|
from .gnss_utils import current_utc_time
|
|||
|
|
|
|||
|
|
class GNSSModule:
|
|||
|
|
"""
|
|||
|
|
Основной класс для работы с GNSS на Raspberry Pi.
|
|||
|
|
Поддерживает GPS, GLONASS, BeiDou через NMEA-формат.
|
|||
|
|
"""
|
|||
|
|
def __init__(self, port='/dev/ttyAMA0', baudrate=9600, timeout=1):
|
|||
|
|
self.port = port
|
|||
|
|
self.baudrate = baudrate
|
|||
|
|
self.timeout = timeout
|
|||
|
|
self.serial_conn = None
|
|||
|
|
self.last_position = None
|
|||
|
|
|
|||
|
|
def connect(self):
|
|||
|
|
"""Подключение к GNSS модулю"""
|
|||
|
|
try:
|
|||
|
|
self.serial_conn = serial.Serial(
|
|||
|
|
port=self.port,
|
|||
|
|
baudrate=self.baudrate,
|
|||
|
|
timeout=self.timeout
|
|||
|
|
)
|
|||
|
|
print(f"GNSS подключен на {self.port} @ {self.baudrate} бод")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"Ошибка подключения GNSS: {e}")
|
|||
|
|
raise e
|
|||
|
|
|
|||
|
|
def read_position(self):
|
|||
|
|
"""
|
|||
|
|
Считывает NMEA строку, парсит координаты.
|
|||
|
|
Возвращает словарь с lat, lon, alt, timestamp
|
|||
|
|
"""
|
|||
|
|
if self.serial_conn is None or not self.serial_conn.is_open:
|
|||
|
|
raise ConnectionError("GNSS модуль не подключен")
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
line = self.serial_conn.readline().decode('ascii', errors='replace')
|
|||
|
|
if line.startswith('$G'):
|
|||
|
|
msg = pynmea2.parse(line)
|
|||
|
|
if isinstance(msg, pynmea2.GGA):
|
|||
|
|
self.last_position = {
|
|||
|
|
'lat': msg.latitude,
|
|||
|
|
'lon': msg.longitude,
|
|||
|
|
'alt': msg.altitude,
|
|||
|
|
'timestamp': current_utc_time()
|
|||
|
|
}
|
|||
|
|
return self.last_position
|
|||
|
|
except pynmea2.ParseError:
|
|||
|
|
pass
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
def close(self):
|
|||
|
|
if self.serial_conn and self.serial_conn.is_open:
|
|||
|
|
self.serial_conn.close()
|
|||
|
|
print("GNSS соединение закрыто")
|