Skip to content
This repository has been archived by the owner on May 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #28 from 107-systems/fix-sign-magnetic-deviation
Browse files Browse the repository at this point in the history
Bugfix: Decode magnetic variation indicator.
  • Loading branch information
aentinger authored Nov 24, 2020
2 parents 359f331 + fae2119 commit b608ca8
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 41 deletions.
20 changes: 10 additions & 10 deletions extras/test/src/test_GxGGA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ SCENARIO("Extracting satellite system from valid GxGGA message", "[GxGGA-01]")
WHEN("GPS")
{
std::string const GPGGA = "$GPGGA,111908.952,4838.0060,N,01301.5895,E,1,05,2.4,454.7,M,46.6,M,0.0,0000*7A\r\n";
nmea::GxGGA::parse(GPGGA.c_str(), data);
nmea::GxGGA::parse(const_cast<char *>(GPGGA.c_str()), data);
REQUIRE(data.source == nmea::GgaSource::GPS);
}
}

TEST_CASE("Extracting position time from valid GxGGA message", "[GxGGA-02]")
{
std::string const GPGGA = "$GPGGA,111908.952,4838.0060,N,01301.5895,E,1,05,2.4,454.7,M,46.6,M,0.0,0000*7A\r\n";
nmea::GxGGA::parse(GPGGA.c_str(), data);
nmea::GxGGA::parse(const_cast<char *>(GPGGA.c_str()), data);
REQUIRE(data.time_utc.hour == 11);
REQUIRE(data.time_utc.minute == 19);
REQUIRE(data.time_utc.second == 8);
Expand All @@ -50,7 +50,7 @@ TEST_CASE("Extracting position time from valid GxGGA message", "[GxGGA-02]")
SCENARIO("Extracting latitude/longiture from valid GPGGA message", "[GxGGA-03]")
{
std::string const GPGGA = "$GPGGA,111908.952,4838.0060,N,01301.5895,E,1,05,2.4,454.7,M,46.6,M,0.0,0000*7A\r\n";
nmea::GxGGA::parse(GPGGA.c_str(), data);
nmea::GxGGA::parse(const_cast<char *>(GPGGA.c_str()), data);
REQUIRE(data.latitude == Approx(48.633433));
REQUIRE(data.longitude == Approx(13.026492));
}
Expand All @@ -60,49 +60,49 @@ TEST_CASE("Extracting fix quality angle from valid GxGGA message", "[GxGGA-04]")
WHEN("GPS Fix")
{
std::string const GPGGA = "$GPGGA,111908.952,4838.0060,N,01301.5895,E,1,05,2.4,454.7,M,46.6,M,0.0,0000*7A\r\n";
nmea::GxGGA::parse(GPGGA.c_str(), data);
nmea::GxGGA::parse(const_cast<char *>(GPGGA.c_str()), data);
REQUIRE(data.fix_quality == nmea::FixQuality::GPS_Fix);
}
}

SCENARIO("Extracting number of satellites from valid GPGGA message", "[GxGGA-05]")
{
std::string const GPGGA = "$GPGGA,111908.952,4838.0060,N,01301.5895,E,1,05,2.4,454.7,M,46.6,M,0.0,0000*7A\r\n";
nmea::GxGGA::parse(GPGGA.c_str(), data);
nmea::GxGGA::parse(const_cast<char *>(GPGGA.c_str()), data);
REQUIRE(data.num_satellites == 5);
}

SCENARIO("Extracting horizontal dilution of precision from valid GPGGA message", "[GxGGA-06]")
{
std::string const GPGGA = "$GPGGA,111908.952,4838.0060,N,01301.5895,E,1,05,2.4,454.7,M,46.6,M,0.0,0000*7A\r\n";
nmea::GxGGA::parse(GPGGA.c_str(), data);
nmea::GxGGA::parse(const_cast<char *>(GPGGA.c_str()), data);
REQUIRE(data.hdop == Approx(2.4));
}

SCENARIO("Extracting altitude from valid GPGGA message", "[GxGGA-07]")
{
std::string const GPGGA = "$GPGGA,111908.952,4838.0060,N,01301.5895,E,1,05,2.4,454.7,M,46.6,M,0.0,0000*7A\r\n";
nmea::GxGGA::parse(GPGGA.c_str(), data);
nmea::GxGGA::parse(const_cast<char *>(GPGGA.c_str()), data);
REQUIRE(data.altitude == Approx(454.7));
}

