source: ntrip/trunk/BNC/bncutils.cpp@ 2675

Last change on this file since 2675 was 2582, checked in by mervart, 14 years ago
File size: 9.3 KB
RevLine 
[280]1// Part of BNC, a utility for retrieving decoding and
[464]2// converting GNSS data streams from NTRIP broadcasters.
[280]3//
[464]4// Copyright (C) 2007
[280]5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
[464]7// Czech Technical University Prague, Department of Geodesy
[280]8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
[83]24
25/* -------------------------------------------------------------------------
[93]26 * BKG NTRIP Client
[83]27 * -------------------------------------------------------------------------
28 *
29 * Class: bncutils
30 *
31 * Purpose: Auxiliary Functions
32 *
33 * Author: L. Mervart
34 *
35 * Created: 30-Aug-2006
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
[124]41#include <iostream>
[218]42#include <ctime>
[221]43#include <math.h>
[124]44
[83]45#include <QRegExp>
46#include <QStringList>
[271]47#include <QDateTime>
[83]48
49#include "bncutils.h"
[1155]50#include "bncapp.h"
[83]51
[124]52using namespace std;
53
[1381]54//
55////////////////////////////////////////////////////////////////////////////
[83]56void expandEnvVar(QString& str) {
57
58 QRegExp rx("(\\$\\{.+\\})");
59
60 if (rx.indexIn(str) != -1) {
61 QStringListIterator it(rx.capturedTexts());
62 if (it.hasNext()) {
63 QString rxStr = it.next();
64 QString envVar = rxStr.mid(2,rxStr.length()-3);
65 str.replace(rxStr, qgetenv(envVar.toAscii()));
66 }
67 }
68
69}
[124]70
[1381]71//
72////////////////////////////////////////////////////////////////////////////
[124]73QDateTime dateAndTimeFromGPSweek(int GPSWeek, double GPSWeeks) {
74
75 static const QDate zeroEpoch(1980, 1, 6);
76
77 QDate date(zeroEpoch);
78 QTime time(0,0,0,0);
79
80 int weekDays = int(GPSWeeks) / 86400;
81 date = date.addDays( GPSWeek * 7 + weekDays );
82 time = time.addMSecs( int( (GPSWeeks - 86400 * weekDays) * 1e3 ) );
83
84 return QDateTime(date,time);
85}
[210]86
[1381]87//
88////////////////////////////////////////////////////////////////////////////
[218]89void currentGPSWeeks(int& week, double& sec) {
[210]90
[1942]91 QDateTime currDateTimeGPS;
[1155]92
93 if ( ((bncApp*) qApp)->_currentDateAndTimeGPS ) {
[1942]94 currDateTimeGPS = *(((bncApp*) qApp)->_currentDateAndTimeGPS);
[1155]95 }
96 else {
[1942]97 currDateTimeGPS = QDateTime::currentDateTime().toUTC();
98 QDate hlp = currDateTimeGPS.date();
99 currDateTimeGPS = currDateTimeGPS.addSecs(gnumleap(hlp.year(),
100 hlp.month(), hlp.day()));
[1155]101 }
102
[1942]103 QDate currDateGPS = currDateTimeGPS.date();
104 QTime currTimeGPS = currDateTimeGPS.time();
[210]105
[1942]106 week = int( (double(currDateGPS.toJulianDay()) - 2444244.5) / 7 );
[1036]107
[1942]108 sec = (currDateGPS.dayOfWeek() % 7) * 24.0 * 3600.0 +
109 currTimeGPS.hour() * 3600.0 +
110 currTimeGPS.minute() * 60.0 +
111 currTimeGPS.second() +
112 currTimeGPS.msec() / 1000.0;
[1036]113}
[1154]114
[1381]115//
116////////////////////////////////////////////////////////////////////////////
[1154]117QDateTime currentDateAndTimeGPS() {
[2530]118 if ( ((bncApp*) qApp)->_currentDateAndTimeGPS ) {
119 return *(((bncApp*) qApp)->_currentDateAndTimeGPS);
120 }
121 else {
122 int GPSWeek;
123 double GPSWeeks;
124 currentGPSWeeks(GPSWeek, GPSWeeks);
125 return dateAndTimeFromGPSweek(GPSWeek, GPSWeeks);
126 }
[1154]127}
128
[1381]129//
130////////////////////////////////////////////////////////////////////////////
[1595]131QByteArray ggaString(const QByteArray& latitude,
132 const QByteArray& longitude,
133 const QByteArray& height) {
[1381]134
135 double lat = strtod(latitude,NULL);
136 double lon = strtod(longitude,NULL);
[1595]137 double hei = strtod(height,NULL);
[1381]138
139 const char* flagN="N";
140 const char* flagE="E";
141 if (lon >180.) {lon=(lon-360.)*(-1.); flagE="W";}
142 if ((lon < 0.) && (lon >= -180.)) {lon=lon*(-1.); flagE="W";}
143 if (lon < -180.) {lon=(lon+360.); flagE="E";}
144 if (lat < 0.) {lat=lat*(-1.); flagN="S";}
145 QTime ttime(QDateTime::currentDateTime().toUTC().time());
146 int lat_deg = (int)lat;
147 double lat_min=(lat-lat_deg)*60.;
148 int lon_deg = (int)lon;
149 double lon_min=(lon-lon_deg)*60.;
150 int hh = 0 , mm = 0;
151 double ss = 0.0;
152 hh=ttime.hour();
153 mm=ttime.minute();
154 ss=(double)ttime.second()+0.001*ttime.msec();
155 QString gga;
[1506]156 gga += "GPGGA,";
[1381]157 gga += QString("%1%2%3,").arg((int)hh, 2, 10, QLatin1Char('0')).arg((int)mm, 2, 10, QLatin1Char('0')).arg((int)ss, 2, 10, QLatin1Char('0'));
158 gga += QString("%1%2,").arg((int)lat_deg,2, 10, QLatin1Char('0')).arg(lat_min, 7, 'f', 4, QLatin1Char('0'));
159 gga += flagN;
160 gga += QString(",%1%2,").arg((int)lon_deg,3, 10, QLatin1Char('0')).arg(lon_min, 7, 'f', 4, QLatin1Char('0'));
[1595]161 gga += flagE + QString(",1,05,1.00");
[1599]162 gga += QString(",%1,").arg(hei, 2, 'f', 1);
[1595]163 gga += QString("M,10.000,M,,");
[1381]164 int xori;
165 char XOR = 0;
166 char *Buff =gga.toAscii().data();
167 int iLen = strlen(Buff);
168 for (xori = 0; xori < iLen; xori++) {
169 XOR ^= (char)Buff[xori];
170 }
[1506]171 gga = "$" + gga + QString("*%1").arg(XOR, 2, 16, QLatin1Char('0'));
[1381]172
[1387]173 return gga.toAscii();
[1381]174}
[2043]175
176//
177////////////////////////////////////////////////////////////////////////////
178void RSW_to_XYZ(const ColumnVector& rr, const ColumnVector& vv,
179 const ColumnVector& rsw, ColumnVector& xyz) {
180
181 ColumnVector along = vv / vv.norm_Frobenius();
182 ColumnVector cross = crossproduct(rr, vv); cross /= cross.norm_Frobenius();
183 ColumnVector radial = crossproduct(along, cross);
184
185 Matrix RR(3,3);
186 RR.Column(1) = radial;
187 RR.Column(2) = along;
188 RR.Column(3) = cross;
189
190 xyz = RR * rsw;
191}
[2063]192
193// Rectangular Coordinates -> Ellipsoidal Coordinates
194////////////////////////////////////////////////////////////////////////////
195t_irc xyz2ell(const double* XYZ, double* Ell) {
196
197 const double bell = t_CST::aell*(1.0-1.0/t_CST::fInv) ;
198 const double e2 = (t_CST::aell*t_CST::aell-bell*bell)/(t_CST::aell*t_CST::aell) ;
199 const double e2c = (t_CST::aell*t_CST::aell-bell*bell)/(bell*bell) ;
200
201 double nn, ss, zps, hOld, phiOld, theta, sin3, cos3;
202
203 ss = sqrt(XYZ[0]*XYZ[0]+XYZ[1]*XYZ[1]) ;
204 zps = XYZ[2]/ss ;
205 theta = atan( (XYZ[2]*t_CST::aell) / (ss*bell) );
206 sin3 = sin(theta) * sin(theta) * sin(theta);
207 cos3 = cos(theta) * cos(theta) * cos(theta);
208
209 // Closed formula
210 Ell[0] = atan( (XYZ[2] + e2c * bell * sin3) / (ss - e2 * t_CST::aell * cos3) );
211 Ell[1] = atan2(XYZ[1],XYZ[0]) ;
212 nn = t_CST::aell/sqrt(1.0-e2*sin(Ell[0])*sin(Ell[0])) ;
213 Ell[2] = ss / cos(Ell[0]) - nn;
214
215 const int MAXITER = 100;
216 for (int ii = 1; ii <= MAXITER; ii++) {
217 nn = t_CST::aell/sqrt(1.0-e2*sin(Ell[0])*sin(Ell[0])) ;
218 hOld = Ell[2] ;
219 phiOld = Ell[0] ;
220 Ell[2] = ss/cos(Ell[0])-nn ;
221 Ell[0] = atan(zps/(1.0-e2*nn/(nn+Ell[2]))) ;
222 if ( fabs(phiOld-Ell[0]) <= 1.0e-11 && fabs(hOld-Ell[2]) <= 1.0e-5 ) {
223 return success;
224 }
225 }
226
227 return failure;
228}
[2065]229
230// Rectangular Coordinates -> North, East, Up Components
231////////////////////////////////////////////////////////////////////////////
232void xyz2neu(const double* Ell, const double* xyz, double* neu) {
233
234 double sinPhi = sin(Ell[0]);
235 double cosPhi = cos(Ell[0]);
236 double sinLam = sin(Ell[1]);
237 double cosLam = cos(Ell[1]);
238
239 neu[0] = - sinPhi*cosLam * xyz[0]
240 - sinPhi*sinLam * xyz[1]
241 + cosPhi * xyz[2];
242
243 neu[1] = - sinLam * xyz[0]
244 + cosLam * xyz[1];
245
246 neu[2] = + cosPhi*cosLam * xyz[0]
247 + cosPhi*sinLam * xyz[1]
248 + sinPhi * xyz[2];
249}
[2221]250
[2582]251// North, East, Up Components -> Rectangular Coordinates
252////////////////////////////////////////////////////////////////////////////
253void neu2xyz(const double* Ell, const double* neu, double* xyz) {
254
255 double sinPhi = sin(Ell[0]);
256 double cosPhi = cos(Ell[0]);
257 double sinLam = sin(Ell[1]);
258 double cosLam = cos(Ell[1]);
259
260 xyz[0] = - sinPhi*cosLam * neu[0]
261 - sinLam * neu[1]
262 + cosPhi*cosLam * neu[2];
263
264 xyz[1] = - sinPhi*sinLam * neu[0]
265 + cosLam * neu[1]
266 + cosPhi*sinLam * neu[2];
267
268 xyz[2] = + cosPhi * neu[0]
269 + sinPhi * neu[2];
270}
271
[2221]272// Fourth order Runge-Kutta numerical integrator for ODEs
273////////////////////////////////////////////////////////////////////////////
274ColumnVector rungeKutta4(
275 double xi, // the initial x-value
276 const ColumnVector& yi, // vector of the initial y-values
277 double dx, // the step size for the integration
[2556]278 double* acc, // aditional acceleration
279 ColumnVector (*der)(double x, const ColumnVector& y, double* acc)
[2221]280 // A pointer to a function that computes the
281 // derivative of a function at a point (x,y)
282 ) {
283
[2556]284 ColumnVector k1 = der(xi , yi , acc) * dx;
285 ColumnVector k2 = der(xi+dx/2.0, yi+k1/2.0, acc) * dx;
286 ColumnVector k3 = der(xi+dx/2.0, yi+k2/2.0, acc) * dx;
287 ColumnVector k4 = der(xi+dx , yi+k3 , acc) * dx;
[2221]288
289 ColumnVector yf = yi + k1/6.0 + k2/3.0 + k3/3.0 + k4/6.0;
290
291 return yf;
292}
293
Note: See TracBrowser for help on using the repository browser.