1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/boo0ood-NMEA_GPS_parse

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README.md 11 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 30.11.2024 06:47 feff685
// 定位模式(选择2D/3D),A=自动选择,M=手动选择
unsigned char mode_123;           // 定位类型,1=未定位,2=2D定位,3=3D定位
double pdop;                      // PDOP综合位置精度因子(0.5 - 99.9)
double hdop;                      // HDOP水平精度因子(0.5 - 99.9)
double vdop;                      // VDOP垂直精度因子(0.5 - 99.9)
GSA_PRN *gsa_prn;                 // 存放信道信息
}GSA;

Функция анализа данных GSA:

// Функция получения данных канала GSA из поля данных GPS, поскольку количество полей GSA в одном кадре данных GPS не одинаково, необходимо передать исходные данные GPS и найти все поля GSA.
static GSA_PRN* get_prn_data(char *gps_data) {
    GSA_PRN *gsa_prn;
    unsigned char times = 0;
    unsigned char i;
    unsigned char sentences_index = 0;  // подсчёт количества найденных полей gsa
    // поле данных, разделённое на предложения
    char *p;
    // скопированное предложение
    char *s;
    // извлечённое поле данных
    char *sentences;
    // количество предложений gsa
    int gsa_count;

    // подсчитать количество полей gsa
    gsa_count = strstr_cnt(gps_data, PRE_GSA);

    // динамически выделить память в соответствии с количеством полей gsa
    gsa_prn = (GSA_PRN *)malloc(sizeof(GSA_PRN) * (gsa_count * 12 + 1));
    memset(gsa_prn, 0, sizeof(GSA_PRN) * (gsa_count * 12 + 1));
    // разделить исходные данные
    sentences = strtok(gps_data, "\r\n");
    while (sentences) {
        // определить, является ли разделенное предложение полем gsa
        if (strstr(sentences, PRE_GSA)) {
            // увеличить на 1 при обнаружении поля gsa
            sentences_index++;
            s = strdup(sentences);
            // начать разделение предложения
            p = strsplit(&s, ",");
            while (p) {
                if (times == 2) {
                    // каждое поле gsa содержит 12 спутниковых данных
                    for (i = 0; i < 12; i++) {
                        p = strsplit(&s, ",");
                        (gsa_prn + i + (sentences_index - 1) * 12)->total = (unsigned char)gsa_count * 12;
                        (gsa_prn + i + (sentences_index - 1) * 12)->prn_ID = i + (sentences_index - 1) * 12;
                        (gsa_prn + i + (sentences_index - 1) * 12)->prn = (unsigned char)strtol(p, NULL, 10);
                    }
                }
                // продолжить разделение следующего предложения
                p = strsplit(&s, ",");
                times++;
            }
            times = 0;
        }
        // продолжить разделение следующих исходных данных
        sentences = strtok(NULL, "\r\n");
    }
    free(s);
    return gsa_prn;
}
// Анализ данных GSA
// gsa_data: входные данные GSA
// gpsdata: входные данные GPS
static GSA gsa_data_parse(char *gsa_data, char *gpsdata) {
    GSA gsa;
    unsigned char times = 0;
    char *p;
    char *end;
    // скопировать данные gsa в s для разделения
    char *s = strdup(gsa_data);
    // сделать копию исходных данных
    char *alldata = strdup(gpsdata);

    p = strsplit(&s, ",");
    while (p) {
        switch (times) {
            case 1:   // mode_MA
                gsa.mode_MA = p[0];
                break;
            case 2:   // mode_123
                gsa.mode_123 = p[0];
                break;
            case 3:   // prn
                // получить информацию PRN всех полей GSA, передать исходные данные GPS
                gsa.gsa_prn = get_prn_data(alldata);
                break;
            case 15:  // pdop
                gsa.pdop = strtod(p, NULL);
                break;
            case 16:  // hdop
                gsa.hdop = strtod(p, NULL);
                break;
            case 17:  // vdop
                // извлечь последний элемент данных
                end = (char *)malloc(sizeof(p));
                strncpy(end, p, strlen(p)-3);
                end[strlen(p)-3] = '\0';
                gsa.vdop = strtod(end, NULL);
                free(end);
            default:
                break;
        }
        p = strsplit(&s, ",");
        times++;
    }
    free(s);
    return gsa;
}

Анализ структуры данных GSV

// Структура данных видимого спутника
typedef struct {
    unsigned char prn;                // код PRN (псевдослучайный код шума)
    unsigned char elev;               // угол возвышения спутника (00 - 90) градусов
    short azimuth;                    // азимут спутника (00 - 359) градусов
    unsigned char SNR;                // отношение сигнал-шум
}SAT_INFO;
#pragma pack()

