Skip to content

Commit b443b79

Browse files
authored
unicore: parse AGRICA message, request heading (#140)
* unicore: parse AGRICA message, request heading This add support to parse (but not use) the Unicore AGRICA message. This allows to determine whether we are talking to a UM982 and hence request the heading (UNIHEADINGA) message that we actually require. Signed-off-by: Julian Oes <[email protected]>
1 parent 1de64da commit b443b79

File tree

5 files changed

+85
-3
lines changed

5 files changed

+85
-3
lines changed

gps-parser-test.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,30 @@ void test_uniheadinga_twice()
112112
assert(num_parsed == 2);
113113
}
114114

115+
void test_agrica()
116+
{
117+
const char str[] =
118+
"#AGRICA,68,GPS,FINE,2063,454587000,0,0,18,38;GNSS,236,19,7,26,6,16,9,4,4,12,10,"
119+
"9,306.7191,10724.0176,-"
120+
"16.4796,0.0089,0.0070,0.0181,67.9651,29.3584,0.0000,0.003,0.003,0.001,-"
121+
"0.002,0.021,0.039,0.025,40.07896719907,116.23652055432,67.3108,-"
122+
"2160482.7849,4383625.2350,4084735.7632,0.0140,0.0125,0.0296,0.0107,0.0198,0.012"
123+
"8,40.07627310896,116.11079363322,65.3740,0.00000000000,0.00000000000,0.0000,4"
124+
"54587000,38.000,16.723207,-9.406086,0.000000,0.000000,8,0,0,0*e9402e02";
125+
126+
UnicoreParser unicore_parser;
127+
128+
for (unsigned i = 0; i < sizeof(str); ++i) {
129+
auto result = unicore_parser.parseChar(str[i]);
130+
131+
if (result == UnicoreParser::Result::GotAgrica) {
132+
return;
133+
}
134+
}
135+
136+
assert(false);
137+
}
138+
115139
void test_unicore()
116140
{
117141
test_empty();
@@ -120,6 +144,7 @@ void test_unicore()
120144
test_uniheadinga_wrong_crc();
121145
test_uniheadinga();
122146
test_uniheadinga_twice();
147+
test_agrica();
123148
}
124149

125150
int main(int, char **)

src/nmea.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,11 @@ int GPSDriverNMEA::receive(unsigned timeout)
889889
handled |= handleMessage(l);
890890
}
891891

892-
if (_unicore_parser.parseChar(buf[i]) == UnicoreParser::Result::GotHeading) {
892+
UnicoreParser::Result result = _unicore_parser.parseChar(buf[i]);
893+
894+
if (result == UnicoreParser::Result::GotHeading) {
893895
++handled;
896+
_unicore_heading_received_last = gps_absolute_time();
894897

895898
// Unicore seems to publish heading and standard deviation of 0
896899
// to signal that it has not initialized the heading yet.
@@ -911,6 +914,17 @@ int GPSDriverNMEA::receive(unsigned timeout)
911914
(double)_unicore_parser.heading().heading_deg,
912915
(double)_unicore_parser.heading().heading_stddev_deg,
913916
(double)_unicore_parser.heading().baseline_m);
917+
918+
} else if (result == UnicoreParser::Result::GotAgrica) {
919+
++handled;
920+
921+
// We don't use anything of that message at this point, however, this
922+
// allows to determine whether we are talking to a UM982 and hence
923+
// request the heading (UNIHEADINGA) message that we actually require.
924+
925+
if (gps_absolute_time() - _unicore_heading_received_last > 1000000) {
926+
request_unicore_heading_message();
927+
}
914928
}
915929
}
916930

@@ -945,6 +959,13 @@ void GPSDriverNMEA::handleHeading(float heading_deg, float heading_stddev_deg)
945959
_gps_position->heading_accuracy = heading_stddev_rad;
946960
}
947961

962+
void GPSDriverNMEA::request_unicore_heading_message()
963+
{
964+
// Configure heading message on serial port at 5 Hz. Don't save it though.
965+
uint8_t buf[] = "UNIHEADINGA COM1 0.2\r\n";
966+
write(buf, sizeof(buf) - 1);
967+
}
968+
948969
#define HEXDIGIT_CHAR(d) ((char)((d) + (((d) < 0xA) ? '0' : 'A'-0xA)))
949970

950971
int GPSDriverNMEA::parseChar(uint8_t b)

src/nmea.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ class GPSDriverNMEA : public GPSHelper
7171

7272
private:
7373
void handleHeading(float heading_deg, float heading_stddev_deg);
74+
void request_unicore_heading_message();
7475

7576
UnicoreParser _unicore_parser;
77+
gps_abstime _unicore_heading_received_last;
7678

7779
enum class NMEADecodeState {
7880
uninit,

src/unicore.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@ UnicoreParser::Result UnicoreParser::parseChar(char c)
8787
return Result::WrongStructure;
8888
}
8989

90+
} else if (isAgrica()) {
91+
if (extractAgrica()) {
92+
reset();
93+
return Result::GotAgrica;
94+
95+
} else {
96+
reset();
97+
return Result::WrongStructure;
98+
}
99+
90100
} else {
91101
reset();
92102
return Result::UnknownSentence;
@@ -120,6 +130,13 @@ bool UnicoreParser::isHeading() const
120130
return strncmp(header, _buffer, strlen(header)) == 0;
121131
}
122132

133+
bool UnicoreParser::isAgrica() const
134+
{
135+
const char header[] = "AGRICA";
136+
137+
return strncmp(header, _buffer, strlen(header)) == 0;
138+
}
139+
123140
bool UnicoreParser::extractHeading()
124141
{
125142
// The basline starts after ;,, and then follows the heading.
@@ -158,3 +175,8 @@ bool UnicoreParser::extractHeading()
158175

159176
return false;
160177
}
178+
179+
bool UnicoreParser::extractAgrica()
180+
{
181+
return true;
182+
}

src/unicore.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class UnicoreParser
4444
WrongCrc,
4545
WrongStructure,
4646
GotHeading,
47+
GotAgrica,
4748
UnknownSentence,
4849
};
4950

@@ -55,20 +56,30 @@ class UnicoreParser
5556
float baseline_m;
5657
};
5758

59+
struct Agrica {
60+
};
61+
5862
Heading heading() const
5963
{
6064
return _heading;
6165
}
6266

67+
Agrica agrica() const
68+
{
69+
return _agrica;
70+
}
71+
6372

6473
private:
6574
void reset();
6675
bool crcCorrect() const;
6776
bool isHeading() const;
77+
bool isAgrica() const;
6878
bool extractHeading();
79+
bool extractAgrica();
6980

70-
// We have seen buffers with 154 bytes.
71-
char _buffer[256];
81+
// We have seen buffers with 540 bytes for AGRICA.
82+
char _buffer[600];
7283
unsigned _buffer_pos {0};
7384
char _buffer_crc[9];
7485
unsigned _buffer_crc_pos {0};
@@ -80,4 +91,5 @@ class UnicoreParser
8091
} _state {State::Uninit};
8192

8293
Heading _heading{};
94+
Agrica _agrica{};
8395
};

0 commit comments

Comments
 (0)