Как синхронизировать вывод предложений NMEA gps

#c #gps #nmea

#c #gps #nmea

Вопрос:

У меня есть две функции :

 string get_GPGGA() {
// read_gga_sentence extract only gga
return gps.read_gga_sentence();
}

string get_GPGSA() {
// read_gsa_sentence extract only gsa
return gps.read_gsa_sentence();
}

int main() {
    while(true) {
    cout << get_GPGGA();
    cout << get_GPGSA();
    }
}
 

Проблема в том, что GPS-модуль передает 4 предложения за одну секунду. Поэтому, когда я в первый раз вызываю read_gga_sentence(), я отбросил все остальные предложения и сохранил gga. и то же самое с read_gsa_sentence. Но я обнаружил, что это создает задержку в моей программе, потому что, как только я вызываю первый get_GPGGA() , он ждет 1 секунду, а затем я могу вызвать get_GPGSA(). Тем не менее, я хочу иметь возможность распечатать их все за одну и ту же 1 секунду

Нужна ли мне здесь многопоточность?

Ответ №1:

Вам не нужна многопоточность, просто буферизация и функция gps.Read() . Какую библиотеку вы используете?

Сообщения GPS основаны на тексте / строке:

 $GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76
$GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A
$GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70
$GPGSV,3,2,11,02,39,223,19,13,28,070,17,26,23,252,,04,14,186,14*79
$GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76
$GPRMC,092750.000,A,5321.6802,N,00630.3372,W,0.02,31.66,280511,,,A*43
$GPGGA,092751.000,5321.6802,N,00630.3371,W,1,8,1.03,61.7,M,55.3,M,,*75
$GPGSA,A,3,10,07,05,02,29,04,08,13,,,,,1.72,1.03,1.38*0A
$GPGSV,3,1,11,10,63,137,17,07,61,098,15,05,59,290,20,08,54,157,30*70
$GPGSV,3,2,11,02,39,223,16,13,28,070,17,26,23,252,,04,14,186,15*77
$GPGSV,3,3,11,29,09,301,24,16,09,020,,36,,,*76
$GPRMC,092751.000,A,5321.6802,N,00630.3371,W,0.06,31.66,280511,,,A*45
 

Прочитайте их и сохраните каждую строку в буфере.
Затем прочитайте ваш буфер, начиная с конца, и найдите последнее сообщение GGA.

Ваш код может быть чем-то вроде

 // wait 1 GPS message
string get_GPGGA() {
buffer.add(gps.Read()); 
// read_gga_sentence extract only gga
return buffer.read_last_gga_sentence();
}

string get_GPGSA() {
// Wait 1 GPS message
buffer.add(gps.Read()); 
// read_gsa_sentence extract last gsa
return buffer.read_gsa_sentence();
}

int main() {
    while(true) {
    cout << get_GPGGA();
    cout << get_GPGSA();
    }
}
 

Создайте класс GPSBuffer

 class GPSBuffer {
   void add(string msg);
   string read_last_gga_sentence();
   string read_last_gga_sentence();
} buffer;
 

Комментарии:

1. Я получаю их из собственной библиотеки win32 api через последовательный com. но у меня есть вопрос, я должен обновлять gps.Read() каждый раз, когда я хочу получить какую-либо строку, куда мне поместить этот gps.Read()? Я не хочу помещать его в основную функцию, я хочу, чтобы он был скрыт, и все, что мне нужно, это get_GPGGA