source: ntrip/trunk/BNC/RTCM/RTCM.h@ 87

Last change on this file since 87 was 36, checked in by mervart, 19 years ago

* empty log message *

File size: 8.4 KB
Line 
1// -*- C++ -*-
2//
3// $Id: RTCM.h,v 1.1.1.1 2006/05/30 11:05:27 mervart Exp $
4
5#if defined(__GNUC__)
6using namespace std;
7#endif
8
9#include "GPSDecoder.h"
10#include "m_date.h"
11#include <cmath>
12#include <map>
13#include <iostream>
14#include <sys/types.h>
15
16class RTCM : public GPSDecoder {
17 public:
18 RTCM(char _StationID,bool fullRange)
19 :GPSDecoder()
20 ,StationID(_StationID)
21 ,lowerBound(fullRange ? -715827883 : 715827882 )
22 ,upperBound(fullRange ? 715827882 : 1431655764 )
23 ,rolloverIntervall(fullRange ? 4294967296. /* pow(2,32) */
24 : 2147483648. /* pow(2,31) */)
25 ,debug(0)
26 ,this_word(0)
27 ,data_word(0)
28 ,next_bits(0)
29 ,rtcm_state(/* NO_SYNC */ 0)
30 ,fail_count(0)
31 ,p_fail(0)
32 ,preamble_flag(0)
33 ,sync_bit(0)
34 ,fill_shift(0)
35 ,word_sync(0)
36 ,frame_sync(0)
37 ,frame_fill(0)
38 ,word_count(0)
39 ,frame_count(0)
40 ,pf_count(0)
41 ,msg_type(0)
42 ,station_id(0)
43 ,z_count(0)
44 ,seqno(0)
45 ,msg_len(0)
46 ,health(0)
47 ,fillptr(message)
48 ,pfptr(NULL) {}
49
50 // defined as required by baseclass
51 void Decode(char* _ptrBuffer=NULL, int _nBufLen=0) {
52 while(_nBufLen--) {
53 new_byte((u_char)*_ptrBuffer);
54 _ptrBuffer++;
55 }
56 }
57
58 protected:
59 // Station ID used in m_lObsList
60 char StationID;
61
62 typedef u_int SVPRN;
63
64 struct Rollover {
65 Rollover():lastValue(0),rollOver(0) {}
66 int lastValue;
67 int rollOver;
68 } ;
69
70 struct RolloverChannel {
71 Rollover l1;
72 Rollover l2;
73 } ;
74
75 typedef map<SVPRN,RolloverChannel> RolloverMap;
76 RolloverMap rolloverMap;
77
78 // Collector for Measurement
79 struct ObsSort {
80 ObsSort():C1(0.),P2(0.),l1(0),l2(0),assigned(0) {}
81 void set_C1(double _C1) { assigned|=1; C1= _C1; }
82 void set_P2(double _P2) { assigned|=2; P2= _P2; }
83 void set_l1(int _l1) { assigned|=4; l1= _l1; }
84 void set_l2(int _l2) { assigned|=8; l2= _l2; }
85 void set_pCodeIndicator(int _pCodeIndicator){ assigned|=16; pCodeIndicator = _pCodeIndicator;}
86 void set_cumuLossOfCont(u_char _cumuLossOfCont){ assigned|=32; cumuLossOfCont = _cumuLossOfCont;}
87 bool allAssigned() const { return assigned == 63; }
88 double C1; // m
89 double P2; // m
90 int l1; // [1/256 Cycles mod int/half int ]
91 int l2; // [1/256 Cycles mod int/half int ]
92 int pCodeIndicator;
93 u_int cumuLossOfCont;
94 u_int assigned;
95 } ;
96
97 typedef map<SVPRN,ObsSort> ObsMap;
98 ObsMap obsMap;
99
100 // GPStime mod 3600 of current epoch
101 // GLONASS measurements/epochs are ignored
102 double obsMapTimeTagMod3600;
103
104 // Complete mod 3600s time with the help of system time
105 // to timetag. Assume that the diffence is below 20min.
106 static long completeMod3600BySysTime(int mod3600time) {
107 const long sysTimeTag= Date::timeNow().tag_get();
108 const long offset = ((sysTimeTag%3600) < 1200) && (mod3600time > 2400)
109 ? -1
110 : ((sysTimeTag%3600) > 2400) && (mod3600time < 1200)
111 ? 1
112 : 0;
113 return ((sysTimeTag/3600)+offset)*3600 + mod3600time;
114 }
115
116
117 //
118 //
119 //
120 virtual void endOfEpoch(Date d) {}
121
122 //
123 //
124 // called if reference position arises in datastream
125 virtual void onPosition(double x,double y,double z) {}
126
127 // Rollover managment
128 int lowerBound;
129 int upperBound;
130 double rolloverIntervall;
131
132 int rollOverCondition(int oldv,int newv) {
133 return (oldv < lowerBound && newv > upperBound )
134 ? -1
135 : (newv < lowerBound && oldv > upperBound )
136 ? 1
137 : 0;
138 }
139
140 //
141 //
142 //
143 void updateRollovers() {
144 ObsMap::iterator i;
145 for(i= obsMap.begin();i != obsMap.end();i++) {
146 RolloverMap::iterator rm(rolloverMap.find(i->first));
147 if(rm != rolloverMap.end()) {
148 rm->second.l1.rollOver +=
149 rollOverCondition( rm->second.l1.lastValue
150 ,i->second.l1 );
151 rm->second.l2.rollOver +=
152 rollOverCondition( rm->second.l2.lastValue
153 ,i->second.l2 );
154 } else {
155 rolloverMap[i->first].l1.rollOver= 0;
156 rolloverMap[i->first].l2.rollOver= 0;
157 }
158 rolloverMap[i->first].l1.lastValue= i->second.l1;
159 rolloverMap[i->first].l2.lastValue= i->second.l2;
160 }
161 }
162
163 //
164 //
165 //
166 virtual void debugOut( SVPRN svprn,long timetag,double mod3600,long mod3600int
167 ,double C1,int l1,int roll_l1,double unrolled_l1
168 ,int l2,int roll_l2,double unrolled_l2) {}
169
170 //
171 //
172 //
173 void dumpObsMap() {
174 const int obsMapTimeTagMod3600int=int(rint(obsMapTimeTagMod3600));
175 const long timeTag = completeMod3600BySysTime(obsMapTimeTagMod3600int);
176 Date d;
177 d.tag_set(timeTag);
178
179 updateRollovers();
180
181 endOfEpoch(d);
182
183 ObsMap::iterator i;
184 for(i= obsMap.begin();i != obsMap.end();i++) {
185 if(!i->second.allAssigned() ) {
186 // cerr << "incomplete measurements" << endl;
187 } else {
188 Observation *op = new Observation;
189
190 op->StatID[0] = StationID;
191 op->StatID[1] = '\0';
192 op->SVPRN= i->first;
193 op->GPSWeek= timeTag / Date::SECONDS_PER_WEEK;
194 op->GPSWeeks= timeTag % Date::SECONDS_PER_WEEK;
195 op->sec = obsMapTimeTagMod3600!=3600.0 ? obsMapTimeTagMod3600 : 0.0;
196 op->C1= i->second.C1;
197 op->P2= i->second.P2;
198 op->pCodeIndicator = i->second.pCodeIndicator;
199 op->cumuLossOfCont = i->second.cumuLossOfCont;
200 const double l1_offset( rolloverMap[i->first].l1.rollOver
201 * rolloverIntervall );
202 const double unrolled_l1 = i->second.l1 + l1_offset;
203 op->L1=(unrolled_l1 / -256.) * lambda1;
204
205 const double l2_offset( rolloverMap[i->first].l2.rollOver
206 * rolloverIntervall );
207 const double unrolled_l2 = i->second.l2 + l2_offset;
208 op->L2=(unrolled_l2 / -256.) * lambda2;
209
210 op->SNR1= 0;
211 op->SNR2= 0;
212 m_lObsList.push_back(op);
213 debugOut( i->first,timeTag,obsMapTimeTagMod3600,obsMapTimeTagMod3600int
214 ,op->C1
215 ,i->second.l1,rolloverMap[i->first].l1.rollOver,unrolled_l1
216 ,i->second.l2,rolloverMap[i->first].l2.rollOver,unrolled_l2);
217 }
218 }
219 obsMap.clear();
220 }
221
222 // SC-104 V2.3 4-42 Note 1 4.
223 // Recover TimeTag ( modulo 3600s ) GPS/GLONASS Time and ClockError
224 // from expandedTimeOfMeasurement
225 // Assume receiver measurements at hard edges at a grid of 10ms
226 // and clock error as less 5 ms (1.1ms max recommended).
227 //
228 struct RecoveredTimeTagAndClockError {
229 static double fastestUpdatePeriod() { return 0.01; }
230 static double shift() { return fastestUpdatePeriod() / 2.; }
231 RecoveredTimeTagAndClockError(double expandedTimeOfMeasurement /* [s] */)
232 :clockError(fmod(expandedTimeOfMeasurement+shift(),fastestUpdatePeriod()) - shift())
233 ,timeTagMod3600(expandedTimeOfMeasurement - clockError) {}
234 double clockError; /* [s] */
235 double timeTagMod3600; /* [s] */
236 } ;
237
238 virtual void debugTime(double timeTagMod3600,double clockError) {}
239
240 void dumpOnNewTimeTag(double expandedTimeOfMeasurement) {
241 const RecoveredTimeTagAndClockError r(expandedTimeOfMeasurement);
242 if(r.timeTagMod3600 != obsMapTimeTagMod3600) {
243 debugTime(r.timeTagMod3600,r.clockError);
244 if(obsMap.size()) dumpObsMap();
245 obsMapTimeTagMod3600= r.timeTagMod3600;
246 }
247 }
248
249 int preamble();
250 void state_change(u_int s);
251 u_int parity_ok();
252 int find_sync(u_char b);
253 void next_word();
254 int filled_word(u_char b);
255
256 void msgRTKUncorrectedCarrierPhases();
257 void msgRTKUncorrectedPseudoranges();
258
259 void printcor();
260 void printref();
261 void printba();
262 void printspec();
263 void printnull();
264 void printdatum();
265 void printconh();
266
267 void new_frame();
268 void buffer(u_int w);
269 void frame_start();
270 void find_start();
271 void fill_frame();
272 void status_byte(u_char b);
273 void data_byte(u_char b);
274 void new_byte(u_char b);
275
276 int debug;
277
278 u_int this_word, data_word;
279 u_char next_bits;
280
281 int rtcm_state, fail_count, p_fail, preamble_flag;
282 int sync_bit, fill_shift, word_sync, frame_sync, frame_fill;
283 int word_count, frame_count, pf_count;
284 int msg_type, station_id, z_count, seqno, msg_len, health;
285
286 u_int message[40]; /* message buffer */
287 u_int *fillptr; /* pointer to fill message */
288 u_int *pfptr; /* pointer to first parity error */
289
290 static char *state_name[];
291 static u_int tx_speed[];
292 static u_char parity_of[];
293 static u_char reverse_bits[];
294} ;
Note: See TracBrowser for help on using the repository browser.