SCENARIO("Extracting geoidal separation from valid GPGGA message", "[GxGGA-08]")
{
std::string const GPGGA = "$GPGGA,111908.952,4838.0060,N,01301.5895,E,1,05,2.4,454.7,M,46.6,M,0.0,0000*7A\r\n";
nmea::GxGGA::parse(GPGGA.c_str(), data);
nmea::GxGGA::parse(const_cast<char *>(GPGGA.c_str()), data);
REQUIRE(data.geoidal_separation == Approx(46.6));
}

SCENARIO("Extracting time since last DGPS update from valid GPGGA message", "[GxGGA-09]")
{
std::string const GPGGA = "$GPGGA,111908.952,4838.0060,N,01301.5895,E,1,05,2.4,454.7,M,46.6,M,0.0,0000*7A\r\n";
nmea::GxGGA::parse(GPGGA.c_str(), data);
nmea::GxGGA::parse(const_cast<char *>(GPGGA.c_str()), data);
REQUIRE(data.dgps_age == Approx(0.0));
}

SCENARIO("Extracting DGPS station id from valid GPGGA message", "[GxGGA-10]")
{
std::string const GPGGA = "$GPGGA,111908.952,4838.0060,N,01301.5895,E,1,05,2.4,454.7,M,46.6,M,0.0,0000*7A\r\n";
nmea::GxGGA::parse(GPGGA.c_str(), data);
nmea::GxGGA::parse(const_cast<char *>(GPGGA.c_str()), data);
REQUIRE(strncmp(data.dgps_id, "0000", 4) == 0);
}
26 changes: 13 additions & 13 deletions extras/test/src/test_GxRMC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ SCENARIO("Extracting latitude/longiture from valid GPRMC message", "[GxRMC-01]")
{
std::string const GPRMC = "$GPRMC,062101.714,A,5001.869,N,01912.114,E,955535.7,116.2,290520,000.0,W*45\r\n";

nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);

REQUIRE(data.latitude == Approx(50.03114442));
REQUIRE(data.longitude == Approx(19.20189679));
Expand All @@ -43,7 +43,7 @@ SCENARIO("Extracting latitude/longiture from valid GPRMC message", "[GxRMC-01]")
{
std::string const GPRMC = "$GPRMC,122311.239,A,4056.748,N,11212.614,W,,,290620,000.0,W*63\r\n";

nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);

REQUIRE(data.latitude == Approx(40.9458060446613));
REQUIRE(data.longitude == Approx(-112.210235595703));
Expand All @@ -53,7 +53,7 @@ SCENARIO("Extracting latitude/longiture from valid GPRMC message", "[GxRMC-01]")
{
std::string const GPRMC = "$GPRMC,122311.239,A,2727.069,S,05859.190,W,,,290620,000.0,W*76\r\n";

nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);

REQUIRE(data.latitude == Approx(-27.4511422937699));
REQUIRE(data.longitude == Approx(-58.986502289772));
Expand All @@ -63,7 +63,7 @@ SCENARIO("Extracting latitude/longiture from valid GPRMC message", "[GxRMC-01]")
{
std::string const GPRMC = "$GPRMC,122311.239,A,0610.522,S,10649.632,E,,,290620,000.0,W*6D\r\n";

nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);

REQUIRE(data.latitude == Approx(-6.17536097471491));
REQUIRE(data.longitude == Approx(106.827192306519));
Expand All @@ -75,13 +75,13 @@ SCENARIO("Extracting satellite system from valid GxRMC message", "[GxRMC-02]")
WHEN("GPS")
{
std::string const GPRMC = "$GPRMC,122311.239,A,0610.522,S,10649.632,E,,,290620,000.0,W*6D\r\n";
nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);
REQUIRE(data.source == nmea::RmcSource::GPS);
}
WHEN("GNSS")
{
std::string const GNSS = "$GNRMC,090348.80,A,4838.00682,N,01301.61381,E,1.533,,301020,,,A*61\r\n";
nmea::GxRMC::parse(GNSS.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GNSS.c_str()), data);
REQUIRE(data.source == nmea::RmcSource::GNSS);
}
}
Expand All @@ -90,7 +90,7 @@ TEST_CASE("Extracting speed over ground from valid GPRMC message", "[GxRMC-03]")
{
std::string const GPRMC = ("$GPRMC,052856.105,A,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n");

nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);

/* 85.7 kts ~= 44.088 m/s */
REQUIRE(data.speed == Approx(44.088f));
Expand All @@ -100,7 +100,7 @@ TEST_CASE("Extracting track angle from valid GPRMC message", "[GxRMC-04]")
{
std::string const GPRMC = ("$GPRMC,052856.105,A,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n");

nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);

