-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgps.cpp
178 lines (148 loc) · 4.22 KB
/
gps.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#ifndef __UBLOX_GPS
#define __UBLOX_GPS
#include <stdint.h>
#include <stdlib.h>
//Заголовок сообщения UBX
#define UBX_MSG_HEADER_L 0xB5
#define UBX_MSG_HEADER_H 0x62
//Коды сообщений
//UBX-NAV-PVT Navigation Position Velocity Time Solution
#define MSG_ID_UBX_NAV_PVT 0x0701
//Сообщение протокола UBX UBX-NAV-PVT (0x01 0x07)
struct UBX_NAV_PVT
{
uint32_t iTOW;
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t min;
uint8_t sec;
uint8_t valid;
uint32_t tAcc;
int32_t nano;
uint8_t fixType;
uint8_t flags;
uint8_t reserved1;
uint8_t numSV;
int32_t lon;
int32_t lat;
int32_t height;
int32_t hMSL;
uint32_t hAcc;
uint32_t vAcc;
int32_t velN;
int32_t velE;
int32_t velD;
int32_t gSpeed;
int32_t headMot;
uint32_t sAcc;
uint32_t headAcc;
uint16_t pDOP;
uint16_t reserved2;
uint32_t reserved3;
int32_t headVeh;
uint32_t reserved4;
};
namespace GPSDecoderState
{
enum GPSDecoderState
{
Header = 0,
ClassID = 1,
Length = 2,
Payload = 3,
Checksum = 4
};
}
class GPSDecoder
{
public:
GPSDecoderState::GPSDecoderState state;
uint8_t prev_byte;
uint8_t* data;
uint16_t buffer_size;
uint8_t cnt;
uint16_t msg_class_id;
uint16_t msg_length;
uint16_t msg_checksum;
GPSDecoder(uint16_t _buffer_size): state(GPSDecoderState::Header), prev_byte(0), buffer_size(_buffer_size), cnt(0)
{
data = (uint8_t*)malloc(buffer_size);
}
uint16_t process(uint8_t byte)
{
uint16_t result = 0;
if(byte == UBX_MSG_HEADER_H && prev_byte == UBX_MSG_HEADER_L)
{
state = GPSDecoderState::ClassID;
cnt = 0;
}
else
{
if (state != GPSDecoderState::Header)
{
switch(state)
{
case GPSDecoderState::ClassID :
{
data[cnt++] = byte;
if(cnt >= 2)
{
msg_class_id = *((uint16_t*)data);
state = GPSDecoderState::Length;
cnt = 0;
}
break;
}
case GPSDecoderState::Length :
{
data[cnt++] = byte;
if(cnt >= 2)
{
msg_length = *((uint16_t*)data);
state = GPSDecoderState::Payload;
cnt = 0;
}
break;
}
case GPSDecoderState::Payload :
{
//защита от переполнения буфера
if(cnt >= buffer_size)
{
state = GPSDecoderState::Header;
break;
}
data[cnt++] = byte;
if(cnt >= msg_length)
{
state = GPSDecoderState::Checksum;
cnt = 0;
}
break;
}
case GPSDecoderState::Checksum :
{
data[cnt++] = byte;
if(cnt >= 2)
{
msg_checksum = *((uint16_t*)data);
state = GPSDecoderState::Header;
result = msg_class_id;
}
break;
}
default:
{
state = GPSDecoderState::Header;
break;
}
}
}
}
prev_byte = byte;
return result;
}
};
#endif /*__UBLOX_GPS*/