PySerial буферизация GPS-координат на Raspberry Pi

У меня довольно неприятная проблема, и я совсем новичок в Python/Raspberry pi

У меня есть скрипт, который сопоставляет координаты GPS с отсканированным SSID сканированием iwlist, а затем отправляет полученный файл по электронной почте всякий раз, когда есть соединение Wi-Fi.

Моя проблема в том, что результаты постоянно буферизуются, поэтому координаты GPS могут значительно отличаться от отсканированных SSID.

У меня есть последовательная линия, очищенная в начале цикла while, но, похоже, она не работает. У меня также есть Python, работающий без буферизации (-u, но это может быть только для текстовых файлов..) Я добавил Output.flush(), но я пока не смог его протестировать. Подумал, я бы сначала спросил.

Итак, мой вопрос: есть ли способ отключить буфер последовательной линии, чтобы каждая итерация получала координату GPS в то время, когда выполняется цикл while? Все мои текстовые файлы имеют file.flush() после того, как они были написаны. Должно ли это быть до того, как файлы будут записаны, или это не повлияет на последовательный буфер? Что мне не хватает?

Любая помощь будет оценена

#!/usr/bin/python -u
import os
import gps
import time
import serial
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders

username = 'gmail account'
password = 'account password'

port = serial.Serial("/dev/ttyAMA0", baudrate=9600)

#Setting GPS session, listen on port 2947 (gpsd) of localhost
session = gps.gps("localhost", "2947")
session.stream(gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE)

#Begin GPS and WiFi Scan loop..
while True:

    try:
        port.flushInput()
        #port.flushOutput() commented out because I haven't tested with this yet.
        time.sleep(.5)
        report = session.next()
        #Uncomment below for report data
        #print report
        if report['class'] == 'TPV':
            if hasattr(report, 'lat' and 'lon'):
                #setting GPS variables and strings
                latitude = report.lat
                latString = "%f" %(latitude)
                longitude = report.lon
                lonString = "%f" %(longitude)

        #WiFi scan and parse script. I don't think it is necessary to post,       
        #but if it is, I will. All text files are flushed before being closed

        #Email when connected
        ping = os.system('sudo ping -c4 8.8.8.8')
        try:
            if ping == 0:
                msg = MIMEMultipart()
                msg['Subject'] = "GPS/WiFi data from GPS PILOT"
                msg['From'] = username
                msg['To'] = username

                body = "GPS/WiFi data attached.."

                msg.attach(MIMEText(body, 'plain'))
                part = MIMEBase('application', "octet-stream")
                part.set_payload(open("/home/pi/gpsMaster/dataLog.csv", "rb").read())
                Encoders.encode_base64(part)
                part.add_header('Content-Disposition', 'attachment; filename="GPSWiFi_Scan.csv"')

                msg.attach(part)

                server = smtplib.SMTP('smtp.gmail.com:587')
                server.ehlo()
                server.starttls()
                server.login(username, password)
                server.sendmail(username, username, msg.as_string())
                server.quit()
                os.system("sudo rm /home/pi/gpsMaster/dataLog.csv")
            else:
                pass

        except smtplib.SMTPException:
            os.system('sudo reboot now')

            #Adding loop delay
            time.sleep(10)

    #Loop ending exceptions            
    except KeyError:
        pass
    except IOError:
        print ("ERROR")
        #os.system('sudo reboot now')
    except KeyboardInterrupt:
        quit()
    except StopIteration:
        session = None
        os.system("sudo reboot now")

2 ответа

У меня была похожая проблема. Я исправил, сбрасывая ввод и вывод.

port.flushInput()
port.flushOutput()

Я понимаю, что это старый вопрос, но он все еще актуален, поскольку я столкнулся с той же проблемой. Проблема связана с:

      time.sleep(10)

в основном цикле. Поток gpsd добавляет полученные данные в очередь, доступ к которой осуществляется через:

      report = session.next()

Это означает, что когда вы вытащите следующий образец, со временем он будет все дальше и дальше отклоняться от реальности (вы используете координаты GPS, которые отстают от вашего текущего местоположения). У нас большая очередь, потребитель вытягивает данные гораздо медленнее, чем добавляется из-за 10s sleep. Я получил большое удовольствие, решая эту проблему, и только сократив систему до ее самых необходимых основ, я, наконец, нашел причину. Решение состоит в том, чтобы извлечь данные, как только они станут доступны, но отбросить столько точек данных, сколько необходимо, пока не будет достигнуто время задержки. Это останавливает рассинхронизацию очереди gpsd, поскольку клиент gpsd Python использует их слишком медленно, что вызывает дрейф координат с течением времени.

Псевдокод (его можно отшлифовать, оставив упражнение читателю):

      import time

start = time.time()

while True:
   # Consume the report from the gpsd
   report = session.next()

   # What time is it?
   now = time.time()

   # Magic number of 10s
   if now > (start + 10):

        # use the data contained in report

        # Update with the latest time ready for the next iteration.
        start = now
Другие вопросы по тегам