0.4.1
Loading...
Searching...
No Matches
EmlidUtilities.cpp
Go to the documentation of this file.
1// This file is part of INSTINCT, the INS Toolkit for Integrated
2// Navigation Concepts and Training by the Institute of Navigation of
3// the University of Stuttgart, Germany.
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#include "EmlidUtilities.hpp"
10#include "EmlidTypes.hpp"
11
12#include "util/Logger.hpp"
14
15void NAV::vendor::emlid::decryptEmlidObs(const std::shared_ptr<NAV::EmlidObs>& obs, uart::protocol::Packet& packet)
16{
17 if (packet.type() == uart::protocol::Packet::Type::TYPE_BINARY)
18 {
19 obs->msgId = packet.extractUint8();
20 obs->payloadLength = packet.extractUint16();
21
22 // Navigation Results Messages: Position
23 auto msgId = static_cast<ErbMessageID>(obs->msgId);
25 {
26 obs->data = ErbVer();
27
28 std::get<ErbVer>(obs->data).iTOW = packet.extractUint32();
29 std::get<ErbVer>(obs->data).verH = packet.extractUint8();
30 std::get<ErbVer>(obs->data).verM = packet.extractUint8();
31 std::get<ErbVer>(obs->data).verL = packet.extractUint8();
32
33 // Calculate the insTime with the iTOW
34 auto currentTime = util::time::GetCurrentInsTime();
35 if (!currentTime.empty())
36 {
37 auto gpst = currentTime.toGPSweekTow();
38 currentTime = InsTime(gpst.gpsCycle,
39 gpst.gpsWeek,
40 static_cast<long double>(std::get<ErbVer>(obs->data).iTOW) / 1000.0L);
41 obs->insTime = currentTime;
42 }
43
44 LOG_DATA("Erb: VER, iTOW {}, verH {}, verH {}, verH {}",
45 std::get<ErbVer>(obs->data).iTOW,
46 std::get<ErbVer>(obs->data).verH,
47 std::get<ErbVer>(obs->data).verM,
48 std::get<ErbVer>(obs->data).verL);
49 }
50 else if (msgId == ErbMessageID::ERB_MessageId_POS)
51 {
52 obs->data = ErbPos();
53
54 std::get<ErbPos>(obs->data).iTOW = packet.extractUint32();
55 std::get<ErbPos>(obs->data).lon = packet.extractDouble();
56 std::get<ErbPos>(obs->data).lat = packet.extractDouble();
57 std::get<ErbPos>(obs->data).height = packet.extractDouble();
58 std::get<ErbPos>(obs->data).hMSL = packet.extractDouble();
59 std::get<ErbPos>(obs->data).hAcc = packet.extractUint32();
60 std::get<ErbPos>(obs->data).vAcc = packet.extractUint32();
61
62 // Calculate the insTime with the iTOW
63 auto currentTime = util::time::GetCurrentInsTime();
64 if (!currentTime.empty())
65 {
66 auto gpst = currentTime.toGPSweekTow();
67 currentTime = InsTime(gpst.gpsCycle,
68 gpst.gpsWeek,
69 static_cast<long double>(std::get<ErbPos>(obs->data).iTOW) / 1000.0L);
70 obs->insTime = currentTime;
71 }
72
73 LOG_DATA("Erb: POS, iTOW {}, lon {}, lat {}, height {}",
74 std::get<ErbPos>(obs->data).iTOW, std::get<ErbPos>(obs->data).lon,
75 std::get<ErbPos>(obs->data).lat, std::get<ErbPos>(obs->data).height);
76 }
77 else if (msgId == ErbMessageID::ERB_MessageId_STAT)
78 {
79 obs->data = ErbStat();
80
81 std::get<ErbStat>(obs->data).iTOW = packet.extractUint32();
82 std::get<ErbStat>(obs->data).weekGPS = packet.extractUint16();
83 std::get<ErbStat>(obs->data).fixType = packet.extractUint8();
84 std::get<ErbStat>(obs->data).fixStatus = packet.extractUint8();
85 std::get<ErbStat>(obs->data).numSV = packet.extractUint8();
86
87 // Calculate the insTime with the iTOW
88 auto currentTime = util::time::GetCurrentInsTime();
89 if (!currentTime.empty())
90 {
91 auto gpst = currentTime.toGPSweekTow();
92 currentTime = InsTime(gpst.gpsCycle,
93 gpst.gpsWeek,
94 static_cast<long double>(std::get<ErbStat>(obs->data).iTOW) / 1000.0L);
95 obs->insTime = currentTime;
96 }
97
98 LOG_DATA("Erb: STAT, iTOW {}, weekGPS {}, fixType {}, fixStatus {}, numSV {}",
99 std::get<ErbStat>(obs->data).iTOW,
100 std::get<ErbStat>(obs->data).weekGPS, std::get<ErbStat>(obs->data).fixType,
101 std::get<ErbStat>(obs->data).fixStatus, std::get<ErbStat>(obs->data).numSV);
102 }
103 else if (msgId == ErbMessageID::ERB_MessageId_DPOS)
104 {
105 obs->data = ErbDops();
106
107 std::get<ErbDops>(obs->data).iTOW = packet.extractUint32();
108 std::get<ErbDops>(obs->data).dopGeo = packet.extractUint16();
109 std::get<ErbDops>(obs->data).dopPos = packet.extractUint16();
110 std::get<ErbDops>(obs->data).dopVer = packet.extractUint16();
111 std::get<ErbDops>(obs->data).dopHor = packet.extractUint16();
112
113 // Calculate the insTime with the iTOW
114 auto currentTime = util::time::GetCurrentInsTime();
115 if (!currentTime.empty())
116 {
117 auto gpst = currentTime.toGPSweekTow();
118 currentTime = InsTime(gpst.gpsCycle,
119 gpst.gpsWeek,
120 static_cast<long double>(std::get<ErbDops>(obs->data).iTOW) / 1000.0L);
121 obs->insTime = currentTime;
122 }
123
124 LOG_DATA("Erb: DOPS, iTOW {}, dopGeo {}, dopPos {}, dopVer {}, dopHor {}",
125 std::get<ErbDops>(obs->data).iTOW,
126 std::get<ErbDops>(obs->data).dopGeo, std::get<ErbDops>(obs->data).dopPos,
127 std::get<ErbDops>(obs->data).dopVer, std::get<ErbDops>(obs->data).dopHor);
128 }
129 else if (msgId == ErbMessageID::ERB_MessageId_VEL)
130 {
131 obs->data = ErbVel();
132
133 std::get<ErbVel>(obs->data).iTOW = packet.extractUint32();
134 std::get<ErbVel>(obs->data).velN = packet.extractInt32();
135 std::get<ErbVel>(obs->data).velE = packet.extractInt32();
136 std::get<ErbVel>(obs->data).velD = packet.extractInt32();
137 std::get<ErbVel>(obs->data).speed = packet.extractUint32();
138 std::get<ErbVel>(obs->data).gSpeed = packet.extractUint32();
139 std::get<ErbVel>(obs->data).heading = packet.extractInt32();
140 std::get<ErbVel>(obs->data).sAcc = packet.extractUint32();
141
142 // Calculate the insTime with the iTOW
143 auto currentTime = util::time::GetCurrentInsTime();
144 if (!currentTime.empty())
145 {
146 auto gpst = currentTime.toGPSweekTow();
147 currentTime = InsTime(gpst.gpsCycle,
148 gpst.gpsWeek,
149 static_cast<long double>(std::get<ErbVel>(obs->data).iTOW) / 1000.0L);
150 obs->insTime = currentTime;
151 }
152
153 LOG_DATA("Erb: VEL, iTOW {}, gSpeed {} [cm/s], heading {} [deg*1e-5], velD {} [cm/s]",
154 std::get<ErbVel>(obs->data).iTOW, std::get<ErbVel>(obs->data).gSpeed,
155 std::get<ErbVel>(obs->data).heading, std::get<ErbVel>(obs->data).velD);
156 }
157 else if (msgId == ErbMessageID::ERB_MessageId_SVI)
158 {
159 obs->data = ErbSvi();
160
161 std::get<ErbSvi>(obs->data).iTOW = packet.extractUint32();
162 std::get<ErbSvi>(obs->data).nSV = packet.extractUint8();
163 std::get<ErbSvi>(obs->data).idSV = packet.extractUint8();
164 std::get<ErbSvi>(obs->data).typeSV = packet.extractUint8();
165 std::get<ErbSvi>(obs->data).carPh = packet.extractInt32();
166 std::get<ErbSvi>(obs->data).psRan = packet.extractInt32();
167 std::get<ErbSvi>(obs->data).freqD = packet.extractInt32();
168 std::get<ErbSvi>(obs->data).snr = packet.extractUint16();
169 std::get<ErbSvi>(obs->data).azim = packet.extractUint16();
170 std::get<ErbSvi>(obs->data).elev = packet.extractUint16();
171
172 // Calculate the insTime with the iTOW
173 auto currentTime = util::time::GetCurrentInsTime();
174 if (!currentTime.empty())
175 {
176 auto gpst = currentTime.toGPSweekTow();
177 currentTime = InsTime(gpst.gpsCycle,
178 gpst.gpsWeek,
179 static_cast<long double>(std::get<ErbSvi>(obs->data).iTOW) / 1000.0L);
180 obs->insTime = currentTime;
181 }
182
183 LOG_DATA("Erb: SVI, iTOW {}, nSV {} , idSV {} , typeSV {} , carPh {}, psRan {} , freqD {} , snr {}, , azim {} , elev {}",
184 std::get<ErbSvi>(obs->data).iTOW, std::get<ErbSvi>(obs->data).nSV, std::get<ErbSvi>(obs->data).idSV,
185 std::get<ErbSvi>(obs->data).typeSV, std::get<ErbSvi>(obs->data).carPh,
186 std::get<ErbSvi>(obs->data).psRan, std::get<ErbSvi>(obs->data).freqD,
187 std::get<ErbSvi>(obs->data).snr, std::get<ErbSvi>(obs->data).azim,
188 std::get<ErbSvi>(obs->data).elev);
189 }
190 else if (msgId == ErbMessageID::ERB_MessageId_RTK)
191 {
192 obs->data = ErbRtk();
193
194 std::get<ErbRtk>(obs->data).numSV = packet.extractUint8();
195 std::get<ErbRtk>(obs->data).age = packet.extractUint16();
196 std::get<ErbRtk>(obs->data).baselineN = packet.extractInt32();
197 std::get<ErbRtk>(obs->data).baselineE = packet.extractInt32();
198 std::get<ErbRtk>(obs->data).baselineD = packet.extractInt32();
199 std::get<ErbRtk>(obs->data).arRatio = packet.extractUint16();
200 std::get<ErbRtk>(obs->data).weekGPS = packet.extractUint16();
201 std::get<ErbRtk>(obs->data).timeGPS = packet.extractUint32();
202
203 LOG_DATA("Erb: RTK, numSV {}, age {} [s * 1e-2] , baselineN {} , baselineE {} , baselineD {}, arRatio {} [*1e-1] , weekGPS {} , timeGPS {}",
204 std::get<ErbRtk>(obs->data).numSV, std::get<ErbRtk>(obs->data).age, std::get<ErbRtk>(obs->data).baselineN,
205 std::get<ErbRtk>(obs->data).baselineE, std::get<ErbRtk>(obs->data).baselineD,
206 std::get<ErbRtk>(obs->data).arRatio, std::get<ErbRtk>(obs->data).weekGPS,
207 std::get<ErbRtk>(obs->data).timeGPS);
208 }
209 else
210 {
211 LOG_DATA("Erb: {:x}, Size {}, not implemented yet!", obs->msgId, packet.getRawDataLength());
212 }
213 }
214}
215
216std::pair<uint8_t, uint8_t> NAV::vendor::emlid::checksumUBX(const std::vector<uint8_t>& data)
217{
218 uint8_t cka = 0;
219 uint8_t ckb = 0;
220
221 for (size_t i = 2; i < data.size() - 2; i++)
222 {
223 cka += data.at(i);
224 ckb += cka;
225 }
226 return std::make_pair(cka, ckb);
227}
Type Definitions for Emlid messages for Emlid Reach M2 ER Protocol.
Helper Functions to work with Emlid Sensors.
Utility class for logging to console and file.
#define LOG_DATA
All output which occurs repeatedly every time observations are received.
Definition Logger.hpp:29
Keeps track of the current real/simulation time.
The class is responsible for all time-related tasks.
Definition InsTime.hpp:710
ErbMessageID
The available ERB Message IDs.
@ ERB_MessageId_RTK
RTK information.
@ ERB_MessageId_POS
Geodetic position solution.
@ ERB_MessageId_VEL
Velocity solution in NED.
@ ERB_MessageId_STAT
Receiver navigation status.
@ ERB_MessageId_VER
Version of protocol.
@ ERB_MessageId_SVI
Space vehicle information.
@ ERB_MessageId_DPOS
Dilution of precision.
std::pair< uint8_t, uint8_t > checksumUBX(const std::vector< uint8_t > &data)
Calculates the two UBX checksums for the provided data vector.
void decryptEmlidObs(const std::shared_ptr< NAV::EmlidObs > &obs, uart::protocol::Packet &packet)
Decrypts the provided Emlid observation.
Dilution of Precision This message outputs dimensionless values of DOP. These values are scaled by fa...
Geodetic Position Solution.
RTK Information This message output information about RTK.
Receiver Navigation Status This message contains status of Fix, its type and also the number of used ...
Space Vehicle Information This message output information about observation satellites.
Velocity Solution in NED See important comments concerning validity of position given in section Navi...
Version of Protocol.