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

Last change on this file since 2928 was 2928, checked in by mervart, 13 years ago
File size: 7.0 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
50// Destructor
51////////////////////////////////////////////////////////////////////////////
52bncComb::~bncComb() {
53 QMapIterator<QString, cmbAC*> it(_ACs);
54 while (it.hasNext()) {
55 it.next();
56 delete it.value();
57 }
58 delete _caster;
59}
60
61// Read and store one correction line
62////////////////////////////////////////////////////////////////////////////
63void bncComb::processCorrLine(const QString& staID, const QString& line) {
64 QMutexLocker locker(&_mutex);
65
66 // Find the relevant instance of cmbAC class
67 // -----------------------------------------
68 if (_ACs.find(staID) == _ACs.end()) {
69 return;
70 }
71 cmbAC* AC = _ACs[staID];
72
73 // Read the Correction
74 // -------------------
75 t_corr* newCorr = new t_corr();
76 if (!newCorr->readLine(line) == success) {
77 delete newCorr;
78 return;
79 }
80
81 // Reject delayed corrections
82 // --------------------------
83 if (_processedBeforeTime.valid() && newCorr->tt < _processedBeforeTime) {
84 delete newCorr;
85 return;
86 }
87
88 // Process all older Epochs (if there are any)
89 // -------------------------------------------
90 const double waitTime = 5.0; // wait 5 sec
91 _processedBeforeTime = newCorr->tt - waitTime;
92
93 QList<cmbEpoch*> epochsToProcess;
94
95 QMapIterator<QString, cmbAC*> itAC(_ACs);
96 while (itAC.hasNext()) {
97 itAC.next();
98 cmbAC* AC = itAC.value();
99
100 QMutableListIterator<cmbEpoch*> itEpo(AC->epochs);
101 while (itEpo.hasNext()) {
102 cmbEpoch* epoch = itEpo.next();
103 if (epoch->time < _processedBeforeTime) {
104 epochsToProcess.append(epoch);
105 itEpo.remove();
106 }
107 }
108 }
109
110 if (epochsToProcess.size()) {
111 processEpochs(epochsToProcess);
112 }
113
114 // Check Modulo Time
115 // -----------------
116 const int moduloTime = 10;
117 if (int(newCorr->tt.gpssec()) % moduloTime != 0.0) {
118 delete newCorr;
119 return;
120 }
121
122 // Find/Create the instance of cmbEpoch class
123 // ------------------------------------------
124 cmbEpoch* newEpoch = 0;
125 QListIterator<cmbEpoch*> it(AC->epochs);
126 while (it.hasNext()) {
127 cmbEpoch* hlpEpoch = it.next();
128 if (hlpEpoch->time == newCorr->tt) {
129 newEpoch = hlpEpoch;
130 break;
131 }
132 }
133 if (newEpoch == 0) {
134 newEpoch = new cmbEpoch(AC->name);
135 newEpoch->time = newCorr->tt;
136 AC->epochs.append(newEpoch);
137 }
138
139 // Merge or add the correction
140 // ---------------------------
141 if (newEpoch->corr.find(newCorr->prn) != newEpoch->corr.end()) {
142 newEpoch->corr[newCorr->prn]->readLine(line); // merge (multiple messages)
143 }
144 else {
145 newEpoch->corr[newCorr->prn] = newCorr;
146 }
147}
148
149// Print one correction
150////////////////////////////////////////////////////////////////////////////
151void bncComb::printSingleCorr(const QString& acName, const t_corr* corr) {
152 cout.setf(ios::fixed);
153 cout << acName.toAscii().data() << " "
154 << corr->prn.toAscii().data() << " "
155 << corr->tt.timestr() << " "
156 << setw(4) << corr->iod << " "
157 << setw(8) << setprecision(4) << corr->dClk * t_CST::c << " "
158 << setw(8) << setprecision(4) << corr->rao[0] << " "
159 << setw(8) << setprecision(4) << corr->rao[1] << " "
160 << setw(8) << setprecision(4) << corr->rao[2] << endl;
161}
162
163// Send results to caster
164////////////////////////////////////////////////////////////////////////////
165void bncComb::dumpResults(const bncTime& resTime,
166 const QMap<QString, t_corr*>& resCorr) {
167
168 _caster->open();
169
170 unsigned year, month, day;
171 resTime.civil_date (year, month, day);
172 double GPSweeks = resTime.gpssec();
173
174 struct ClockOrbit co;
175 memset(&co, 0, sizeof(co));
176 co.GPSEpochTime = (int)GPSweeks;
177 co.GLONASSEpochTime = (int)fmod(GPSweeks, 86400.0)
178 + 3 * 3600 - gnumleap(year, month, day);
179 co.ClockDataSupplied = 1;
180 co.OrbitDataSupplied = 1;
181 co.SatRefDatum = DATUM_ITRF;
182
183 struct ClockOrbit::SatData* sd = 0;
184
185 QMapIterator<QString, t_corr*> it(resCorr);
186 while (it.hasNext()) {
187 it.next();
188 t_corr* corr = it.value();
189
190 if (corr->prn[0] == 'G') {
191 sd = co.Sat + co.NumberOfGPSSat;
192 ++co.NumberOfGPSSat;
193 }
194 else if (corr->prn[0] == 'R') {
195 sd = co.Sat + CLOCKORBIT_NUMGPS + co.NumberOfGLONASSSat;
196 ++co.NumberOfGLONASSSat;
197 }
198
199 if (sd != 0) {
200 sd->ID = corr->prn.mid(1).toInt();
201 sd->IOD = corr->iod;
202 sd->Clock.DeltaA0 = corr->dClk;
203 sd->Orbit.DeltaRadial = corr->rao(1);
204 sd->Orbit.DeltaAlongTrack = corr->rao(2);
205 sd->Orbit.DeltaCrossTrack = corr->rao(3);
206 sd->Orbit.DotDeltaRadial = corr->dotRao(1);
207 sd->Orbit.DotDeltaAlongTrack = corr->dotRao(2);
208 sd->Orbit.DotDeltaCrossTrack = corr->dotRao(3);
209 }
210
211 delete corr;
212 }
213
214 if ( _caster->usedSocket() &&
215 (co.NumberOfGPSSat > 0 || co.NumberOfGLONASSSat > 0) ) {
216 char obuffer[CLOCKORBIT_BUFFERSIZE];
217 int len = MakeClockOrbit(&co, COTYPE_AUTO, 0, obuffer, sizeof(obuffer));
218 if (len > 0) {
219 _caster->write(obuffer, len);
220 }
221 }
222}
223
224// Process Epochs
225////////////////////////////////////////////////////////////////////////////
226void bncComb::processEpochs(const QList<cmbEpoch*>& epochs) {
227
228 bncTime resTime = epochs.first()->time;
229 QMap<QString, t_corr*> resCorr;
230
231 QListIterator<cmbEpoch*> itEpo(epochs);
232 while (itEpo.hasNext()) {
233 cmbEpoch* epo = itEpo.next();
234 QMapIterator<QString, t_corr*> itCorr(epo->corr);
235
236 while (itCorr.hasNext()) {
237 itCorr.next();
238 t_corr* corr = itCorr.value();
239
240 //// beg test
241 if (epo->acName == "BKG") {
242 resCorr[corr->prn] = new t_corr(*corr);
243 }
244 //// end test
245
246 printSingleCorr(epo->acName, corr);
247 delete corr;
248 }
249 }
250
251 dumpResults(resTime, resCorr);
252
253 cout << "Corrections processed" << endl << endl;
254}
255
Note: See TracBrowser for help on using the repository browser.