-
Notifications
You must be signed in to change notification settings - Fork 52
/
rtcmtool.cc
172 lines (149 loc) · 4.44 KB
/
rtcmtool.cc
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
#include "rtcm.hh"
#include "bits.hh"
#include <vector>
#include <iostream>
#include <signal.h>
#include "nmmsender.hh"
#include "CLI/CLI.hpp"
#include "swrappers.hh"
#include "sclasses.hh"
#include "version.hh"
using namespace std;
bool RTCMReader::get(RTCMFrame& rf)
{
int c;
bool skipped=false;
while( ((c=fgetc(d_fp)) != -1) && c != 211) {
skipped=true;
cerr<<".";
continue;
}
if(skipped)
cerr<<endl;
if(c != 211) {
cerr<<"EOF"<<endl;
return false;
}
// cout<<"Found preamble"<<endl;
unsigned char buffer[2];
if(fread((char*)buffer, 1, 2, d_fp) != 2)
return false;
// cout<<"Got two byte buffer"<<endl;
// 6 bits reserved, 10 bits of size
int size = getbitu(buffer, 6, 10);
size += 3;
// cout<<"Now reading "<<size<<" bytes"<<endl;
vector<char> buf(size);
if((int)fread(&buf[0], 1, size, d_fp) != size)
return false;
// cout<<"Returning true"<<endl;
rf.payload.assign(&buf[0], size - 3);
return true;
}
/*
Message types:
Type 1240, Galileo orbit corrections to Broadcast Ephemeris
Type 1241, Galileo clock corrections to Broadcast Ephemeris
1057 message for GPS orbit corrections to Broadcast Ephemeris,
1058 message for GPS clock corrections to Broadcast Ephemeris,
*/
/* 1057 (GPS), 1240 (Galileo)
0 12 bits message number
12 20 bits galileo SOW
32 4 bits SSR update interval
36 1 bit multiple message indicator
37 1 bit Satellite Reference Datum (0: ITRF, 1: regional)
38 4 bit (IOD SSR)
42 16 bits SSR provider ID
58 4 bits SSR solution ID
62 6 bits number of satellites
68
Repeat, starting from pos 68:
0 6 bits sv
6 10 bits IODE nav / 8 for GPS, a shift of -2 everywhere below
16 22 bits delta radial (0.1mm)
38 20 bits along track (0.4mm)
58 20 bits cross track (0.4mm)
78 21 bits dot delta radial (0.001 mm/s)
99 19 bits dot delta along (0.004 mm/s)
118 19 bits dot delta cross-track (0.004 mm/s)
137
*/
/*
1058 (GPS), 1241 (Galileo)
0 12 bits message number
12 20 bits galileo SOW (GPS Epoch time)
32 4 bits "UDI" ("SSR Update interval")
36 1 bit "sync" ("multiple message indicator")
37 4 bit (IOD SSR, link to 1240 I think)
41 16 bits SSR provider ID
57 4 bits SSR solution ID
61 6 bits number of satellites
67
67
Repeat, starting from pos 68:
0 6 bits sv
6 22 bits dclk[0] 1e-4 meter // 0.1 mm
28 21 bits dclk[1] 1e-6 meter/s // 0.001 mm/s
49 27 bits dclk[2] 2e-8 meter // 0.0002mm/s^2
76
Reference time is Epoch Time + 0.5* SSR update interval, which can be zero.
*/
/*
CLKA[0,1]_DEU1 – containing the SSR corrections regarding the satellites’ Antenna Phase Center
CLKC[0,1]_DEU1 – containing the SSR corrections regarding the satellites’ Center of Mass.
*/
static char program[]="rtcmtool";
uint16_t g_srcid{0};
int main(int argc, char** argv)
{
// time_t starttime=time(0);
GOOGLE_PROTOBUF_VERIFY_VERSION;
vector<string> destinations;
bool doVERSION{false}, doSTDOUT{false};
CLI::App app(program);
app.add_option("--destination,-d", destinations, "Send output to this IPv4/v6 address");
app.add_option("--station", g_srcid, "Station id")->required();
app.add_flag("--version", doVERSION, "show program version and copyright");
app.add_flag("--stdout", doSTDOUT, "Emit output to stdout");
try {
app.parse(argc, argv);
} catch(const CLI::Error &e) {
return app.exit(e);
}
if(doVERSION) {
showVersion(program, g_gitHash);
exit(0);
}
signal(SIGPIPE, SIG_IGN);
NMMSender ns;
ns.d_debug = true;
for(const auto& s : destinations) {
auto res=resolveName(s, true, true);
if(res.empty()) {
cerr<<"Unable to resolve '"<<s<<"' as destination for data, exiting"<<endl;
exit(EXIT_FAILURE);
}
ns.addDestination(s); // ComboAddress(s, 29603));
}
if(doSTDOUT)
ns.addDestination(1);
ns.launch();
RTCMReader rr(0);
RTCMFrame rf;
cerr<<"Station "<<g_srcid<<endl;
while(rr.get(rf)) {
// cerr<<"Got a "<<rf.payload.size()<<" byte frame"<<endl;
RTCMMessage rm;
NavMonMessage nmm;
struct timespec ts;
clock_gettime(CLOCK_REALTIME, & ts);
nmm.set_type(NavMonMessage::RTCMMessageType);
nmm.set_localutcseconds(ts.tv_sec);
nmm.set_localutcnanoseconds(ts.tv_nsec);
nmm.set_sourceid(g_srcid);
nmm.mutable_rm()->set_contents(rf.payload);
ns.emitNMM(nmm);
// rm.parse(rf.payload);
}
}