1

I have written some C/C++ code including this NMEA library to parse data incoming from a gps device.

#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <thread>

#include <nmea/nmea.h>

#include "GPSDevice.h"

using namespace std;

bool debugverbose = true;
void debug(string message) {
    if(debugverbose)
        cout << "[ DEBUG ] " << message << endl;
}

bool errorverbose = true;
void error(string message) {
    if(errorverbose)
        cout << "[ ERROR ] " << message << endl;
    exit(-1);
}

GPSDevice gpsDevice;

nmeaINFO nmeainfo;
nmeaPARSER nmeaparser;

nmeaPOS nmeapos;

void nmeatrace(const char *str, int str_size) {
    printf("[ NMEA TRACE ] ");
    write(1, str, str_size);
    printf("\n");
}

void nmeaerror(const char *str, int str_size) {
    printf("[ NMEA ERROR ] ");
    write(1, str, str_size);
    printf("\n");
}

int main(int argc, char *argv[]) {
    // open gps device
    debug("opening gps device");
    GPSDevice gpsDevice("/dev/ttyO3");
    if(!(gpsDevice.openport()))
        error("gpsDevice.openport()");

    // set up nmea parser
    debug("setting up nmea parser");
    nmea_property()->trace_func = &nmeatrace;
    nmea_property()->error_func = &nmeaerror;

    nmea_zero_INFO(&nmeainfo);
    nmea_parser_init(&nmeaparser);

    // read nmea data
    debug("reading nmea data");
    for(;;) {
        string data = gpsDevice.readline();
        debug(data);

        // nmea_parser expects \r\n
        data += "\r\n";

        // parse nmea data
        nmea_parse(&nmeaparser, data.c_str(), (int) strlen(data.c_str()), &nmeainfo);

        // get position
        nmea_info2pos(&nmeainfo, &nmeapos);

        cout << "Lat: " << nmeapos.lat << endl;
        cout << "Lon: " << nmeapos.lon << endl;
    }

    // destroy parser
    debug("destroying parser");
    nmea_parser_destroy(&nmeaparser);

    // close gps device
    debug("closing gps device");
    gpsDevice.closeport();

    return 0;
}

The gpsDevice successfully reads the incoming data, but after parsing it, the nmeaINFO object is still empty. I attached an excerpt of my program's output.

[ DEBUG ] opening gps device
[ DEBUG ] setting up nmea parser
[ DEBUG ] reading nmea data
[ DEBUG ] $GPGGA,132431.000,5222.8791,N,01032.3533,E,1,11,0.78,84.2,M,46.9,M,,*56
Lat: 0
Lon: 0
[ DEBUG ] $GPGSA,A,3,13,07,23,16,08,09,20,29,10,04,02,,1.07,0.78,0.73*03
Lat: 0
Lon: 0
[ DEBUG ] $GPRMC,132431.000,A,5222.8791,N,01032.3533,E,0.55,318.66,010214,,,A*62
Lat: 0
Lon: 0
[ DEBUG ] $GPVTG,318.66,T,,M,0.55,N,1.01,K,A*37
Lat: 0
Lon: 0
[ DEBUG ] $GPGGA,132432.000,5222.8787,N,01032.3540,E,1,11,0.78,84.0,M,46.9,M,,*54
Lat: 0
Lon: 0
...

I hope you can help me.

Edit(working sample code):

/* gpslog.txt */
$PSRFTXTVersion GSW3.2.1PAT_3.1.00.12-SDK001P1.00c *3F
$PSRFTXTHTC GPS_ART_321000_GEN*20
$PSRFTXTTOW:  258712*32
$PSRFTXTWK:   1412*4F
$PSRFTXTPOS:  1518885 -4470072 4274168*24
$PSRFTXTCLK:  94817*02
$PSRFTXTCHNL: 12*5F
$PSRFTXTBaud rate: 57600 *51
$GPGGA,213638.949,,,,,0,00,,,M,0.0,M,,0000*5F
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,213638.949,V,,,,,,,010207,,,N*40
$GPGGA,213639.897,,,,,0,00,,,M,0.0,M,,0000*5C
...