// Структуры данных GSV (видимые спутники)
typedef struct {
    unsigned char msgs;               // общее количество полей GSV в этом сообщении (1 - 3)
    unsigned char msg;                // это поле GSV является каким по счёту в этом сообщении (1 - 3)
    unsigned char sats;               // текущее количество видимых спутников (00 - 12)
    SAT_INFO *sat_info;               // информация о спутниках
}GSV;

Функция анализа GSV:

/*
 * function: получение информации GPS из поля GSV
 * gps_data:
 */
``` ```
Самый исходный GPS-строка, используемая для поиска всех GSV-операторов:
* stas: количество спутников;
* prefix: префикс поля информации GSV.

static SAT_INFO *get_sats_info(char *gps_data, unsigned char sats, char *prefix) {
    SAT_INFO *sats_info;
    unsigned char times = 0;
    // Сохраняем общее количество операторов GSV
    unsigned char msgs = 0;
    // Записываем текущий номер оператора GSV
    unsigned char msg = 0;
    // Храним вычисленное количество итераций цикла for
    unsigned char for_times;
    unsigned char i;
    // Поле оператора, полученное путём разделения
    char *p;
    // Копируем одну копию оператора для удобства разделения
    char *s;
    // Оператор, извлечённый из исходных данных
    char *sentences;

    sats_info = (SAT_INFO *)malloc(sizeof(SAT_INFO) * (sats+1));
    memset(sats_info, 0, sizeof(SAT_INFO) * (sats+1));
    sentences = strtok(gps_data, "\r\n");
    while (sentences) {
        if (strstr(sentences, prefix)) {
            s = strdup(sentences);
            p = strsplit(&s, ",");
            while (p) {
                switch (times) {
                    case 1: // msgs
                        msgs = (unsigned char) strtol(p, NULL, 10);
                        break;
                    case 2: // msg
                        msg = (unsigned char) strtol(p, NULL, 10);
                        break;
                    case 3: // sat info
                        // Вычисляем количество информации об операторе GSV в этом операторе, то есть количество итераций в цикле for
                        for_times = (msgs == msg) ? ((sats % 4) ? sats % 4 : 4) : 4;
                        for (i = 0; i < for_times; i++) {
                            // Начиная с четвёртого поля, каждые четыре сегмента представляют информацию о спутнике
                            p = strsplit(&s, ",");
                            (sats_info+(msg-1)*4+i)->prn = (unsigned char) strtol(p, NULL, 10);
                            p = strsplit(&s, ",");
                            (sats_info+(msg-1)*4+i)->elev = (unsigned char) strtol(p, NULL, 10);
                            p = strsplit(&s, ",");
                            (sats_info+(msg-1)*4+i)->azimuth = (unsigned short) strtol(p, NULL, 10);
                            p = strsplit(&s, ",");
                            (sats_info+(msg-1)*4+i)->SNR = (unsigned char) strtol(p, NULL, 10);
                        }
                        break;
                    default:
                        break;
                }
                p = strsplit(&s, ",");
                times++;
            }
            times = 0;
        }
        // Разделяем следующий оператор
        sentences = strtok(NULL, "\r\n");
    }
    free(s);
    return sats_info;
}

// Анализ данных GSV
// gsv_data: оператор GSV, используемый для извлечения общего количества операторов GSV и количества спутников
// gps_data: исходные данные GPS, используемые для поиска всех операторов GSV в функции get_sats_info
// prefix: Префикс оператора GSV. В зависимости от различных методов позиционирования, в группе данных GPS могут быть GPGSV, GLGSV и GNSSV. Передайте по мере необходимости
static GSV gsv_data_parse(char *gsv_data, char *gps_data, char *prefix) {
    GSV gsv;
    unsigned char times = 0;
    char *p;
    char *s = strdup(gsv_data);
    char *src_data = strdup(gps_data);

    p = strsplit(&s, ",");
    while (p) {
        switch (times) {
            case 1: // msgs
                gsv.msgs = (unsigned char)strtol(p, NULL, 10);
                break;
            case 2: // msg
                gsv.msg = (unsigned char)strtol(p, NULL, 10);
                break;
            case 3: // sats
                gsv.sats = (unsigned char)strtol(p, NULL, 10);
                // Получаем всю информацию об операторах GSV во всех операторах. Введите исходные данные GPS, количество спутников и идентификатор оператора GSV
                gsv.sat_info = get_sats_info(src_data, gsv.sats, prefix);
                break;
            default:
                break;
        }
        p = strsplit(&s, ",");
        times++;
    }
    free(s);
    return gsv;
}```

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/boo0ood-NMEA_GPS_parse.git
git@api.gitlife.ru:oschina-mirror/boo0ood-NMEA_GPS_parse.git
oschina-mirror
boo0ood-NMEA_GPS_parse
boo0ood-NMEA_GPS_parse
master