REQUIRE(data.course == Approx(206.4f));
}
Expand All @@ -109,7 +109,7 @@ TEST_CASE("Extracting position time from valid GPRMC message", "[GxRMC-05]")
{
std::string const GPRMC = ("$GPRMC,052856.105,A,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n");

nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);

/* 052856.105 -> 05:28:56.105 -> */
REQUIRE(data.time_utc.hour == 5);
Expand All @@ -122,7 +122,7 @@ TEST_CASE("Extracting date from valid GPRMC message", "[GxRMC-06]")
{
std::string const GPRMC = ("$GPRMC,052856.105,A,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n");

nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);

REQUIRE(data.date.day == 8);
REQUIRE(data.date.month == 7);
Expand All @@ -133,7 +133,7 @@ TEST_CASE("Extracting magnetic variation from valid GPRMC message", "[GxRMC-07]"
{
std::string const GPRMC = ("$GPRMC,052856.105,A,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n");

nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);

REQUIRE(data.magnetic_variation == Approx(0.0));
}
Expand All @@ -142,7 +142,7 @@ TEST_CASE("Extracted status indicates void ('V') position data", "[GxRMC-08]")
{
std::string const GPRMC = ("$GPRMC,052856.105,V,5230.874,N,01321.056,E,085.7,206.4,080720,000.0,W*78\r\n");

nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);

REQUIRE(data.is_valid == false);
}
Expand All @@ -151,7 +151,7 @@ TEST_CASE("GxRMC message contains only date and time, but no location fix yet ",
{
std::string const GPRMC = ("$GPRMC,144602.00,V,,,,,,,011120,,,N*7B\r\n");

nmea::GxRMC::parse(GPRMC.c_str(), data);
nmea::GxRMC::parse(const_cast<char *>(GPRMC.c_str()), data);

/* RMC TIME = '144602.00' */
REQUIRE(data.time_utc.hour == 14);
Expand Down
8 changes: 4 additions & 4 deletions src/nmea/GxGGA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,19 @@ namespace nmea
* PUBLIC MEMBER FUNCTIONS
**************************************************************************************/

void GxGGA::parse(char const * gxgga, GgaData & data)
void GxGGA::parse(char * gxgga, GgaData & data)
{
ParserState state = ParserState::MessadeId;

/* Replace the '*' sign denoting the start of the checksum
* with a ',' in order to be able to tokenize all elements
* including the one before the checksum.
*/
*strchr((char *)gxgga, '*') = ',';
*strchr(gxgga, '*') = ',';

for (char * token = strsep((char **)&gxgga, ",");
for (char * token = strsep(&gxgga, ",");
token != nullptr;
token = strsep((char **)&gxgga, ","))
token = strsep(&gxgga, ","))
{
ParserState next_state = state;

Expand Down
2 changes: 1 addition & 1 deletion src/nmea/GxGGA.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class GxGGA

public:

static void parse(char const * gxgga, GgaData & data);
static void parse(char * gxgga, GgaData & data);

private:

Expand Down
21 changes: 9 additions & 12 deletions src/nmea/GxRMC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,20 @@ constexpr float kts_to_m_per_s(float const v) { return (v / 1.9438444924574f); }
* PUBLIC MEMBER FUNCTIONS
**************************************************************************************/

void GxRMC::parse(char const * gprmc, RmcData & data)
void GxRMC::parse(char * gxrmc, RmcData & data)
{
ParserState state = ParserState::MessadeId;

for (char * token = strsep((char **)&gprmc, ",");
/* Replace the '*' sign denoting the start of the checksum
* with a ',' in order to be able to tokenize all elements
* including the one before the checksum.
*/
*strchr(gxrmc, '*') = ',';

for (char * token = strsep(&gxrmc, ",");
token != nullptr;
token = strsep((char **)&gprmc, ","))
token = strsep(&gxrmc, ","))
{
/* All GPS receivers should at least implement the the fields: UTC Position Fix,
* Status, Latitude, Longitude, Speed over ground, Track Angle. All other fields
* are optional. Therefore we are checking in the following if statement if the
* current token is a checksum token. If that's the case we are directly jumping
* to ParserState::Checksum.
*/
if (util::isChecksumToken(token))
state = ParserState::Checksum;

ParserState next_state = state;

switch(state)
Expand Down
2 changes: 1 addition & 1 deletion src/nmea/GxRMC.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class GxRMC

public:

static void parse(char const * gprmc, RmcData & data);
static void parse(char * gxrmc, RmcData & data);

private:

Expand Down

0 comments on commit b608ca8

Please sign in to comment.