/* nmealib/samples/parse_file/main.c */
#include <nmea/nmea.h>

#include <string.h>
#include <stdio.h>

#ifdef NMEA_WIN
#   include <io.h>
#endif

void trace(const char *str, int str_size)
{
    printf("Trace: ");
    write(1, str, str_size);
    printf("\n");
}
void error(const char *str, int str_size)
{
    printf("Error: ");
    write(1, str, str_size);
    printf("\n");
}

int main()
{
    nmeaINFO info;
    nmeaPARSER parser;
    FILE *file;
    char buff[2048];
    int size, it = 0;
    nmeaPOS dpos;

    file = fopen("gpslog.txt", "rb");

    if(!file)
        return -1;

    nmea_property()->trace_func = &trace;
    nmea_property()->error_func = &error;

    nmea_zero_INFO(&info);
    nmea_parser_init(&parser);

    /*
    while(1)
    {
    */

    while(!feof(file))
    {
        size = (int)fread(&buff[0], 1, 100, file);

        nmea_parse(&parser, &buff[0], size, &info);

        nmea_info2pos(&info, &dpos);

        printf(
            "%03d, Lat: %f, Lon: %f, Sig: %d, Fix: %d\n",
            it++, dpos.lat, dpos.lon, info.sig, info.fix
            );
    }

    fseek(file, 0, SEEK_SET);

    /*
    }
    */

    nmea_parser_destroy(&parser);
    fclose(file);

    return 0;
}
raptor
  • 760
  • 7
  • 18
  • Suggest that you check the result returned by `nmea_parse`. Also consider simplifying your program to a single test to track down the issue: const char *gpsData = "$GPRMC,111609.14,A,5001.27,N,3613.06,E,11.2,0.0,261206,0.0,E*50\r\n"; nmea_parse(&nmeaparser, gpsData, (int)strlen(gpsData), &nmeainfo); Does this work? – mockinterface Feb 03 '14 at 11:03
  • Thank you for your answer! The value returned by nmea_parse is 0. Instead of simplifying my code I compiled one of the samples with simple sentences and it worked. I am going attach the sample to my answer to compare both. – raptor Feb 03 '14 at 13:37
  • The sample working NMEA example, does not contain any coordinates. Look at the RMC line: ",,,,,,". So just enable your debugger, and look step by step what happens. – AlexWien Feb 03 '14 at 15:17
  • It is just an excerpt of the whole gpslog.txt. – raptor Feb 03 '14 at 15:51
  • Check the code of nmea_parse: Use a NMEa file with one sentence only: the RMC sentence. Check if it works, if not, there are two nmea versions, where in RMC was one attribute added: Count the number of attributes in the nmea file, and count the number that nmea_parse tries to parse for RMC msg. – AlexWien Feb 06 '14 at 17:25

1 Answers1

0

There is nothing wrong with the code itself. I've replaced the gpsDevice.readline() with a constant string from your output, and I get the following:

[ DEBUG ] opening gps device
[ DEBUG ] setting up nmea parser
[ DEBUG ] reading nmea data
[ DEBUG ] $GPRMC,132431.000,A,5222.8791,N,01032.3533,E,0.55,318.66,010214,,,A*62

[ NMEA TRACE ] $GPRMC,132431.000,A,5222.8791,N,01032.3533,E,0.55,318.66,010214,,,A*62

Lat: 0.914226
Lon: 0.183944

Notice that there are additional line ends in my output which are missing in yours. The GPS string has \r\n appended and you printf \n in addition, total of two line endings. The difference in line endings makes me suspicious that your string is wrongly parsed with your particular build/version of nmealib. Try rebuilding the nmea library from source and add additional debugging info.

mockinterface
  • 14,452
  • 5
  • 28
  • 49
  • Thank you for your response. I tried compiling my code and the library with another toolchain. But I am getting errors caused by calculation with floating points. I am compiling for an arm processor which needs some floating point optimization. I think this is the mistake. – raptor Feb 08 '14 at 16:58