source: ntrip/trunk/BNC/combination/bnccomb.cpp@ 2930

Last change on this file since 2930 was 2930, checked in by mervart, 16 years ago
File size: 7.6 KB
Line 
1/* -------------------------------------------------------------------------
2 * BKG NTRIP Client
3 * -------------------------------------------------------------------------
4 *
5 * Class: bncComb
6 *
7 * Purpose: Combinations of Orbit/Clock Corrections
8 *
9 * Author: L. Mervart
10 *
11 * Created: 22-Jan-2011
12 *
13 * Changes:
14 *
15 * -----------------------------------------------------------------------*/
16
17#include <iomanip>
18
19#include "bnccomb.h"
20#include "bncapp.h"
21#include "cmbcaster.h"
22#include "bncsettings.h"
23
24using namespace std;
25
26// Constructor
27////////////////////////////////////////////////////////////////////////////
28bncComb::bncComb() {
29
30 bncSettings settings;
31
32 QStringList combineStreams = settings.value("combineStreams").toStringList();
33
34 if (combineStreams.size() >= 2) {
35 QListIterator<QString> it(combineStreams);
36 while (it.hasNext()) {
37 QStringList hlp = it.next().split(" ");
38 cmbAC* newAC = new cmbAC();
39 newAC->mountPoint = hlp[0];
40 newAC->name = hlp[1];
41 newAC->weight = hlp[2].toDouble();
42
43 _ACs[newAC->mountPoint] = newAC;
44 }
45 }
46
47 _caster = new cmbCaster();
48
49 connect(_caster, SIGNAL(error(const QByteArray)),
50 this, SLOT(slotError(const QByteArray)));
51
52 connect(_caster, SIGNAL(newMessage(const QByteArray)),
53 this, SLOT(slotMessage(const QByteArray)));
54}
55
56// Destructor
57////////////////////////////////////////////////////////////////////////////
58bncComb::~bncComb() {
59 QMapIterator<QString, cmbAC*> it(_ACs);
60 while (it.hasNext()) {
61 it.next();
62 delete it.value();
63 }
64 delete _caster;
65}
66
67// Read and store one correction line
68////////////////////////////////////////////////////////////////////////////
69void bncComb::processCorrLine(const QString& staID, const QString& line) {
70 QMutexLocker locker(&_mutex);
71
72 // Find the relevant instance of cmbAC class
73 // -----------------------------------------
74 if (_ACs.find(staID) == _ACs.end()) {
75 return;
76 }
77 cmbAC* AC = _ACs[staID];
78
79 // Read the Correction
80 // -------------------
81 t_corr* newCorr = new t_corr();
82 if (!newCorr->readLine(line) == success) {
83 delete newCorr;
84 return;
85 }
86
87 // Reject delayed corrections
88 // --------------------------
89 if (_processedBeforeTime.valid() && newCorr->tt < _processedBeforeTime) {
90 delete newCorr;
91 return;
92 }
93
94 // Process all older Epochs (if there are any)
95 // -------------------------------------------
96 const double waitTime = 5.0; // wait 5 sec
97 _processedBeforeTime = newCorr->tt - waitTime;
98
99 QList<cmbEpoch*> epochsToProcess;
100
101 QMapIterator<QString, cmbAC*> itAC(_ACs);
102 while (itAC.hasNext()) {
103 itAC.next();
104 cmbAC* AC = itAC.value();
105
106 QMutableListIterator<cmbEpoch*> itEpo(AC->epochs);
107 while (itEpo.hasNext()) {
108 cmbEpoch* epoch = itEpo.next();
109 if (epoch->time < _processedBeforeTime) {
110 epochsToProcess.append(epoch);
111 itEpo.remove();
112 }
113 }
114 }
115
116 if (epochsToProcess.size()) {
117 processEpochs(epochsToProcess);
118 }
119
120 // Check Modulo Time
121 // -----------------
122 const int moduloTime = 10;
123 if (int(newCorr->tt.gpssec()) % moduloTime != 0.0) {
124 delete newCorr;
125 return;
126 }
127
128 // Find/Create the instance of cmbEpoch class
129 // ------------------------------------------
130 cmbEpoch* newEpoch = 0;
131 QListIterator<cmbEpoch*> it(AC->epochs);
132 while (it.hasNext()) {
133 cmbEpoch* hlpEpoch = it.next();
134 if (hlpEpoch->time == newCorr->tt) {
135 newEpoch = hlpEpoch;
136 break;
137 }
138 }
139 if (newEpoch == 0) {
140 newEpoch = new cmbEpoch(AC->name);
141 newEpoch->time = newCorr->tt;
142 AC->epochs.append(newEpoch);
143 }
144
145 // Merge or add the correction
146 // ---------------------------
147 if (newEpoch->corr.find(newCorr->prn) != newEpoch->corr.end()) {
148 newEpoch->corr[newCorr->prn]->readLine(line); // merge (multiple messages)
149 }
150 else {
151 newEpoch->corr[newCorr->prn] = newCorr;
152 }
153}
154
155// Print one correction
156////////////////////////////////////////////////////////////////////////////
157void bncComb::printSingleCorr(const QString& acName, const t_corr* corr) {
158 cout.setf(ios::fixed);
159 cout << acName.toAscii().data() << " "
160 << corr->prn.toAscii().data() << " "
161 << corr->tt.timestr() << " "
162 << setw(4) << corr->iod << " "
163 << setw(8) << setprecision(4) << corr->dClk * t_CST::c << " "
164 << setw(8) << setprecision(4) << corr->rao[0] << " "
165 << setw(8) << setprecision(4) << corr->rao[1] << " "
166 << setw(8) << setprecision(4) << corr->rao[2] << endl;
167}
168
169// Send results to caster
170////////////////////////////////////////////////////////////////////////////
171void bncComb::dumpResults(const bncTime& resTime,
172 const QMap<QString, t_corr*>& resCorr) {
173
174 _caster->open();
175
176 unsigned year, month, day;
177 resTime.civil_date (year, month, day);
178 double GPSweeks = resTime.gpssec();
179
180 struct ClockOrbit co;
181 memset(&co, 0, sizeof(co));
182 co.GPSEpochTime = (int)GPSweeks;
183 co.GLONASSEpochTime = (int)fmod(GPSweeks, 86400.0)
184 + 3 * 3600 - gnumleap(year, month, day);
185 co.ClockDataSupplied = 1;
186 co.OrbitDataSupplied = 1;
187 co.SatRefDatum = DATUM_ITRF;
188
189 struct ClockOrbit::SatData* sd = 0;
190
191 QMapIterator<QString, t_corr*> it(resCorr);
192 while (it.hasNext()) {
193 it.next();
194 t_corr* corr = it.value();
195
196 if (corr->prn[0] == 'G') {
197 sd = co.Sat + co.NumberOfGPSSat;
198 ++co.NumberOfGPSSat;
199 }
200 else if (corr->prn[0] == 'R') {
201 sd = co.Sat + CLOCKORBIT_NUMGPS + co.NumberOfGLONASSSat;
202 ++co.NumberOfGLONASSSat;
203 }
204
205 if (sd != 0) {
206 sd->ID = corr->prn.mid(1).toInt();
207 sd->IOD = corr->iod;
208 sd->Clock.DeltaA0 = corr->dClk * t_CST::c;
209 sd->Orbit.DeltaRadial = corr->rao(1);
210 sd->Orbit.DeltaAlongTrack = corr->rao(2);
211 sd->Orbit.DeltaCrossTrack = corr->rao(3);
212 sd->Orbit.DotDeltaRadial = corr->dotRao(1);
213 sd->Orbit.DotDeltaAlongTrack = corr->dotRao(2);
214 sd->Orbit.DotDeltaCrossTrack = corr->dotRao(3);
215 }
216
217 delete corr;
218 }
219
220 if ( _caster->usedSocket() &&
221 (co.NumberOfGPSSat > 0 || co.NumberOfGLONASSSat > 0) ) {
222 char obuffer[CLOCKORBIT_BUFFERSIZE];
223 int len = MakeClockOrbit(&co, COTYPE_AUTO, 0, obuffer, sizeof(obuffer));
224 if (len > 0) {
225 _caster->write(obuffer, len);
226 }
227 }
228}
229
230// Write an Error Message
231////////////////////////////////////////////////////////////////////////////
232void bncComb::slotError(const QByteArray msg) {
233 cout << msg.data() << endl;
234}
235
236// Write a Message
237////////////////////////////////////////////////////////////////////////////
238void bncComb::slotMessage(const QByteArray msg) {
239 cout << msg.data() << endl;
240}
241
242// Process Epochs
243////////////////////////////////////////////////////////////////////////////
244void bncComb::processEpochs(const QList<cmbEpoch*>& epochs) {
245
246 bncTime resTime = epochs.first()->time;
247 QMap<QString, t_corr*> resCorr;
248
249 QListIterator<cmbEpoch*> itEpo(epochs);
250 while (itEpo.hasNext()) {
251 cmbEpoch* epo = itEpo.next();
252 QMapIterator<QString, t_corr*> itCorr(epo->corr);
253
254 while (itCorr.hasNext()) {
255 itCorr.next();
256 t_corr* corr = itCorr.value();
257
258 //// beg test
259 if (epo->acName == "BKG") {
260 resCorr[corr->prn] = new t_corr(*corr);
261 }
262 //// end test
263
264 printSingleCorr(epo->acName, corr);
265 delete corr;
266 }
267 }
268
269 dumpResults(resTime, resCorr);
270
271 cout << "Corrections processed" << endl << endl;
272}
273
Note: See TracBrowser for help on using the repository browser.